Annotation of embedaddon/quagga/zebra/zserv.c, revision 1.1.1.4
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"
1.1.1.4 ! misho 39: #include "vrf.h"
1.1 misho 40:
41: #include "zebra/zserv.h"
42: #include "zebra/router-id.h"
43: #include "zebra/redistribute.h"
44: #include "zebra/debug.h"
45: #include "zebra/ipforward.h"
1.1.1.4 ! misho 46:
1.1 misho 47: /* Event list of zebra. */
48: enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
49:
50: extern struct zebra_t zebrad;
51:
52: static void zebra_event (enum event event, int sock, struct zserv *client);
53:
54: extern struct zebra_privs_t zserv_privs;
1.1.1.4 ! misho 55:
1.1 misho 56: static void zebra_client_close (struct zserv *client);
57:
58: static int
59: zserv_delayed_close(struct thread *thread)
60: {
61: struct zserv *client = THREAD_ARG(thread);
62:
63: client->t_suicide = NULL;
64: zebra_client_close(client);
65: return 0;
66: }
67:
1.1.1.2 misho 68: /* When client connects, it sends hello message
69: * with promise to send zebra routes of specific type.
70: * Zebra stores a socket fd of the client into
71: * this array. And use it to clean up routes that
72: * client didn't remove for some reasons after closing
73: * connection.
74: */
75: static int route_type_oaths[ZEBRA_ROUTE_MAX];
76:
1.1 misho 77: static int
78: zserv_flush_data(struct thread *thread)
79: {
80: struct zserv *client = THREAD_ARG(thread);
81:
82: client->t_write = NULL;
83: if (client->t_suicide)
84: {
85: zebra_client_close(client);
86: return -1;
87: }
88: switch (buffer_flush_available(client->wb, client->sock))
89: {
90: case BUFFER_ERROR:
91: zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
92: "closing", __func__, client->sock);
93: zebra_client_close(client);
94: break;
95: case BUFFER_PENDING:
96: client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
97: client, client->sock);
98: break;
99: case BUFFER_EMPTY:
100: break;
101: }
102: return 0;
103: }
104:
105: static int
106: zebra_server_send_message(struct zserv *client)
107: {
108: if (client->t_suicide)
109: return -1;
110: switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
111: stream_get_endp(client->obuf)))
112: {
113: case BUFFER_ERROR:
114: zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
115: __func__, client->sock);
116: /* Schedule a delayed close since many of the functions that call this
117: one do not check the return code. They do not allow for the
118: possibility that an I/O error may have caused the client to be
119: deleted. */
120: client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
121: client, 0);
122: return -1;
123: case BUFFER_EMPTY:
124: THREAD_OFF(client->t_write);
125: break;
126: case BUFFER_PENDING:
127: THREAD_WRITE_ON(zebrad.master, client->t_write,
128: zserv_flush_data, client, client->sock);
129: break;
130: }
131: return 0;
132: }
133:
134: static void
1.1.1.4 ! misho 135: zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
1.1 misho 136: {
137: /* length placeholder, caller can update */
138: stream_putw (s, ZEBRA_HEADER_SIZE);
139: stream_putc (s, ZEBRA_HEADER_MARKER);
140: stream_putc (s, ZSERV_VERSION);
1.1.1.4 ! misho 141: stream_putw (s, vrf_id);
1.1 misho 142: stream_putw (s, cmd);
143: }
144:
1.1.1.2 misho 145: static void
146: zserv_encode_interface (struct stream *s, struct interface *ifp)
147: {
148: /* Interface information. */
149: stream_put (s, ifp->name, INTERFACE_NAMSIZ);
150: stream_putl (s, ifp->ifindex);
151: stream_putc (s, ifp->status);
152: stream_putq (s, ifp->flags);
153: stream_putl (s, ifp->metric);
154: stream_putl (s, ifp->mtu);
155: stream_putl (s, ifp->mtu6);
156: stream_putl (s, ifp->bandwidth);
1.1.1.4 ! misho 157: stream_putl (s, ifp->ll_type);
1.1.1.2 misho 158: stream_putl (s, ifp->hw_addr_len);
159: if (ifp->hw_addr_len)
160: stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
161:
162: /* Write packet size. */
163: stream_putw_at (s, 0, stream_get_endp (s));
164: }
165:
1.1 misho 166: /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
167: /*
168: * This function is called in the following situations:
169: * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
170: * from the client.
171: * - at startup, when zebra figures out the available interfaces
172: * - when an interface is added (where support for
173: * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
174: * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
175: * received)
176: */
177: int
178: zsend_interface_add (struct zserv *client, struct interface *ifp)
179: {
180: struct stream *s;
181:
182: /* Check this client need interface information. */
1.1.1.4 ! misho 183: if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
1.1 misho 184: return 0;
185:
186: s = client->obuf;
187: stream_reset (s);
188:
1.1.1.4 ! misho 189: zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
1.1.1.2 misho 190: zserv_encode_interface (s, ifp);
1.1 misho 191:
192: return zebra_server_send_message(client);
193: }
194:
195: /* Interface deletion from zebra daemon. */
196: int
197: zsend_interface_delete (struct zserv *client, struct interface *ifp)
198: {
199: struct stream *s;
200:
201: /* Check this client need interface information. */
1.1.1.4 ! misho 202: if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
1.1 misho 203: return 0;
204:
205: s = client->obuf;
206: stream_reset (s);
207:
1.1.1.4 ! misho 208: zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
1.1.1.2 misho 209: zserv_encode_interface (s, ifp);
1.1 misho 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. */
1.1.1.4 ! misho 261: if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
1.1 misho 262: return 0;
263:
264: s = client->obuf;
265: stream_reset (s);
266:
1.1.1.4 ! misho 267: zserv_create_header (s, cmd, ifp->vrf_id);
1.1 misho 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. */
1.1.1.4 ! misho 315: if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
1.1 misho 316: return 0;
317:
318: s = client->obuf;
319: stream_reset (s);
320:
1.1.1.4 ! misho 321: zserv_create_header (s, cmd, ifp->vrf_id);
1.1.1.2 misho 322: zserv_encode_interface (s, ifp);
1.1 misho 323:
324: return zebra_server_send_message(client);
325: }
326:
327: /*
328: * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
329: * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
330: * situations:
331: * - when the client starts up, and requests default information
332: * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
333: * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
334: * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
335: * - when the zebra server redistributes routes after it updates its rib
336: *
337: * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
338: * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
339: * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
340: * - deleted from zebra's rib, and this info
341: * has to be redistributed to the clients
342: *
343: * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
344: * zebra server when the client wants to tell the zebra server to add a
345: * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
346: * same message being sent back and forth, this function and
347: * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
348: * duplication.
349: */
350: int
351: zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
352: struct rib *rib)
353: {
354: int psize;
355: struct stream *s;
356: struct nexthop *nexthop;
357: unsigned long nhnummark = 0, messmark = 0;
358: int nhnum = 0;
359: u_char zapi_flags = 0;
1.1.1.4 ! misho 360:
! 361: /* Check this client need this route. */
! 362: if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) &&
! 363: !(is_default (p) &&
! 364: vrf_bitmap_check (client->redist_default, rib->vrf_id)))
! 365: return 0;
! 366:
1.1 misho 367: s = client->obuf;
368: stream_reset (s);
369:
1.1.1.4 ! misho 370: zserv_create_header (s, cmd, rib->vrf_id);
1.1 misho 371:
372: /* Put type and nexthop. */
373: stream_putc (s, rib->type);
374: stream_putc (s, rib->flags);
375:
376: /* marker for message flags field */
377: messmark = stream_get_endp (s);
378: stream_putc (s, 0);
379:
380: /* Prefix. */
381: psize = PSIZE (p->prefixlen);
382: stream_putc (s, p->prefixlen);
383: stream_write (s, (u_char *) & p->u.prefix, psize);
384:
385: /*
386: * XXX The message format sent by zebra below does not match the format
387: * of the corresponding message expected by the zebra server
388: * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
389: * (is there a bug on the client side if more than one segment is sent?)
390: * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
391: * is hard-coded.
392: */
393: /* Nexthop */
394:
395: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
396: {
1.1.1.4 ! misho 397: if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1.1 misho 398: {
399: SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
400: SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
401:
402: if (nhnummark == 0)
403: {
404: nhnummark = stream_get_endp (s);
405: stream_putc (s, 1); /* placeholder */
406: }
407:
408: nhnum++;
409:
410: switch(nexthop->type)
411: {
412: case NEXTHOP_TYPE_IPV4:
413: case NEXTHOP_TYPE_IPV4_IFINDEX:
414: stream_put_in_addr (s, &nexthop->gate.ipv4);
415: break;
416: #ifdef HAVE_IPV6
417: case NEXTHOP_TYPE_IPV6:
418: case NEXTHOP_TYPE_IPV6_IFINDEX:
419: case NEXTHOP_TYPE_IPV6_IFNAME:
420: stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
421: break;
422: #endif
423: default:
424: if (cmd == ZEBRA_IPV4_ROUTE_ADD
425: || cmd == ZEBRA_IPV4_ROUTE_DELETE)
426: {
427: struct in_addr empty;
428: memset (&empty, 0, sizeof (struct in_addr));
429: stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
430: }
431: else
432: {
433: struct in6_addr empty;
434: memset (&empty, 0, sizeof (struct in6_addr));
435: stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
436: }
437: }
438:
439: /* Interface index. */
440: stream_putc (s, 1);
441: stream_putl (s, nexthop->ifindex);
442:
443: break;
444: }
445: }
446:
447: /* Metric */
448: if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
449: {
450: SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
451: stream_putc (s, rib->distance);
452: SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
453: stream_putl (s, rib->metric);
1.1.1.4 ! misho 454: SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
! 455: stream_putl (s, rib->mtu);
1.1 misho 456: }
457:
458: /* write real message flags value */
459: stream_putc_at (s, messmark, zapi_flags);
460:
461: /* Write next-hop number */
462: if (nhnummark)
463: stream_putc_at (s, nhnummark, nhnum);
464:
465: /* Write packet size. */
466: stream_putw_at (s, 0, stream_get_endp (s));
467:
468: return zebra_server_send_message(client);
469: }
470:
471: #ifdef HAVE_IPV6
472: static int
1.1.1.4 ! misho 473: zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
! 474: vrf_id_t vrf_id)
1.1 misho 475: {
476: struct stream *s;
477: struct rib *rib;
478: unsigned long nump;
479: u_char num;
480: struct nexthop *nexthop;
481:
482: /* Lookup nexthop. */
1.1.1.4 ! misho 483: rib = rib_match_ipv6 (addr, vrf_id);
1.1 misho 484:
485: /* Get output stream. */
486: s = client->obuf;
487: stream_reset (s);
488:
489: /* Fill in result. */
1.1.1.4 ! misho 490: zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
! 491: stream_put (s, addr, 16);
1.1 misho 492:
493: if (rib)
494: {
495: stream_putl (s, rib->metric);
496: num = 0;
497: nump = stream_get_endp(s);
498: stream_putc (s, 0);
1.1.1.4 ! misho 499: /* Only non-recursive routes are elegible to resolve nexthop we
! 500: * are looking up. Therefore, we will just iterate over the top
! 501: * chain of nexthops. */
1.1 misho 502: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1.1.1.4 ! misho 503: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1.1 misho 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
1.1.1.4 ! misho 541: zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
! 542: vrf_id_t vrf_id)
1.1 misho 543: {
544: struct stream *s;
545: struct rib *rib;
546: unsigned long nump;
547: u_char num;
548: struct nexthop *nexthop;
549:
1.1.1.4 ! misho 550: /* Lookup nexthop - eBGP excluded */
! 551: rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
1.1 misho 552:
553: /* Get output stream. */
554: s = client->obuf;
555: stream_reset (s);
556:
557: /* Fill in result. */
1.1.1.4 ! misho 558: zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
1.1 misho 559: stream_put_in_addr (s, &addr);
560:
561: if (rib)
562: {
1.1.1.4 ! misho 563: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
! 564: zlog_debug("%s: Matching rib entry found.", __func__);
1.1 misho 565: stream_putl (s, rib->metric);
566: num = 0;
567: nump = stream_get_endp(s);
568: stream_putc (s, 0);
1.1.1.4 ! misho 569: /* Only non-recursive routes are elegible to resolve the nexthop we
! 570: * are looking up. Therefore, we will just iterate over the top
! 571: * chain of nexthops. */
1.1 misho 572: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1.1.1.4 ! misho 573: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1.1 misho 574: {
575: stream_putc (s, nexthop->type);
576: switch (nexthop->type)
577: {
578: case ZEBRA_NEXTHOP_IPV4:
579: stream_put_in_addr (s, &nexthop->gate.ipv4);
580: break;
1.1.1.4 ! misho 581: case ZEBRA_NEXTHOP_IPV4_IFINDEX:
! 582: stream_put_in_addr (s, &nexthop->gate.ipv4);
! 583: stream_putl (s, nexthop->ifindex);
! 584: break;
1.1 misho 585: case ZEBRA_NEXTHOP_IFINDEX:
586: case ZEBRA_NEXTHOP_IFNAME:
587: stream_putl (s, nexthop->ifindex);
588: break;
589: default:
590: /* do nothing */
591: break;
592: }
593: num++;
594: }
595: stream_putc_at (s, nump, num);
596: }
597: else
598: {
1.1.1.4 ! misho 599: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
! 600: zlog_debug("%s: No matching rib entry found.", __func__);
1.1 misho 601: stream_putl (s, 0);
602: stream_putc (s, 0);
603: }
604:
605: stream_putw_at (s, 0, stream_get_endp (s));
606:
607: return zebra_server_send_message(client);
608: }
609:
1.1.1.4 ! misho 610: /*
! 611: Modified version of zsend_ipv4_nexthop_lookup():
! 612: Query unicast rib if nexthop is not found on mrib.
! 613: Returns both route metric and protocol distance.
! 614: */
1.1 misho 615: static int
1.1.1.4 ! misho 616: zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
! 617: struct rib *rib)
! 618: {
! 619: struct stream *s;
! 620: unsigned long nump;
! 621: u_char num;
! 622: struct nexthop *nexthop;
! 623:
! 624: /* Get output stream. */
! 625: s = client->obuf;
! 626: stream_reset (s);
! 627:
! 628: /* Fill in result. */
! 629: zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
! 630: stream_put_in_addr (s, &addr);
! 631:
! 632: if (rib)
! 633: {
! 634: stream_putc (s, rib->distance);
! 635: stream_putl (s, rib->metric);
! 636: num = 0;
! 637: nump = stream_get_endp(s); /* remember position for nexthop_num */
! 638: stream_putc (s, 0); /* reserve room for nexthop_num */
! 639: /* Only non-recursive routes are elegible to resolve the nexthop we
! 640: * are looking up. Therefore, we will just iterate over the top
! 641: * chain of nexthops. */
! 642: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
! 643: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
! 644: {
! 645: stream_putc (s, nexthop->type);
! 646: switch (nexthop->type)
! 647: {
! 648: case ZEBRA_NEXTHOP_IPV4:
! 649: stream_put_in_addr (s, &nexthop->gate.ipv4);
! 650: break;
! 651: case ZEBRA_NEXTHOP_IPV4_IFINDEX:
! 652: stream_put_in_addr (s, &nexthop->gate.ipv4);
! 653: stream_putl (s, nexthop->ifindex);
! 654: break;
! 655: case ZEBRA_NEXTHOP_IFINDEX:
! 656: case ZEBRA_NEXTHOP_IFNAME:
! 657: stream_putl (s, nexthop->ifindex);
! 658: break;
! 659: default:
! 660: /* do nothing */
! 661: break;
! 662: }
! 663: num++;
! 664: }
! 665:
! 666: stream_putc_at (s, nump, num); /* store nexthop_num */
! 667: }
! 668: else
! 669: {
! 670: stream_putc (s, 0); /* distance */
! 671: stream_putl (s, 0); /* metric */
! 672: stream_putc (s, 0); /* nexthop_num */
! 673: }
! 674:
! 675: stream_putw_at (s, 0, stream_get_endp (s));
! 676:
! 677: return zebra_server_send_message(client);
! 678: }
! 679:
! 680: static int
! 681: zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
! 682: vrf_id_t vrf_id)
1.1 misho 683: {
684: struct stream *s;
685: struct rib *rib;
686: unsigned long nump;
687: u_char num;
688: struct nexthop *nexthop;
689:
690: /* Lookup nexthop. */
1.1.1.4 ! misho 691: rib = rib_lookup_ipv4 (p, vrf_id);
1.1 misho 692:
693: /* Get output stream. */
694: s = client->obuf;
695: stream_reset (s);
696:
697: /* Fill in result. */
1.1.1.4 ! misho 698: zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
1.1 misho 699: stream_put_in_addr (s, &p->prefix);
700:
701: if (rib)
702: {
703: stream_putl (s, rib->metric);
704: num = 0;
705: nump = stream_get_endp(s);
706: stream_putc (s, 0);
707: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1.1.1.4 ! misho 708: if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1.1 misho 709: {
710: stream_putc (s, nexthop->type);
711: switch (nexthop->type)
712: {
713: case ZEBRA_NEXTHOP_IPV4:
714: stream_put_in_addr (s, &nexthop->gate.ipv4);
715: break;
1.1.1.4 ! misho 716: case ZEBRA_NEXTHOP_IPV4_IFINDEX:
! 717: stream_put_in_addr (s, &nexthop->gate.ipv4);
! 718: stream_putl (s, nexthop->ifindex);
! 719: break;
1.1 misho 720: case ZEBRA_NEXTHOP_IFINDEX:
721: case ZEBRA_NEXTHOP_IFNAME:
722: stream_putl (s, nexthop->ifindex);
723: break;
724: default:
725: /* do nothing */
726: break;
727: }
728: num++;
729: }
730: stream_putc_at (s, nump, num);
731: }
732: else
733: {
734: stream_putl (s, 0);
735: stream_putc (s, 0);
736: }
737:
738: stream_putw_at (s, 0, stream_get_endp (s));
739:
740: return zebra_server_send_message(client);
741: }
1.1.1.4 ! misho 742:
1.1 misho 743: /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
744: int
1.1.1.4 ! misho 745: zsend_router_id_update (struct zserv *client, struct prefix *p,
! 746: vrf_id_t vrf_id)
1.1 misho 747: {
748: struct stream *s;
749: int blen;
750:
751: /* Check this client need interface information. */
1.1.1.4 ! misho 752: if (! vrf_bitmap_check (client->ridinfo, vrf_id))
1.1 misho 753: return 0;
754:
755: s = client->obuf;
756: stream_reset (s);
757:
758: /* Message type. */
1.1.1.4 ! misho 759: zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
1.1 misho 760:
761: /* Prefix information. */
762: stream_putc (s, p->family);
763: blen = prefix_blen (p);
764: stream_put (s, &p->u.prefix, blen);
765: stream_putc (s, p->prefixlen);
766:
767: /* Write packet size. */
768: stream_putw_at (s, 0, stream_get_endp (s));
769:
770: return zebra_server_send_message(client);
771: }
1.1.1.4 ! misho 772:
1.1 misho 773: /* Register zebra server interface information. Send current all
774: interface and address information. */
775: static int
1.1.1.4 ! misho 776: zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 777: {
778: struct listnode *ifnode, *ifnnode;
779: struct listnode *cnode, *cnnode;
780: struct interface *ifp;
781: struct connected *c;
782:
783: /* Interface information is needed. */
1.1.1.4 ! misho 784: vrf_bitmap_set (client->ifinfo, vrf_id);
1.1 misho 785:
1.1.1.4 ! misho 786: for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
1.1 misho 787: {
788: /* Skip pseudo interface. */
789: if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
790: continue;
791:
792: if (zsend_interface_add (client, ifp) < 0)
793: return -1;
794:
795: for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
796: {
797: if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
798: (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
799: ifp, c) < 0))
800: return -1;
801: }
802: }
803: return 0;
804: }
805:
806: /* Unregister zebra server interface information. */
807: static int
1.1.1.4 ! misho 808: zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 809: {
1.1.1.4 ! misho 810: vrf_bitmap_unset (client->ifinfo, vrf_id);
1.1 misho 811: return 0;
812: }
813:
814: /* This function support multiple nexthop. */
815: /*
816: * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
817: * add kernel route.
818: */
819: static int
1.1.1.4 ! misho 820: zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 821: {
822: int i;
823: struct rib *rib;
824: struct prefix_ipv4 p;
825: u_char message;
826: struct in_addr nexthop;
827: u_char nexthop_num;
828: u_char nexthop_type;
829: struct stream *s;
1.1.1.4 ! misho 830: ifindex_t ifindex;
1.1 misho 831: u_char ifname_len;
1.1.1.2 misho 832: safi_t safi;
833:
1.1 misho 834:
835: /* Get input stream. */
836: s = client->ibuf;
837:
838: /* Allocate new rib. */
839: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
840:
841: /* Type, flags, message. */
842: rib->type = stream_getc (s);
843: rib->flags = stream_getc (s);
844: message = stream_getc (s);
1.1.1.2 misho 845: safi = stream_getw (s);
1.1 misho 846: rib->uptime = time (NULL);
847:
848: /* IPv4 prefix. */
849: memset (&p, 0, sizeof (struct prefix_ipv4));
850: p.family = AF_INET;
851: p.prefixlen = stream_getc (s);
852: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
853:
1.1.1.4 ! misho 854: /* VRF ID */
! 855: rib->vrf_id = vrf_id;
! 856:
1.1 misho 857: /* Nexthop parse. */
858: if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
859: {
860: nexthop_num = stream_getc (s);
861:
862: for (i = 0; i < nexthop_num; i++)
863: {
864: nexthop_type = stream_getc (s);
865:
866: switch (nexthop_type)
867: {
868: case ZEBRA_NEXTHOP_IFINDEX:
869: ifindex = stream_getl (s);
870: nexthop_ifindex_add (rib, ifindex);
871: break;
872: case ZEBRA_NEXTHOP_IFNAME:
873: ifname_len = stream_getc (s);
874: stream_forward_getp (s, ifname_len);
875: break;
876: case ZEBRA_NEXTHOP_IPV4:
877: nexthop.s_addr = stream_get_ipv4 (s);
878: nexthop_ipv4_add (rib, &nexthop, NULL);
879: break;
1.1.1.3 misho 880: case ZEBRA_NEXTHOP_IPV4_IFINDEX:
881: nexthop.s_addr = stream_get_ipv4 (s);
882: ifindex = stream_getl (s);
883: nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
884: break;
1.1 misho 885: case ZEBRA_NEXTHOP_IPV6:
886: stream_forward_getp (s, IPV6_MAX_BYTELEN);
887: break;
1.1.1.2 misho 888: case ZEBRA_NEXTHOP_BLACKHOLE:
889: nexthop_blackhole_add (rib);
890: break;
891: }
1.1 misho 892: }
893: }
894:
895: /* Distance. */
896: if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
897: rib->distance = stream_getc (s);
898:
899: /* Metric. */
900: if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
901: rib->metric = stream_getl (s);
902:
1.1.1.4 ! misho 903: if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
! 904: rib->mtu = stream_getl (s);
! 905:
1.1 misho 906: /* Table */
907: rib->table=zebrad.rtm_table_default;
1.1.1.2 misho 908: rib_add_ipv4_multipath (&p, rib, safi);
1.1 misho 909: return 0;
910: }
911:
912: /* Zebra server IPv4 prefix delete function. */
913: static int
1.1.1.4 ! misho 914: zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 915: {
916: int i;
917: struct stream *s;
918: struct zapi_ipv4 api;
1.1.1.2 misho 919: struct in_addr nexthop, *nexthop_p;
1.1 misho 920: unsigned long ifindex;
921: struct prefix_ipv4 p;
922: u_char nexthop_num;
923: u_char nexthop_type;
924: u_char ifname_len;
925:
926: s = client->ibuf;
927: ifindex = 0;
928: nexthop.s_addr = 0;
1.1.1.2 misho 929: nexthop_p = NULL;
1.1 misho 930:
931: /* Type, flags, message. */
932: api.type = stream_getc (s);
933: api.flags = stream_getc (s);
934: api.message = stream_getc (s);
1.1.1.2 misho 935: api.safi = stream_getw (s);
1.1 misho 936:
937: /* IPv4 prefix. */
938: memset (&p, 0, sizeof (struct prefix_ipv4));
939: p.family = AF_INET;
940: p.prefixlen = stream_getc (s);
941: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
942:
943: /* Nexthop, ifindex, distance, metric. */
944: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
945: {
946: nexthop_num = stream_getc (s);
947:
948: for (i = 0; i < nexthop_num; i++)
949: {
950: nexthop_type = stream_getc (s);
951:
952: switch (nexthop_type)
953: {
954: case ZEBRA_NEXTHOP_IFINDEX:
955: ifindex = stream_getl (s);
956: break;
957: case ZEBRA_NEXTHOP_IFNAME:
958: ifname_len = stream_getc (s);
959: stream_forward_getp (s, ifname_len);
960: break;
961: case ZEBRA_NEXTHOP_IPV4:
962: nexthop.s_addr = stream_get_ipv4 (s);
1.1.1.2 misho 963: nexthop_p = &nexthop;
1.1 misho 964: break;
1.1.1.3 misho 965: case ZEBRA_NEXTHOP_IPV4_IFINDEX:
966: nexthop.s_addr = stream_get_ipv4 (s);
1.1.1.4 ! misho 967: nexthop_p = &nexthop;
1.1.1.3 misho 968: ifindex = stream_getl (s);
969: break;
1.1 misho 970: case ZEBRA_NEXTHOP_IPV6:
971: stream_forward_getp (s, IPV6_MAX_BYTELEN);
972: break;
973: }
974: }
975: }
976:
977: /* Distance. */
978: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
979: api.distance = stream_getc (s);
980: else
981: api.distance = 0;
982:
983: /* Metric. */
984: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
985: api.metric = stream_getl (s);
986: else
987: api.metric = 0;
988:
1.1.1.2 misho 989: rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
1.1.1.4 ! misho 990: vrf_id, api.safi);
1.1 misho 991: return 0;
992: }
993:
994: /* Nexthop lookup for IPv4. */
995: static int
1.1.1.4 ! misho 996: zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
! 997: vrf_id_t vrf_id)
! 998: {
! 999: struct in_addr addr;
! 1000: char buf[BUFSIZ];
! 1001:
! 1002: addr.s_addr = stream_get_ipv4 (client->ibuf);
! 1003: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
! 1004: zlog_debug("%s: looking up %s", __func__,
! 1005: inet_ntop (AF_INET, &addr, buf, BUFSIZ));
! 1006: return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
! 1007: }
! 1008:
! 1009: /* MRIB Nexthop lookup for IPv4. */
! 1010: static int
! 1011: zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
! 1012: vrf_id_t vrf_id)
1.1 misho 1013: {
1014: struct in_addr addr;
1.1.1.4 ! misho 1015: struct rib *rib;
1.1 misho 1016:
1017: addr.s_addr = stream_get_ipv4 (client->ibuf);
1.1.1.4 ! misho 1018: rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
! 1019: return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
1.1 misho 1020: }
1021:
1022: /* Nexthop lookup for IPv4. */
1023: static int
1.1.1.4 ! misho 1024: zread_ipv4_import_lookup (struct zserv *client, u_short length,
! 1025: vrf_id_t vrf_id)
1.1 misho 1026: {
1027: struct prefix_ipv4 p;
1028:
1029: p.family = AF_INET;
1030: p.prefixlen = stream_getc (client->ibuf);
1031: p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1032:
1.1.1.4 ! misho 1033: return zsend_ipv4_import_lookup (client, &p, vrf_id);
1.1 misho 1034: }
1035:
1036: #ifdef HAVE_IPV6
1037: /* Zebra server IPv6 prefix add function. */
1038: static int
1.1.1.4 ! misho 1039: zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 1040: {
1041: int i;
1042: struct stream *s;
1043: struct zapi_ipv6 api;
1044: struct in6_addr nexthop;
1045: unsigned long ifindex;
1046: struct prefix_ipv6 p;
1047:
1048: s = client->ibuf;
1049: ifindex = 0;
1050: memset (&nexthop, 0, sizeof (struct in6_addr));
1051:
1052: /* Type, flags, message. */
1053: api.type = stream_getc (s);
1054: api.flags = stream_getc (s);
1055: api.message = stream_getc (s);
1.1.1.2 misho 1056: api.safi = stream_getw (s);
1.1 misho 1057:
1058: /* IPv4 prefix. */
1059: memset (&p, 0, sizeof (struct prefix_ipv6));
1060: p.family = AF_INET6;
1061: p.prefixlen = stream_getc (s);
1062: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1063:
1064: /* Nexthop, ifindex, distance, metric. */
1065: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1066: {
1067: u_char nexthop_type;
1068:
1069: api.nexthop_num = stream_getc (s);
1070: for (i = 0; i < api.nexthop_num; i++)
1071: {
1072: nexthop_type = stream_getc (s);
1073:
1074: switch (nexthop_type)
1075: {
1076: case ZEBRA_NEXTHOP_IPV6:
1077: stream_get (&nexthop, s, 16);
1078: break;
1079: case ZEBRA_NEXTHOP_IFINDEX:
1080: ifindex = stream_getl (s);
1081: break;
1082: }
1083: }
1084: }
1085:
1086: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1087: api.distance = stream_getc (s);
1088: else
1089: api.distance = 0;
1090:
1091: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1092: api.metric = stream_getl (s);
1093: else
1094: api.metric = 0;
1.1.1.4 ! misho 1095:
! 1096: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU))
! 1097: api.mtu = stream_getl (s);
! 1098: else
! 1099: api.mtu = 0;
1.1 misho 1100:
1101: if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1.1.1.4 ! misho 1102: rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
! 1103: vrf_id, zebrad.rtm_table_default, api.metric,
! 1104: api.mtu, api.distance, api.safi);
1.1 misho 1105: else
1.1.1.4 ! misho 1106: rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
! 1107: vrf_id, zebrad.rtm_table_default, api.metric,
! 1108: api.mtu, api.distance, api.safi);
1.1 misho 1109: return 0;
1110: }
1111:
1112: /* Zebra server IPv6 prefix delete function. */
1113: static int
1.1.1.4 ! misho 1114: zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 1115: {
1116: int i;
1117: struct stream *s;
1118: struct zapi_ipv6 api;
1119: struct in6_addr nexthop;
1120: unsigned long ifindex;
1121: struct prefix_ipv6 p;
1122:
1123: s = client->ibuf;
1124: ifindex = 0;
1125: memset (&nexthop, 0, sizeof (struct in6_addr));
1126:
1127: /* Type, flags, message. */
1128: api.type = stream_getc (s);
1129: api.flags = stream_getc (s);
1130: api.message = stream_getc (s);
1.1.1.2 misho 1131: api.safi = stream_getw (s);
1.1 misho 1132:
1133: /* IPv4 prefix. */
1134: memset (&p, 0, sizeof (struct prefix_ipv6));
1135: p.family = AF_INET6;
1136: p.prefixlen = stream_getc (s);
1137: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1138:
1139: /* Nexthop, ifindex, distance, metric. */
1140: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1141: {
1142: u_char nexthop_type;
1143:
1144: api.nexthop_num = stream_getc (s);
1145: for (i = 0; i < api.nexthop_num; i++)
1146: {
1147: nexthop_type = stream_getc (s);
1148:
1149: switch (nexthop_type)
1150: {
1151: case ZEBRA_NEXTHOP_IPV6:
1152: stream_get (&nexthop, s, 16);
1153: break;
1154: case ZEBRA_NEXTHOP_IFINDEX:
1155: ifindex = stream_getl (s);
1156: break;
1157: }
1158: }
1159: }
1160:
1161: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1162: api.distance = stream_getc (s);
1163: else
1164: api.distance = 0;
1165: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1166: api.metric = stream_getl (s);
1167: else
1168: api.metric = 0;
1169:
1170: if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1.1.1.4 ! misho 1171: rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
! 1172: api.safi);
1.1 misho 1173: else
1.1.1.4 ! misho 1174: rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
! 1175: api.safi);
1.1 misho 1176: return 0;
1177: }
1178:
1179: static int
1.1.1.4 ! misho 1180: zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
! 1181: vrf_id_t vrf_id)
1.1 misho 1182: {
1183: struct in6_addr addr;
1184: char buf[BUFSIZ];
1185:
1186: stream_get (&addr, client->ibuf, 16);
1.1.1.4 ! misho 1187: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
! 1188: zlog_debug("%s: looking up %s", __func__,
! 1189: inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1.1 misho 1190:
1.1.1.4 ! misho 1191: return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
1.1 misho 1192: }
1193: #endif /* HAVE_IPV6 */
1194:
1195: /* Register zebra server router-id information. Send current router-id */
1196: static int
1.1.1.4 ! misho 1197: zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 1198: {
1199: struct prefix p;
1200:
1201: /* Router-id information is needed. */
1.1.1.4 ! misho 1202: vrf_bitmap_set (client->ridinfo, vrf_id);
1.1 misho 1203:
1.1.1.4 ! misho 1204: router_id_get (&p, vrf_id);
1.1 misho 1205:
1.1.1.4 ! misho 1206: return zsend_router_id_update (client, &p, vrf_id);
1.1 misho 1207: }
1208:
1209: /* Unregister zebra server router-id information. */
1210: static int
1.1.1.4 ! misho 1211: zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
1.1 misho 1212: {
1.1.1.4 ! misho 1213: vrf_bitmap_unset (client->ridinfo, vrf_id);
1.1 misho 1214: return 0;
1215: }
1216:
1.1.1.2 misho 1217: /* Tie up route-type and client->sock */
1218: static void
1219: zread_hello (struct zserv *client)
1220: {
1221: /* type of protocol (lib/zebra.h) */
1222: u_char proto;
1223: proto = stream_getc (client->ibuf);
1224:
1225: /* accept only dynamic routing protocols */
1226: if ((proto < ZEBRA_ROUTE_MAX)
1227: && (proto > ZEBRA_ROUTE_STATIC))
1228: {
1229: zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1230: client->sock, zebra_route_string(proto));
1231:
1232: /* if route-type was binded by other client */
1233: if (route_type_oaths[proto])
1234: zlog_warn ("sender of %s routes changed %c->%c",
1235: zebra_route_string(proto), route_type_oaths[proto],
1236: client->sock);
1237:
1238: route_type_oaths[proto] = client->sock;
1239: }
1240: }
1241:
1.1.1.4 ! misho 1242: /* Unregister all information in a VRF. */
! 1243: static int
! 1244: zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
! 1245: {
! 1246: int i;
! 1247:
! 1248: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
! 1249: vrf_bitmap_unset (client->redist[i], vrf_id);
! 1250: vrf_bitmap_unset (client->redist_default, vrf_id);
! 1251: vrf_bitmap_unset (client->ifinfo, vrf_id);
! 1252: vrf_bitmap_unset (client->ridinfo, vrf_id);
! 1253:
! 1254: return 0;
! 1255: }
! 1256:
1.1.1.2 misho 1257: /* If client sent routes of specific type, zebra removes it
1258: * and returns number of deleted routes.
1259: */
1260: static void
1261: zebra_score_rib (int client_sock)
1262: {
1263: int i;
1264:
1265: for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1266: if (client_sock == route_type_oaths[i])
1267: {
1268: zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1269: client_sock, rib_score_proto (i), zebra_route_string (i));
1270: route_type_oaths[i] = 0;
1271: break;
1272: }
1273: }
1274:
1.1 misho 1275: /* Close zebra client. */
1276: static void
1277: zebra_client_close (struct zserv *client)
1278: {
1279: /* Close file descriptor. */
1280: if (client->sock)
1281: {
1282: close (client->sock);
1.1.1.2 misho 1283: zebra_score_rib (client->sock);
1.1 misho 1284: client->sock = -1;
1285: }
1286:
1287: /* Free stream buffers. */
1288: if (client->ibuf)
1289: stream_free (client->ibuf);
1290: if (client->obuf)
1291: stream_free (client->obuf);
1292: if (client->wb)
1293: buffer_free(client->wb);
1294:
1295: /* Release threads. */
1296: if (client->t_read)
1297: thread_cancel (client->t_read);
1298: if (client->t_write)
1299: thread_cancel (client->t_write);
1300: if (client->t_suicide)
1301: thread_cancel (client->t_suicide);
1302:
1303: /* Free client structure. */
1304: listnode_delete (zebrad.client_list, client);
1305: XFREE (0, client);
1306: }
1307:
1308: /* Make new client. */
1309: static void
1310: zebra_client_create (int sock)
1311: {
1312: struct zserv *client;
1.1.1.4 ! misho 1313: int i;
1.1 misho 1314:
1315: client = XCALLOC (0, sizeof (struct zserv));
1316:
1317: /* Make client input/output buffer. */
1318: client->sock = sock;
1319: client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1320: client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1321: client->wb = buffer_new(0);
1322:
1323: /* Set table number. */
1324: client->rtm_table = zebrad.rtm_table_default;
1325:
1.1.1.4 ! misho 1326: /* Initialize flags */
! 1327: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
! 1328: client->redist[i] = vrf_bitmap_init ();
! 1329: client->redist_default = vrf_bitmap_init ();
! 1330: client->ifinfo = vrf_bitmap_init ();
! 1331: client->ridinfo = vrf_bitmap_init ();
! 1332:
1.1 misho 1333: /* Add this client to linked list. */
1334: listnode_add (zebrad.client_list, client);
1335:
1336: /* Make new read thread. */
1337: zebra_event (ZEBRA_READ, sock, client);
1338: }
1339:
1340: /* Handler of zebra service request. */
1341: static int
1342: zebra_client_read (struct thread *thread)
1343: {
1344: int sock;
1345: struct zserv *client;
1346: size_t already;
1347: uint16_t length, command;
1348: uint8_t marker, version;
1.1.1.4 ! misho 1349: vrf_id_t vrf_id;
1.1 misho 1350:
1351: /* Get thread data. Reset reading thread because I'm running. */
1352: sock = THREAD_FD (thread);
1353: client = THREAD_ARG (thread);
1354: client->t_read = NULL;
1355:
1356: if (client->t_suicide)
1357: {
1358: zebra_client_close(client);
1359: return -1;
1360: }
1361:
1362: /* Read length and command (if we don't have it already). */
1363: if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
1364: {
1365: ssize_t nbyte;
1366: if (((nbyte = stream_read_try (client->ibuf, sock,
1367: ZEBRA_HEADER_SIZE-already)) == 0) ||
1368: (nbyte == -1))
1369: {
1370: if (IS_ZEBRA_DEBUG_EVENT)
1371: zlog_debug ("connection closed socket [%d]", sock);
1372: zebra_client_close (client);
1373: return -1;
1374: }
1375: if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1376: {
1377: /* Try again later. */
1378: zebra_event (ZEBRA_READ, sock, client);
1379: return 0;
1380: }
1381: already = ZEBRA_HEADER_SIZE;
1382: }
1383:
1384: /* Reset to read from the beginning of the incoming packet. */
1385: stream_set_getp(client->ibuf, 0);
1386:
1387: /* Fetch header values */
1388: length = stream_getw (client->ibuf);
1389: marker = stream_getc (client->ibuf);
1390: version = stream_getc (client->ibuf);
1.1.1.4 ! misho 1391: vrf_id = stream_getw (client->ibuf);
1.1 misho 1392: command = stream_getw (client->ibuf);
1393:
1394: if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1395: {
1396: zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1397: __func__, sock, marker, version);
1398: zebra_client_close (client);
1399: return -1;
1400: }
1401: if (length < ZEBRA_HEADER_SIZE)
1402: {
1403: zlog_warn("%s: socket %d message length %u is less than header size %d",
1404: __func__, sock, length, ZEBRA_HEADER_SIZE);
1405: zebra_client_close (client);
1406: return -1;
1407: }
1408: if (length > STREAM_SIZE(client->ibuf))
1409: {
1410: zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1411: __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
1412: zebra_client_close (client);
1413: return -1;
1414: }
1415:
1416: /* Read rest of data. */
1417: if (already < length)
1418: {
1419: ssize_t nbyte;
1420: if (((nbyte = stream_read_try (client->ibuf, sock,
1421: length-already)) == 0) ||
1422: (nbyte == -1))
1423: {
1424: if (IS_ZEBRA_DEBUG_EVENT)
1425: zlog_debug ("connection closed [%d] when reading zebra data", sock);
1426: zebra_client_close (client);
1427: return -1;
1428: }
1429: if (nbyte != (ssize_t)(length-already))
1430: {
1431: /* Try again later. */
1432: zebra_event (ZEBRA_READ, sock, client);
1433: return 0;
1434: }
1435: }
1436:
1437: length -= ZEBRA_HEADER_SIZE;
1438:
1439: /* Debug packet information. */
1440: if (IS_ZEBRA_DEBUG_EVENT)
1441: zlog_debug ("zebra message comes from socket [%d]", sock);
1442:
1443: if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1.1.1.4 ! misho 1444: zlog_debug ("zebra message received [%s] %d in VRF %u",
! 1445: zserv_command_string (command), length, vrf_id);
1.1 misho 1446:
1447: switch (command)
1448: {
1449: case ZEBRA_ROUTER_ID_ADD:
1.1.1.4 ! misho 1450: zread_router_id_add (client, length, vrf_id);
1.1 misho 1451: break;
1452: case ZEBRA_ROUTER_ID_DELETE:
1.1.1.4 ! misho 1453: zread_router_id_delete (client, length, vrf_id);
1.1 misho 1454: break;
1455: case ZEBRA_INTERFACE_ADD:
1.1.1.4 ! misho 1456: zread_interface_add (client, length, vrf_id);
1.1 misho 1457: break;
1458: case ZEBRA_INTERFACE_DELETE:
1.1.1.4 ! misho 1459: zread_interface_delete (client, length, vrf_id);
1.1 misho 1460: break;
1461: case ZEBRA_IPV4_ROUTE_ADD:
1.1.1.4 ! misho 1462: zread_ipv4_add (client, length, vrf_id);
1.1 misho 1463: break;
1464: case ZEBRA_IPV4_ROUTE_DELETE:
1.1.1.4 ! misho 1465: zread_ipv4_delete (client, length, vrf_id);
1.1 misho 1466: break;
1467: #ifdef HAVE_IPV6
1468: case ZEBRA_IPV6_ROUTE_ADD:
1.1.1.4 ! misho 1469: zread_ipv6_add (client, length, vrf_id);
1.1 misho 1470: break;
1471: case ZEBRA_IPV6_ROUTE_DELETE:
1.1.1.4 ! misho 1472: zread_ipv6_delete (client, length, vrf_id);
1.1 misho 1473: break;
1474: #endif /* HAVE_IPV6 */
1475: case ZEBRA_REDISTRIBUTE_ADD:
1.1.1.4 ! misho 1476: zebra_redistribute_add (command, client, length, vrf_id);
1.1 misho 1477: break;
1478: case ZEBRA_REDISTRIBUTE_DELETE:
1.1.1.4 ! misho 1479: zebra_redistribute_delete (command, client, length, vrf_id);
1.1 misho 1480: break;
1481: case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1.1.1.4 ! misho 1482: zebra_redistribute_default_add (command, client, length, vrf_id);
1.1 misho 1483: break;
1484: case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1.1.1.4 ! misho 1485: zebra_redistribute_default_delete (command, client, length, vrf_id);
1.1 misho 1486: break;
1487: case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1.1.1.4 ! misho 1488: zread_ipv4_nexthop_lookup (client, length, vrf_id);
! 1489: break;
! 1490: case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
! 1491: zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
1.1 misho 1492: break;
1493: #ifdef HAVE_IPV6
1494: case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1.1.1.4 ! misho 1495: zread_ipv6_nexthop_lookup (client, length, vrf_id);
1.1 misho 1496: break;
1497: #endif /* HAVE_IPV6 */
1498: case ZEBRA_IPV4_IMPORT_LOOKUP:
1.1.1.4 ! misho 1499: zread_ipv4_import_lookup (client, length, vrf_id);
1.1 misho 1500: break;
1.1.1.2 misho 1501: case ZEBRA_HELLO:
1502: zread_hello (client);
1503: break;
1.1.1.4 ! misho 1504: case ZEBRA_VRF_UNREGISTER:
! 1505: zread_vrf_unregister (client, length, vrf_id);
! 1506: break;
1.1 misho 1507: default:
1508: zlog_info ("Zebra received unknown command %d", command);
1509: break;
1510: }
1511:
1512: if (client->t_suicide)
1513: {
1514: /* No need to wait for thread callback, just kill immediately. */
1515: zebra_client_close(client);
1516: return -1;
1517: }
1518:
1519: stream_reset (client->ibuf);
1520: zebra_event (ZEBRA_READ, sock, client);
1521: return 0;
1522: }
1523:
1524:
1525: /* Accept code of zebra server socket. */
1526: static int
1527: zebra_accept (struct thread *thread)
1528: {
1529: int accept_sock;
1530: int client_sock;
1531: struct sockaddr_in client;
1532: socklen_t len;
1533:
1534: accept_sock = THREAD_FD (thread);
1535:
1536: /* Reregister myself. */
1537: zebra_event (ZEBRA_SERV, accept_sock, NULL);
1538:
1539: len = sizeof (struct sockaddr_in);
1540: client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1541:
1542: if (client_sock < 0)
1543: {
1544: zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
1545: return -1;
1546: }
1547:
1548: /* Make client socket non-blocking. */
1549: set_nonblocking(client_sock);
1550:
1551: /* Create new zebra client. */
1552: zebra_client_create (client_sock);
1553:
1554: return 0;
1555: }
1556:
1557: #ifdef HAVE_TCP_ZEBRA
1558: /* Make zebra's server socket. */
1559: static void
1560: zebra_serv ()
1561: {
1562: int ret;
1563: int accept_sock;
1564: struct sockaddr_in addr;
1565:
1566: accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1567:
1568: if (accept_sock < 0)
1569: {
1570: zlog_warn ("Can't create zserv stream socket: %s",
1571: safe_strerror (errno));
1572: zlog_warn ("zebra can't provice full functionality due to above error");
1573: return;
1574: }
1575:
1.1.1.2 misho 1576: memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1.1 misho 1577: memset (&addr, 0, sizeof (struct sockaddr_in));
1578: addr.sin_family = AF_INET;
1579: addr.sin_port = htons (ZEBRA_PORT);
1580: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1581: addr.sin_len = sizeof (struct sockaddr_in);
1582: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1583: addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1584:
1585: sockopt_reuseaddr (accept_sock);
1586: sockopt_reuseport (accept_sock);
1587:
1588: if ( zserv_privs.change(ZPRIVS_RAISE) )
1589: zlog (NULL, LOG_ERR, "Can't raise privileges");
1590:
1591: ret = bind (accept_sock, (struct sockaddr *)&addr,
1592: sizeof (struct sockaddr_in));
1593: if (ret < 0)
1594: {
1595: zlog_warn ("Can't bind to stream socket: %s",
1596: safe_strerror (errno));
1597: zlog_warn ("zebra can't provice full functionality due to above error");
1598: close (accept_sock); /* Avoid sd leak. */
1599: return;
1600: }
1601:
1602: if ( zserv_privs.change(ZPRIVS_LOWER) )
1603: zlog (NULL, LOG_ERR, "Can't lower privileges");
1604:
1605: ret = listen (accept_sock, 1);
1606: if (ret < 0)
1607: {
1608: zlog_warn ("Can't listen to stream socket: %s",
1609: safe_strerror (errno));
1610: zlog_warn ("zebra can't provice full functionality due to above error");
1611: close (accept_sock); /* Avoid sd leak. */
1612: return;
1613: }
1614:
1615: zebra_event (ZEBRA_SERV, accept_sock, NULL);
1616: }
1.1.1.4 ! misho 1617: #else /* HAVE_TCP_ZEBRA */
1.1 misho 1618:
1619: /* For sockaddr_un. */
1620: #include <sys/un.h>
1621:
1622: /* zebra server UNIX domain socket. */
1623: static void
1624: zebra_serv_un (const char *path)
1625: {
1626: int ret;
1627: int sock, len;
1628: struct sockaddr_un serv;
1629: mode_t old_mask;
1630:
1631: /* First of all, unlink existing socket */
1632: unlink (path);
1633:
1634: /* Set umask */
1635: old_mask = umask (0077);
1636:
1637: /* Make UNIX domain socket. */
1638: sock = socket (AF_UNIX, SOCK_STREAM, 0);
1639: if (sock < 0)
1640: {
1641: zlog_warn ("Can't create zserv unix socket: %s",
1642: safe_strerror (errno));
1643: zlog_warn ("zebra can't provide full functionality due to above error");
1644: return;
1645: }
1646:
1.1.1.2 misho 1647: memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1648:
1.1 misho 1649: /* Make server socket. */
1650: memset (&serv, 0, sizeof (struct sockaddr_un));
1651: serv.sun_family = AF_UNIX;
1652: strncpy (serv.sun_path, path, strlen (path));
1653: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1654: len = serv.sun_len = SUN_LEN(&serv);
1655: #else
1656: len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1657: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
1658:
1659: ret = bind (sock, (struct sockaddr *) &serv, len);
1660: if (ret < 0)
1661: {
1662: zlog_warn ("Can't bind to unix socket %s: %s",
1663: path, safe_strerror (errno));
1664: zlog_warn ("zebra can't provide full functionality due to above error");
1665: close (sock);
1666: return;
1667: }
1668:
1669: ret = listen (sock, 5);
1670: if (ret < 0)
1671: {
1672: zlog_warn ("Can't listen to unix socket %s: %s",
1673: path, safe_strerror (errno));
1674: zlog_warn ("zebra can't provide full functionality due to above error");
1675: close (sock);
1676: return;
1677: }
1678:
1679: umask (old_mask);
1680:
1681: zebra_event (ZEBRA_SERV, sock, NULL);
1682: }
1.1.1.4 ! misho 1683: #endif /* HAVE_TCP_ZEBRA */
! 1684:
1.1 misho 1685:
1686: static void
1687: zebra_event (enum event event, int sock, struct zserv *client)
1688: {
1689: switch (event)
1690: {
1691: case ZEBRA_SERV:
1692: thread_add_read (zebrad.master, zebra_accept, client, sock);
1693: break;
1694: case ZEBRA_READ:
1695: client->t_read =
1696: thread_add_read (zebrad.master, zebra_client_read, client, sock);
1697: break;
1698: case ZEBRA_WRITE:
1699: /**/
1700: break;
1701: }
1702: }
1.1.1.4 ! misho 1703:
1.1 misho 1704: /* Display default rtm_table for all clients. */
1705: DEFUN (show_table,
1706: show_table_cmd,
1707: "show table",
1708: SHOW_STR
1709: "default routing table to use for all clients\n")
1710: {
1711: vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1712: VTY_NEWLINE);
1713: return CMD_SUCCESS;
1714: }
1715:
1716: DEFUN (config_table,
1717: config_table_cmd,
1718: "table TABLENO",
1719: "Configure target kernel routing table\n"
1720: "TABLE integer\n")
1721: {
1722: zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
1723: return CMD_SUCCESS;
1724: }
1725:
1726: DEFUN (ip_forwarding,
1727: ip_forwarding_cmd,
1728: "ip forwarding",
1729: IP_STR
1730: "Turn on IP forwarding")
1731: {
1732: int ret;
1733:
1734: ret = ipforward ();
1735: if (ret == 0)
1736: ret = ipforward_on ();
1737:
1738: if (ret == 0)
1739: {
1740: vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1741: return CMD_WARNING;
1742: }
1743:
1744: return CMD_SUCCESS;
1745: }
1746:
1747: DEFUN (no_ip_forwarding,
1748: no_ip_forwarding_cmd,
1749: "no ip forwarding",
1750: NO_STR
1751: IP_STR
1752: "Turn off IP forwarding")
1753: {
1754: int ret;
1755:
1756: ret = ipforward ();
1757: if (ret != 0)
1758: ret = ipforward_off ();
1759:
1760: if (ret != 0)
1761: {
1762: vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1763: return CMD_WARNING;
1764: }
1765:
1766: return CMD_SUCCESS;
1767: }
1768:
1769: /* This command is for debugging purpose. */
1770: DEFUN (show_zebra_client,
1771: show_zebra_client_cmd,
1772: "show zebra client",
1773: SHOW_STR
1774: "Zebra information"
1775: "Client information")
1776: {
1777: struct listnode *node;
1778: struct zserv *client;
1779:
1780: for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1781: vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1782:
1783: return CMD_SUCCESS;
1784: }
1785:
1786: /* Table configuration write function. */
1787: static int
1788: config_write_table (struct vty *vty)
1789: {
1790: if (zebrad.rtm_table_default)
1791: vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1792: VTY_NEWLINE);
1793: return 0;
1794: }
1795:
1796: /* table node for routing tables. */
1797: static struct cmd_node table_node =
1798: {
1799: TABLE_NODE,
1800: "", /* This node has no interface. */
1801: 1
1802: };
1.1.1.4 ! misho 1803:
1.1 misho 1804: /* Only display ip forwarding is enabled or not. */
1805: DEFUN (show_ip_forwarding,
1806: show_ip_forwarding_cmd,
1807: "show ip forwarding",
1808: SHOW_STR
1809: IP_STR
1810: "IP forwarding status\n")
1811: {
1812: int ret;
1813:
1814: ret = ipforward ();
1815:
1816: if (ret == 0)
1817: vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1818: else
1819: vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1820: return CMD_SUCCESS;
1821: }
1822:
1823: #ifdef HAVE_IPV6
1824: /* Only display ipv6 forwarding is enabled or not. */
1825: DEFUN (show_ipv6_forwarding,
1826: show_ipv6_forwarding_cmd,
1827: "show ipv6 forwarding",
1828: SHOW_STR
1829: "IPv6 information\n"
1830: "Forwarding status\n")
1831: {
1832: int ret;
1833:
1834: ret = ipforward_ipv6 ();
1835:
1836: switch (ret)
1837: {
1838: case -1:
1839: vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1840: break;
1841: case 0:
1842: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1843: break;
1844: case 1:
1845: vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1846: break;
1847: default:
1848: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1849: break;
1850: }
1851: return CMD_SUCCESS;
1852: }
1853:
1854: DEFUN (ipv6_forwarding,
1855: ipv6_forwarding_cmd,
1856: "ipv6 forwarding",
1857: IPV6_STR
1858: "Turn on IPv6 forwarding")
1859: {
1860: int ret;
1861:
1862: ret = ipforward_ipv6 ();
1863: if (ret == 0)
1864: ret = ipforward_ipv6_on ();
1865:
1866: if (ret == 0)
1867: {
1868: vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1869: return CMD_WARNING;
1870: }
1871:
1872: return CMD_SUCCESS;
1873: }
1874:
1875: DEFUN (no_ipv6_forwarding,
1876: no_ipv6_forwarding_cmd,
1877: "no ipv6 forwarding",
1878: NO_STR
1879: IPV6_STR
1880: "Turn off IPv6 forwarding")
1881: {
1882: int ret;
1883:
1884: ret = ipforward_ipv6 ();
1885: if (ret != 0)
1886: ret = ipforward_ipv6_off ();
1887:
1888: if (ret != 0)
1889: {
1890: vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1891: return CMD_WARNING;
1892: }
1893:
1894: return CMD_SUCCESS;
1895: }
1896:
1897: #endif /* HAVE_IPV6 */
1898:
1899: /* IPForwarding configuration write function. */
1900: static int
1901: config_write_forwarding (struct vty *vty)
1902: {
1903: /* FIXME: Find better place for that. */
1904: router_id_write (vty);
1905:
1906: if (ipforward ())
1907: vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
1908: #ifdef HAVE_IPV6
1909: if (ipforward_ipv6 ())
1910: vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
1911: #endif /* HAVE_IPV6 */
1912: vty_out (vty, "!%s", VTY_NEWLINE);
1913: return 0;
1914: }
1915:
1916: /* table node for routing tables. */
1917: static struct cmd_node forwarding_node =
1918: {
1919: FORWARDING_NODE,
1920: "", /* This node has no interface. */
1921: 1
1922: };
1923:
1.1.1.4 ! misho 1924:
1.1 misho 1925: /* Initialisation of zebra and installation of commands. */
1926: void
1927: zebra_init (void)
1928: {
1929: /* Client list init. */
1930: zebrad.client_list = list_new ();
1931:
1932: /* Install configuration write function. */
1933: install_node (&table_node, config_write_table);
1934: install_node (&forwarding_node, config_write_forwarding);
1935:
1936: install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1937: install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1938: install_element (CONFIG_NODE, &ip_forwarding_cmd);
1939: install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1940: install_element (ENABLE_NODE, &show_zebra_client_cmd);
1941:
1942: #ifdef HAVE_NETLINK
1943: install_element (VIEW_NODE, &show_table_cmd);
1944: install_element (ENABLE_NODE, &show_table_cmd);
1945: install_element (CONFIG_NODE, &config_table_cmd);
1946: #endif /* HAVE_NETLINK */
1947:
1948: #ifdef HAVE_IPV6
1949: install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1950: install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1951: install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
1952: install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1953: #endif /* HAVE_IPV6 */
1954:
1955: /* Route-map */
1956: zebra_route_map_init ();
1957: }
1958:
1959: /* Make zebra server socket, wiping any existing one (see bug #403). */
1960: void
1.1.1.2 misho 1961: zebra_zserv_socket_init (char *path)
1.1 misho 1962: {
1963: #ifdef HAVE_TCP_ZEBRA
1964: zebra_serv ();
1965: #else
1.1.1.2 misho 1966: zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
1.1 misho 1967: #endif /* HAVE_TCP_ZEBRA */
1968: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>