1 /* Zebra daemon server routine.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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.
33 #include "sockunion.h"
42 #include "zebra/zserv.h"
43 #include "zebra/zebra_ns.h"
44 #include "zebra/zebra_vrf.h"
45 #include "zebra/router-id.h"
46 #include "zebra/redistribute.h"
47 #include "zebra/debug.h"
48 #include "zebra/ipforward.h"
49 #include "zebra/zebra_rnh.h"
50 #include "zebra/rt_netlink.h"
51 #include "zebra/interface.h"
52 #include "zebra/zebra_ptm.h"
53 #include "zebra/rtadv.h"
55 /* Event list of zebra. */
56 enum event
{ ZEBRA_SERV
, ZEBRA_READ
, ZEBRA_WRITE
};
58 static void zebra_event (enum event event
, int sock
, struct zserv
*client
);
60 extern struct zebra_privs_t zserv_privs
;
62 static void zebra_client_close (struct zserv
*client
);
65 zserv_delayed_close(struct thread
*thread
)
67 struct zserv
*client
= THREAD_ARG(thread
);
69 client
->t_suicide
= NULL
;
70 zebra_client_close(client
);
75 zserv_flush_data(struct thread
*thread
)
77 struct zserv
*client
= THREAD_ARG(thread
);
79 client
->t_write
= NULL
;
80 if (client
->t_suicide
)
82 zebra_client_close(client
);
85 switch (buffer_flush_available(client
->wb
, client
->sock
))
88 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
89 "closing", __func__
, client
->sock
);
90 zebra_client_close(client
);
93 client
->t_write
= thread_add_write(zebrad
.master
, zserv_flush_data
,
94 client
, client
->sock
);
100 client
->last_write_time
= quagga_monotime();
105 zebra_server_send_message(struct zserv
*client
)
107 if (client
->t_suicide
)
110 stream_set_getp(client
->obuf
, 0);
111 client
->last_write_cmd
= stream_getw_from(client
->obuf
, 6);
112 switch (buffer_write(client
->wb
, client
->sock
, STREAM_DATA(client
->obuf
),
113 stream_get_endp(client
->obuf
)))
116 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
117 __func__
, client
->sock
);
118 /* Schedule a delayed close since many of the functions that call this
119 one do not check the return code. They do not allow for the
120 possibility that an I/O error may have caused the client to be
122 client
->t_suicide
= thread_add_event(zebrad
.master
, zserv_delayed_close
,
126 THREAD_OFF(client
->t_write
);
129 THREAD_WRITE_ON(zebrad
.master
, client
->t_write
,
130 zserv_flush_data
, client
, client
->sock
);
134 client
->last_write_time
= quagga_monotime();
139 zserv_create_header (struct stream
*s
, uint16_t cmd
, vrf_id_t vrf_id
)
141 /* length placeholder, caller can update */
142 stream_putw (s
, ZEBRA_HEADER_SIZE
);
143 stream_putc (s
, ZEBRA_HEADER_MARKER
);
144 stream_putc (s
, ZSERV_VERSION
);
145 stream_putw (s
, vrf_id
);
146 stream_putw (s
, cmd
);
150 zserv_encode_interface (struct stream
*s
, struct interface
*ifp
)
152 /* Interface information. */
153 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
154 stream_putl (s
, ifp
->ifindex
);
155 stream_putc (s
, ifp
->status
);
156 stream_putq (s
, ifp
->flags
);
157 stream_putc (s
, ifp
->ptm_enable
);
158 stream_putc (s
, ifp
->ptm_status
);
159 stream_putl (s
, ifp
->metric
);
160 stream_putl (s
, ifp
->mtu
);
161 stream_putl (s
, ifp
->mtu6
);
162 stream_putl (s
, ifp
->bandwidth
);
163 stream_putl (s
, ifp
->ll_type
);
164 stream_putl (s
, ifp
->hw_addr_len
);
165 if (ifp
->hw_addr_len
)
166 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
168 /* Write packet size. */
169 stream_putw_at (s
, 0, stream_get_endp (s
));
173 zserv_encode_vrf (struct stream
*s
, struct zebra_vrf
*zvrf
)
175 /* Interface information. */
176 stream_put (s
, zvrf
->name
, VRF_NAMSIZ
);
178 /* Write packet size. */
179 stream_putw_at (s
, 0, stream_get_endp (s
));
182 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
184 * This function is called in the following situations:
185 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
187 * - at startup, when zebra figures out the available interfaces
188 * - when an interface is added (where support for
189 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
190 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
194 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
201 zserv_create_header (s
, ZEBRA_INTERFACE_ADD
, ifp
->vrf_id
);
202 zserv_encode_interface (s
, ifp
);
205 return zebra_server_send_message(client
);
208 /* Interface deletion from zebra daemon. */
210 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
217 zserv_create_header (s
, ZEBRA_INTERFACE_DELETE
, ifp
->vrf_id
);
218 zserv_encode_interface (s
, ifp
);
221 return zebra_server_send_message (client
);
225 zsend_vrf_add (struct zserv
*client
, struct zebra_vrf
*zvrf
)
232 zserv_create_header (s
, ZEBRA_VRF_ADD
, zvrf
->vrf_id
);
233 zserv_encode_vrf (s
, zvrf
);
235 client
->vrfadd_cnt
++;
236 return zebra_server_send_message(client
);
239 /* VRF deletion from zebra daemon. */
241 zsend_vrf_delete (struct zserv
*client
, struct zebra_vrf
*zvrf
)
248 zserv_create_header (s
, ZEBRA_VRF_DELETE
, zvrf
->vrf_id
);
249 zserv_encode_vrf (s
, zvrf
);
251 client
->vrfdel_cnt
++;
252 return zebra_server_send_message (client
);
255 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
256 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
258 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
259 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
260 * from the client, after the ZEBRA_INTERFACE_ADD has been
261 * sent from zebra to the client
262 * - redistribute new address info to all clients in the following situations
263 * - at startup, when zebra figures out the available interfaces
264 * - when an interface is added (where support for
265 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
266 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
268 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
269 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
270 * - when an RTM_NEWADDR message is received from the kernel,
272 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
274 * zsend_interface_address(DELETE)
277 * zebra_interface_address_delete_update
279 * | | if_delete_update
281 * ip_address_uninstall connected_delete_ipv4
282 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
285 * | RTM_NEWADDR on routing/netlink socket
288 * "no ip address A.B.C.D/M [label LINE]"
289 * "no ip address A.B.C.D/M secondary"
290 * ["no ipv6 address X:X::X:X/M"]
294 zsend_interface_address (int cmd
, struct zserv
*client
,
295 struct interface
*ifp
, struct connected
*ifc
)
304 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
305 stream_putl (s
, ifp
->ifindex
);
307 /* Interface address flag. */
308 stream_putc (s
, ifc
->flags
);
310 /* Prefix information. */
312 stream_putc (s
, p
->family
);
313 blen
= prefix_blen (p
);
314 stream_put (s
, &p
->u
.prefix
, blen
);
317 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
318 * but zebra_interface_address_delete_read() in the gnu version
321 stream_putc (s
, p
->prefixlen
);
324 p
= ifc
->destination
;
326 stream_put (s
, &p
->u
.prefix
, blen
);
328 stream_put (s
, NULL
, blen
);
330 /* Write packet size. */
331 stream_putw_at (s
, 0, stream_get_endp (s
));
333 client
->connected_rt_add_cnt
++;
334 return zebra_server_send_message(client
);
338 zsend_interface_nbr_address (int cmd
, struct zserv
*client
,
339 struct interface
*ifp
, struct nbr_connected
*ifc
)
348 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
349 stream_putl (s
, ifp
->ifindex
);
351 /* Prefix information. */
353 stream_putc (s
, p
->family
);
354 blen
= prefix_blen (p
);
355 stream_put (s
, &p
->u
.prefix
, blen
);
358 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
359 * but zebra_interface_address_delete_read() in the gnu version
362 stream_putc (s
, p
->prefixlen
);
364 /* Write packet size. */
365 stream_putw_at (s
, 0, stream_get_endp (s
));
367 return zebra_server_send_message(client
);
370 /* Interface address addition. */
372 zebra_interface_nbr_address_add_update (struct interface
*ifp
,
373 struct nbr_connected
*ifc
)
375 struct listnode
*node
, *nnode
;
376 struct zserv
*client
;
379 if (IS_ZEBRA_DEBUG_EVENT
)
381 char buf
[INET6_ADDRSTRLEN
];
384 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
385 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
386 p
->prefixlen
, ifc
->ifp
->name
);
389 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
390 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
, client
, ifp
, ifc
);
393 /* Interface address deletion. */
395 zebra_interface_nbr_address_delete_update (struct interface
*ifp
,
396 struct nbr_connected
*ifc
)
398 struct listnode
*node
, *nnode
;
399 struct zserv
*client
;
402 if (IS_ZEBRA_DEBUG_EVENT
)
404 char buf
[INET6_ADDRSTRLEN
];
407 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
408 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
409 p
->prefixlen
, ifc
->ifp
->name
);
412 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
413 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE
, client
, ifp
, ifc
);
416 /* Send addresses on interface to client */
418 zsend_interface_addresses (struct zserv
*client
, struct interface
*ifp
)
420 struct listnode
*cnode
, *cnnode
;
422 struct nbr_connected
*nc
;
424 /* Send interface addresses. */
425 for (ALL_LIST_ELEMENTS (ifp
->connected
, cnode
, cnnode
, c
))
427 if (!CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
))
430 if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
,
435 /* Send interface neighbors. */
436 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, cnode
, cnnode
, nc
))
438 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
,
439 client
, ifp
, nc
) < 0)
446 /* Notify client about interface moving from one VRF to another.
447 * Whether client is interested in old and new VRF is checked by caller.
450 zsend_interface_vrf_update (struct zserv
*client
, struct interface
*ifp
,
458 zserv_create_header (s
, ZEBRA_INTERFACE_VRF_UPDATE
, ifp
->vrf_id
);
460 /* Fill in the ifIndex of the interface and its new VRF (id) */
461 stream_putl (s
, ifp
->ifindex
);
462 stream_putw (s
, vrf_id
);
464 /* Write packet size. */
465 stream_putw_at (s
, 0, stream_get_endp (s
));
467 client
->if_vrfchg_cnt
++;
468 return zebra_server_send_message(client
);
471 /* Add new nbr connected IPv6 address */
473 nbr_connected_add_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
475 struct nbr_connected
*ifc
;
479 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
480 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
482 if (!(ifc
= listnode_head(ifp
->nbr_connected
)))
485 ifc
= nbr_connected_new ();
486 ifc
->address
= prefix_new();
488 listnode_add (ifp
->nbr_connected
, ifc
);
491 prefix_copy(ifc
->address
, &p
);
493 zebra_interface_nbr_address_add_update (ifp
, ifc
);
495 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 1);
499 nbr_connected_delete_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
501 struct nbr_connected
*ifc
;
505 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
506 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
508 ifc
= nbr_connected_check(ifp
, &p
);
512 listnode_delete (ifp
->nbr_connected
, ifc
);
514 zebra_interface_nbr_address_delete_update (ifp
, ifc
);
516 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 0);
518 nbr_connected_free (ifc
);
522 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
523 * ZEBRA_INTERFACE_DOWN.
525 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
526 * the clients in one of 2 situations:
527 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
528 * - a vty command modifying the bandwidth of an interface is received.
529 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
532 zsend_interface_update (int cmd
, struct zserv
*client
, struct interface
*ifp
)
539 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
540 zserv_encode_interface (s
, ifp
);
542 if (cmd
== ZEBRA_INTERFACE_UP
)
545 client
->ifdown_cnt
++;
547 return zebra_server_send_message(client
);
551 * This is the new function to announce and withdraw redistributed routes, used
552 * by Zebra. This is the old zsend_route_multipath() function. That function
553 * was duplicating code to send a lot of information that was essentially thrown
554 * away or ignored by the receiver. This is the leaner function that is not a
555 * duplicate of the zapi_ipv4_route_add/del.
557 * The primary difference is that this function merely sends a single NH instead of
561 zsend_redistribute_route (int cmd
, struct zserv
*client
, struct prefix
*p
,
566 struct nexthop
*nexthop
;
567 unsigned long nhnummark
= 0, messmark
= 0;
569 u_char zapi_flags
= 0;
570 struct nexthop dummy_nh
;
572 /* Came from VRF lib patch, is this really needed? callers of this routine
573 do check for redist.., so may be its not needed.
574 Check this client need this route.
575 if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
578 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
584 memset(&dummy_nh
, 0, sizeof(struct nexthop
));
586 zserv_create_header (s
, cmd
, rib
->vrf_id
);
588 /* Put type and nexthop. */
589 stream_putc (s
, rib
->type
);
590 stream_putw (s
, rib
->instance
);
591 stream_putc (s
, rib
->flags
);
593 /* marker for message flags field */
594 messmark
= stream_get_endp (s
);
598 psize
= PSIZE (p
->prefixlen
);
599 stream_putc (s
, p
->prefixlen
);
600 stream_write (s
, (u_char
*) & p
->u
.prefix
, psize
);
602 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
604 /* We don't send any nexthops when there's a multipath */
605 if (rib
->nexthop_active_num
> 1)
607 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
608 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
611 if (p
->family
== AF_INET
)
613 stream_put_in_addr (s
, &dummy_nh
.gate
.ipv4
);
615 else if (p
->family
== AF_INET6
)
617 stream_write (s
, (u_char
*) &dummy_nh
.gate
.ipv6
, 16);
621 /* We don't handle anything else now, abort */
622 zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
623 __func__
, p
->family
);
627 stream_putl (s
, 0); /* dummy ifindex */
631 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
632 || nexthop_has_fib_child(nexthop
))
634 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
635 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
638 nhnummark
= stream_get_endp (s
);
639 stream_putc (s
, 1); /* placeholder */
643 switch(nexthop
->type
)
645 case NEXTHOP_TYPE_IPV4
:
646 case NEXTHOP_TYPE_IPV4_IFINDEX
:
647 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
649 case NEXTHOP_TYPE_IPV6
:
650 case NEXTHOP_TYPE_IPV6_IFINDEX
:
651 /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
652 if (p
->family
== AF_INET
)
653 stream_put_in_addr(s
, &dummy_nh
.gate
.ipv4
);
655 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
658 if (cmd
== ZEBRA_REDISTRIBUTE_IPV4_ADD
659 || cmd
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
661 struct in_addr empty
;
662 memset (&empty
, 0, sizeof (struct in_addr
));
663 stream_write (s
, (u_char
*) &empty
, IPV4_MAX_BYTELEN
);
667 struct in6_addr empty
;
668 memset (&empty
, 0, sizeof (struct in6_addr
));
669 stream_write (s
, (u_char
*) &empty
, IPV6_MAX_BYTELEN
);
673 /* Interface index. */
675 stream_putl (s
, nexthop
->ifindex
);
682 if (cmd
== ZEBRA_REDISTRIBUTE_IPV4_ADD
|| cmd
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
684 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_DISTANCE
);
685 stream_putc (s
, rib
->distance
);
686 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_METRIC
);
687 stream_putl (s
, rib
->metric
);
692 SET_FLAG(zapi_flags
, ZAPI_MESSAGE_TAG
);
693 stream_putw(s
, rib
->tag
);
695 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_MTU
);
696 stream_putl (s
, rib
->mtu
);
699 /* write real message flags value */
700 stream_putc_at (s
, messmark
, zapi_flags
);
702 /* Write next-hop number */
704 stream_putc_at (s
, nhnummark
, nhnum
);
706 /* Write packet size. */
707 stream_putw_at (s
, 0, stream_get_endp (s
));
709 return zebra_server_send_message(client
);
713 zsend_nexthop_lookup (struct zserv
*client
, afi_t afi
, safi_t safi
,
714 vrf_id_t vrf_id
, union g_addr
*addr
)
720 struct nexthop
*nexthop
;
722 /* Lookup nexthop. */
723 rib
= rib_match (afi
, safi
, vrf_id
, addr
, NULL
);
725 /* Get output stream. */
729 /* Fill in result. */
732 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
, vrf_id
);
733 stream_put_in_addr (s
, &addr
->ipv4
);
737 zserv_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
, vrf_id
);
738 stream_put (s
, &addr
->ipv6
, 16);
743 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
744 zlog_debug("%s: Matching rib entry found.", __func__
);
745 stream_putl (s
, rib
->metric
);
747 nump
= stream_get_endp(s
);
749 /* Only non-recursive routes are elegible to resolve nexthop we
750 * are looking up. Therefore, we will just iterate over the top
751 * chain of nexthops. */
752 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
753 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
755 stream_putc (s
, nexthop
->type
);
756 switch (nexthop
->type
)
758 case NEXTHOP_TYPE_IPV4
:
759 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
761 case NEXTHOP_TYPE_IPV4_IFINDEX
:
762 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
763 stream_putl (s
, nexthop
->ifindex
);
765 case NEXTHOP_TYPE_IPV6
:
766 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
768 case NEXTHOP_TYPE_IPV6_IFINDEX
:
769 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
770 stream_putl (s
, nexthop
->ifindex
);
772 case NEXTHOP_TYPE_IFINDEX
:
773 stream_putl (s
, nexthop
->ifindex
);
781 stream_putc_at (s
, nump
, num
);
785 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
786 zlog_debug("%s: No matching rib entry found.", __func__
);
791 stream_putw_at (s
, 0, stream_get_endp (s
));
793 return zebra_server_send_message(client
);
796 /* Nexthop register */
798 zserv_rnh_register (struct zserv
*client
, int sock
, u_short length
,
799 rnh_type_t type
, struct zebra_vrf
*zvrf
)
807 if (IS_ZEBRA_DEBUG_NHT
)
808 zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
809 zebra_route_string(client
->proto
), length
,
810 (type
== RNH_NEXTHOP_TYPE
) ? "nexthop" : "route");
814 client
->nh_reg_time
= quagga_monotime();
818 flags
= stream_getc(s
);
819 p
.family
= stream_getw(s
);
820 p
.prefixlen
= stream_getc(s
);
822 if (p
.family
== AF_INET
)
824 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
825 l
+= IPV4_MAX_BYTELEN
;
827 else if (p
.family
== AF_INET6
)
829 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
830 l
+= IPV6_MAX_BYTELEN
;
834 zlog_err("rnh_register: Received unknown family type %d\n",
838 rnh
= zebra_add_rnh(&p
, zvrf
->vrf_id
, type
);
839 if (type
== RNH_NEXTHOP_TYPE
)
841 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
842 SET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
843 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
844 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
846 else if (type
== RNH_IMPORT_CHECK_TYPE
)
848 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
849 SET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
850 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
851 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
854 zebra_add_rnh_client(rnh
, client
, type
, zvrf
->vrf_id
);
855 /* Anything not AF_INET/INET6 has been filtered out above */
856 zebra_evaluate_rnh(zvrf
->vrf_id
, p
.family
, 1, type
, &p
);
861 /* Nexthop register */
863 zserv_rnh_unregister (struct zserv
*client
, int sock
, u_short length
,
864 rnh_type_t type
, struct zebra_vrf
*zvrf
)
871 if (IS_ZEBRA_DEBUG_NHT
)
872 zlog_debug("rnh_unregister msg from client %s: length=%d\n",
873 zebra_route_string(client
->proto
), length
);
879 (void)stream_getc(s
); //Connected or not. Not used in this function
880 p
.family
= stream_getw(s
);
881 p
.prefixlen
= stream_getc(s
);
883 if (p
.family
== AF_INET
)
885 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
886 l
+= IPV4_MAX_BYTELEN
;
888 else if (p
.family
== AF_INET6
)
890 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
891 l
+= IPV6_MAX_BYTELEN
;
895 zlog_err("rnh_register: Received unknown family type %d\n",
899 rnh
= zebra_lookup_rnh(&p
, zvrf
->vrf_id
, type
);
902 client
->nh_dereg_time
= quagga_monotime();
903 zebra_remove_rnh_client(rnh
, client
, type
);
910 Modified version of zsend_ipv4_nexthop_lookup():
911 Query unicast rib if nexthop is not found on mrib.
912 Returns both route metric and protocol distance.
915 zsend_ipv4_nexthop_lookup_mrib (struct zserv
*client
, struct in_addr addr
, struct rib
*rib
, struct zebra_vrf
*zvrf
)
920 struct nexthop
*nexthop
;
922 /* Get output stream. */
926 /* Fill in result. */
927 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
, zvrf
->vrf_id
);
928 stream_put_in_addr (s
, &addr
);
932 stream_putc (s
, rib
->distance
);
933 stream_putl (s
, rib
->metric
);
935 nump
= stream_get_endp(s
); /* remember position for nexthop_num */
936 stream_putc (s
, 0); /* reserve room for nexthop_num */
937 /* Only non-recursive routes are elegible to resolve the nexthop we
938 * are looking up. Therefore, we will just iterate over the top
939 * chain of nexthops. */
940 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
941 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
943 stream_putc (s
, nexthop
->type
);
944 switch (nexthop
->type
)
946 case NEXTHOP_TYPE_IPV4
:
947 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
949 case NEXTHOP_TYPE_IPV4_IFINDEX
:
950 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
951 stream_putl (s
, nexthop
->ifindex
);
953 case NEXTHOP_TYPE_IFINDEX
:
954 stream_putl (s
, nexthop
->ifindex
);
963 stream_putc_at (s
, nump
, num
); /* store nexthop_num */
967 stream_putc (s
, 0); /* distance */
968 stream_putl (s
, 0); /* metric */
969 stream_putc (s
, 0); /* nexthop_num */
972 stream_putw_at (s
, 0, stream_get_endp (s
));
974 return zebra_server_send_message(client
);
978 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
,
985 struct nexthop
*nexthop
;
987 /* Lookup nexthop. */
988 rib
= rib_lookup_ipv4 (p
, vrf_id
);
990 /* Get output stream. */
994 /* Fill in result. */
995 zserv_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
, vrf_id
);
996 stream_put_in_addr (s
, &p
->prefix
);
1000 stream_putl (s
, rib
->metric
);
1002 nump
= stream_get_endp(s
);
1004 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1005 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1006 || nexthop_has_fib_child(nexthop
))
1008 stream_putc (s
, nexthop
->type
);
1009 switch (nexthop
->type
)
1011 case NEXTHOP_TYPE_IPV4
:
1012 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1014 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1015 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1016 stream_putl (s
, nexthop
->ifindex
);
1018 case NEXTHOP_TYPE_IFINDEX
:
1019 stream_putl (s
, nexthop
->ifindex
);
1027 stream_putc_at (s
, nump
, num
);
1035 stream_putw_at (s
, 0, stream_get_endp (s
));
1037 return zebra_server_send_message(client
);
1040 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
1042 zsend_router_id_update (struct zserv
*client
, struct prefix
*p
,
1048 /* Check this client need interface information. */
1049 if (! vrf_bitmap_check (client
->ridinfo
, vrf_id
))
1056 zserv_create_header (s
, ZEBRA_ROUTER_ID_UPDATE
, vrf_id
);
1058 /* Prefix information. */
1059 stream_putc (s
, p
->family
);
1060 blen
= prefix_blen (p
);
1061 stream_put (s
, &p
->u
.prefix
, blen
);
1062 stream_putc (s
, p
->prefixlen
);
1064 /* Write packet size. */
1065 stream_putw_at (s
, 0, stream_get_endp (s
));
1067 return zebra_server_send_message(client
);
1070 /* Register zebra server interface information. Send current all
1071 interface and address information. */
1073 zread_interface_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1075 struct listnode
*ifnode
, *ifnnode
;
1077 struct interface
*ifp
;
1078 struct zebra_vrf
*zvrf_iter
;
1080 /* Interface information is needed. */
1081 vrf_bitmap_set (client
->ifinfo
, zvrf
->vrf_id
);
1083 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
1085 zvrf_iter
= vrf_iter2info (iter
);
1086 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter
->vrf_id
), ifnode
, ifnnode
, ifp
))
1088 /* Skip pseudo interface. */
1089 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1092 if (zsend_interface_add (client
, ifp
) < 0)
1095 if (zsend_interface_addresses (client
, ifp
) < 0)
1102 /* Unregister zebra server interface information. */
1104 zread_interface_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1106 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1111 zserv_nexthop_num_warn (const char *caller
, const struct prefix
*p
, const unsigned int nexthop_num
)
1113 if (nexthop_num
> MULTIPATH_NUM
)
1115 char buff
[PREFIX2STR_BUFFER
];
1116 prefix2str(p
, buff
, sizeof (buff
));
1117 zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
1118 caller
, buff
, nexthop_num
, MULTIPATH_NUM
);
1122 /* This function support multiple nexthop. */
1124 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
1128 zread_ipv4_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1134 struct in_addr nexthop
;
1136 u_char nexthop_type
;
1142 /* Get input stream. */
1145 /* Allocate new rib. */
1146 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1148 /* Type, flags, message. */
1149 rib
->type
= stream_getc (s
);
1150 rib
->instance
= stream_getw (s
);
1151 rib
->flags
= stream_getc (s
);
1152 message
= stream_getc (s
);
1153 safi
= stream_getw (s
);
1154 rib
->uptime
= time (NULL
);
1157 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1159 p
.prefixlen
= stream_getc (s
);
1160 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1163 rib
->vrf_id
= zvrf
->vrf_id
;
1165 /* Nexthop parse. */
1166 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1168 nexthop_num
= stream_getc (s
);
1169 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1171 for (i
= 0; i
< nexthop_num
; i
++)
1173 nexthop_type
= stream_getc (s
);
1175 switch (nexthop_type
)
1177 case NEXTHOP_TYPE_IFINDEX
:
1178 ifindex
= stream_getl (s
);
1179 rib_nexthop_ifindex_add (rib
, ifindex
);
1181 case NEXTHOP_TYPE_IPV4
:
1182 nexthop
.s_addr
= stream_get_ipv4 (s
);
1183 rib_nexthop_ipv4_add (rib
, &nexthop
, NULL
);
1185 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1186 nexthop
.s_addr
= stream_get_ipv4 (s
);
1187 ifindex
= stream_getl (s
);
1188 rib_nexthop_ipv4_ifindex_add (rib
, &nexthop
, NULL
, ifindex
);
1190 case NEXTHOP_TYPE_IPV6
:
1191 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1193 case NEXTHOP_TYPE_BLACKHOLE
:
1194 rib_nexthop_blackhole_add (rib
);
1201 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1202 rib
->distance
= stream_getc (s
);
1205 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1206 rib
->metric
= stream_getl (s
);
1209 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1210 rib
->tag
= stream_getw (s
);
1214 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1215 rib
->mtu
= stream_getl (s
);
1220 rib
->table
= zvrf
->table_id
;
1222 ret
= rib_add_multipath (AFI_IP
, safi
, &p
, rib
);
1226 client
->v4_route_add_cnt
++;
1228 client
->v4_route_upd8_cnt
++;
1232 /* Zebra server IPv4 prefix delete function. */
1234 zread_ipv4_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1238 struct zapi_ipv4 api
;
1239 struct in_addr nexthop
;
1240 union g_addr
*nexthop_p
;
1241 unsigned long ifindex
;
1244 u_char nexthop_type
;
1252 /* Type, flags, message. */
1253 api
.type
= stream_getc (s
);
1254 api
.instance
= stream_getw (s
);
1255 api
.flags
= stream_getc (s
);
1256 api
.message
= stream_getc (s
);
1257 api
.safi
= stream_getw (s
);
1260 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1262 p
.prefixlen
= stream_getc (s
);
1263 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1265 /* Nexthop, ifindex, distance, metric. */
1266 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1268 nexthop_num
= stream_getc (s
);
1270 for (i
= 0; i
< nexthop_num
; i
++)
1272 nexthop_type
= stream_getc (s
);
1274 switch (nexthop_type
)
1276 case NEXTHOP_TYPE_IFINDEX
:
1277 ifindex
= stream_getl (s
);
1279 case NEXTHOP_TYPE_IPV4
:
1280 nexthop
.s_addr
= stream_get_ipv4 (s
);
1281 nexthop_p
= (union g_addr
*)&nexthop
;
1283 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1284 nexthop
.s_addr
= stream_get_ipv4 (s
);
1285 nexthop_p
= (union g_addr
*)&nexthop
;
1286 ifindex
= stream_getl (s
);
1288 case NEXTHOP_TYPE_IPV6
:
1289 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1296 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1297 api
.distance
= stream_getc (s
);
1302 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1303 api
.metric
= stream_getl (s
);
1308 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1309 api
.tag
= stream_getw (s
);
1313 table_id
= zvrf
->table_id
;
1315 rib_delete (AFI_IP
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1316 api
.flags
, &p
, nexthop_p
, ifindex
, table_id
);
1317 client
->v4_route_del_cnt
++;
1321 /* Nexthop lookup for IPv4. */
1323 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
,
1324 struct zebra_vrf
*zvrf
)
1326 struct in_addr addr
;
1329 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1330 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1331 zlog_debug("%s: looking up %s", __func__
,
1332 inet_ntop (AF_INET
, &addr
, buf
, BUFSIZ
));
1333 return zsend_nexthop_lookup (client
, AFI_IP
, SAFI_UNICAST
,
1334 zvrf
->vrf_id
, (union g_addr
*)&addr
);
1337 /* MRIB Nexthop lookup for IPv4. */
1339 zread_ipv4_nexthop_lookup_mrib (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1341 struct in_addr addr
;
1344 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1345 rib
= rib_match_ipv4_multicast (addr
, NULL
);
1346 return zsend_ipv4_nexthop_lookup_mrib (client
, addr
, rib
, zvrf
);
1349 /* Nexthop lookup for IPv4. */
1351 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
,
1352 struct zebra_vrf
*zvrf
)
1354 struct prefix_ipv4 p
;
1357 p
.prefixlen
= stream_getc (client
->ibuf
);
1358 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1360 return zsend_ipv4_import_lookup (client
, &p
, zvrf
->vrf_id
);
1363 /* Zebra server IPv6 prefix add function. */
1365 zread_ipv4_route_ipv6_nexthop_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1369 struct in6_addr nexthop
;
1373 u_char nexthop_type
;
1376 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1377 static unsigned int ifindices
[MULTIPATH_NUM
];
1380 /* Get input stream. */
1383 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1385 /* Allocate new rib. */
1386 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1388 /* Type, flags, message. */
1389 rib
->type
= stream_getc (s
);
1390 rib
->instance
= stream_getw (s
);
1391 rib
->flags
= stream_getc (s
);
1392 message
= stream_getc (s
);
1393 safi
= stream_getw (s
);
1394 rib
->uptime
= time (NULL
);
1397 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1399 p
.prefixlen
= stream_getc (s
);
1400 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1403 rib
->vrf_id
= zvrf
->vrf_id
;
1405 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1406 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1407 * these. Clients should send the same number of paired set of
1408 * next-hop-addr/next-hop-ifindices. */
1409 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1415 nexthop_num
= stream_getc (s
);
1416 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1417 for (i
= 0; i
< nexthop_num
; i
++)
1419 nexthop_type
= stream_getc (s
);
1421 switch (nexthop_type
)
1423 case NEXTHOP_TYPE_IPV6
:
1424 stream_get (&nexthop
, s
, 16);
1425 if (nh_count
< MULTIPATH_NUM
) {
1426 nexthops
[nh_count
++] = nexthop
;
1429 case NEXTHOP_TYPE_IFINDEX
:
1430 if (if_count
< MULTIPATH_NUM
) {
1431 ifindices
[if_count
++] = stream_getl (s
);
1434 case NEXTHOP_TYPE_BLACKHOLE
:
1435 rib_nexthop_blackhole_add (rib
);
1440 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1441 for (i
= 0; i
< max_nh_if
; i
++)
1443 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1444 if ((i
< if_count
) && ifindices
[i
]) {
1445 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1448 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1452 if ((i
< if_count
) && ifindices
[i
]) {
1453 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1460 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1461 rib
->distance
= stream_getc (s
);
1464 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1465 rib
->metric
= stream_getl (s
);
1468 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1469 rib
->tag
= stream_getw (s
);
1473 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1474 rib
->mtu
= stream_getl (s
);
1479 rib
->table
= zvrf
->table_id
;
1481 ret
= rib_add_multipath (AFI_IP6
, safi
, &p
, rib
);
1484 client
->v4_route_add_cnt
++;
1486 client
->v4_route_upd8_cnt
++;
1492 zread_ipv6_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1496 struct in6_addr nexthop
;
1500 u_char nexthop_type
;
1503 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1504 static unsigned int ifindices
[MULTIPATH_NUM
];
1507 /* Get input stream. */
1510 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1512 /* Allocate new rib. */
1513 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1515 /* Type, flags, message. */
1516 rib
->type
= stream_getc (s
);
1517 rib
->instance
= stream_getw (s
);
1518 rib
->flags
= stream_getc (s
);
1519 message
= stream_getc (s
);
1520 safi
= stream_getw (s
);
1521 rib
->uptime
= time (NULL
);
1524 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1525 p
.family
= AF_INET6
;
1526 p
.prefixlen
= stream_getc (s
);
1527 stream_get (&p
.u
.prefix6
, s
, PSIZE (p
.prefixlen
));
1529 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1530 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1531 * these. Clients should send the same number of paired set of
1532 * next-hop-addr/next-hop-ifindices. */
1533 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1539 nexthop_num
= stream_getc (s
);
1540 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1541 for (i
= 0; i
< nexthop_num
; i
++)
1543 nexthop_type
= stream_getc (s
);
1545 switch (nexthop_type
)
1547 case NEXTHOP_TYPE_IPV6
:
1548 stream_get (&nexthop
, s
, 16);
1549 if (nh_count
< MULTIPATH_NUM
) {
1550 nexthops
[nh_count
++] = nexthop
;
1553 case NEXTHOP_TYPE_IFINDEX
:
1554 if (if_count
< MULTIPATH_NUM
) {
1555 ifindices
[if_count
++] = stream_getl (s
);
1558 case NEXTHOP_TYPE_BLACKHOLE
:
1559 rib_nexthop_blackhole_add (rib
);
1564 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1565 for (i
= 0; i
< max_nh_if
; i
++)
1567 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1568 if ((i
< if_count
) && ifindices
[i
])
1569 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1571 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1574 if ((i
< if_count
) && ifindices
[i
])
1575 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1581 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1582 rib
->distance
= stream_getc (s
);
1585 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1586 rib
->metric
= stream_getl (s
);
1589 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1590 rib
->tag
= stream_getw (s
);
1594 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1595 rib
->mtu
= stream_getl (s
);
1600 rib
->vrf_id
= zvrf
->vrf_id
;
1601 rib
->table
= zvrf
->table_id
;
1603 ret
= rib_add_multipath (AFI_IP
, safi
, &p
, rib
);
1606 client
->v6_route_add_cnt
++;
1608 client
->v6_route_upd8_cnt
++;
1613 /* Zebra server IPv6 prefix delete function. */
1615 zread_ipv6_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1619 struct zapi_ipv6 api
;
1620 struct in6_addr nexthop
;
1621 union g_addr
*pnexthop
;
1622 unsigned long ifindex
;
1627 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1629 /* Type, flags, message. */
1630 api
.type
= stream_getc (s
);
1631 api
.instance
= stream_getw (s
);
1632 api
.flags
= stream_getc (s
);
1633 api
.message
= stream_getc (s
);
1634 api
.safi
= stream_getw (s
);
1637 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1638 p
.family
= AF_INET6
;
1639 p
.prefixlen
= stream_getc (s
);
1640 stream_get (&p
.u
.prefix6
, s
, PSIZE (p
.prefixlen
));
1642 /* Nexthop, ifindex, distance, metric. */
1643 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1645 u_char nexthop_type
;
1647 api
.nexthop_num
= stream_getc (s
);
1648 for (i
= 0; i
< api
.nexthop_num
; i
++)
1650 nexthop_type
= stream_getc (s
);
1652 switch (nexthop_type
)
1654 case NEXTHOP_TYPE_IPV6
:
1655 stream_get (&nexthop
, s
, 16);
1656 pnexthop
= (union g_addr
*)&nexthop
;
1658 case NEXTHOP_TYPE_IFINDEX
:
1659 ifindex
= stream_getl (s
);
1666 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1667 api
.distance
= stream_getc (s
);
1672 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1673 api
.metric
= stream_getl (s
);
1678 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1679 api
.tag
= stream_getw (s
);
1683 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1684 rib_delete (AFI_IP6
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1685 api
.flags
, &p
, NULL
, ifindex
, client
->rtm_table
);
1687 rib_delete (AFI_IP6
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1688 api
.flags
, &p
, pnexthop
, ifindex
, client
->rtm_table
);
1690 client
->v6_route_del_cnt
++;
1695 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
,
1696 struct zebra_vrf
*zvrf
)
1698 struct in6_addr addr
;
1701 stream_get (&addr
, client
->ibuf
, 16);
1702 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1703 zlog_debug("%s: looking up %s", __func__
,
1704 inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1706 return zsend_nexthop_lookup (client
, AFI_IP6
, SAFI_UNICAST
,
1707 zvrf
->vrf_id
, (union g_addr
*)&addr
);
1710 /* Register zebra server router-id information. Send current router-id */
1712 zread_router_id_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1716 /* Router-id information is needed. */
1717 vrf_bitmap_set (client
->ridinfo
, zvrf
->vrf_id
);
1719 router_id_get (&p
, zvrf
->vrf_id
);
1721 return zsend_router_id_update (client
, &p
, zvrf
->vrf_id
);
1724 /* Unregister zebra server router-id information. */
1726 zread_router_id_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1728 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1732 /* Tie up route-type and client->sock */
1734 zread_hello (struct zserv
*client
)
1736 /* type of protocol (lib/zebra.h) */
1740 proto
= stream_getc (client
->ibuf
);
1741 instance
= stream_getw (client
->ibuf
);
1743 /* accept only dynamic routing protocols */
1744 if ((proto
< ZEBRA_ROUTE_MAX
)
1745 && (proto
> ZEBRA_ROUTE_STATIC
))
1747 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1748 client
->sock
, zebra_route_string(proto
));
1750 zlog_notice ("client protocol instance %d", instance
);
1752 client
->proto
= proto
;
1753 client
->instance
= instance
;
1757 /* Unregister all information in a VRF. */
1759 zread_vrf_unregister (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1764 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1765 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1766 vrf_bitmap_unset (client
->redist
[afi
][i
], zvrf
->vrf_id
);
1767 vrf_bitmap_unset (client
->redist_default
, zvrf
->vrf_id
);
1768 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1769 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1774 /* Cleanup registered nexthops (across VRFs) upon client disconnect. */
1776 zebra_client_close_cleanup_rnh (struct zserv
*client
)
1779 struct zebra_vrf
*zvrf
;
1781 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
1783 if ((zvrf
= vrf_iter2info (iter
)) != NULL
)
1785 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_NEXTHOP_TYPE
);
1786 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_NEXTHOP_TYPE
);
1787 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_IMPORT_CHECK_TYPE
);
1788 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_IMPORT_CHECK_TYPE
);
1793 /* Close zebra client. */
1795 zebra_client_close (struct zserv
*client
)
1797 /* Send client de-registration to BFD */
1798 zebra_ptm_bfd_client_deregister(client
->proto
);
1800 /* Cleanup any registered nexthops - across all VRFs. */
1801 zebra_client_close_cleanup_rnh (client
);
1803 /* Close file descriptor. */
1806 unsigned long nroutes
;
1808 close (client
->sock
);
1809 nroutes
= rib_score_proto (client
->proto
, client
->instance
);
1810 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1811 client
->sock
, nroutes
, zebra_route_string (client
->proto
));
1815 /* Free stream buffers. */
1817 stream_free (client
->ibuf
);
1819 stream_free (client
->obuf
);
1821 buffer_free(client
->wb
);
1823 /* Release threads. */
1825 thread_cancel (client
->t_read
);
1826 if (client
->t_write
)
1827 thread_cancel (client
->t_write
);
1828 if (client
->t_suicide
)
1829 thread_cancel (client
->t_suicide
);
1831 /* Free client structure. */
1832 listnode_delete (zebrad
.client_list
, client
);
1833 XFREE (MTYPE_TMP
, client
);
1836 /* Make new client. */
1838 zebra_client_create (int sock
)
1840 struct zserv
*client
;
1844 client
= XCALLOC (MTYPE_TMP
, sizeof (struct zserv
));
1846 /* Make client input/output buffer. */
1847 client
->sock
= sock
;
1848 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1849 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1850 client
->wb
= buffer_new(0);
1852 /* Set table number. */
1853 client
->rtm_table
= zebrad
.rtm_table_default
;
1855 client
->connect_time
= quagga_monotime();
1856 /* Initialize flags */
1857 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1858 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1859 client
->redist
[afi
][i
] = vrf_bitmap_init ();
1860 client
->redist_default
= vrf_bitmap_init ();
1861 client
->ifinfo
= vrf_bitmap_init ();
1862 client
->ridinfo
= vrf_bitmap_init ();
1864 /* Add this client to linked list. */
1865 listnode_add (zebrad
.client_list
, client
);
1867 /* Make new read thread. */
1868 zebra_event (ZEBRA_READ
, sock
, client
);
1870 zebra_vrf_update_all (client
);
1873 /* Handler of zebra service request. */
1875 zebra_client_read (struct thread
*thread
)
1878 struct zserv
*client
;
1880 uint16_t length
, command
;
1881 uint8_t marker
, version
;
1883 struct zebra_vrf
*zvrf
;
1885 /* Get thread data. Reset reading thread because I'm running. */
1886 sock
= THREAD_FD (thread
);
1887 client
= THREAD_ARG (thread
);
1888 client
->t_read
= NULL
;
1890 if (client
->t_suicide
)
1892 zebra_client_close(client
);
1896 /* Read length and command (if we don't have it already). */
1897 if ((already
= stream_get_endp(client
->ibuf
)) < ZEBRA_HEADER_SIZE
)
1900 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1901 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
1904 if (IS_ZEBRA_DEBUG_EVENT
)
1905 zlog_debug ("connection closed socket [%d]", sock
);
1906 zebra_client_close (client
);
1909 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
1911 /* Try again later. */
1912 zebra_event (ZEBRA_READ
, sock
, client
);
1915 already
= ZEBRA_HEADER_SIZE
;
1918 /* Reset to read from the beginning of the incoming packet. */
1919 stream_set_getp(client
->ibuf
, 0);
1921 /* Fetch header values */
1922 length
= stream_getw (client
->ibuf
);
1923 marker
= stream_getc (client
->ibuf
);
1924 version
= stream_getc (client
->ibuf
);
1925 vrf_id
= stream_getw (client
->ibuf
);
1926 command
= stream_getw (client
->ibuf
);
1928 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
1930 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1931 __func__
, sock
, marker
, version
);
1932 zebra_client_close (client
);
1935 if (length
< ZEBRA_HEADER_SIZE
)
1937 zlog_warn("%s: socket %d message length %u is less than header size %d",
1938 __func__
, sock
, length
, ZEBRA_HEADER_SIZE
);
1939 zebra_client_close (client
);
1942 if (length
> STREAM_SIZE(client
->ibuf
))
1944 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1945 __func__
, sock
, length
, (u_long
)STREAM_SIZE(client
->ibuf
));
1946 zebra_client_close (client
);
1950 /* Read rest of data. */
1951 if (already
< length
)
1954 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1955 length
-already
)) == 0) ||
1958 if (IS_ZEBRA_DEBUG_EVENT
)
1959 zlog_debug ("connection closed [%d] when reading zebra data", sock
);
1960 zebra_client_close (client
);
1963 if (nbyte
!= (ssize_t
)(length
-already
))
1965 /* Try again later. */
1966 zebra_event (ZEBRA_READ
, sock
, client
);
1971 length
-= ZEBRA_HEADER_SIZE
;
1973 /* Debug packet information. */
1974 if (IS_ZEBRA_DEBUG_EVENT
)
1975 zlog_debug ("zebra message comes from socket [%d]", sock
);
1977 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1978 zlog_debug ("zebra message received [%s] %d in VRF %u",
1979 zserv_command_string (command
), length
, vrf_id
);
1981 client
->last_read_time
= quagga_monotime();
1982 client
->last_read_cmd
= command
;
1984 zvrf
= zebra_vrf_lookup (vrf_id
);
1987 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1988 zlog_debug ("zebra received unknown VRF[%u]", vrf_id
);
1989 goto zclient_read_out
;
1994 case ZEBRA_ROUTER_ID_ADD
:
1995 zread_router_id_add (client
, length
, zvrf
);
1997 case ZEBRA_ROUTER_ID_DELETE
:
1998 zread_router_id_delete (client
, length
, zvrf
);
2000 case ZEBRA_INTERFACE_ADD
:
2001 zread_interface_add (client
, length
, zvrf
);
2003 case ZEBRA_INTERFACE_DELETE
:
2004 zread_interface_delete (client
, length
, zvrf
);
2006 case ZEBRA_IPV4_ROUTE_ADD
:
2007 zread_ipv4_add (client
, length
, zvrf
);
2009 case ZEBRA_IPV4_ROUTE_DELETE
:
2010 zread_ipv4_delete (client
, length
, zvrf
);
2012 case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD
:
2013 zread_ipv4_route_ipv6_nexthop_add (client
, length
, zvrf
);
2015 case ZEBRA_IPV6_ROUTE_ADD
:
2016 zread_ipv6_add (client
, length
, zvrf
);
2018 case ZEBRA_IPV6_ROUTE_DELETE
:
2019 zread_ipv6_delete (client
, length
, zvrf
);
2021 case ZEBRA_REDISTRIBUTE_ADD
:
2022 zebra_redistribute_add (command
, client
, length
, zvrf
);
2024 case ZEBRA_REDISTRIBUTE_DELETE
:
2025 zebra_redistribute_delete (command
, client
, length
, zvrf
);
2027 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
2028 zebra_redistribute_default_add (command
, client
, length
, zvrf
);
2030 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
2031 zebra_redistribute_default_delete (command
, client
, length
, zvrf
);
2033 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
2034 zread_ipv4_nexthop_lookup (client
, length
, zvrf
);
2036 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
:
2037 zread_ipv4_nexthop_lookup_mrib (client
, length
, zvrf
);
2039 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
2040 zread_ipv6_nexthop_lookup (client
, length
, zvrf
);
2042 case ZEBRA_IPV4_IMPORT_LOOKUP
:
2043 zread_ipv4_import_lookup (client
, length
, zvrf
);
2046 zread_hello (client
);
2048 case ZEBRA_NEXTHOP_REGISTER
:
2049 zserv_rnh_register(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
2051 case ZEBRA_NEXTHOP_UNREGISTER
:
2052 zserv_rnh_unregister(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
2054 case ZEBRA_IMPORT_ROUTE_REGISTER
:
2055 zserv_rnh_register(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
2057 case ZEBRA_IMPORT_ROUTE_UNREGISTER
:
2058 zserv_rnh_unregister(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
2060 case ZEBRA_BFD_DEST_UPDATE
:
2061 case ZEBRA_BFD_DEST_REGISTER
:
2062 zebra_ptm_bfd_dst_register(client
, sock
, length
, command
, zvrf
);
2064 case ZEBRA_BFD_DEST_DEREGISTER
:
2065 zebra_ptm_bfd_dst_deregister(client
, sock
, length
, zvrf
);
2067 case ZEBRA_VRF_UNREGISTER
:
2068 zread_vrf_unregister (client
, length
, zvrf
);
2070 case ZEBRA_BFD_CLIENT_REGISTER
:
2071 zebra_ptm_bfd_client_register(client
, sock
, length
);
2073 case ZEBRA_INTERFACE_ENABLE_RADV
:
2074 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 1);
2076 case ZEBRA_INTERFACE_DISABLE_RADV
:
2077 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 0);
2080 zlog_info ("Zebra received unknown command %d", command
);
2084 if (client
->t_suicide
)
2086 /* No need to wait for thread callback, just kill immediately. */
2087 zebra_client_close(client
);
2092 stream_reset (client
->ibuf
);
2093 zebra_event (ZEBRA_READ
, sock
, client
);
2098 /* Accept code of zebra server socket. */
2100 zebra_accept (struct thread
*thread
)
2104 struct sockaddr_in client
;
2107 accept_sock
= THREAD_FD (thread
);
2109 /* Reregister myself. */
2110 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2112 len
= sizeof (struct sockaddr_in
);
2113 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
2115 if (client_sock
< 0)
2117 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno
));
2121 /* Make client socket non-blocking. */
2122 set_nonblocking(client_sock
);
2124 /* Create new zebra client. */
2125 zebra_client_create (client_sock
);
2130 #ifdef HAVE_TCP_ZEBRA
2131 /* Make zebra's server socket. */
2137 struct sockaddr_in addr
;
2139 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
2141 if (accept_sock
< 0)
2143 zlog_warn ("Can't create zserv stream socket: %s",
2144 safe_strerror (errno
));
2145 zlog_warn ("zebra can't provice full functionality due to above error");
2149 memset (&addr
, 0, sizeof (struct sockaddr_in
));
2150 addr
.sin_family
= AF_INET
;
2151 addr
.sin_port
= htons (ZEBRA_PORT
);
2152 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2153 addr
.sin_len
= sizeof (struct sockaddr_in
);
2154 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
2155 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
2157 sockopt_reuseaddr (accept_sock
);
2158 sockopt_reuseport (accept_sock
);
2160 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
2161 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
2163 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
2164 sizeof (struct sockaddr_in
));
2167 zlog_warn ("Can't bind to stream socket: %s",
2168 safe_strerror (errno
));
2169 zlog_warn ("zebra can't provice full functionality due to above error");
2170 close (accept_sock
); /* Avoid sd leak. */
2174 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
2175 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
2177 ret
= listen (accept_sock
, 1);
2180 zlog_warn ("Can't listen to stream socket: %s",
2181 safe_strerror (errno
));
2182 zlog_warn ("zebra can't provice full functionality due to above error");
2183 close (accept_sock
); /* Avoid sd leak. */
2187 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2189 #else /* HAVE_TCP_ZEBRA */
2191 /* For sockaddr_un. */
2194 /* zebra server UNIX domain socket. */
2196 zebra_serv_un (const char *path
)
2200 struct sockaddr_un serv
;
2203 /* First of all, unlink existing socket */
2207 old_mask
= umask (0077);
2209 /* Make UNIX domain socket. */
2210 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
2213 zlog_warn ("Can't create zserv unix socket: %s",
2214 safe_strerror (errno
));
2215 zlog_warn ("zebra can't provide full functionality due to above error");
2219 /* Make server socket. */
2220 memset (&serv
, 0, sizeof (struct sockaddr_un
));
2221 serv
.sun_family
= AF_UNIX
;
2222 strncpy (serv
.sun_path
, path
, strlen (path
));
2223 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2224 len
= serv
.sun_len
= SUN_LEN(&serv
);
2226 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
2227 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2229 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
2232 zlog_warn ("Can't bind to unix socket %s: %s",
2233 path
, safe_strerror (errno
));
2234 zlog_warn ("zebra can't provide full functionality due to above error");
2239 ret
= listen (sock
, 5);
2242 zlog_warn ("Can't listen to unix socket %s: %s",
2243 path
, safe_strerror (errno
));
2244 zlog_warn ("zebra can't provide full functionality due to above error");
2251 zebra_event (ZEBRA_SERV
, sock
, NULL
);
2253 #endif /* HAVE_TCP_ZEBRA */
2257 zebra_event (enum event event
, int sock
, struct zserv
*client
)
2262 thread_add_read (zebrad
.master
, zebra_accept
, client
, sock
);
2266 thread_add_read (zebrad
.master
, zebra_client_read
, client
, sock
);
2274 #define ZEBRA_TIME_BUF 32
2276 zserv_time_buf(time_t *time1
, char *buf
, int buflen
)
2281 assert (buf
!= NULL
);
2282 assert (buflen
>= ZEBRA_TIME_BUF
);
2283 assert (time1
!= NULL
);
2287 snprintf(buf
, buflen
, "never ");
2291 now
= quagga_monotime();
2295 /* Making formatted timer strings. */
2296 #define ONE_DAY_SECOND 60*60*24
2297 #define ONE_WEEK_SECOND 60*60*24*7
2299 if (now
< ONE_DAY_SECOND
)
2300 snprintf (buf
, buflen
, "%02d:%02d:%02d",
2301 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
2302 else if (now
< ONE_WEEK_SECOND
)
2303 snprintf (buf
, buflen
, "%dd%02dh%02dm",
2304 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
2306 snprintf (buf
, buflen
, "%02dw%dd%02dh",
2307 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
2312 zebra_show_client_detail (struct vty
*vty
, struct zserv
*client
)
2314 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2315 char wbuf
[ZEBRA_TIME_BUF
], nhbuf
[ZEBRA_TIME_BUF
], mbuf
[ZEBRA_TIME_BUF
];
2317 vty_out (vty
, "Client: %s", zebra_route_string(client
->proto
));
2318 if (client
->instance
)
2319 vty_out (vty
, " Instance: %d", client
->instance
);
2320 vty_out (vty
, "%s", VTY_NEWLINE
);
2322 vty_out (vty
, "------------------------ %s", VTY_NEWLINE
);
2323 vty_out (vty
, "FD: %d %s", client
->sock
, VTY_NEWLINE
);
2324 vty_out (vty
, "Route Table ID: %d %s", client
->rtm_table
, VTY_NEWLINE
);
2326 vty_out (vty
, "Connect Time: %s %s",
2327 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2329 if (client
->nh_reg_time
)
2331 vty_out (vty
, "Nexthop Registry Time: %s %s",
2332 zserv_time_buf(&client
->nh_reg_time
, nhbuf
, ZEBRA_TIME_BUF
),
2334 if (client
->nh_last_upd_time
)
2335 vty_out (vty
, "Nexthop Last Update Time: %s %s",
2336 zserv_time_buf(&client
->nh_last_upd_time
, mbuf
, ZEBRA_TIME_BUF
),
2339 vty_out (vty
, "No Nexthop Update sent%s", VTY_NEWLINE
);
2342 vty_out (vty
, "Not registered for Nexthop Updates%s", VTY_NEWLINE
);
2344 vty_out (vty
, "Last Msg Rx Time: %s %s",
2345 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2347 vty_out (vty
, "Last Msg Tx Time: %s %s",
2348 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2350 if (client
->last_read_time
)
2351 vty_out (vty
, "Last Rcvd Cmd: %s %s",
2352 zserv_command_string(client
->last_read_cmd
), VTY_NEWLINE
);
2353 if (client
->last_write_time
)
2354 vty_out (vty
, "Last Sent Cmd: %s %s",
2355 zserv_command_string(client
->last_write_cmd
), VTY_NEWLINE
);
2356 vty_out (vty
, "%s", VTY_NEWLINE
);
2358 vty_out (vty
, "Type Add Update Del %s", VTY_NEWLINE
);
2359 vty_out (vty
, "================================================== %s", VTY_NEWLINE
);
2360 vty_out (vty
, "IPv4 %-12d%-12d%-12d%s", client
->v4_route_add_cnt
,
2361 client
->v4_route_upd8_cnt
, client
->v4_route_del_cnt
, VTY_NEWLINE
);
2362 vty_out (vty
, "IPv6 %-12d%-12d%-12d%s", client
->v6_route_add_cnt
,
2363 client
->v6_route_upd8_cnt
, client
->v6_route_del_cnt
, VTY_NEWLINE
);
2364 vty_out (vty
, "Redist:v4 %-12d%-12d%-12d%s", client
->redist_v4_add_cnt
, 0,
2365 client
->redist_v4_del_cnt
, VTY_NEWLINE
);
2366 vty_out (vty
, "Redist:v6 %-12d%-12d%-12d%s", client
->redist_v6_add_cnt
, 0,
2367 client
->redist_v6_del_cnt
, VTY_NEWLINE
);
2368 vty_out (vty
, "Connected %-12d%-12d%-12d%s", client
->ifadd_cnt
, 0,
2369 client
->ifdel_cnt
, VTY_NEWLINE
);
2370 vty_out (vty
, "BFD peer %-12d%-12d%-12d%s", client
->bfd_peer_add_cnt
,
2371 client
->bfd_peer_upd8_cnt
, client
->bfd_peer_del_cnt
, VTY_NEWLINE
);
2372 vty_out (vty
, "Interface Up Notifications: %d%s", client
->ifup_cnt
,
2374 vty_out (vty
, "Interface Down Notifications: %d%s", client
->ifdown_cnt
,
2377 vty_out (vty
, "%s", VTY_NEWLINE
);
2382 zebra_show_client_brief (struct vty
*vty
, struct zserv
*client
)
2384 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2385 char wbuf
[ZEBRA_TIME_BUF
];
2387 vty_out (vty
, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
2388 zebra_route_string(client
->proto
),
2389 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2390 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2391 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2392 client
->v4_route_add_cnt
+client
->v4_route_upd8_cnt
,
2393 client
->v4_route_del_cnt
,
2394 client
->v6_route_add_cnt
+client
->v6_route_upd8_cnt
,
2395 client
->v6_route_del_cnt
, VTY_NEWLINE
);
2400 /* Display default rtm_table for all clients. */
2405 "default routing table to use for all clients\n")
2407 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2412 DEFUN (config_table
,
2415 "Configure target kernel routing table\n"
2418 zebrad
.rtm_table_default
= strtol (argv
[0], (char**)0, 10);
2422 DEFUN (no_config_table
,
2423 no_config_table_cmd
,
2426 "Configure target kernel routing table\n"
2429 zebrad
.rtm_table_default
= 0;
2433 DEFUN (ip_forwarding
,
2437 "Turn on IP forwarding")
2443 ret
= ipforward_on ();
2447 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
2454 DEFUN (no_ip_forwarding
,
2455 no_ip_forwarding_cmd
,
2459 "Turn off IP forwarding")
2465 ret
= ipforward_off ();
2469 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
2476 /* This command is for debugging purpose. */
2477 DEFUN (show_zebra_client
,
2478 show_zebra_client_cmd
,
2479 "show zebra client",
2482 "Client information")
2484 struct listnode
*node
;
2485 struct zserv
*client
;
2487 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2488 zebra_show_client_detail(vty
, client
);
2493 /* This command is for debugging purpose. */
2494 DEFUN (show_zebra_client_summary
,
2495 show_zebra_client_summary_cmd
,
2496 "show zebra client summary",
2498 "Zebra information brief"
2499 "Client information brief")
2501 struct listnode
*node
;
2502 struct zserv
*client
;
2504 vty_out (vty
, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
2506 vty_out (vty
,"--------------------------------------------------------------------------------%s",
2509 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2510 zebra_show_client_brief(vty
, client
);
2512 vty_out (vty
, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE
);
2516 /* Table configuration write function. */
2518 config_write_table (struct vty
*vty
)
2520 if (zebrad
.rtm_table_default
)
2521 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2526 /* table node for routing tables. */
2527 static struct cmd_node table_node
=
2530 "", /* This node has no interface. */
2534 /* Only display ip forwarding is enabled or not. */
2535 DEFUN (show_ip_forwarding
,
2536 show_ip_forwarding_cmd
,
2537 "show ip forwarding",
2540 "IP forwarding status\n")
2547 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
2549 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
2554 /* Only display ipv6 forwarding is enabled or not. */
2555 DEFUN (show_ipv6_forwarding
,
2556 show_ipv6_forwarding_cmd
,
2557 "show ipv6 forwarding",
2559 "IPv6 information\n"
2560 "Forwarding status\n")
2564 ret
= ipforward_ipv6 ();
2569 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
2572 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2575 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
2578 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2584 DEFUN (ipv6_forwarding
,
2585 ipv6_forwarding_cmd
,
2588 "Turn on IPv6 forwarding")
2592 ret
= ipforward_ipv6 ();
2594 ret
= ipforward_ipv6_on ();
2598 vty_out (vty
, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE
);
2605 DEFUN (no_ipv6_forwarding
,
2606 no_ipv6_forwarding_cmd
,
2607 "no ipv6 forwarding",
2610 "Turn off IPv6 forwarding")
2614 ret
= ipforward_ipv6 ();
2616 ret
= ipforward_ipv6_off ();
2620 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
2627 #endif /* HAVE_IPV6 */
2629 /* IPForwarding configuration write function. */
2631 config_write_forwarding (struct vty
*vty
)
2633 /* FIXME: Find better place for that. */
2634 router_id_write (vty
);
2637 vty_out (vty
, "no ip forwarding%s", VTY_NEWLINE
);
2639 if (!ipforward_ipv6 ())
2640 vty_out (vty
, "no ipv6 forwarding%s", VTY_NEWLINE
);
2641 #endif /* HAVE_IPV6 */
2642 vty_out (vty
, "!%s", VTY_NEWLINE
);
2646 /* table node for routing tables. */
2647 static struct cmd_node forwarding_node
=
2650 "", /* This node has no interface. */
2655 /* Initialisation of zebra and installation of commands. */
2659 /* Client list init. */
2660 zebrad
.client_list
= list_new ();
2662 /* Install configuration write function. */
2663 install_node (&table_node
, config_write_table
);
2664 install_node (&forwarding_node
, config_write_forwarding
);
2666 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
2667 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
2668 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
2669 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
2670 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
2671 install_element (ENABLE_NODE
, &show_zebra_client_summary_cmd
);
2674 install_element (VIEW_NODE
, &show_table_cmd
);
2675 install_element (ENABLE_NODE
, &show_table_cmd
);
2676 install_element (CONFIG_NODE
, &config_table_cmd
);
2677 install_element (CONFIG_NODE
, &no_config_table_cmd
);
2678 #endif /* HAVE_NETLINK */
2681 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2682 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
2683 install_element (CONFIG_NODE
, &ipv6_forwarding_cmd
);
2684 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2685 #endif /* HAVE_IPV6 */
2688 zebra_route_map_init ();
2691 /* Make zebra server socket, wiping any existing one (see bug #403). */
2693 zebra_zserv_socket_init (char *path
)
2695 #ifdef HAVE_TCP_ZEBRA
2698 zebra_serv_un (path
? path
: ZEBRA_SERV_PATH
);
2699 #endif /* HAVE_TCP_ZEBRA */