Annotation of embedaddon/quagga/ripngd/ripng_zebra.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * RIPngd and zebra interface.
                      3:  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.  
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "command.h"
                     26: #include "prefix.h"
                     27: #include "stream.h"
                     28: #include "routemap.h"
                     29: #include "zclient.h"
                     30: #include "log.h"
                     31: 
                     32: #include "ripngd/ripngd.h"
                     33: 
                     34: /* All information about zebra. */
                     35: struct zclient *zclient = NULL;
                     36: 
                     37: /* Callback prototypes for zebra client service. */
                     38: int ripng_interface_up (int, struct zclient *, zebra_size_t);
                     39: int ripng_interface_down (int, struct zclient *, zebra_size_t);
                     40: int ripng_interface_add (int, struct zclient *, zebra_size_t);
                     41: int ripng_interface_delete (int, struct zclient *, zebra_size_t);
                     42: int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
                     43: int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
                     44: 
                     45: void
                     46: ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
                     47:                      unsigned int ifindex, u_char metric)
                     48: {
                     49:   struct zapi_ipv6 api;
                     50: 
                     51:   if (zclient->redist[ZEBRA_ROUTE_RIPNG])
                     52:     {
                     53:       api.type = ZEBRA_ROUTE_RIPNG;
                     54:       api.flags = 0;
                     55:       api.message = 0;
1.1.1.2 ! misho      56:       api.safi = SAFI_UNICAST;
1.1       misho      57:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                     58:       api.nexthop_num = 1;
                     59:       api.nexthop = &nexthop;
                     60:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
                     61:       api.ifindex_num = 1;
                     62:       api.ifindex = &ifindex;
                     63:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
                     64:       api.metric = metric;
                     65:       
                     66:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
                     67:     }
                     68: }
                     69: 
                     70: void
                     71: ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
                     72:                         unsigned int ifindex)
                     73: {
                     74:   struct zapi_ipv6 api;
                     75: 
                     76:   if (zclient->redist[ZEBRA_ROUTE_RIPNG])
                     77:     {
                     78:       api.type = ZEBRA_ROUTE_RIPNG;
                     79:       api.flags = 0;
                     80:       api.message = 0;
1.1.1.2 ! misho      81:       api.safi = SAFI_UNICAST;
1.1       misho      82:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                     83:       api.nexthop_num = 1;
                     84:       api.nexthop = &nexthop;
                     85:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
                     86:       api.ifindex_num = 1;
                     87:       api.ifindex = &ifindex;
                     88: 
                     89:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
                     90:     }
                     91: }
                     92: 
                     93: /* Zebra route add and delete treatment. */
                     94: static int
                     95: ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
                     96:                       zebra_size_t length)
                     97: {
                     98:   struct stream *s;
                     99:   struct zapi_ipv6 api;
                    100:   unsigned long ifindex;
                    101:   struct in6_addr nexthop;
                    102:   struct prefix_ipv6 p;
                    103: 
                    104:   s = zclient->ibuf;
                    105:   ifindex = 0;
                    106:   memset (&nexthop, 0, sizeof (struct in6_addr));
                    107: 
                    108:   /* Type, flags, message. */
                    109:   api.type = stream_getc (s);
                    110:   api.flags = stream_getc (s);
                    111:   api.message = stream_getc (s);
                    112: 
                    113:   /* IPv6 prefix. */
                    114:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    115:   p.family = AF_INET6;
                    116:   p.prefixlen = stream_getc (s);
                    117:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    118: 
                    119:   /* Nexthop, ifindex, distance, metric. */
                    120:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    121:     {
                    122:       api.nexthop_num = stream_getc (s);
                    123:       stream_get (&nexthop, s, 16);
                    124:     }
                    125:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
                    126:     {
                    127:       api.ifindex_num = stream_getc (s);
                    128:       ifindex = stream_getl (s);
                    129:     }
                    130:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    131:     api.distance = stream_getc (s);
                    132:   else
                    133:     api.distance = 0;
                    134:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    135:     api.metric = stream_getl (s);
                    136:   else
                    137:     api.metric = 0;
                    138: 
                    139:   if (command == ZEBRA_IPV6_ROUTE_ADD)
                    140:     ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
                    141:   else
                    142:     ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
                    143: 
                    144:   return 0;
                    145: }
                    146: 
                    147: void
                    148: ripng_zclient_reset (void)
                    149: {
                    150:   zclient_reset (zclient);
                    151: }
                    152: 
                    153: static int
                    154: ripng_redistribute_unset (int type)
                    155: {
                    156:   if (! zclient->redist[type])
                    157:     return CMD_SUCCESS;
                    158: 
                    159:   zclient->redist[type] = 0;
                    160: 
                    161:   if (zclient->sock > 0)
                    162:     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
                    163: 
                    164:   ripng_redistribute_withdraw (type);
                    165:   
                    166:   return CMD_SUCCESS;
                    167: }
                    168: 
                    169: int
                    170: ripng_redistribute_check (int type)
                    171: {
                    172:   return (zclient->redist[type]);
                    173: }
                    174: 
                    175: static void
                    176: ripng_redistribute_metric_set (int type, int metric)
                    177: {
                    178:   ripng->route_map[type].metric_config = 1;
                    179:   ripng->route_map[type].metric = metric;
                    180: }
                    181: 
                    182: static int
                    183: ripng_redistribute_metric_unset (int type)
                    184: {
                    185:   ripng->route_map[type].metric_config = 0;
                    186:   ripng->route_map[type].metric = 0;
                    187:   return 0;
                    188: }
                    189: 
                    190: static void
                    191: ripng_redistribute_routemap_set (int type, const char *name)
                    192: {
                    193:   if (ripng->route_map[type].name)
                    194:     free (ripng->route_map[type].name);
                    195: 
                    196:   ripng->route_map[type].name = strdup (name);
                    197:   ripng->route_map[type].map = route_map_lookup_by_name (name);
                    198: }
                    199: 
                    200: static void
                    201: ripng_redistribute_routemap_unset (int type)
                    202: {
                    203:   if (ripng->route_map[type].name)
                    204:     free (ripng->route_map[type].name);
                    205: 
                    206:   ripng->route_map[type].name = NULL;
                    207:   ripng->route_map[type].map = NULL;
                    208: }
                    209: 
                    210: /* Redistribution types */
                    211: static struct {
                    212:   int type;
                    213:   int str_min_len;
                    214:   const char *str;
                    215: } redist_type[] = {
                    216:   {ZEBRA_ROUTE_KERNEL,  1, "kernel"},
                    217:   {ZEBRA_ROUTE_CONNECT, 1, "connected"},
                    218:   {ZEBRA_ROUTE_STATIC,  1, "static"},
                    219:   {ZEBRA_ROUTE_OSPF6,   1, "ospf6"},
1.1.1.2 ! misho     220:   {ZEBRA_ROUTE_BGP,     2, "bgp"},
        !           221:   {ZEBRA_ROUTE_BABEL,   2, "babel"},
1.1       misho     222:   {0, 0, NULL}
                    223: };
                    224: 
                    225: void
                    226: ripng_redistribute_clean ()
                    227: {
                    228:   int i;
                    229: 
                    230:   for (i = 0; redist_type[i].str; i++)
                    231:     {
                    232:       if (zclient->redist[redist_type[i].type])
                    233:         {
                    234:           if (zclient->sock > 0)
                    235:             zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
                    236:                                      zclient, redist_type[i].type);
                    237: 
                    238:           zclient->redist[redist_type[i].type] = 0;
                    239: 
                    240:           /* Remove the routes from RIPng table. */
                    241:           ripng_redistribute_withdraw (redist_type[i].type);
                    242:         }
                    243:     }
                    244: }
                    245: 
                    246: DEFUN (router_zebra,
                    247:        router_zebra_cmd,
                    248:        "router zebra",
                    249:        "Enable a routing process\n"
                    250:        "Make connection to zebra daemon\n")
                    251: {
                    252:   vty->node = ZEBRA_NODE;
                    253:   zclient->enable = 1;
                    254:   zclient_start (zclient);
                    255:   return CMD_SUCCESS;
                    256: }
                    257: 
                    258: DEFUN (no_router_zebra,
                    259:        no_router_zebra_cmd,
                    260:        "no router zebra",
                    261:        NO_STR
                    262:        "Disable a routing process\n"
                    263:        "Stop connection to zebra daemon\n")
                    264: {
                    265:   zclient->enable = 0;
                    266:   zclient_stop (zclient);
                    267:   return CMD_SUCCESS;
                    268: }
                    269: 
                    270: DEFUN (ripng_redistribute_ripng,
                    271:        ripng_redistribute_ripng_cmd,
                    272:        "redistribute ripng",
                    273:        "Redistribute information from another routing protocol\n"
                    274:        "RIPng route\n")
                    275: {
                    276:   zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
                    277:   return CMD_SUCCESS;
                    278: }
                    279: 
                    280: DEFUN (no_ripng_redistribute_ripng,
                    281:        no_ripng_redistribute_ripng_cmd,
                    282:        "no redistribute ripng",
                    283:        NO_STR
                    284:        "Redistribute information from another routing protocol\n"
                    285:        "RIPng route\n")
                    286: {
                    287:   zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
                    288:   return CMD_SUCCESS;
                    289: }
                    290: 
                    291: DEFUN (ripng_redistribute_type,
                    292:        ripng_redistribute_type_cmd,
1.1.1.2 ! misho     293:        "redistribute " QUAGGA_REDIST_STR_RIPNGD,
        !           294:        "Redistribute\n"
        !           295:        QUAGGA_REDIST_HELP_STR_RIPNGD)
1.1       misho     296: {
1.1.1.2 ! misho     297:   int type;
1.1       misho     298: 
1.1.1.2 ! misho     299:   type = proto_redistnum(AFI_IP6, argv[0]);
        !           300: 
        !           301:   if (type < 0)
1.1       misho     302:     {
1.1.1.2 ! misho     303:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
        !           304:       return CMD_WARNING;
1.1       misho     305:     }
                    306: 
1.1.1.2 ! misho     307:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
        !           308:   return CMD_SUCCESS;
1.1       misho     309: }
                    310: 
                    311: DEFUN (no_ripng_redistribute_type,
                    312:        no_ripng_redistribute_type_cmd,
1.1.1.2 ! misho     313:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD,
1.1       misho     314:        NO_STR
1.1.1.2 ! misho     315:        "Redistribute\n"
        !           316:        QUAGGA_REDIST_HELP_STR_RIPNGD)
1.1       misho     317: {
1.1.1.2 ! misho     318:   int type;
1.1       misho     319: 
1.1.1.2 ! misho     320:   type = proto_redistnum(AFI_IP6, argv[0]);
        !           321: 
        !           322:   if (type < 0)
1.1       misho     323:     {
1.1.1.2 ! misho     324:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
        !           325:       return CMD_WARNING;
1.1       misho     326:     }
                    327: 
1.1.1.2 ! misho     328:   ripng_redistribute_metric_unset (type);
        !           329:   ripng_redistribute_routemap_unset (type);
        !           330:   return ripng_redistribute_unset (type);
1.1       misho     331: }
                    332: 
                    333: 
                    334: DEFUN (ripng_redistribute_type_metric,
                    335:        ripng_redistribute_type_metric_cmd,
1.1.1.2 ! misho     336:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16>",
        !           337:        "Redistribute\n"
        !           338:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     339:        "Metric\n"
                    340:        "Metric value\n")
                    341: {
1.1.1.2 ! misho     342:   int type;
1.1       misho     343:   int metric;
                    344: 
                    345:   metric = atoi (argv[1]);
1.1.1.2 ! misho     346:   type = proto_redistnum(AFI_IP6, argv[0]);
1.1       misho     347: 
1.1.1.2 ! misho     348:   if (type < 0)
        !           349:     {
        !           350:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
        !           351:       return CMD_WARNING;
        !           352:     }
1.1       misho     353: 
1.1.1.2 ! misho     354:   ripng_redistribute_metric_set (type, metric);
        !           355:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
        !           356:   return CMD_SUCCESS;
1.1       misho     357: }
                    358: 
                    359: ALIAS (no_ripng_redistribute_type,
                    360:        no_ripng_redistribute_type_metric_cmd,
1.1.1.2 ! misho     361:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16>",
1.1       misho     362:        NO_STR
1.1.1.2 ! misho     363:        "Redistribute\n"
        !           364:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     365:        "Metric\n"
                    366:        "Metric value\n")
                    367: 
                    368: DEFUN (ripng_redistribute_type_routemap,
                    369:        ripng_redistribute_type_routemap_cmd,
1.1.1.2 ! misho     370:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " route-map WORD",
        !           371:        "Redistribute\n"
        !           372:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     373:        "Route map reference\n"
                    374:        "Pointer to route-map entries\n")
                    375: {
1.1.1.2 ! misho     376:   int type;
1.1       misho     377: 
1.1.1.2 ! misho     378:   type = proto_redistnum(AFI_IP6, argv[0]);
1.1       misho     379: 
1.1.1.2 ! misho     380:   if (type < 0)
        !           381:     {
        !           382:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
        !           383:       return CMD_WARNING;
        !           384:     }
1.1       misho     385: 
1.1.1.2 ! misho     386:   ripng_redistribute_routemap_set (type, argv[1]);
        !           387:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
        !           388:  return CMD_SUCCESS;
1.1       misho     389: }
                    390: 
                    391: ALIAS (no_ripng_redistribute_type,
                    392:        no_ripng_redistribute_type_routemap_cmd,
1.1.1.2 ! misho     393:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " route-map WORD",
1.1       misho     394:        NO_STR
1.1.1.2 ! misho     395:        "Redistribute\n"
        !           396:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     397:        "Route map reference\n"
                    398:        "Pointer to route-map entries\n")
                    399: 
                    400: DEFUN (ripng_redistribute_type_metric_routemap,
                    401:        ripng_redistribute_type_metric_routemap_cmd,
1.1.1.2 ! misho     402:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
        !           403:        "Redistribute\n"
        !           404:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     405:        "Metric\n"
                    406:        "Metric value\n"
                    407:        "Route map reference\n"
                    408:        "Pointer to route-map entries\n")
                    409: {
1.1.1.2 ! misho     410:   int type;
1.1       misho     411:   int metric;
                    412: 
1.1.1.2 ! misho     413:   type = proto_redistnum(AFI_IP6, argv[0]);
1.1       misho     414:   metric = atoi (argv[1]);
                    415: 
1.1.1.2 ! misho     416:   if (type < 0)
        !           417:     {
        !           418:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
        !           419:       return CMD_WARNING;
        !           420:     }
1.1       misho     421: 
1.1.1.2 ! misho     422:   ripng_redistribute_metric_set (type, metric);
        !           423:   ripng_redistribute_routemap_set (type, argv[2]);
        !           424:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
        !           425:   return CMD_SUCCESS;
1.1       misho     426: }
                    427: 
                    428: ALIAS (no_ripng_redistribute_type,
                    429:        no_ripng_redistribute_type_metric_routemap_cmd,
1.1.1.2 ! misho     430:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
1.1       misho     431:        NO_STR
1.1.1.2 ! misho     432:        "Redistribute\n"
        !           433:        QUAGGA_REDIST_HELP_STR_RIPNGD
1.1       misho     434:        "Route map reference\n"
                    435:        "Pointer to route-map entries\n")
                    436: 
                    437: void
                    438: ripng_redistribute_write (struct vty *vty, int config_mode)
                    439: {
                    440:   int i;
                    441: 
                    442:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                    443:     if (i != zclient->redist_default && zclient->redist[i])
                    444:       {
                    445:       if (config_mode)
                    446:        {
                    447:          if (ripng->route_map[i].metric_config)
                    448:            {
                    449:              if (ripng->route_map[i].name)
                    450:                vty_out (vty, " redistribute %s metric %d route-map %s%s",
                    451:                         zebra_route_string(i), ripng->route_map[i].metric,
                    452:                        ripng->route_map[i].name, VTY_NEWLINE);
                    453:              else
                    454:                vty_out (vty, " redistribute %s metric %d%s",
                    455:                        zebra_route_string(i), ripng->route_map[i].metric,
                    456:                        VTY_NEWLINE);
                    457:            }
                    458:          else
                    459:            {
                    460:              if (ripng->route_map[i].name)
                    461:                vty_out (vty, " redistribute %s route-map %s%s",
                    462:                         zebra_route_string(i), ripng->route_map[i].name,
                    463:                         VTY_NEWLINE);
                    464:              else
                    465:                vty_out (vty, " redistribute %s%s", zebra_route_string(i),
                    466:                         VTY_NEWLINE);
                    467:            }
                    468:        }
                    469:       else
                    470:        vty_out (vty, "    %s", zebra_route_string(i));
                    471:       }
                    472: }
                    473: 
                    474: /* RIPng configuration write function. */
                    475: static int
                    476: zebra_config_write (struct vty *vty)
                    477: {
                    478:   if (! zclient->enable)
                    479:     {
                    480:       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
                    481:       return 1;
                    482:     }
                    483:   else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
                    484:     {
                    485:       vty_out (vty, "router zebra%s", VTY_NEWLINE);
                    486:       vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
                    487:       return 1;
                    488:     }
                    489:   return 0;
                    490: }
                    491: 
                    492: /* Zebra node structure. */
                    493: static struct cmd_node zebra_node =
                    494: {
                    495:   ZEBRA_NODE,
                    496:   "%s(config-router)# ",
                    497: };
                    498: 
                    499: /* Initialize zebra structure and it's commands. */
                    500: void
                    501: zebra_init ()
                    502: {
                    503:   /* Allocate zebra structure. */
                    504:   zclient = zclient_new ();
                    505:   zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
                    506: 
                    507:   zclient->interface_up = ripng_interface_up;
                    508:   zclient->interface_down = ripng_interface_down;
                    509:   zclient->interface_add = ripng_interface_add;
                    510:   zclient->interface_delete = ripng_interface_delete;
                    511:   zclient->interface_address_add = ripng_interface_address_add;
                    512:   zclient->interface_address_delete = ripng_interface_address_delete;
                    513:   zclient->ipv6_route_add = ripng_zebra_read_ipv6;
                    514:   zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
                    515:   
                    516:   /* Install zebra node. */
                    517:   install_node (&zebra_node, zebra_config_write);
                    518: 
                    519:   /* Install command element for zebra node. */ 
                    520:   install_element (CONFIG_NODE, &router_zebra_cmd);
                    521:   install_element (CONFIG_NODE, &no_router_zebra_cmd);
                    522:   install_default (ZEBRA_NODE);
                    523:   install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
                    524:   install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
                    525: 
                    526:   /* Install command elements to ripng node */
                    527:   install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
                    528:   install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
                    529:   install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
                    530:   install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
                    531:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
                    532:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
                    533:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
                    534:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
                    535: }

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