Annotation of embedaddon/quagga/babeld/babel_zebra.c, revision 1.1.1.1

1.1       misho       1: /*  
                      2:  *  This file is free software: you may copy, redistribute and/or modify it  
                      3:  *  under the terms of the GNU General Public License as published by the  
                      4:  *  Free Software Foundation, either version 2 of the License, or (at your  
                      5:  *  option) any later version.  
                      6:  *  
                      7:  *  This file is distributed in the hope that it will be useful, but  
                      8:  *  WITHOUT ANY WARRANTY; without even the implied warranty of  
                      9:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
                     10:  *  General Public License for more details.  
                     11:  *  
                     12:  *  You should have received a copy of the GNU General Public License  
                     13:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
                     14:  *  
                     15:  * This file incorporates work covered by the following copyright and  
                     16:  * permission notice:  
                     17:  *
                     18: Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
                     19: 
                     20: Permission is hereby granted, free of charge, to any person obtaining a copy
                     21: of this software and associated documentation files (the "Software"), to deal
                     22: in the Software without restriction, including without limitation the rights
                     23: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     24: copies of the Software, and to permit persons to whom the Software is
                     25: furnished to do so, subject to the following conditions:
                     26: 
                     27: The above copyright notice and this permission notice shall be included in
                     28: all copies or substantial portions of the Software.
                     29: 
                     30: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     31: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     32: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
                     33: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     34: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     35: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     36: THE SOFTWARE.
                     37: */
                     38: 
                     39: /* quagga's includes */
                     40: #include <zebra.h>
                     41: #include "command.h"
                     42: #include "zclient.h"
                     43: #include "stream.h"
                     44: 
                     45: /* babel's includes*/
                     46: #include "babel_zebra.h"
                     47: #include "babel_interface.h"
                     48: #include "xroute.h"
                     49: #include "util.h"
                     50: 
                     51: void babelz_zebra_init(void);
                     52: 
                     53: 
                     54: /* we must use a pointer because of zclient.c's functions (new, free). */
                     55: struct zclient *zclient;
                     56: static int zebra_config_write (struct vty *vty);
                     57: 
                     58: /* Debug types */
                     59: static struct {
                     60:     int type;
                     61:     int str_min_len;
                     62:     const char *str;
                     63: } debug_type[] = {
                     64:     {BABEL_DEBUG_COMMON,  1, "common"},
                     65:     {BABEL_DEBUG_KERNEL,  1, "kernel"},
                     66:     {BABEL_DEBUG_FILTER,  1, "filter"},
                     67:     {BABEL_DEBUG_TIMEOUT, 1, "timeout"},
                     68:     {BABEL_DEBUG_IF,      1, "interface"},
                     69:     {BABEL_DEBUG_ROUTE,   1, "route"},
                     70:     {BABEL_DEBUG_ALL,     1, "all"},
                     71:     {0, 0, NULL}
                     72: };
                     73: 
                     74: /* Zebra node structure. */
                     75: struct cmd_node zebra_node =
                     76: {
                     77:     ZEBRA_NODE,
                     78:     "%s(config-router)# ",
                     79:     1 /* vtysh? yes */
                     80: };
                     81: 
                     82: 
                     83: /* Zebra route add and delete treatment (ipv6). */
                     84: static int
                     85: babel_zebra_read_ipv6 (int command, struct zclient *zclient,
                     86:                       zebra_size_t length)
                     87: {
                     88:     struct stream *s;
                     89:     struct zapi_ipv6 api;
                     90:     unsigned long ifindex = -1;
                     91:     struct in6_addr nexthop;
                     92:     struct prefix_ipv6 prefix;
                     93: 
                     94:     s = zclient->ibuf;
                     95:     ifindex = 0;
                     96:     memset (&nexthop, 0, sizeof (struct in6_addr));
                     97:     memset (&api, 0, sizeof(struct zapi_ipv6));
                     98:     memset (&prefix, 0, sizeof (struct prefix_ipv6));
                     99: 
                    100:     /* Type, flags, message. */
                    101:     api.type = stream_getc (s);
                    102:     api.flags = stream_getc (s);
                    103:     api.message = stream_getc (s);
                    104: 
                    105:     /* IPv6 prefix. */
                    106:     prefix.family = AF_INET6;
                    107:     prefix.prefixlen = stream_getc (s);
                    108:     stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
                    109: 
                    110:     /* Nexthop, ifindex, distance, metric. */
                    111:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
                    112:         api.nexthop_num = stream_getc (s);
                    113:         stream_get (&nexthop, s, sizeof(nexthop));
                    114:     }
                    115:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
                    116:         api.ifindex_num = stream_getc (s);
                    117:         ifindex = stream_getl (s);
                    118:     }
                    119:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    120:         api.distance = stream_getc (s);
                    121:     else
                    122:         api.distance = 0;
                    123:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    124:         api.metric = stream_getl (s);
                    125:     else
                    126:         api.metric = 0;
                    127: 
                    128:     if (command == ZEBRA_IPV6_ROUTE_ADD)
                    129:         babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop);
                    130:     else
                    131:         babel_ipv6_route_delete(&api, &prefix, ifindex);
                    132: 
                    133:     return 0;
                    134: }
                    135: 
                    136: static int
                    137: babel_zebra_read_ipv4 (int command, struct zclient *zclient,
                    138:                       zebra_size_t length)
                    139: {
                    140:     struct stream *s;
                    141:     struct zapi_ipv4 api;
                    142:     unsigned long ifindex = -1;
                    143:     struct in_addr nexthop;
                    144:     struct prefix_ipv4 prefix;
                    145: 
                    146:     s = zclient->ibuf;
                    147:     ifindex = 0;
                    148:     memset (&nexthop, 0, sizeof (struct in_addr));
                    149:     memset (&api, 0, sizeof(struct zapi_ipv4));
                    150:     memset (&prefix, 0, sizeof (struct prefix_ipv4));
                    151: 
                    152:     /* Type, flags, message. */
                    153:     api.type = stream_getc (s);
                    154:     api.flags = stream_getc (s);
                    155:     api.message = stream_getc (s);
                    156: 
                    157:     /* IPv6 prefix. */
                    158:     prefix.family = AF_INET;
                    159:     prefix.prefixlen = stream_getc (s);
                    160:     stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
                    161: 
                    162:     /* Nexthop, ifindex, distance, metric. */
                    163:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
                    164:         api.nexthop_num = stream_getc (s);
                    165:         stream_get (&nexthop, s, sizeof(nexthop));
                    166:     }
                    167:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
                    168:         api.ifindex_num = stream_getc (s);
                    169:         ifindex = stream_getl (s);
                    170:     }
                    171:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    172:         api.distance = stream_getc (s);
                    173:     else
                    174:         api.distance = 0;
                    175:     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    176:         api.metric = stream_getl (s);
                    177:     else
                    178:         api.metric = 0;
                    179: 
                    180:     if (command == ZEBRA_IPV6_ROUTE_ADD) {
                    181:         babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop);
                    182:     } else {
                    183:         babel_ipv4_route_delete(&api, &prefix, ifindex);
                    184:     }
                    185: 
                    186:     return 0;
                    187: }
                    188: 
                    189: /* [Babel Command] */
                    190: DEFUN (babel_redistribute_type,
                    191:        babel_redistribute_type_cmd,
                    192:        "redistribute " QUAGGA_REDIST_STR_BABELD,
                    193:        "Redistribute\n"
                    194:        QUAGGA_REDIST_HELP_STR_BABELD)
                    195: {
                    196:     int type;
                    197: 
                    198:     type = proto_redistnum(AFI_IP6, argv[0]);
                    199: 
                    200:     if (type < 0)
                    201:         type = proto_redistnum(AFI_IP, argv[0]);
                    202: 
                    203:     if (type < 0) {
                    204:         vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
                    205:         return CMD_WARNING;
                    206:     }
                    207: 
                    208:     zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
                    209:     return CMD_SUCCESS;
                    210: }
                    211: 
                    212: /* [Babel Command] */
                    213: DEFUN (no_babel_redistribute_type,
                    214:        no_babel_redistribute_type_cmd,
                    215:        "no redistribute " QUAGGA_REDIST_STR_BABELD,
                    216:        NO_STR
                    217:        "Redistribute\n"
                    218:        QUAGGA_REDIST_HELP_STR_BABELD)
                    219: {
                    220:     int type;
                    221: 
                    222:     type = proto_redistnum(AFI_IP6, argv[0]);
                    223: 
                    224:     if (type < 0)
                    225:         type = proto_redistnum(AFI_IP, argv[0]);
                    226: 
                    227:     if (type < 0) {
                    228:         vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
                    229:         return CMD_WARNING;
                    230:     }
                    231: 
                    232:     zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
                    233:     /* perhaps should we remove xroutes having the same type... */
                    234:     return CMD_SUCCESS;
                    235: }
                    236: 
                    237: #ifndef NO_DEBUG
                    238: /* [Babel Command] */
                    239: DEFUN (debug_babel,
                    240:        debug_babel_cmd,
                    241:        "debug babel (common|kernel|filter|timeout|interface|route|all)",
                    242:        "Enable debug messages for specific or all part.\n"
                    243:        "Babel information\n"
                    244:        "Common messages (default)\n"
                    245:        "Kernel messages\n"
                    246:        "Filter messages\n"
                    247:        "Timeout messages\n"
                    248:        "Interface messages\n"
                    249:        "Route messages\n"
                    250:        "All messages\n")
                    251: {
                    252:     int i;
                    253: 
                    254:     for(i = 0; debug_type[i].str != NULL; i++) {
                    255:         if (strncmp (debug_type[i].str, argv[0],
                    256:                      debug_type[i].str_min_len) == 0) {
                    257:             debug |= debug_type[i].type;
                    258:             return CMD_SUCCESS;
                    259:         }
                    260:     }
                    261: 
                    262:     vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
                    263: 
                    264:     return CMD_WARNING;
                    265: }
                    266: 
                    267: /* [Babel Command] */
                    268: DEFUN (no_debug_babel,
                    269:        no_debug_babel_cmd,
                    270:        "no debug babel (common|kernel|filter|timeout|interface|route|all)",
                    271:        NO_STR
                    272:        "Disable debug messages for specific or all part.\n"
                    273:        "Babel information\n"
                    274:        "Common messages (default)\n"
                    275:        "Kernel messages\n"
                    276:        "Filter messages\n"
                    277:        "Timeout messages\n"
                    278:        "Interface messages\n"
                    279:        "Route messages\n"
                    280:        "All messages\n")
                    281: {
                    282:     int i;
                    283: 
                    284:     for (i = 0; debug_type[i].str; i++) {
                    285:         if (strncmp(debug_type[i].str, argv[0],
                    286:                     debug_type[i].str_min_len) == 0) {
                    287:             debug &= ~debug_type[i].type;
                    288:             return CMD_SUCCESS;
                    289:         }
                    290:     }
                    291: 
                    292:     vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
                    293: 
                    294:     return CMD_WARNING;
                    295: }
                    296: #endif /* NO_DEBUG */
                    297: 
                    298: /* Output "debug" statement lines, if necessary. */
                    299: int
                    300: debug_babel_config_write (struct vty * vty)
                    301: {
                    302: #ifdef NO_DEBUG
                    303:     return 0;
                    304: #else
                    305:     int i, lines = 0;
                    306: 
                    307:     if (debug == BABEL_DEBUG_ALL)
                    308:     {
                    309:         vty_out (vty, "debug babel all%s", VTY_NEWLINE);
                    310:         lines++;
                    311:     }
                    312:     else
                    313:         for (i = 0; debug_type[i].str != NULL; i++)
                    314:             if
                    315:             (
                    316:                 debug_type[i].type != BABEL_DEBUG_ALL
                    317:                 && CHECK_FLAG (debug, debug_type[i].type)
                    318:             )
                    319:             {
                    320:                 vty_out (vty, "debug babel %s%s", debug_type[i].str, VTY_NEWLINE);
                    321:                 lines++;
                    322:             }
                    323:     if (lines)
                    324:     {
                    325:         vty_out (vty, "!%s", VTY_NEWLINE);
                    326:         lines++;
                    327:     }
                    328:     return lines;
                    329: #endif /* NO_DEBUG */
                    330: }
                    331: 
                    332: void babelz_zebra_init(void)
                    333: {
                    334:     zclient = zclient_new();
                    335:     zclient_init(zclient, ZEBRA_ROUTE_BABEL);
                    336: 
                    337:     zclient->interface_add = babel_interface_add;
                    338:     zclient->interface_delete = babel_interface_delete;
                    339:     zclient->interface_up = babel_interface_up;
                    340:     zclient->interface_down = babel_interface_down;
                    341:     zclient->interface_address_add = babel_interface_address_add;
                    342:     zclient->interface_address_delete = babel_interface_address_delete;
                    343:     zclient->ipv4_route_add = babel_zebra_read_ipv4;
                    344:     zclient->ipv4_route_delete = babel_zebra_read_ipv4;
                    345:     zclient->ipv6_route_add = babel_zebra_read_ipv6;
                    346:     zclient->ipv6_route_delete = babel_zebra_read_ipv6;
                    347: 
                    348:     install_node (&zebra_node, zebra_config_write);
                    349:     install_element(BABEL_NODE, &babel_redistribute_type_cmd);
                    350:     install_element(BABEL_NODE, &no_babel_redistribute_type_cmd);
                    351:     install_element(ENABLE_NODE, &debug_babel_cmd);
                    352:     install_element(ENABLE_NODE, &no_debug_babel_cmd);
                    353:     install_element(CONFIG_NODE, &debug_babel_cmd);
                    354:     install_element(CONFIG_NODE, &no_debug_babel_cmd);
                    355: }
                    356: 
                    357: static int
                    358: zebra_config_write (struct vty *vty)
                    359: {
                    360:     if (! zclient->enable)
                    361:     {
                    362:         vty_out (vty, "no router zebra%s", VTY_NEWLINE);
                    363:         return 1;
                    364:     }
                    365:     else if (! zclient->redist[ZEBRA_ROUTE_BABEL])
                    366:     {
                    367:         vty_out (vty, "router zebra%s", VTY_NEWLINE);
                    368:         vty_out (vty, " no redistribute babel%s", VTY_NEWLINE);
                    369:         return 1;
                    370:     }
                    371:     return 0;
                    372: }
                    373: 
                    374: void
                    375: babel_zebra_close_connexion(void)
                    376: {
                    377:     zclient_stop(zclient);
                    378: }

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