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