]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zserv.c
lib, zebra: unify link layer type and hardware address handling
[mirror_frr.git] / zebra / zserv.c
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 #include "nexthop.h"
40 #include "vrf.h"
41
42 #include "zebra/zserv.h"
43 #include "zebra/zebra_ns.h"
44 #include "zebra/zebra_vrf.h"
45 #include "zebra/router-id.h"
46 #include "zebra/redistribute.h"
47 #include "zebra/debug.h"
48 #include "zebra/ipforward.h"
49 #include "zebra/zebra_rnh.h"
50 #include "zebra/rt_netlink.h"
51 #include "zebra/interface.h"
52 #include "zebra/zebra_ptm.h"
53 #include "zebra/rtadv.h"
54
55 /* Event list of zebra. */
56 enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
57
58 static void zebra_event (enum event event, int sock, struct zserv *client);
59
60 extern struct zebra_privs_t zserv_privs;
61
62 static void zebra_client_close (struct zserv *client);
63
64 static int
65 zserv_delayed_close(struct thread *thread)
66 {
67 struct zserv *client = THREAD_ARG(thread);
68
69 client->t_suicide = NULL;
70 zebra_client_close(client);
71 return 0;
72 }
73
74 static int
75 zserv_flush_data(struct thread *thread)
76 {
77 struct zserv *client = THREAD_ARG(thread);
78
79 client->t_write = NULL;
80 if (client->t_suicide)
81 {
82 zebra_client_close(client);
83 return -1;
84 }
85 switch (buffer_flush_available(client->wb, client->sock))
86 {
87 case BUFFER_ERROR:
88 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
89 "closing", __func__, client->sock);
90 zebra_client_close(client);
91 break;
92 case BUFFER_PENDING:
93 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
94 client, client->sock);
95 break;
96 case BUFFER_EMPTY:
97 break;
98 }
99
100 client->last_write_time = quagga_monotime();
101 return 0;
102 }
103
104 int
105 zebra_server_send_message(struct zserv *client)
106 {
107 if (client->t_suicide)
108 return -1;
109
110 stream_set_getp(client->obuf, 0);
111 client->last_write_cmd = stream_getw_from(client->obuf, 6);
112 switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
113 stream_get_endp(client->obuf)))
114 {
115 case BUFFER_ERROR:
116 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
117 __func__, client->sock);
118 /* Schedule a delayed close since many of the functions that call this
119 one do not check the return code. They do not allow for the
120 possibility that an I/O error may have caused the client to be
121 deleted. */
122 client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
123 client, 0);
124 return -1;
125 case BUFFER_EMPTY:
126 THREAD_OFF(client->t_write);
127 break;
128 case BUFFER_PENDING:
129 THREAD_WRITE_ON(zebrad.master, client->t_write,
130 zserv_flush_data, client, client->sock);
131 break;
132 }
133
134 client->last_write_time = quagga_monotime();
135 return 0;
136 }
137
138 void
139 zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
140 {
141 /* length placeholder, caller can update */
142 stream_putw (s, ZEBRA_HEADER_SIZE);
143 stream_putc (s, ZEBRA_HEADER_MARKER);
144 stream_putc (s, ZSERV_VERSION);
145 stream_putw (s, vrf_id);
146 stream_putw (s, cmd);
147 }
148
149 static void
150 zserv_encode_interface (struct stream *s, struct interface *ifp)
151 {
152 /* Interface information. */
153 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
154 stream_putl (s, ifp->ifindex);
155 stream_putc (s, ifp->status);
156 stream_putq (s, ifp->flags);
157 stream_putc (s, ifp->ptm_enable);
158 stream_putc (s, ifp->ptm_status);
159 stream_putl (s, ifp->metric);
160 stream_putl (s, ifp->mtu);
161 stream_putl (s, ifp->mtu6);
162 stream_putl (s, ifp->bandwidth);
163 stream_putl (s, ifp->ll_type);
164 stream_putl (s, ifp->hw_addr_len);
165 if (ifp->hw_addr_len)
166 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
167
168 /* Write packet size. */
169 stream_putw_at (s, 0, stream_get_endp (s));
170 }
171
172 static void
173 zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
174 {
175 /* Interface information. */
176 stream_put (s, zvrf->name, VRF_NAMSIZ);
177
178 /* Write packet size. */
179 stream_putw_at (s, 0, stream_get_endp (s));
180 }
181
182 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
183 /*
184 * This function is called in the following situations:
185 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
186 * from the client.
187 * - at startup, when zebra figures out the available interfaces
188 * - when an interface is added (where support for
189 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
190 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
191 * received)
192 */
193 int
194 zsend_interface_add (struct zserv *client, struct interface *ifp)
195 {
196 struct stream *s;
197
198 s = client->obuf;
199 stream_reset (s);
200
201 zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
202 zserv_encode_interface (s, ifp);
203
204 client->ifadd_cnt++;
205 return zebra_server_send_message(client);
206 }
207
208 /* Interface deletion from zebra daemon. */
209 int
210 zsend_interface_delete (struct zserv *client, struct interface *ifp)
211 {
212 struct stream *s;
213
214 s = client->obuf;
215 stream_reset (s);
216
217 zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
218 zserv_encode_interface (s, ifp);
219
220 client->ifdel_cnt++;
221 return zebra_server_send_message (client);
222 }
223
224 int
225 zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf)
226 {
227 struct stream *s;
228
229 s = client->obuf;
230 stream_reset (s);
231
232 zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id);
233 zserv_encode_vrf (s, zvrf);
234
235 client->vrfadd_cnt++;
236 return zebra_server_send_message(client);
237 }
238
239 /* VRF deletion from zebra daemon. */
240 int
241 zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
242 {
243 struct stream *s;
244
245 s = client->obuf;
246 stream_reset (s);
247
248 zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id);
249 zserv_encode_vrf (s, zvrf);
250
251 client->vrfdel_cnt++;
252 return zebra_server_send_message (client);
253 }
254
255 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
256 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
257 *
258 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
259 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
260 * from the client, after the ZEBRA_INTERFACE_ADD has been
261 * sent from zebra to the client
262 * - redistribute new address info to all clients in the following situations
263 * - at startup, when zebra figures out the available interfaces
264 * - when an interface is added (where support for
265 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
266 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
267 * received)
268 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
269 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
270 * - when an RTM_NEWADDR message is received from the kernel,
271 *
272 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
273 *
274 * zsend_interface_address(DELETE)
275 * ^
276 * |
277 * zebra_interface_address_delete_update
278 * ^ ^ ^
279 * | | if_delete_update
280 * | |
281 * ip_address_uninstall connected_delete_ipv4
282 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
283 * ^ ^
284 * | |
285 * | RTM_NEWADDR on routing/netlink socket
286 * |
287 * vty commands:
288 * "no ip address A.B.C.D/M [label LINE]"
289 * "no ip address A.B.C.D/M secondary"
290 * ["no ipv6 address X:X::X:X/M"]
291 *
292 */
293 int
294 zsend_interface_address (int cmd, struct zserv *client,
295 struct interface *ifp, struct connected *ifc)
296 {
297 int blen;
298 struct stream *s;
299 struct prefix *p;
300
301 s = client->obuf;
302 stream_reset (s);
303
304 zserv_create_header (s, cmd, ifp->vrf_id);
305 stream_putl (s, ifp->ifindex);
306
307 /* Interface address flag. */
308 stream_putc (s, ifc->flags);
309
310 /* Prefix information. */
311 p = ifc->address;
312 stream_putc (s, p->family);
313 blen = prefix_blen (p);
314 stream_put (s, &p->u.prefix, blen);
315
316 /*
317 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
318 * but zebra_interface_address_delete_read() in the gnu version
319 * expects to find it
320 */
321 stream_putc (s, p->prefixlen);
322
323 /* Destination. */
324 p = ifc->destination;
325 if (p)
326 stream_put (s, &p->u.prefix, blen);
327 else
328 stream_put (s, NULL, blen);
329
330 /* Write packet size. */
331 stream_putw_at (s, 0, stream_get_endp (s));
332
333 client->connected_rt_add_cnt++;
334 return zebra_server_send_message(client);
335 }
336
337 static int
338 zsend_interface_nbr_address (int cmd, struct zserv *client,
339 struct interface *ifp, struct nbr_connected *ifc)
340 {
341 int blen;
342 struct stream *s;
343 struct prefix *p;
344
345 s = client->obuf;
346 stream_reset (s);
347
348 zserv_create_header (s, cmd, ifp->vrf_id);
349 stream_putl (s, ifp->ifindex);
350
351 /* Prefix information. */
352 p = ifc->address;
353 stream_putc (s, p->family);
354 blen = prefix_blen (p);
355 stream_put (s, &p->u.prefix, blen);
356
357 /*
358 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
359 * but zebra_interface_address_delete_read() in the gnu version
360 * expects to find it
361 */
362 stream_putc (s, p->prefixlen);
363
364 /* Write packet size. */
365 stream_putw_at (s, 0, stream_get_endp (s));
366
367 return zebra_server_send_message(client);
368 }
369
370 /* Interface address addition. */
371 static void
372 zebra_interface_nbr_address_add_update (struct interface *ifp,
373 struct nbr_connected *ifc)
374 {
375 struct listnode *node, *nnode;
376 struct zserv *client;
377 struct prefix *p;
378
379 if (IS_ZEBRA_DEBUG_EVENT)
380 {
381 char buf[INET6_ADDRSTRLEN];
382
383 p = ifc->address;
384 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
385 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
386 p->prefixlen, ifc->ifp->name);
387 }
388
389 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
390 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc);
391 }
392
393 /* Interface address deletion. */
394 static void
395 zebra_interface_nbr_address_delete_update (struct interface *ifp,
396 struct nbr_connected *ifc)
397 {
398 struct listnode *node, *nnode;
399 struct zserv *client;
400 struct prefix *p;
401
402 if (IS_ZEBRA_DEBUG_EVENT)
403 {
404 char buf[INET6_ADDRSTRLEN];
405
406 p = ifc->address;
407 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
408 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
409 p->prefixlen, ifc->ifp->name);
410 }
411
412 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
413 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
414 }
415
416 /* Send addresses on interface to client */
417 int
418 zsend_interface_addresses (struct zserv *client, struct interface *ifp)
419 {
420 struct listnode *cnode, *cnnode;
421 struct connected *c;
422 struct nbr_connected *nc;
423
424 /* Send interface addresses. */
425 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
426 {
427 if (!CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
428 continue;
429
430 if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
431 ifp, c) < 0)
432 return -1;
433 }
434
435 /* Send interface neighbors. */
436 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
437 {
438 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
439 client, ifp, nc) < 0)
440 return -1;
441 }
442
443 return 0;
444 }
445
446 /* Notify client about interface moving from one VRF to another.
447 * Whether client is interested in old and new VRF is checked by caller.
448 */
449 int
450 zsend_interface_vrf_update (struct zserv *client, struct interface *ifp,
451 vrf_id_t vrf_id)
452 {
453 struct stream *s;
454
455 s = client->obuf;
456 stream_reset (s);
457
458 zserv_create_header (s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
459
460 /* Fill in the ifIndex of the interface and its new VRF (id) */
461 stream_putl (s, ifp->ifindex);
462 stream_putw (s, vrf_id);
463
464 /* Write packet size. */
465 stream_putw_at (s, 0, stream_get_endp (s));
466
467 client->if_vrfchg_cnt++;
468 return zebra_server_send_message(client);
469 }
470
471 /* Add new nbr connected IPv6 address */
472 void
473 nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address)
474 {
475 struct nbr_connected *ifc;
476 struct prefix p;
477
478 p.family = AF_INET6;
479 IPV6_ADDR_COPY (&p.u.prefix, address);
480 p.prefixlen = IPV6_MAX_PREFIXLEN;
481
482 if (!(ifc = listnode_head(ifp->nbr_connected)))
483 {
484 /* new addition */
485 ifc = nbr_connected_new ();
486 ifc->address = prefix_new();
487 ifc->ifp = ifp;
488 listnode_add (ifp->nbr_connected, ifc);
489 }
490
491 prefix_copy(ifc->address, &p);
492
493 zebra_interface_nbr_address_add_update (ifp, ifc);
494
495 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
496 }
497
498 void
499 nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address)
500 {
501 struct nbr_connected *ifc;
502 struct prefix p;
503
504 p.family = AF_INET6;
505 IPV6_ADDR_COPY (&p.u.prefix, address);
506 p.prefixlen = IPV6_MAX_PREFIXLEN;
507
508 ifc = nbr_connected_check(ifp, &p);
509 if (!ifc)
510 return;
511
512 listnode_delete (ifp->nbr_connected, ifc);
513
514 zebra_interface_nbr_address_delete_update (ifp, ifc);
515
516 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);
517
518 nbr_connected_free (ifc);
519 }
520
521 /*
522 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
523 * ZEBRA_INTERFACE_DOWN.
524 *
525 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
526 * the clients in one of 2 situations:
527 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
528 * - a vty command modifying the bandwidth of an interface is received.
529 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
530 */
531 int
532 zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
533 {
534 struct stream *s;
535
536 s = client->obuf;
537 stream_reset (s);
538
539 zserv_create_header (s, cmd, ifp->vrf_id);
540 zserv_encode_interface (s, ifp);
541
542 if (cmd == ZEBRA_INTERFACE_UP)
543 client->ifup_cnt++;
544 else
545 client->ifdown_cnt++;
546
547 return zebra_server_send_message(client);
548 }
549
550 /*
551 * This is the new function to announce and withdraw redistributed routes, used
552 * by Zebra. This is the old zsend_route_multipath() function. That function
553 * was duplicating code to send a lot of information that was essentially thrown
554 * away or ignored by the receiver. This is the leaner function that is not a
555 * duplicate of the zapi_ipv4_route_add/del.
556 *
557 * The primary difference is that this function merely sends a single NH instead of
558 * all the nexthops.
559 */
560 int
561 zsend_redistribute_route (int cmd, struct zserv *client, struct prefix *p,
562 struct rib *rib)
563 {
564 int psize;
565 struct stream *s;
566 struct nexthop *nexthop;
567 unsigned long nhnummark = 0, messmark = 0;
568 int nhnum = 0;
569 u_char zapi_flags = 0;
570 struct nexthop dummy_nh;
571
572 /* Came from VRF lib patch, is this really needed? callers of this routine
573 do check for redist.., so may be its not needed.
574 Check this client need this route.
575 if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
576 rib->vrf_id) &&
577 !(is_default (p) &&
578 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
579 return 0;
580 */
581
582 s = client->obuf;
583 stream_reset (s);
584 memset(&dummy_nh, 0, sizeof(struct nexthop));
585
586 zserv_create_header (s, cmd, rib->vrf_id);
587
588 /* Put type and nexthop. */
589 stream_putc (s, rib->type);
590 stream_putw (s, rib->instance);
591 stream_putc (s, rib->flags);
592
593 /* marker for message flags field */
594 messmark = stream_get_endp (s);
595 stream_putc (s, 0);
596
597 /* Prefix. */
598 psize = PSIZE (p->prefixlen);
599 stream_putc (s, p->prefixlen);
600 stream_write (s, (u_char *) & p->u.prefix, psize);
601
602 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
603 {
604 /* We don't send any nexthops when there's a multipath */
605 if (rib->nexthop_active_num > 1)
606 {
607 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
608 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
609
610 stream_putc(s, 1);
611 if (p->family == AF_INET)
612 {
613 stream_put_in_addr (s, &dummy_nh.gate.ipv4);
614 }
615 else if (p->family == AF_INET6)
616 {
617 stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16);
618 }
619 else
620 {
621 /* We don't handle anything else now, abort */
622 zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
623 __func__, p->family);
624 return -1;
625 }
626 stream_putc (s, 1);
627 stream_putl (s, 0); /* dummy ifindex */
628 break;
629 }
630
631 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
632 || nexthop_has_fib_child(nexthop))
633 {
634 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
635 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
636 if (nhnummark == 0)
637 {
638 nhnummark = stream_get_endp (s);
639 stream_putc (s, 1); /* placeholder */
640 }
641 nhnum++;
642
643 switch(nexthop->type)
644 {
645 case NEXTHOP_TYPE_IPV4:
646 case NEXTHOP_TYPE_IPV4_IFINDEX:
647 stream_put_in_addr (s, &nexthop->gate.ipv4);
648 break;
649 case NEXTHOP_TYPE_IPV6:
650 case NEXTHOP_TYPE_IPV6_IFINDEX:
651 /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
652 if (p->family == AF_INET)
653 stream_put_in_addr(s, &dummy_nh.gate.ipv4);
654 else
655 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
656 break;
657 default:
658 if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD
659 || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL)
660 {
661 struct in_addr empty;
662 memset (&empty, 0, sizeof (struct in_addr));
663 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
664 }
665 else
666 {
667 struct in6_addr empty;
668 memset (&empty, 0, sizeof (struct in6_addr));
669 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
670 }
671 }
672
673 /* Interface index. */
674 stream_putc (s, 1);
675 stream_putl (s, nexthop->ifindex);
676
677 break;
678 }
679 }
680
681 /* Metric */
682 if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
683 {
684 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
685 stream_putc (s, rib->distance);
686 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
687 stream_putl (s, rib->metric);
688
689 /* tag */
690 if (rib->tag)
691 {
692 SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
693 stream_putw(s, rib->tag);
694 }
695 SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
696 stream_putl (s, rib->mtu);
697 }
698
699 /* write real message flags value */
700 stream_putc_at (s, messmark, zapi_flags);
701
702 /* Write next-hop number */
703 if (nhnummark)
704 stream_putc_at (s, nhnummark, nhnum);
705
706 /* Write packet size. */
707 stream_putw_at (s, 0, stream_get_endp (s));
708
709 return zebra_server_send_message(client);
710 }
711
712 static int
713 zsend_nexthop_lookup (struct zserv *client, afi_t afi, safi_t safi,
714 vrf_id_t vrf_id, union g_addr *addr)
715 {
716 struct stream *s;
717 struct rib *rib;
718 unsigned long nump;
719 u_char num;
720 struct nexthop *nexthop;
721
722 /* Lookup nexthop. */
723 rib = rib_match (afi, safi, vrf_id, addr, NULL);
724
725 /* Get output stream. */
726 s = client->obuf;
727 stream_reset (s);
728
729 /* Fill in result. */
730 if (afi == AFI_IP)
731 {
732 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
733 stream_put_in_addr (s, &addr->ipv4);
734 }
735 else
736 {
737 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
738 stream_put (s, &addr->ipv6, 16);
739 }
740
741 if (rib)
742 {
743 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
744 zlog_debug("%s: Matching rib entry found.", __func__);
745 stream_putl (s, rib->metric);
746 num = 0;
747 nump = stream_get_endp(s);
748 stream_putc (s, 0);
749 /* Only non-recursive routes are elegible to resolve nexthop we
750 * are looking up. Therefore, we will just iterate over the top
751 * chain of nexthops. */
752 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
753 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
754 {
755 stream_putc (s, nexthop->type);
756 switch (nexthop->type)
757 {
758 case NEXTHOP_TYPE_IPV4:
759 stream_put_in_addr (s, &nexthop->gate.ipv4);
760 break;
761 case NEXTHOP_TYPE_IPV4_IFINDEX:
762 stream_put_in_addr (s, &nexthop->gate.ipv4);
763 stream_putl (s, nexthop->ifindex);
764 break;
765 case NEXTHOP_TYPE_IPV6:
766 stream_put (s, &nexthop->gate.ipv6, 16);
767 break;
768 case NEXTHOP_TYPE_IPV6_IFINDEX:
769 stream_put (s, &nexthop->gate.ipv6, 16);
770 stream_putl (s, nexthop->ifindex);
771 break;
772 case NEXTHOP_TYPE_IFINDEX:
773 stream_putl (s, nexthop->ifindex);
774 break;
775 default:
776 /* do nothing */
777 break;
778 }
779 num++;
780 }
781 stream_putc_at (s, nump, num);
782 }
783 else
784 {
785 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
786 zlog_debug("%s: No matching rib entry found.", __func__);
787 stream_putl (s, 0);
788 stream_putc (s, 0);
789 }
790
791 stream_putw_at (s, 0, stream_get_endp (s));
792
793 return zebra_server_send_message(client);
794 }
795
796 /* Nexthop register */
797 static int
798 zserv_rnh_register (struct zserv *client, int sock, u_short length,
799 rnh_type_t type, struct zebra_vrf *zvrf)
800 {
801 struct rnh *rnh;
802 struct stream *s;
803 struct prefix p;
804 u_short l = 0;
805 u_char flags = 0;
806
807 if (IS_ZEBRA_DEBUG_NHT)
808 zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
809 zebra_route_string(client->proto), length,
810 (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route");
811
812 s = client->ibuf;
813
814 client->nh_reg_time = quagga_monotime();
815
816 while (l < length)
817 {
818 flags = stream_getc(s);
819 p.family = stream_getw(s);
820 p.prefixlen = stream_getc(s);
821 l += 4;
822 if (p.family == AF_INET)
823 {
824 p.u.prefix4.s_addr = stream_get_ipv4(s);
825 l += IPV4_MAX_BYTELEN;
826 }
827 else if (p.family == AF_INET6)
828 {
829 stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
830 l += IPV6_MAX_BYTELEN;
831 }
832 else
833 {
834 zlog_err("rnh_register: Received unknown family type %d\n",
835 p.family);
836 return -1;
837 }
838 rnh = zebra_add_rnh(&p, zvrf->vrf_id, type);
839 if (type == RNH_NEXTHOP_TYPE)
840 {
841 if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
842 SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
843 else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
844 UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
845 }
846 else if (type == RNH_IMPORT_CHECK_TYPE)
847 {
848 if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
849 SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
850 else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
851 UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
852 }
853
854 zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id);
855 /* Anything not AF_INET/INET6 has been filtered out above */
856 zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p);
857 }
858 return 0;
859 }
860
861 /* Nexthop register */
862 static int
863 zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
864 rnh_type_t type, struct zebra_vrf *zvrf)
865 {
866 struct rnh *rnh;
867 struct stream *s;
868 struct prefix p;
869 u_short l = 0;
870
871 if (IS_ZEBRA_DEBUG_NHT)
872 zlog_debug("rnh_unregister msg from client %s: length=%d\n",
873 zebra_route_string(client->proto), length);
874
875 s = client->ibuf;
876
877 while (l < length)
878 {
879 (void)stream_getc(s); //Connected or not. Not used in this function
880 p.family = stream_getw(s);
881 p.prefixlen = stream_getc(s);
882 l += 4;
883 if (p.family == AF_INET)
884 {
885 p.u.prefix4.s_addr = stream_get_ipv4(s);
886 l += IPV4_MAX_BYTELEN;
887 }
888 else if (p.family == AF_INET6)
889 {
890 stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
891 l += IPV6_MAX_BYTELEN;
892 }
893 else
894 {
895 zlog_err("rnh_register: Received unknown family type %d\n",
896 p.family);
897 return -1;
898 }
899 rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type);
900 if (rnh)
901 {
902 client->nh_dereg_time = quagga_monotime();
903 zebra_remove_rnh_client(rnh, client, type);
904 }
905 }
906 return 0;
907 }
908
909 /*
910 Modified version of zsend_ipv4_nexthop_lookup():
911 Query unicast rib if nexthop is not found on mrib.
912 Returns both route metric and protocol distance.
913 */
914 static int
915 zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct rib *rib, struct zebra_vrf *zvrf)
916 {
917 struct stream *s;
918 unsigned long nump;
919 u_char num;
920 struct nexthop *nexthop;
921
922 /* Get output stream. */
923 s = client->obuf;
924 stream_reset (s);
925
926 /* Fill in result. */
927 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id);
928 stream_put_in_addr (s, &addr);
929
930 if (rib)
931 {
932 stream_putc (s, rib->distance);
933 stream_putl (s, rib->metric);
934 num = 0;
935 nump = stream_get_endp(s); /* remember position for nexthop_num */
936 stream_putc (s, 0); /* reserve room for nexthop_num */
937 /* Only non-recursive routes are elegible to resolve the nexthop we
938 * are looking up. Therefore, we will just iterate over the top
939 * chain of nexthops. */
940 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
941 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
942 {
943 stream_putc (s, nexthop->type);
944 switch (nexthop->type)
945 {
946 case NEXTHOP_TYPE_IPV4:
947 stream_put_in_addr (s, &nexthop->gate.ipv4);
948 break;
949 case NEXTHOP_TYPE_IPV4_IFINDEX:
950 stream_put_in_addr (s, &nexthop->gate.ipv4);
951 stream_putl (s, nexthop->ifindex);
952 break;
953 case NEXTHOP_TYPE_IFINDEX:
954 stream_putl (s, nexthop->ifindex);
955 break;
956 default:
957 /* do nothing */
958 break;
959 }
960 num++;
961 }
962
963 stream_putc_at (s, nump, num); /* store nexthop_num */
964 }
965 else
966 {
967 stream_putc (s, 0); /* distance */
968 stream_putl (s, 0); /* metric */
969 stream_putc (s, 0); /* nexthop_num */
970 }
971
972 stream_putw_at (s, 0, stream_get_endp (s));
973
974 return zebra_server_send_message(client);
975 }
976
977 static int
978 zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
979 vrf_id_t vrf_id)
980 {
981 struct stream *s;
982 struct rib *rib;
983 unsigned long nump;
984 u_char num;
985 struct nexthop *nexthop;
986
987 /* Lookup nexthop. */
988 rib = rib_lookup_ipv4 (p, vrf_id);
989
990 /* Get output stream. */
991 s = client->obuf;
992 stream_reset (s);
993
994 /* Fill in result. */
995 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
996 stream_put_in_addr (s, &p->prefix);
997
998 if (rib)
999 {
1000 stream_putl (s, rib->metric);
1001 num = 0;
1002 nump = stream_get_endp(s);
1003 stream_putc (s, 0);
1004 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1005 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
1006 || nexthop_has_fib_child(nexthop))
1007 {
1008 stream_putc (s, nexthop->type);
1009 switch (nexthop->type)
1010 {
1011 case NEXTHOP_TYPE_IPV4:
1012 stream_put_in_addr (s, &nexthop->gate.ipv4);
1013 break;
1014 case NEXTHOP_TYPE_IPV4_IFINDEX:
1015 stream_put_in_addr (s, &nexthop->gate.ipv4);
1016 stream_putl (s, nexthop->ifindex);
1017 break;
1018 case NEXTHOP_TYPE_IFINDEX:
1019 stream_putl (s, nexthop->ifindex);
1020 break;
1021 default:
1022 /* do nothing */
1023 break;
1024 }
1025 num++;
1026 }
1027 stream_putc_at (s, nump, num);
1028 }
1029 else
1030 {
1031 stream_putl (s, 0);
1032 stream_putc (s, 0);
1033 }
1034
1035 stream_putw_at (s, 0, stream_get_endp (s));
1036
1037 return zebra_server_send_message(client);
1038 }
1039
1040 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
1041 int
1042 zsend_router_id_update (struct zserv *client, struct prefix *p,
1043 vrf_id_t vrf_id)
1044 {
1045 struct stream *s;
1046 int blen;
1047
1048 /* Check this client need interface information. */
1049 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
1050 return 0;
1051
1052 s = client->obuf;
1053 stream_reset (s);
1054
1055 /* Message type. */
1056 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
1057
1058 /* Prefix information. */
1059 stream_putc (s, p->family);
1060 blen = prefix_blen (p);
1061 stream_put (s, &p->u.prefix, blen);
1062 stream_putc (s, p->prefixlen);
1063
1064 /* Write packet size. */
1065 stream_putw_at (s, 0, stream_get_endp (s));
1066
1067 return zebra_server_send_message(client);
1068 }
1069
1070 /* Register zebra server interface information. Send current all
1071 interface and address information. */
1072 static int
1073 zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1074 {
1075 struct listnode *ifnode, *ifnnode;
1076 vrf_iter_t iter;
1077 struct interface *ifp;
1078 struct zebra_vrf *zvrf_iter;
1079
1080 /* Interface information is needed. */
1081 vrf_bitmap_set (client->ifinfo, zvrf->vrf_id);
1082
1083 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1084 {
1085 zvrf_iter = vrf_iter2info (iter);
1086 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp))
1087 {
1088 /* Skip pseudo interface. */
1089 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1090 continue;
1091
1092 if (zsend_interface_add (client, ifp) < 0)
1093 return -1;
1094
1095 if (zsend_interface_addresses (client, ifp) < 0)
1096 return -1;
1097 }
1098 }
1099 return 0;
1100 }
1101
1102 /* Unregister zebra server interface information. */
1103 static int
1104 zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1105 {
1106 vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
1107 return 0;
1108 }
1109
1110 void
1111 zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num)
1112 {
1113 if (nexthop_num > MULTIPATH_NUM)
1114 {
1115 char buff[PREFIX2STR_BUFFER];
1116 prefix2str(p, buff, sizeof (buff));
1117 zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
1118 caller, buff, nexthop_num, MULTIPATH_NUM);
1119 }
1120 }
1121
1122 /* This function support multiple nexthop. */
1123 /*
1124 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
1125 * add kernel route.
1126 */
1127 static int
1128 zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1129 {
1130 int i;
1131 struct rib *rib;
1132 struct prefix p;
1133 u_char message;
1134 struct in_addr nexthop;
1135 u_char nexthop_num;
1136 u_char nexthop_type;
1137 struct stream *s;
1138 ifindex_t ifindex;
1139 safi_t safi;
1140 int ret;
1141
1142 /* Get input stream. */
1143 s = client->ibuf;
1144
1145 /* Allocate new rib. */
1146 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1147
1148 /* Type, flags, message. */
1149 rib->type = stream_getc (s);
1150 rib->instance = stream_getw (s);
1151 rib->flags = stream_getc (s);
1152 message = stream_getc (s);
1153 safi = stream_getw (s);
1154 rib->uptime = time (NULL);
1155
1156 /* IPv4 prefix. */
1157 memset (&p, 0, sizeof (struct prefix_ipv4));
1158 p.family = AF_INET;
1159 p.prefixlen = stream_getc (s);
1160 stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
1161
1162 /* VRF ID */
1163 rib->vrf_id = zvrf->vrf_id;
1164
1165 /* Nexthop parse. */
1166 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1167 {
1168 nexthop_num = stream_getc (s);
1169 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
1170
1171 for (i = 0; i < nexthop_num; i++)
1172 {
1173 nexthop_type = stream_getc (s);
1174
1175 switch (nexthop_type)
1176 {
1177 case NEXTHOP_TYPE_IFINDEX:
1178 ifindex = stream_getl (s);
1179 rib_nexthop_ifindex_add (rib, ifindex);
1180 break;
1181 case NEXTHOP_TYPE_IPV4:
1182 nexthop.s_addr = stream_get_ipv4 (s);
1183 rib_nexthop_ipv4_add (rib, &nexthop, NULL);
1184 break;
1185 case NEXTHOP_TYPE_IPV4_IFINDEX:
1186 nexthop.s_addr = stream_get_ipv4 (s);
1187 ifindex = stream_getl (s);
1188 rib_nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
1189 break;
1190 case NEXTHOP_TYPE_IPV6:
1191 stream_forward_getp (s, IPV6_MAX_BYTELEN);
1192 break;
1193 case NEXTHOP_TYPE_BLACKHOLE:
1194 rib_nexthop_blackhole_add (rib);
1195 break;
1196 }
1197 }
1198 }
1199
1200 /* Distance. */
1201 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1202 rib->distance = stream_getc (s);
1203
1204 /* Metric. */
1205 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1206 rib->metric = stream_getl (s);
1207
1208 /* Tag */
1209 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1210 rib->tag = stream_getw (s);
1211 else
1212 rib->tag = 0;
1213
1214 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
1215 rib->mtu = stream_getl (s);
1216 else
1217 rib->mtu = 0;
1218
1219 /* Table */
1220 rib->table = zvrf->table_id;
1221
1222 ret = rib_add_multipath (AFI_IP, safi, &p, rib);
1223
1224 /* Stats */
1225 if (ret > 0)
1226 client->v4_route_add_cnt++;
1227 else if (ret < 0)
1228 client->v4_route_upd8_cnt++;
1229 return 0;
1230 }
1231
1232 /* Zebra server IPv4 prefix delete function. */
1233 static int
1234 zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1235 {
1236 int i;
1237 struct stream *s;
1238 struct zapi_ipv4 api;
1239 struct in_addr nexthop;
1240 union g_addr *nexthop_p;
1241 unsigned long ifindex;
1242 struct prefix p;
1243 u_char nexthop_num;
1244 u_char nexthop_type;
1245 u_int32_t table_id;
1246
1247 s = client->ibuf;
1248 ifindex = 0;
1249 nexthop.s_addr = 0;
1250 nexthop_p = NULL;
1251
1252 /* Type, flags, message. */
1253 api.type = stream_getc (s);
1254 api.instance = stream_getw (s);
1255 api.flags = stream_getc (s);
1256 api.message = stream_getc (s);
1257 api.safi = stream_getw (s);
1258
1259 /* IPv4 prefix. */
1260 memset (&p, 0, sizeof (struct prefix_ipv4));
1261 p.family = AF_INET;
1262 p.prefixlen = stream_getc (s);
1263 stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
1264
1265 /* Nexthop, ifindex, distance, metric. */
1266 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1267 {
1268 nexthop_num = stream_getc (s);
1269
1270 for (i = 0; i < nexthop_num; i++)
1271 {
1272 nexthop_type = stream_getc (s);
1273
1274 switch (nexthop_type)
1275 {
1276 case NEXTHOP_TYPE_IFINDEX:
1277 ifindex = stream_getl (s);
1278 break;
1279 case NEXTHOP_TYPE_IPV4:
1280 nexthop.s_addr = stream_get_ipv4 (s);
1281 nexthop_p = (union g_addr *)&nexthop;
1282 break;
1283 case NEXTHOP_TYPE_IPV4_IFINDEX:
1284 nexthop.s_addr = stream_get_ipv4 (s);
1285 nexthop_p = (union g_addr *)&nexthop;
1286 ifindex = stream_getl (s);
1287 break;
1288 case NEXTHOP_TYPE_IPV6:
1289 stream_forward_getp (s, IPV6_MAX_BYTELEN);
1290 break;
1291 }
1292 }
1293 }
1294
1295 /* Distance. */
1296 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1297 api.distance = stream_getc (s);
1298 else
1299 api.distance = 0;
1300
1301 /* Metric. */
1302 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1303 api.metric = stream_getl (s);
1304 else
1305 api.metric = 0;
1306
1307 /* tag */
1308 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1309 api.tag = stream_getw (s);
1310 else
1311 api.tag = 0;
1312
1313 table_id = zvrf->table_id;
1314
1315 rib_delete (AFI_IP, api.safi, zvrf->vrf_id, api.type, api.instance,
1316 api.flags, &p, nexthop_p, ifindex, table_id);
1317 client->v4_route_del_cnt++;
1318 return 0;
1319 }
1320
1321 /* Nexthop lookup for IPv4. */
1322 static int
1323 zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
1324 struct zebra_vrf *zvrf)
1325 {
1326 struct in_addr addr;
1327 char buf[BUFSIZ];
1328
1329 addr.s_addr = stream_get_ipv4 (client->ibuf);
1330 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1331 zlog_debug("%s: looking up %s", __func__,
1332 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
1333 return zsend_nexthop_lookup (client, AFI_IP, SAFI_UNICAST,
1334 zvrf->vrf_id, (union g_addr *)&addr);
1335 }
1336
1337 /* MRIB Nexthop lookup for IPv4. */
1338 static int
1339 zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1340 {
1341 struct in_addr addr;
1342 struct rib *rib;
1343
1344 addr.s_addr = stream_get_ipv4 (client->ibuf);
1345 rib = rib_match_ipv4_multicast (addr, NULL);
1346 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf);
1347 }
1348
1349 /* Nexthop lookup for IPv4. */
1350 static int
1351 zread_ipv4_import_lookup (struct zserv *client, u_short length,
1352 struct zebra_vrf *zvrf)
1353 {
1354 struct prefix_ipv4 p;
1355
1356 p.family = AF_INET;
1357 p.prefixlen = stream_getc (client->ibuf);
1358 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1359
1360 return zsend_ipv4_import_lookup (client, &p, zvrf->vrf_id);
1361 }
1362
1363 /* Zebra server IPv6 prefix add function. */
1364 static int
1365 zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1366 {
1367 int i;
1368 struct stream *s;
1369 struct in6_addr nexthop;
1370 struct rib *rib;
1371 u_char message;
1372 u_char nexthop_num;
1373 u_char nexthop_type;
1374 struct prefix p;
1375 safi_t safi;
1376 static struct in6_addr nexthops[MULTIPATH_NUM];
1377 static unsigned int ifindices[MULTIPATH_NUM];
1378 int ret;
1379
1380 /* Get input stream. */
1381 s = client->ibuf;
1382
1383 memset (&nexthop, 0, sizeof (struct in6_addr));
1384
1385 /* Allocate new rib. */
1386 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1387
1388 /* Type, flags, message. */
1389 rib->type = stream_getc (s);
1390 rib->instance = stream_getw (s);
1391 rib->flags = stream_getc (s);
1392 message = stream_getc (s);
1393 safi = stream_getw (s);
1394 rib->uptime = time (NULL);
1395
1396 /* IPv4 prefix. */
1397 memset (&p, 0, sizeof (struct prefix_ipv4));
1398 p.family = AF_INET;
1399 p.prefixlen = stream_getc (s);
1400 stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
1401
1402 /* VRF ID */
1403 rib->vrf_id = zvrf->vrf_id;
1404
1405 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1406 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1407 * these. Clients should send the same number of paired set of
1408 * next-hop-addr/next-hop-ifindices. */
1409 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1410 {
1411 int nh_count = 0;
1412 int if_count = 0;
1413 int max_nh_if = 0;
1414
1415 nexthop_num = stream_getc (s);
1416 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
1417 for (i = 0; i < nexthop_num; i++)
1418 {
1419 nexthop_type = stream_getc (s);
1420
1421 switch (nexthop_type)
1422 {
1423 case NEXTHOP_TYPE_IPV6:
1424 stream_get (&nexthop, s, 16);
1425 if (nh_count < MULTIPATH_NUM) {
1426 nexthops[nh_count++] = nexthop;
1427 }
1428 break;
1429 case NEXTHOP_TYPE_IFINDEX:
1430 if (if_count < MULTIPATH_NUM) {
1431 ifindices[if_count++] = stream_getl (s);
1432 }
1433 break;
1434 case NEXTHOP_TYPE_BLACKHOLE:
1435 rib_nexthop_blackhole_add (rib);
1436 break;
1437 }
1438 }
1439
1440 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1441 for (i = 0; i < max_nh_if; i++)
1442 {
1443 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
1444 if ((i < if_count) && ifindices[i]) {
1445 rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
1446 }
1447 else {
1448 rib_nexthop_ipv6_add (rib, &nexthops[i]);
1449 }
1450 }
1451 else {
1452 if ((i < if_count) && ifindices[i]) {
1453 rib_nexthop_ifindex_add (rib, ifindices[i]);
1454 }
1455 }
1456 }
1457 }
1458
1459 /* Distance. */
1460 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1461 rib->distance = stream_getc (s);
1462
1463 /* Metric. */
1464 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1465 rib->metric = stream_getl (s);
1466
1467 /* Tag */
1468 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1469 rib->tag = stream_getw (s);
1470 else
1471 rib->tag = 0;
1472
1473 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
1474 rib->mtu = stream_getl (s);
1475 else
1476 rib->mtu = 0;
1477
1478 /* Table */
1479 rib->table = zvrf->table_id;
1480
1481 ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
1482 /* Stats */
1483 if (ret > 0)
1484 client->v4_route_add_cnt++;
1485 else if (ret < 0)
1486 client->v4_route_upd8_cnt++;
1487
1488 return 0;
1489 }
1490
1491 static int
1492 zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1493 {
1494 int i;
1495 struct stream *s;
1496 struct in6_addr nexthop;
1497 struct rib *rib;
1498 u_char message;
1499 u_char nexthop_num;
1500 u_char nexthop_type;
1501 struct prefix p;
1502 safi_t safi;
1503 static struct in6_addr nexthops[MULTIPATH_NUM];
1504 static unsigned int ifindices[MULTIPATH_NUM];
1505 int ret;
1506
1507 /* Get input stream. */
1508 s = client->ibuf;
1509
1510 memset (&nexthop, 0, sizeof (struct in6_addr));
1511
1512 /* Allocate new rib. */
1513 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1514
1515 /* Type, flags, message. */
1516 rib->type = stream_getc (s);
1517 rib->instance = stream_getw (s);
1518 rib->flags = stream_getc (s);
1519 message = stream_getc (s);
1520 safi = stream_getw (s);
1521 rib->uptime = time (NULL);
1522
1523 /* IPv6 prefix. */
1524 memset (&p, 0, sizeof (struct prefix_ipv6));
1525 p.family = AF_INET6;
1526 p.prefixlen = stream_getc (s);
1527 stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
1528
1529 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1530 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1531 * these. Clients should send the same number of paired set of
1532 * next-hop-addr/next-hop-ifindices. */
1533 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1534 {
1535 int nh_count = 0;
1536 int if_count = 0;
1537 int max_nh_if = 0;
1538
1539 nexthop_num = stream_getc (s);
1540 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
1541 for (i = 0; i < nexthop_num; i++)
1542 {
1543 nexthop_type = stream_getc (s);
1544
1545 switch (nexthop_type)
1546 {
1547 case NEXTHOP_TYPE_IPV6:
1548 stream_get (&nexthop, s, 16);
1549 if (nh_count < MULTIPATH_NUM) {
1550 nexthops[nh_count++] = nexthop;
1551 }
1552 break;
1553 case NEXTHOP_TYPE_IFINDEX:
1554 if (if_count < MULTIPATH_NUM) {
1555 ifindices[if_count++] = stream_getl (s);
1556 }
1557 break;
1558 case NEXTHOP_TYPE_BLACKHOLE:
1559 rib_nexthop_blackhole_add (rib);
1560 break;
1561 }
1562 }
1563
1564 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1565 for (i = 0; i < max_nh_if; i++)
1566 {
1567 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
1568 if ((i < if_count) && ifindices[i])
1569 rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
1570 else
1571 rib_nexthop_ipv6_add (rib, &nexthops[i]);
1572 }
1573 else {
1574 if ((i < if_count) && ifindices[i])
1575 rib_nexthop_ifindex_add (rib, ifindices[i]);
1576 }
1577 }
1578 }
1579
1580 /* Distance. */
1581 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1582 rib->distance = stream_getc (s);
1583
1584 /* Metric. */
1585 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1586 rib->metric = stream_getl (s);
1587
1588 /* Tag */
1589 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1590 rib->tag = stream_getw (s);
1591 else
1592 rib->tag = 0;
1593
1594 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
1595 rib->mtu = stream_getl (s);
1596 else
1597 rib->mtu = 0;
1598
1599 /* VRF ID */
1600 rib->vrf_id = zvrf->vrf_id;
1601 rib->table = zvrf->table_id;
1602
1603 ret = rib_add_multipath (AFI_IP, safi, &p, rib);
1604 /* Stats */
1605 if (ret > 0)
1606 client->v6_route_add_cnt++;
1607 else if (ret < 0)
1608 client->v6_route_upd8_cnt++;
1609
1610 return 0;
1611 }
1612
1613 /* Zebra server IPv6 prefix delete function. */
1614 static int
1615 zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1616 {
1617 int i;
1618 struct stream *s;
1619 struct zapi_ipv6 api;
1620 struct in6_addr nexthop;
1621 union g_addr *pnexthop;
1622 unsigned long ifindex;
1623 struct prefix p;
1624
1625 s = client->ibuf;
1626 ifindex = 0;
1627 memset (&nexthop, 0, sizeof (struct in6_addr));
1628
1629 /* Type, flags, message. */
1630 api.type = stream_getc (s);
1631 api.instance = stream_getw (s);
1632 api.flags = stream_getc (s);
1633 api.message = stream_getc (s);
1634 api.safi = stream_getw (s);
1635
1636 /* IPv4 prefix. */
1637 memset (&p, 0, sizeof (struct prefix_ipv6));
1638 p.family = AF_INET6;
1639 p.prefixlen = stream_getc (s);
1640 stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
1641
1642 /* Nexthop, ifindex, distance, metric. */
1643 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1644 {
1645 u_char nexthop_type;
1646
1647 api.nexthop_num = stream_getc (s);
1648 for (i = 0; i < api.nexthop_num; i++)
1649 {
1650 nexthop_type = stream_getc (s);
1651
1652 switch (nexthop_type)
1653 {
1654 case NEXTHOP_TYPE_IPV6:
1655 stream_get (&nexthop, s, 16);
1656 pnexthop = (union g_addr *)&nexthop;
1657 break;
1658 case NEXTHOP_TYPE_IFINDEX:
1659 ifindex = stream_getl (s);
1660 break;
1661 }
1662 }
1663 }
1664
1665 /* Distance. */
1666 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1667 api.distance = stream_getc (s);
1668 else
1669 api.distance = 0;
1670
1671 /* Metric. */
1672 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1673 api.metric = stream_getl (s);
1674 else
1675 api.metric = 0;
1676
1677 /* tag */
1678 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1679 api.tag = stream_getw (s);
1680 else
1681 api.tag = 0;
1682
1683 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1684 rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
1685 api.flags, &p, NULL, ifindex, client->rtm_table);
1686 else
1687 rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
1688 api.flags, &p, pnexthop, ifindex, client->rtm_table);
1689
1690 client->v6_route_del_cnt++;
1691 return 0;
1692 }
1693
1694 static int
1695 zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1696 struct zebra_vrf *zvrf)
1697 {
1698 struct in6_addr addr;
1699 char buf[BUFSIZ];
1700
1701 stream_get (&addr, client->ibuf, 16);
1702 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1703 zlog_debug("%s: looking up %s", __func__,
1704 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1705
1706 return zsend_nexthop_lookup (client, AFI_IP6, SAFI_UNICAST,
1707 zvrf->vrf_id, (union g_addr *)&addr);
1708 }
1709
1710 /* Register zebra server router-id information. Send current router-id */
1711 static int
1712 zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1713 {
1714 struct prefix p;
1715
1716 /* Router-id information is needed. */
1717 vrf_bitmap_set (client->ridinfo, zvrf->vrf_id);
1718
1719 router_id_get (&p, zvrf->vrf_id);
1720
1721 return zsend_router_id_update (client, &p, zvrf->vrf_id);
1722 }
1723
1724 /* Unregister zebra server router-id information. */
1725 static int
1726 zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1727 {
1728 vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
1729 return 0;
1730 }
1731
1732 /* Tie up route-type and client->sock */
1733 static void
1734 zread_hello (struct zserv *client)
1735 {
1736 /* type of protocol (lib/zebra.h) */
1737 u_char proto;
1738 u_short instance;
1739
1740 proto = stream_getc (client->ibuf);
1741 instance = stream_getw (client->ibuf);
1742
1743 /* accept only dynamic routing protocols */
1744 if ((proto < ZEBRA_ROUTE_MAX)
1745 && (proto > ZEBRA_ROUTE_STATIC))
1746 {
1747 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1748 client->sock, zebra_route_string(proto));
1749 if (instance)
1750 zlog_notice ("client protocol instance %d", instance);
1751
1752 client->proto = proto;
1753 client->instance = instance;
1754 }
1755 }
1756
1757 /* Unregister all information in a VRF. */
1758 static int
1759 zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
1760 {
1761 int i;
1762 afi_t afi;
1763
1764 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1765 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1766 vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id);
1767 vrf_bitmap_unset (client->redist_default, zvrf->vrf_id);
1768 vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
1769 vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
1770
1771 return 0;
1772 }
1773
1774 /* Cleanup registered nexthops (across VRFs) upon client disconnect. */
1775 static void
1776 zebra_client_close_cleanup_rnh (struct zserv *client)
1777 {
1778 vrf_iter_t iter;
1779 struct zebra_vrf *zvrf;
1780
1781 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1782 {
1783 if ((zvrf = vrf_iter2info (iter)) != NULL)
1784 {
1785 zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE);
1786 zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE);
1787 zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
1788 zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
1789 }
1790 }
1791 }
1792
1793 /* Close zebra client. */
1794 static void
1795 zebra_client_close (struct zserv *client)
1796 {
1797 /* Send client de-registration to BFD */
1798 zebra_ptm_bfd_client_deregister(client->proto);
1799
1800 /* Cleanup any registered nexthops - across all VRFs. */
1801 zebra_client_close_cleanup_rnh (client);
1802
1803 /* Close file descriptor. */
1804 if (client->sock)
1805 {
1806 unsigned long nroutes;
1807
1808 close (client->sock);
1809 nroutes = rib_score_proto (client->proto, client->instance);
1810 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1811 client->sock, nroutes, zebra_route_string (client->proto));
1812 client->sock = -1;
1813 }
1814
1815 /* Free stream buffers. */
1816 if (client->ibuf)
1817 stream_free (client->ibuf);
1818 if (client->obuf)
1819 stream_free (client->obuf);
1820 if (client->wb)
1821 buffer_free(client->wb);
1822
1823 /* Release threads. */
1824 if (client->t_read)
1825 thread_cancel (client->t_read);
1826 if (client->t_write)
1827 thread_cancel (client->t_write);
1828 if (client->t_suicide)
1829 thread_cancel (client->t_suicide);
1830
1831 /* Free client structure. */
1832 listnode_delete (zebrad.client_list, client);
1833 XFREE (MTYPE_TMP, client);
1834 }
1835
1836 /* Make new client. */
1837 static void
1838 zebra_client_create (int sock)
1839 {
1840 struct zserv *client;
1841 int i;
1842 afi_t afi;
1843
1844 client = XCALLOC (MTYPE_TMP, sizeof (struct zserv));
1845
1846 /* Make client input/output buffer. */
1847 client->sock = sock;
1848 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1849 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1850 client->wb = buffer_new(0);
1851
1852 /* Set table number. */
1853 client->rtm_table = zebrad.rtm_table_default;
1854
1855 client->connect_time = quagga_monotime();
1856 /* Initialize flags */
1857 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1858 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1859 client->redist[afi][i] = vrf_bitmap_init ();
1860 client->redist_default = vrf_bitmap_init ();
1861 client->ifinfo = vrf_bitmap_init ();
1862 client->ridinfo = vrf_bitmap_init ();
1863
1864 /* Add this client to linked list. */
1865 listnode_add (zebrad.client_list, client);
1866
1867 /* Make new read thread. */
1868 zebra_event (ZEBRA_READ, sock, client);
1869
1870 zebra_vrf_update_all (client);
1871 }
1872
1873 /* Handler of zebra service request. */
1874 static int
1875 zebra_client_read (struct thread *thread)
1876 {
1877 int sock;
1878 struct zserv *client;
1879 size_t already;
1880 uint16_t length, command;
1881 uint8_t marker, version;
1882 vrf_id_t vrf_id;
1883 struct zebra_vrf *zvrf;
1884
1885 /* Get thread data. Reset reading thread because I'm running. */
1886 sock = THREAD_FD (thread);
1887 client = THREAD_ARG (thread);
1888 client->t_read = NULL;
1889
1890 if (client->t_suicide)
1891 {
1892 zebra_client_close(client);
1893 return -1;
1894 }
1895
1896 /* Read length and command (if we don't have it already). */
1897 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
1898 {
1899 ssize_t nbyte;
1900 if (((nbyte = stream_read_try (client->ibuf, sock,
1901 ZEBRA_HEADER_SIZE-already)) == 0) ||
1902 (nbyte == -1))
1903 {
1904 if (IS_ZEBRA_DEBUG_EVENT)
1905 zlog_debug ("connection closed socket [%d]", sock);
1906 zebra_client_close (client);
1907 return -1;
1908 }
1909 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1910 {
1911 /* Try again later. */
1912 zebra_event (ZEBRA_READ, sock, client);
1913 return 0;
1914 }
1915 already = ZEBRA_HEADER_SIZE;
1916 }
1917
1918 /* Reset to read from the beginning of the incoming packet. */
1919 stream_set_getp(client->ibuf, 0);
1920
1921 /* Fetch header values */
1922 length = stream_getw (client->ibuf);
1923 marker = stream_getc (client->ibuf);
1924 version = stream_getc (client->ibuf);
1925 vrf_id = stream_getw (client->ibuf);
1926 command = stream_getw (client->ibuf);
1927
1928 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1929 {
1930 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1931 __func__, sock, marker, version);
1932 zebra_client_close (client);
1933 return -1;
1934 }
1935 if (length < ZEBRA_HEADER_SIZE)
1936 {
1937 zlog_warn("%s: socket %d message length %u is less than header size %d",
1938 __func__, sock, length, ZEBRA_HEADER_SIZE);
1939 zebra_client_close (client);
1940 return -1;
1941 }
1942 if (length > STREAM_SIZE(client->ibuf))
1943 {
1944 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1945 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
1946 zebra_client_close (client);
1947 return -1;
1948 }
1949
1950 /* Read rest of data. */
1951 if (already < length)
1952 {
1953 ssize_t nbyte;
1954 if (((nbyte = stream_read_try (client->ibuf, sock,
1955 length-already)) == 0) ||
1956 (nbyte == -1))
1957 {
1958 if (IS_ZEBRA_DEBUG_EVENT)
1959 zlog_debug ("connection closed [%d] when reading zebra data", sock);
1960 zebra_client_close (client);
1961 return -1;
1962 }
1963 if (nbyte != (ssize_t)(length-already))
1964 {
1965 /* Try again later. */
1966 zebra_event (ZEBRA_READ, sock, client);
1967 return 0;
1968 }
1969 }
1970
1971 length -= ZEBRA_HEADER_SIZE;
1972
1973 /* Debug packet information. */
1974 if (IS_ZEBRA_DEBUG_EVENT)
1975 zlog_debug ("zebra message comes from socket [%d]", sock);
1976
1977 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1978 zlog_debug ("zebra message received [%s] %d in VRF %u",
1979 zserv_command_string (command), length, vrf_id);
1980
1981 client->last_read_time = quagga_monotime();
1982 client->last_read_cmd = command;
1983
1984 zvrf = zebra_vrf_lookup (vrf_id);
1985 if (!zvrf)
1986 {
1987 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1988 zlog_debug ("zebra received unknown VRF[%u]", vrf_id);
1989 goto zclient_read_out;
1990 }
1991
1992 switch (command)
1993 {
1994 case ZEBRA_ROUTER_ID_ADD:
1995 zread_router_id_add (client, length, zvrf);
1996 break;
1997 case ZEBRA_ROUTER_ID_DELETE:
1998 zread_router_id_delete (client, length, zvrf);
1999 break;
2000 case ZEBRA_INTERFACE_ADD:
2001 zread_interface_add (client, length, zvrf);
2002 break;
2003 case ZEBRA_INTERFACE_DELETE:
2004 zread_interface_delete (client, length, zvrf);
2005 break;
2006 case ZEBRA_IPV4_ROUTE_ADD:
2007 zread_ipv4_add (client, length, zvrf);
2008 break;
2009 case ZEBRA_IPV4_ROUTE_DELETE:
2010 zread_ipv4_delete (client, length, zvrf);
2011 break;
2012 case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
2013 zread_ipv4_route_ipv6_nexthop_add (client, length, zvrf);
2014 break;
2015 case ZEBRA_IPV6_ROUTE_ADD:
2016 zread_ipv6_add (client, length, zvrf);
2017 break;
2018 case ZEBRA_IPV6_ROUTE_DELETE:
2019 zread_ipv6_delete (client, length, zvrf);
2020 break;
2021 case ZEBRA_REDISTRIBUTE_ADD:
2022 zebra_redistribute_add (command, client, length, zvrf);
2023 break;
2024 case ZEBRA_REDISTRIBUTE_DELETE:
2025 zebra_redistribute_delete (command, client, length, zvrf);
2026 break;
2027 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
2028 zebra_redistribute_default_add (command, client, length, zvrf);
2029 break;
2030 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
2031 zebra_redistribute_default_delete (command, client, length, zvrf);
2032 break;
2033 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
2034 zread_ipv4_nexthop_lookup (client, length, zvrf);
2035 break;
2036 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
2037 zread_ipv4_nexthop_lookup_mrib (client, length, zvrf);
2038 break;
2039 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
2040 zread_ipv6_nexthop_lookup (client, length, zvrf);
2041 break;
2042 case ZEBRA_IPV4_IMPORT_LOOKUP:
2043 zread_ipv4_import_lookup (client, length, zvrf);
2044 break;
2045 case ZEBRA_HELLO:
2046 zread_hello (client);
2047 break;
2048 case ZEBRA_NEXTHOP_REGISTER:
2049 zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, zvrf);
2050 break;
2051 case ZEBRA_NEXTHOP_UNREGISTER:
2052 zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, zvrf);
2053 break;
2054 case ZEBRA_IMPORT_ROUTE_REGISTER:
2055 zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf);
2056 break;
2057 case ZEBRA_IMPORT_ROUTE_UNREGISTER:
2058 zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf);
2059 break;
2060 case ZEBRA_BFD_DEST_UPDATE:
2061 case ZEBRA_BFD_DEST_REGISTER:
2062 zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf);
2063 break;
2064 case ZEBRA_BFD_DEST_DEREGISTER:
2065 zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf);
2066 break;
2067 case ZEBRA_VRF_UNREGISTER:
2068 zread_vrf_unregister (client, length, zvrf);
2069 break;
2070 case ZEBRA_BFD_CLIENT_REGISTER:
2071 zebra_ptm_bfd_client_register(client, sock, length);
2072 break;
2073 case ZEBRA_INTERFACE_ENABLE_RADV:
2074 zebra_interface_radv_set (client, sock, length, zvrf, 1);
2075 break;
2076 case ZEBRA_INTERFACE_DISABLE_RADV:
2077 zebra_interface_radv_set (client, sock, length, zvrf, 0);
2078 break;
2079 default:
2080 zlog_info ("Zebra received unknown command %d", command);
2081 break;
2082 }
2083
2084 if (client->t_suicide)
2085 {
2086 /* No need to wait for thread callback, just kill immediately. */
2087 zebra_client_close(client);
2088 return -1;
2089 }
2090
2091 zclient_read_out:
2092 stream_reset (client->ibuf);
2093 zebra_event (ZEBRA_READ, sock, client);
2094 return 0;
2095 }
2096
2097
2098 /* Accept code of zebra server socket. */
2099 static int
2100 zebra_accept (struct thread *thread)
2101 {
2102 int accept_sock;
2103 int client_sock;
2104 struct sockaddr_in client;
2105 socklen_t len;
2106
2107 accept_sock = THREAD_FD (thread);
2108
2109 /* Reregister myself. */
2110 zebra_event (ZEBRA_SERV, accept_sock, NULL);
2111
2112 len = sizeof (struct sockaddr_in);
2113 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
2114
2115 if (client_sock < 0)
2116 {
2117 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
2118 return -1;
2119 }
2120
2121 /* Make client socket non-blocking. */
2122 set_nonblocking(client_sock);
2123
2124 /* Create new zebra client. */
2125 zebra_client_create (client_sock);
2126
2127 return 0;
2128 }
2129
2130 #ifdef HAVE_TCP_ZEBRA
2131 /* Make zebra's server socket. */
2132 static void
2133 zebra_serv ()
2134 {
2135 int ret;
2136 int accept_sock;
2137 struct sockaddr_in addr;
2138
2139 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
2140
2141 if (accept_sock < 0)
2142 {
2143 zlog_warn ("Can't create zserv stream socket: %s",
2144 safe_strerror (errno));
2145 zlog_warn ("zebra can't provice full functionality due to above error");
2146 return;
2147 }
2148
2149 memset (&addr, 0, sizeof (struct sockaddr_in));
2150 addr.sin_family = AF_INET;
2151 addr.sin_port = htons (ZEBRA_PORT);
2152 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2153 addr.sin_len = sizeof (struct sockaddr_in);
2154 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
2155 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
2156
2157 sockopt_reuseaddr (accept_sock);
2158 sockopt_reuseport (accept_sock);
2159
2160 if ( zserv_privs.change(ZPRIVS_RAISE) )
2161 zlog (NULL, LOG_ERR, "Can't raise privileges");
2162
2163 ret = bind (accept_sock, (struct sockaddr *)&addr,
2164 sizeof (struct sockaddr_in));
2165 if (ret < 0)
2166 {
2167 zlog_warn ("Can't bind to stream socket: %s",
2168 safe_strerror (errno));
2169 zlog_warn ("zebra can't provice full functionality due to above error");
2170 close (accept_sock); /* Avoid sd leak. */
2171 return;
2172 }
2173
2174 if ( zserv_privs.change(ZPRIVS_LOWER) )
2175 zlog (NULL, LOG_ERR, "Can't lower privileges");
2176
2177 ret = listen (accept_sock, 1);
2178 if (ret < 0)
2179 {
2180 zlog_warn ("Can't listen to stream socket: %s",
2181 safe_strerror (errno));
2182 zlog_warn ("zebra can't provice full functionality due to above error");
2183 close (accept_sock); /* Avoid sd leak. */
2184 return;
2185 }
2186
2187 zebra_event (ZEBRA_SERV, accept_sock, NULL);
2188 }
2189 #else /* HAVE_TCP_ZEBRA */
2190
2191 /* For sockaddr_un. */
2192 #include <sys/un.h>
2193
2194 /* zebra server UNIX domain socket. */
2195 static void
2196 zebra_serv_un (const char *path)
2197 {
2198 int ret;
2199 int sock, len;
2200 struct sockaddr_un serv;
2201 mode_t old_mask;
2202
2203 /* First of all, unlink existing socket */
2204 unlink (path);
2205
2206 /* Set umask */
2207 old_mask = umask (0077);
2208
2209 /* Make UNIX domain socket. */
2210 sock = socket (AF_UNIX, SOCK_STREAM, 0);
2211 if (sock < 0)
2212 {
2213 zlog_warn ("Can't create zserv unix socket: %s",
2214 safe_strerror (errno));
2215 zlog_warn ("zebra can't provide full functionality due to above error");
2216 return;
2217 }
2218
2219 /* Make server socket. */
2220 memset (&serv, 0, sizeof (struct sockaddr_un));
2221 serv.sun_family = AF_UNIX;
2222 strncpy (serv.sun_path, path, strlen (path));
2223 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2224 len = serv.sun_len = SUN_LEN(&serv);
2225 #else
2226 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
2227 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2228
2229 ret = bind (sock, (struct sockaddr *) &serv, len);
2230 if (ret < 0)
2231 {
2232 zlog_warn ("Can't bind to unix socket %s: %s",
2233 path, safe_strerror (errno));
2234 zlog_warn ("zebra can't provide full functionality due to above error");
2235 close (sock);
2236 return;
2237 }
2238
2239 ret = listen (sock, 5);
2240 if (ret < 0)
2241 {
2242 zlog_warn ("Can't listen to unix socket %s: %s",
2243 path, safe_strerror (errno));
2244 zlog_warn ("zebra can't provide full functionality due to above error");
2245 close (sock);
2246 return;
2247 }
2248
2249 umask (old_mask);
2250
2251 zebra_event (ZEBRA_SERV, sock, NULL);
2252 }
2253 #endif /* HAVE_TCP_ZEBRA */
2254
2255
2256 static void
2257 zebra_event (enum event event, int sock, struct zserv *client)
2258 {
2259 switch (event)
2260 {
2261 case ZEBRA_SERV:
2262 thread_add_read (zebrad.master, zebra_accept, client, sock);
2263 break;
2264 case ZEBRA_READ:
2265 client->t_read =
2266 thread_add_read (zebrad.master, zebra_client_read, client, sock);
2267 break;
2268 case ZEBRA_WRITE:
2269 /**/
2270 break;
2271 }
2272 }
2273
2274 #define ZEBRA_TIME_BUF 32
2275 static char *
2276 zserv_time_buf(time_t *time1, char *buf, int buflen)
2277 {
2278 struct tm *tm;
2279 time_t now;
2280
2281 assert (buf != NULL);
2282 assert (buflen >= ZEBRA_TIME_BUF);
2283 assert (time1 != NULL);
2284
2285 if (!*time1)
2286 {
2287 snprintf(buf, buflen, "never ");
2288 return (buf);
2289 }
2290
2291 now = quagga_monotime();
2292 now -= *time1;
2293 tm = gmtime(&now);
2294
2295 /* Making formatted timer strings. */
2296 #define ONE_DAY_SECOND 60*60*24
2297 #define ONE_WEEK_SECOND 60*60*24*7
2298
2299 if (now < ONE_DAY_SECOND)
2300 snprintf (buf, buflen, "%02d:%02d:%02d",
2301 tm->tm_hour, tm->tm_min, tm->tm_sec);
2302 else if (now < ONE_WEEK_SECOND)
2303 snprintf (buf, buflen, "%dd%02dh%02dm",
2304 tm->tm_yday, tm->tm_hour, tm->tm_min);
2305 else
2306 snprintf (buf, buflen, "%02dw%dd%02dh",
2307 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
2308 return buf;
2309 }
2310
2311 static void
2312 zebra_show_client_detail (struct vty *vty, struct zserv *client)
2313 {
2314 char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
2315 char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
2316
2317 vty_out (vty, "Client: %s", zebra_route_string(client->proto));
2318 if (client->instance)
2319 vty_out (vty, " Instance: %d", client->instance);
2320 vty_out (vty, "%s", VTY_NEWLINE);
2321
2322 vty_out (vty, "------------------------ %s", VTY_NEWLINE);
2323 vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
2324 vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
2325
2326 vty_out (vty, "Connect Time: %s %s",
2327 zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
2328 VTY_NEWLINE);
2329 if (client->nh_reg_time)
2330 {
2331 vty_out (vty, "Nexthop Registry Time: %s %s",
2332 zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF),
2333 VTY_NEWLINE);
2334 if (client->nh_last_upd_time)
2335 vty_out (vty, "Nexthop Last Update Time: %s %s",
2336 zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF),
2337 VTY_NEWLINE);
2338 else
2339 vty_out (vty, "No Nexthop Update sent%s", VTY_NEWLINE);
2340 }
2341 else
2342 vty_out (vty, "Not registered for Nexthop Updates%s", VTY_NEWLINE);
2343
2344 vty_out (vty, "Last Msg Rx Time: %s %s",
2345 zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
2346 VTY_NEWLINE);
2347 vty_out (vty, "Last Msg Tx Time: %s %s",
2348 zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
2349 VTY_NEWLINE);
2350 if (client->last_read_time)
2351 vty_out (vty, "Last Rcvd Cmd: %s %s",
2352 zserv_command_string(client->last_read_cmd), VTY_NEWLINE);
2353 if (client->last_write_time)
2354 vty_out (vty, "Last Sent Cmd: %s %s",
2355 zserv_command_string(client->last_write_cmd), VTY_NEWLINE);
2356 vty_out (vty, "%s", VTY_NEWLINE);
2357
2358 vty_out (vty, "Type Add Update Del %s", VTY_NEWLINE);
2359 vty_out (vty, "================================================== %s", VTY_NEWLINE);
2360 vty_out (vty, "IPv4 %-12d%-12d%-12d%s", client->v4_route_add_cnt,
2361 client->v4_route_upd8_cnt, client->v4_route_del_cnt, VTY_NEWLINE);
2362 vty_out (vty, "IPv6 %-12d%-12d%-12d%s", client->v6_route_add_cnt,
2363 client->v6_route_upd8_cnt, client->v6_route_del_cnt, VTY_NEWLINE);
2364 vty_out (vty, "Redist:v4 %-12d%-12d%-12d%s", client->redist_v4_add_cnt, 0,
2365 client->redist_v4_del_cnt, VTY_NEWLINE);
2366 vty_out (vty, "Redist:v6 %-12d%-12d%-12d%s", client->redist_v6_add_cnt, 0,
2367 client->redist_v6_del_cnt, VTY_NEWLINE);
2368 vty_out (vty, "Connected %-12d%-12d%-12d%s", client->ifadd_cnt, 0,
2369 client->ifdel_cnt, VTY_NEWLINE);
2370 vty_out (vty, "BFD peer %-12d%-12d%-12d%s", client->bfd_peer_add_cnt,
2371 client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt, VTY_NEWLINE);
2372 vty_out (vty, "Interface Up Notifications: %d%s", client->ifup_cnt,
2373 VTY_NEWLINE);
2374 vty_out (vty, "Interface Down Notifications: %d%s", client->ifdown_cnt,
2375 VTY_NEWLINE);
2376
2377 vty_out (vty, "%s", VTY_NEWLINE);
2378 return;
2379 }
2380
2381 static void
2382 zebra_show_client_brief (struct vty *vty, struct zserv *client)
2383 {
2384 char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
2385 char wbuf[ZEBRA_TIME_BUF];
2386
2387 vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
2388 zebra_route_string(client->proto),
2389 zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
2390 zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
2391 zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
2392 client->v4_route_add_cnt+client->v4_route_upd8_cnt,
2393 client->v4_route_del_cnt,
2394 client->v6_route_add_cnt+client->v6_route_upd8_cnt,
2395 client->v6_route_del_cnt, VTY_NEWLINE);
2396
2397 }
2398
2399
2400 /* Display default rtm_table for all clients. */
2401 DEFUN (show_table,
2402 show_table_cmd,
2403 "show table",
2404 SHOW_STR
2405 "default routing table to use for all clients\n")
2406 {
2407 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
2408 VTY_NEWLINE);
2409 return CMD_SUCCESS;
2410 }
2411
2412 DEFUN (config_table,
2413 config_table_cmd,
2414 "table TABLENO",
2415 "Configure target kernel routing table\n"
2416 "TABLE integer\n")
2417 {
2418 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
2419 return CMD_SUCCESS;
2420 }
2421
2422 DEFUN (no_config_table,
2423 no_config_table_cmd,
2424 "no table TABLENO",
2425 NO_STR
2426 "Configure target kernel routing table\n"
2427 "TABLE integer\n")
2428 {
2429 zebrad.rtm_table_default = 0;
2430 return CMD_SUCCESS;
2431 }
2432
2433 DEFUN (ip_forwarding,
2434 ip_forwarding_cmd,
2435 "ip forwarding",
2436 IP_STR
2437 "Turn on IP forwarding")
2438 {
2439 int ret;
2440
2441 ret = ipforward ();
2442 if (ret == 0)
2443 ret = ipforward_on ();
2444
2445 if (ret == 0)
2446 {
2447 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
2448 return CMD_WARNING;
2449 }
2450
2451 return CMD_SUCCESS;
2452 }
2453
2454 DEFUN (no_ip_forwarding,
2455 no_ip_forwarding_cmd,
2456 "no ip forwarding",
2457 NO_STR
2458 IP_STR
2459 "Turn off IP forwarding")
2460 {
2461 int ret;
2462
2463 ret = ipforward ();
2464 if (ret != 0)
2465 ret = ipforward_off ();
2466
2467 if (ret != 0)
2468 {
2469 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
2470 return CMD_WARNING;
2471 }
2472
2473 return CMD_SUCCESS;
2474 }
2475
2476 /* This command is for debugging purpose. */
2477 DEFUN (show_zebra_client,
2478 show_zebra_client_cmd,
2479 "show zebra client",
2480 SHOW_STR
2481 "Zebra information"
2482 "Client information")
2483 {
2484 struct listnode *node;
2485 struct zserv *client;
2486
2487 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
2488 zebra_show_client_detail(vty, client);
2489
2490 return CMD_SUCCESS;
2491 }
2492
2493 /* This command is for debugging purpose. */
2494 DEFUN (show_zebra_client_summary,
2495 show_zebra_client_summary_cmd,
2496 "show zebra client summary",
2497 SHOW_STR
2498 "Zebra information brief"
2499 "Client information brief")
2500 {
2501 struct listnode *node;
2502 struct zserv *client;
2503
2504 vty_out (vty, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
2505 VTY_NEWLINE);
2506 vty_out (vty,"--------------------------------------------------------------------------------%s",
2507 VTY_NEWLINE);
2508
2509 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
2510 zebra_show_client_brief(vty, client);
2511
2512 vty_out (vty, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE);
2513 return CMD_SUCCESS;
2514 }
2515
2516 /* Table configuration write function. */
2517 static int
2518 config_write_table (struct vty *vty)
2519 {
2520 if (zebrad.rtm_table_default)
2521 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
2522 VTY_NEWLINE);
2523 return 0;
2524 }
2525
2526 /* table node for routing tables. */
2527 static struct cmd_node table_node =
2528 {
2529 TABLE_NODE,
2530 "", /* This node has no interface. */
2531 1
2532 };
2533
2534 /* Only display ip forwarding is enabled or not. */
2535 DEFUN (show_ip_forwarding,
2536 show_ip_forwarding_cmd,
2537 "show ip forwarding",
2538 SHOW_STR
2539 IP_STR
2540 "IP forwarding status\n")
2541 {
2542 int ret;
2543
2544 ret = ipforward ();
2545
2546 if (ret == 0)
2547 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
2548 else
2549 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
2550 return CMD_SUCCESS;
2551 }
2552
2553 #ifdef HAVE_IPV6
2554 /* Only display ipv6 forwarding is enabled or not. */
2555 DEFUN (show_ipv6_forwarding,
2556 show_ipv6_forwarding_cmd,
2557 "show ipv6 forwarding",
2558 SHOW_STR
2559 "IPv6 information\n"
2560 "Forwarding status\n")
2561 {
2562 int ret;
2563
2564 ret = ipforward_ipv6 ();
2565
2566 switch (ret)
2567 {
2568 case -1:
2569 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
2570 break;
2571 case 0:
2572 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2573 break;
2574 case 1:
2575 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
2576 break;
2577 default:
2578 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2579 break;
2580 }
2581 return CMD_SUCCESS;
2582 }
2583
2584 DEFUN (ipv6_forwarding,
2585 ipv6_forwarding_cmd,
2586 "ipv6 forwarding",
2587 IPV6_STR
2588 "Turn on IPv6 forwarding")
2589 {
2590 int ret;
2591
2592 ret = ipforward_ipv6 ();
2593 if (ret == 0)
2594 ret = ipforward_ipv6_on ();
2595
2596 if (ret == 0)
2597 {
2598 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
2599 return CMD_WARNING;
2600 }
2601
2602 return CMD_SUCCESS;
2603 }
2604
2605 DEFUN (no_ipv6_forwarding,
2606 no_ipv6_forwarding_cmd,
2607 "no ipv6 forwarding",
2608 NO_STR
2609 IPV6_STR
2610 "Turn off IPv6 forwarding")
2611 {
2612 int ret;
2613
2614 ret = ipforward_ipv6 ();
2615 if (ret != 0)
2616 ret = ipforward_ipv6_off ();
2617
2618 if (ret != 0)
2619 {
2620 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
2621 return CMD_WARNING;
2622 }
2623
2624 return CMD_SUCCESS;
2625 }
2626
2627 #endif /* HAVE_IPV6 */
2628
2629 /* IPForwarding configuration write function. */
2630 static int
2631 config_write_forwarding (struct vty *vty)
2632 {
2633 /* FIXME: Find better place for that. */
2634 router_id_write (vty);
2635
2636 if (!ipforward ())
2637 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
2638 #ifdef HAVE_IPV6
2639 if (!ipforward_ipv6 ())
2640 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
2641 #endif /* HAVE_IPV6 */
2642 vty_out (vty, "!%s", VTY_NEWLINE);
2643 return 0;
2644 }
2645
2646 /* table node for routing tables. */
2647 static struct cmd_node forwarding_node =
2648 {
2649 FORWARDING_NODE,
2650 "", /* This node has no interface. */
2651 1
2652 };
2653
2654
2655 /* Initialisation of zebra and installation of commands. */
2656 void
2657 zebra_init (void)
2658 {
2659 /* Client list init. */
2660 zebrad.client_list = list_new ();
2661
2662 /* Install configuration write function. */
2663 install_node (&table_node, config_write_table);
2664 install_node (&forwarding_node, config_write_forwarding);
2665
2666 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
2667 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
2668 install_element (CONFIG_NODE, &ip_forwarding_cmd);
2669 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
2670 install_element (ENABLE_NODE, &show_zebra_client_cmd);
2671 install_element (ENABLE_NODE, &show_zebra_client_summary_cmd);
2672
2673 #ifdef HAVE_NETLINK
2674 install_element (VIEW_NODE, &show_table_cmd);
2675 install_element (ENABLE_NODE, &show_table_cmd);
2676 install_element (CONFIG_NODE, &config_table_cmd);
2677 install_element (CONFIG_NODE, &no_config_table_cmd);
2678 #endif /* HAVE_NETLINK */
2679
2680 #ifdef HAVE_IPV6
2681 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
2682 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
2683 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
2684 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2685 #endif /* HAVE_IPV6 */
2686
2687 /* Route-map */
2688 zebra_route_map_init ();
2689 }
2690
2691 /* Make zebra server socket, wiping any existing one (see bug #403). */
2692 void
2693 zebra_zserv_socket_init (char *path)
2694 {
2695 #ifdef HAVE_TCP_ZEBRA
2696 zebra_serv ();
2697 #else
2698 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
2699 #endif /* HAVE_TCP_ZEBRA */
2700 }