File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / isisd / isis_zebra.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /*
    2:  * IS-IS Rout(e)ing protocol - isis_zebra.c   
    3:  *
    4:  * Copyright (C) 2001,2002   Sampo Saaristo
    5:  *                           Tampere University of Technology      
    6:  *                           Institute of Communications Engineering
    7:  * Copyright (C) 2013-2015   Christian Franke <chris@opensourcerouting.org>
    8:  *
    9:  * This program is free software; you can redistribute it and/or modify it 
   10:  * under the terms of the GNU General Public Licenseas published by the Free 
   11:  * Software Foundation; either version 2 of the License, or (at your option) 
   12:  * any later version.
   13:  *
   14:  * This program is distributed in the hope that it will be useful,but WITHOUT 
   15:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
   16:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
   17:  * more details.
   18: 
   19:  * You should have received a copy of the GNU General Public License along 
   20:  * with this program; if not, write to the Free Software Foundation, Inc., 
   21:  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   22:  */
   23: 
   24: #include <zebra.h>
   25: 
   26: #include "thread.h"
   27: #include "command.h"
   28: #include "memory.h"
   29: #include "log.h"
   30: #include "if.h"
   31: #include "network.h"
   32: #include "prefix.h"
   33: #include "zclient.h"
   34: #include "stream.h"
   35: #include "linklist.h"
   36: #include "vrf.h"
   37: 
   38: #include "isisd/dict.h"
   39: #include "isisd/isis_constants.h"
   40: #include "isisd/isis_common.h"
   41: #include "isisd/isis_flags.h"
   42: #include "isisd/isis_misc.h"
   43: #include "isisd/isis_circuit.h"
   44: #include "isisd/isis_tlv.h"
   45: #include "isisd/isisd.h"
   46: #include "isisd/isis_circuit.h"
   47: #include "isisd/isis_csm.h"
   48: #include "isisd/isis_lsp.h"
   49: #include "isisd/isis_route.h"
   50: #include "isisd/isis_zebra.h"
   51: 
   52: struct zclient *zclient = NULL;
   53: 
   54: /* Router-id update message from zebra. */
   55: static int
   56: isis_router_id_update_zebra (int command, struct zclient *zclient,
   57: 			     zebra_size_t length, vrf_id_t vrf_id)
   58: {
   59:   struct isis_area *area;
   60:   struct listnode *node;
   61:   struct prefix router_id;
   62: 
   63:   zebra_router_id_update_read (zclient->ibuf, &router_id);
   64:   if (isis->router_id == router_id.u.prefix4.s_addr)
   65:     return 0;
   66: 
   67:   isis->router_id = router_id.u.prefix4.s_addr;
   68:   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
   69:     if (listcount (area->area_addrs) > 0)
   70:       lsp_regenerate_schedule (area, area->is_type, 0);
   71: 
   72:   return 0;
   73: }
   74: 
   75: static int
   76: isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
   77:     vrf_id_t vrf_id)
   78: {
   79:   struct interface *ifp;
   80: 
   81:   ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
   82: 
   83:   if (isis->debugs & DEBUG_ZEBRA)
   84:     zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
   85: 		ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
   86: 
   87:   if (if_is_operative (ifp))
   88:     isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
   89: 
   90:   return 0;
   91: }
   92: 
   93: static int
   94: isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
   95:     vrf_id_t vrf_id)
   96: {
   97:   struct interface *ifp;
   98:   struct stream *s;
   99: 
  100:   s = zclient->ibuf;
  101:   ifp = zebra_interface_state_read (s, vrf_id);
  102: 
  103:   if (!ifp)
  104:     return 0;
  105: 
  106:   if (if_is_operative (ifp))
  107:     zlog_warn ("Zebra: got delete of %s, but interface is still up",
  108: 	       ifp->name);
  109: 
  110:   if (isis->debugs & DEBUG_ZEBRA)
  111:     zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
  112: 		ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
  113: 
  114:   isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
  115: 
  116:   /* Cannot call if_delete because we should retain the pseudo interface
  117:      in case there is configuration info attached to it. */
  118:   if_delete_retain(ifp);
  119: 
  120:   ifp->ifindex = IFINDEX_INTERNAL;
  121: 
  122:   return 0;
  123: }
  124: 
  125: static int
  126: isis_zebra_if_state_up (int command, struct zclient *zclient,
  127: 			zebra_size_t length, vrf_id_t vrf_id)
  128: {
  129:   struct interface *ifp;
  130: 
  131:   ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
  132: 
  133:   if (ifp == NULL)
  134:     return 0;
  135: 
  136:   isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
  137: 
  138:   return 0;
  139: }
  140: 
  141: static int
  142: isis_zebra_if_state_down (int command, struct zclient *zclient,
  143: 			  zebra_size_t length, vrf_id_t vrf_id)
  144: {
  145:   struct interface *ifp;
  146:   struct isis_circuit *circuit;
  147: 
  148:   ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
  149: 
  150:   if (ifp == NULL)
  151:     return 0;
  152: 
  153:   circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
  154:                                    ifp);
  155:   if (circuit)
  156:     SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
  157: 
  158:   return 0;
  159: }
  160: 
  161: static int
  162: isis_zebra_if_address_add (int command, struct zclient *zclient,
  163: 			   zebra_size_t length, vrf_id_t vrf_id)
  164: {
  165:   struct connected *c;
  166:   struct prefix *p;
  167:   char buf[BUFSIZ];
  168: 
  169:   c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
  170: 				    zclient->ibuf, vrf_id);
  171: 
  172:   if (c == NULL)
  173:     return 0;
  174: 
  175:   p = c->address;
  176: 
  177:   prefix2str (p, buf, BUFSIZ);
  178: #ifdef EXTREME_DEBUG
  179:   if (p->family == AF_INET)
  180:     zlog_debug ("connected IP address %s", buf);
  181: #ifdef HAVE_IPV6
  182:   if (p->family == AF_INET6)
  183:     zlog_debug ("connected IPv6 address %s", buf);
  184: #endif /* HAVE_IPV6 */
  185: #endif /* EXTREME_DEBUG */
  186:   if (if_is_operative (c->ifp))
  187:     isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
  188: 
  189:   return 0;
  190: }
  191: 
  192: static int
  193: isis_zebra_if_address_del (int command, struct zclient *client,
  194: 			   zebra_size_t length, vrf_id_t vrf_id)
  195: {
  196:   struct connected *c;
  197:   struct interface *ifp;
  198: #ifdef EXTREME_DEBUG
  199:   struct prefix *p;
  200:   u_char buf[BUFSIZ];
  201: #endif /* EXTREME_DEBUG */
  202: 
  203:   c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
  204: 				    zclient->ibuf, vrf_id);
  205: 
  206:   if (c == NULL)
  207:     return 0;
  208: 
  209:   ifp = c->ifp;
  210: 
  211: #ifdef EXTREME_DEBUG
  212:   p = c->address;
  213:   prefix2str (p, buf, BUFSIZ);
  214: 
  215:   if (p->family == AF_INET)
  216:     zlog_debug ("disconnected IP address %s", buf);
  217: #ifdef HAVE_IPV6
  218:   if (p->family == AF_INET6)
  219:     zlog_debug ("disconnected IPv6 address %s", buf);
  220: #endif /* HAVE_IPV6 */
  221: #endif /* EXTREME_DEBUG */
  222: 
  223:   if (if_is_operative (ifp))
  224:     isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
  225:   connected_free (c);
  226: 
  227:   return 0;
  228: }
  229: 
  230: static void
  231: isis_zebra_route_add_ipv4 (struct prefix *prefix,
  232: 			   struct isis_route_info *route_info)
  233: {
  234:   u_char message, flags;
  235:   int psize;
  236:   struct stream *stream;
  237:   struct isis_nexthop *nexthop;
  238:   struct listnode *node;
  239: 
  240:   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  241:     return;
  242: 
  243:   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  244:     {
  245:       message = 0;
  246:       flags = 0;
  247: 
  248:       SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
  249:       SET_FLAG (message, ZAPI_MESSAGE_METRIC);
  250: #if 0
  251:       SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
  252: #endif
  253: 
  254:       stream = zclient->obuf;
  255:       stream_reset (stream);
  256:       zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
  257:       /* type */
  258:       stream_putc (stream, ZEBRA_ROUTE_ISIS);
  259:       /* flags */
  260:       stream_putc (stream, flags);
  261:       /* message */
  262:       stream_putc (stream, message);
  263:       /* SAFI */
  264:       stream_putw (stream, SAFI_UNICAST);
  265:       /* prefix information */
  266:       psize = PSIZE (prefix->prefixlen);
  267:       stream_putc (stream, prefix->prefixlen);
  268:       stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
  269: 
  270:       stream_putc (stream, listcount (route_info->nexthops));
  271: 
  272:       /* Nexthop, ifindex, distance and metric information */
  273:       for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
  274: 	{
  275: 	  /* FIXME: can it be ? */
  276: 	  if (nexthop->ip.s_addr != INADDR_ANY)
  277: 	    {
  278: 	      stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
  279: 	      stream_put_in_addr (stream, &nexthop->ip);
  280: 	    }
  281: 	  else
  282: 	    {
  283: 	      stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
  284: 	      stream_putl (stream, nexthop->ifindex);
  285: 	    }
  286: 	}
  287: #if 0
  288:       if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
  289: 	stream_putc (stream, route_info->depth);
  290: #endif
  291:       if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
  292: 	stream_putl (stream, route_info->cost);
  293: 
  294:       stream_putw_at (stream, 0, stream_get_endp (stream));
  295:       zclient_send_message(zclient);
  296:       SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  297:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
  298:     }
  299: }
  300: 
  301: static void
  302: isis_zebra_route_del_ipv4 (struct prefix *prefix,
  303: 			   struct isis_route_info *route_info)
  304: {
  305:   struct zapi_ipv4 api;
  306:   struct prefix_ipv4 prefix4;
  307: 
  308:   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  309:     {
  310:       api.vrf_id = VRF_DEFAULT;
  311:       api.type = ZEBRA_ROUTE_ISIS;
  312:       api.flags = 0;
  313:       api.message = 0;
  314:       api.safi = SAFI_UNICAST;
  315:       prefix4.family = AF_INET;
  316:       prefix4.prefixlen = prefix->prefixlen;
  317:       prefix4.prefix = prefix->u.prefix4;
  318:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
  319:     }
  320:   UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  321: 
  322:   return;
  323: }
  324: 
  325: #ifdef HAVE_IPV6
  326: static void
  327: isis_zebra_route_add_ipv6 (struct prefix *prefix,
  328: 			   struct isis_route_info *route_info)
  329: {
  330:   struct zapi_ipv6 api;
  331:   struct in6_addr **nexthop_list;
  332:   ifindex_t *ifindex_list;
  333:   struct isis_nexthop6 *nexthop6;
  334:   int i, size;
  335:   struct listnode *node;
  336:   struct prefix_ipv6 prefix6;
  337: 
  338:   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  339:     return;
  340: 
  341:   api.vrf_id = VRF_DEFAULT;
  342:   api.type = ZEBRA_ROUTE_ISIS;
  343:   api.flags = 0;
  344:   api.message = 0;
  345:   api.safi = SAFI_UNICAST;
  346:   SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  347:   SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  348:   SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  349:   api.metric = route_info->cost;
  350: #if 0
  351:   SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
  352:   api.distance = route_info->depth;
  353: #endif
  354:   api.nexthop_num = listcount (route_info->nexthops6);
  355:   api.ifindex_num = listcount (route_info->nexthops6);
  356: 
  357:   /* allocate memory for nexthop_list */
  358:   size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
  359:   nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
  360:   if (!nexthop_list)
  361:     {
  362:       zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
  363:       return;
  364:     }
  365: 
  366:   /* allocate memory for ifindex_list */
  367:   size = sizeof (unsigned int) * listcount (route_info->nexthops6);
  368:   ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
  369:   if (!ifindex_list)
  370:     {
  371:       zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
  372:       XFREE (MTYPE_ISIS_TMP, nexthop_list);
  373:       return;
  374:     }
  375: 
  376:   /* for each nexthop */
  377:   i = 0;
  378:   for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
  379:     {
  380:       if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
  381: 	  !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
  382: 	{
  383: 	  api.nexthop_num--;
  384: 	  api.ifindex_num--;
  385: 	  continue;
  386: 	}
  387: 
  388:       nexthop_list[i] = &nexthop6->ip6;
  389:       ifindex_list[i] = nexthop6->ifindex;
  390:       i++;
  391:     }
  392: 
  393:   api.nexthop = nexthop_list;
  394:   api.ifindex = ifindex_list;
  395: 
  396:   if (api.nexthop_num && api.ifindex_num)
  397:     {
  398:       prefix6.family = AF_INET6;
  399:       prefix6.prefixlen = prefix->prefixlen;
  400:       memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
  401:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
  402:       SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  403:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
  404:     }
  405: 
  406:   XFREE (MTYPE_ISIS_TMP, nexthop_list);
  407:   XFREE (MTYPE_ISIS_TMP, ifindex_list);
  408: 
  409:   return;
  410: }
  411: 
  412: static void
  413: isis_zebra_route_del_ipv6 (struct prefix *prefix,
  414: 			   struct isis_route_info *route_info)
  415: {
  416:   struct zapi_ipv6 api;
  417:   struct in6_addr **nexthop_list;
  418:   ifindex_t *ifindex_list;
  419:   struct isis_nexthop6 *nexthop6;
  420:   int i, size;
  421:   struct listnode *node;
  422:   struct prefix_ipv6 prefix6;
  423: 
  424:   if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  425:     return;
  426: 
  427:   api.vrf_id = VRF_DEFAULT;
  428:   api.type = ZEBRA_ROUTE_ISIS;
  429:   api.flags = 0;
  430:   api.message = 0;
  431:   api.safi = SAFI_UNICAST;
  432:   SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  433:   SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  434:   api.nexthop_num = listcount (route_info->nexthops6);
  435:   api.ifindex_num = listcount (route_info->nexthops6);
  436: 
  437:   /* allocate memory for nexthop_list */
  438:   size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
  439:   nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
  440:   if (!nexthop_list)
  441:     {
  442:       zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
  443:       return;
  444:     }
  445: 
  446:   /* allocate memory for ifindex_list */
  447:   size = sizeof (unsigned int) * listcount (route_info->nexthops6);
  448:   ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
  449:   if (!ifindex_list)
  450:     {
  451:       zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
  452:       XFREE (MTYPE_ISIS_TMP, nexthop_list);
  453:       return;
  454:     }
  455: 
  456:   /* for each nexthop */
  457:   i = 0;
  458:   for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
  459:     {
  460:       if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
  461: 	  !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
  462: 	{
  463: 	  api.nexthop_num--;
  464: 	  api.ifindex_num--;
  465: 	  continue;
  466: 	}
  467: 
  468:       nexthop_list[i] = &nexthop6->ip6;
  469:       ifindex_list[i] = nexthop6->ifindex;
  470:       i++;
  471:     }
  472: 
  473:   api.nexthop = nexthop_list;
  474:   api.ifindex = ifindex_list;
  475: 
  476:   if (api.nexthop_num && api.ifindex_num)
  477:     {
  478:       prefix6.family = AF_INET6;
  479:       prefix6.prefixlen = prefix->prefixlen;
  480:       memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
  481:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
  482:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  483:     }
  484: 
  485:   XFREE (MTYPE_ISIS_TMP, nexthop_list);
  486:   XFREE (MTYPE_ISIS_TMP, ifindex_list);
  487: }
  488: 
  489: #endif /* HAVE_IPV6 */
  490: 
  491: void
  492: isis_zebra_route_update (struct prefix *prefix,
  493: 			 struct isis_route_info *route_info)
  494: {
  495:   if (zclient->sock < 0)
  496:     return;
  497: 
  498:   if (!vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  499:     return;
  500: 
  501:   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
  502:     {
  503:       if (prefix->family == AF_INET)
  504: 	isis_zebra_route_add_ipv4 (prefix, route_info);
  505: #ifdef HAVE_IPV6
  506:       else if (prefix->family == AF_INET6)
  507: 	isis_zebra_route_add_ipv6 (prefix, route_info);
  508: #endif /* HAVE_IPV6 */
  509:     }
  510:   else
  511:     {
  512:       if (prefix->family == AF_INET)
  513: 	isis_zebra_route_del_ipv4 (prefix, route_info);
  514: #ifdef HAVE_IPV6
  515:       else if (prefix->family == AF_INET6)
  516: 	isis_zebra_route_del_ipv6 (prefix, route_info);
  517: #endif /* HAVE_IPV6 */
  518:     }
  519:   return;
  520: }
  521: 
  522: static int
  523: isis_zebra_read_ipv4 (int command, struct zclient *zclient,
  524: 		      zebra_size_t length, vrf_id_t vrf_id)
  525: {
  526:   struct stream *stream;
  527:   struct zapi_ipv4 api;
  528:   struct prefix_ipv4 p;
  529:   struct prefix *p_generic = (struct prefix*)&p;
  530:   unsigned long ifindex __attribute__ ((unused));
  531:   struct in_addr nexthop __attribute__ ((unused));
  532:   unsigned char plength = 0;
  533: 
  534:   stream = zclient->ibuf;
  535:   memset(&api, 0, sizeof(api));
  536:   memset (&p, 0, sizeof (struct prefix_ipv4));
  537:   memset(&nexthop, 0, sizeof(nexthop));
  538:   ifindex = 0;
  539: 
  540:   api.type = stream_getc (stream);
  541:   api.flags = stream_getc (stream);
  542:   api.message = stream_getc (stream);
  543: 
  544:   p.family = AF_INET;
  545:   plength = stream_getc (stream);
  546:   p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
  547:   stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
  548: 
  549:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  550:     {
  551:       api.nexthop_num = stream_getc (stream);
  552:       nexthop.s_addr = stream_get_ipv4 (stream);
  553:     }
  554:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  555:     {
  556:       api.ifindex_num = stream_getc (stream);
  557:       ifindex = stream_getl (stream);
  558:     }
  559:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  560:     api.distance = stream_getc (stream);
  561:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  562:     api.metric = stream_getl (stream);
  563: 
  564:   /*
  565:    * Avoid advertising a false default reachability. (A default
  566:    * route installed by IS-IS gets redistributed from zebra back
  567:    * into IS-IS causing us to start advertising default reachabity
  568:    * without this check)
  569:    */
  570:   if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
  571:     command = ZEBRA_IPV4_ROUTE_DELETE;
  572: 
  573:   if (command == ZEBRA_IPV4_ROUTE_ADD)
  574:     isis_redist_add(api.type, p_generic, api.distance, api.metric);
  575:   else
  576:     isis_redist_delete(api.type, p_generic);
  577: 
  578:   return 0;
  579: }
  580: 
  581: static int
  582: isis_zebra_read_ipv6 (int command, struct zclient *zclient,
  583: 		      zebra_size_t length, vrf_id_t vrf_id)
  584: {
  585:   struct stream *stream;
  586:   struct zapi_ipv6 api;
  587:   struct prefix_ipv6 p;
  588:   struct prefix *p_generic = (struct prefix*)&p;
  589:   struct in6_addr nexthop;
  590:   unsigned long ifindex __attribute__((unused));
  591: 
  592:   stream = zclient->ibuf;
  593:   memset(&api, 0, sizeof(api));
  594:   memset(&p, 0, sizeof(struct prefix_ipv6));
  595:   memset(&nexthop, 0, sizeof(nexthop));
  596:   ifindex = 0;
  597: 
  598:   api.type = stream_getc(stream);
  599:   api.flags = stream_getc(stream);
  600:   api.message = stream_getc(stream);
  601: 
  602:   p.family = AF_INET6;
  603:   p.prefixlen = stream_getc(stream);
  604:   stream_get(&p.prefix, stream, PSIZE(p.prefixlen));
  605: 
  606:   if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
  607:     {
  608:       api.nexthop_num = stream_getc(stream); /* this is always 1 */
  609:       stream_get(&nexthop, stream, sizeof(nexthop));
  610:     }
  611:   if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX))
  612:     {
  613:       api.ifindex_num = stream_getc(stream);
  614:       ifindex = stream_getl(stream);
  615:     }
  616:   if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
  617:     api.distance = stream_getc(stream);
  618:   if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
  619:     api.metric = stream_getl(stream);
  620: 
  621:   /*
  622:    * Avoid advertising a false default reachability. (A default
  623:    * route installed by IS-IS gets redistributed from zebra back
  624:    * into IS-IS causing us to start advertising default reachabity
  625:    * without this check)
  626:    */
  627:   if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
  628:     command = ZEBRA_IPV6_ROUTE_DELETE;
  629: 
  630:   if (command == ZEBRA_IPV6_ROUTE_ADD)
  631:     isis_redist_add(api.type, p_generic, api.distance, api.metric);
  632:   else
  633:     isis_redist_delete(api.type, p_generic);
  634: 
  635:   return 0;
  636: }
  637: 
  638: int
  639: isis_distribute_list_update (int routetype)
  640: {
  641:   return 0;
  642: }
  643: 
  644: void
  645: isis_zebra_redistribute_set(int type)
  646: {
  647:   if (type == DEFAULT_ROUTE)
  648:     zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT);
  649:   else
  650:     zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
  651: }
  652: 
  653: void
  654: isis_zebra_redistribute_unset(int type)
  655: {
  656:   if (type == DEFAULT_ROUTE)
  657:     zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT);
  658:   else
  659:     zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, type, VRF_DEFAULT);
  660: }
  661: 
  662: static void
  663: isis_zebra_connected (struct zclient *zclient)
  664: {
  665:   zclient_send_requests (zclient, VRF_DEFAULT);
  666: }
  667: 
  668: void
  669: isis_zebra_init (struct thread_master *master)
  670: {
  671:   zclient = zclient_new (master);
  672:   zclient_init (zclient, ZEBRA_ROUTE_ISIS);
  673:   zclient->zebra_connected = isis_zebra_connected;
  674:   zclient->router_id_update = isis_router_id_update_zebra;
  675:   zclient->interface_add = isis_zebra_if_add;
  676:   zclient->interface_delete = isis_zebra_if_del;
  677:   zclient->interface_up = isis_zebra_if_state_up;
  678:   zclient->interface_down = isis_zebra_if_state_down;
  679:   zclient->interface_address_add = isis_zebra_if_address_add;
  680:   zclient->interface_address_delete = isis_zebra_if_address_del;
  681:   zclient->ipv4_route_add = isis_zebra_read_ipv4;
  682:   zclient->ipv4_route_delete = isis_zebra_read_ipv4;
  683: #ifdef HAVE_IPV6
  684:   zclient->ipv6_route_add = isis_zebra_read_ipv6;
  685:   zclient->ipv6_route_delete = isis_zebra_read_ipv6;
  686: #endif /* HAVE_IPV6 */
  687: 
  688:   return;
  689: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>