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