LCOV - code coverage report
Current view: top level - zebra - redistribute.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 59 163 36.2 %
Date: 2015-11-19 Functions: 9 16 56.2 %

          Line data    Source code
       1             : /* Redistribution Handler
       2             :  * Copyright (C) 1998 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 Free
      18             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      19             :  * 02111-1307, USA.  
      20             :  */
      21             : 
      22             : #include <zebra.h>
      23             : 
      24             : #include "vector.h"
      25             : #include "vty.h"
      26             : #include "command.h"
      27             : #include "prefix.h"
      28             : #include "table.h"
      29             : #include "stream.h"
      30             : #include "zclient.h"
      31             : #include "linklist.h"
      32             : #include "log.h"
      33             : #include "srcdest_table.h"
      34             : 
      35             : #include "zebra/rib.h"
      36             : #include "zebra/zserv.h"
      37             : #include "zebra/redistribute.h"
      38             : #include "zebra/debug.h"
      39             : #include "zebra/router-id.h"
      40             : 
      41             : /* master zebra server structure */
      42             : extern struct zebra_t zebrad;
      43             : 
      44             : int
      45         111 : zebra_check_addr (struct prefix *p)
      46             : {
      47         111 :   if (p->family == AF_INET)
      48             :     {
      49             :       u_int32_t addr;
      50             : 
      51         111 :       addr = p->u.prefix4.s_addr;
      52         111 :       addr = ntohl (addr);
      53             : 
      54         111 :       if (IPV4_NET127 (addr)
      55          66 :           || IN_CLASSD (addr)
      56          66 :           || IPV4_LINKLOCAL(addr))
      57          45 :         return 0;
      58             :     }
      59             : #ifdef HAVE_IPV6
      60          66 :   if (p->family == AF_INET6)
      61             :     {
      62           0 :       if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
      63           0 :         return 0;
      64           0 :       if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
      65           0 :         return 0;
      66             :     }
      67             : #endif /* HAVE_IPV6 */
      68          66 :   return 1;
      69             : }
      70             : 
      71             : static int
      72         189 : is_default (struct prefix *p)
      73             : {
      74         189 :   if (p->family == AF_INET)
      75         127 :     if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
      76           0 :       return 1;
      77             : #ifdef HAVE_IPV6
      78             : #if 0  /* IPv6 default separation is now pending until protocol daemon
      79             :           can handle that. */
      80             :   if (p->family == AF_INET6)
      81             :     if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
      82             :       return 1;
      83             : #endif /* 0 */
      84             : #endif /* HAVE_IPV6 */
      85         189 :   return 0;
      86             : }
      87             : 
      88             : static void
      89           0 : zebra_redistribute_default (struct zserv *client)
      90             : {
      91             :   struct prefix_ipv4 p;
      92             :   struct route_table *table;
      93             :   struct route_node *rn;
      94             :   struct rib *newrib;
      95             : #ifdef HAVE_IPV6
      96             :   struct prefix_ipv6 p6;
      97             : #endif /* HAVE_IPV6 */
      98             : 
      99             : 
     100             :   /* Lookup default route. */
     101           0 :   memset (&p, 0, sizeof (struct prefix_ipv4));
     102           0 :   p.family = AF_INET;
     103             : 
     104             :   /* Lookup table.  */
     105           0 :   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
     106           0 :   if (table)
     107             :     {
     108           0 :       rn = route_node_lookup (table, (struct prefix *)&p);
     109           0 :       if (rn)
     110             :         {
     111           0 :           RNODE_FOREACH_RIB (rn, newrib)
     112           0 :             if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
     113           0 :                 && newrib->distance != DISTANCE_INFINITY)
     114           0 :               zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client,
     115             :                                      &rn->p, NULL, newrib);
     116           0 :           route_unlock_node (rn);
     117             :         }
     118             :     }
     119             : 
     120             : #ifdef HAVE_IPV6
     121             :   /* Lookup default route. */
     122           0 :   memset (&p6, 0, sizeof (struct prefix_ipv6));
     123           0 :   p6.family = AF_INET6;
     124             : 
     125             :   /* Lookup table.  */
     126           0 :   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
     127           0 :   if (table)
     128             :     {
     129           0 :       rn = route_node_lookup (table, (struct prefix *)&p6);
     130           0 :       if (rn)
     131             :         {
     132           0 :           RNODE_FOREACH_RIB (rn, newrib)
     133           0 :             if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
     134           0 :                 && newrib->distance != DISTANCE_INFINITY)
     135           0 :               zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client,
     136             :                                      &rn->p, NULL, newrib);
     137           0 :           route_unlock_node (rn);
     138             :         }
     139             :     }
     140             : #endif /* HAVE_IPV6 */
     141           0 : }
     142             : 
     143             : /* Redistribute routes. */
     144             : static void
     145           0 : zebra_redistribute (struct zserv *client, int type)
     146             : {
     147             :   struct rib *newrib;
     148             :   struct route_table *table;
     149             :   struct route_node *rn;
     150             : 
     151           0 :   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
     152           0 :   if (table)
     153           0 :     for (rn = route_top (table); rn; rn = route_next (rn))
     154           0 :       RNODE_FOREACH_RIB (rn, newrib)
     155           0 :         if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) 
     156           0 :             && newrib->type == type 
     157           0 :             && newrib->distance != DISTANCE_INFINITY
     158           0 :             && zebra_check_addr (&rn->p))
     159           0 :           zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client,
     160             :                                  &rn->p, NULL, newrib);
     161             :   
     162             : #ifdef HAVE_IPV6
     163           0 :   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
     164           0 :   if (table)
     165           0 :     for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
     166             :       {
     167             :         struct prefix *dst_p, *src_p;
     168           0 :         srcdest_rnode_prefixes(rn, &dst_p, &src_p);
     169             : 
     170           0 :         if (!zebra_check_addr (dst_p))
     171           0 :           continue;
     172             : 
     173           0 :         RNODE_FOREACH_RIB (rn, newrib)
     174             :           {
     175           0 :             if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
     176           0 :                 && newrib->type == type
     177           0 :                 && newrib->distance != DISTANCE_INFINITY)
     178             :               {
     179           0 :                 zsend_route_multipath(ZEBRA_IPV6_ROUTE_ADD, client,
     180             :                                       dst_p, src_p, newrib);
     181             :               }
     182             :           }
     183             :       }
     184             : #endif /* HAVE_IPV6 */
     185           0 : }
     186             : 
     187             : void
     188         429 : redistribute_add (struct prefix *p, struct prefix *src_p, struct rib *rib)
     189             : {
     190             :   struct listnode *node, *nnode;
     191             :   struct zserv *client;
     192             : 
     193         564 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     194             :     {
     195         135 :       if (is_default (p))
     196             :         {
     197           0 :           if (client->redist_default || client->redist[rib->type])
     198             :             {
     199           0 :               if (p->family == AF_INET)
     200           0 :                 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p,
     201             :                                        src_p, rib);
     202             : #ifdef HAVE_IPV6
     203           0 :               if (p->family == AF_INET6)
     204           0 :                 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p,
     205             :                                        src_p, rib);
     206             : #endif /* HAVE_IPV6 */    
     207             :             }
     208             :         }
     209         135 :       else if (client->redist[rib->type])
     210             :         {
     211           0 :           if (p->family == AF_INET)
     212           0 :             zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p,
     213             :                                    src_p, rib);
     214             : #ifdef HAVE_IPV6
     215           0 :           if (p->family == AF_INET6)
     216           0 :             zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p,
     217             :                                    src_p, rib);
     218             : #endif /* HAVE_IPV6 */    
     219             :         }
     220             :     }
     221         429 : }
     222             : 
     223             : void
     224          58 : redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
     225             : {
     226             :   struct listnode *node, *nnode;
     227             :   struct zserv *client;
     228             : 
     229             :   /* Add DISTANCE_INFINITY check. */
     230          58 :   if (rib->distance == DISTANCE_INFINITY)
     231           0 :     return;
     232             : 
     233         112 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     234             :     {
     235          54 :       if (is_default (p))
     236             :         {
     237           0 :           if (client->redist_default || client->redist[rib->type])
     238             :             {
     239           0 :               if (p->family == AF_INET)
     240           0 :                 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
     241             :                                        src_p, rib);
     242             : #ifdef HAVE_IPV6
     243           0 :               if (p->family == AF_INET6)
     244           0 :                 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
     245             :                                        src_p, rib);
     246             : #endif /* HAVE_IPV6 */
     247             :             }
     248             :         }
     249          54 :       else if (client->redist[rib->type])
     250             :         {
     251           0 :           if (p->family == AF_INET)
     252           0 :             zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
     253             :                                    src_p, rib);
     254             : #ifdef HAVE_IPV6
     255           0 :           if (p->family == AF_INET6)
     256           0 :             zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
     257             :                                    src_p, rib);
     258             : #endif /* HAVE_IPV6 */
     259             :         }
     260             :     }
     261             : }
     262             : 
     263             : void
     264           0 : zebra_redistribute_add (int command, struct zserv *client, int length)
     265             : {
     266             :   int type;
     267             : 
     268           0 :   type = stream_getc (client->ibuf);
     269             : 
     270           0 :   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
     271           0 :     return;
     272             : 
     273           0 :   if (! client->redist[type])
     274             :     {
     275           0 :       client->redist[type] = 1;
     276           0 :       zebra_redistribute (client, type);
     277             :     }
     278             : }
     279             : 
     280             : void
     281           0 : zebra_redistribute_delete (int command, struct zserv *client, int length)
     282             : {
     283             :   int type;
     284             : 
     285           0 :   type = stream_getc (client->ibuf);
     286             : 
     287           0 :   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
     288           0 :     return;
     289             : 
     290           0 :   client->redist[type] = 0;
     291             : }
     292             : 
     293             : void
     294           0 : zebra_redistribute_default_add (int command, struct zserv *client, int length)
     295             : {
     296           0 :   client->redist_default = 1;
     297           0 :   zebra_redistribute_default (client);
     298           0 : }     
     299             : 
     300             : void
     301           0 : zebra_redistribute_default_delete (int command, struct zserv *client,
     302             :                                    int length)
     303             : {
     304           0 :   client->redist_default = 0;;
     305           0 : }     
     306             : 
     307             : /* Interface up information. */
     308             : void
     309           5 : zebra_interface_up_update (struct interface *ifp)
     310             : {
     311             :   struct listnode *node, *nnode;
     312             :   struct zserv *client;
     313             : 
     314           5 :   if (IS_ZEBRA_DEBUG_EVENT)
     315           5 :     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
     316             : 
     317           5 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     318           0 :     zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
     319           5 : }
     320             : 
     321             : /* Interface down information. */
     322             : void
     323           2 : zebra_interface_down_update (struct interface *ifp)
     324             : {
     325             :   struct listnode *node, *nnode;
     326             :   struct zserv *client;
     327             : 
     328           2 :   if (IS_ZEBRA_DEBUG_EVENT)
     329           2 :     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
     330             : 
     331           2 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     332           0 :     zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
     333           2 : }
     334             : 
     335             : /* Interface information update. */
     336             : void
     337         134 : zebra_interface_add_update (struct interface *ifp)
     338             : {
     339             :   struct listnode *node, *nnode;
     340             :   struct zserv *client;
     341             : 
     342         134 :   if (IS_ZEBRA_DEBUG_EVENT)
     343           0 :     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
     344             :     
     345         134 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     346           0 :     if (client->ifinfo)
     347           0 :       zsend_interface_add (client, ifp);
     348         134 : }
     349             : 
     350             : void
     351           0 : zebra_interface_delete_update (struct interface *ifp)
     352             : {
     353             :   struct listnode *node, *nnode;
     354             :   struct zserv *client;
     355             : 
     356           0 :   if (IS_ZEBRA_DEBUG_EVENT)
     357           0 :     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
     358             : 
     359           0 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     360           0 :     if (client->ifinfo)
     361           0 :       zsend_interface_delete (client, ifp);
     362           0 : }
     363             : 
     364             : /* Interface address addition. */
     365             : void
     366         279 : zebra_interface_address_add_update (struct interface *ifp,
     367             :                                     struct connected *ifc)
     368             : {
     369             :   struct listnode *node, *nnode;
     370             :   struct zserv *client;
     371             :   struct prefix *p;
     372             : 
     373         279 :   if (IS_ZEBRA_DEBUG_EVENT)
     374             :     {
     375             :       char buf[INET6_ADDRSTRLEN];
     376             : 
     377          17 :       p = ifc->address;
     378          34 :       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
     379          17 :                   inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
     380          17 :                   p->prefixlen, ifc->ifp->name);
     381             :     }
     382             : 
     383         279 :   if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
     384           0 :     zlog_warn("WARNING: advertising address to clients that is not yet usable.");
     385             : 
     386         279 :   router_id_add_address(ifc);
     387             : 
     388         285 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     389           6 :     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
     390           0 :       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
     391         279 : }
     392             : 
     393             : /* Interface address deletion. */
     394             : void
     395           8 : zebra_interface_address_delete_update (struct interface *ifp,
     396             :                                        struct connected *ifc)
     397             : {
     398             :   struct listnode *node, *nnode;
     399             :   struct zserv *client;
     400             :   struct prefix *p;
     401             : 
     402           8 :   if (IS_ZEBRA_DEBUG_EVENT)
     403             :     {
     404             :       char buf[INET6_ADDRSTRLEN];
     405             : 
     406           8 :       p = ifc->address;
     407          16 :       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
     408           8 :                   inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
     409           8 :                  p->prefixlen, ifc->ifp->name);
     410             :     }
     411             : 
     412           8 :   router_id_del_address(ifc);
     413             : 
     414          11 :   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     415           3 :     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
     416           0 :       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
     417           8 : }

Generated by: LCOV version 1.10