Annotation of embedaddon/quagga/isisd/isis_zebra.c, revision 1.1.1.3

1.1       misho       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
1.1.1.3 ! misho       7:  * Copyright (C) 2013-2015   Christian Franke <chris@opensourcerouting.org>
1.1       misho       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"
1.1.1.3 ! misho      36: #include "vrf.h"
1.1       misho      37: 
                     38: #include "isisd/dict.h"
                     39: #include "isisd/isis_constants.h"
                     40: #include "isisd/isis_common.h"
1.1.1.2   misho      41: #include "isisd/isis_flags.h"
                     42: #include "isisd/isis_misc.h"
                     43: #include "isisd/isis_circuit.h"
                     44: #include "isisd/isis_tlv.h"
1.1       misho      45: #include "isisd/isisd.h"
                     46: #include "isisd/isis_circuit.h"
                     47: #include "isisd/isis_csm.h"
1.1.1.2   misho      48: #include "isisd/isis_lsp.h"
1.1       misho      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,
1.1.1.3 ! misho      57:                             zebra_size_t length, vrf_id_t vrf_id)
1.1       misho      58: {
1.1.1.2   misho      59:   struct isis_area *area;
                     60:   struct listnode *node;
1.1       misho      61:   struct prefix router_id;
                     62: 
1.1.1.2   misho      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);
1.1       misho      71: 
                     72:   return 0;
                     73: }
                     74: 
                     75: static int
1.1.1.3 ! misho      76: isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
        !            77:     vrf_id_t vrf_id)
1.1       misho      78: {
                     79:   struct interface *ifp;
                     80: 
1.1.1.3 ! misho      81:   ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
1.1       misho      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
1.1.1.3 ! misho      94: isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
        !            95:     vrf_id_t vrf_id)
1.1       misho      96: {
                     97:   struct interface *ifp;
                     98:   struct stream *s;
                     99: 
                    100:   s = zclient->ibuf;
1.1.1.3 ! misho     101:   ifp = zebra_interface_state_read (s, vrf_id);
1.1       misho     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: 
1.1.1.2   misho     114:   isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
1.1       misho     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,
1.1.1.3 ! misho     127:                        zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     128: {
                    129:   struct interface *ifp;
                    130: 
1.1.1.3 ! misho     131:   ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
1.1       misho     132: 
1.1.1.2   misho     133:   if (ifp == NULL)
1.1       misho     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,
1.1.1.3 ! misho     143:                          zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     144: {
                    145:   struct interface *ifp;
1.1.1.2   misho     146:   struct isis_circuit *circuit;
1.1       misho     147: 
1.1.1.3 ! misho     148:   ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
1.1       misho     149: 
                    150:   if (ifp == NULL)
                    151:     return 0;
                    152: 
1.1.1.2   misho     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);
1.1       misho     157: 
                    158:   return 0;
                    159: }
                    160: 
                    161: static int
                    162: isis_zebra_if_address_add (int command, struct zclient *zclient,
1.1.1.3 ! misho     163:                           zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     164: {
                    165:   struct connected *c;
                    166:   struct prefix *p;
                    167:   char buf[BUFSIZ];
                    168: 
                    169:   c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
1.1.1.3 ! misho     170:                                    zclient->ibuf, vrf_id);
1.1       misho     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,
1.1.1.3 ! misho     194:                           zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     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,
1.1.1.3 ! misho     204:                                    zclient->ibuf, vrf_id);
1.1       misho     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: 
1.1.1.2   misho     240:   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
1.1       misho     241:     return;
                    242: 
1.1.1.3 ! misho     243:   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
1.1       misho     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);
1.1.1.3 ! misho     256:       zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
1.1       misho     257:       /* type */
                    258:       stream_putc (stream, ZEBRA_ROUTE_ISIS);
                    259:       /* flags */
                    260:       stream_putc (stream, flags);
                    261:       /* message */
                    262:       stream_putc (stream, message);
1.1.1.2   misho     263:       /* SAFI */
                    264:       stream_putw (stream, SAFI_UNICAST);
1.1       misho     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);
1.1.1.2   misho     296:       SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
                    297:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
1.1       misho     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: 
1.1.1.3 ! misho     308:   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
1.1       misho     309:     {
1.1.1.3 ! misho     310:       api.vrf_id = VRF_DEFAULT;
1.1       misho     311:       api.type = ZEBRA_ROUTE_ISIS;
                    312:       api.flags = 0;
                    313:       api.message = 0;
1.1.1.2   misho     314:       api.safi = SAFI_UNICAST;
1.1       misho     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:     }
1.1.1.2   misho     320:   UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
1.1       misho     321: 
                    322:   return;
                    323: }
                    324: 
                    325: #ifdef HAVE_IPV6
1.1.1.3 ! misho     326: static void
1.1       misho     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;
1.1.1.3 ! misho     332:   ifindex_t *ifindex_list;
1.1       misho     333:   struct isis_nexthop6 *nexthop6;
                    334:   int i, size;
                    335:   struct listnode *node;
                    336:   struct prefix_ipv6 prefix6;
                    337: 
1.1.1.2   misho     338:   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
1.1       misho     339:     return;
                    340: 
1.1.1.3 ! misho     341:   api.vrf_id = VRF_DEFAULT;
1.1       misho     342:   api.type = ZEBRA_ROUTE_ISIS;
                    343:   api.flags = 0;
                    344:   api.message = 0;
1.1.1.2   misho     345:   api.safi = SAFI_UNICAST;
1.1       misho     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);
1.1.1.3 ! misho     368:   ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
1.1       misho     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);
1.1.1.2   misho     402:       SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
                    403:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
1.1       misho     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;
1.1.1.3 ! misho     418:   ifindex_t *ifindex_list;
1.1       misho     419:   struct isis_nexthop6 *nexthop6;
                    420:   int i, size;
                    421:   struct listnode *node;
                    422:   struct prefix_ipv6 prefix6;
                    423: 
1.1.1.3 ! misho     424:   if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
1.1       misho     425:     return;
                    426: 
1.1.1.3 ! misho     427:   api.vrf_id = VRF_DEFAULT;
1.1       misho     428:   api.type = ZEBRA_ROUTE_ISIS;
                    429:   api.flags = 0;
                    430:   api.message = 0;
1.1.1.2   misho     431:   api.safi = SAFI_UNICAST;
1.1       misho     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);
1.1.1.3 ! misho     448:   ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
1.1       misho     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);
1.1.1.2   misho     482:       UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
1.1       misho     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: 
1.1.1.3 ! misho     498:   if (!vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
1.1       misho     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,
1.1.1.3 ! misho     524:                      zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     525: {
                    526:   struct stream *stream;
                    527:   struct zapi_ipv4 api;
                    528:   struct prefix_ipv4 p;
1.1.1.3 ! misho     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;
1.1       misho     533: 
                    534:   stream = zclient->ibuf;
1.1.1.3 ! misho     535:   memset(&api, 0, sizeof(api));
1.1       misho     536:   memset (&p, 0, sizeof (struct prefix_ipv4));
1.1.1.3 ! misho     537:   memset(&nexthop, 0, sizeof(nexthop));
1.1       misho     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;
1.1.1.3 ! misho     545:   plength = stream_getc (stream);
        !           546:   p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
1.1       misho     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);
1.1.1.3 ! misho     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;
1.1       misho     572: 
                    573:   if (command == ZEBRA_IPV4_ROUTE_ADD)
1.1.1.3 ! misho     574:     isis_redist_add(api.type, p_generic, api.distance, api.metric);
        !           575:   else
        !           576:     isis_redist_delete(api.type, p_generic);
1.1       misho     577: 
                    578:   return 0;
                    579: }
                    580: 
                    581: static int
                    582: isis_zebra_read_ipv6 (int command, struct zclient *zclient,
1.1.1.3 ! misho     583:                      zebra_size_t length, vrf_id_t vrf_id)
1.1       misho     584: {
1.1.1.3 ! misho     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: 
1.1       misho     635:   return 0;
                    636: }
                    637: 
                    638: int
                    639: isis_distribute_list_update (int routetype)
                    640: {
                    641:   return 0;
                    642: }
                    643: 
1.1.1.3 ! misho     644: void
        !           645: isis_zebra_redistribute_set(int type)
1.1       misho     646: {
1.1.1.3 ! misho     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);
1.1       misho     666: }
                    667: 
                    668: void
1.1.1.3 ! misho     669: isis_zebra_init (struct thread_master *master)
1.1       misho     670: {
1.1.1.3 ! misho     671:   zclient = zclient_new (master);
1.1       misho     672:   zclient_init (zclient, ZEBRA_ROUTE_ISIS);
1.1.1.3 ! misho     673:   zclient->zebra_connected = isis_zebra_connected;
1.1       misho     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>