Annotation of embedaddon/quagga/zebra/zserv.c, revision 1.1.1.1
1.1 misho 1: /* Zebra daemon server routine.
2: * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the
18: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19: * Boston, MA 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #include "prefix.h"
25: #include "command.h"
26: #include "if.h"
27: #include "thread.h"
28: #include "stream.h"
29: #include "memory.h"
30: #include "table.h"
31: #include "rib.h"
32: #include "network.h"
33: #include "sockunion.h"
34: #include "log.h"
35: #include "zclient.h"
36: #include "privs.h"
37: #include "network.h"
38: #include "buffer.h"
39:
40: #include "zebra/zserv.h"
41: #include "zebra/router-id.h"
42: #include "zebra/redistribute.h"
43: #include "zebra/debug.h"
44: #include "zebra/ipforward.h"
45:
46: /* Event list of zebra. */
47: enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
48:
49: extern struct zebra_t zebrad;
50:
51: static void zebra_event (enum event event, int sock, struct zserv *client);
52:
53: extern struct zebra_privs_t zserv_privs;
54:
55: static void zebra_client_close (struct zserv *client);
56:
57: static int
58: zserv_delayed_close(struct thread *thread)
59: {
60: struct zserv *client = THREAD_ARG(thread);
61:
62: client->t_suicide = NULL;
63: zebra_client_close(client);
64: return 0;
65: }
66:
67: static int
68: zserv_flush_data(struct thread *thread)
69: {
70: struct zserv *client = THREAD_ARG(thread);
71:
72: client->t_write = NULL;
73: if (client->t_suicide)
74: {
75: zebra_client_close(client);
76: return -1;
77: }
78: switch (buffer_flush_available(client->wb, client->sock))
79: {
80: case BUFFER_ERROR:
81: zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
82: "closing", __func__, client->sock);
83: zebra_client_close(client);
84: break;
85: case BUFFER_PENDING:
86: client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
87: client, client->sock);
88: break;
89: case BUFFER_EMPTY:
90: break;
91: }
92: return 0;
93: }
94:
95: static int
96: zebra_server_send_message(struct zserv *client)
97: {
98: if (client->t_suicide)
99: return -1;
100: switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
101: stream_get_endp(client->obuf)))
102: {
103: case BUFFER_ERROR:
104: zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
105: __func__, client->sock);
106: /* Schedule a delayed close since many of the functions that call this
107: one do not check the return code. They do not allow for the
108: possibility that an I/O error may have caused the client to be
109: deleted. */
110: client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
111: client, 0);
112: return -1;
113: case BUFFER_EMPTY:
114: THREAD_OFF(client->t_write);
115: break;
116: case BUFFER_PENDING:
117: THREAD_WRITE_ON(zebrad.master, client->t_write,
118: zserv_flush_data, client, client->sock);
119: break;
120: }
121: return 0;
122: }
123:
124: static void
125: zserv_create_header (struct stream *s, uint16_t cmd)
126: {
127: /* length placeholder, caller can update */
128: stream_putw (s, ZEBRA_HEADER_SIZE);
129: stream_putc (s, ZEBRA_HEADER_MARKER);
130: stream_putc (s, ZSERV_VERSION);
131: stream_putw (s, cmd);
132: }
133:
134: /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
135: /*
136: * This function is called in the following situations:
137: * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
138: * from the client.
139: * - at startup, when zebra figures out the available interfaces
140: * - when an interface is added (where support for
141: * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
142: * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
143: * received)
144: */
145: int
146: zsend_interface_add (struct zserv *client, struct interface *ifp)
147: {
148: struct stream *s;
149:
150: /* Check this client need interface information. */
151: if (! client->ifinfo)
152: return 0;
153:
154: s = client->obuf;
155: stream_reset (s);
156:
157: /* Message type. */
158: zserv_create_header (s, ZEBRA_INTERFACE_ADD);
159:
160: /* Interface information. */
161: stream_put (s, ifp->name, INTERFACE_NAMSIZ);
162: stream_putl (s, ifp->ifindex);
163: stream_putc (s, ifp->status);
164: stream_putq (s, ifp->flags);
165: stream_putl (s, ifp->metric);
166: stream_putl (s, ifp->mtu);
167: stream_putl (s, ifp->mtu6);
168: stream_putl (s, ifp->bandwidth);
169: #ifdef HAVE_STRUCT_SOCKADDR_DL
170: stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
171: #else
172: stream_putl (s, ifp->hw_addr_len);
173: if (ifp->hw_addr_len)
174: stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
175: #endif /* HAVE_STRUCT_SOCKADDR_DL */
176:
177: /* Write packet size. */
178: stream_putw_at (s, 0, stream_get_endp (s));
179:
180: return zebra_server_send_message(client);
181: }
182:
183: /* Interface deletion from zebra daemon. */
184: int
185: zsend_interface_delete (struct zserv *client, struct interface *ifp)
186: {
187: struct stream *s;
188:
189: /* Check this client need interface information. */
190: if (! client->ifinfo)
191: return 0;
192:
193: s = client->obuf;
194: stream_reset (s);
195:
196: zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
197:
198: /* Interface information. */
199: stream_put (s, ifp->name, INTERFACE_NAMSIZ);
200: stream_putl (s, ifp->ifindex);
201: stream_putc (s, ifp->status);
202: stream_putq (s, ifp->flags);
203: stream_putl (s, ifp->metric);
204: stream_putl (s, ifp->mtu);
205: stream_putl (s, ifp->mtu6);
206: stream_putl (s, ifp->bandwidth);
207:
208: /* Write packet length. */
209: stream_putw_at (s, 0, stream_get_endp (s));
210:
211: return zebra_server_send_message (client);
212: }
213:
214: /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
215: * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
216: *
217: * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
218: * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
219: * from the client, after the ZEBRA_INTERFACE_ADD has been
220: * sent from zebra to the client
221: * - redistribute new address info to all clients in the following situations
222: * - at startup, when zebra figures out the available interfaces
223: * - when an interface is added (where support for
224: * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
225: * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
226: * received)
227: * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
228: * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
229: * - when an RTM_NEWADDR message is received from the kernel,
230: *
231: * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
232: *
233: * zsend_interface_address(DELETE)
234: * ^
235: * |
236: * zebra_interface_address_delete_update
237: * ^ ^ ^
238: * | | if_delete_update
239: * | |
240: * ip_address_uninstall connected_delete_ipv4
241: * [ipv6_addresss_uninstall] [connected_delete_ipv6]
242: * ^ ^
243: * | |
244: * | RTM_NEWADDR on routing/netlink socket
245: * |
246: * vty commands:
247: * "no ip address A.B.C.D/M [label LINE]"
248: * "no ip address A.B.C.D/M secondary"
249: * ["no ipv6 address X:X::X:X/M"]
250: *
251: */
252: int
253: zsend_interface_address (int cmd, struct zserv *client,
254: struct interface *ifp, struct connected *ifc)
255: {
256: int blen;
257: struct stream *s;
258: struct prefix *p;
259:
260: /* Check this client need interface information. */
261: if (! client->ifinfo)
262: return 0;
263:
264: s = client->obuf;
265: stream_reset (s);
266:
267: zserv_create_header (s, cmd);
268: stream_putl (s, ifp->ifindex);
269:
270: /* Interface address flag. */
271: stream_putc (s, ifc->flags);
272:
273: /* Prefix information. */
274: p = ifc->address;
275: stream_putc (s, p->family);
276: blen = prefix_blen (p);
277: stream_put (s, &p->u.prefix, blen);
278:
279: /*
280: * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
281: * but zebra_interface_address_delete_read() in the gnu version
282: * expects to find it
283: */
284: stream_putc (s, p->prefixlen);
285:
286: /* Destination. */
287: p = ifc->destination;
288: if (p)
289: stream_put (s, &p->u.prefix, blen);
290: else
291: stream_put (s, NULL, blen);
292:
293: /* Write packet size. */
294: stream_putw_at (s, 0, stream_get_endp (s));
295:
296: return zebra_server_send_message(client);
297: }
298:
299: /*
300: * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
301: * ZEBRA_INTERFACE_DOWN.
302: *
303: * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
304: * the clients in one of 2 situations:
305: * - an if_up is detected e.g., as a result of an RTM_IFINFO message
306: * - a vty command modifying the bandwidth of an interface is received.
307: * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
308: */
309: int
310: zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
311: {
312: struct stream *s;
313:
314: /* Check this client need interface information. */
315: if (! client->ifinfo)
316: return 0;
317:
318: s = client->obuf;
319: stream_reset (s);
320:
321: zserv_create_header (s, cmd);
322:
323: /* Interface information. */
324: stream_put (s, ifp->name, INTERFACE_NAMSIZ);
325: stream_putl (s, ifp->ifindex);
326: stream_putc (s, ifp->status);
327: stream_putq (s, ifp->flags);
328: stream_putl (s, ifp->metric);
329: stream_putl (s, ifp->mtu);
330: stream_putl (s, ifp->mtu6);
331: stream_putl (s, ifp->bandwidth);
332:
333: /* Write packet size. */
334: stream_putw_at (s, 0, stream_get_endp (s));
335:
336: return zebra_server_send_message(client);
337: }
338:
339: /*
340: * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
341: * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
342: * situations:
343: * - when the client starts up, and requests default information
344: * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
345: * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
346: * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
347: * - when the zebra server redistributes routes after it updates its rib
348: *
349: * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
350: * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
351: * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
352: * - deleted from zebra's rib, and this info
353: * has to be redistributed to the clients
354: *
355: * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
356: * zebra server when the client wants to tell the zebra server to add a
357: * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
358: * same message being sent back and forth, this function and
359: * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
360: * duplication.
361: */
362: int
363: zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
364: struct rib *rib)
365: {
366: int psize;
367: struct stream *s;
368: struct nexthop *nexthop;
369: unsigned long nhnummark = 0, messmark = 0;
370: int nhnum = 0;
371: u_char zapi_flags = 0;
372:
373: s = client->obuf;
374: stream_reset (s);
375:
376: zserv_create_header (s, cmd);
377:
378: /* Put type and nexthop. */
379: stream_putc (s, rib->type);
380: stream_putc (s, rib->flags);
381:
382: /* marker for message flags field */
383: messmark = stream_get_endp (s);
384: stream_putc (s, 0);
385:
386: /* Prefix. */
387: psize = PSIZE (p->prefixlen);
388: stream_putc (s, p->prefixlen);
389: stream_write (s, (u_char *) & p->u.prefix, psize);
390:
391: /*
392: * XXX The message format sent by zebra below does not match the format
393: * of the corresponding message expected by the zebra server
394: * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
395: * (is there a bug on the client side if more than one segment is sent?)
396: * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
397: * is hard-coded.
398: */
399: /* Nexthop */
400:
401: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
402: {
403: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
404: {
405: SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
406: SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
407:
408: if (nhnummark == 0)
409: {
410: nhnummark = stream_get_endp (s);
411: stream_putc (s, 1); /* placeholder */
412: }
413:
414: nhnum++;
415:
416: switch(nexthop->type)
417: {
418: case NEXTHOP_TYPE_IPV4:
419: case NEXTHOP_TYPE_IPV4_IFINDEX:
420: stream_put_in_addr (s, &nexthop->gate.ipv4);
421: break;
422: #ifdef HAVE_IPV6
423: case NEXTHOP_TYPE_IPV6:
424: case NEXTHOP_TYPE_IPV6_IFINDEX:
425: case NEXTHOP_TYPE_IPV6_IFNAME:
426: stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
427: break;
428: #endif
429: default:
430: if (cmd == ZEBRA_IPV4_ROUTE_ADD
431: || cmd == ZEBRA_IPV4_ROUTE_DELETE)
432: {
433: struct in_addr empty;
434: memset (&empty, 0, sizeof (struct in_addr));
435: stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
436: }
437: else
438: {
439: struct in6_addr empty;
440: memset (&empty, 0, sizeof (struct in6_addr));
441: stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
442: }
443: }
444:
445: /* Interface index. */
446: stream_putc (s, 1);
447: stream_putl (s, nexthop->ifindex);
448:
449: break;
450: }
451: }
452:
453: /* Metric */
454: if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
455: {
456: SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
457: stream_putc (s, rib->distance);
458: SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
459: stream_putl (s, rib->metric);
460: }
461:
462: /* write real message flags value */
463: stream_putc_at (s, messmark, zapi_flags);
464:
465: /* Write next-hop number */
466: if (nhnummark)
467: stream_putc_at (s, nhnummark, nhnum);
468:
469: /* Write packet size. */
470: stream_putw_at (s, 0, stream_get_endp (s));
471:
472: return zebra_server_send_message(client);
473: }
474:
475: #ifdef HAVE_IPV6
476: static int
477: zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
478: {
479: struct stream *s;
480: struct rib *rib;
481: unsigned long nump;
482: u_char num;
483: struct nexthop *nexthop;
484:
485: /* Lookup nexthop. */
486: rib = rib_match_ipv6 (addr);
487:
488: /* Get output stream. */
489: s = client->obuf;
490: stream_reset (s);
491:
492: /* Fill in result. */
493: zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
494: stream_put (s, &addr, 16);
495:
496: if (rib)
497: {
498: stream_putl (s, rib->metric);
499: num = 0;
500: nump = stream_get_endp(s);
501: stream_putc (s, 0);
502: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
503: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
504: {
505: stream_putc (s, nexthop->type);
506: switch (nexthop->type)
507: {
508: case ZEBRA_NEXTHOP_IPV6:
509: stream_put (s, &nexthop->gate.ipv6, 16);
510: break;
511: case ZEBRA_NEXTHOP_IPV6_IFINDEX:
512: case ZEBRA_NEXTHOP_IPV6_IFNAME:
513: stream_put (s, &nexthop->gate.ipv6, 16);
514: stream_putl (s, nexthop->ifindex);
515: break;
516: case ZEBRA_NEXTHOP_IFINDEX:
517: case ZEBRA_NEXTHOP_IFNAME:
518: stream_putl (s, nexthop->ifindex);
519: break;
520: default:
521: /* do nothing */
522: break;
523: }
524: num++;
525: }
526: stream_putc_at (s, nump, num);
527: }
528: else
529: {
530: stream_putl (s, 0);
531: stream_putc (s, 0);
532: }
533:
534: stream_putw_at (s, 0, stream_get_endp (s));
535:
536: return zebra_server_send_message(client);
537: }
538: #endif /* HAVE_IPV6 */
539:
540: static int
541: zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
542: {
543: struct stream *s;
544: struct rib *rib;
545: unsigned long nump;
546: u_char num;
547: struct nexthop *nexthop;
548:
549: /* Lookup nexthop. */
550: rib = rib_match_ipv4 (addr);
551:
552: /* Get output stream. */
553: s = client->obuf;
554: stream_reset (s);
555:
556: /* Fill in result. */
557: zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
558: stream_put_in_addr (s, &addr);
559:
560: if (rib)
561: {
562: stream_putl (s, rib->metric);
563: num = 0;
564: nump = stream_get_endp(s);
565: stream_putc (s, 0);
566: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
567: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
568: {
569: stream_putc (s, nexthop->type);
570: switch (nexthop->type)
571: {
572: case ZEBRA_NEXTHOP_IPV4:
573: stream_put_in_addr (s, &nexthop->gate.ipv4);
574: break;
575: case ZEBRA_NEXTHOP_IFINDEX:
576: case ZEBRA_NEXTHOP_IFNAME:
577: stream_putl (s, nexthop->ifindex);
578: break;
579: default:
580: /* do nothing */
581: break;
582: }
583: num++;
584: }
585: stream_putc_at (s, nump, num);
586: }
587: else
588: {
589: stream_putl (s, 0);
590: stream_putc (s, 0);
591: }
592:
593: stream_putw_at (s, 0, stream_get_endp (s));
594:
595: return zebra_server_send_message(client);
596: }
597:
598: static int
599: zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
600: {
601: struct stream *s;
602: struct rib *rib;
603: unsigned long nump;
604: u_char num;
605: struct nexthop *nexthop;
606:
607: /* Lookup nexthop. */
608: rib = rib_lookup_ipv4 (p);
609:
610: /* Get output stream. */
611: s = client->obuf;
612: stream_reset (s);
613:
614: /* Fill in result. */
615: zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
616: stream_put_in_addr (s, &p->prefix);
617:
618: if (rib)
619: {
620: stream_putl (s, rib->metric);
621: num = 0;
622: nump = stream_get_endp(s);
623: stream_putc (s, 0);
624: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
625: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
626: {
627: stream_putc (s, nexthop->type);
628: switch (nexthop->type)
629: {
630: case ZEBRA_NEXTHOP_IPV4:
631: stream_put_in_addr (s, &nexthop->gate.ipv4);
632: break;
633: case ZEBRA_NEXTHOP_IFINDEX:
634: case ZEBRA_NEXTHOP_IFNAME:
635: stream_putl (s, nexthop->ifindex);
636: break;
637: default:
638: /* do nothing */
639: break;
640: }
641: num++;
642: }
643: stream_putc_at (s, nump, num);
644: }
645: else
646: {
647: stream_putl (s, 0);
648: stream_putc (s, 0);
649: }
650:
651: stream_putw_at (s, 0, stream_get_endp (s));
652:
653: return zebra_server_send_message(client);
654: }
655:
656: /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
657: int
658: zsend_router_id_update (struct zserv *client, struct prefix *p)
659: {
660: struct stream *s;
661: int blen;
662:
663: /* Check this client need interface information. */
664: if (!client->ridinfo)
665: return 0;
666:
667: s = client->obuf;
668: stream_reset (s);
669:
670: /* Message type. */
671: zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
672:
673: /* Prefix information. */
674: stream_putc (s, p->family);
675: blen = prefix_blen (p);
676: stream_put (s, &p->u.prefix, blen);
677: stream_putc (s, p->prefixlen);
678:
679: /* Write packet size. */
680: stream_putw_at (s, 0, stream_get_endp (s));
681:
682: return zebra_server_send_message(client);
683: }
684:
685: /* Register zebra server interface information. Send current all
686: interface and address information. */
687: static int
688: zread_interface_add (struct zserv *client, u_short length)
689: {
690: struct listnode *ifnode, *ifnnode;
691: struct listnode *cnode, *cnnode;
692: struct interface *ifp;
693: struct connected *c;
694:
695: /* Interface information is needed. */
696: client->ifinfo = 1;
697:
698: for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
699: {
700: /* Skip pseudo interface. */
701: if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
702: continue;
703:
704: if (zsend_interface_add (client, ifp) < 0)
705: return -1;
706:
707: for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
708: {
709: if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
710: (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
711: ifp, c) < 0))
712: return -1;
713: }
714: }
715: return 0;
716: }
717:
718: /* Unregister zebra server interface information. */
719: static int
720: zread_interface_delete (struct zserv *client, u_short length)
721: {
722: client->ifinfo = 0;
723: return 0;
724: }
725:
726: /* This function support multiple nexthop. */
727: /*
728: * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
729: * add kernel route.
730: */
731: static int
732: zread_ipv4_add (struct zserv *client, u_short length)
733: {
734: int i;
735: struct rib *rib;
736: struct prefix_ipv4 p;
737: u_char message;
738: struct in_addr nexthop;
739: u_char nexthop_num;
740: u_char nexthop_type;
741: struct stream *s;
742: unsigned int ifindex;
743: u_char ifname_len;
744:
745: /* Get input stream. */
746: s = client->ibuf;
747:
748: /* Allocate new rib. */
749: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
750:
751: /* Type, flags, message. */
752: rib->type = stream_getc (s);
753: rib->flags = stream_getc (s);
754: message = stream_getc (s);
755: rib->uptime = time (NULL);
756:
757: /* IPv4 prefix. */
758: memset (&p, 0, sizeof (struct prefix_ipv4));
759: p.family = AF_INET;
760: p.prefixlen = stream_getc (s);
761: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
762:
763: /* Nexthop parse. */
764: if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
765: {
766: nexthop_num = stream_getc (s);
767:
768: for (i = 0; i < nexthop_num; i++)
769: {
770: nexthop_type = stream_getc (s);
771:
772: switch (nexthop_type)
773: {
774: case ZEBRA_NEXTHOP_IFINDEX:
775: ifindex = stream_getl (s);
776: nexthop_ifindex_add (rib, ifindex);
777: break;
778: case ZEBRA_NEXTHOP_IFNAME:
779: ifname_len = stream_getc (s);
780: stream_forward_getp (s, ifname_len);
781: break;
782: case ZEBRA_NEXTHOP_IPV4:
783: nexthop.s_addr = stream_get_ipv4 (s);
784: nexthop_ipv4_add (rib, &nexthop, NULL);
785: break;
786: case ZEBRA_NEXTHOP_IPV6:
787: stream_forward_getp (s, IPV6_MAX_BYTELEN);
788: break;
789: case ZEBRA_NEXTHOP_BLACKHOLE:
790: nexthop_blackhole_add (rib);
791: break;
792: }
793: }
794: }
795:
796: /* Distance. */
797: if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
798: rib->distance = stream_getc (s);
799:
800: /* Metric. */
801: if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
802: rib->metric = stream_getl (s);
803:
804: /* Table */
805: rib->table=zebrad.rtm_table_default;
806: rib_add_ipv4_multipath (&p, rib);
807: return 0;
808: }
809:
810: /* Zebra server IPv4 prefix delete function. */
811: static int
812: zread_ipv4_delete (struct zserv *client, u_short length)
813: {
814: int i;
815: struct stream *s;
816: struct zapi_ipv4 api;
817: struct in_addr nexthop;
818: unsigned long ifindex;
819: struct prefix_ipv4 p;
820: u_char nexthop_num;
821: u_char nexthop_type;
822: u_char ifname_len;
823:
824: s = client->ibuf;
825: ifindex = 0;
826: nexthop.s_addr = 0;
827:
828: /* Type, flags, message. */
829: api.type = stream_getc (s);
830: api.flags = stream_getc (s);
831: api.message = stream_getc (s);
832:
833: /* IPv4 prefix. */
834: memset (&p, 0, sizeof (struct prefix_ipv4));
835: p.family = AF_INET;
836: p.prefixlen = stream_getc (s);
837: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
838:
839: /* Nexthop, ifindex, distance, metric. */
840: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
841: {
842: nexthop_num = stream_getc (s);
843:
844: for (i = 0; i < nexthop_num; i++)
845: {
846: nexthop_type = stream_getc (s);
847:
848: switch (nexthop_type)
849: {
850: case ZEBRA_NEXTHOP_IFINDEX:
851: ifindex = stream_getl (s);
852: break;
853: case ZEBRA_NEXTHOP_IFNAME:
854: ifname_len = stream_getc (s);
855: stream_forward_getp (s, ifname_len);
856: break;
857: case ZEBRA_NEXTHOP_IPV4:
858: nexthop.s_addr = stream_get_ipv4 (s);
859: break;
860: case ZEBRA_NEXTHOP_IPV6:
861: stream_forward_getp (s, IPV6_MAX_BYTELEN);
862: break;
863: }
864: }
865: }
866:
867: /* Distance. */
868: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
869: api.distance = stream_getc (s);
870: else
871: api.distance = 0;
872:
873: /* Metric. */
874: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
875: api.metric = stream_getl (s);
876: else
877: api.metric = 0;
878:
879: rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
880: client->rtm_table);
881: return 0;
882: }
883:
884: /* Nexthop lookup for IPv4. */
885: static int
886: zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
887: {
888: struct in_addr addr;
889:
890: addr.s_addr = stream_get_ipv4 (client->ibuf);
891: return zsend_ipv4_nexthop_lookup (client, addr);
892: }
893:
894: /* Nexthop lookup for IPv4. */
895: static int
896: zread_ipv4_import_lookup (struct zserv *client, u_short length)
897: {
898: struct prefix_ipv4 p;
899:
900: p.family = AF_INET;
901: p.prefixlen = stream_getc (client->ibuf);
902: p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
903:
904: return zsend_ipv4_import_lookup (client, &p);
905: }
906:
907: #ifdef HAVE_IPV6
908: /* Zebra server IPv6 prefix add function. */
909: static int
910: zread_ipv6_add (struct zserv *client, u_short length)
911: {
912: int i;
913: struct stream *s;
914: struct zapi_ipv6 api;
915: struct in6_addr nexthop;
916: unsigned long ifindex;
917: struct prefix_ipv6 p;
918:
919: s = client->ibuf;
920: ifindex = 0;
921: memset (&nexthop, 0, sizeof (struct in6_addr));
922:
923: /* Type, flags, message. */
924: api.type = stream_getc (s);
925: api.flags = stream_getc (s);
926: api.message = stream_getc (s);
927:
928: /* IPv4 prefix. */
929: memset (&p, 0, sizeof (struct prefix_ipv6));
930: p.family = AF_INET6;
931: p.prefixlen = stream_getc (s);
932: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
933:
934: /* Nexthop, ifindex, distance, metric. */
935: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
936: {
937: u_char nexthop_type;
938:
939: api.nexthop_num = stream_getc (s);
940: for (i = 0; i < api.nexthop_num; i++)
941: {
942: nexthop_type = stream_getc (s);
943:
944: switch (nexthop_type)
945: {
946: case ZEBRA_NEXTHOP_IPV6:
947: stream_get (&nexthop, s, 16);
948: break;
949: case ZEBRA_NEXTHOP_IFINDEX:
950: ifindex = stream_getl (s);
951: break;
952: }
953: }
954: }
955:
956: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
957: api.distance = stream_getc (s);
958: else
959: api.distance = 0;
960:
961: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
962: api.metric = stream_getl (s);
963: else
964: api.metric = 0;
965:
966: if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
967: rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric,
968: api.distance);
969: else
970: rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
971: api.distance);
972: return 0;
973: }
974:
975: /* Zebra server IPv6 prefix delete function. */
976: static int
977: zread_ipv6_delete (struct zserv *client, u_short length)
978: {
979: int i;
980: struct stream *s;
981: struct zapi_ipv6 api;
982: struct in6_addr nexthop;
983: unsigned long ifindex;
984: struct prefix_ipv6 p;
985:
986: s = client->ibuf;
987: ifindex = 0;
988: memset (&nexthop, 0, sizeof (struct in6_addr));
989:
990: /* Type, flags, message. */
991: api.type = stream_getc (s);
992: api.flags = stream_getc (s);
993: api.message = stream_getc (s);
994:
995: /* IPv4 prefix. */
996: memset (&p, 0, sizeof (struct prefix_ipv6));
997: p.family = AF_INET6;
998: p.prefixlen = stream_getc (s);
999: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1000:
1001: /* Nexthop, ifindex, distance, metric. */
1002: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1003: {
1004: u_char nexthop_type;
1005:
1006: api.nexthop_num = stream_getc (s);
1007: for (i = 0; i < api.nexthop_num; i++)
1008: {
1009: nexthop_type = stream_getc (s);
1010:
1011: switch (nexthop_type)
1012: {
1013: case ZEBRA_NEXTHOP_IPV6:
1014: stream_get (&nexthop, s, 16);
1015: break;
1016: case ZEBRA_NEXTHOP_IFINDEX:
1017: ifindex = stream_getl (s);
1018: break;
1019: }
1020: }
1021: }
1022:
1023: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1024: api.distance = stream_getc (s);
1025: else
1026: api.distance = 0;
1027: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1028: api.metric = stream_getl (s);
1029: else
1030: api.metric = 0;
1031:
1032: if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1033: rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table);
1034: else
1035: rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table);
1036: return 0;
1037: }
1038:
1039: static int
1040: zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1041: {
1042: struct in6_addr addr;
1043: char buf[BUFSIZ];
1044:
1045: stream_get (&addr, client->ibuf, 16);
1046: printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1047:
1048: return zsend_ipv6_nexthop_lookup (client, &addr);
1049: }
1050: #endif /* HAVE_IPV6 */
1051:
1052: /* Register zebra server router-id information. Send current router-id */
1053: static int
1054: zread_router_id_add (struct zserv *client, u_short length)
1055: {
1056: struct prefix p;
1057:
1058: /* Router-id information is needed. */
1059: client->ridinfo = 1;
1060:
1061: router_id_get (&p);
1062:
1063: return zsend_router_id_update (client,&p);
1064: }
1065:
1066: /* Unregister zebra server router-id information. */
1067: static int
1068: zread_router_id_delete (struct zserv *client, u_short length)
1069: {
1070: client->ridinfo = 0;
1071: return 0;
1072: }
1073:
1074: /* Close zebra client. */
1075: static void
1076: zebra_client_close (struct zserv *client)
1077: {
1078: /* Close file descriptor. */
1079: if (client->sock)
1080: {
1081: close (client->sock);
1082: client->sock = -1;
1083: }
1084:
1085: /* Free stream buffers. */
1086: if (client->ibuf)
1087: stream_free (client->ibuf);
1088: if (client->obuf)
1089: stream_free (client->obuf);
1090: if (client->wb)
1091: buffer_free(client->wb);
1092:
1093: /* Release threads. */
1094: if (client->t_read)
1095: thread_cancel (client->t_read);
1096: if (client->t_write)
1097: thread_cancel (client->t_write);
1098: if (client->t_suicide)
1099: thread_cancel (client->t_suicide);
1100:
1101: /* Free client structure. */
1102: listnode_delete (zebrad.client_list, client);
1103: XFREE (0, client);
1104: }
1105:
1106: /* Make new client. */
1107: static void
1108: zebra_client_create (int sock)
1109: {
1110: struct zserv *client;
1111:
1112: client = XCALLOC (0, sizeof (struct zserv));
1113:
1114: /* Make client input/output buffer. */
1115: client->sock = sock;
1116: client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1117: client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1118: client->wb = buffer_new(0);
1119:
1120: /* Set table number. */
1121: client->rtm_table = zebrad.rtm_table_default;
1122:
1123: /* Add this client to linked list. */
1124: listnode_add (zebrad.client_list, client);
1125:
1126: /* Make new read thread. */
1127: zebra_event (ZEBRA_READ, sock, client);
1128: }
1129:
1130: /* Handler of zebra service request. */
1131: static int
1132: zebra_client_read (struct thread *thread)
1133: {
1134: int sock;
1135: struct zserv *client;
1136: size_t already;
1137: uint16_t length, command;
1138: uint8_t marker, version;
1139:
1140: /* Get thread data. Reset reading thread because I'm running. */
1141: sock = THREAD_FD (thread);
1142: client = THREAD_ARG (thread);
1143: client->t_read = NULL;
1144:
1145: if (client->t_suicide)
1146: {
1147: zebra_client_close(client);
1148: return -1;
1149: }
1150:
1151: /* Read length and command (if we don't have it already). */
1152: if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
1153: {
1154: ssize_t nbyte;
1155: if (((nbyte = stream_read_try (client->ibuf, sock,
1156: ZEBRA_HEADER_SIZE-already)) == 0) ||
1157: (nbyte == -1))
1158: {
1159: if (IS_ZEBRA_DEBUG_EVENT)
1160: zlog_debug ("connection closed socket [%d]", sock);
1161: zebra_client_close (client);
1162: return -1;
1163: }
1164: if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1165: {
1166: /* Try again later. */
1167: zebra_event (ZEBRA_READ, sock, client);
1168: return 0;
1169: }
1170: already = ZEBRA_HEADER_SIZE;
1171: }
1172:
1173: /* Reset to read from the beginning of the incoming packet. */
1174: stream_set_getp(client->ibuf, 0);
1175:
1176: /* Fetch header values */
1177: length = stream_getw (client->ibuf);
1178: marker = stream_getc (client->ibuf);
1179: version = stream_getc (client->ibuf);
1180: command = stream_getw (client->ibuf);
1181:
1182: if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1183: {
1184: zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1185: __func__, sock, marker, version);
1186: zebra_client_close (client);
1187: return -1;
1188: }
1189: if (length < ZEBRA_HEADER_SIZE)
1190: {
1191: zlog_warn("%s: socket %d message length %u is less than header size %d",
1192: __func__, sock, length, ZEBRA_HEADER_SIZE);
1193: zebra_client_close (client);
1194: return -1;
1195: }
1196: if (length > STREAM_SIZE(client->ibuf))
1197: {
1198: zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1199: __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
1200: zebra_client_close (client);
1201: return -1;
1202: }
1203:
1204: /* Read rest of data. */
1205: if (already < length)
1206: {
1207: ssize_t nbyte;
1208: if (((nbyte = stream_read_try (client->ibuf, sock,
1209: length-already)) == 0) ||
1210: (nbyte == -1))
1211: {
1212: if (IS_ZEBRA_DEBUG_EVENT)
1213: zlog_debug ("connection closed [%d] when reading zebra data", sock);
1214: zebra_client_close (client);
1215: return -1;
1216: }
1217: if (nbyte != (ssize_t)(length-already))
1218: {
1219: /* Try again later. */
1220: zebra_event (ZEBRA_READ, sock, client);
1221: return 0;
1222: }
1223: }
1224:
1225: length -= ZEBRA_HEADER_SIZE;
1226:
1227: /* Debug packet information. */
1228: if (IS_ZEBRA_DEBUG_EVENT)
1229: zlog_debug ("zebra message comes from socket [%d]", sock);
1230:
1231: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1232: zlog_debug ("zebra message received [%s] %d",
1233: zserv_command_string (command), length);
1234:
1235: switch (command)
1236: {
1237: case ZEBRA_ROUTER_ID_ADD:
1238: zread_router_id_add (client, length);
1239: break;
1240: case ZEBRA_ROUTER_ID_DELETE:
1241: zread_router_id_delete (client, length);
1242: break;
1243: case ZEBRA_INTERFACE_ADD:
1244: zread_interface_add (client, length);
1245: break;
1246: case ZEBRA_INTERFACE_DELETE:
1247: zread_interface_delete (client, length);
1248: break;
1249: case ZEBRA_IPV4_ROUTE_ADD:
1250: zread_ipv4_add (client, length);
1251: break;
1252: case ZEBRA_IPV4_ROUTE_DELETE:
1253: zread_ipv4_delete (client, length);
1254: break;
1255: #ifdef HAVE_IPV6
1256: case ZEBRA_IPV6_ROUTE_ADD:
1257: zread_ipv6_add (client, length);
1258: break;
1259: case ZEBRA_IPV6_ROUTE_DELETE:
1260: zread_ipv6_delete (client, length);
1261: break;
1262: #endif /* HAVE_IPV6 */
1263: case ZEBRA_REDISTRIBUTE_ADD:
1264: zebra_redistribute_add (command, client, length);
1265: break;
1266: case ZEBRA_REDISTRIBUTE_DELETE:
1267: zebra_redistribute_delete (command, client, length);
1268: break;
1269: case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1270: zebra_redistribute_default_add (command, client, length);
1271: break;
1272: case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1273: zebra_redistribute_default_delete (command, client, length);
1274: break;
1275: case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1276: zread_ipv4_nexthop_lookup (client, length);
1277: break;
1278: #ifdef HAVE_IPV6
1279: case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1280: zread_ipv6_nexthop_lookup (client, length);
1281: break;
1282: #endif /* HAVE_IPV6 */
1283: case ZEBRA_IPV4_IMPORT_LOOKUP:
1284: zread_ipv4_import_lookup (client, length);
1285: break;
1286: default:
1287: zlog_info ("Zebra received unknown command %d", command);
1288: break;
1289: }
1290:
1291: if (client->t_suicide)
1292: {
1293: /* No need to wait for thread callback, just kill immediately. */
1294: zebra_client_close(client);
1295: return -1;
1296: }
1297:
1298: stream_reset (client->ibuf);
1299: zebra_event (ZEBRA_READ, sock, client);
1300: return 0;
1301: }
1302:
1303:
1304: /* Accept code of zebra server socket. */
1305: static int
1306: zebra_accept (struct thread *thread)
1307: {
1308: int accept_sock;
1309: int client_sock;
1310: struct sockaddr_in client;
1311: socklen_t len;
1312:
1313: accept_sock = THREAD_FD (thread);
1314:
1315: /* Reregister myself. */
1316: zebra_event (ZEBRA_SERV, accept_sock, NULL);
1317:
1318: len = sizeof (struct sockaddr_in);
1319: client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1320:
1321: if (client_sock < 0)
1322: {
1323: zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
1324: return -1;
1325: }
1326:
1327: /* Make client socket non-blocking. */
1328: set_nonblocking(client_sock);
1329:
1330: /* Create new zebra client. */
1331: zebra_client_create (client_sock);
1332:
1333: return 0;
1334: }
1335:
1336: #ifdef HAVE_TCP_ZEBRA
1337: /* Make zebra's server socket. */
1338: static void
1339: zebra_serv ()
1340: {
1341: int ret;
1342: int accept_sock;
1343: struct sockaddr_in addr;
1344:
1345: accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1346:
1347: if (accept_sock < 0)
1348: {
1349: zlog_warn ("Can't create zserv stream socket: %s",
1350: safe_strerror (errno));
1351: zlog_warn ("zebra can't provice full functionality due to above error");
1352: return;
1353: }
1354:
1355: memset (&addr, 0, sizeof (struct sockaddr_in));
1356: addr.sin_family = AF_INET;
1357: addr.sin_port = htons (ZEBRA_PORT);
1358: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1359: addr.sin_len = sizeof (struct sockaddr_in);
1360: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1361: addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1362:
1363: sockopt_reuseaddr (accept_sock);
1364: sockopt_reuseport (accept_sock);
1365:
1366: if ( zserv_privs.change(ZPRIVS_RAISE) )
1367: zlog (NULL, LOG_ERR, "Can't raise privileges");
1368:
1369: ret = bind (accept_sock, (struct sockaddr *)&addr,
1370: sizeof (struct sockaddr_in));
1371: if (ret < 0)
1372: {
1373: zlog_warn ("Can't bind to stream socket: %s",
1374: safe_strerror (errno));
1375: zlog_warn ("zebra can't provice full functionality due to above error");
1376: close (accept_sock); /* Avoid sd leak. */
1377: return;
1378: }
1379:
1380: if ( zserv_privs.change(ZPRIVS_LOWER) )
1381: zlog (NULL, LOG_ERR, "Can't lower privileges");
1382:
1383: ret = listen (accept_sock, 1);
1384: if (ret < 0)
1385: {
1386: zlog_warn ("Can't listen to stream socket: %s",
1387: safe_strerror (errno));
1388: zlog_warn ("zebra can't provice full functionality due to above error");
1389: close (accept_sock); /* Avoid sd leak. */
1390: return;
1391: }
1392:
1393: zebra_event (ZEBRA_SERV, accept_sock, NULL);
1394: }
1395: #endif /* HAVE_TCP_ZEBRA */
1396:
1397: /* For sockaddr_un. */
1398: #include <sys/un.h>
1399:
1400: /* zebra server UNIX domain socket. */
1401: static void
1402: zebra_serv_un (const char *path)
1403: {
1404: int ret;
1405: int sock, len;
1406: struct sockaddr_un serv;
1407: mode_t old_mask;
1408:
1409: /* First of all, unlink existing socket */
1410: unlink (path);
1411:
1412: /* Set umask */
1413: old_mask = umask (0077);
1414:
1415: /* Make UNIX domain socket. */
1416: sock = socket (AF_UNIX, SOCK_STREAM, 0);
1417: if (sock < 0)
1418: {
1419: zlog_warn ("Can't create zserv unix socket: %s",
1420: safe_strerror (errno));
1421: zlog_warn ("zebra can't provide full functionality due to above error");
1422: return;
1423: }
1424:
1425: /* Make server socket. */
1426: memset (&serv, 0, sizeof (struct sockaddr_un));
1427: serv.sun_family = AF_UNIX;
1428: strncpy (serv.sun_path, path, strlen (path));
1429: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1430: len = serv.sun_len = SUN_LEN(&serv);
1431: #else
1432: len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1433: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
1434:
1435: ret = bind (sock, (struct sockaddr *) &serv, len);
1436: if (ret < 0)
1437: {
1438: zlog_warn ("Can't bind to unix socket %s: %s",
1439: path, safe_strerror (errno));
1440: zlog_warn ("zebra can't provide full functionality due to above error");
1441: close (sock);
1442: return;
1443: }
1444:
1445: ret = listen (sock, 5);
1446: if (ret < 0)
1447: {
1448: zlog_warn ("Can't listen to unix socket %s: %s",
1449: path, safe_strerror (errno));
1450: zlog_warn ("zebra can't provide full functionality due to above error");
1451: close (sock);
1452: return;
1453: }
1454:
1455: umask (old_mask);
1456:
1457: zebra_event (ZEBRA_SERV, sock, NULL);
1458: }
1459:
1460:
1461: static void
1462: zebra_event (enum event event, int sock, struct zserv *client)
1463: {
1464: switch (event)
1465: {
1466: case ZEBRA_SERV:
1467: thread_add_read (zebrad.master, zebra_accept, client, sock);
1468: break;
1469: case ZEBRA_READ:
1470: client->t_read =
1471: thread_add_read (zebrad.master, zebra_client_read, client, sock);
1472: break;
1473: case ZEBRA_WRITE:
1474: /**/
1475: break;
1476: }
1477: }
1478:
1479: /* Display default rtm_table for all clients. */
1480: DEFUN (show_table,
1481: show_table_cmd,
1482: "show table",
1483: SHOW_STR
1484: "default routing table to use for all clients\n")
1485: {
1486: vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1487: VTY_NEWLINE);
1488: return CMD_SUCCESS;
1489: }
1490:
1491: DEFUN (config_table,
1492: config_table_cmd,
1493: "table TABLENO",
1494: "Configure target kernel routing table\n"
1495: "TABLE integer\n")
1496: {
1497: zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
1498: return CMD_SUCCESS;
1499: }
1500:
1501: DEFUN (ip_forwarding,
1502: ip_forwarding_cmd,
1503: "ip forwarding",
1504: IP_STR
1505: "Turn on IP forwarding")
1506: {
1507: int ret;
1508:
1509: ret = ipforward ();
1510: if (ret == 0)
1511: ret = ipforward_on ();
1512:
1513: if (ret == 0)
1514: {
1515: vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1516: return CMD_WARNING;
1517: }
1518:
1519: return CMD_SUCCESS;
1520: }
1521:
1522: DEFUN (no_ip_forwarding,
1523: no_ip_forwarding_cmd,
1524: "no ip forwarding",
1525: NO_STR
1526: IP_STR
1527: "Turn off IP forwarding")
1528: {
1529: int ret;
1530:
1531: ret = ipforward ();
1532: if (ret != 0)
1533: ret = ipforward_off ();
1534:
1535: if (ret != 0)
1536: {
1537: vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1538: return CMD_WARNING;
1539: }
1540:
1541: return CMD_SUCCESS;
1542: }
1543:
1544: /* This command is for debugging purpose. */
1545: DEFUN (show_zebra_client,
1546: show_zebra_client_cmd,
1547: "show zebra client",
1548: SHOW_STR
1549: "Zebra information"
1550: "Client information")
1551: {
1552: struct listnode *node;
1553: struct zserv *client;
1554:
1555: for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1556: vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1557:
1558: return CMD_SUCCESS;
1559: }
1560:
1561: /* Table configuration write function. */
1562: static int
1563: config_write_table (struct vty *vty)
1564: {
1565: if (zebrad.rtm_table_default)
1566: vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1567: VTY_NEWLINE);
1568: return 0;
1569: }
1570:
1571: /* table node for routing tables. */
1572: static struct cmd_node table_node =
1573: {
1574: TABLE_NODE,
1575: "", /* This node has no interface. */
1576: 1
1577: };
1578:
1579: /* Only display ip forwarding is enabled or not. */
1580: DEFUN (show_ip_forwarding,
1581: show_ip_forwarding_cmd,
1582: "show ip forwarding",
1583: SHOW_STR
1584: IP_STR
1585: "IP forwarding status\n")
1586: {
1587: int ret;
1588:
1589: ret = ipforward ();
1590:
1591: if (ret == 0)
1592: vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1593: else
1594: vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1595: return CMD_SUCCESS;
1596: }
1597:
1598: #ifdef HAVE_IPV6
1599: /* Only display ipv6 forwarding is enabled or not. */
1600: DEFUN (show_ipv6_forwarding,
1601: show_ipv6_forwarding_cmd,
1602: "show ipv6 forwarding",
1603: SHOW_STR
1604: "IPv6 information\n"
1605: "Forwarding status\n")
1606: {
1607: int ret;
1608:
1609: ret = ipforward_ipv6 ();
1610:
1611: switch (ret)
1612: {
1613: case -1:
1614: vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1615: break;
1616: case 0:
1617: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1618: break;
1619: case 1:
1620: vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1621: break;
1622: default:
1623: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1624: break;
1625: }
1626: return CMD_SUCCESS;
1627: }
1628:
1629: DEFUN (ipv6_forwarding,
1630: ipv6_forwarding_cmd,
1631: "ipv6 forwarding",
1632: IPV6_STR
1633: "Turn on IPv6 forwarding")
1634: {
1635: int ret;
1636:
1637: ret = ipforward_ipv6 ();
1638: if (ret == 0)
1639: ret = ipforward_ipv6_on ();
1640:
1641: if (ret == 0)
1642: {
1643: vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1644: return CMD_WARNING;
1645: }
1646:
1647: return CMD_SUCCESS;
1648: }
1649:
1650: DEFUN (no_ipv6_forwarding,
1651: no_ipv6_forwarding_cmd,
1652: "no ipv6 forwarding",
1653: NO_STR
1654: IPV6_STR
1655: "Turn off IPv6 forwarding")
1656: {
1657: int ret;
1658:
1659: ret = ipforward_ipv6 ();
1660: if (ret != 0)
1661: ret = ipforward_ipv6_off ();
1662:
1663: if (ret != 0)
1664: {
1665: vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1666: return CMD_WARNING;
1667: }
1668:
1669: return CMD_SUCCESS;
1670: }
1671:
1672: #endif /* HAVE_IPV6 */
1673:
1674: /* IPForwarding configuration write function. */
1675: static int
1676: config_write_forwarding (struct vty *vty)
1677: {
1678: /* FIXME: Find better place for that. */
1679: router_id_write (vty);
1680:
1681: if (ipforward ())
1682: vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
1683: #ifdef HAVE_IPV6
1684: if (ipforward_ipv6 ())
1685: vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
1686: #endif /* HAVE_IPV6 */
1687: vty_out (vty, "!%s", VTY_NEWLINE);
1688: return 0;
1689: }
1690:
1691: /* table node for routing tables. */
1692: static struct cmd_node forwarding_node =
1693: {
1694: FORWARDING_NODE,
1695: "", /* This node has no interface. */
1696: 1
1697: };
1698:
1699:
1700: /* Initialisation of zebra and installation of commands. */
1701: void
1702: zebra_init (void)
1703: {
1704: /* Client list init. */
1705: zebrad.client_list = list_new ();
1706:
1707: /* Install configuration write function. */
1708: install_node (&table_node, config_write_table);
1709: install_node (&forwarding_node, config_write_forwarding);
1710:
1711: install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1712: install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1713: install_element (CONFIG_NODE, &ip_forwarding_cmd);
1714: install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1715: install_element (ENABLE_NODE, &show_zebra_client_cmd);
1716:
1717: #ifdef HAVE_NETLINK
1718: install_element (VIEW_NODE, &show_table_cmd);
1719: install_element (ENABLE_NODE, &show_table_cmd);
1720: install_element (CONFIG_NODE, &config_table_cmd);
1721: #endif /* HAVE_NETLINK */
1722:
1723: #ifdef HAVE_IPV6
1724: install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1725: install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1726: install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
1727: install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1728: #endif /* HAVE_IPV6 */
1729:
1730: /* Route-map */
1731: zebra_route_map_init ();
1732: }
1733:
1734: /* Make zebra server socket, wiping any existing one (see bug #403). */
1735: void
1736: zebra_zserv_socket_init (void)
1737: {
1738: #ifdef HAVE_TCP_ZEBRA
1739: zebra_serv ();
1740: #else
1741: zebra_serv_un (ZEBRA_SERV_PATH);
1742: #endif /* HAVE_TCP_ZEBRA */
1743: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>