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>