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