LCOV - code coverage report
Current view: top level - bgpd - bgp_zebra.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 9 488 1.8 %
Date: 2015-11-19 Functions: 1 27 3.7 %

          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
      17             : along with GNU Zebra; see the file COPYING.  If not, write to the
      18             : Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      19             : Boston, MA 02111-1307, USA.  */
      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             : 
      33             : #include "bgpd/bgpd.h"
      34             : #include "bgpd/bgp_route.h"
      35             : #include "bgpd/bgp_attr.h"
      36             : #include "bgpd/bgp_nexthop.h"
      37             : #include "bgpd/bgp_zebra.h"
      38             : #include "bgpd/bgp_fsm.h"
      39             : #include "bgpd/bgp_debug.h"
      40             : #include "bgpd/bgp_mpath.h"
      41             : 
      42             : /* All information about zebra. */
      43             : struct zclient *zclient = NULL;
      44             : struct in_addr router_id_zebra;
      45             : 
      46             : /* Growable buffer for nexthops sent to zebra */
      47             : struct stream *bgp_nexthop_buf = NULL;
      48             : 
      49             : /* Router-id update message from zebra. */
      50             : static int
      51           0 : bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
      52             : {
      53             :   struct prefix router_id;
      54             :   struct listnode *node, *nnode;
      55             :   struct bgp *bgp;
      56             : 
      57           0 :   zebra_router_id_update_read(zclient->ibuf,&router_id);
      58             : 
      59           0 :   if (BGP_DEBUG(zebra, ZEBRA))
      60             :     {
      61             :       char buf[128];
      62           0 :       prefix2str(&router_id, buf, sizeof(buf));
      63           0 :       zlog_debug("Zebra rcvd: router id update %s", buf);
      64             :     }
      65             : 
      66           0 :   router_id_zebra = router_id.u.prefix4;
      67             : 
      68           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
      69             :     {
      70           0 :       if (!bgp->router_id_static.s_addr)
      71           0 :         bgp_router_id_set (bgp, &router_id.u.prefix4);
      72             :     }
      73             : 
      74           0 :   return 0;
      75             : }
      76             : 
      77             : /* Inteface addition message from zebra. */
      78             : static int
      79           0 : bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
      80             : {
      81             :   struct interface *ifp;
      82             : 
      83           0 :   ifp = zebra_interface_add_read (zclient->ibuf);
      84             : 
      85           0 :   if (BGP_DEBUG(zebra, ZEBRA) && ifp)
      86           0 :     zlog_debug("Zebra rcvd: interface add %s", ifp->name);
      87             : 
      88           0 :   return 0;
      89             : }
      90             : 
      91             : static int
      92           0 : bgp_interface_delete (int command, struct zclient *zclient,
      93             :                       zebra_size_t length)
      94             : {
      95             :   struct stream *s;
      96             :   struct interface *ifp;
      97             : 
      98           0 :   s = zclient->ibuf;
      99           0 :   ifp = zebra_interface_state_read (s);
     100           0 :   ifp->ifindex = IFINDEX_INTERNAL;
     101             : 
     102           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     103           0 :     zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
     104             : 
     105           0 :   return 0;
     106             : }
     107             : 
     108             : static int
     109           0 : bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
     110             : {
     111             :   struct stream *s;
     112             :   struct interface *ifp;
     113             :   struct connected *c;
     114             :   struct listnode *node, *nnode;
     115             : 
     116           0 :   s = zclient->ibuf;
     117           0 :   ifp = zebra_interface_state_read (s);
     118             : 
     119           0 :   if (! ifp)
     120           0 :     return 0;
     121             : 
     122           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     123           0 :     zlog_debug("Zebra rcvd: interface %s up", ifp->name);
     124             : 
     125           0 :   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
     126           0 :     bgp_connected_add (c);
     127             : 
     128           0 :   return 0;
     129             : }
     130             : 
     131             : static int
     132           0 : bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
     133             : {
     134             :   struct stream *s;
     135             :   struct interface *ifp;
     136             :   struct connected *c;
     137             :   struct listnode *node, *nnode;
     138             : 
     139           0 :   s = zclient->ibuf;
     140           0 :   ifp = zebra_interface_state_read (s);
     141           0 :   if (! ifp)
     142           0 :     return 0;
     143             : 
     144           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     145           0 :     zlog_debug("Zebra rcvd: interface %s down", ifp->name);
     146             : 
     147           0 :   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
     148           0 :     bgp_connected_delete (c);
     149             : 
     150             :   /* Fast external-failover (Currently IPv4 only) */
     151             :   {
     152             :     struct listnode *mnode;
     153             :     struct bgp *bgp;
     154             :     struct peer *peer;
     155             :     struct interface *peer_if;
     156             : 
     157           0 :     for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
     158             :       {
     159           0 :         if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
     160           0 :           continue;
     161             : 
     162           0 :         for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
     163             :           {
     164           0 :             if (peer->ttl != 1)
     165           0 :               continue;
     166             : 
     167           0 :             if (peer->su.sa.sa_family == AF_INET)
     168           0 :               peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
     169             :             else
     170           0 :               continue;
     171             : 
     172           0 :             if (ifp == peer_if)
     173           0 :               BGP_EVENT_ADD (peer, BGP_Stop);
     174             :           }
     175             :       }
     176             :   }
     177             : 
     178           0 :   return 0;
     179             : }
     180             : 
     181             : static int
     182           0 : bgp_interface_address_add (int command, struct zclient *zclient,
     183             :                            zebra_size_t length)
     184             : {
     185             :   struct connected *ifc;
     186             : 
     187           0 :   ifc = zebra_interface_address_read (command, zclient->ibuf);
     188             : 
     189           0 :   if (ifc == NULL)
     190           0 :     return 0;
     191             : 
     192           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     193             :     {
     194             :       char buf[128];
     195           0 :       prefix2str(ifc->address, buf, sizeof(buf));
     196           0 :       zlog_debug("Zebra rcvd: interface %s address add %s",
     197           0 :                  ifc->ifp->name, buf);
     198             :     }
     199             : 
     200           0 :   if (if_is_operative (ifc->ifp))
     201           0 :     bgp_connected_add (ifc);
     202             : 
     203           0 :   return 0;
     204             : }
     205             : 
     206             : static int
     207           0 : bgp_interface_address_delete (int command, struct zclient *zclient,
     208             :                               zebra_size_t length)
     209             : {
     210             :   struct connected *ifc;
     211             : 
     212           0 :   ifc = zebra_interface_address_read (command, zclient->ibuf);
     213             : 
     214           0 :   if (ifc == NULL)
     215           0 :     return 0;
     216             : 
     217           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     218             :     {
     219             :       char buf[128];
     220           0 :       prefix2str(ifc->address, buf, sizeof(buf));
     221           0 :       zlog_debug("Zebra rcvd: interface %s address delete %s",
     222           0 :                  ifc->ifp->name, buf);
     223             :     }
     224             : 
     225           0 :   if (if_is_operative (ifc->ifp))
     226           0 :     bgp_connected_delete (ifc);
     227             : 
     228           0 :   connected_free (ifc);
     229             : 
     230           0 :   return 0;
     231             : }
     232             : 
     233             : /* Zebra route add and delete treatment. */
     234             : static int
     235           0 : zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
     236             : {
     237             :   struct stream *s;
     238             :   struct zapi_ipv4 api;
     239             :   struct in_addr nexthop;
     240             :   struct prefix_ipv4 p;
     241             : 
     242           0 :   s = zclient->ibuf;
     243           0 :   nexthop.s_addr = 0;
     244             : 
     245             :   /* Type, flags, message. */
     246           0 :   api.type = stream_getc (s);
     247           0 :   api.flags = stream_getc (s);
     248           0 :   api.message = stream_getc (s);
     249             : 
     250             :   /* IPv4 prefix. */
     251           0 :   memset (&p, 0, sizeof (struct prefix_ipv4));
     252           0 :   p.family = AF_INET;
     253           0 :   p.prefixlen = stream_getc (s);
     254           0 :   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
     255             : 
     256             :   /* Nexthop, ifindex, distance, metric. */
     257           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
     258             :     {
     259           0 :       api.nexthop_num = stream_getc (s);
     260           0 :       nexthop.s_addr = stream_get_ipv4 (s);
     261             :     }
     262           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
     263             :     {
     264           0 :       api.ifindex_num = stream_getc (s);
     265           0 :       stream_getl (s); /* ifindex, unused */
     266             :     }
     267           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
     268           0 :     api.distance = stream_getc (s);
     269           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
     270           0 :     api.metric = stream_getl (s);
     271             :   else
     272           0 :     api.metric = 0;
     273             : 
     274           0 :   if (command == ZEBRA_IPV4_ROUTE_ADD)
     275             :     {
     276           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     277             :         {
     278             :           char buf[2][INET_ADDRSTRLEN];
     279           0 :           zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
     280           0 :                      zebra_route_string(api.type),
     281             :                      inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
     282           0 :                      p.prefixlen,
     283             :                      inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
     284             :                      api.metric);
     285             :         }
     286           0 :       bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
     287           0 :                            api.metric, api.type);
     288             :     }
     289             :   else
     290             :     {
     291           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     292             :         {
     293             :           char buf[2][INET_ADDRSTRLEN];
     294           0 :           zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
     295             :                      "nexthop %s metric %u",
     296           0 :                      zebra_route_string(api.type),
     297             :                      inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
     298           0 :                      p.prefixlen,
     299             :                      inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
     300             :                      api.metric);
     301             :         }
     302           0 :       bgp_redistribute_delete((struct prefix *)&p, api.type);
     303             :     }
     304             : 
     305           0 :   return 0;
     306             : }
     307             : 
     308             : #ifdef HAVE_IPV6
     309             : /* Zebra route add and delete treatment. */
     310             : static int
     311           0 : zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
     312             : {
     313             :   struct stream *s;
     314             :   struct zapi_ipv6 api;
     315             :   struct in6_addr nexthop;
     316             :   struct prefix_ipv6 p, src_p;
     317             : 
     318           0 :   s = zclient->ibuf;
     319           0 :   memset (&nexthop, 0, sizeof (struct in6_addr));
     320             : 
     321             :   /* Type, flags, message. */
     322           0 :   api.type = stream_getc (s);
     323           0 :   api.flags = stream_getc (s);
     324           0 :   api.message = stream_getc (s);
     325             : 
     326             :   /* IPv6 prefix. */
     327           0 :   memset (&p, 0, sizeof (struct prefix_ipv6));
     328           0 :   p.family = AF_INET6;
     329           0 :   p.prefixlen = stream_getc (s);
     330           0 :   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
     331             : 
     332           0 :   memset (&src_p, 0, sizeof (struct prefix_ipv6));
     333           0 :   src_p.family = AF_INET6;
     334           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
     335             :     {
     336           0 :       src_p.prefixlen = stream_getc (s);
     337           0 :       stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
     338             :     }
     339             : 
     340           0 :   if (src_p.prefixlen)
     341             :     /* we completely ignore srcdest routes for now. */
     342           0 :     return;
     343             : 
     344             :   /* Nexthop, ifindex, distance, metric. */
     345           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
     346             :     {
     347           0 :       api.nexthop_num = stream_getc (s);
     348           0 :       stream_get (&nexthop, s, 16);
     349             :     }
     350           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
     351             :     {
     352           0 :       api.ifindex_num = stream_getc (s);
     353           0 :       stream_getl (s); /* ifindex, unused */
     354             :     }
     355           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
     356           0 :     api.distance = stream_getc (s);
     357             :   else
     358           0 :     api.distance = 0;
     359           0 :   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
     360           0 :     api.metric = stream_getl (s);
     361             :   else
     362           0 :     api.metric = 0;
     363             : 
     364             :   /* Simply ignore link-local address. */
     365           0 :   if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
     366           0 :     return 0;
     367             : 
     368           0 :   if (command == ZEBRA_IPV6_ROUTE_ADD)
     369             :     {
     370           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     371             :         {
     372             :           char buf[2][INET6_ADDRSTRLEN];
     373           0 :           zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
     374           0 :                      zebra_route_string(api.type),
     375             :                      inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
     376           0 :                      p.prefixlen,
     377             :                      inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
     378             :                      api.metric);
     379             :         }
     380           0 :       bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
     381           0 :                             api.metric, api.type);
     382             :     }
     383             :   else
     384             :     {
     385           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     386             :         {
     387             :           char buf[2][INET6_ADDRSTRLEN];
     388           0 :           zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
     389             :                      "nexthop %s metric %u",
     390           0 :                      zebra_route_string(api.type),
     391             :                      inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
     392           0 :                      p.prefixlen,
     393             :                      inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
     394             :                      api.metric);
     395             :         }
     396           0 :       bgp_redistribute_delete ((struct prefix *) &p, api.type);
     397             :     }
     398             :   
     399           0 :   return 0;
     400             : }
     401             : #endif /* HAVE_IPV6 */
     402             : 
     403             : struct interface *
     404           0 : if_lookup_by_ipv4 (struct in_addr *addr)
     405             : {
     406             :   struct listnode *ifnode;
     407             :   struct listnode *cnode;
     408             :   struct interface *ifp;
     409             :   struct connected *connected;
     410             :   struct prefix_ipv4 p;
     411             :   struct prefix *cp; 
     412             :   
     413           0 :   p.family = AF_INET;
     414           0 :   p.prefix = *addr;
     415           0 :   p.prefixlen = IPV4_MAX_BITLEN;
     416             : 
     417           0 :   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
     418             :     {
     419           0 :       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     420             :         {
     421           0 :           cp = connected->address;
     422             :             
     423           0 :           if (cp->family == AF_INET)
     424           0 :             if (prefix_match (cp, (struct prefix *)&p))
     425           0 :               return ifp;
     426             :         }
     427             :     }
     428           0 :   return NULL;
     429             : }
     430             : 
     431             : struct interface *
     432           0 : if_lookup_by_ipv4_exact (struct in_addr *addr)
     433             : {
     434             :   struct listnode *ifnode;
     435             :   struct listnode *cnode;
     436             :   struct interface *ifp;
     437             :   struct connected *connected;
     438             :   struct prefix *cp; 
     439             :   
     440           0 :   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
     441             :     {
     442           0 :       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     443             :         {
     444           0 :           cp = connected->address;
     445             :             
     446           0 :           if (cp->family == AF_INET)
     447           0 :             if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
     448           0 :               return ifp;
     449             :         }
     450             :     }
     451           0 :   return NULL;
     452             : }
     453             : 
     454             : #ifdef HAVE_IPV6
     455             : struct interface *
     456           0 : if_lookup_by_ipv6 (struct in6_addr *addr)
     457             : {
     458             :   struct listnode *ifnode;
     459             :   struct listnode *cnode;
     460             :   struct interface *ifp;
     461             :   struct connected *connected;
     462             :   struct prefix_ipv6 p;
     463             :   struct prefix *cp; 
     464             :   
     465           0 :   p.family = AF_INET6;
     466           0 :   p.prefix = *addr;
     467           0 :   p.prefixlen = IPV6_MAX_BITLEN;
     468             : 
     469           0 :   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
     470             :     {
     471           0 :       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     472             :         {
     473           0 :           cp = connected->address;
     474             :             
     475           0 :           if (cp->family == AF_INET6)
     476           0 :             if (prefix_match (cp, (struct prefix *)&p))
     477           0 :               return ifp;
     478             :         }
     479             :     }
     480           0 :   return NULL;
     481             : }
     482             : 
     483             : struct interface *
     484           0 : if_lookup_by_ipv6_exact (struct in6_addr *addr)
     485             : {
     486             :   struct listnode *ifnode;
     487             :   struct listnode *cnode;
     488             :   struct interface *ifp;
     489             :   struct connected *connected;
     490             :   struct prefix *cp; 
     491             : 
     492           0 :   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
     493             :     {
     494           0 :       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     495             :         {
     496           0 :           cp = connected->address;
     497             :             
     498           0 :           if (cp->family == AF_INET6)
     499           0 :             if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
     500           0 :               return ifp;
     501             :         }
     502             :     }
     503           0 :   return NULL;
     504             : }
     505             : 
     506             : static int
     507           0 : if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
     508             : {
     509             :   struct listnode *cnode;
     510             :   struct connected *connected;
     511             :   struct prefix *cp; 
     512             :   
     513           0 :   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     514             :     {
     515           0 :       cp = connected->address;
     516             :             
     517           0 :       if (cp->family == AF_INET6)
     518           0 :         if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
     519             :           {
     520           0 :             memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
     521           0 :             return 1;
     522             :           }
     523             :     }
     524           0 :   return 0;
     525             : }
     526             : 
     527             : static int
     528           0 : if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
     529             : {
     530             :   struct listnode *cnode;
     531             :   struct connected *connected;
     532             :   struct prefix *cp; 
     533             :   
     534           0 :   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     535             :     {
     536           0 :       cp = connected->address;
     537             :             
     538           0 :       if (cp->family == AF_INET6)
     539           0 :         if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
     540             :           {
     541           0 :             memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
     542           0 :             return 1;
     543             :           }
     544             :     }
     545           0 :   return 0;
     546             : }
     547             : #endif /* HAVE_IPV6 */
     548             : 
     549             : static int
     550           0 : if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
     551             : {
     552             :   struct listnode *cnode;
     553             :   struct connected *connected;
     554             :   struct prefix *cp;
     555             : 
     556           0 :   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
     557             :     {
     558           0 :       cp = connected->address;
     559           0 :       if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
     560             :           {
     561           0 :             *addr = cp->u.prefix4;
     562           0 :             return 1;
     563             :           }
     564             :     }
     565           0 :   return 0;
     566             : }
     567             : 
     568             : int
     569           0 : bgp_nexthop_set (union sockunion *local, union sockunion *remote, 
     570             :                  struct bgp_nexthop *nexthop, struct peer *peer)
     571             : {
     572           0 :   int ret = 0;
     573           0 :   struct interface *ifp = NULL;
     574             : 
     575           0 :   memset (nexthop, 0, sizeof (struct bgp_nexthop));
     576             : 
     577           0 :   if (!local)
     578           0 :     return -1;
     579           0 :   if (!remote)
     580           0 :     return -1;
     581             : 
     582           0 :   if (local->sa.sa_family == AF_INET)
     583             :     {
     584           0 :       nexthop->v4 = local->sin.sin_addr;
     585           0 :       ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
     586             :     }
     587             : #ifdef HAVE_IPV6
     588           0 :   if (local->sa.sa_family == AF_INET6)
     589             :     {
     590           0 :       if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
     591             :         {
     592           0 :           if (peer->ifname)
     593           0 :             ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
     594             :         }
     595             :       else
     596           0 :         ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
     597             :     }
     598             : #endif /* HAVE_IPV6 */
     599             : 
     600           0 :   if (!ifp)
     601           0 :     return -1;
     602             : 
     603           0 :   nexthop->ifp = ifp;
     604             : 
     605             :   /* IPv4 connection. */
     606           0 :   if (local->sa.sa_family == AF_INET)
     607             :     {
     608             : #ifdef HAVE_IPV6
     609             :       /* IPv6 nexthop*/
     610           0 :       ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
     611             : 
     612             :       /* There is no global nexthop. */
     613           0 :       if (!ret)
     614           0 :         if_get_ipv6_local (ifp, &nexthop->v6_global);
     615             :       else
     616           0 :         if_get_ipv6_local (ifp, &nexthop->v6_local);
     617             : #endif /* HAVE_IPV6 */
     618             :     }
     619             : 
     620             : #ifdef HAVE_IPV6
     621             :   /* IPv6 connection. */
     622           0 :   if (local->sa.sa_family == AF_INET6)
     623             :     {
     624           0 :       struct interface *direct = NULL;
     625             : 
     626             :       /* IPv4 nexthop. */
     627           0 :       ret = if_get_ipv4_address(ifp, &nexthop->v4);
     628           0 :       if (!ret && peer->local_id.s_addr)
     629           0 :         nexthop->v4 = peer->local_id;
     630             : 
     631             :       /* Global address*/
     632           0 :       if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
     633             :         {
     634           0 :           memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
     635             :                   IPV6_MAX_BYTELEN);
     636             : 
     637             :           /* If directory connected set link-local address. */
     638           0 :           direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
     639           0 :           if (direct)
     640           0 :             if_get_ipv6_local (ifp, &nexthop->v6_local);
     641             :         }
     642             :       else
     643             :         /* Link-local address. */
     644             :         {
     645           0 :           ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
     646             : 
     647             :           /* If there is no global address.  Set link-local address as
     648             :              global.  I know this break RFC specification... */
     649           0 :           if (!ret)
     650           0 :             memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
     651             :                     IPV6_MAX_BYTELEN);
     652             :           else
     653           0 :             memcpy (&nexthop->v6_local, &local->sin6.sin6_addr, 
     654             :                     IPV6_MAX_BYTELEN);
     655             :         }
     656             :     }
     657             : 
     658           0 :   if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
     659           0 :       if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
     660           0 :     peer->shared_network = 1;
     661             :   else
     662           0 :     peer->shared_network = 0;
     663             : 
     664             :   /* KAME stack specific treatment.  */
     665             : #ifdef KAME
     666             :   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
     667             :       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
     668             :     {
     669             :       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
     670             :     }
     671             :   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
     672             :       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
     673             :     {
     674             :       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
     675             :     }
     676             : #endif /* KAME */
     677             : #endif /* HAVE_IPV6 */
     678           0 :   return ret;
     679             : }
     680             : 
     681             : void
     682           0 : bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
     683             : {
     684             :   int flags;
     685             :   u_char distance;
     686             :   struct peer *peer;
     687             :   struct bgp_info *mpinfo;
     688             :   size_t oldsize, newsize;
     689             : 
     690           0 :   if (zclient->sock < 0)
     691           0 :     return;
     692             : 
     693           0 :   if (! zclient->redist[ZEBRA_ROUTE_BGP])
     694           0 :     return;
     695             : 
     696           0 :   flags = 0;
     697           0 :   peer = info->peer;
     698             : 
     699           0 :   if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
     700             :     {
     701           0 :       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
     702           0 :       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
     703             :     }
     704             : 
     705           0 :   if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
     706           0 :       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
     707           0 :     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
     708             : 
     709             :   /* resize nexthop buffer size if necessary */
     710           0 :   if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
     711           0 :       (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
     712             :     {
     713           0 :       newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
     714           0 :       newsize = stream_resize (bgp_nexthop_buf, newsize);
     715           0 :       if (newsize == oldsize)
     716             :         {
     717           0 :           zlog_err ("can't resize nexthop buffer");
     718           0 :           return;
     719             :         }
     720             :     }
     721             : 
     722           0 :   stream_reset (bgp_nexthop_buf);
     723             : 
     724           0 :   if (p->family == AF_INET)
     725             :     {
     726             :       struct zapi_ipv4 api;
     727             :       struct in_addr *nexthop;
     728             : 
     729           0 :       api.flags = flags;
     730           0 :       nexthop = &info->attr->nexthop;
     731           0 :       stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
     732           0 :       for (mpinfo = bgp_info_mpath_first (info); mpinfo;
     733           0 :            mpinfo = bgp_info_mpath_next (mpinfo))
     734             :         {
     735           0 :           nexthop = &mpinfo->attr->nexthop;
     736           0 :           stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
     737             :         }
     738             : 
     739           0 :       api.type = ZEBRA_ROUTE_BGP;
     740           0 :       api.message = 0;
     741           0 :       api.safi = safi;
     742           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
     743           0 :       api.nexthop_num = 1 + bgp_info_mpath_count (info);
     744           0 :       api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
     745           0 :       api.ifindex_num = 0;
     746           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
     747           0 :       api.metric = info->attr->med;
     748             : 
     749           0 :       distance = bgp_distance_apply (p, info, bgp);
     750             : 
     751           0 :       if (distance)
     752             :         {
     753           0 :           SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
     754           0 :           api.distance = distance;
     755             :         }
     756             : 
     757           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     758             :         {
     759             :           int i;
     760             :           char buf[2][INET_ADDRSTRLEN];
     761           0 :           zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
     762             :                      " count %d",
     763           0 :                      inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
     764           0 :                      p->prefixlen,
     765           0 :                      inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
     766           0 :                      api.metric, api.nexthop_num);
     767           0 :           for (i = 1; i < api.nexthop_num; i++)
     768           0 :             zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
     769           0 :                        i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
     770             :                                     sizeof(buf[1])));
     771             :         }
     772             : 
     773           0 :       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
     774             :                        (struct prefix_ipv4 *) p, &api);
     775             :     }
     776             : #ifdef HAVE_IPV6
     777             :   /* We have to think about a IPv6 link-local address curse. */
     778           0 :   if (p->family == AF_INET6)
     779             :     {
     780             :       unsigned int ifindex;
     781             :       struct in6_addr *nexthop;
     782             :       struct zapi_ipv6 api;
     783             : 
     784           0 :       ifindex = 0;
     785           0 :       nexthop = NULL;
     786             :       
     787           0 :       assert (info->attr->extra);
     788             :       
     789             :       /* Only global address nexthop exists. */
     790           0 :       if (info->attr->extra->mp_nexthop_len == 16)
     791           0 :         nexthop = &info->attr->extra->mp_nexthop_global;
     792             :       
     793             :       /* If both global and link-local address present. */
     794           0 :       if (info->attr->extra->mp_nexthop_len == 32)
     795             :         {
     796             :           /* Workaround for Cisco's nexthop bug.  */
     797           0 :           if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
     798           0 :               && peer->su_remote->sa.sa_family == AF_INET6)
     799           0 :             nexthop = &peer->su_remote->sin6.sin6_addr;
     800             :           else
     801           0 :             nexthop = &info->attr->extra->mp_nexthop_local;
     802             : 
     803           0 :           if (info->peer->nexthop.ifp)
     804           0 :             ifindex = info->peer->nexthop.ifp->ifindex;
     805             :         }
     806             : 
     807           0 :       if (nexthop == NULL)
     808           0 :         return;
     809             : 
     810           0 :       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
     811             :         {
     812           0 :           if (info->peer->ifname)
     813           0 :             ifindex = if_nametoindex (info->peer->ifname);
     814           0 :           else if (info->peer->nexthop.ifp)
     815           0 :             ifindex = info->peer->nexthop.ifp->ifindex;
     816             :         }
     817             : 
     818             :       /* Make Zebra API structure. */
     819           0 :       api.flags = flags;
     820           0 :       api.type = ZEBRA_ROUTE_BGP;
     821           0 :       api.message = 0;
     822           0 :       api.safi = safi;
     823           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
     824           0 :       api.nexthop_num = 1;
     825           0 :       api.nexthop = &nexthop;
     826           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
     827           0 :       api.ifindex_num = 1;
     828           0 :       api.ifindex = &ifindex;
     829           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
     830           0 :       api.metric = info->attr->med;
     831             : 
     832           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     833             :         {
     834             :           char buf[2][INET6_ADDRSTRLEN];
     835           0 :           zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
     836           0 :                      inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
     837           0 :                      p->prefixlen,
     838             :                      inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
     839             :                      api.metric);
     840             :         }
     841             : 
     842           0 :       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
     843             :                        (struct prefix_ipv6 *) p, NULL, &api);
     844             :     }
     845             : #endif /* HAVE_IPV6 */
     846             : }
     847             : 
     848             : void
     849           0 : bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
     850             : {
     851             :   int flags;
     852             :   struct peer *peer;
     853             : 
     854           0 :   if (zclient->sock < 0)
     855           0 :     return;
     856             : 
     857           0 :   if (! zclient->redist[ZEBRA_ROUTE_BGP])
     858           0 :     return;
     859             : 
     860           0 :   peer = info->peer;
     861           0 :   flags = 0;
     862             : 
     863           0 :   if (peer->sort == BGP_PEER_IBGP)
     864             :     {
     865           0 :       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
     866           0 :       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
     867             :     }
     868             : 
     869           0 :   if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
     870           0 :       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
     871           0 :     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
     872             : 
     873           0 :   if (p->family == AF_INET)
     874             :     {
     875             :       struct zapi_ipv4 api;
     876             :       struct in_addr *nexthop;
     877             : 
     878           0 :       api.flags = flags;
     879           0 :       nexthop = &info->attr->nexthop;
     880             : 
     881           0 :       api.type = ZEBRA_ROUTE_BGP;
     882           0 :       api.message = 0;
     883           0 :       api.safi = safi;
     884           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
     885           0 :       api.nexthop_num = 1;
     886           0 :       api.nexthop = &nexthop;
     887           0 :       api.ifindex_num = 0;
     888           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
     889           0 :       api.metric = info->attr->med;
     890             : 
     891           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     892             :         {
     893             :           char buf[2][INET_ADDRSTRLEN];
     894           0 :           zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
     895           0 :                      inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
     896           0 :                      p->prefixlen,
     897             :                      inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
     898             :                      api.metric);
     899             :         }
     900             : 
     901           0 :       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, 
     902             :                        (struct prefix_ipv4 *) p, &api);
     903             :     }
     904             : #ifdef HAVE_IPV6
     905             :   /* We have to think about a IPv6 link-local address curse. */
     906           0 :   if (p->family == AF_INET6)
     907             :     {
     908             :       struct zapi_ipv6 api;
     909             :       unsigned int ifindex;
     910             :       struct in6_addr *nexthop;
     911             :       
     912           0 :       assert (info->attr->extra);
     913             :       
     914           0 :       ifindex = 0;
     915           0 :       nexthop = NULL;
     916             : 
     917             :       /* Only global address nexthop exists. */
     918           0 :       if (info->attr->extra->mp_nexthop_len == 16)
     919           0 :         nexthop = &info->attr->extra->mp_nexthop_global;
     920             : 
     921             :       /* If both global and link-local address present. */
     922           0 :       if (info->attr->extra->mp_nexthop_len == 32)
     923             :         {
     924           0 :           nexthop = &info->attr->extra->mp_nexthop_local;
     925           0 :           if (info->peer->nexthop.ifp)
     926           0 :             ifindex = info->peer->nexthop.ifp->ifindex;
     927             :         }
     928             : 
     929           0 :       if (nexthop == NULL)
     930           0 :         return;
     931             : 
     932           0 :       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
     933           0 :         if (info->peer->ifname)
     934           0 :           ifindex = if_nametoindex (info->peer->ifname);
     935             : 
     936           0 :       api.flags = flags;
     937           0 :       api.type = ZEBRA_ROUTE_BGP;
     938           0 :       api.message = 0;
     939           0 :       api.safi = safi;
     940           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
     941           0 :       api.nexthop_num = 1;
     942           0 :       api.nexthop = &nexthop;
     943           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
     944           0 :       api.ifindex_num = 1;
     945           0 :       api.ifindex = &ifindex;
     946           0 :       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
     947           0 :       api.metric = info->attr->med;
     948             : 
     949           0 :       if (BGP_DEBUG(zebra, ZEBRA))
     950             :         {
     951             :           char buf[2][INET6_ADDRSTRLEN];
     952           0 :           zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
     953           0 :                      inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
     954           0 :                      p->prefixlen,
     955             :                      inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
     956             :                      api.metric);
     957             :         }
     958             : 
     959           0 :       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, 
     960             :                        (struct prefix_ipv6 *) p, NULL, &api);
     961             :     }
     962             : #endif /* HAVE_IPV6 */
     963             : }
     964             : 
     965             : /* Other routes redistribution into BGP. */
     966             : int
     967           0 : bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
     968             : {
     969             :   /* Set flag to BGP instance. */
     970           0 :   bgp->redist[afi][type] = 1;
     971             : 
     972             :   /* Return if already redistribute flag is set. */
     973           0 :   if (zclient->redist[type])
     974           0 :     return CMD_WARNING;
     975             : 
     976           0 :   zclient->redist[type] = 1;
     977             : 
     978             :   /* Return if zebra connection is not established. */
     979           0 :   if (zclient->sock < 0)
     980           0 :     return CMD_WARNING;
     981             : 
     982           0 :   if (BGP_DEBUG(zebra, ZEBRA))
     983           0 :     zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
     984             :     
     985             :   /* Send distribute add message to zebra. */
     986           0 :   zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
     987             : 
     988           0 :   return CMD_SUCCESS;
     989             : }
     990             : 
     991             : /* Redistribute with route-map specification.  */
     992             : int
     993           0 : bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, 
     994             :                            const char *name)
     995             : {
     996           0 :   if (bgp->rmap[afi][type].name
     997           0 :       && (strcmp (bgp->rmap[afi][type].name, name) == 0))
     998           0 :     return 0;
     999             : 
    1000           0 :   if (bgp->rmap[afi][type].name)
    1001           0 :     free (bgp->rmap[afi][type].name);
    1002           0 :   bgp->rmap[afi][type].name = strdup (name);
    1003           0 :   bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
    1004             : 
    1005           0 :   return 1;
    1006             : }
    1007             : 
    1008             : /* Redistribute with metric specification.  */
    1009             : int
    1010           0 : bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
    1011             :                              u_int32_t metric)
    1012             : {
    1013           0 :   if (bgp->redist_metric_flag[afi][type]
    1014           0 :       && bgp->redist_metric[afi][type] == metric)
    1015           0 :     return 0;
    1016             : 
    1017           0 :   bgp->redist_metric_flag[afi][type] = 1;
    1018           0 :   bgp->redist_metric[afi][type] = metric;
    1019             : 
    1020           0 :   return 1;
    1021             : }
    1022             : 
    1023             : /* Unset redistribution.  */
    1024             : int
    1025          24 : bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
    1026             : {
    1027             :   /* Unset flag from BGP instance. */
    1028          24 :   bgp->redist[afi][type] = 0;
    1029             : 
    1030             :   /* Unset route-map. */
    1031          24 :   if (bgp->rmap[afi][type].name)
    1032           0 :     free (bgp->rmap[afi][type].name);
    1033          24 :   bgp->rmap[afi][type].name = NULL;
    1034          24 :   bgp->rmap[afi][type].map = NULL;
    1035             : 
    1036             :   /* Unset metric. */
    1037          24 :   bgp->redist_metric_flag[afi][type] = 0;
    1038          24 :   bgp->redist_metric[afi][type] = 0;
    1039             : 
    1040             :   /* Return if zebra connection is disabled. */
    1041          24 :   if (! zclient->redist[type])
    1042          24 :     return CMD_WARNING;
    1043           0 :   zclient->redist[type] = 0;
    1044             : 
    1045           0 :   if (bgp->redist[AFI_IP][type] == 0 
    1046           0 :       && bgp->redist[AFI_IP6][type] == 0 
    1047           0 :       && zclient->sock >= 0)
    1048             :     {
    1049             :       /* Send distribute delete message to zebra. */
    1050           0 :       if (BGP_DEBUG(zebra, ZEBRA))
    1051           0 :         zlog_debug("Zebra send: redistribute delete %s",
    1052             :                    zebra_route_string(type));
    1053           0 :       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
    1054             :     }
    1055             :   
    1056             :   /* Withdraw redistributed routes from current BGP's routing table. */
    1057           0 :   bgp_redistribute_withdraw (bgp, afi, type);
    1058             : 
    1059           0 :   return CMD_SUCCESS;
    1060             : }
    1061             : 
    1062             : /* Unset redistribution route-map configuration.  */
    1063             : int
    1064           0 : bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
    1065             : {
    1066           0 :   if (! bgp->rmap[afi][type].name)
    1067           0 :     return 0;
    1068             : 
    1069             :   /* Unset route-map. */
    1070           0 :   free (bgp->rmap[afi][type].name);
    1071           0 :   bgp->rmap[afi][type].name = NULL;
    1072           0 :   bgp->rmap[afi][type].map = NULL;
    1073             : 
    1074           0 :   return 1;
    1075             : }
    1076             : 
    1077             : /* Unset redistribution metric configuration.  */
    1078             : int
    1079           0 : bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
    1080             : {
    1081           0 :   if (! bgp->redist_metric_flag[afi][type])
    1082           0 :     return 0;
    1083             : 
    1084             :   /* Unset metric. */
    1085           0 :   bgp->redist_metric_flag[afi][type] = 0;
    1086           0 :   bgp->redist_metric[afi][type] = 0;
    1087             : 
    1088           0 :   return 1;
    1089             : }
    1090             : 
    1091             : void
    1092           0 : bgp_zclient_reset (void)
    1093             : {
    1094           0 :   zclient_reset (zclient);
    1095           0 : }
    1096             : 
    1097             : void
    1098           0 : bgp_zebra_init (void)
    1099             : {
    1100             :   /* Set default values. */
    1101           0 :   zclient = zclient_new ();
    1102           0 :   zclient_init (zclient, ZEBRA_ROUTE_BGP);
    1103           0 :   zclient->router_id_update = bgp_router_id_update;
    1104           0 :   zclient->interface_add = bgp_interface_add;
    1105           0 :   zclient->interface_delete = bgp_interface_delete;
    1106           0 :   zclient->interface_address_add = bgp_interface_address_add;
    1107           0 :   zclient->interface_address_delete = bgp_interface_address_delete;
    1108           0 :   zclient->ipv4_route_add = zebra_read_ipv4;
    1109           0 :   zclient->ipv4_route_delete = zebra_read_ipv4;
    1110           0 :   zclient->interface_up = bgp_interface_up;
    1111           0 :   zclient->interface_down = bgp_interface_down;
    1112             : #ifdef HAVE_IPV6
    1113           0 :   zclient->ipv6_route_add = zebra_read_ipv6;
    1114           0 :   zclient->ipv6_route_delete = zebra_read_ipv6;
    1115             : #endif /* HAVE_IPV6 */
    1116             : 
    1117             :   /* Interface related init. */
    1118           0 :   if_init ();
    1119             : 
    1120           0 :   bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
    1121           0 : }

Generated by: LCOV version 1.10