back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_zebra.c (source / functions) Hit Total Coverage
Test: test_bgp_set_aspath_replace.py::BGPSetAspathReplace Lines: 461 1929 23.9 %
Date: 2023-02-24 18:37:49 Functions: 38 103 36.9 %

          Line data    Source code
       1             : /* zebra client
       2             :  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "command.h"
      24             : #include "stream.h"
      25             : #include "network.h"
      26             : #include "prefix.h"
      27             : #include "log.h"
      28             : #include "sockunion.h"
      29             : #include "zclient.h"
      30             : #include "routemap.h"
      31             : #include "thread.h"
      32             : #include "queue.h"
      33             : #include "memory.h"
      34             : #include "lib/json.h"
      35             : #include "lib/bfd.h"
      36             : #include "lib/route_opaque.h"
      37             : #include "filter.h"
      38             : #include "mpls.h"
      39             : #include "vxlan.h"
      40             : #include "pbr.h"
      41             : 
      42             : #include "bgpd/bgpd.h"
      43             : #include "bgpd/bgp_route.h"
      44             : #include "bgpd/bgp_attr.h"
      45             : #include "bgpd/bgp_aspath.h"
      46             : #include "bgpd/bgp_nexthop.h"
      47             : #include "bgpd/bgp_zebra.h"
      48             : #include "bgpd/bgp_fsm.h"
      49             : #include "bgpd/bgp_debug.h"
      50             : #include "bgpd/bgp_errors.h"
      51             : #include "bgpd/bgp_mpath.h"
      52             : #include "bgpd/bgp_nexthop.h"
      53             : #include "bgpd/bgp_nht.h"
      54             : #include "bgpd/bgp_bfd.h"
      55             : #include "bgpd/bgp_label.h"
      56             : #ifdef ENABLE_BGP_VNC
      57             : #include "bgpd/rfapi/rfapi_backend.h"
      58             : #include "bgpd/rfapi/vnc_export_bgp.h"
      59             : #endif
      60             : #include "bgpd/bgp_evpn.h"
      61             : #include "bgpd/bgp_mplsvpn.h"
      62             : #include "bgpd/bgp_labelpool.h"
      63             : #include "bgpd/bgp_pbr.h"
      64             : #include "bgpd/bgp_evpn_private.h"
      65             : #include "bgpd/bgp_evpn_mh.h"
      66             : #include "bgpd/bgp_mac.h"
      67             : #include "bgpd/bgp_trace.h"
      68             : #include "bgpd/bgp_community.h"
      69             : #include "bgpd/bgp_lcommunity.h"
      70             : 
      71             : /* All information about zebra. */
      72             : struct zclient *zclient = NULL;
      73             : 
      74             : /* hook to indicate vrf status change for SNMP */
      75          44 : DEFINE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),
      76             :             (bgp, ifp));
      77             : 
      78           9 : DEFINE_MTYPE_STATIC(BGPD, BGP_IF_INFO, "BGP interface context");
      79             : 
      80             : /* Can we install into zebra? */
      81          18 : static inline bool bgp_install_info_to_zebra(struct bgp *bgp)
      82             : {
      83          18 :         if (zclient->sock <= 0)
      84             :                 return false;
      85             : 
      86          18 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
      87           0 :                 zlog_debug(
      88             :                         "%s: No zebra instance to talk to, not installing information",
      89             :                         __func__);
      90           0 :                 return false;
      91             :         }
      92             : 
      93             :         return true;
      94             : }
      95             : 
      96             : int zclient_num_connects;
      97             : 
      98             : /* Router-id update message from zebra. */
      99           3 : static int bgp_router_id_update(ZAPI_CALLBACK_ARGS)
     100             : {
     101           3 :         struct prefix router_id;
     102             : 
     103           3 :         zebra_router_id_update_read(zclient->ibuf, &router_id);
     104             : 
     105           3 :         if (BGP_DEBUG(zebra, ZEBRA))
     106           0 :                 zlog_debug("Rx Router Id update VRF %u Id %pFX", vrf_id,
     107             :                            &router_id);
     108             : 
     109           3 :         bgp_router_id_zebra_bump(vrf_id, &router_id);
     110           3 :         return 0;
     111             : }
     112             : 
     113             : /* Nexthop update message from zebra. */
     114           4 : static int bgp_read_nexthop_update(ZAPI_CALLBACK_ARGS)
     115             : {
     116           4 :         bgp_parse_nexthop_update(cmd, vrf_id);
     117           4 :         return 0;
     118             : }
     119             : 
     120             : /* Set or clear interface on which unnumbered neighbor is configured. This
     121             :  * would in turn cause BGP to initiate or turn off IPv6 RAs on this
     122             :  * interface.
     123             :  */
     124          24 : static void bgp_update_interface_nbrs(struct bgp *bgp, struct interface *ifp,
     125             :                                       struct interface *upd_ifp)
     126             : {
     127          24 :         struct listnode *node, *nnode;
     128          24 :         struct peer *peer;
     129             : 
     130          81 :         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     131          33 :                 if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0)) {
     132           0 :                         if (upd_ifp) {
     133           0 :                                 peer->ifp = upd_ifp;
     134           0 :                                 bgp_zebra_initiate_radv(bgp, peer);
     135             :                         } else {
     136           0 :                                 bgp_zebra_terminate_radv(bgp, peer);
     137           0 :                                 peer->ifp = upd_ifp;
     138             :                         }
     139             :                 }
     140             :         }
     141          24 : }
     142             : 
     143           0 : static int bgp_read_fec_update(ZAPI_CALLBACK_ARGS)
     144             : {
     145           0 :         bgp_parse_fec_update();
     146           0 :         return 0;
     147             : }
     148             : 
     149           0 : static void bgp_start_interface_nbrs(struct bgp *bgp, struct interface *ifp)
     150             : {
     151           0 :         struct listnode *node, *nnode;
     152           0 :         struct peer *peer;
     153             : 
     154           0 :         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     155           0 :                 if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0)
     156           0 :                     && !peer_established(peer)) {
     157           0 :                         if (peer_active(peer))
     158           0 :                                 BGP_EVENT_ADD(peer, BGP_Stop);
     159           0 :                         BGP_EVENT_ADD(peer, BGP_Start);
     160             :                 }
     161             :         }
     162           0 : }
     163             : 
     164           0 : static void bgp_nbr_connected_add(struct bgp *bgp, struct nbr_connected *ifc)
     165             : {
     166           0 :         struct listnode *node;
     167           0 :         struct connected *connected;
     168           0 :         struct interface *ifp;
     169           0 :         struct prefix *p;
     170             : 
     171             :         /* Kick-off the FSM for any relevant peers only if there is a
     172             :          * valid local address on the interface.
     173             :          */
     174           0 :         ifp = ifc->ifp;
     175           0 :         for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
     176           0 :                 p = connected->address;
     177           0 :                 if (p->family == AF_INET6
     178           0 :                     && IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
     179             :                         break;
     180             :         }
     181           0 :         if (!connected)
     182             :                 return;
     183             : 
     184           0 :         bgp_start_interface_nbrs(bgp, ifp);
     185             : }
     186             : 
     187           0 : static void bgp_nbr_connected_delete(struct bgp *bgp, struct nbr_connected *ifc,
     188             :                                      int del)
     189             : {
     190           0 :         struct listnode *node, *nnode;
     191           0 :         struct peer *peer;
     192           0 :         struct interface *ifp;
     193             : 
     194           0 :         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     195           0 :                 if (peer->conf_if
     196           0 :                     && (strcmp(peer->conf_if, ifc->ifp->name) == 0)) {
     197           0 :                         peer->last_reset = PEER_DOWN_NBR_ADDR_DEL;
     198           0 :                         BGP_EVENT_ADD(peer, BGP_Stop);
     199             :                 }
     200             :         }
     201             :         /* Free neighbor also, if we're asked to. */
     202           0 :         if (del) {
     203           0 :                 ifp = ifc->ifp;
     204           0 :                 listnode_delete(ifp->nbr_connected, ifc);
     205           0 :                 nbr_connected_free(ifc);
     206             :         }
     207           0 : }
     208             : 
     209           0 : static int bgp_ifp_destroy(struct interface *ifp)
     210             : {
     211           0 :         struct bgp *bgp;
     212             : 
     213           0 :         bgp = ifp->vrf->info;
     214             : 
     215           0 :         if (BGP_DEBUG(zebra, ZEBRA))
     216           0 :                 zlog_debug("Rx Intf del VRF %u IF %s", ifp->vrf->vrf_id,
     217             :                            ifp->name);
     218             : 
     219           0 :         if (bgp) {
     220           0 :                 bgp_update_interface_nbrs(bgp, ifp, NULL);
     221           0 :                 hook_call(bgp_vrf_status_changed, bgp, ifp);
     222             :         }
     223             : 
     224           0 :         bgp_mac_del_mac_entry(ifp);
     225             : 
     226           0 :         return 0;
     227             : }
     228             : 
     229          10 : static int bgp_ifp_up(struct interface *ifp)
     230             : {
     231          10 :         struct connected *c;
     232          10 :         struct nbr_connected *nc;
     233          10 :         struct listnode *node, *nnode;
     234          10 :         struct bgp *bgp;
     235             : 
     236          10 :         bgp = ifp->vrf->info;
     237             : 
     238          10 :         bgp_mac_add_mac_entry(ifp);
     239             : 
     240          10 :         if (BGP_DEBUG(zebra, ZEBRA))
     241           0 :                 zlog_debug("Rx Intf up VRF %u IF %s", ifp->vrf->vrf_id,
     242             :                            ifp->name);
     243             : 
     244          10 :         if (!bgp)
     245             :                 return 0;
     246             : 
     247          20 :         for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
     248           0 :                 bgp_connected_add(bgp, c);
     249             : 
     250          20 :         for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
     251           0 :                 bgp_nbr_connected_add(bgp, nc);
     252             : 
     253          10 :         hook_call(bgp_vrf_status_changed, bgp, ifp);
     254          10 :         bgp_nht_ifp_up(ifp);
     255             : 
     256          10 :         return 0;
     257             : }
     258             : 
     259          10 : static int bgp_ifp_down(struct interface *ifp)
     260             : {
     261          10 :         struct connected *c;
     262          10 :         struct nbr_connected *nc;
     263          10 :         struct listnode *node, *nnode;
     264          10 :         struct bgp *bgp;
     265          10 :         struct peer *peer;
     266             : 
     267          10 :         bgp = ifp->vrf->info;
     268             : 
     269          10 :         bgp_mac_del_mac_entry(ifp);
     270             : 
     271          10 :         if (BGP_DEBUG(zebra, ZEBRA))
     272           0 :                 zlog_debug("Rx Intf down VRF %u IF %s", ifp->vrf->vrf_id,
     273             :                            ifp->name);
     274             : 
     275          10 :         if (!bgp)
     276             :                 return 0;
     277             : 
     278          37 :         for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
     279          17 :                 bgp_connected_delete(bgp, c);
     280             : 
     281          20 :         for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
     282           0 :                 bgp_nbr_connected_delete(bgp, nc, 1);
     283             : 
     284             :         /* Fast external-failover */
     285          10 :         if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
     286             : 
     287          34 :                 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     288             :                         /* Take down directly connected peers. */
     289          14 :                         if ((peer->ttl != BGP_DEFAULT_TTL)
     290           0 :                             && (peer->gtsm_hops != BGP_GTSM_HOPS_CONNECTED))
     291           0 :                                 continue;
     292             : 
     293          14 :                         if (ifp == peer->nexthop.ifp) {
     294           0 :                                 BGP_EVENT_ADD(peer, BGP_Stop);
     295           0 :                                 peer->last_reset = PEER_DOWN_IF_DOWN;
     296             :                         }
     297             :                 }
     298             :         }
     299             : 
     300          10 :         hook_call(bgp_vrf_status_changed, bgp, ifp);
     301          10 :         bgp_nht_ifp_down(ifp);
     302             : 
     303          10 :         return 0;
     304             : }
     305             : 
     306          49 : static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)
     307             : {
     308          49 :         struct connected *ifc;
     309          49 :         struct bgp *bgp;
     310          49 :         struct peer *peer;
     311          49 :         struct prefix *addr;
     312          49 :         struct listnode *node, *nnode;
     313          49 :         afi_t afi;
     314          49 :         safi_t safi;
     315             : 
     316          49 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
     317             : 
     318          49 :         ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
     319             : 
     320          49 :         if (ifc == NULL)
     321             :                 return 0;
     322             : 
     323          49 :         if (bgp_debug_zebra(ifc->address))
     324           0 :                 zlog_debug("Rx Intf address add VRF %u IF %s addr %pFX", vrf_id,
     325             :                            ifc->ifp->name, ifc->address);
     326             : 
     327          49 :         if (!bgp)
     328             :                 return 0;
     329             : 
     330          49 :         if (if_is_operative(ifc->ifp)) {
     331          49 :                 bgp_connected_add(bgp, ifc);
     332             : 
     333             :                 /* If we have learnt of any neighbors on this interface,
     334             :                  * check to kick off any BGP interface-based neighbors,
     335             :                  * but only if this is a link-local address.
     336             :                  */
     337          49 :                 if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)
     338           5 :                     && !list_isempty(ifc->ifp->nbr_connected))
     339           0 :                         bgp_start_interface_nbrs(bgp, ifc->ifp);
     340             :                 else {
     341          49 :                         addr = ifc->address;
     342             : 
     343         165 :                         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     344          67 :                                 if (addr->family == AF_INET)
     345          31 :                                         continue;
     346             : 
     347             :                                 /*
     348             :                                  * If the Peer's interface name matches the
     349             :                                  * interface name for which BGP received the
     350             :                                  * update and if the received interface address
     351             :                                  * is a globalV6 and if the peer is currently
     352             :                                  * using a v4-mapped-v6 addr or a link local
     353             :                                  * address, then copy the Rxed global v6 addr
     354             :                                  * into peer's v6_global and send updates out
     355             :                                  * with new nexthop addr.
     356             :                                  */
     357          36 :                                 if ((peer->conf_if &&
     358           0 :                                      (strcmp(peer->conf_if, ifc->ifp->name) ==
     359           0 :                                       0)) &&
     360           0 :                                     !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) &&
     361           0 :                                     ((IS_MAPPED_IPV6(
     362           0 :                                              &peer->nexthop.v6_global)) ||
     363           0 :                                      IN6_IS_ADDR_LINKLOCAL(
     364             :                                              &peer->nexthop.v6_global))) {
     365             : 
     366           0 :                                         if (bgp_debug_zebra(ifc->address)) {
     367           0 :                                                 zlog_debug(
     368             :                                                         "Update peer %pBP's current intf addr %pI6 and send updates",
     369             :                                                         peer,
     370             :                                                         &peer->nexthop
     371             :                                                                  .v6_global);
     372             :                                         }
     373           0 :                                         memcpy(&peer->nexthop.v6_global,
     374             :                                                &addr->u.prefix6,
     375             :                                                IPV6_MAX_BYTELEN);
     376           0 :                                         FOREACH_AFI_SAFI (afi, safi)
     377           0 :                                                 bgp_announce_route(peer, afi,
     378             :                                                                    safi, true);
     379             :                                 }
     380             :                         }
     381             :                 }
     382             :         }
     383             : 
     384             :         return 0;
     385             : }
     386             : 
     387          10 : static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)
     388             : {
     389          10 :         struct listnode *node, *nnode;
     390          10 :         struct connected *ifc;
     391          10 :         struct peer *peer;
     392          10 :         struct bgp *bgp;
     393          10 :         struct prefix *addr;
     394             : 
     395          10 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
     396             : 
     397          10 :         ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
     398             : 
     399          10 :         if (ifc == NULL)
     400             :                 return 0;
     401             : 
     402          10 :         if (bgp_debug_zebra(ifc->address))
     403           0 :                 zlog_debug("Rx Intf address del VRF %u IF %s addr %pFX", vrf_id,
     404             :                            ifc->ifp->name, ifc->address);
     405             : 
     406          10 :         if (bgp && if_is_operative(ifc->ifp)) {
     407           0 :                 bgp_connected_delete(bgp, ifc);
     408             :         }
     409             : 
     410          10 :         addr = ifc->address;
     411             : 
     412          10 :         if (bgp) {
     413             :                 /*
     414             :                  * When we are using the v6 global as part of the peering
     415             :                  * nexthops and we are removing it, then we need to
     416             :                  * clear the peer data saved for that nexthop and
     417             :                  * cause a re-announcement of the route.  Since
     418             :                  * we do not want the peering to bounce.
     419             :                  */
     420          34 :                 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     421          14 :                         afi_t afi;
     422          14 :                         safi_t safi;
     423             : 
     424          14 :                         if (addr->family == AF_INET)
     425           7 :                                 continue;
     426             : 
     427           7 :                         if (!IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6)
     428           7 :                             && memcmp(&peer->nexthop.v6_global,
     429           7 :                                       &addr->u.prefix6, 16)
     430             :                                        == 0) {
     431           0 :                                 memset(&peer->nexthop.v6_global, 0, 16);
     432           0 :                                 FOREACH_AFI_SAFI (afi, safi)
     433           0 :                                         bgp_announce_route(peer, afi, safi,
     434             :                                                            true);
     435             :                         }
     436             :                 }
     437             :         }
     438             : 
     439          10 :         connected_free(&ifc);
     440             : 
     441          10 :         return 0;
     442             : }
     443             : 
     444           0 : static int bgp_interface_nbr_address_add(ZAPI_CALLBACK_ARGS)
     445             : {
     446           0 :         struct nbr_connected *ifc = NULL;
     447           0 :         struct bgp *bgp;
     448             : 
     449           0 :         ifc = zebra_interface_nbr_address_read(cmd, zclient->ibuf, vrf_id);
     450             : 
     451           0 :         if (ifc == NULL)
     452             :                 return 0;
     453             : 
     454           0 :         if (bgp_debug_zebra(ifc->address))
     455           0 :                 zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %pFX",
     456             :                            vrf_id, ifc->ifp->name, ifc->address);
     457             : 
     458           0 :         if (if_is_operative(ifc->ifp)) {
     459           0 :                 bgp = bgp_lookup_by_vrf_id(vrf_id);
     460           0 :                 if (bgp)
     461           0 :                         bgp_nbr_connected_add(bgp, ifc);
     462             :         }
     463             : 
     464             :         return 0;
     465             : }
     466             : 
     467           0 : static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS)
     468             : {
     469           0 :         struct nbr_connected *ifc = NULL;
     470           0 :         struct bgp *bgp;
     471             : 
     472           0 :         ifc = zebra_interface_nbr_address_read(cmd, zclient->ibuf, vrf_id);
     473             : 
     474           0 :         if (ifc == NULL)
     475             :                 return 0;
     476             : 
     477           0 :         if (bgp_debug_zebra(ifc->address))
     478           0 :                 zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %pFX",
     479             :                            vrf_id, ifc->ifp->name, ifc->address);
     480             : 
     481           0 :         if (if_is_operative(ifc->ifp)) {
     482           0 :                 bgp = bgp_lookup_by_vrf_id(vrf_id);
     483           0 :                 if (bgp)
     484           0 :                         bgp_nbr_connected_delete(bgp, ifc, 0);
     485             :         }
     486             : 
     487           0 :         nbr_connected_free(ifc);
     488             : 
     489           0 :         return 0;
     490             : }
     491             : 
     492             : /* VRF update for an interface. */
     493           0 : static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS)
     494             : {
     495           0 :         struct interface *ifp;
     496           0 :         vrf_id_t new_vrf_id;
     497           0 :         struct connected *c;
     498           0 :         struct nbr_connected *nc;
     499           0 :         struct listnode *node, *nnode;
     500           0 :         struct bgp *bgp;
     501           0 :         struct peer *peer;
     502             : 
     503           0 :         ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
     504             :                                               &new_vrf_id);
     505           0 :         if (!ifp)
     506             :                 return 0;
     507             : 
     508           0 :         if (BGP_DEBUG(zebra, ZEBRA))
     509           0 :                 zlog_debug("Rx Intf VRF change VRF %u IF %s NewVRF %u", vrf_id,
     510             :                            ifp->name, new_vrf_id);
     511             : 
     512           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
     513             : 
     514           0 :         if (bgp) {
     515           0 :                 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
     516           0 :                         bgp_connected_delete(bgp, c);
     517             : 
     518           0 :                 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
     519           0 :                         bgp_nbr_connected_delete(bgp, nc, 1);
     520             : 
     521             :                 /* Fast external-failover */
     522           0 :                 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
     523           0 :                         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     524           0 :                                 if ((peer->ttl != BGP_DEFAULT_TTL)
     525           0 :                                     && (peer->gtsm_hops
     526             :                                         != BGP_GTSM_HOPS_CONNECTED))
     527           0 :                                         continue;
     528             : 
     529           0 :                                 if (ifp == peer->nexthop.ifp)
     530           0 :                                         BGP_EVENT_ADD(peer, BGP_Stop);
     531             :                         }
     532             :                 }
     533             :         }
     534             : 
     535           0 :         if_update_to_new_vrf(ifp, new_vrf_id);
     536             : 
     537           0 :         bgp = bgp_lookup_by_vrf_id(new_vrf_id);
     538           0 :         if (!bgp)
     539             :                 return 0;
     540             : 
     541           0 :         for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
     542           0 :                 bgp_connected_add(bgp, c);
     543             : 
     544           0 :         for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
     545           0 :                 bgp_nbr_connected_add(bgp, nc);
     546             : 
     547           0 :         hook_call(bgp_vrf_status_changed, bgp, ifp);
     548           0 :         return 0;
     549             : }
     550             : 
     551             : /* Zebra route add and delete treatment. */
     552          10 : static int zebra_read_route(ZAPI_CALLBACK_ARGS)
     553             : {
     554          10 :         enum nexthop_types_t nhtype;
     555          10 :         enum blackhole_type bhtype = BLACKHOLE_UNSPEC;
     556          10 :         struct zapi_route api;
     557          10 :         union g_addr nexthop = {};
     558          10 :         ifindex_t ifindex;
     559          10 :         int add, i;
     560          10 :         struct bgp *bgp;
     561             : 
     562          10 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
     563          10 :         if (!bgp)
     564             :                 return 0;
     565             : 
     566          10 :         if (zapi_route_decode(zclient->ibuf, &api) < 0)
     567             :                 return -1;
     568             : 
     569             :         /* we completely ignore srcdest routes for now. */
     570          10 :         if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
     571             :                 return 0;
     572             : 
     573             :         /* ignore link-local address. */
     574          10 :         if (api.prefix.family == AF_INET6
     575           0 :             && IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
     576             :                 return 0;
     577             : 
     578          10 :         ifindex = api.nexthops[0].ifindex;
     579          10 :         nhtype = api.nexthops[0].type;
     580             : 
     581             :         /* api_nh structure has union of gate and bh_type */
     582          10 :         if (nhtype == NEXTHOP_TYPE_BLACKHOLE) {
     583             :                 /* bh_type is only applicable if NEXTHOP_TYPE_BLACKHOLE*/
     584           0 :                 bhtype = api.nexthops[0].bh_type;
     585             :         } else
     586          10 :                 nexthop = api.nexthops[0].gate;
     587             : 
     588          10 :         add = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
     589          10 :         if (add) {
     590             :                 /*
     591             :                  * The ADD message is actually an UPDATE and there is no
     592             :                  * explicit DEL
     593             :                  * for a prior redistributed route, if any. So, perform an
     594             :                  * implicit
     595             :                  * DEL processing for the same redistributed route from any
     596             :                  * other
     597             :                  * source type.
     598             :                  */
     599         192 :                 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
     600         186 :                         if (i != api.type)
     601         180 :                                 bgp_redistribute_delete(bgp, &api.prefix, i,
     602         180 :                                                         api.instance);
     603             :                 }
     604             : 
     605             :                 /* Now perform the add/update. */
     606           6 :                 bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
     607           6 :                                      nhtype, bhtype, api.distance, api.metric,
     608           6 :                                      api.type, api.instance, api.tag);
     609             :         } else {
     610           4 :                 bgp_redistribute_delete(bgp, &api.prefix, api.type,
     611           4 :                                         api.instance);
     612             :         }
     613             : 
     614          10 :         if (bgp_debug_zebra(&api.prefix)) {
     615           0 :                 char buf[PREFIX_STRLEN];
     616             : 
     617           0 :                 if (add) {
     618           0 :                         inet_ntop(api.prefix.family, &nexthop, buf,
     619             :                                   sizeof(buf));
     620           0 :                         zlog_debug(
     621             :                                 "Rx route ADD VRF %u %s[%d] %pFX nexthop %s (type %d if %u) metric %u distance %u tag %" ROUTE_TAG_PRI,
     622             :                                 vrf_id, zebra_route_string(api.type),
     623             :                                 api.instance, &api.prefix, buf, nhtype, ifindex,
     624             :                                 api.metric, api.distance, api.tag);
     625             :                 } else {
     626           0 :                         zlog_debug("Rx route DEL VRF %u %s[%d] %pFX", vrf_id,
     627             :                                    zebra_route_string(api.type), api.instance,
     628             :                                    &api.prefix);
     629             :                 }
     630             :         }
     631             : 
     632             :         return 0;
     633             : }
     634             : 
     635          12 : struct interface *if_lookup_by_ipv4(struct in_addr *addr, vrf_id_t vrf_id)
     636             : {
     637          12 :         struct vrf *vrf;
     638          12 :         struct listnode *cnode;
     639          12 :         struct interface *ifp;
     640          12 :         struct connected *connected;
     641          12 :         struct prefix_ipv4 p;
     642          12 :         struct prefix *cp;
     643             : 
     644          12 :         vrf = vrf_lookup_by_id(vrf_id);
     645          12 :         if (!vrf)
     646             :                 return NULL;
     647             : 
     648          12 :         p.family = AF_INET;
     649          12 :         p.prefix = *addr;
     650          12 :         p.prefixlen = IPV4_MAX_BITLEN;
     651             : 
     652          41 :         FOR_ALL_INTERFACES (vrf, ifp) {
     653          99 :                 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     654          53 :                         cp = connected->address;
     655             : 
     656          53 :                         if (cp->family == AF_INET)
     657          31 :                                 if (prefix_match(cp, (struct prefix *)&p))
     658          12 :                                         return ifp;
     659             :                 }
     660             :         }
     661             :         return NULL;
     662             : }
     663             : 
     664          16 : struct interface *if_lookup_by_ipv4_exact(struct in_addr *addr, vrf_id_t vrf_id)
     665             : {
     666          16 :         struct vrf *vrf;
     667          16 :         struct listnode *cnode;
     668          16 :         struct interface *ifp;
     669          16 :         struct connected *connected;
     670          16 :         struct prefix *cp;
     671             : 
     672          16 :         vrf = vrf_lookup_by_id(vrf_id);
     673          16 :         if (!vrf)
     674             :                 return NULL;
     675             : 
     676          49 :         FOR_ALL_INTERFACES (vrf, ifp) {
     677          99 :                 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     678          53 :                         cp = connected->address;
     679             : 
     680          53 :                         if (cp->family == AF_INET)
     681          31 :                                 if (IPV4_ADDR_SAME(&cp->u.prefix4, addr))
     682          12 :                                         return ifp;
     683             :                 }
     684             :         }
     685             :         return NULL;
     686             : }
     687             : 
     688           0 : struct interface *if_lookup_by_ipv6(struct in6_addr *addr, ifindex_t ifindex,
     689             :                                     vrf_id_t vrf_id)
     690             : {
     691           0 :         struct vrf *vrf;
     692           0 :         struct listnode *cnode;
     693           0 :         struct interface *ifp;
     694           0 :         struct connected *connected;
     695           0 :         struct prefix_ipv6 p;
     696           0 :         struct prefix *cp;
     697             : 
     698           0 :         vrf = vrf_lookup_by_id(vrf_id);
     699           0 :         if (!vrf)
     700             :                 return NULL;
     701             : 
     702           0 :         p.family = AF_INET6;
     703           0 :         p.prefix = *addr;
     704           0 :         p.prefixlen = IPV6_MAX_BITLEN;
     705             : 
     706           0 :         FOR_ALL_INTERFACES (vrf, ifp) {
     707           0 :                 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     708           0 :                         cp = connected->address;
     709             : 
     710           0 :                         if (cp->family == AF_INET6)
     711           0 :                                 if (prefix_match(cp, (struct prefix *)&p)) {
     712           0 :                                         if (IN6_IS_ADDR_LINKLOCAL(
     713             :                                                     &cp->u.prefix6)) {
     714           0 :                                                 if (ifindex == ifp->ifindex)
     715           0 :                                                         return ifp;
     716             :                                         } else
     717           0 :                                                 return ifp;
     718             :                                 }
     719             :                 }
     720             :         }
     721             :         return NULL;
     722             : }
     723             : 
     724           0 : struct interface *if_lookup_by_ipv6_exact(struct in6_addr *addr,
     725             :                                           ifindex_t ifindex, vrf_id_t vrf_id)
     726             : {
     727           0 :         struct vrf *vrf;
     728           0 :         struct listnode *cnode;
     729           0 :         struct interface *ifp;
     730           0 :         struct connected *connected;
     731           0 :         struct prefix *cp;
     732             : 
     733           0 :         vrf = vrf_lookup_by_id(vrf_id);
     734           0 :         if (!vrf)
     735             :                 return NULL;
     736             : 
     737           0 :         FOR_ALL_INTERFACES (vrf, ifp) {
     738           0 :                 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     739           0 :                         cp = connected->address;
     740             : 
     741           0 :                         if (cp->family == AF_INET6)
     742           0 :                                 if (IPV6_ADDR_SAME(&cp->u.prefix6, addr)) {
     743           0 :                                         if (IN6_IS_ADDR_LINKLOCAL(
     744             :                                                     &cp->u.prefix6)) {
     745           0 :                                                 if (ifindex == ifp->ifindex)
     746           0 :                                                         return ifp;
     747             :                                         } else
     748           0 :                                                 return ifp;
     749             :                                 }
     750             :                 }
     751             :         }
     752             :         return NULL;
     753             : }
     754             : 
     755          12 : static int if_get_ipv6_global(struct interface *ifp, struct in6_addr *addr)
     756             : {
     757          12 :         struct listnode *cnode;
     758          12 :         struct connected *connected;
     759          12 :         struct prefix *cp;
     760             : 
     761          36 :         for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     762          24 :                 cp = connected->address;
     763             : 
     764          24 :                 if (cp->family == AF_INET6)
     765          12 :                         if (!IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
     766          12 :                                 memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
     767          12 :                                 return 1;
     768             :                         }
     769             :         }
     770             :         return 0;
     771             : }
     772             : 
     773          12 : static bool if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
     774             : {
     775          12 :         struct listnode *cnode;
     776          12 :         struct connected *connected;
     777          12 :         struct prefix *cp;
     778             : 
     779          48 :         for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     780          36 :                 cp = connected->address;
     781             : 
     782          36 :                 if (cp->family == AF_INET6)
     783          24 :                         if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
     784          12 :                                 memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
     785          12 :                                 return true;
     786             :                         }
     787             :         }
     788             :         return false;
     789             : }
     790             : 
     791           0 : static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
     792             : {
     793           0 :         struct listnode *cnode;
     794           0 :         struct connected *connected;
     795           0 :         struct prefix *cp;
     796             : 
     797           0 :         for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
     798           0 :                 cp = connected->address;
     799           0 :                 if ((cp->family == AF_INET)
     800           0 :                     && !ipv4_martian(&(cp->u.prefix4))) {
     801           0 :                         *addr = cp->u.prefix4;
     802           0 :                         return 1;
     803             :                 }
     804             :         }
     805             :         return 0;
     806             : }
     807             : 
     808             : 
     809          12 : bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
     810             :                            struct bgp_nexthop *nexthop, struct peer *peer)
     811             : {
     812          12 :         int ret = 0;
     813          12 :         struct interface *ifp = NULL;
     814          12 :         bool v6_ll_avail = true;
     815             : 
     816          12 :         memset(nexthop, 0, sizeof(struct bgp_nexthop));
     817             : 
     818          12 :         if (!local)
     819             :                 return false;
     820          12 :         if (!remote)
     821             :                 return false;
     822             : 
     823          12 :         if (local->sa.sa_family == AF_INET) {
     824          12 :                 nexthop->v4 = local->sin.sin_addr;
     825          12 :                 if (peer->update_if)
     826           0 :                         ifp = if_lookup_by_name(peer->update_if,
     827           0 :                                                 peer->bgp->vrf_id);
     828             :                 else
     829          12 :                         ifp = if_lookup_by_ipv4_exact(&local->sin.sin_addr,
     830          12 :                                                       peer->bgp->vrf_id);
     831             :         }
     832          12 :         if (local->sa.sa_family == AF_INET6) {
     833           0 :                 memcpy(&nexthop->v6_global, &local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
     834           0 :                 if (IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)) {
     835           0 :                         if (peer->conf_if || peer->ifname)
     836           0 :                                 ifp = if_lookup_by_name(peer->conf_if
     837             :                                                                 ? peer->conf_if
     838             :                                                                 : peer->ifname,
     839           0 :                                                         peer->bgp->vrf_id);
     840           0 :                         else if (peer->update_if)
     841           0 :                                 ifp = if_lookup_by_name(peer->update_if,
     842           0 :                                                         peer->bgp->vrf_id);
     843           0 :                 } else if (peer->update_if)
     844           0 :                         ifp = if_lookup_by_name(peer->update_if,
     845           0 :                                                 peer->bgp->vrf_id);
     846             :                 else
     847           0 :                         ifp = if_lookup_by_ipv6_exact(&local->sin6.sin6_addr,
     848           0 :                                                       local->sin6.sin6_scope_id,
     849           0 :                                                       peer->bgp->vrf_id);
     850             :         }
     851             : 
     852          12 :         if (!ifp) {
     853             :                 /*
     854             :                  * BGP views do not currently get proper data
     855             :                  * from zebra( when attached ) to be able to
     856             :                  * properly resolve nexthops, so give this
     857             :                  * instance type a pass.
     858             :                  */
     859           0 :                 if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
     860             :                         return true;
     861             :                 /*
     862             :                  * If we have no interface data but we have established
     863             :                  * some connection w/ zebra than something has gone
     864             :                  * terribly terribly wrong here, so say this failed
     865             :                  * If we do not any zebra connection then not
     866             :                  * having a ifp pointer is ok.
     867             :                  */
     868           0 :                 return zclient_num_connects ? false : true;
     869             :         }
     870             : 
     871          12 :         nexthop->ifp = ifp;
     872             : 
     873             :         /* IPv4 connection, fetch and store IPv6 local address(es) if any. */
     874          12 :         if (local->sa.sa_family == AF_INET) {
     875             :                 /* IPv6 nexthop*/
     876          12 :                 ret = if_get_ipv6_global(ifp, &nexthop->v6_global);
     877             : 
     878          12 :                 if (!ret) {
     879             :                         /* There is no global nexthop. Use link-local address as
     880             :                          * both the
     881             :                          * global and link-local nexthop. In this scenario, the
     882             :                          * expectation
     883             :                          * for interop is that the network admin would use a
     884             :                          * route-map to
     885             :                          * specify the global IPv6 nexthop.
     886             :                          */
     887           0 :                         v6_ll_avail =
     888           0 :                                 if_get_ipv6_local(ifp, &nexthop->v6_global);
     889           0 :                         memcpy(&nexthop->v6_local, &nexthop->v6_global,
     890             :                                IPV6_MAX_BYTELEN);
     891             :                 } else
     892          12 :                         v6_ll_avail =
     893          12 :                                 if_get_ipv6_local(ifp, &nexthop->v6_local);
     894             : 
     895             :                 /*
     896             :                  * If we are a v4 connection and we are not doing unnumbered
     897             :                  * not having a v6 LL address is ok
     898             :                  */
     899          12 :                 if (!v6_ll_avail && !peer->conf_if)
     900          12 :                         v6_ll_avail = true;
     901          12 :                 if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id))
     902          12 :                         peer->shared_network = 1;
     903             :                 else
     904           0 :                         peer->shared_network = 0;
     905             :         }
     906             : 
     907             :         /* IPv6 connection, fetch and store IPv4 local address if any. */
     908          12 :         if (local->sa.sa_family == AF_INET6) {
     909           0 :                 struct interface *direct = NULL;
     910             : 
     911             :                 /* IPv4 nexthop. */
     912           0 :                 ret = if_get_ipv4_address(ifp, &nexthop->v4);
     913           0 :                 if (!ret && peer->local_id.s_addr != INADDR_ANY)
     914           0 :                         nexthop->v4 = peer->local_id;
     915             : 
     916             :                 /* Global address*/
     917           0 :                 if (!IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)) {
     918           0 :                         memcpy(&nexthop->v6_global, &local->sin6.sin6_addr,
     919             :                                IPV6_MAX_BYTELEN);
     920             : 
     921             :                         /* If directly connected set link-local address. */
     922           0 :                         direct = if_lookup_by_ipv6(&remote->sin6.sin6_addr,
     923           0 :                                                    remote->sin6.sin6_scope_id,
     924           0 :                                                    peer->bgp->vrf_id);
     925           0 :                         if (direct)
     926           0 :                                 v6_ll_avail = if_get_ipv6_local(
     927             :                                         ifp, &nexthop->v6_local);
     928             :                         /*
     929             :                          * It's fine to not have a v6 LL when using
     930             :                          * update-source loopback/vrf
     931             :                          */
     932           0 :                         if (!v6_ll_avail && if_is_loopback(ifp))
     933             :                                 v6_ll_avail = true;
     934           0 :                         else if (!v6_ll_avail) {
     935           0 :                                 flog_warn(
     936             :                                         EC_BGP_NO_LL_ADDRESS_AVAILABLE,
     937             :                                         "Interface: %s does not have a v6 LL address associated with it, waiting until one is created for it",
     938             :                                         ifp->name);
     939             :                         }
     940             :                 } else
     941             :                 /* Link-local address. */
     942             :                 {
     943           0 :                         ret = if_get_ipv6_global(ifp, &nexthop->v6_global);
     944             : 
     945             :                         /* If there is no global address.  Set link-local
     946             :                            address as
     947             :                            global.  I know this break RFC specification... */
     948             :                         /* In this scenario, the expectation for interop is that
     949             :                          * the
     950             :                          * network admin would use a route-map to specify the
     951             :                          * global
     952             :                          * IPv6 nexthop.
     953             :                          */
     954           0 :                         if (!ret)
     955           0 :                                 memcpy(&nexthop->v6_global,
     956             :                                        &local->sin6.sin6_addr,
     957             :                                        IPV6_MAX_BYTELEN);
     958             :                         /* Always set the link-local address */
     959           0 :                         memcpy(&nexthop->v6_local, &local->sin6.sin6_addr,
     960             :                                IPV6_MAX_BYTELEN);
     961             :                 }
     962             : 
     963           0 :                 if (IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)
     964           0 :                     || if_lookup_by_ipv6(&remote->sin6.sin6_addr,
     965           0 :                                          remote->sin6.sin6_scope_id,
     966           0 :                                          peer->bgp->vrf_id))
     967           0 :                         peer->shared_network = 1;
     968             :                 else
     969           0 :                         peer->shared_network = 0;
     970             :         }
     971             : 
     972             : /* KAME stack specific treatment.  */
     973             : #ifdef KAME
     974             :         if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_global)
     975             :             && IN6_LINKLOCAL_IFINDEX(nexthop->v6_global)) {
     976             :                 SET_IN6_LINKLOCAL_IFINDEX(nexthop->v6_global, 0);
     977             :         }
     978             :         if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_local)
     979             :             && IN6_LINKLOCAL_IFINDEX(nexthop->v6_local)) {
     980             :                 SET_IN6_LINKLOCAL_IFINDEX(nexthop->v6_local, 0);
     981             :         }
     982             : #endif /* KAME */
     983             : 
     984             :         /* If we have identified the local interface, there is no error for now.
     985             :          */
     986             :         return v6_ll_avail;
     987             : }
     988             : 
     989             : static struct in6_addr *
     990           0 : bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)
     991             : {
     992           0 :         struct in6_addr *nexthop = NULL;
     993             : 
     994             :         /* Only global address nexthop exists. */
     995           0 :         if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
     996           0 :             || path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) {
     997           0 :                 nexthop = &path->attr->mp_nexthop_global;
     998           0 :                 if (IN6_IS_ADDR_LINKLOCAL(nexthop))
     999           0 :                         *ifindex = path->attr->nh_ifindex;
    1000             :         }
    1001             : 
    1002             :         /* If both global and link-local address present. */
    1003           0 :         if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
    1004           0 :             || path->attr->mp_nexthop_len
    1005             :                        == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
    1006             :                 /* Check if route-map is set to prefer global over link-local */
    1007           0 :                 if (path->attr->mp_nexthop_prefer_global) {
    1008           0 :                         nexthop = &path->attr->mp_nexthop_global;
    1009           0 :                         if (IN6_IS_ADDR_LINKLOCAL(nexthop))
    1010           0 :                                 *ifindex = path->attr->nh_ifindex;
    1011             :                 } else {
    1012             :                         /* Workaround for Cisco's nexthop bug.  */
    1013           0 :                         if (IN6_IS_ADDR_UNSPECIFIED(
    1014             :                                     &path->attr->mp_nexthop_global)
    1015           0 :                             && path->peer->su_remote
    1016           0 :                             && path->peer->su_remote->sa.sa_family
    1017             :                                        == AF_INET6) {
    1018           0 :                                 nexthop =
    1019             :                                         &path->peer->su_remote->sin6.sin6_addr;
    1020           0 :                                 if (IN6_IS_ADDR_LINKLOCAL(nexthop))
    1021           0 :                                         *ifindex = path->peer->nexthop.ifp
    1022           0 :                                                            ->ifindex;
    1023             :                         } else {
    1024           0 :                                 nexthop = &path->attr->mp_nexthop_local;
    1025           0 :                                 if (IN6_IS_ADDR_LINKLOCAL(nexthop))
    1026           0 :                                         *ifindex = path->attr->nh_lla_ifindex;
    1027             :                         }
    1028             :                 }
    1029             :         }
    1030             : 
    1031           0 :         return nexthop;
    1032             : }
    1033             : 
    1034           0 : static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p,
    1035             :                                 struct bgp_path_info *path)
    1036             : {
    1037           0 :         route_map_result_t ret;
    1038             : 
    1039           0 :         ret = route_map_apply(map, p, path);
    1040           0 :         bgp_attr_flush(path->attr);
    1041             : 
    1042           0 :         if (ret != RMAP_DENYMATCH)
    1043             :                 return true;
    1044             : 
    1045           0 :         if (bgp_debug_zebra(p)) {
    1046           0 :                 if (p->family == AF_INET) {
    1047           0 :                         zlog_debug(
    1048             :                                 "Zebra rmap deny: IPv4 route %pFX nexthop %pI4",
    1049             :                                 p, &path->attr->nexthop);
    1050             :                 }
    1051           0 :                 if (p->family == AF_INET6) {
    1052           0 :                         ifindex_t ifindex;
    1053           0 :                         struct in6_addr *nexthop;
    1054             : 
    1055           0 :                         nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
    1056           0 :                         zlog_debug(
    1057             :                                 "Zebra rmap deny: IPv6 route %pFX nexthop %pI6",
    1058             :                                 p, nexthop);
    1059             :                 }
    1060             :         }
    1061             :         return false;
    1062             : }
    1063             : 
    1064             : static struct thread *bgp_tm_thread_connect;
    1065             : static bool bgp_tm_status_connected;
    1066             : static bool bgp_tm_chunk_obtained;
    1067             : #define BGP_FLOWSPEC_TABLE_CHUNK 100000
    1068             : static uint32_t bgp_tm_min, bgp_tm_max, bgp_tm_chunk_size;
    1069             : struct bgp *bgp_tm_bgp;
    1070             : 
    1071           0 : static void bgp_zebra_tm_connect(struct thread *t)
    1072             : {
    1073           0 :         struct zclient *zclient;
    1074           0 :         int delay = 10, ret = 0;
    1075             : 
    1076           0 :         zclient = THREAD_ARG(t);
    1077           0 :         if (bgp_tm_status_connected && zclient->sock > 0)
    1078             :                 delay = 60;
    1079             :         else {
    1080           0 :                 bgp_tm_status_connected = false;
    1081           0 :                 ret = tm_table_manager_connect(zclient);
    1082             :         }
    1083           0 :         if (ret < 0) {
    1084           0 :                 zlog_info("Error connecting to table manager!");
    1085           0 :                 bgp_tm_status_connected = false;
    1086             :         } else {
    1087           0 :                 if (!bgp_tm_status_connected)
    1088           0 :                         zlog_debug("Connecting to table manager. Success");
    1089           0 :                 bgp_tm_status_connected = true;
    1090           0 :                 if (!bgp_tm_chunk_obtained) {
    1091           0 :                         if (bgp_zebra_get_table_range(bgp_tm_chunk_size,
    1092             :                                                       &bgp_tm_min,
    1093             :                                                       &bgp_tm_max) >= 0) {
    1094           0 :                                 bgp_tm_chunk_obtained = true;
    1095             :                                 /* parse non installed entries */
    1096           0 :                                 bgp_zebra_announce_table(bgp_tm_bgp, AFI_IP, SAFI_FLOWSPEC);
    1097             :                         }
    1098             :                 }
    1099             :         }
    1100           0 :         thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
    1101             :                          &bgp_tm_thread_connect);
    1102           0 : }
    1103             : 
    1104           0 : bool bgp_zebra_tm_chunk_obtained(void)
    1105             : {
    1106           0 :         return bgp_tm_chunk_obtained;
    1107             : }
    1108             : 
    1109           0 : uint32_t bgp_zebra_tm_get_id(void)
    1110             : {
    1111           0 :         static int table_id;
    1112             : 
    1113           0 :         if (!bgp_tm_chunk_obtained)
    1114           0 :                 return ++table_id;
    1115           0 :         return bgp_tm_min++;
    1116             : }
    1117             : 
    1118           0 : void bgp_zebra_init_tm_connect(struct bgp *bgp)
    1119             : {
    1120           0 :         int delay = 1;
    1121             : 
    1122             :         /* if already set, do nothing
    1123             :          */
    1124           0 :         if (bgp_tm_thread_connect != NULL)
    1125             :                 return;
    1126           0 :         bgp_tm_status_connected = false;
    1127           0 :         bgp_tm_chunk_obtained = false;
    1128           0 :         bgp_tm_min = bgp_tm_max = 0;
    1129           0 :         bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK;
    1130           0 :         bgp_tm_bgp = bgp;
    1131           0 :         thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
    1132             :                          &bgp_tm_thread_connect);
    1133             : }
    1134             : 
    1135           0 : int bgp_zebra_get_table_range(uint32_t chunk_size,
    1136             :                               uint32_t *start, uint32_t *end)
    1137             : {
    1138           0 :         int ret;
    1139             : 
    1140           0 :         if (!bgp_tm_status_connected)
    1141             :                 return -1;
    1142           0 :         ret = tm_get_table_chunk(zclient, chunk_size, start, end);
    1143           0 :         if (ret < 0) {
    1144           0 :                 flog_err(EC_BGP_TABLE_CHUNK,
    1145             :                          "BGP: Error getting table chunk %u", chunk_size);
    1146           0 :                 return -1;
    1147             :         }
    1148           0 :         zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]",
    1149             :                  chunk_size, *start, *end);
    1150           0 :         return 0;
    1151             : }
    1152             : 
    1153           8 : static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
    1154             :                                             struct in_addr *nexthop,
    1155             :                                             struct attr *attr, bool is_evpn,
    1156             :                                             struct zapi_nexthop *api_nh)
    1157             : {
    1158           8 :         api_nh->gate.ipv4 = *nexthop;
    1159           8 :         api_nh->vrf_id = nh_bgp->vrf_id;
    1160             : 
    1161             :         /* Need to set fields appropriately for EVPN routes imported into
    1162             :          * a VRF (which are programmed as onlink on l3-vni SVI) as well as
    1163             :          * connected routes leaked into a VRF.
    1164             :          */
    1165           8 :         if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
    1166           0 :                 api_nh->type = attr->nh_type;
    1167           0 :                 api_nh->bh_type = attr->bh_type;
    1168           8 :         } else if (is_evpn) {
    1169             :                 /*
    1170             :                  * If the nexthop is EVPN overlay index gateway IP,
    1171             :                  * treat the nexthop as NEXTHOP_TYPE_IPV4
    1172             :                  * Else, mark the nexthop as onlink.
    1173             :                  */
    1174           0 :                 if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
    1175           0 :                         api_nh->type = NEXTHOP_TYPE_IPV4;
    1176             :                 else {
    1177           0 :                         api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
    1178           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
    1179           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
    1180           0 :                         api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
    1181             :                 }
    1182           8 :         } else if (nh_othervrf && api_nh->gate.ipv4.s_addr == INADDR_ANY) {
    1183           0 :                 api_nh->type = NEXTHOP_TYPE_IFINDEX;
    1184           0 :                 api_nh->ifindex = attr->nh_ifindex;
    1185             :         } else
    1186           8 :                 api_nh->type = NEXTHOP_TYPE_IPV4;
    1187             : 
    1188           8 :         return true;
    1189             : }
    1190             : 
    1191           0 : static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
    1192             :                                             struct in6_addr *nexthop,
    1193             :                                             ifindex_t ifindex,
    1194             :                                             struct bgp_path_info *pi,
    1195             :                                             struct bgp_path_info *best_pi,
    1196             :                                             bool is_evpn,
    1197             :                                             struct zapi_nexthop *api_nh)
    1198             : {
    1199           0 :         struct attr *attr;
    1200             : 
    1201           0 :         attr = pi->attr;
    1202           0 :         api_nh->vrf_id = nh_bgp->vrf_id;
    1203             : 
    1204           0 :         if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
    1205           0 :                 api_nh->type = attr->nh_type;
    1206           0 :                 api_nh->bh_type = attr->bh_type;
    1207           0 :         } else if (is_evpn) {
    1208             :                 /*
    1209             :                  * If the nexthop is EVPN overlay index gateway IP,
    1210             :                  * treat the nexthop as NEXTHOP_TYPE_IPV4
    1211             :                  * Else, mark the nexthop as onlink.
    1212             :                  */
    1213           0 :                 if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
    1214           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6;
    1215             :                 else {
    1216           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
    1217           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
    1218           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
    1219           0 :                         api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
    1220             :                 }
    1221           0 :         } else if (nh_othervrf) {
    1222           0 :                 if (IN6_IS_ADDR_UNSPECIFIED(nexthop)) {
    1223           0 :                         api_nh->type = NEXTHOP_TYPE_IFINDEX;
    1224           0 :                         api_nh->ifindex = attr->nh_ifindex;
    1225           0 :                 } else if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
    1226           0 :                         if (ifindex == 0)
    1227             :                                 return false;
    1228           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
    1229           0 :                         api_nh->ifindex = ifindex;
    1230             :                 } else {
    1231           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6;
    1232           0 :                         api_nh->ifindex = 0;
    1233             :                 }
    1234             :         } else {
    1235           0 :                 if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
    1236           0 :                         if (pi == best_pi
    1237           0 :                             && attr->mp_nexthop_len
    1238             :                                        == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
    1239           0 :                                 if (pi->peer->nexthop.ifp)
    1240           0 :                                         ifindex =
    1241             :                                                 pi->peer->nexthop.ifp->ifindex;
    1242           0 :                         if (!ifindex) {
    1243           0 :                                 if (pi->peer->conf_if)
    1244           0 :                                         ifindex = pi->peer->ifp->ifindex;
    1245           0 :                                 else if (pi->peer->ifname)
    1246           0 :                                         ifindex = ifname2ifindex(
    1247             :                                                 pi->peer->ifname,
    1248           0 :                                                 pi->peer->bgp->vrf_id);
    1249           0 :                                 else if (pi->peer->nexthop.ifp)
    1250           0 :                                         ifindex =
    1251             :                                                 pi->peer->nexthop.ifp->ifindex;
    1252             :                         }
    1253             : 
    1254           0 :                         if (ifindex == 0)
    1255             :                                 return false;
    1256           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
    1257           0 :                         api_nh->ifindex = ifindex;
    1258             :                 } else {
    1259           0 :                         api_nh->type = NEXTHOP_TYPE_IPV6;
    1260           0 :                         api_nh->ifindex = 0;
    1261             :                 }
    1262             :         }
    1263             :         /* api_nh structure has union of gate and bh_type */
    1264           0 :         if (nexthop && api_nh->type != NEXTHOP_TYPE_BLACKHOLE)
    1265           0 :                 api_nh->gate.ipv6 = *nexthop;
    1266             : 
    1267             :         return true;
    1268             : }
    1269             : 
    1270           0 : static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr,
    1271             :                                         uint64_t tot_bw, uint32_t *nh_weight)
    1272             : {
    1273           0 :         uint32_t bw;
    1274           0 :         uint64_t tmp;
    1275             : 
    1276           0 :         bw = attr->link_bw;
    1277             :         /* zero link-bandwidth and link-bandwidth not present are treated
    1278             :          * as the same situation.
    1279             :          */
    1280           0 :         if (!bw) {
    1281             :                 /* the only situations should be if we're either told
    1282             :                  * to skip or use default weight.
    1283             :                  */
    1284           0 :                 if (bgp->lb_handling == BGP_LINK_BW_SKIP_MISSING)
    1285             :                         return false;
    1286             :                 *nh_weight = BGP_ZEBRA_DEFAULT_NHOP_WEIGHT;
    1287             :         } else {
    1288           0 :                 tmp = (uint64_t)bw * 100;
    1289           0 :                 *nh_weight = ((uint32_t)(tmp / tot_bw));
    1290             :         }
    1291             : 
    1292             :         return true;
    1293             : }
    1294             : 
    1295           8 : void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
    1296             :                         struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
    1297             :                         safi_t safi)
    1298             : {
    1299           8 :         struct zapi_route api = { 0 };
    1300           8 :         struct zapi_nexthop *api_nh;
    1301           8 :         int nh_family;
    1302           8 :         unsigned int valid_nh_count = 0;
    1303           8 :         bool allow_recursion = false;
    1304           8 :         uint8_t distance;
    1305           8 :         struct peer *peer;
    1306           8 :         struct bgp_path_info *mpinfo;
    1307           8 :         struct bgp *bgp_orig;
    1308           8 :         uint32_t metric;
    1309           8 :         struct attr local_attr;
    1310           8 :         struct bgp_path_info local_info;
    1311           8 :         struct bgp_path_info *mpinfo_cp = &local_info;
    1312           8 :         route_tag_t tag;
    1313           8 :         mpls_label_t label;
    1314           8 :         struct bgp_sid_info *sid_info;
    1315           8 :         int nh_othervrf = 0;
    1316           8 :         bool nh_updated = false;
    1317           8 :         bool do_wt_ecmp;
    1318           8 :         uint64_t cum_bw = 0;
    1319           8 :         uint32_t nhg_id = 0;
    1320           8 :         bool is_add;
    1321           8 :         uint32_t ttl = 0;
    1322           8 :         uint32_t bos = 0;
    1323           8 :         uint32_t exp = 0;
    1324             : 
    1325             :         /* Don't try to install if we're not connected to Zebra or Zebra doesn't
    1326             :          * know of this instance.
    1327             :          */
    1328           8 :         if (!bgp_install_info_to_zebra(bgp))
    1329           0 :                 return;
    1330             : 
    1331           8 :         if (bgp->main_zebra_update_hold)
    1332             :                 return;
    1333             : 
    1334           8 :         if (safi == SAFI_FLOWSPEC) {
    1335           0 :                 bgp_pbr_update_entry(bgp, bgp_dest_get_prefix(dest), info, afi,
    1336             :                                      safi, true);
    1337           0 :                 return;
    1338             :         }
    1339             : 
    1340             :         /*
    1341             :          * vrf leaking support (will have only one nexthop)
    1342             :          */
    1343           8 :         if (info->extra && info->extra->bgp_orig)
    1344           8 :                 nh_othervrf = 1;
    1345             : 
    1346             :         /* Make Zebra API structure. */
    1347           8 :         api.vrf_id = bgp->vrf_id;
    1348           8 :         api.type = ZEBRA_ROUTE_BGP;
    1349           8 :         api.safi = safi;
    1350           8 :         api.prefix = *p;
    1351           8 :         SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
    1352             : 
    1353           8 :         peer = info->peer;
    1354             : 
    1355           8 :         if (info->type == ZEBRA_ROUTE_BGP
    1356           8 :             && info->sub_type == BGP_ROUTE_IMPORTED) {
    1357             : 
    1358             :                 /* Obtain peer from parent */
    1359           0 :                 if (info->extra && info->extra->parent)
    1360           0 :                         peer = ((struct bgp_path_info *)(info->extra->parent))
    1361             :                                        ->peer;
    1362             :         }
    1363             : 
    1364           8 :         tag = info->attr->tag;
    1365             : 
    1366           8 :         if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED
    1367           8 :             || info->sub_type == BGP_ROUTE_AGGREGATE) {
    1368           0 :                 SET_FLAG(api.flags, ZEBRA_FLAG_IBGP);
    1369           0 :                 SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
    1370             :         }
    1371             : 
    1372           8 :         if ((peer->sort == BGP_PEER_EBGP && peer->ttl != BGP_DEFAULT_TTL)
    1373           8 :             || CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
    1374           8 :             || CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
    1375             : 
    1376           0 :                 allow_recursion = true;
    1377             : 
    1378           8 :         if (info->attr->rmap_table_id) {
    1379           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
    1380           0 :                 api.tableid = info->attr->rmap_table_id;
    1381             :         }
    1382             : 
    1383           8 :         if (CHECK_FLAG(info->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
    1384           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_SRTE);
    1385             : 
    1386             :         /* Metric is currently based on the best-path only */
    1387           8 :         metric = info->attr->med;
    1388             : 
    1389             :         /* Determine if we're doing weighted ECMP or not */
    1390           8 :         do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info);
    1391           8 :         if (do_wt_ecmp)
    1392           0 :                 cum_bw = bgp_path_info_mpath_cumbw(info);
    1393             : 
    1394             :         /* EVPN MAC-IP routes are installed with a L3 NHG id */
    1395           8 :         if (bgp_evpn_path_es_use_nhg(bgp, info, &nhg_id)) {
    1396           0 :                 mpinfo = NULL;
    1397           0 :                 api.nhgid = nhg_id;
    1398           0 :                 if (nhg_id)
    1399           0 :                         SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
    1400             :         } else {
    1401             :                 mpinfo = info;
    1402             :         }
    1403             : 
    1404          16 :         for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
    1405           8 :                 uint32_t nh_weight;
    1406           8 :                 bool is_evpn;
    1407             : 
    1408           8 :                 if (valid_nh_count >= multipath_num)
    1409             :                         break;
    1410             : 
    1411           8 :                 *mpinfo_cp = *mpinfo;
    1412           8 :                 nh_weight = 0;
    1413             : 
    1414             :                 /* Get nexthop address-family */
    1415           8 :                 if (p->family == AF_INET &&
    1416           8 :                     !BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr))
    1417             :                         nh_family = AF_INET;
    1418           0 :                 else if (p->family == AF_INET6 ||
    1419           0 :                          (p->family == AF_INET &&
    1420           0 :                           BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr)))
    1421             :                         nh_family = AF_INET6;
    1422             :                 else
    1423           8 :                         continue;
    1424             : 
    1425             :                 /* If processing for weighted ECMP, determine the next hop's
    1426             :                  * weight. Based on user setting, we may skip the next hop
    1427             :                  * in some situations.
    1428             :                  */
    1429           8 :                 if (do_wt_ecmp) {
    1430           0 :                         if (!bgp_zebra_use_nhop_weighted(bgp, mpinfo->attr,
    1431             :                                                          cum_bw, &nh_weight))
    1432           0 :                                 continue;
    1433             :                 }
    1434           8 :                 api_nh = &api.nexthops[valid_nh_count];
    1435             : 
    1436           8 :                 if (CHECK_FLAG(info->attr->flag,
    1437             :                                ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
    1438           0 :                         api_nh->srte_color = info->attr->srte_color;
    1439             : 
    1440           8 :                 if (bgp_debug_zebra(&api.prefix)) {
    1441           0 :                         if (mpinfo->extra) {
    1442           0 :                                 zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d",
    1443             :                                            __func__, p,
    1444             :                                            bgp_is_valid_label(
    1445             :                                                    &mpinfo->extra->label[0]));
    1446             :                         } else {
    1447           0 :                                 zlog_debug(
    1448             :                                         "%s: p=%pFX, extra is NULL, no label",
    1449             :                                         __func__, p);
    1450             :                         }
    1451             :                 }
    1452             : 
    1453           8 :                 if (bgp->table_map[afi][safi].name) {
    1454             :                         /* Copy info and attributes, so the route-map
    1455             :                            apply doesn't modify the BGP route info. */
    1456           0 :                         local_attr = *mpinfo->attr;
    1457           0 :                         mpinfo_cp->attr = &local_attr;
    1458           0 :                         if (!bgp_table_map_apply(bgp->table_map[afi][safi].map,
    1459             :                                                  p, mpinfo_cp))
    1460           0 :                                 continue;
    1461             : 
    1462             :                         /* metric/tag is only allowed to be
    1463             :                          * overridden on 1st nexthop */
    1464           0 :                         if (mpinfo == info) {
    1465           0 :                                 metric = mpinfo_cp->attr->med;
    1466           0 :                                 tag = mpinfo_cp->attr->tag;
    1467             :                         }
    1468             :                 }
    1469             : 
    1470           8 :                 BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp);
    1471             : 
    1472           8 :                 if (nh_family == AF_INET) {
    1473           8 :                         is_evpn = is_route_parent_evpn(mpinfo);
    1474             : 
    1475           8 :                         nh_updated = update_ipv4nh_for_route_install(
    1476             :                                 nh_othervrf, bgp_orig,
    1477             :                                 &mpinfo_cp->attr->nexthop, mpinfo_cp->attr,
    1478             :                                 is_evpn, api_nh);
    1479             :                 } else {
    1480           0 :                         ifindex_t ifindex = IFINDEX_INTERNAL;
    1481           0 :                         struct in6_addr *nexthop;
    1482             : 
    1483           0 :                         nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
    1484             :                                                                 &ifindex);
    1485             : 
    1486           0 :                         is_evpn = is_route_parent_evpn(mpinfo);
    1487             : 
    1488           0 :                         if (!nexthop)
    1489           0 :                                 nh_updated = update_ipv4nh_for_route_install(
    1490             :                                         nh_othervrf, bgp_orig,
    1491             :                                         &mpinfo_cp->attr->nexthop,
    1492             :                                         mpinfo_cp->attr, is_evpn, api_nh);
    1493             :                         else
    1494           0 :                                 nh_updated = update_ipv6nh_for_route_install(
    1495             :                                         nh_othervrf, bgp_orig, nexthop, ifindex,
    1496             :                                         mpinfo, info, is_evpn, api_nh);
    1497             :                 }
    1498             : 
    1499             :                 /* Did we get proper nexthop info to update zebra? */
    1500           8 :                 if (!nh_updated)
    1501           0 :                         continue;
    1502             : 
    1503             :                 /* Allow recursion if it is a multipath group with both
    1504             :                  * eBGP and iBGP paths.
    1505             :                  */
    1506           8 :                 if (!allow_recursion
    1507           8 :                     && CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX)
    1508           0 :                     && (mpinfo->peer->sort == BGP_PEER_IBGP
    1509           0 :                         || mpinfo->peer->sort == BGP_PEER_CONFED))
    1510           8 :                         allow_recursion = true;
    1511             : 
    1512           8 :                 if (mpinfo->extra &&
    1513           0 :                     bgp_is_valid_label(&mpinfo->extra->label[0]) &&
    1514           0 :                     !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
    1515           0 :                         mpls_lse_decode(mpinfo->extra->label[0], &label, &ttl,
    1516             :                                         &exp, &bos);
    1517             : 
    1518           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
    1519             : 
    1520           0 :                         api_nh->label_num = 1;
    1521           0 :                         api_nh->labels[0] = label;
    1522             :                 }
    1523             : 
    1524           8 :                 if (is_evpn
    1525           0 :                     && mpinfo->attr->evpn_overlay.type
    1526             :                                != OVERLAY_INDEX_GATEWAY_IP)
    1527           0 :                         memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
    1528             :                                sizeof(struct ethaddr));
    1529             : 
    1530           8 :                 api_nh->weight = nh_weight;
    1531             : 
    1532           8 :                 if (mpinfo->extra &&
    1533           0 :                     bgp_is_valid_label(&mpinfo->extra->label[0]) &&
    1534           0 :                     !sid_zero(&mpinfo->extra->sid[0].sid) &&
    1535           0 :                     !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
    1536           0 :                         sid_info = &mpinfo->extra->sid[0];
    1537             : 
    1538           0 :                         memcpy(&api_nh->seg6_segs, &sid_info->sid,
    1539             :                                sizeof(api_nh->seg6_segs));
    1540             : 
    1541           0 :                         if (sid_info->transposition_len != 0) {
    1542           0 :                                 mpls_lse_decode(mpinfo->extra->label[0], &label,
    1543             :                                                 &ttl, &exp, &bos);
    1544             : 
    1545           0 :                                 if (label < MPLS_LABEL_UNRESERVED_MIN) {
    1546           0 :                                         if (bgp_debug_zebra(&api.prefix))
    1547           0 :                                                 zlog_debug(
    1548             :                                                         "skip invalid SRv6 routes: transposition scheme is used, but label is too small");
    1549           0 :                                         continue;
    1550             :                                 }
    1551             : 
    1552           0 :                                 transpose_sid(&api_nh->seg6_segs, label,
    1553           0 :                                               sid_info->transposition_offset,
    1554             :                                               sid_info->transposition_len);
    1555             :                         }
    1556             : 
    1557           0 :                         SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6);
    1558             :                 }
    1559             : 
    1560           8 :                 valid_nh_count++;
    1561             :         }
    1562             : 
    1563           8 :         is_add = (valid_nh_count || nhg_id) ? true : false;
    1564             : 
    1565           8 :         if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
    1566           0 :                 struct bgp_zebra_opaque bzo = {};
    1567           0 :                 const char *reason =
    1568           0 :                         bgp_path_selection_reason2str(dest->reason);
    1569             : 
    1570           0 :                 strlcpy(bzo.aspath, info->attr->aspath->str,
    1571             :                         sizeof(bzo.aspath));
    1572             : 
    1573           0 :                 if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
    1574           0 :                         strlcpy(bzo.community,
    1575           0 :                                 bgp_attr_get_community(info->attr)->str,
    1576             :                                 sizeof(bzo.community));
    1577             : 
    1578           0 :                 if (info->attr->flag
    1579           0 :                     & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
    1580           0 :                         strlcpy(bzo.lcommunity,
    1581           0 :                                 bgp_attr_get_lcommunity(info->attr)->str,
    1582             :                                 sizeof(bzo.lcommunity));
    1583             : 
    1584           0 :                 strlcpy(bzo.selection_reason, reason,
    1585             :                         sizeof(bzo.selection_reason));
    1586             : 
    1587           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
    1588           0 :                 api.opaque.length = MIN(sizeof(struct bgp_zebra_opaque),
    1589             :                                         ZAPI_MESSAGE_OPAQUE_LENGTH);
    1590           0 :                 memcpy(api.opaque.data, &bzo, api.opaque.length);
    1591             :         }
    1592             : 
    1593           8 :         if (allow_recursion)
    1594           0 :                 SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
    1595             : 
    1596             :         /*
    1597             :          * When we create an aggregate route we must also
    1598             :          * install a Null0 route in the RIB, so overwrite
    1599             :          * what was written into api with a blackhole route
    1600             :          */
    1601           8 :         if (info->sub_type == BGP_ROUTE_AGGREGATE)
    1602           0 :                 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
    1603             :         else
    1604           8 :                 api.nexthop_num = valid_nh_count;
    1605             : 
    1606           8 :         SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
    1607           8 :         api.metric = metric;
    1608             : 
    1609           8 :         if (tag) {
    1610           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
    1611           0 :                 api.tag = tag;
    1612             :         }
    1613             : 
    1614           8 :         distance = bgp_distance_apply(p, info, afi, safi, bgp);
    1615           8 :         if (distance) {
    1616           8 :                 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
    1617           8 :                 api.distance = distance;
    1618             :         }
    1619             : 
    1620           8 :         if (bgp_debug_zebra(p)) {
    1621           0 :                 char nh_buf[INET6_ADDRSTRLEN];
    1622           0 :                 char eth_buf[ETHER_ADDR_STRLEN + 7] = {'\0'};
    1623           0 :                 char buf1[ETHER_ADDR_STRLEN];
    1624           0 :                 char label_buf[20];
    1625           0 :                 char sid_buf[20];
    1626           0 :                 char segs_buf[256];
    1627           0 :                 int i;
    1628             : 
    1629           0 :                 zlog_debug(
    1630             :                         "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI
    1631             :                         " count %d nhg %d",
    1632             :                         is_add ? "add" : "delete", bgp->vrf_id, &api.prefix,
    1633             :                         api.metric, api.tag, api.nexthop_num, nhg_id);
    1634           0 :                 for (i = 0; i < api.nexthop_num; i++) {
    1635           0 :                         api_nh = &api.nexthops[i];
    1636             : 
    1637           0 :                         switch (api_nh->type) {
    1638           0 :                         case NEXTHOP_TYPE_IFINDEX:
    1639           0 :                                 nh_buf[0] = '\0';
    1640           0 :                                 break;
    1641           0 :                         case NEXTHOP_TYPE_IPV4:
    1642             :                         case NEXTHOP_TYPE_IPV4_IFINDEX:
    1643           0 :                                 nh_family = AF_INET;
    1644           0 :                                 inet_ntop(nh_family, &api_nh->gate, nh_buf,
    1645             :                                           sizeof(nh_buf));
    1646           0 :                                 break;
    1647           0 :                         case NEXTHOP_TYPE_IPV6:
    1648             :                         case NEXTHOP_TYPE_IPV6_IFINDEX:
    1649           0 :                                 nh_family = AF_INET6;
    1650           0 :                                 inet_ntop(nh_family, &api_nh->gate, nh_buf,
    1651             :                                           sizeof(nh_buf));
    1652           0 :                                 break;
    1653           0 :                         case NEXTHOP_TYPE_BLACKHOLE:
    1654           0 :                                 strlcpy(nh_buf, "blackhole", sizeof(nh_buf));
    1655           0 :                                 break;
    1656             :                         default:
    1657             :                                 /* Note: add new nexthop case */
    1658           0 :                                 assert(0);
    1659             :                                 break;
    1660             :                         }
    1661             : 
    1662           0 :                         label_buf[0] = '\0';
    1663           0 :                         eth_buf[0] = '\0';
    1664           0 :                         segs_buf[0] = '\0';
    1665           0 :                         if (CHECK_FLAG(api_nh->flags,
    1666             :                                        ZAPI_NEXTHOP_FLAG_LABEL) &&
    1667             :                             !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN))
    1668           0 :                                 snprintf(label_buf, sizeof(label_buf),
    1669             :                                         "label %u", api_nh->labels[0]);
    1670           0 :                         if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6) &&
    1671             :                             !CHECK_FLAG(api_nh->flags,
    1672             :                                         ZAPI_NEXTHOP_FLAG_EVPN)) {
    1673           0 :                                 inet_ntop(AF_INET6, &api_nh->seg6_segs,
    1674             :                                           sid_buf, sizeof(sid_buf));
    1675           0 :                                 snprintf(segs_buf, sizeof(segs_buf), "segs %s",
    1676             :                                          sid_buf);
    1677             :                         }
    1678           0 :                         if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN) &&
    1679           0 :                             !is_zero_mac(&api_nh->rmac))
    1680           0 :                                 snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
    1681             :                                          prefix_mac2str(&api_nh->rmac,
    1682             :                                                         buf1, sizeof(buf1)));
    1683           0 :                         zlog_debug("  nhop [%d]: %s if %u VRF %u wt %u %s %s %s",
    1684             :                                    i + 1, nh_buf, api_nh->ifindex,
    1685             :                                    api_nh->vrf_id, api_nh->weight,
    1686             :                                    label_buf, segs_buf, eth_buf);
    1687             :                 }
    1688             : 
    1689           0 :                 int recursion_flag = 0;
    1690             : 
    1691           0 :                 if (CHECK_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION))
    1692             :                         recursion_flag = 1;
    1693             : 
    1694           0 :                 zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)",
    1695             :                            __func__, p, (recursion_flag ? "" : "NOT "));
    1696             :         }
    1697           8 :         zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
    1698             :                            zclient, &api);
    1699             : }
    1700             : 
    1701             : /* Announce all routes of a table to zebra */
    1702           0 : void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
    1703             : {
    1704           0 :         struct bgp_dest *dest;
    1705           0 :         struct bgp_table *table;
    1706           0 :         struct bgp_path_info *pi;
    1707             : 
    1708             :         /* Don't try to install if we're not connected to Zebra or Zebra doesn't
    1709             :          * know of this instance.
    1710             :          */
    1711           0 :         if (!bgp_install_info_to_zebra(bgp))
    1712             :                 return;
    1713             : 
    1714           0 :         table = bgp->rib[afi][safi];
    1715           0 :         if (!table)
    1716             :                 return;
    1717             : 
    1718           0 :         for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
    1719           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
    1720           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
    1721             : 
    1722           0 :                             (pi->type == ZEBRA_ROUTE_BGP
    1723           0 :                              && (pi->sub_type == BGP_ROUTE_NORMAL
    1724           0 :                                  || pi->sub_type == BGP_ROUTE_IMPORTED)))
    1725             : 
    1726           0 :                                 bgp_zebra_announce(dest,
    1727             :                                                    bgp_dest_get_prefix(dest),
    1728             :                                                    pi, bgp, afi, safi);
    1729             : }
    1730             : 
    1731             : /* Announce routes of any bgp subtype of a table to zebra */
    1732           0 : void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi,
    1733             :                                            safi_t safi)
    1734             : {
    1735           0 :         struct bgp_dest *dest;
    1736           0 :         struct bgp_table *table;
    1737           0 :         struct bgp_path_info *pi;
    1738             : 
    1739           0 :         if (!bgp_install_info_to_zebra(bgp))
    1740             :                 return;
    1741             : 
    1742           0 :         table = bgp->rib[afi][safi];
    1743           0 :         if (!table)
    1744             :                 return;
    1745             : 
    1746           0 :         for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
    1747           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
    1748           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
    1749           0 :                             pi->type == ZEBRA_ROUTE_BGP)
    1750           0 :                                 bgp_zebra_announce(dest,
    1751             :                                                    bgp_dest_get_prefix(dest),
    1752             :                                                    pi, bgp, afi, safi);
    1753             : }
    1754             : 
    1755           8 : void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
    1756             :                         struct bgp *bgp, safi_t safi)
    1757             : {
    1758           8 :         struct zapi_route api;
    1759           8 :         struct peer *peer;
    1760             : 
    1761             :         /* Don't try to install if we're not connected to Zebra or Zebra doesn't
    1762             :          * know of this instance.
    1763             :          */
    1764           8 :         if (!bgp_install_info_to_zebra(bgp))
    1765           0 :                 return;
    1766             : 
    1767           8 :         if (safi == SAFI_FLOWSPEC) {
    1768           0 :                 peer = info->peer;
    1769           0 :                 bgp_pbr_update_entry(peer->bgp, p, info, AFI_IP, safi, false);
    1770           0 :                 return;
    1771             :         }
    1772             : 
    1773           8 :         memset(&api, 0, sizeof(api));
    1774           8 :         api.vrf_id = bgp->vrf_id;
    1775           8 :         api.type = ZEBRA_ROUTE_BGP;
    1776           8 :         api.safi = safi;
    1777           8 :         api.prefix = *p;
    1778             : 
    1779           8 :         if (info->attr->rmap_table_id) {
    1780           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
    1781           0 :                 api.tableid = info->attr->rmap_table_id;
    1782             :         }
    1783             : 
    1784           8 :         if (bgp_debug_zebra(p))
    1785           0 :                 zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id,
    1786             :                            &api.prefix);
    1787             : 
    1788           8 :         zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
    1789             : }
    1790             : 
    1791             : /* Withdraw all entries in a BGP instances RIB table from Zebra */
    1792           0 : void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t safi)
    1793             : {
    1794           0 :         struct bgp_dest *dest;
    1795           0 :         struct bgp_table *table;
    1796           0 :         struct bgp_path_info *pi;
    1797             : 
    1798           0 :         if (!bgp_install_info_to_zebra(bgp))
    1799             :                 return;
    1800             : 
    1801           0 :         table = bgp->rib[afi][safi];
    1802           0 :         if (!table)
    1803             :                 return;
    1804             : 
    1805           0 :         for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
    1806           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
    1807           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
    1808           0 :                             && (pi->type == ZEBRA_ROUTE_BGP))
    1809           0 :                                 bgp_zebra_withdraw(bgp_dest_get_prefix(dest),
    1810             :                                                    pi, bgp, safi);
    1811             :                 }
    1812             :         }
    1813             : }
    1814             : 
    1815         463 : struct bgp_redist *bgp_redist_lookup(struct bgp *bgp, afi_t afi, uint8_t type,
    1816             :                                      unsigned short instance)
    1817             : {
    1818         463 :         struct list *red_list;
    1819         463 :         struct listnode *node;
    1820         463 :         struct bgp_redist *red;
    1821             : 
    1822         463 :         red_list = bgp->redist[afi][type];
    1823         463 :         if (!red_list)
    1824             :                 return (NULL);
    1825             : 
    1826          13 :         for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
    1827          13 :                 if (red->instance == instance)
    1828          13 :                         return red;
    1829             : 
    1830             :         return NULL;
    1831             : }
    1832             : 
    1833           1 : struct bgp_redist *bgp_redist_add(struct bgp *bgp, afi_t afi, uint8_t type,
    1834             :                                   unsigned short instance)
    1835             : {
    1836           1 :         struct list *red_list;
    1837           1 :         struct bgp_redist *red;
    1838             : 
    1839           1 :         red = bgp_redist_lookup(bgp, afi, type, instance);
    1840           1 :         if (red)
    1841             :                 return red;
    1842             : 
    1843           1 :         if (!bgp->redist[afi][type])
    1844           1 :                 bgp->redist[afi][type] = list_new();
    1845             : 
    1846           1 :         red_list = bgp->redist[afi][type];
    1847           1 :         red = XCALLOC(MTYPE_BGP_REDIST, sizeof(struct bgp_redist));
    1848           1 :         red->instance = instance;
    1849             : 
    1850           1 :         listnode_add(red_list, red);
    1851             : 
    1852           1 :         return red;
    1853             : }
    1854             : 
    1855           1 : static void bgp_redist_del(struct bgp *bgp, afi_t afi, uint8_t type,
    1856             :                            unsigned short instance)
    1857             : {
    1858           1 :         struct bgp_redist *red;
    1859             : 
    1860           1 :         red = bgp_redist_lookup(bgp, afi, type, instance);
    1861             : 
    1862           1 :         if (red) {
    1863           1 :                 listnode_delete(bgp->redist[afi][type], red);
    1864           1 :                 XFREE(MTYPE_BGP_REDIST, red);
    1865           1 :                 if (!bgp->redist[afi][type]->count)
    1866           1 :                         list_delete(&bgp->redist[afi][type]);
    1867             :         }
    1868           1 : }
    1869             : 
    1870             : /* Other routes redistribution into BGP. */
    1871           1 : int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
    1872             :                          unsigned short instance, bool changed)
    1873             : {
    1874             :         /* If redistribute options are changed call
    1875             :          * bgp_redistribute_unreg() to reset the option and withdraw
    1876             :          * the routes
    1877             :          */
    1878           1 :         if (changed)
    1879           0 :                 bgp_redistribute_unreg(bgp, afi, type, instance);
    1880             : 
    1881             :         /* Return if already redistribute flag is set. */
    1882           1 :         if (instance) {
    1883           0 :                 if (redist_check_instance(&zclient->mi_redist[afi][type],
    1884             :                                           instance))
    1885             :                         return CMD_WARNING;
    1886             : 
    1887           0 :                 redist_add_instance(&zclient->mi_redist[afi][type], instance);
    1888             :         } else {
    1889           1 :                 if (vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
    1890             :                         return CMD_WARNING;
    1891             : 
    1892             : #ifdef ENABLE_BGP_VNC
    1893           1 :                 if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
    1894           0 :                         vnc_export_bgp_enable(
    1895             :                                 bgp, afi); /* only enables if mode bits cfg'd */
    1896             :                 }
    1897             : #endif
    1898             : 
    1899           1 :                 vrf_bitmap_set(zclient->redist[afi][type], bgp->vrf_id);
    1900             :         }
    1901             : 
    1902             :         /*
    1903             :          * Don't try to register if we're not connected to Zebra or Zebra
    1904             :          * doesn't know of this instance.
    1905             :          *
    1906             :          * When we come up later well resend if needed.
    1907             :          */
    1908           1 :         if (!bgp_install_info_to_zebra(bgp))
    1909             :                 return CMD_SUCCESS;
    1910             : 
    1911           1 :         if (BGP_DEBUG(zebra, ZEBRA))
    1912           0 :                 zlog_debug("Tx redistribute add VRF %u afi %d %s %d",
    1913             :                            bgp->vrf_id, afi, zebra_route_string(type),
    1914             :                            instance);
    1915             : 
    1916             :         /* Send distribute add message to zebra. */
    1917           1 :         zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
    1918             :                                 instance, bgp->vrf_id);
    1919             : 
    1920           1 :         return CMD_SUCCESS;
    1921             : }
    1922             : 
    1923           0 : int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type,
    1924             :                             unsigned short instance)
    1925             : {
    1926             :         /* Don't try to send if we're not connected to Zebra or Zebra doesn't
    1927             :          * know of this instance.
    1928             :          */
    1929           0 :         if (!bgp_install_info_to_zebra(bgp))
    1930             :                 return -1;
    1931             : 
    1932           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    1933           0 :                 zlog_debug("Tx redistribute del/add VRF %u afi %d %s %d",
    1934             :                            bgp->vrf_id, afi, zebra_route_string(type),
    1935             :                            instance);
    1936             : 
    1937             :         /* Send distribute add message to zebra. */
    1938           0 :         zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type,
    1939             :                                 instance, bgp->vrf_id);
    1940           0 :         zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
    1941             :                                 instance, bgp->vrf_id);
    1942             : 
    1943           0 :         return 0;
    1944             : }
    1945             : 
    1946             : /* Redistribute with route-map specification.  */
    1947           0 : bool bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
    1948             :                                struct route_map *route_map)
    1949             : {
    1950           0 :         if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
    1951             :                 return false;
    1952             : 
    1953           0 :         XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
    1954             :         /* Decrement the count for existing routemap and
    1955             :          * increment the count for new route map.
    1956             :          */
    1957           0 :         route_map_counter_decrement(red->rmap.map);
    1958           0 :         red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
    1959           0 :         red->rmap.map = route_map;
    1960           0 :         route_map_counter_increment(red->rmap.map);
    1961             : 
    1962           0 :         return true;
    1963             : }
    1964             : 
    1965             : /* Redistribute with metric specification.  */
    1966           0 : bool bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
    1967             :                                  afi_t afi, int type, uint32_t metric)
    1968             : {
    1969           0 :         struct bgp_dest *dest;
    1970           0 :         struct bgp_path_info *pi;
    1971             : 
    1972           0 :         if (red->redist_metric_flag && red->redist_metric == metric)
    1973             :                 return false;
    1974             : 
    1975           0 :         red->redist_metric_flag = 1;
    1976           0 :         red->redist_metric = metric;
    1977             : 
    1978           0 :         for (dest = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); dest;
    1979           0 :              dest = bgp_route_next(dest)) {
    1980           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
    1981           0 :                         if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
    1982           0 :                             && pi->type == type
    1983           0 :                             && pi->instance == red->instance) {
    1984           0 :                                 struct attr *old_attr;
    1985           0 :                                 struct attr new_attr;
    1986             : 
    1987           0 :                                 new_attr = *pi->attr;
    1988           0 :                                 new_attr.med = red->redist_metric;
    1989           0 :                                 old_attr = pi->attr;
    1990           0 :                                 pi->attr = bgp_attr_intern(&new_attr);
    1991           0 :                                 bgp_attr_unintern(&old_attr);
    1992             : 
    1993           0 :                                 bgp_path_info_set_flag(dest, pi,
    1994             :                                                        BGP_PATH_ATTR_CHANGED);
    1995           0 :                                 bgp_process(bgp, dest, afi, SAFI_UNICAST);
    1996             :                         }
    1997             :                 }
    1998             :         }
    1999             : 
    2000             :         return true;
    2001             : }
    2002             : 
    2003             : /* Unset redistribution.  */
    2004           1 : int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
    2005             :                            unsigned short instance)
    2006             : {
    2007           1 :         struct bgp_redist *red;
    2008             : 
    2009           1 :         red = bgp_redist_lookup(bgp, afi, type, instance);
    2010           1 :         if (!red)
    2011             :                 return CMD_SUCCESS;
    2012             : 
    2013             :         /* Return if zebra connection is disabled. */
    2014           1 :         if (instance) {
    2015           0 :                 if (!redist_check_instance(&zclient->mi_redist[afi][type],
    2016             :                                            instance))
    2017             :                         return CMD_WARNING;
    2018           0 :                 redist_del_instance(&zclient->mi_redist[afi][type], instance);
    2019             :         } else {
    2020           1 :                 if (!vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
    2021             :                         return CMD_WARNING;
    2022           1 :                 vrf_bitmap_unset(zclient->redist[afi][type], bgp->vrf_id);
    2023             :         }
    2024             : 
    2025           1 :         if (bgp_install_info_to_zebra(bgp)) {
    2026             :                 /* Send distribute delete message to zebra. */
    2027           1 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2028           0 :                         zlog_debug("Tx redistribute del VRF %u afi %d %s %d",
    2029             :                                    bgp->vrf_id, afi, zebra_route_string(type),
    2030             :                                    instance);
    2031           1 :                 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
    2032             :                                         type, instance, bgp->vrf_id);
    2033             :         }
    2034             : 
    2035             :         /* Withdraw redistributed routes from current BGP's routing table. */
    2036           1 :         bgp_redistribute_withdraw(bgp, afi, type, instance);
    2037             : 
    2038           1 :         return CMD_SUCCESS;
    2039             : }
    2040             : 
    2041             : /* Unset redistribution.  */
    2042         270 : int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type,
    2043             :                            unsigned short instance)
    2044             : {
    2045         270 :         struct bgp_redist *red;
    2046             : 
    2047             : /*
    2048             :  * vnc and vpn->vrf checks must be before red check because
    2049             :  * they operate within bgpd irrespective of zebra connection
    2050             :  * status. red lookup fails if there is no zebra connection.
    2051             :  */
    2052             : #ifdef ENABLE_BGP_VNC
    2053         270 :         if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
    2054           0 :                 vnc_export_bgp_disable(bgp, afi);
    2055             :         }
    2056             : #endif
    2057             : 
    2058         270 :         red = bgp_redist_lookup(bgp, afi, type, instance);
    2059         270 :         if (!red)
    2060             :                 return CMD_SUCCESS;
    2061             : 
    2062           1 :         bgp_redistribute_unreg(bgp, afi, type, instance);
    2063             : 
    2064             :         /* Unset route-map. */
    2065           1 :         XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
    2066           1 :         route_map_counter_decrement(red->rmap.map);
    2067           1 :         red->rmap.map = NULL;
    2068             : 
    2069             :         /* Unset metric. */
    2070           1 :         red->redist_metric_flag = 0;
    2071           1 :         red->redist_metric = 0;
    2072             : 
    2073           1 :         bgp_redist_del(bgp, afi, type, instance);
    2074             : 
    2075           1 :         return CMD_SUCCESS;
    2076             : }
    2077             : 
    2078           0 : void bgp_redistribute_redo(struct bgp *bgp)
    2079             : {
    2080           0 :         afi_t afi;
    2081           0 :         int i;
    2082           0 :         struct list *red_list;
    2083           0 :         struct listnode *node;
    2084           0 :         struct bgp_redist *red;
    2085             : 
    2086           0 :         for (afi = AFI_IP; afi < AFI_MAX; afi++) {
    2087           0 :                 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
    2088             : 
    2089           0 :                         red_list = bgp->redist[afi][i];
    2090           0 :                         if (!red_list)
    2091           0 :                                 continue;
    2092             : 
    2093           0 :                         for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
    2094           0 :                                 bgp_redistribute_resend(bgp, afi, i,
    2095           0 :                                                         red->instance);
    2096             :                         }
    2097             :                 }
    2098             :         }
    2099           0 : }
    2100             : 
    2101           0 : void bgp_zclient_reset(void)
    2102             : {
    2103           0 :         zclient_reset(zclient);
    2104           0 : }
    2105             : 
    2106             : /* Register this instance with Zebra. Invoked upon connect (for
    2107             :  * default instance) and when other VRFs are learnt (or created and
    2108             :  * already learnt).
    2109             :  */
    2110           3 : void bgp_zebra_instance_register(struct bgp *bgp)
    2111             : {
    2112             :         /* Don't try to register if we're not connected to Zebra */
    2113           3 :         if (!zclient || zclient->sock < 0)
    2114             :                 return;
    2115             : 
    2116           3 :         if (BGP_DEBUG(zebra, ZEBRA))
    2117           0 :                 zlog_debug("Registering VRF %u", bgp->vrf_id);
    2118             : 
    2119             :         /* Register for router-id, interfaces, redistributed routes. */
    2120           3 :         zclient_send_reg_requests(zclient, bgp->vrf_id);
    2121             : 
    2122             :         /* For EVPN instance, register to learn about VNIs, if appropriate. */
    2123           3 :         if (bgp->advertise_all_vni)
    2124           0 :                 bgp_zebra_advertise_all_vni(bgp, 1);
    2125             : 
    2126           3 :         bgp_nht_register_nexthops(bgp);
    2127             : }
    2128             : 
    2129             : /* Deregister this instance with Zebra. Invoked upon the instance
    2130             :  * being deleted (default or VRF) and it is already registered.
    2131             :  */
    2132           3 : void bgp_zebra_instance_deregister(struct bgp *bgp)
    2133             : {
    2134             :         /* Don't try to deregister if we're not connected to Zebra */
    2135           3 :         if (zclient->sock < 0)
    2136             :                 return;
    2137             : 
    2138           3 :         if (BGP_DEBUG(zebra, ZEBRA))
    2139           0 :                 zlog_debug("Deregistering VRF %u", bgp->vrf_id);
    2140             : 
    2141             :         /* For EVPN instance, unregister learning about VNIs, if appropriate. */
    2142           3 :         if (bgp->advertise_all_vni)
    2143           0 :                 bgp_zebra_advertise_all_vni(bgp, 0);
    2144             : 
    2145             :         /* Deregister for router-id, interfaces, redistributed routes. */
    2146           3 :         zclient_send_dereg_requests(zclient, bgp->vrf_id);
    2147             : }
    2148             : 
    2149           0 : void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
    2150             : {
    2151           0 :         uint32_t ra_interval = BGP_UNNUM_DEFAULT_RA_INTERVAL;
    2152             : 
    2153             :         /* Don't try to initiate if we're not connected to Zebra */
    2154           0 :         if (zclient->sock < 0)
    2155             :                 return;
    2156             : 
    2157           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    2158           0 :                 zlog_debug("%u: Initiating RA for peer %s", bgp->vrf_id,
    2159             :                            peer->host);
    2160             : 
    2161             :         /*
    2162             :          * If unnumbered peer (peer->ifp) call thru zapi to start RAs.
    2163             :          * If we don't have an ifp pointer, call function to find the
    2164             :          * ifps for a numbered enhe peer to turn RAs on.
    2165             :          */
    2166           0 :         peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
    2167             :                                                     peer->ifp, 1, ra_interval)
    2168           0 :                   : bgp_nht_reg_enhe_cap_intfs(peer);
    2169             : }
    2170             : 
    2171           0 : void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
    2172             : {
    2173             :         /* Don't try to terminate if we're not connected to Zebra */
    2174           0 :         if (zclient->sock < 0)
    2175             :                 return;
    2176             : 
    2177           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    2178           0 :                 zlog_debug("%u: Terminating RA for peer %s", bgp->vrf_id,
    2179             :                            peer->host);
    2180             : 
    2181             :         /*
    2182             :          * If unnumbered peer (peer->ifp) call thru zapi to stop RAs.
    2183             :          * If we don't have an ifp pointer, call function to find the
    2184             :          * ifps for a numbered enhe peer to turn RAs off.
    2185             :          */
    2186           0 :         peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
    2187             :                                                     peer->ifp, 0, 0)
    2188           0 :                   : bgp_nht_dereg_enhe_cap_intfs(peer);
    2189             : }
    2190             : 
    2191           0 : int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
    2192             : {
    2193           0 :         struct stream *s = NULL;
    2194             : 
    2195             :         /* Check socket. */
    2196           0 :         if (!zclient || zclient->sock < 0)
    2197             :                 return 0;
    2198             : 
    2199             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2200           0 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
    2201           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2202           0 :                         zlog_debug(
    2203             :                                 "%s: No zebra instance to talk to, cannot advertise subnet",
    2204             :                                 __func__);
    2205           0 :                 return 0;
    2206             :         }
    2207             : 
    2208           0 :         s = zclient->obuf;
    2209           0 :         stream_reset(s);
    2210             : 
    2211           0 :         zclient_create_header(s, ZEBRA_ADVERTISE_SUBNET, bgp->vrf_id);
    2212           0 :         stream_putc(s, advertise);
    2213           0 :         stream_put3(s, vni);
    2214           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    2215             : 
    2216           0 :         return zclient_send_message(zclient);
    2217             : }
    2218             : 
    2219           0 : int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni)
    2220             : {
    2221           0 :         struct stream *s = NULL;
    2222             : 
    2223             :         /* Check socket. */
    2224           0 :         if (!zclient || zclient->sock < 0)
    2225             :                 return 0;
    2226             : 
    2227             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2228           0 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
    2229             :                 return 0;
    2230             : 
    2231           0 :         s = zclient->obuf;
    2232           0 :         stream_reset(s);
    2233             : 
    2234           0 :         zclient_create_header(s, ZEBRA_ADVERTISE_SVI_MACIP, bgp->vrf_id);
    2235           0 :         stream_putc(s, advertise);
    2236           0 :         stream_putl(s, vni);
    2237           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    2238             : 
    2239           0 :         return zclient_send_message(zclient);
    2240             : }
    2241             : 
    2242           0 : int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
    2243             : {
    2244           0 :         struct stream *s = NULL;
    2245             : 
    2246             :         /* Check socket. */
    2247           0 :         if (!zclient || zclient->sock < 0)
    2248             :                 return 0;
    2249             : 
    2250             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2251           0 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
    2252           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2253           0 :                         zlog_debug(
    2254             :                                 "%s: No zebra instance to talk to, not installing gw_macip",
    2255             :                                 __func__);
    2256           0 :                 return 0;
    2257             :         }
    2258             : 
    2259           0 :         s = zclient->obuf;
    2260           0 :         stream_reset(s);
    2261             : 
    2262           0 :         zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id);
    2263           0 :         stream_putc(s, advertise);
    2264           0 :         stream_putl(s, vni);
    2265           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    2266             : 
    2267           0 :         return zclient_send_message(zclient);
    2268             : }
    2269             : 
    2270           0 : int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
    2271             :                                   enum vxlan_flood_control flood_ctrl)
    2272             : {
    2273           0 :         struct stream *s;
    2274             : 
    2275             :         /* Check socket. */
    2276           0 :         if (!zclient || zclient->sock < 0)
    2277             :                 return 0;
    2278             : 
    2279             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2280           0 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
    2281           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2282           0 :                         zlog_debug(
    2283             :                                 "%s: No zebra instance to talk to, not installing all vni",
    2284             :                                 __func__);
    2285           0 :                 return 0;
    2286             :         }
    2287             : 
    2288           0 :         s = zclient->obuf;
    2289           0 :         stream_reset(s);
    2290             : 
    2291           0 :         zclient_create_header(s, ZEBRA_VXLAN_FLOOD_CONTROL, bgp->vrf_id);
    2292           0 :         stream_putc(s, flood_ctrl);
    2293           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    2294             : 
    2295           0 :         return zclient_send_message(zclient);
    2296             : }
    2297             : 
    2298           0 : int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
    2299             : {
    2300           0 :         struct stream *s;
    2301             : 
    2302             :         /* Check socket. */
    2303           0 :         if (!zclient || zclient->sock < 0)
    2304             :                 return 0;
    2305             : 
    2306             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2307           0 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
    2308             :                 return 0;
    2309             : 
    2310           0 :         s = zclient->obuf;
    2311           0 :         stream_reset(s);
    2312             : 
    2313           0 :         zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
    2314           0 :         stream_putc(s, advertise);
    2315             :         /* Also inform current BUM handling setting. This is really
    2316             :          * relevant only when 'advertise' is set.
    2317             :          */
    2318           0 :         stream_putc(s, bgp->vxlan_flood_ctrl);
    2319           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    2320             : 
    2321           0 :         return zclient_send_message(zclient);
    2322             : }
    2323             : 
    2324           3 : int bgp_zebra_dup_addr_detection(struct bgp *bgp)
    2325             : {
    2326           3 :         struct stream *s;
    2327             : 
    2328             :         /* Check socket. */
    2329           3 :         if (!zclient || zclient->sock < 0)
    2330             :                 return 0;
    2331             : 
    2332             :         /* Don't try to register if Zebra doesn't know of this instance. */
    2333           3 :         if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
    2334             :                 return 0;
    2335             : 
    2336           3 :         if (BGP_DEBUG(zebra, ZEBRA))
    2337           0 :                 zlog_debug("dup addr detect %s max_moves %u time %u freeze %s freeze_time %u",
    2338             :                            bgp->evpn_info->dup_addr_detect ?
    2339             :                            "enable" : "disable",
    2340             :                            bgp->evpn_info->dad_max_moves,
    2341             :                            bgp->evpn_info->dad_time,
    2342             :                            bgp->evpn_info->dad_freeze ?
    2343             :                            "enable" : "disable",
    2344             :                            bgp->evpn_info->dad_freeze_time);
    2345             : 
    2346           3 :         s = zclient->obuf;
    2347           3 :         stream_reset(s);
    2348           3 :         zclient_create_header(s, ZEBRA_DUPLICATE_ADDR_DETECTION,
    2349             :                               bgp->vrf_id);
    2350           3 :         stream_putl(s, bgp->evpn_info->dup_addr_detect);
    2351           3 :         stream_putl(s, bgp->evpn_info->dad_time);
    2352           3 :         stream_putl(s, bgp->evpn_info->dad_max_moves);
    2353           3 :         stream_putl(s, bgp->evpn_info->dad_freeze);
    2354           3 :         stream_putl(s, bgp->evpn_info->dad_freeze_time);
    2355           3 :         stream_putw_at(s, 0, stream_get_endp(s));
    2356             : 
    2357           3 :         return zclient_send_message(zclient);
    2358             : }
    2359             : 
    2360           0 : static int rule_notify_owner(ZAPI_CALLBACK_ARGS)
    2361             : {
    2362           0 :         uint32_t seqno, priority, unique;
    2363           0 :         enum zapi_rule_notify_owner note;
    2364           0 :         struct bgp_pbr_action *bgp_pbra;
    2365           0 :         struct bgp_pbr_rule *bgp_pbr = NULL;
    2366           0 :         char ifname[INTERFACE_NAMSIZ + 1];
    2367             : 
    2368           0 :         if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique,
    2369             :                                      ifname, &note))
    2370             :                 return -1;
    2371             : 
    2372           0 :         bgp_pbra = bgp_pbr_action_rule_lookup(vrf_id, unique);
    2373           0 :         if (!bgp_pbra) {
    2374             :                 /* look in bgp pbr rule */
    2375           0 :                 bgp_pbr = bgp_pbr_rule_lookup(vrf_id, unique);
    2376           0 :                 if (!bgp_pbr && note != ZAPI_RULE_REMOVED) {
    2377           0 :                         if (BGP_DEBUG(zebra, ZEBRA))
    2378           0 :                                 zlog_debug("%s: Fail to look BGP rule (%u)",
    2379             :                                            __func__, unique);
    2380           0 :                         return 0;
    2381             :                 }
    2382             :         }
    2383             : 
    2384           0 :         switch (note) {
    2385           0 :         case ZAPI_RULE_FAIL_INSTALL:
    2386           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2387           0 :                         zlog_debug("%s: Received RULE_FAIL_INSTALL", __func__);
    2388           0 :                 if (bgp_pbra) {
    2389           0 :                         bgp_pbra->installed = false;
    2390           0 :                         bgp_pbra->install_in_progress = false;
    2391             :                 } else {
    2392           0 :                         bgp_pbr->installed = false;
    2393           0 :                         bgp_pbr->install_in_progress = false;
    2394             :                 }
    2395             :                 break;
    2396           0 :         case ZAPI_RULE_INSTALLED:
    2397           0 :                 if (bgp_pbra) {
    2398           0 :                         bgp_pbra->installed = true;
    2399           0 :                         bgp_pbra->install_in_progress = false;
    2400             :                 } else {
    2401           0 :                         struct bgp_path_info *path;
    2402           0 :                         struct bgp_path_info_extra *extra;
    2403             : 
    2404           0 :                         bgp_pbr->installed = true;
    2405           0 :                         bgp_pbr->install_in_progress = false;
    2406           0 :                         bgp_pbr->action->refcnt++;
    2407             :                         /* link bgp_info to bgp_pbr */
    2408           0 :                         path = (struct bgp_path_info *)bgp_pbr->path;
    2409           0 :                         extra = bgp_path_info_extra_get(path);
    2410           0 :                         listnode_add_force(&extra->bgp_fs_iprule,
    2411             :                                            bgp_pbr);
    2412             :                 }
    2413           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2414           0 :                         zlog_debug("%s: Received RULE_INSTALLED", __func__);
    2415             :                 break;
    2416           0 :         case ZAPI_RULE_FAIL_REMOVE:
    2417             :         case ZAPI_RULE_REMOVED:
    2418           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2419           0 :                         zlog_debug("%s: Received RULE REMOVED", __func__);
    2420             :                 break;
    2421             :         }
    2422             : 
    2423             :         return 0;
    2424             : }
    2425             : 
    2426           0 : static int ipset_notify_owner(ZAPI_CALLBACK_ARGS)
    2427             : {
    2428           0 :         uint32_t unique;
    2429           0 :         enum zapi_ipset_notify_owner note;
    2430           0 :         struct bgp_pbr_match *bgp_pbim;
    2431             : 
    2432           0 :         if (!zapi_ipset_notify_decode(zclient->ibuf,
    2433             :                                       &unique,
    2434             :                                       &note))
    2435             :                 return -1;
    2436             : 
    2437           0 :         bgp_pbim = bgp_pbr_match_ipset_lookup(vrf_id, unique);
    2438           0 :         if (!bgp_pbim) {
    2439           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2440           0 :                         zlog_debug("%s: Fail to look BGP match ( %u, ID %u)",
    2441             :                                    __func__, note, unique);
    2442           0 :                 return 0;
    2443             :         }
    2444             : 
    2445           0 :         switch (note) {
    2446           0 :         case ZAPI_IPSET_FAIL_INSTALL:
    2447           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2448           0 :                         zlog_debug("%s: Received IPSET_FAIL_INSTALL", __func__);
    2449           0 :                 bgp_pbim->installed = false;
    2450           0 :                 bgp_pbim->install_in_progress = false;
    2451           0 :                 break;
    2452           0 :         case ZAPI_IPSET_INSTALLED:
    2453           0 :                 bgp_pbim->installed = true;
    2454           0 :                 bgp_pbim->install_in_progress = false;
    2455           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2456           0 :                         zlog_debug("%s: Received IPSET_INSTALLED", __func__);
    2457             :                 break;
    2458           0 :         case ZAPI_IPSET_FAIL_REMOVE:
    2459             :         case ZAPI_IPSET_REMOVED:
    2460           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2461           0 :                         zlog_debug("%s: Received IPSET REMOVED", __func__);
    2462             :                 break;
    2463             :         }
    2464             : 
    2465             :         return 0;
    2466             : }
    2467             : 
    2468           0 : static int ipset_entry_notify_owner(ZAPI_CALLBACK_ARGS)
    2469             : {
    2470           0 :         uint32_t unique;
    2471           0 :         char ipset_name[ZEBRA_IPSET_NAME_SIZE];
    2472           0 :         enum zapi_ipset_entry_notify_owner note;
    2473           0 :         struct bgp_pbr_match_entry *bgp_pbime;
    2474             : 
    2475           0 :         if (!zapi_ipset_entry_notify_decode(
    2476             :                                 zclient->ibuf,
    2477             :                                 &unique,
    2478             :                                 ipset_name,
    2479             :                                 &note))
    2480             :                 return -1;
    2481           0 :         bgp_pbime = bgp_pbr_match_ipset_entry_lookup(vrf_id,
    2482             :                                                      ipset_name,
    2483             :                                                      unique);
    2484           0 :         if (!bgp_pbime) {
    2485           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2486           0 :                         zlog_debug(
    2487             :                                 "%s: Fail to look BGP match entry (%u, ID %u)",
    2488             :                                 __func__, note, unique);
    2489           0 :                 return 0;
    2490             :         }
    2491             : 
    2492           0 :         switch (note) {
    2493           0 :         case ZAPI_IPSET_ENTRY_FAIL_INSTALL:
    2494           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2495           0 :                         zlog_debug("%s: Received IPSET_ENTRY_FAIL_INSTALL",
    2496             :                                    __func__);
    2497           0 :                 bgp_pbime->installed = false;
    2498           0 :                 bgp_pbime->install_in_progress = false;
    2499           0 :                 break;
    2500           0 :         case ZAPI_IPSET_ENTRY_INSTALLED:
    2501             :                 {
    2502           0 :                 struct bgp_path_info *path;
    2503           0 :                 struct bgp_path_info_extra *extra;
    2504             : 
    2505           0 :                 bgp_pbime->installed = true;
    2506           0 :                 bgp_pbime->install_in_progress = false;
    2507           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2508           0 :                         zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
    2509             :                                    __func__);
    2510             :                 /* link bgp_path_info to bpme */
    2511           0 :                 path = (struct bgp_path_info *)bgp_pbime->path;
    2512           0 :                 extra = bgp_path_info_extra_get(path);
    2513           0 :                 listnode_add_force(&extra->bgp_fs_pbr, bgp_pbime);
    2514             :                 }
    2515           0 :                 break;
    2516           0 :         case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
    2517             :         case ZAPI_IPSET_ENTRY_REMOVED:
    2518           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2519           0 :                         zlog_debug("%s: Received IPSET_ENTRY_REMOVED",
    2520             :                                    __func__);
    2521             :                 break;
    2522             :         }
    2523             :         return 0;
    2524             : }
    2525             : 
    2526           0 : static int iptable_notify_owner(ZAPI_CALLBACK_ARGS)
    2527             : {
    2528           0 :         uint32_t unique;
    2529           0 :         enum zapi_iptable_notify_owner note;
    2530           0 :         struct bgp_pbr_match *bgpm;
    2531             : 
    2532           0 :         if (!zapi_iptable_notify_decode(
    2533             :                                         zclient->ibuf,
    2534             :                                         &unique,
    2535             :                                         &note))
    2536             :                 return -1;
    2537           0 :         bgpm = bgp_pbr_match_iptable_lookup(vrf_id, unique);
    2538           0 :         if (!bgpm) {
    2539           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2540           0 :                         zlog_debug("%s: Fail to look BGP iptable (%u %u)",
    2541             :                                    __func__, note, unique);
    2542           0 :                 return 0;
    2543             :         }
    2544           0 :         switch (note) {
    2545           0 :         case ZAPI_IPTABLE_FAIL_INSTALL:
    2546           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2547           0 :                         zlog_debug("%s: Received IPTABLE_FAIL_INSTALL",
    2548             :                                    __func__);
    2549           0 :                 bgpm->installed_in_iptable = false;
    2550           0 :                 bgpm->install_iptable_in_progress = false;
    2551           0 :                 break;
    2552           0 :         case ZAPI_IPTABLE_INSTALLED:
    2553           0 :                 bgpm->installed_in_iptable = true;
    2554           0 :                 bgpm->install_iptable_in_progress = false;
    2555           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2556           0 :                         zlog_debug("%s: Received IPTABLE_INSTALLED", __func__);
    2557           0 :                 bgpm->action->refcnt++;
    2558           0 :                 break;
    2559           0 :         case ZAPI_IPTABLE_FAIL_REMOVE:
    2560             :         case ZAPI_IPTABLE_REMOVED:
    2561           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2562           0 :                         zlog_debug("%s: Received IPTABLE REMOVED", __func__);
    2563             :                 break;
    2564             :         }
    2565             :         return 0;
    2566             : }
    2567             : 
    2568             : /* Process route notification messages from RIB */
    2569           0 : static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
    2570             :                                         zebra_size_t length, vrf_id_t vrf_id)
    2571             : {
    2572           0 :         struct prefix p;
    2573           0 :         enum zapi_route_notify_owner note;
    2574           0 :         uint32_t table_id;
    2575           0 :         afi_t afi;
    2576           0 :         safi_t safi;
    2577           0 :         struct bgp_dest *dest;
    2578           0 :         struct bgp *bgp;
    2579           0 :         struct bgp_path_info *pi, *new_select;
    2580             : 
    2581           0 :         if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note,
    2582             :                                       &afi, &safi)) {
    2583           0 :                 zlog_err("%s : error in msg decode", __func__);
    2584           0 :                 return -1;
    2585             :         }
    2586             : 
    2587             :         /* Get the bgp instance */
    2588           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    2589           0 :         if (!bgp) {
    2590           0 :                 flog_err(EC_BGP_INVALID_BGP_INSTANCE,
    2591             :                          "%s : bgp instance not found vrf %d", __func__,
    2592             :                          vrf_id);
    2593           0 :                 return -1;
    2594             :         }
    2595             : 
    2596             :         /* Find the bgp route node */
    2597           0 :         dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p,
    2598             :                                    &bgp->vrf_prd);
    2599           0 :         if (!dest)
    2600             :                 return -1;
    2601             : 
    2602           0 :         switch (note) {
    2603           0 :         case ZAPI_ROUTE_INSTALLED:
    2604           0 :                 new_select = NULL;
    2605             :                 /* Clear the flags so that route can be processed */
    2606           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
    2607           0 :                 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
    2608           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2609           0 :                         zlog_debug("route %pRN : INSTALLED", dest);
    2610             :                 /* Find the best route */
    2611           0 :                 for (pi = dest->info; pi; pi = pi->next) {
    2612             :                         /* Process aggregate route */
    2613           0 :                         bgp_aggregate_increment(bgp, &p, pi, afi, safi);
    2614           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
    2615           0 :                                 new_select = pi;
    2616             :                 }
    2617             :                 /* Advertise the route */
    2618           0 :                 if (new_select)
    2619           0 :                         group_announce_route(bgp, afi, safi, dest, new_select);
    2620             :                 else {
    2621           0 :                         flog_err(EC_BGP_INVALID_ROUTE,
    2622             :                                  "selected route %pRN not found", dest);
    2623             : 
    2624           0 :                         bgp_dest_unlock_node(dest);
    2625           0 :                         return -1;
    2626             :                 }
    2627           0 :                 break;
    2628           0 :         case ZAPI_ROUTE_REMOVED:
    2629             :                 /* Route deleted from dataplane, reset the installed flag
    2630             :                  * so that route can be reinstalled when client sends
    2631             :                  * route add later
    2632             :                  */
    2633           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
    2634           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2635           0 :                         zlog_debug("route %pRN: Removed from Fib", dest);
    2636             :                 break;
    2637           0 :         case ZAPI_ROUTE_FAIL_INSTALL:
    2638           0 :                 new_select = NULL;
    2639           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2640           0 :                         zlog_debug("route: %pRN Failed to Install into Fib",
    2641             :                                    dest);
    2642           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
    2643           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
    2644           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
    2645           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
    2646           0 :                                 new_select = pi;
    2647             :                 }
    2648           0 :                 if (new_select)
    2649           0 :                         group_announce_route(bgp, afi, safi, dest, new_select);
    2650             :                 /* Error will be logged by zebra module */
    2651             :                 break;
    2652           0 :         case ZAPI_ROUTE_BETTER_ADMIN_WON:
    2653           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2654           0 :                         zlog_debug("route: %pRN removed due to better admin won",
    2655             :                                    dest);
    2656           0 :                 new_select = NULL;
    2657           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
    2658           0 :                 UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
    2659           0 :                 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
    2660           0 :                         bgp_aggregate_decrement(bgp, &p, pi, afi, safi);
    2661           0 :                         if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
    2662           0 :                                 new_select = pi;
    2663             :                 }
    2664           0 :                 if (new_select)
    2665           0 :                         group_announce_route(bgp, afi, safi, dest, new_select);
    2666             :                 /* No action required */
    2667             :                 break;
    2668           0 :         case ZAPI_ROUTE_REMOVE_FAIL:
    2669           0 :                 zlog_warn("%s: Route %pRN failure to remove",
    2670             :                           __func__, dest);
    2671           0 :                 break;
    2672             :         }
    2673             : 
    2674           0 :         bgp_dest_unlock_node(dest);
    2675           0 :         return 0;
    2676             : }
    2677             : 
    2678             : /* this function is used to forge ip rule,
    2679             :  * - either for iptable/ipset using fwmark id
    2680             :  * - or for sample ip rule cmd
    2681             :  */
    2682           0 : static void bgp_encode_pbr_rule_action(struct stream *s,
    2683             :                                        struct bgp_pbr_action *pbra,
    2684             :                                        struct bgp_pbr_rule *pbr)
    2685             : {
    2686           0 :         struct prefix pfx;
    2687           0 :         uint8_t fam = AF_INET;
    2688           0 :         char ifname[INTERFACE_NAMSIZ];
    2689             : 
    2690           0 :         if (pbra->nh.type == NEXTHOP_TYPE_IPV6)
    2691           0 :                 fam = AF_INET6;
    2692           0 :         stream_putl(s, 0); /* seqno unused */
    2693           0 :         if (pbr)
    2694           0 :                 stream_putl(s, pbr->priority);
    2695             :         else
    2696           0 :                 stream_putl(s, 0);
    2697             :         /* ruleno unused - priority change
    2698             :          * ruleno permits distinguishing various FS PBR entries
    2699             :          * - FS PBR entries based on ipset/iptables
    2700             :          * - FS PBR entries based on iprule
    2701             :          * the latter may contain default routing information injected by FS
    2702             :          */
    2703           0 :         if (pbr)
    2704           0 :                 stream_putl(s, pbr->unique);
    2705             :         else
    2706           0 :                 stream_putl(s, pbra->unique);
    2707           0 :         stream_putc(s, 0); /* ip protocol being used */
    2708           0 :         if (pbr && pbr->flags & MATCH_IP_SRC_SET)
    2709           0 :                 memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
    2710             :         else {
    2711           0 :                 memset(&pfx, 0, sizeof(pfx));
    2712           0 :                 pfx.family = fam;
    2713             :         }
    2714           0 :         stream_putc(s, pfx.family);
    2715           0 :         stream_putc(s, pfx.prefixlen);
    2716           0 :         stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
    2717             : 
    2718           0 :         stream_putw(s, 0);  /* src port */
    2719             : 
    2720           0 :         if (pbr && pbr->flags & MATCH_IP_DST_SET)
    2721           0 :                 memcpy(&pfx, &(pbr->dst), sizeof(struct prefix));
    2722             :         else {
    2723           0 :                 memset(&pfx, 0, sizeof(pfx));
    2724           0 :                 pfx.family = fam;
    2725             :         }
    2726           0 :         stream_putc(s, pfx.family);
    2727           0 :         stream_putc(s, pfx.prefixlen);
    2728           0 :         stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
    2729             : 
    2730           0 :         stream_putw(s, 0);  /* dst port */
    2731           0 :         stream_putc(s, 0);  /* dsfield */
    2732             :         /* if pbr present, fwmark is not used */
    2733           0 :         if (pbr)
    2734           0 :                 stream_putl(s, 0);
    2735             :         else
    2736           0 :                 stream_putl(s, pbra->fwmark);  /* fwmark */
    2737             : 
    2738           0 :         stream_putl(s, 0); /* queue id */
    2739           0 :         stream_putw(s, 0); /* vlan_id */
    2740           0 :         stream_putw(s, 0); /* vlan_flags */
    2741           0 :         stream_putw(s, 0); /* pcp */
    2742             : 
    2743           0 :         stream_putl(s, pbra->table_id);
    2744             : 
    2745           0 :         memset(ifname, 0, sizeof(ifname));
    2746           0 :         stream_put(s, ifname, INTERFACE_NAMSIZ); /* ifname unused */
    2747           0 : }
    2748             : 
    2749           0 : static void bgp_encode_pbr_ipset_match(struct stream *s,
    2750             :                                   struct bgp_pbr_match *pbim)
    2751             : {
    2752           0 :         stream_putl(s, pbim->unique);
    2753           0 :         stream_putl(s, pbim->type);
    2754           0 :         stream_putc(s, pbim->family);
    2755           0 :         stream_put(s, pbim->ipset_name,
    2756             :                    ZEBRA_IPSET_NAME_SIZE);
    2757           0 : }
    2758             : 
    2759           0 : static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
    2760             :                                   struct bgp_pbr_match_entry *pbime)
    2761             : {
    2762           0 :         stream_putl(s, pbime->unique);
    2763             :         /* check that back pointer is not null */
    2764           0 :         stream_put(s, pbime->backpointer->ipset_name,
    2765             :                    ZEBRA_IPSET_NAME_SIZE);
    2766             : 
    2767           0 :         stream_putc(s, pbime->src.family);
    2768           0 :         stream_putc(s, pbime->src.prefixlen);
    2769           0 :         stream_put(s, &pbime->src.u.prefix, prefix_blen(&pbime->src));
    2770             : 
    2771           0 :         stream_putc(s, pbime->dst.family);
    2772           0 :         stream_putc(s, pbime->dst.prefixlen);
    2773           0 :         stream_put(s, &pbime->dst.u.prefix, prefix_blen(&pbime->dst));
    2774             : 
    2775           0 :         stream_putw(s, pbime->src_port_min);
    2776           0 :         stream_putw(s, pbime->src_port_max);
    2777           0 :         stream_putw(s, pbime->dst_port_min);
    2778           0 :         stream_putw(s, pbime->dst_port_max);
    2779           0 :         stream_putc(s, pbime->proto);
    2780           0 : }
    2781             : 
    2782           0 : static void bgp_encode_pbr_iptable_match(struct stream *s,
    2783             :                                          struct bgp_pbr_action *bpa,
    2784             :                                          struct bgp_pbr_match *pbm)
    2785             : {
    2786           0 :         stream_putl(s, pbm->unique2);
    2787             : 
    2788           0 :         stream_putl(s, pbm->type);
    2789             : 
    2790           0 :         stream_putl(s, pbm->flags);
    2791             : 
    2792             :         /* TODO: correlate with what is contained
    2793             :          * into bgp_pbr_action.
    2794             :          * currently only forward supported
    2795             :          */
    2796           0 :         if (bpa->nh.type == NEXTHOP_TYPE_BLACKHOLE)
    2797           0 :                 stream_putl(s, ZEBRA_IPTABLES_DROP);
    2798             :         else
    2799           0 :                 stream_putl(s, ZEBRA_IPTABLES_FORWARD);
    2800           0 :         stream_putl(s, bpa->fwmark);
    2801           0 :         stream_put(s, pbm->ipset_name,
    2802             :                    ZEBRA_IPSET_NAME_SIZE);
    2803           0 :         stream_putc(s, pbm->family);
    2804           0 :         stream_putw(s, pbm->pkt_len_min);
    2805           0 :         stream_putw(s, pbm->pkt_len_max);
    2806           0 :         stream_putw(s, pbm->tcp_flags);
    2807           0 :         stream_putw(s, pbm->tcp_mask_flags);
    2808           0 :         stream_putc(s, pbm->dscp_value);
    2809           0 :         stream_putc(s, pbm->fragment);
    2810           0 :         stream_putc(s, pbm->protocol);
    2811           0 :         stream_putw(s, pbm->flow_label);
    2812           0 : }
    2813             : 
    2814             : /* BGP has established connection with Zebra. */
    2815           3 : static void bgp_zebra_connected(struct zclient *zclient)
    2816             : {
    2817           3 :         struct bgp *bgp;
    2818             : 
    2819           3 :         zclient_num_connects++; /* increment even if not responding */
    2820             : 
    2821             :         /* Send the client registration */
    2822           3 :         bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT);
    2823             : 
    2824             :         /* At this point, we may or may not have BGP instances configured, but
    2825             :          * we're only interested in the default VRF (others wouldn't have learnt
    2826             :          * the VRF from Zebra yet.)
    2827             :          */
    2828           3 :         bgp = bgp_get_default();
    2829           3 :         if (!bgp)
    2830             :                 return;
    2831             : 
    2832           0 :         bgp_zebra_instance_register(bgp);
    2833             : 
    2834             :         /* tell label pool that zebra is connected */
    2835           0 :         bgp_lp_event_zebra_up();
    2836             : 
    2837             :         /* TODO - What if we have peers and networks configured, do we have to
    2838             :          * kick-start them?
    2839             :          */
    2840           0 :         BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);
    2841             : }
    2842             : 
    2843           0 : static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS)
    2844             : {
    2845           0 :         esi_t esi;
    2846           0 :         struct bgp *bgp = NULL;
    2847           0 :         struct stream *s = NULL;
    2848           0 :         char buf[ESI_STR_LEN];
    2849           0 :         struct in_addr originator_ip;
    2850           0 :         uint8_t active;
    2851           0 :         uint8_t bypass;
    2852           0 :         uint16_t df_pref;
    2853             : 
    2854           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    2855           0 :         if (!bgp)
    2856             :                 return 0;
    2857             : 
    2858           0 :         s = zclient->ibuf;
    2859           0 :         stream_get(&esi, s, sizeof(esi_t));
    2860           0 :         originator_ip.s_addr = stream_get_ipv4(s);
    2861           0 :         active = stream_getc(s);
    2862           0 :         df_pref = stream_getw(s);
    2863           0 :         bypass = stream_getc(s);
    2864             : 
    2865           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    2866           0 :                 zlog_debug(
    2867             :                         "Rx add ESI %s originator-ip %pI4 active %u df_pref %u %s",
    2868             :                         esi_to_str(&esi, buf, sizeof(buf)), &originator_ip,
    2869             :                         active, df_pref, bypass ? "bypass" : "");
    2870             : 
    2871           0 :         frrtrace(5, frr_bgp, evpn_mh_local_es_add_zrecv, &esi, originator_ip,
    2872             :                  active, bypass, df_pref);
    2873             : 
    2874           0 :         bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref,
    2875             :                               !!bypass);
    2876             : 
    2877           0 :         return 0;
    2878             : }
    2879             : 
    2880           0 : static int bgp_zebra_process_local_es_del(ZAPI_CALLBACK_ARGS)
    2881             : {
    2882           0 :         esi_t esi;
    2883           0 :         struct bgp *bgp = NULL;
    2884           0 :         struct stream *s = NULL;
    2885           0 :         char buf[ESI_STR_LEN];
    2886             : 
    2887           0 :         memset(&esi, 0, sizeof(esi_t));
    2888           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    2889           0 :         if (!bgp)
    2890             :                 return 0;
    2891             : 
    2892           0 :         s = zclient->ibuf;
    2893           0 :         stream_get(&esi, s, sizeof(esi_t));
    2894             : 
    2895           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    2896           0 :                 zlog_debug("Rx del ESI %s",
    2897             :                                 esi_to_str(&esi, buf, sizeof(buf)));
    2898             : 
    2899           0 :         frrtrace(1, frr_bgp, evpn_mh_local_es_del_zrecv, &esi);
    2900             : 
    2901           0 :         bgp_evpn_local_es_del(bgp, &esi);
    2902             : 
    2903           0 :         return 0;
    2904             : }
    2905             : 
    2906           0 : static int bgp_zebra_process_local_es_evi(ZAPI_CALLBACK_ARGS)
    2907             : {
    2908           0 :         esi_t esi;
    2909           0 :         vni_t vni;
    2910           0 :         struct bgp *bgp;
    2911           0 :         struct stream *s;
    2912           0 :         char buf[ESI_STR_LEN];
    2913             : 
    2914           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    2915           0 :         if (!bgp)
    2916             :                 return 0;
    2917             : 
    2918           0 :         s = zclient->ibuf;
    2919           0 :         stream_get(&esi, s, sizeof(esi_t));
    2920           0 :         vni = stream_getl(s);
    2921             : 
    2922           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    2923           0 :                 zlog_debug("Rx %s ESI %s VNI %u",
    2924             :                            (cmd == ZEBRA_VNI_ADD) ? "add" : "del",
    2925             :                            esi_to_str(&esi, buf, sizeof(buf)), vni);
    2926             : 
    2927           0 :         if (cmd == ZEBRA_LOCAL_ES_EVI_ADD) {
    2928           0 :                 frrtrace(2, frr_bgp, evpn_mh_local_es_evi_add_zrecv, &esi, vni);
    2929             : 
    2930           0 :                 bgp_evpn_local_es_evi_add(bgp, &esi, vni);
    2931             :         } else {
    2932           0 :                 frrtrace(2, frr_bgp, evpn_mh_local_es_evi_del_zrecv, &esi, vni);
    2933             : 
    2934           0 :                 bgp_evpn_local_es_evi_del(bgp, &esi, vni);
    2935             :         }
    2936             : 
    2937             :         return 0;
    2938             : }
    2939             : 
    2940           0 : static int bgp_zebra_process_local_l3vni(ZAPI_CALLBACK_ARGS)
    2941             : {
    2942           0 :         int filter = 0;
    2943           0 :         vni_t l3vni = 0;
    2944           0 :         struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
    2945           0 :         struct in_addr originator_ip;
    2946           0 :         struct stream *s;
    2947           0 :         ifindex_t svi_ifindex;
    2948           0 :         bool is_anycast_mac = false;
    2949             : 
    2950           0 :         memset(&svi_rmac, 0, sizeof(svi_rmac));
    2951           0 :         memset(&originator_ip, 0, sizeof(originator_ip));
    2952           0 :         s = zclient->ibuf;
    2953           0 :         l3vni = stream_getl(s);
    2954           0 :         if (cmd == ZEBRA_L3VNI_ADD) {
    2955           0 :                 stream_get(&svi_rmac, s, sizeof(struct ethaddr));
    2956           0 :                 originator_ip.s_addr = stream_get_ipv4(s);
    2957           0 :                 stream_get(&filter, s, sizeof(int));
    2958           0 :                 svi_ifindex = stream_getl(s);
    2959           0 :                 stream_get(&vrr_rmac, s, sizeof(struct ethaddr));
    2960           0 :                 is_anycast_mac = stream_getl(s);
    2961             : 
    2962           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2963           0 :                         zlog_debug(
    2964             :                                 "Rx L3-VNI ADD VRF %s VNI %u RMAC svi-mac %pEA vrr-mac %pEA filter %s svi-if %u",
    2965             :                                 vrf_id_to_name(vrf_id), l3vni, &svi_rmac,
    2966             :                                 &vrr_rmac,
    2967             :                                 filter ? "prefix-routes-only" : "none",
    2968             :                                 svi_ifindex);
    2969             : 
    2970           0 :                 frrtrace(8, frr_bgp, evpn_local_l3vni_add_zrecv, l3vni, vrf_id,
    2971             :                          &svi_rmac, &vrr_rmac, filter, originator_ip,
    2972             :                          svi_ifindex, is_anycast_mac);
    2973             : 
    2974           0 :                 bgp_evpn_local_l3vni_add(l3vni, vrf_id, &svi_rmac, &vrr_rmac,
    2975             :                                          originator_ip, filter, svi_ifindex,
    2976             :                                          is_anycast_mac);
    2977             :         } else {
    2978           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    2979           0 :                         zlog_debug("Rx L3-VNI DEL VRF %s VNI %u",
    2980             :                                    vrf_id_to_name(vrf_id), l3vni);
    2981             : 
    2982           0 :                 frrtrace(2, frr_bgp, evpn_local_l3vni_del_zrecv, l3vni, vrf_id);
    2983             : 
    2984           0 :                 bgp_evpn_local_l3vni_del(l3vni, vrf_id);
    2985             :         }
    2986             : 
    2987           0 :         return 0;
    2988             : }
    2989             : 
    2990           0 : static int bgp_zebra_process_local_vni(ZAPI_CALLBACK_ARGS)
    2991             : {
    2992           0 :         struct stream *s;
    2993           0 :         vni_t vni;
    2994           0 :         struct bgp *bgp;
    2995           0 :         struct in_addr vtep_ip = {INADDR_ANY};
    2996           0 :         vrf_id_t tenant_vrf_id = VRF_DEFAULT;
    2997           0 :         struct in_addr mcast_grp = {INADDR_ANY};
    2998           0 :         ifindex_t svi_ifindex = 0;
    2999             : 
    3000           0 :         s = zclient->ibuf;
    3001           0 :         vni = stream_getl(s);
    3002           0 :         if (cmd == ZEBRA_VNI_ADD) {
    3003           0 :                 vtep_ip.s_addr = stream_get_ipv4(s);
    3004           0 :                 stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t));
    3005           0 :                 mcast_grp.s_addr = stream_get_ipv4(s);
    3006           0 :                 stream_get(&svi_ifindex, s, sizeof(ifindex_t));
    3007             :         }
    3008             : 
    3009           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    3010           0 :         if (!bgp)
    3011             :                 return 0;
    3012             : 
    3013           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3014           0 :                 zlog_debug(
    3015             :                         "Rx VNI %s VRF %s VNI %u tenant-vrf %s SVI ifindex %u",
    3016             :                         (cmd == ZEBRA_VNI_ADD) ? "add" : "del",
    3017             :                         vrf_id_to_name(vrf_id), vni,
    3018             :                         vrf_id_to_name(tenant_vrf_id), svi_ifindex);
    3019             : 
    3020           0 :         if (cmd == ZEBRA_VNI_ADD) {
    3021           0 :                 frrtrace(4, frr_bgp, evpn_local_vni_add_zrecv, vni, vtep_ip,
    3022             :                          tenant_vrf_id, mcast_grp);
    3023             : 
    3024           0 :                 return bgp_evpn_local_vni_add(
    3025             :                         bgp, vni,
    3026             :                         vtep_ip.s_addr != INADDR_ANY ? vtep_ip : bgp->router_id,
    3027             :                         tenant_vrf_id, mcast_grp, svi_ifindex);
    3028             :         } else {
    3029           0 :                 frrtrace(1, frr_bgp, evpn_local_vni_del_zrecv, vni);
    3030             : 
    3031           0 :                 return bgp_evpn_local_vni_del(bgp, vni);
    3032             :         }
    3033             : }
    3034             : 
    3035           0 : static int bgp_zebra_process_local_macip(ZAPI_CALLBACK_ARGS)
    3036             : {
    3037           0 :         struct stream *s;
    3038           0 :         vni_t vni;
    3039           0 :         struct bgp *bgp;
    3040           0 :         struct ethaddr mac;
    3041           0 :         struct ipaddr ip;
    3042           0 :         int ipa_len;
    3043           0 :         uint8_t flags = 0;
    3044           0 :         uint32_t seqnum = 0;
    3045           0 :         int state = 0;
    3046           0 :         char buf2[ESI_STR_LEN];
    3047           0 :         esi_t esi;
    3048             : 
    3049           0 :         memset(&ip, 0, sizeof(ip));
    3050           0 :         s = zclient->ibuf;
    3051           0 :         vni = stream_getl(s);
    3052           0 :         stream_get(&mac.octet, s, ETH_ALEN);
    3053           0 :         ipa_len = stream_getl(s);
    3054           0 :         if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN
    3055           0 :             && ipa_len != IPV6_MAX_BYTELEN) {
    3056           0 :                 flog_err(EC_BGP_MACIP_LEN,
    3057             :                          "%u:Recv MACIP %s with invalid IP addr length %d",
    3058             :                          vrf_id, (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
    3059             :                          ipa_len);
    3060           0 :                 return -1;
    3061             :         }
    3062             : 
    3063           0 :         if (ipa_len) {
    3064           0 :                 ip.ipa_type =
    3065           0 :                         (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
    3066           0 :                 stream_get(&ip.ip.addr, s, ipa_len);
    3067             :         }
    3068           0 :         if (cmd == ZEBRA_MACIP_ADD) {
    3069           0 :                 flags = stream_getc(s);
    3070           0 :                 seqnum = stream_getl(s);
    3071           0 :                 stream_get(&esi, s, sizeof(esi_t));
    3072             :         } else {
    3073           0 :                 state = stream_getl(s);
    3074           0 :                 memset(&esi, 0, sizeof(esi_t));
    3075             :         }
    3076             : 
    3077           0 :         bgp = bgp_lookup_by_vrf_id(vrf_id);
    3078           0 :         if (!bgp)
    3079             :                 return 0;
    3080             : 
    3081           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3082           0 :                 zlog_debug(
    3083             :                         "%u:Recv MACIP %s f 0x%x MAC %pEA IP %pIA VNI %u seq %u state %d ESI %s",
    3084             :                         vrf_id, (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags,
    3085             :                         &mac, &ip, vni, seqnum, state,
    3086             :                         esi_to_str(&esi, buf2, sizeof(buf2)));
    3087             : 
    3088           0 :         if (cmd == ZEBRA_MACIP_ADD) {
    3089           0 :                 frrtrace(6, frr_bgp, evpn_local_macip_add_zrecv, vni, &mac, &ip,
    3090             :                          flags, seqnum, &esi);
    3091             : 
    3092           0 :                 return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
    3093             :                                                 flags, seqnum, &esi);
    3094             :         } else {
    3095           0 :                 frrtrace(4, frr_bgp, evpn_local_macip_del_zrecv, vni, &mac, &ip,
    3096             :                          state);
    3097             : 
    3098           0 :                 return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, state);
    3099             :         }
    3100             : }
    3101             : 
    3102           0 : static int bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS)
    3103             : {
    3104           0 :         struct stream *s = NULL;
    3105           0 :         struct bgp *bgp_vrf = NULL;
    3106           0 :         struct prefix p;
    3107             : 
    3108           0 :         memset(&p, 0, sizeof(p));
    3109           0 :         s = zclient->ibuf;
    3110           0 :         stream_get(&p, s, sizeof(struct prefix));
    3111             : 
    3112           0 :         bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
    3113           0 :         if (!bgp_vrf)
    3114             :                 return 0;
    3115             : 
    3116           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3117           0 :                 zlog_debug("Recv prefix %pFX %s on vrf %s", &p,
    3118             :                            (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
    3119             :                            vrf_id_to_name(vrf_id));
    3120             : 
    3121           0 :         if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) {
    3122             : 
    3123           0 :                 if (p.family == AF_INET)
    3124           0 :                         bgp_evpn_advertise_type5_route(bgp_vrf, &p, NULL,
    3125             :                                                        AFI_IP, SAFI_UNICAST);
    3126             :                 else
    3127           0 :                         bgp_evpn_advertise_type5_route(bgp_vrf, &p, NULL,
    3128             :                                                        AFI_IP6, SAFI_UNICAST);
    3129             : 
    3130             :         } else {
    3131           0 :                 if (p.family == AF_INET)
    3132           0 :                         bgp_evpn_withdraw_type5_route(bgp_vrf, &p, AFI_IP,
    3133             :                                                       SAFI_UNICAST);
    3134             :                 else
    3135           0 :                         bgp_evpn_withdraw_type5_route(bgp_vrf, &p, AFI_IP6,
    3136             :                                                       SAFI_UNICAST);
    3137             :         }
    3138             :         return 0;
    3139             : }
    3140             : 
    3141           0 : static int bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS)
    3142             : {
    3143           0 :         struct stream *s = NULL;
    3144           0 :         uint8_t response_keep;
    3145           0 :         uint32_t first;
    3146           0 :         uint32_t last;
    3147           0 :         uint8_t proto;
    3148           0 :         unsigned short instance;
    3149             : 
    3150           0 :         s = zclient->ibuf;
    3151           0 :         STREAM_GETC(s, proto);
    3152           0 :         STREAM_GETW(s, instance);
    3153           0 :         STREAM_GETC(s, response_keep);
    3154           0 :         STREAM_GETL(s, first);
    3155           0 :         STREAM_GETL(s, last);
    3156             : 
    3157           0 :         if (zclient->redist_default != proto) {
    3158           0 :                 flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u",
    3159             :                          proto);
    3160           0 :                 return 0;
    3161             :         }
    3162           0 :         if (zclient->instance != instance) {
    3163           0 :                 flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u",
    3164             :                          proto);
    3165           0 :                 return 0;
    3166             :         }
    3167             : 
    3168           0 :         if (first > last ||
    3169           0 :                 first < MPLS_LABEL_UNRESERVED_MIN ||
    3170             :                 last > MPLS_LABEL_UNRESERVED_MAX) {
    3171             : 
    3172           0 :                 flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
    3173             :                          __func__, first, last);
    3174           0 :                 return 0;
    3175             :         }
    3176           0 :         if (BGP_DEBUG(zebra, ZEBRA)) {
    3177           0 :                 zlog_debug("Label Chunk assign: %u - %u (%u) ",
    3178             :                         first, last, response_keep);
    3179             :         }
    3180             : 
    3181           0 :         bgp_lp_event_chunk(response_keep, first, last);
    3182             : 
    3183           0 :         return 0;
    3184             : 
    3185             : stream_failure:         /* for STREAM_GETX */
    3186             :         return -1;
    3187             : }
    3188             : 
    3189             : extern struct zebra_privs_t bgpd_privs;
    3190             : 
    3191          24 : static int bgp_ifp_create(struct interface *ifp)
    3192             : {
    3193          24 :         struct bgp *bgp;
    3194             : 
    3195          24 :         if (BGP_DEBUG(zebra, ZEBRA))
    3196           0 :                 zlog_debug("Rx Intf add VRF %u IF %s", ifp->vrf->vrf_id,
    3197             :                            ifp->name);
    3198             : 
    3199          24 :         bgp = ifp->vrf->info;
    3200          24 :         if (!bgp)
    3201             :                 return 0;
    3202             : 
    3203          24 :         bgp_mac_add_mac_entry(ifp);
    3204             : 
    3205          24 :         bgp_update_interface_nbrs(bgp, ifp, ifp);
    3206          24 :         hook_call(bgp_vrf_status_changed, bgp, ifp);
    3207          24 :         return 0;
    3208             : }
    3209             : 
    3210           0 : static int bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
    3211             : {
    3212           0 :         struct stream *s = NULL;
    3213           0 :         struct bgp *bgp = bgp_get_default();
    3214           0 :         struct listnode *node;
    3215           0 :         struct srv6_locator_chunk *c;
    3216           0 :         struct srv6_locator_chunk *chunk = srv6_locator_chunk_alloc();
    3217             : 
    3218           0 :         s = zclient->ibuf;
    3219           0 :         zapi_srv6_locator_chunk_decode(s, chunk);
    3220             : 
    3221           0 :         if (strcmp(bgp->srv6_locator_name, chunk->locator_name) != 0) {
    3222           0 :                 zlog_err("%s: Locator name unmatch %s:%s", __func__,
    3223             :                          bgp->srv6_locator_name, chunk->locator_name);
    3224           0 :                 srv6_locator_chunk_free(&chunk);
    3225           0 :                 return 0;
    3226             :         }
    3227             : 
    3228           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, c)) {
    3229           0 :                 if (!prefix_cmp(&c->prefix, &chunk->prefix)) {
    3230           0 :                         srv6_locator_chunk_free(&chunk);
    3231           0 :                         return 0;
    3232             :                 }
    3233             :         }
    3234             : 
    3235           0 :         listnode_add(bgp->srv6_locator_chunks, chunk);
    3236           0 :         vpn_leak_postchange_all();
    3237           0 :         return 0;
    3238             : }
    3239             : 
    3240           0 : static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS)
    3241             : {
    3242           0 :         struct srv6_locator loc = {};
    3243           0 :         struct bgp *bgp = bgp_get_default();
    3244           0 :         const char *loc_name = bgp->srv6_locator_name;
    3245             : 
    3246           0 :         if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
    3247             :                 return -1;
    3248             : 
    3249           0 :         if (!bgp || !bgp->srv6_enabled)
    3250             :                 return 0;
    3251             : 
    3252           0 :         if (bgp_zebra_srv6_manager_get_locator_chunk(loc_name) < 0)
    3253             :                 return -1;
    3254             : 
    3255             :         return 0;
    3256             : }
    3257             : 
    3258           0 : static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
    3259             : {
    3260           0 :         struct srv6_locator loc = {};
    3261           0 :         struct bgp *bgp = bgp_get_default();
    3262           0 :         struct listnode *node, *nnode;
    3263           0 :         struct srv6_locator_chunk *chunk, *tovpn_sid_locator;
    3264           0 :         struct bgp_srv6_function *func;
    3265           0 :         struct bgp *bgp_vrf;
    3266           0 :         struct in6_addr *tovpn_sid;
    3267           0 :         struct prefix_ipv6 tmp_prefi;
    3268             : 
    3269           0 :         if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
    3270             :                 return -1;
    3271             : 
    3272             :         // refresh chunks
    3273           0 :         for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
    3274           0 :                 if (prefix_match((struct prefix *)&loc.prefix,
    3275           0 :                                  (struct prefix *)&chunk->prefix)) {
    3276           0 :                         listnode_delete(bgp->srv6_locator_chunks, chunk);
    3277           0 :                         srv6_locator_chunk_free(&chunk);
    3278             :                 }
    3279             : 
    3280             :         // refresh functions
    3281           0 :         for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) {
    3282           0 :                 tmp_prefi.family = AF_INET6;
    3283           0 :                 tmp_prefi.prefixlen = 128;
    3284           0 :                 tmp_prefi.prefix = func->sid;
    3285           0 :                 if (prefix_match((struct prefix *)&loc.prefix,
    3286             :                                  (struct prefix *)&tmp_prefi)) {
    3287           0 :                         listnode_delete(bgp->srv6_functions, func);
    3288           0 :                         XFREE(MTYPE_BGP_SRV6_FUNCTION, func);
    3289             :                 }
    3290             :         }
    3291             : 
    3292             :         // refresh tovpn_sid
    3293           0 :         for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
    3294           0 :                 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
    3295           0 :                         continue;
    3296             : 
    3297             :                 // refresh vpnv4 tovpn_sid
    3298           0 :                 tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid;
    3299           0 :                 if (tovpn_sid) {
    3300           0 :                         tmp_prefi.family = AF_INET6;
    3301           0 :                         tmp_prefi.prefixlen = 128;
    3302           0 :                         tmp_prefi.prefix = *tovpn_sid;
    3303           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3304             :                                          (struct prefix *)&tmp_prefi))
    3305           0 :                                 XFREE(MTYPE_BGP_SRV6_SID,
    3306             :                                       bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
    3307             :                 }
    3308             : 
    3309             :                 // refresh vpnv6 tovpn_sid
    3310           0 :                 tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid;
    3311           0 :                 if (tovpn_sid) {
    3312           0 :                         tmp_prefi.family = AF_INET6;
    3313           0 :                         tmp_prefi.prefixlen = 128;
    3314           0 :                         tmp_prefi.prefix = *tovpn_sid;
    3315           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3316             :                                          (struct prefix *)&tmp_prefi))
    3317           0 :                                 XFREE(MTYPE_BGP_SRV6_SID,
    3318             :                                       bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
    3319             :                 }
    3320             : 
    3321             :                 /* refresh per-vrf tovpn_sid */
    3322           0 :                 tovpn_sid = bgp_vrf->tovpn_sid;
    3323           0 :                 if (tovpn_sid) {
    3324           0 :                         tmp_prefi.family = AF_INET6;
    3325           0 :                         tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
    3326           0 :                         tmp_prefi.prefix = *tovpn_sid;
    3327           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3328             :                                          (struct prefix *)&tmp_prefi))
    3329           0 :                                 XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
    3330             :                 }
    3331             :         }
    3332             : 
    3333           0 :         vpn_leak_postchange_all();
    3334             : 
    3335             :         /* refresh tovpn_sid_locator */
    3336           0 :         for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
    3337           0 :                 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
    3338           0 :                         continue;
    3339             : 
    3340             :                 /* refresh vpnv4 tovpn_sid_locator */
    3341           0 :                 tovpn_sid_locator =
    3342             :                         bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator;
    3343           0 :                 if (tovpn_sid_locator) {
    3344           0 :                         tmp_prefi.family = AF_INET6;
    3345           0 :                         tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
    3346           0 :                         tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
    3347           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3348             :                                          (struct prefix *)&tmp_prefi))
    3349           0 :                                 srv6_locator_chunk_free(
    3350             :                                         &bgp_vrf->vpn_policy[AFI_IP]
    3351             :                                                  .tovpn_sid_locator);
    3352             :                 }
    3353             : 
    3354             :                 /* refresh vpnv6 tovpn_sid_locator */
    3355           0 :                 tovpn_sid_locator =
    3356             :                         bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator;
    3357           0 :                 if (tovpn_sid_locator) {
    3358           0 :                         tmp_prefi.family = AF_INET6;
    3359           0 :                         tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
    3360           0 :                         tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
    3361           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3362             :                                          (struct prefix *)&tmp_prefi))
    3363           0 :                                 srv6_locator_chunk_free(
    3364             :                                         &bgp_vrf->vpn_policy[AFI_IP6]
    3365             :                                                  .tovpn_sid_locator);
    3366             :                 }
    3367             : 
    3368             :                 /* refresh per-vrf tovpn_sid_locator */
    3369           0 :                 tovpn_sid_locator = bgp_vrf->tovpn_sid_locator;
    3370           0 :                 if (tovpn_sid_locator) {
    3371           0 :                         tmp_prefi.family = AF_INET6;
    3372           0 :                         tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
    3373           0 :                         tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
    3374           0 :                         if (prefix_match((struct prefix *)&loc.prefix,
    3375             :                                          (struct prefix *)&tmp_prefi))
    3376           0 :                                 srv6_locator_chunk_free(
    3377             :                                         &bgp_vrf->tovpn_sid_locator);
    3378             :                 }
    3379             :         }
    3380             : 
    3381             :         return 0;
    3382             : }
    3383             : 
    3384             : static zclient_handler *const bgp_handlers[] = {
    3385             :         [ZEBRA_ROUTER_ID_UPDATE] = bgp_router_id_update,
    3386             :         [ZEBRA_INTERFACE_ADDRESS_ADD] = bgp_interface_address_add,
    3387             :         [ZEBRA_INTERFACE_ADDRESS_DELETE] = bgp_interface_address_delete,
    3388             :         [ZEBRA_INTERFACE_NBR_ADDRESS_ADD] = bgp_interface_nbr_address_add,
    3389             :         [ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete,
    3390             :         [ZEBRA_INTERFACE_VRF_UPDATE] = bgp_interface_vrf_update,
    3391             :         [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route,
    3392             :         [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route,
    3393             :         [ZEBRA_NEXTHOP_UPDATE] = bgp_read_nexthop_update,
    3394             :         [ZEBRA_FEC_UPDATE] = bgp_read_fec_update,
    3395             :         [ZEBRA_LOCAL_ES_ADD] = bgp_zebra_process_local_es_add,
    3396             :         [ZEBRA_LOCAL_ES_DEL] = bgp_zebra_process_local_es_del,
    3397             :         [ZEBRA_VNI_ADD] = bgp_zebra_process_local_vni,
    3398             :         [ZEBRA_LOCAL_ES_EVI_ADD] = bgp_zebra_process_local_es_evi,
    3399             :         [ZEBRA_LOCAL_ES_EVI_DEL] = bgp_zebra_process_local_es_evi,
    3400             :         [ZEBRA_VNI_DEL] = bgp_zebra_process_local_vni,
    3401             :         [ZEBRA_MACIP_ADD] = bgp_zebra_process_local_macip,
    3402             :         [ZEBRA_MACIP_DEL] = bgp_zebra_process_local_macip,
    3403             :         [ZEBRA_L3VNI_ADD] = bgp_zebra_process_local_l3vni,
    3404             :         [ZEBRA_L3VNI_DEL] = bgp_zebra_process_local_l3vni,
    3405             :         [ZEBRA_IP_PREFIX_ROUTE_ADD] = bgp_zebra_process_local_ip_prefix,
    3406             :         [ZEBRA_IP_PREFIX_ROUTE_DEL] = bgp_zebra_process_local_ip_prefix,
    3407             :         [ZEBRA_GET_LABEL_CHUNK] = bgp_zebra_process_label_chunk,
    3408             :         [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner,
    3409             :         [ZEBRA_IPSET_NOTIFY_OWNER] = ipset_notify_owner,
    3410             :         [ZEBRA_IPSET_ENTRY_NOTIFY_OWNER] = ipset_entry_notify_owner,
    3411             :         [ZEBRA_IPTABLE_NOTIFY_OWNER] = iptable_notify_owner,
    3412             :         [ZEBRA_ROUTE_NOTIFY_OWNER] = bgp_zebra_route_notify_owner,
    3413             :         [ZEBRA_SRV6_LOCATOR_ADD] = bgp_zebra_process_srv6_locator_add,
    3414             :         [ZEBRA_SRV6_LOCATOR_DELETE] = bgp_zebra_process_srv6_locator_delete,
    3415             :         [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
    3416             :                 bgp_zebra_process_srv6_locator_chunk,
    3417             : };
    3418             : 
    3419           8 : static int bgp_if_new_hook(struct interface *ifp)
    3420             : {
    3421           8 :         struct bgp_interface *iifp;
    3422             : 
    3423           8 :         if (ifp->info)
    3424             :                 return 0;
    3425           8 :         iifp = XCALLOC(MTYPE_BGP_IF_INFO, sizeof(struct bgp_interface));
    3426           8 :         ifp->info = iifp;
    3427             : 
    3428           8 :         return 0;
    3429             : }
    3430             : 
    3431           8 : static int bgp_if_delete_hook(struct interface *ifp)
    3432             : {
    3433           8 :         XFREE(MTYPE_BGP_IF_INFO, ifp->info);
    3434           8 :         return 0;
    3435             : }
    3436             : 
    3437           3 : void bgp_if_init(void)
    3438             : {
    3439             :         /* Initialize Zebra interface data structure. */
    3440           3 :         hook_register_prio(if_add, 0, bgp_if_new_hook);
    3441           3 :         hook_register_prio(if_del, 0, bgp_if_delete_hook);
    3442           3 : }
    3443             : 
    3444           3 : void bgp_zebra_init(struct thread_master *master, unsigned short instance)
    3445             : {
    3446           3 :         zclient_num_connects = 0;
    3447             : 
    3448           3 :         if_zapi_callbacks(bgp_ifp_create, bgp_ifp_up,
    3449             :                           bgp_ifp_down, bgp_ifp_destroy);
    3450             : 
    3451             :         /* Set default values. */
    3452           3 :         zclient = zclient_new(master, &zclient_options_default, bgp_handlers,
    3453             :                               array_size(bgp_handlers));
    3454           3 :         zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
    3455           3 :         zclient->zebra_connected = bgp_zebra_connected;
    3456           3 :         zclient->instance = instance;
    3457           3 : }
    3458             : 
    3459           3 : void bgp_zebra_destroy(void)
    3460             : {
    3461           3 :         if (zclient == NULL)
    3462             :                 return;
    3463           3 :         zclient_stop(zclient);
    3464           3 :         zclient_free(zclient);
    3465           3 :         zclient = NULL;
    3466             : }
    3467             : 
    3468          36 : int bgp_zebra_num_connects(void)
    3469             : {
    3470          36 :         return zclient_num_connects;
    3471             : }
    3472             : 
    3473           0 : void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
    3474             :                               struct bgp_pbr_rule *pbr,
    3475             :                               bool install)
    3476             : {
    3477           0 :         struct stream *s;
    3478             : 
    3479           0 :         if (pbra->install_in_progress && !pbr)
    3480             :                 return;
    3481           0 :         if (pbr && pbr->install_in_progress)
    3482             :                 return;
    3483           0 :         if (BGP_DEBUG(zebra, ZEBRA)) {
    3484           0 :                 if (pbr)
    3485           0 :                         zlog_debug("%s: table %d (ip rule) %d", __func__,
    3486             :                                    pbra->table_id, install);
    3487             :                 else
    3488           0 :                         zlog_debug("%s: table %d fwmark %d %d", __func__,
    3489             :                                    pbra->table_id, pbra->fwmark, install);
    3490             :         }
    3491           0 :         s = zclient->obuf;
    3492           0 :         stream_reset(s);
    3493             : 
    3494           0 :         zclient_create_header(s,
    3495             :                               install ? ZEBRA_RULE_ADD : ZEBRA_RULE_DELETE,
    3496             :                               VRF_DEFAULT);
    3497           0 :         stream_putl(s, 1); /* send one pbr action */
    3498             : 
    3499           0 :         bgp_encode_pbr_rule_action(s, pbra, pbr);
    3500             : 
    3501           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    3502           0 :         if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE)
    3503           0 :             && install) {
    3504           0 :                 if (!pbr)
    3505           0 :                         pbra->install_in_progress = true;
    3506             :                 else
    3507           0 :                         pbr->install_in_progress = true;
    3508             :         }
    3509             : }
    3510             : 
    3511           0 : void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
    3512             : {
    3513           0 :         struct stream *s;
    3514             : 
    3515           0 :         if (pbrim->install_in_progress)
    3516             :                 return;
    3517           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3518           0 :                 zlog_debug("%s: name %s type %d %d, ID %u", __func__,
    3519             :                            pbrim->ipset_name, pbrim->type, install,
    3520             :                            pbrim->unique);
    3521           0 :         s = zclient->obuf;
    3522           0 :         stream_reset(s);
    3523             : 
    3524           0 :         zclient_create_header(s,
    3525             :                               install ? ZEBRA_IPSET_CREATE :
    3526             :                               ZEBRA_IPSET_DESTROY,
    3527             :                               VRF_DEFAULT);
    3528             : 
    3529           0 :         stream_putl(s, 1); /* send one pbr action */
    3530             : 
    3531           0 :         bgp_encode_pbr_ipset_match(s, pbrim);
    3532             : 
    3533           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    3534           0 :         if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
    3535           0 :                 pbrim->install_in_progress = true;
    3536             : }
    3537             : 
    3538           0 : void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
    3539             :                                     bool install)
    3540             : {
    3541           0 :         struct stream *s;
    3542             : 
    3543           0 :         if (pbrime->install_in_progress)
    3544             :                 return;
    3545           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3546           0 :                 zlog_debug("%s: name %s %d %d, ID %u", __func__,
    3547             :                            pbrime->backpointer->ipset_name, pbrime->unique,
    3548             :                            install, pbrime->unique);
    3549           0 :         s = zclient->obuf;
    3550           0 :         stream_reset(s);
    3551             : 
    3552           0 :         zclient_create_header(s,
    3553             :                               install ? ZEBRA_IPSET_ENTRY_ADD :
    3554             :                               ZEBRA_IPSET_ENTRY_DELETE,
    3555             :                               VRF_DEFAULT);
    3556             : 
    3557           0 :         stream_putl(s, 1); /* send one pbr action */
    3558             : 
    3559           0 :         bgp_encode_pbr_ipset_entry_match(s, pbrime);
    3560             : 
    3561           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    3562           0 :         if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
    3563           0 :                 pbrime->install_in_progress = true;
    3564             : }
    3565             : 
    3566           0 : static void bgp_encode_pbr_interface_list(struct bgp *bgp, struct stream *s,
    3567             :                                           uint8_t family)
    3568             : {
    3569           0 :         struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
    3570           0 :         struct bgp_pbr_interface_head *head;
    3571           0 :         struct bgp_pbr_interface *pbr_if;
    3572           0 :         struct interface *ifp;
    3573             : 
    3574           0 :         if (!bgp_pbr_cfg)
    3575             :                 return;
    3576           0 :         if (family == AF_INET)
    3577           0 :                 head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
    3578             :         else
    3579           0 :                 head = &(bgp_pbr_cfg->ifaces_by_name_ipv6);
    3580           0 :         RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
    3581           0 :                 ifp = if_lookup_by_name(pbr_if->name, bgp->vrf_id);
    3582           0 :                 if (ifp)
    3583           0 :                         stream_putl(s, ifp->ifindex);
    3584             :         }
    3585             : }
    3586             : 
    3587           0 : static int bgp_pbr_get_ifnumber(struct bgp *bgp, uint8_t family)
    3588             : {
    3589           0 :         struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
    3590           0 :         struct bgp_pbr_interface_head *head;
    3591           0 :         struct bgp_pbr_interface *pbr_if;
    3592           0 :         int cnt = 0;
    3593             : 
    3594           0 :         if (!bgp_pbr_cfg)
    3595             :                 return 0;
    3596           0 :         if (family == AF_INET)
    3597           0 :                 head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
    3598             :         else
    3599           0 :                 head = &(bgp_pbr_cfg->ifaces_by_name_ipv6);
    3600           0 :         RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
    3601           0 :                 if (if_lookup_by_name(pbr_if->name, bgp->vrf_id))
    3602           0 :                         cnt++;
    3603             :         }
    3604             :         return cnt;
    3605             : }
    3606             : 
    3607           0 : void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
    3608             :                           struct bgp_pbr_match *pbm,
    3609             :                           bool install)
    3610             : {
    3611           0 :         struct stream *s;
    3612           0 :         int ret = 0;
    3613           0 :         int nb_interface;
    3614             : 
    3615           0 :         if (pbm->install_iptable_in_progress)
    3616             :                 return;
    3617           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3618           0 :                 zlog_debug("%s: name %s type %d mark %d %d, ID %u", __func__,
    3619             :                            pbm->ipset_name, pbm->type, pba->fwmark, install,
    3620             :                            pbm->unique2);
    3621           0 :         s = zclient->obuf;
    3622           0 :         stream_reset(s);
    3623             : 
    3624           0 :         zclient_create_header(s,
    3625             :                               install ? ZEBRA_IPTABLE_ADD :
    3626             :                               ZEBRA_IPTABLE_DELETE,
    3627             :                               VRF_DEFAULT);
    3628             : 
    3629           0 :         bgp_encode_pbr_iptable_match(s, pba, pbm);
    3630           0 :         nb_interface = bgp_pbr_get_ifnumber(pba->bgp, pbm->family);
    3631           0 :         stream_putl(s, nb_interface);
    3632           0 :         if (nb_interface)
    3633           0 :                 bgp_encode_pbr_interface_list(pba->bgp, s, pbm->family);
    3634           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    3635           0 :         ret = zclient_send_message(zclient);
    3636           0 :         if (install) {
    3637           0 :                 if (ret != ZCLIENT_SEND_FAILURE)
    3638           0 :                         pba->refcnt++;
    3639             :                 else
    3640           0 :                         pbm->install_iptable_in_progress = true;
    3641             :         }
    3642             : }
    3643             : 
    3644             : /* inject in table <table_id> a default route to:
    3645             :  * - if nexthop IP is present : to this nexthop
    3646             :  * - if vrf is different from local : to the matching VRF
    3647             :  */
    3648           0 : void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
    3649             :                                 afi_t afi, uint32_t table_id, bool announce)
    3650             : {
    3651           0 :         struct zapi_nexthop *api_nh;
    3652           0 :         struct zapi_route api;
    3653           0 :         struct prefix p;
    3654             : 
    3655           0 :         if (!nh || (nh->type != NEXTHOP_TYPE_IPV4
    3656           0 :                     && nh->type != NEXTHOP_TYPE_IPV6)
    3657           0 :             || nh->vrf_id == VRF_UNKNOWN)
    3658           0 :                 return;
    3659             : 
    3660             :         /* in vrf-lite, no default route has to be announced
    3661             :          * the table id of vrf is directly used to divert traffic
    3662             :          */
    3663           0 :         if (!vrf_is_backend_netns() && bgp->vrf_id != nh->vrf_id)
    3664             :                 return;
    3665             : 
    3666           0 :         memset(&p, 0, sizeof(p));
    3667           0 :         if (afi != AFI_IP && afi != AFI_IP6)
    3668             :                 return;
    3669           0 :         p.family = afi2family(afi);
    3670           0 :         memset(&api, 0, sizeof(api));
    3671           0 :         api.vrf_id = bgp->vrf_id;
    3672           0 :         api.type = ZEBRA_ROUTE_BGP;
    3673           0 :         api.safi = SAFI_UNICAST;
    3674           0 :         api.prefix = p;
    3675           0 :         api.tableid = table_id;
    3676           0 :         api.nexthop_num = 1;
    3677           0 :         SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
    3678           0 :         SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
    3679           0 :         api_nh = &api.nexthops[0];
    3680             : 
    3681           0 :         api.distance = ZEBRA_EBGP_DISTANCE_DEFAULT;
    3682           0 :         SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
    3683             : 
    3684             :         /* redirect IP */
    3685           0 :         if (afi == AFI_IP && nh->gate.ipv4.s_addr != INADDR_ANY) {
    3686           0 :                 api_nh->vrf_id = nh->vrf_id;
    3687           0 :                 api_nh->gate.ipv4 = nh->gate.ipv4;
    3688           0 :                 api_nh->type = NEXTHOP_TYPE_IPV4;
    3689             : 
    3690           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3691           0 :                         zlog_debug(
    3692             :                                 "BGP: %s default route to %pI4 table %d (redirect IP)",
    3693             :                                 announce ? "adding" : "withdrawing",
    3694             :                                 &nh->gate.ipv4, table_id);
    3695             : 
    3696           0 :                 zclient_route_send(announce ? ZEBRA_ROUTE_ADD
    3697             :                                    : ZEBRA_ROUTE_DELETE,
    3698             :                                    zclient, &api);
    3699           0 :         } else if (afi == AFI_IP6 &&
    3700           0 :                    memcmp(&nh->gate.ipv6,
    3701             :                           &in6addr_any, sizeof(struct in6_addr))) {
    3702           0 :                 api_nh->vrf_id = nh->vrf_id;
    3703           0 :                 memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6,
    3704             :                        sizeof(struct in6_addr));
    3705           0 :                 api_nh->type = NEXTHOP_TYPE_IPV6;
    3706             : 
    3707           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3708           0 :                         zlog_debug(
    3709             :                                 "BGP: %s default route to %pI6 table %d (redirect IP)",
    3710             :                                 announce ? "adding" : "withdrawing",
    3711             :                                 &nh->gate.ipv6, table_id);
    3712             : 
    3713           0 :                 zclient_route_send(announce ? ZEBRA_ROUTE_ADD
    3714             :                                    : ZEBRA_ROUTE_DELETE,
    3715             :                                    zclient, &api);
    3716           0 :         } else if (nh->vrf_id != bgp->vrf_id) {
    3717           0 :                 struct vrf *vrf;
    3718           0 :                 struct interface *ifp;
    3719             : 
    3720           0 :                 vrf = vrf_lookup_by_id(nh->vrf_id);
    3721           0 :                 if (!vrf)
    3722             :                         return;
    3723             :                 /* create default route with interface <VRF>
    3724             :                  * with nexthop-vrf <VRF>
    3725             :                  */
    3726           0 :                 ifp = if_lookup_by_name_vrf(vrf->name, vrf);
    3727           0 :                 if (!ifp)
    3728             :                         return;
    3729           0 :                 api_nh->vrf_id = nh->vrf_id;
    3730           0 :                 api_nh->type = NEXTHOP_TYPE_IFINDEX;
    3731           0 :                 api_nh->ifindex = ifp->ifindex;
    3732           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3733           0 :                         zlog_info("BGP: %s default route to %s table %d (redirect VRF)",
    3734             :                                   announce ? "adding" : "withdrawing",
    3735             :                                   vrf->name, table_id);
    3736           0 :                 zclient_route_send(announce ? ZEBRA_ROUTE_ADD
    3737             :                                    : ZEBRA_ROUTE_DELETE,
    3738             :                                    zclient, &api);
    3739           0 :                 return;
    3740             :         }
    3741             : }
    3742             : 
    3743             : /* Send capabilities to RIB */
    3744           0 : int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
    3745             : {
    3746           0 :         struct zapi_cap api;
    3747           0 :         int ret = BGP_GR_SUCCESS;
    3748             : 
    3749           0 :         if (zclient == NULL) {
    3750           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3751           0 :                         zlog_debug("zclient invalid");
    3752           0 :                 return BGP_GR_FAILURE;
    3753             :         }
    3754             : 
    3755             :         /* Check if the client is connected */
    3756           0 :         if ((zclient->sock < 0) || (zclient->t_connect)) {
    3757           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3758           0 :                         zlog_debug("client not connected");
    3759           0 :                 return BGP_GR_FAILURE;
    3760             :         }
    3761             : 
    3762             :         /* Check if capability is already sent. If the flag force is set
    3763             :          * send the capability since this can be initial bgp configuration
    3764             :          */
    3765           0 :         memset(&api, 0, sizeof(api));
    3766           0 :         if (disable) {
    3767           0 :                 api.cap = ZEBRA_CLIENT_GR_DISABLE;
    3768           0 :                 api.vrf_id = bgp->vrf_id;
    3769             :         } else {
    3770           0 :                 api.cap = ZEBRA_CLIENT_GR_CAPABILITIES;
    3771           0 :                 api.stale_removal_time = bgp->rib_stale_time;
    3772           0 :                 api.vrf_id = bgp->vrf_id;
    3773             :         }
    3774             : 
    3775           0 :         if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
    3776             :             == ZCLIENT_SEND_FAILURE) {
    3777           0 :                 zlog_err("error sending capability");
    3778           0 :                 ret = BGP_GR_FAILURE;
    3779             :         } else {
    3780           0 :                 if (disable)
    3781           0 :                         bgp->present_zebra_gr_state = ZEBRA_GR_DISABLE;
    3782             :                 else
    3783           0 :                         bgp->present_zebra_gr_state = ZEBRA_GR_ENABLE;
    3784             : 
    3785           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3786           0 :                         zlog_debug("send capabilty success");
    3787             :                 ret = BGP_GR_SUCCESS;
    3788             :         }
    3789             :         return ret;
    3790             : }
    3791             : 
    3792             : /* Send route update pesding or completed status to RIB for the
    3793             :  * specific AFI, SAFI
    3794             :  */
    3795          88 : int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type)
    3796             : {
    3797          88 :         struct zapi_cap api = {0};
    3798             : 
    3799          88 :         if (zclient == NULL) {
    3800           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3801           0 :                         zlog_debug("zclient == NULL, invalid");
    3802           0 :                 return BGP_GR_FAILURE;
    3803             :         }
    3804             : 
    3805             :         /* Check if the client is connected */
    3806          88 :         if ((zclient->sock < 0) || (zclient->t_connect)) {
    3807           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3808           0 :                         zlog_debug("client not connected");
    3809           0 :                 return BGP_GR_FAILURE;
    3810             :         }
    3811             : 
    3812          88 :         api.afi = afi;
    3813          88 :         api.safi = safi;
    3814          88 :         api.vrf_id = vrf_id;
    3815          88 :         api.cap = type;
    3816             : 
    3817          88 :         if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
    3818             :             == ZCLIENT_SEND_FAILURE) {
    3819           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3820           0 :                         zlog_debug("error sending capability");
    3821           0 :                 return BGP_GR_FAILURE;
    3822             :         }
    3823             :         return BGP_GR_SUCCESS;
    3824             : }
    3825             : 
    3826             : 
    3827             : /* Send RIB stale timer update */
    3828           0 : int bgp_zebra_stale_timer_update(struct bgp *bgp)
    3829             : {
    3830           0 :         struct zapi_cap api;
    3831             : 
    3832           0 :         if (zclient == NULL) {
    3833           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3834           0 :                         zlog_debug("zclient invalid");
    3835           0 :                 return BGP_GR_FAILURE;
    3836             :         }
    3837             : 
    3838             :         /* Check if the client is connected */
    3839           0 :         if ((zclient->sock < 0) || (zclient->t_connect)) {
    3840           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3841           0 :                         zlog_debug("client not connected");
    3842           0 :                 return BGP_GR_FAILURE;
    3843             :         }
    3844             : 
    3845           0 :         memset(&api, 0, sizeof(api));
    3846           0 :         api.cap = ZEBRA_CLIENT_RIB_STALE_TIME;
    3847           0 :         api.stale_removal_time = bgp->rib_stale_time;
    3848           0 :         api.vrf_id = bgp->vrf_id;
    3849           0 :         if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
    3850             :             == ZCLIENT_SEND_FAILURE) {
    3851           0 :                 if (BGP_DEBUG(zebra, ZEBRA))
    3852           0 :                         zlog_debug("error sending capability");
    3853           0 :                 return BGP_GR_FAILURE;
    3854             :         }
    3855           0 :         if (BGP_DEBUG(zebra, ZEBRA))
    3856           0 :                 zlog_debug("send capabilty success");
    3857             :         return BGP_GR_SUCCESS;
    3858             : }
    3859             : 
    3860           0 : int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
    3861             : {
    3862           0 :         return srv6_manager_get_locator_chunk(zclient, name);
    3863             : }
    3864             : 
    3865           0 : int bgp_zebra_srv6_manager_release_locator_chunk(const char *name)
    3866             : {
    3867           0 :         return srv6_manager_release_locator_chunk(zclient, name);
    3868             : }

Generated by: LCOV version v1.16-topotato