Annotation of embedaddon/quagga/lib/zclient.c, revision 1.1.1.3

1.1       misho       1: /* Zebra's client library.
                      2:  * Copyright (C) 1999 Kunihiro Ishiguro
                      3:  * Copyright (C) 2005 Andrew J. Schorr
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify
                      8:  * it under the terms of the GNU General Public License as published
                      9:  * by the Free Software Foundation; either version 2, or (at your
                     10:  * option) any 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
                     19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20:  * MA 02111-1307, USA.
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "prefix.h"
                     26: #include "stream.h"
                     27: #include "buffer.h"
                     28: #include "network.h"
                     29: #include "if.h"
                     30: #include "log.h"
                     31: #include "thread.h"
                     32: #include "zclient.h"
                     33: #include "memory.h"
                     34: #include "table.h"
                     35: 
                     36: /* Zebra client events. */
                     37: enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
                     38: 
                     39: /* Prototype for event manager. */
                     40: static void zclient_event (enum event, struct zclient *);
                     41: 
                     42: extern struct thread_master *master;
                     43: 
1.1.1.2   misho      44: char *zclient_serv_path = NULL;
                     45: 
1.1       misho      46: /* This file local debug flag. */
                     47: int zclient_debug = 0;
                     48: 
                     49: /* Allocate zclient structure. */
                     50: struct zclient *
                     51: zclient_new ()
                     52: {
                     53:   struct zclient *zclient;
                     54:   zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
                     55: 
                     56:   zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                     57:   zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                     58:   zclient->wb = buffer_new(0);
                     59: 
                     60:   return zclient;
                     61: }
                     62: 
                     63: /* This function is only called when exiting, because
                     64:    many parts of the code do not check for I/O errors, so they could
                     65:    reference an invalid pointer if the structure was ever freed.
                     66: 
                     67:    Free zclient structure. */
                     68: void
                     69: zclient_free (struct zclient *zclient)
                     70: {
                     71:   if (zclient->ibuf)
                     72:     stream_free(zclient->ibuf);
                     73:   if (zclient->obuf)
                     74:     stream_free(zclient->obuf);
                     75:   if (zclient->wb)
                     76:     buffer_free(zclient->wb);
                     77: 
                     78:   XFREE (MTYPE_ZCLIENT, zclient);
                     79: }
                     80: 
                     81: /* Initialize zebra client.  Argument redist_default is unwanted
                     82:    redistribute route type. */
                     83: void
                     84: zclient_init (struct zclient *zclient, int redist_default)
                     85: {
                     86:   int i;
                     87:   
                     88:   /* Enable zebra client connection by default. */
                     89:   zclient->enable = 1;
                     90: 
                     91:   /* Set -1 to the default socket value. */
                     92:   zclient->sock = -1;
                     93: 
                     94:   /* Clear redistribution flags. */
                     95:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                     96:     zclient->redist[i] = 0;
                     97: 
                     98:   /* Set unwanted redistribute route.  bgpd does not need BGP route
                     99:      redistribution. */
                    100:   zclient->redist_default = redist_default;
                    101:   zclient->redist[redist_default] = 1;
                    102: 
                    103:   /* Set default-information redistribute to zero. */
                    104:   zclient->default_information = 0;
                    105: 
                    106:   /* Schedule first zclient connection. */
                    107:   if (zclient_debug)
                    108:     zlog_debug ("zclient start scheduled");
                    109: 
                    110:   zclient_event (ZCLIENT_SCHEDULE, zclient);
                    111: }
                    112: 
                    113: /* Stop zebra client services. */
                    114: void
                    115: zclient_stop (struct zclient *zclient)
                    116: {
                    117:   if (zclient_debug)
                    118:     zlog_debug ("zclient stopped");
                    119: 
                    120:   /* Stop threads. */
                    121:   THREAD_OFF(zclient->t_read);
                    122:   THREAD_OFF(zclient->t_connect);
                    123:   THREAD_OFF(zclient->t_write);
                    124: 
                    125:   /* Reset streams. */
                    126:   stream_reset(zclient->ibuf);
                    127:   stream_reset(zclient->obuf);
                    128: 
                    129:   /* Empty the write buffer. */
                    130:   buffer_reset(zclient->wb);
                    131: 
                    132:   /* Close socket. */
                    133:   if (zclient->sock >= 0)
                    134:     {
                    135:       close (zclient->sock);
                    136:       zclient->sock = -1;
                    137:     }
                    138:   zclient->fail = 0;
                    139: }
                    140: 
                    141: void
                    142: zclient_reset (struct zclient *zclient)
                    143: {
                    144:   zclient_stop (zclient);
                    145:   zclient_init (zclient, zclient->redist_default);
                    146: }
                    147: 
1.1.1.2   misho     148: #ifdef HAVE_TCP_ZEBRA
                    149: 
1.1       misho     150: /* Make socket to zebra daemon. Return zebra socket. */
1.1.1.2   misho     151: static int
1.1       misho     152: zclient_socket(void)
                    153: {
                    154:   int sock;
                    155:   int ret;
                    156:   struct sockaddr_in serv;
                    157: 
                    158:   /* We should think about IPv6 connection. */
                    159:   sock = socket (AF_INET, SOCK_STREAM, 0);
                    160:   if (sock < 0)
                    161:     return -1;
                    162:   
                    163:   /* Make server socket. */ 
                    164:   memset (&serv, 0, sizeof (struct sockaddr_in));
                    165:   serv.sin_family = AF_INET;
                    166:   serv.sin_port = htons (ZEBRA_PORT);
                    167: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                    168:   serv.sin_len = sizeof (struct sockaddr_in);
                    169: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                    170:   serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
                    171: 
                    172:   /* Connect to zebra. */
                    173:   ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
                    174:   if (ret < 0)
                    175:     {
                    176:       close (sock);
                    177:       return -1;
                    178:     }
                    179:   return sock;
                    180: }
                    181: 
1.1.1.2   misho     182: #else
                    183: 
1.1       misho     184: /* For sockaddr_un. */
                    185: #include <sys/un.h>
                    186: 
1.1.1.2   misho     187: static int
1.1       misho     188: zclient_socket_un (const char *path)
                    189: {
                    190:   int ret;
                    191:   int sock, len;
                    192:   struct sockaddr_un addr;
                    193: 
                    194:   sock = socket (AF_UNIX, SOCK_STREAM, 0);
                    195:   if (sock < 0)
                    196:     return -1;
                    197:   
                    198:   /* Make server socket. */ 
                    199:   memset (&addr, 0, sizeof (struct sockaddr_un));
                    200:   addr.sun_family = AF_UNIX;
                    201:   strncpy (addr.sun_path, path, strlen (path));
                    202: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
                    203:   len = addr.sun_len = SUN_LEN(&addr);
                    204: #else
                    205:   len = sizeof (addr.sun_family) + strlen (addr.sun_path);
                    206: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
                    207: 
                    208:   ret = connect (sock, (struct sockaddr *) &addr, len);
                    209:   if (ret < 0)
                    210:     {
                    211:       close (sock);
                    212:       return -1;
                    213:     }
                    214:   return sock;
                    215: }
                    216: 
1.1.1.2   misho     217: #endif /* HAVE_TCP_ZEBRA */
                    218: 
                    219: /**
                    220:  * Connect to zebra daemon.
                    221:  * @param zclient a pointer to zclient structure
                    222:  * @return socket fd just to make sure that connection established
                    223:  * @see zclient_init
                    224:  * @see zclient_new
                    225:  */
                    226: int
                    227: zclient_socket_connect (struct zclient *zclient)
                    228: {
                    229: #ifdef HAVE_TCP_ZEBRA
                    230:   zclient->sock = zclient_socket ();
                    231: #else
                    232:   zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH);
                    233: #endif
                    234:   return zclient->sock;
                    235: }
                    236: 
1.1       misho     237: static int
                    238: zclient_failed(struct zclient *zclient)
                    239: {
                    240:   zclient->fail++;
                    241:   zclient_stop(zclient);
                    242:   zclient_event(ZCLIENT_CONNECT, zclient);
                    243:   return -1;
                    244: }
                    245: 
                    246: static int
                    247: zclient_flush_data(struct thread *thread)
                    248: {
                    249:   struct zclient *zclient = THREAD_ARG(thread);
                    250: 
                    251:   zclient->t_write = NULL;
                    252:   if (zclient->sock < 0)
                    253:     return -1;
                    254:   switch (buffer_flush_available(zclient->wb, zclient->sock))
                    255:     {
                    256:     case BUFFER_ERROR:
                    257:       zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
                    258:                __func__, zclient->sock);
                    259:       return zclient_failed(zclient);
                    260:       break;
                    261:     case BUFFER_PENDING:
                    262:       zclient->t_write = thread_add_write(master, zclient_flush_data,
                    263:                                          zclient, zclient->sock);
                    264:       break;
                    265:     case BUFFER_EMPTY:
                    266:       break;
                    267:     }
                    268:   return 0;
                    269: }
                    270: 
                    271: int
                    272: zclient_send_message(struct zclient *zclient)
                    273: {
                    274:   if (zclient->sock < 0)
                    275:     return -1;
                    276:   switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
                    277:                       stream_get_endp(zclient->obuf)))
                    278:     {
                    279:     case BUFFER_ERROR:
                    280:       zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
                    281:                 __func__, zclient->sock);
                    282:       return zclient_failed(zclient);
                    283:       break;
                    284:     case BUFFER_EMPTY:
                    285:       THREAD_OFF(zclient->t_write);
                    286:       break;
                    287:     case BUFFER_PENDING:
                    288:       THREAD_WRITE_ON(master, zclient->t_write,
                    289:                      zclient_flush_data, zclient, zclient->sock);
                    290:       break;
                    291:     }
                    292:   return 0;
                    293: }
                    294: 
                    295: void
                    296: zclient_create_header (struct stream *s, uint16_t command)
                    297: {
                    298:   /* length placeholder, caller can update */
                    299:   stream_putw (s, ZEBRA_HEADER_SIZE);
                    300:   stream_putc (s, ZEBRA_HEADER_MARKER);
                    301:   stream_putc (s, ZSERV_VERSION);
                    302:   stream_putw (s, command);
                    303: }
                    304: 
                    305: /* Send simple Zebra message. */
                    306: static int
                    307: zebra_message_send (struct zclient *zclient, int command)
                    308: {
                    309:   struct stream *s;
                    310: 
                    311:   /* Get zclient output buffer. */
                    312:   s = zclient->obuf;
                    313:   stream_reset (s);
                    314: 
                    315:   /* Send very simple command only Zebra message. */
                    316:   zclient_create_header (s, command);
                    317:   
                    318:   return zclient_send_message(zclient);
                    319: }
                    320: 
1.1.1.2   misho     321: static int
                    322: zebra_hello_send (struct zclient *zclient)
                    323: {
                    324:   struct stream *s;
                    325: 
                    326:   if (zclient->redist_default)
                    327:     {
                    328:       s = zclient->obuf;
                    329:       stream_reset (s);
                    330: 
                    331:       zclient_create_header (s, ZEBRA_HELLO);
                    332:       stream_putc (s, zclient->redist_default);
                    333:       stream_putw_at (s, 0, stream_get_endp (s));
                    334:       return zclient_send_message(zclient);
                    335:     }
                    336: 
                    337:   return 0;
                    338: }
                    339: 
1.1       misho     340: /* Make connection to zebra daemon. */
                    341: int
                    342: zclient_start (struct zclient *zclient)
                    343: {
                    344:   int i;
                    345: 
                    346:   if (zclient_debug)
                    347:     zlog_debug ("zclient_start is called");
                    348: 
                    349:   /* zclient is disabled. */
                    350:   if (! zclient->enable)
                    351:     return 0;
                    352: 
                    353:   /* If already connected to the zebra. */
                    354:   if (zclient->sock >= 0)
                    355:     return 0;
                    356: 
                    357:   /* Check connect thread. */
                    358:   if (zclient->t_connect)
                    359:     return 0;
                    360: 
1.1.1.2   misho     361:   if (zclient_socket_connect(zclient) < 0)
1.1       misho     362:     {
                    363:       if (zclient_debug)
                    364:        zlog_debug ("zclient connection fail");
                    365:       zclient->fail++;
                    366:       zclient_event (ZCLIENT_CONNECT, zclient);
                    367:       return -1;
                    368:     }
                    369: 
                    370:   if (set_nonblocking(zclient->sock) < 0)
                    371:     zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
                    372: 
                    373:   /* Clear fail count. */
                    374:   zclient->fail = 0;
                    375:   if (zclient_debug)
                    376:     zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
                    377:       
                    378:   /* Create read thread. */
                    379:   zclient_event (ZCLIENT_READ, zclient);
                    380: 
1.1.1.2   misho     381:   zebra_hello_send (zclient);
                    382: 
1.1       misho     383:   /* We need router-id information. */
                    384:   zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
                    385: 
                    386:   /* We need interface information. */
                    387:   zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
                    388: 
                    389:   /* Flush all redistribute request. */
                    390:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                    391:     if (i != zclient->redist_default && zclient->redist[i])
                    392:       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
                    393: 
                    394:   /* If default information is needed. */
                    395:   if (zclient->default_information)
                    396:     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
                    397: 
                    398:   return 0;
                    399: }
                    400: 
                    401: /* This function is a wrapper function for calling zclient_start from
                    402:    timer or event thread. */
                    403: static int
                    404: zclient_connect (struct thread *t)
                    405: {
                    406:   struct zclient *zclient;
                    407: 
                    408:   zclient = THREAD_ARG (t);
                    409:   zclient->t_connect = NULL;
                    410: 
                    411:   if (zclient_debug)
                    412:     zlog_debug ("zclient_connect is called");
                    413: 
                    414:   return zclient_start (zclient);
                    415: }
                    416: 
                    417:  /* 
                    418:   * "xdr_encode"-like interface that allows daemon (client) to send
                    419:   * a message to zebra server for a route that needs to be
                    420:   * added/deleted to the kernel. Info about the route is specified
                    421:   * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
                    422:   * the info down the zclient socket using the stream_* functions.
                    423:   * 
                    424:   * The corresponding read ("xdr_decode") function on the server
                    425:   * side is zread_ipv4_add()/zread_ipv4_delete().
                    426:   *
                    427:   *  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
                    428:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    429:   * |            Length (2)         |    Command    | Route Type    |
                    430:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    431:   * | ZEBRA Flags   | Message Flags | Prefix length |
                    432:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    433:   * | Destination IPv4 Prefix for route                             |
                    434:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    435:   * | Nexthop count | 
                    436:   * +-+-+-+-+-+-+-+-+
                    437:   *
                    438:   * 
                    439:   * A number of IPv4 nexthop(s) or nexthop interface index(es) are then 
                    440:   * described, as per the Nexthop count. Each nexthop described as:
                    441:   *
                    442:   * +-+-+-+-+-+-+-+-+
                    443:   * | Nexthop Type  |  Set to one of ZEBRA_NEXTHOP_*
                    444:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    445:   * |       IPv4 Nexthop address or Interface Index number          |
                    446:   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    447:   *
                    448:   * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
                    449:   * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ 
                    450:   * nexthop information is provided, and the message describes a prefix
                    451:   * to blackhole or reject route.
                    452:   *
                    453:   * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
                    454:   * byte value.
                    455:   * 
                    456:   * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
                    457:   * byte value.
                    458:   *
                    459:   * XXX: No attention paid to alignment.
                    460:   */ 
                    461: int
                    462: zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
                    463:                  struct zapi_ipv4 *api)
                    464: {
                    465:   int i;
                    466:   int psize;
                    467:   struct stream *s;
                    468: 
                    469:   /* Reset stream. */
                    470:   s = zclient->obuf;
                    471:   stream_reset (s);
                    472:   
                    473:   zclient_create_header (s, cmd);
                    474:   
                    475:   /* Put type and nexthop. */
                    476:   stream_putc (s, api->type);
                    477:   stream_putc (s, api->flags);
                    478:   stream_putc (s, api->message);
1.1.1.2   misho     479:   stream_putw (s, api->safi);
1.1       misho     480: 
                    481:   /* Put prefix information. */
                    482:   psize = PSIZE (p->prefixlen);
                    483:   stream_putc (s, p->prefixlen);
                    484:   stream_write (s, (u_char *) & p->prefix, psize);
                    485: 
                    486:   /* Nexthop, ifindex, distance and metric information. */
                    487:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
                    488:     {
                    489:       if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
                    490:         {
                    491:           stream_putc (s, 1);
                    492:           stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
                    493:           /* XXX assert(api->nexthop_num == 0); */
                    494:           /* XXX assert(api->ifindex_num == 0); */
                    495:         }
                    496:       else
                    497:         stream_putc (s, api->nexthop_num + api->ifindex_num);
                    498: 
                    499:       for (i = 0; i < api->nexthop_num; i++)
                    500:         {
                    501:           stream_putc (s, ZEBRA_NEXTHOP_IPV4);
                    502:           stream_put_in_addr (s, api->nexthop[i]);
                    503:         }
                    504:       for (i = 0; i < api->ifindex_num; i++)
                    505:         {
                    506:           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
                    507:           stream_putl (s, api->ifindex[i]);
                    508:         }
                    509:     }
                    510: 
                    511:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
                    512:     stream_putc (s, api->distance);
                    513:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
                    514:     stream_putl (s, api->metric);
                    515: 
                    516:   /* Put length at the first point of the stream. */
                    517:   stream_putw_at (s, 0, stream_get_endp (s));
                    518: 
                    519:   return zclient_send_message(zclient);
                    520: }
                    521: 
                    522: #ifdef HAVE_IPV6
                    523: int
                    524: zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
                    525:               struct zapi_ipv6 *api)
                    526: {
                    527:   int i;
                    528:   int psize;
                    529:   struct stream *s;
                    530: 
                    531:   /* Reset stream. */
                    532:   s = zclient->obuf;
                    533:   stream_reset (s);
                    534: 
                    535:   zclient_create_header (s, cmd);
                    536: 
                    537:   /* Put type and nexthop. */
                    538:   stream_putc (s, api->type);
                    539:   stream_putc (s, api->flags);
                    540:   stream_putc (s, api->message);
1.1.1.2   misho     541:   stream_putw (s, api->safi);
1.1       misho     542:   
                    543:   /* Put prefix information. */
                    544:   psize = PSIZE (p->prefixlen);
                    545:   stream_putc (s, p->prefixlen);
                    546:   stream_write (s, (u_char *)&p->prefix, psize);
                    547: 
                    548:   /* Nexthop, ifindex, distance and metric information. */
                    549:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
                    550:     {
                    551:       stream_putc (s, api->nexthop_num + api->ifindex_num);
                    552: 
                    553:       for (i = 0; i < api->nexthop_num; i++)
                    554:        {
                    555:          stream_putc (s, ZEBRA_NEXTHOP_IPV6);
                    556:          stream_write (s, (u_char *)api->nexthop[i], 16);
                    557:        }
                    558:       for (i = 0; i < api->ifindex_num; i++)
                    559:        {
                    560:          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
                    561:          stream_putl (s, api->ifindex[i]);
                    562:        }
                    563:     }
                    564: 
                    565:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
                    566:     stream_putc (s, api->distance);
                    567:   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
                    568:     stream_putl (s, api->metric);
                    569: 
                    570:   /* Put length at the first point of the stream. */
                    571:   stream_putw_at (s, 0, stream_get_endp (s));
                    572: 
                    573:   return zclient_send_message(zclient);
                    574: }
                    575: #endif /* HAVE_IPV6 */
                    576: 
                    577: /* 
                    578:  * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
                    579:  * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
                    580:  * then set/unset redist[type] in the client handle (a struct zserv) for the 
                    581:  * sending client
                    582:  */
                    583: int
                    584: zebra_redistribute_send (int command, struct zclient *zclient, int type)
                    585: {
                    586:   struct stream *s;
                    587: 
                    588:   s = zclient->obuf;
                    589:   stream_reset(s);
                    590:   
                    591:   zclient_create_header (s, command);
                    592:   stream_putc (s, type);
                    593:   
                    594:   stream_putw_at (s, 0, stream_get_endp (s));
                    595:   
                    596:   return zclient_send_message(zclient);
                    597: }
                    598: 
                    599: /* Router-id update from zebra daemon. */
                    600: void
                    601: zebra_router_id_update_read (struct stream *s, struct prefix *rid)
                    602: {
                    603:   int plen;
                    604: 
                    605:   /* Fetch interface address. */
                    606:   rid->family = stream_getc (s);
                    607: 
                    608:   plen = prefix_blen (rid);
                    609:   stream_get (&rid->u.prefix, s, plen);
                    610:   rid->prefixlen = stream_getc (s);
                    611: }
                    612: 
                    613: /* Interface addition from zebra daemon. */
                    614: /*  
                    615:  * The format of the message sent with type ZEBRA_INTERFACE_ADD or
                    616:  * ZEBRA_INTERFACE_DELETE from zebra to the client is:
                    617:  *     0                   1                   2                   3
                    618:  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    619:  * +-+-+-+-+-+-+-+-+
                    620:  * |   type        |
                    621:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    622:  * |  ifname                                                       |
                    623:  * |                                                               |
                    624:  * |                                                               |
                    625:  * |                                                               |
                    626:  * |                                                               |
                    627:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    628:  * |         ifindex                                               |
                    629:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    630:  * |         if_flags                                              |
                    631:  * |                                                               |
                    632:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    633:  * |         metric                                                |
                    634:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    635:  * |         ifmtu                                                 |
                    636:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    637:  * |         ifmtu6                                                |
                    638:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    639:  * |         bandwidth                                             |
                    640:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    641:  * |         sockaddr_dl                                           |
                    642:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    643:  */
                    644: 
                    645: struct interface *
                    646: zebra_interface_add_read (struct stream *s)
                    647: {
                    648:   struct interface *ifp;
                    649:   char ifname_tmp[INTERFACE_NAMSIZ];
                    650: 
                    651:   /* Read interface name. */
                    652:   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
                    653: 
                    654:   /* Lookup/create interface by name. */
                    655:   ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
                    656: 
1.1.1.2   misho     657:   zebra_interface_if_set_value (s, ifp);
1.1       misho     658: 
                    659:   return ifp;
                    660: }
                    661: 
                    662: /* 
                    663:  * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
                    664:  * from zebra server.  The format of this message is the same as
                    665:  * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
                    666:  * comments for zebra_interface_add_read), except that no sockaddr_dl
                    667:  * is sent at the tail of the message.
                    668:  */
                    669: struct interface *
                    670: zebra_interface_state_read (struct stream *s)
                    671: {
                    672:   struct interface *ifp;
                    673:   char ifname_tmp[INTERFACE_NAMSIZ];
                    674: 
                    675:   /* Read interface name. */
                    676:   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
                    677: 
                    678:   /* Lookup this by interface index. */
                    679:   ifp = if_lookup_by_name_len (ifname_tmp,
                    680:                               strnlen(ifname_tmp, INTERFACE_NAMSIZ));
                    681: 
                    682:   /* If such interface does not exist, indicate an error */
                    683:   if (! ifp)
                    684:      return NULL;
                    685: 
1.1.1.2   misho     686:   zebra_interface_if_set_value (s, ifp);
1.1       misho     687: 
                    688:   return ifp;
                    689: }
                    690: 
                    691: /* 
                    692:  * format of message for address additon is:
                    693:  *    0
                    694:  *  0 1 2 3 4 5 6 7
                    695:  * +-+-+-+-+-+-+-+-+
                    696:  * |   type        |  ZEBRA_INTERFACE_ADDRESS_ADD or
                    697:  * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_ADDRES_DELETE
                    698:  * |               |
                    699:  * +               +
                    700:  * |   ifindex     |
                    701:  * +               +
                    702:  * |               |
                    703:  * +               +
                    704:  * |               |
                    705:  * +-+-+-+-+-+-+-+-+
                    706:  * |   ifc_flags   |  flags for connected address
                    707:  * +-+-+-+-+-+-+-+-+
                    708:  * |  addr_family  |
                    709:  * +-+-+-+-+-+-+-+-+
                    710:  * |    addr...    |
                    711:  * :               :
                    712:  * |               |
                    713:  * +-+-+-+-+-+-+-+-+
                    714:  * |    addr_len   |  len of addr. E.g., addr_len = 4 for ipv4 addrs.
                    715:  * +-+-+-+-+-+-+-+-+
                    716:  * |     daddr..   |
                    717:  * :               :
                    718:  * |               |
                    719:  * +-+-+-+-+-+-+-+-+
                    720:  *
                    721:  */
                    722: 
                    723: void
                    724: zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
                    725: {
                    726:   /* Read interface's index. */
                    727:   ifp->ifindex = stream_getl (s);
                    728:   ifp->status = stream_getc (s);
                    729: 
                    730:   /* Read interface's value. */
                    731:   ifp->flags = stream_getq (s);
                    732:   ifp->metric = stream_getl (s);
                    733:   ifp->mtu = stream_getl (s);
                    734:   ifp->mtu6 = stream_getl (s);
                    735:   ifp->bandwidth = stream_getl (s);
1.1.1.2   misho     736: #ifdef HAVE_STRUCT_SOCKADDR_DL
1.1.1.3 ! misho     737:   stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage));
1.1.1.2   misho     738: #else
                    739:   ifp->hw_addr_len = stream_getl (s);
                    740:   if (ifp->hw_addr_len)
                    741:     stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
                    742: #endif /* HAVE_STRUCT_SOCKADDR_DL */
1.1       misho     743: }
                    744: 
                    745: static int
                    746: memconstant(const void *s, int c, size_t n)
                    747: {
                    748:   const u_char *p = s;
                    749: 
                    750:   while (n-- > 0)
                    751:     if (*p++ != c)
                    752:       return 0;
                    753:   return 1;
                    754: }
                    755: 
                    756: struct connected *
                    757: zebra_interface_address_read (int type, struct stream *s)
                    758: {
                    759:   unsigned int ifindex;
                    760:   struct interface *ifp;
                    761:   struct connected *ifc;
                    762:   struct prefix p, d;
                    763:   int family;
                    764:   int plen;
                    765:   u_char ifc_flags;
                    766: 
                    767:   memset (&p, 0, sizeof(p));
                    768:   memset (&d, 0, sizeof(d));
                    769: 
                    770:   /* Get interface index. */
                    771:   ifindex = stream_getl (s);
                    772: 
                    773:   /* Lookup index. */
                    774:   ifp = if_lookup_by_index (ifindex);
                    775:   if (ifp == NULL)
                    776:     {
                    777:       zlog_warn ("zebra_interface_address_read(%s): "
                    778:                  "Can't find interface by ifindex: %d ",
                    779:                  (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
                    780:                  ifindex);
                    781:       return NULL;
                    782:     }
                    783: 
                    784:   /* Fetch flag. */
                    785:   ifc_flags = stream_getc (s);
                    786: 
                    787:   /* Fetch interface address. */
                    788:   family = p.family = stream_getc (s);
                    789: 
                    790:   plen = prefix_blen (&p);
                    791:   stream_get (&p.u.prefix, s, plen);
                    792:   p.prefixlen = stream_getc (s);
                    793: 
                    794:   /* Fetch destination address. */
                    795:   stream_get (&d.u.prefix, s, plen);
                    796:   d.family = family;
                    797: 
                    798:   if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
                    799:     {
                    800:        /* N.B. NULL destination pointers are encoded as all zeroes */
                    801:        ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
                    802:                                              NULL : &d));
                    803:        if (ifc != NULL)
                    804:         {
                    805:           ifc->flags = ifc_flags;
                    806:           if (ifc->destination)
                    807:             ifc->destination->prefixlen = ifc->address->prefixlen;
                    808:         }
                    809:     }
                    810:   else
                    811:     {
                    812:       assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
                    813:       ifc = connected_delete_by_prefix(ifp, &p);
                    814:     }
                    815: 
                    816:   return ifc;
                    817: }
                    818: 
                    819: 
                    820: /* Zebra client message read function. */
                    821: static int
                    822: zclient_read (struct thread *thread)
                    823: {
                    824:   size_t already;
                    825:   uint16_t length, command;
                    826:   uint8_t marker, version;
                    827:   struct zclient *zclient;
                    828: 
                    829:   /* Get socket to zebra. */
                    830:   zclient = THREAD_ARG (thread);
                    831:   zclient->t_read = NULL;
                    832: 
                    833:   /* Read zebra header (if we don't have it already). */
                    834:   if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
                    835:     {
                    836:       ssize_t nbyte;
                    837:       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
                    838:                                     ZEBRA_HEADER_SIZE-already)) == 0) ||
                    839:          (nbyte == -1))
                    840:        {
                    841:          if (zclient_debug)
                    842:           zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
                    843:          return zclient_failed(zclient);
                    844:        }
                    845:       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
                    846:        {
                    847:          /* Try again later. */
                    848:          zclient_event (ZCLIENT_READ, zclient);
                    849:          return 0;
                    850:        }
                    851:       already = ZEBRA_HEADER_SIZE;
                    852:     }
                    853: 
                    854:   /* Reset to read from the beginning of the incoming packet. */
                    855:   stream_set_getp(zclient->ibuf, 0);
                    856: 
                    857:   /* Fetch header values. */
                    858:   length = stream_getw (zclient->ibuf);
                    859:   marker = stream_getc (zclient->ibuf);
                    860:   version = stream_getc (zclient->ibuf);
                    861:   command = stream_getw (zclient->ibuf);
                    862:   
                    863:   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
                    864:     {
                    865:       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
                    866:                __func__, zclient->sock, marker, version);
                    867:       return zclient_failed(zclient);
                    868:     }
                    869:   
                    870:   if (length < ZEBRA_HEADER_SIZE) 
                    871:     {
                    872:       zlog_err("%s: socket %d message length %u is less than %d ",
                    873:               __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
                    874:       return zclient_failed(zclient);
                    875:     }
                    876: 
                    877:   /* Length check. */
                    878:   if (length > STREAM_SIZE(zclient->ibuf))
                    879:     {
                    880:       struct stream *ns;
                    881:       zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
                    882:                __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
                    883:       ns = stream_new(length);
                    884:       stream_copy(ns, zclient->ibuf);
                    885:       stream_free (zclient->ibuf);
                    886:       zclient->ibuf = ns;
                    887:     }
                    888: 
                    889:   /* Read rest of zebra packet. */
                    890:   if (already < length)
                    891:     {
                    892:       ssize_t nbyte;
                    893:       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
                    894:                                     length-already)) == 0) ||
                    895:          (nbyte == -1))
                    896:        {
                    897:          if (zclient_debug)
                    898:            zlog_debug("zclient connection closed socket [%d].", zclient->sock);
                    899:          return zclient_failed(zclient);
                    900:        }
                    901:       if (nbyte != (ssize_t)(length-already))
                    902:        {
                    903:          /* Try again later. */
                    904:          zclient_event (ZCLIENT_READ, zclient);
                    905:          return 0;
                    906:        }
                    907:     }
                    908: 
                    909:   length -= ZEBRA_HEADER_SIZE;
                    910: 
                    911:   if (zclient_debug)
                    912:     zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
                    913: 
                    914:   switch (command)
                    915:     {
                    916:     case ZEBRA_ROUTER_ID_UPDATE:
                    917:       if (zclient->router_id_update)
1.1.1.2   misho     918:        (*zclient->router_id_update) (command, zclient, length);
1.1       misho     919:       break;
                    920:     case ZEBRA_INTERFACE_ADD:
                    921:       if (zclient->interface_add)
1.1.1.2   misho     922:        (*zclient->interface_add) (command, zclient, length);
1.1       misho     923:       break;
                    924:     case ZEBRA_INTERFACE_DELETE:
                    925:       if (zclient->interface_delete)
1.1.1.2   misho     926:        (*zclient->interface_delete) (command, zclient, length);
1.1       misho     927:       break;
                    928:     case ZEBRA_INTERFACE_ADDRESS_ADD:
                    929:       if (zclient->interface_address_add)
1.1.1.2   misho     930:        (*zclient->interface_address_add) (command, zclient, length);
1.1       misho     931:       break;
                    932:     case ZEBRA_INTERFACE_ADDRESS_DELETE:
                    933:       if (zclient->interface_address_delete)
1.1.1.2   misho     934:        (*zclient->interface_address_delete) (command, zclient, length);
1.1       misho     935:       break;
                    936:     case ZEBRA_INTERFACE_UP:
                    937:       if (zclient->interface_up)
1.1.1.2   misho     938:        (*zclient->interface_up) (command, zclient, length);
1.1       misho     939:       break;
                    940:     case ZEBRA_INTERFACE_DOWN:
                    941:       if (zclient->interface_down)
1.1.1.2   misho     942:        (*zclient->interface_down) (command, zclient, length);
1.1       misho     943:       break;
                    944:     case ZEBRA_IPV4_ROUTE_ADD:
                    945:       if (zclient->ipv4_route_add)
1.1.1.2   misho     946:        (*zclient->ipv4_route_add) (command, zclient, length);
1.1       misho     947:       break;
                    948:     case ZEBRA_IPV4_ROUTE_DELETE:
                    949:       if (zclient->ipv4_route_delete)
1.1.1.2   misho     950:        (*zclient->ipv4_route_delete) (command, zclient, length);
1.1       misho     951:       break;
                    952:     case ZEBRA_IPV6_ROUTE_ADD:
                    953:       if (zclient->ipv6_route_add)
1.1.1.2   misho     954:        (*zclient->ipv6_route_add) (command, zclient, length);
1.1       misho     955:       break;
                    956:     case ZEBRA_IPV6_ROUTE_DELETE:
                    957:       if (zclient->ipv6_route_delete)
1.1.1.2   misho     958:        (*zclient->ipv6_route_delete) (command, zclient, length);
1.1       misho     959:       break;
                    960:     default:
                    961:       break;
                    962:     }
                    963: 
                    964:   if (zclient->sock < 0)
                    965:     /* Connection was closed during packet processing. */
                    966:     return -1;
                    967: 
                    968:   /* Register read thread. */
                    969:   stream_reset(zclient->ibuf);
                    970:   zclient_event (ZCLIENT_READ, zclient);
                    971: 
                    972:   return 0;
                    973: }
                    974: 
                    975: void
                    976: zclient_redistribute (int command, struct zclient *zclient, int type)
                    977: {
                    978: 
                    979:   if (command == ZEBRA_REDISTRIBUTE_ADD) 
                    980:     {
                    981:       if (zclient->redist[type])
                    982:          return;
                    983:       zclient->redist[type] = 1;
                    984:     }
                    985:   else
                    986:     {
                    987:       if (!zclient->redist[type])
                    988:          return;
                    989:       zclient->redist[type] = 0;
                    990:     }
                    991: 
                    992:   if (zclient->sock > 0)
                    993:     zebra_redistribute_send (command, zclient, type);
                    994: }
                    995: 
                    996: 
                    997: void
                    998: zclient_redistribute_default (int command, struct zclient *zclient)
                    999: {
                   1000: 
                   1001:   if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
                   1002:     {
                   1003:       if (zclient->default_information)
                   1004:         return;
                   1005:       zclient->default_information = 1;
                   1006:     }
                   1007:   else 
                   1008:     {
                   1009:       if (!zclient->default_information)
                   1010:         return;
                   1011:       zclient->default_information = 0;
                   1012:     }
                   1013: 
                   1014:   if (zclient->sock > 0)
                   1015:     zebra_message_send (zclient, command);
                   1016: }
                   1017: 
                   1018: static void
                   1019: zclient_event (enum event event, struct zclient *zclient)
                   1020: {
                   1021:   switch (event)
                   1022:     {
                   1023:     case ZCLIENT_SCHEDULE:
                   1024:       if (! zclient->t_connect)
                   1025:        zclient->t_connect =
                   1026:          thread_add_event (master, zclient_connect, zclient, 0);
                   1027:       break;
                   1028:     case ZCLIENT_CONNECT:
                   1029:       if (zclient->fail >= 10)
                   1030:        return;
                   1031:       if (zclient_debug)
                   1032:        zlog_debug ("zclient connect schedule interval is %d", 
                   1033:                   zclient->fail < 3 ? 10 : 60);
                   1034:       if (! zclient->t_connect)
                   1035:        zclient->t_connect = 
                   1036:          thread_add_timer (master, zclient_connect, zclient,
                   1037:                            zclient->fail < 3 ? 10 : 60);
                   1038:       break;
                   1039:     case ZCLIENT_READ:
                   1040:       zclient->t_read = 
                   1041:        thread_add_read (master, zclient_read, zclient, zclient->sock);
                   1042:       break;
                   1043:     }
                   1044: }
1.1.1.2   misho    1045: 
                   1046: void
                   1047: zclient_serv_path_set (char *path)
                   1048: {
                   1049:   struct stat sb;
                   1050: 
                   1051:   /* reset */
                   1052:   zclient_serv_path = NULL;
                   1053: 
                   1054:   /* test if `path' is socket. don't set it otherwise. */
                   1055:   if (stat(path, &sb) == -1)
                   1056:     {
                   1057:       zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
                   1058:       return;
                   1059:     }
                   1060: 
                   1061:   if ((sb.st_mode & S_IFMT) != S_IFSOCK)
                   1062:     {
                   1063:       zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
                   1064:       return;
                   1065:     }
                   1066: 
                   1067:   /* it seems that path is unix socket */
                   1068:   zclient_serv_path = path;
                   1069: }
                   1070: 

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