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 #ifdef HAVE_STRUCT_SOCKADDR_DL
164 stream_put (s
, &ifp
->sdl
, sizeof (ifp
->sdl_storage
));
166 stream_putl (s
, ifp
->hw_addr_len
);
167 if (ifp
->hw_addr_len
)
168 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
169 #endif /* HAVE_STRUCT_SOCKADDR_DL */
171 /* Write packet size. */
172 stream_putw_at (s
, 0, stream_get_endp (s
));
176 zserv_encode_vrf (struct stream
*s
, struct zebra_vrf
*zvrf
)
178 /* Interface information. */
179 stream_put (s
, zvrf
->name
, VRF_NAMSIZ
);
181 /* Write packet size. */
182 stream_putw_at (s
, 0, stream_get_endp (s
));
185 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
187 * This function is called in the following situations:
188 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
190 * - at startup, when zebra figures out the available interfaces
191 * - when an interface is added (where support for
192 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
193 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
197 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
204 zserv_create_header (s
, ZEBRA_INTERFACE_ADD
, ifp
->vrf_id
);
205 zserv_encode_interface (s
, ifp
);
208 return zebra_server_send_message(client
);
211 /* Interface deletion from zebra daemon. */
213 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
220 zserv_create_header (s
, ZEBRA_INTERFACE_DELETE
, ifp
->vrf_id
);
221 zserv_encode_interface (s
, ifp
);
224 return zebra_server_send_message (client
);
228 zsend_vrf_add (struct zserv
*client
, struct zebra_vrf
*zvrf
)
235 zserv_create_header (s
, ZEBRA_VRF_ADD
, zvrf
->vrf_id
);
236 zserv_encode_vrf (s
, zvrf
);
238 client
->vrfadd_cnt
++;
239 return zebra_server_send_message(client
);
242 /* VRF deletion from zebra daemon. */
244 zsend_vrf_delete (struct zserv
*client
, struct zebra_vrf
*zvrf
)
251 zserv_create_header (s
, ZEBRA_VRF_DELETE
, zvrf
->vrf_id
);
252 zserv_encode_vrf (s
, zvrf
);
254 client
->vrfdel_cnt
++;
255 return zebra_server_send_message (client
);
258 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
259 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
261 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
262 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
263 * from the client, after the ZEBRA_INTERFACE_ADD has been
264 * sent from zebra to the client
265 * - redistribute new address info to all clients in the following situations
266 * - at startup, when zebra figures out the available interfaces
267 * - when an interface is added (where support for
268 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
269 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
271 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
272 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
273 * - when an RTM_NEWADDR message is received from the kernel,
275 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
277 * zsend_interface_address(DELETE)
280 * zebra_interface_address_delete_update
282 * | | if_delete_update
284 * ip_address_uninstall connected_delete_ipv4
285 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
288 * | RTM_NEWADDR on routing/netlink socket
291 * "no ip address A.B.C.D/M [label LINE]"
292 * "no ip address A.B.C.D/M secondary"
293 * ["no ipv6 address X:X::X:X/M"]
297 zsend_interface_address (int cmd
, struct zserv
*client
,
298 struct interface
*ifp
, struct connected
*ifc
)
307 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
308 stream_putl (s
, ifp
->ifindex
);
310 /* Interface address flag. */
311 stream_putc (s
, ifc
->flags
);
313 /* Prefix information. */
315 stream_putc (s
, p
->family
);
316 blen
= prefix_blen (p
);
317 stream_put (s
, &p
->u
.prefix
, blen
);
320 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
321 * but zebra_interface_address_delete_read() in the gnu version
324 stream_putc (s
, p
->prefixlen
);
327 p
= ifc
->destination
;
329 stream_put (s
, &p
->u
.prefix
, blen
);
331 stream_put (s
, NULL
, blen
);
333 /* Write packet size. */
334 stream_putw_at (s
, 0, stream_get_endp (s
));
336 client
->connected_rt_add_cnt
++;
337 return zebra_server_send_message(client
);
341 zsend_interface_nbr_address (int cmd
, struct zserv
*client
,
342 struct interface
*ifp
, struct nbr_connected
*ifc
)
351 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
352 stream_putl (s
, ifp
->ifindex
);
354 /* Prefix information. */
356 stream_putc (s
, p
->family
);
357 blen
= prefix_blen (p
);
358 stream_put (s
, &p
->u
.prefix
, blen
);
361 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
362 * but zebra_interface_address_delete_read() in the gnu version
365 stream_putc (s
, p
->prefixlen
);
367 /* Write packet size. */
368 stream_putw_at (s
, 0, stream_get_endp (s
));
370 return zebra_server_send_message(client
);
373 /* Interface address addition. */
375 zebra_interface_nbr_address_add_update (struct interface
*ifp
,
376 struct nbr_connected
*ifc
)
378 struct listnode
*node
, *nnode
;
379 struct zserv
*client
;
382 if (IS_ZEBRA_DEBUG_EVENT
)
384 char buf
[INET6_ADDRSTRLEN
];
387 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
388 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
389 p
->prefixlen
, ifc
->ifp
->name
);
392 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
393 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
, client
, ifp
, ifc
);
396 /* Interface address deletion. */
398 zebra_interface_nbr_address_delete_update (struct interface
*ifp
,
399 struct nbr_connected
*ifc
)
401 struct listnode
*node
, *nnode
;
402 struct zserv
*client
;
405 if (IS_ZEBRA_DEBUG_EVENT
)
407 char buf
[INET6_ADDRSTRLEN
];
410 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
411 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
412 p
->prefixlen
, ifc
->ifp
->name
);
415 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
416 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE
, client
, ifp
, ifc
);
419 /* Send addresses on interface to client */
421 zsend_interface_addresses (struct zserv
*client
, struct interface
*ifp
)
423 struct listnode
*cnode
, *cnnode
;
425 struct nbr_connected
*nc
;
427 /* Send interface addresses. */
428 for (ALL_LIST_ELEMENTS (ifp
->connected
, cnode
, cnnode
, c
))
430 if (!CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
))
433 if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
,
438 /* Send interface neighbors. */
439 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, cnode
, cnnode
, nc
))
441 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
,
442 client
, ifp
, nc
) < 0)
449 /* Notify client about interface moving from one VRF to another.
450 * Whether client is interested in old and new VRF is checked by caller.
453 zsend_interface_vrf_update (struct zserv
*client
, struct interface
*ifp
,
461 zserv_create_header (s
, ZEBRA_INTERFACE_VRF_UPDATE
, ifp
->vrf_id
);
463 /* Fill in the ifIndex of the interface and its new VRF (id) */
464 stream_putl (s
, ifp
->ifindex
);
465 stream_putw (s
, vrf_id
);
467 /* Write packet size. */
468 stream_putw_at (s
, 0, stream_get_endp (s
));
470 client
->if_vrfchg_cnt
++;
471 return zebra_server_send_message(client
);
474 /* Add new nbr connected IPv6 address */
476 nbr_connected_add_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
478 struct nbr_connected
*ifc
;
482 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
483 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
485 if (!(ifc
= listnode_head(ifp
->nbr_connected
)))
488 ifc
= nbr_connected_new ();
489 ifc
->address
= prefix_new();
491 listnode_add (ifp
->nbr_connected
, ifc
);
494 prefix_copy(ifc
->address
, &p
);
496 zebra_interface_nbr_address_add_update (ifp
, ifc
);
498 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 1);
502 nbr_connected_delete_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
504 struct nbr_connected
*ifc
;
508 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
509 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
511 ifc
= nbr_connected_check(ifp
, &p
);
515 listnode_delete (ifp
->nbr_connected
, ifc
);
517 zebra_interface_nbr_address_delete_update (ifp
, ifc
);
519 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 0);
521 nbr_connected_free (ifc
);
525 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
526 * ZEBRA_INTERFACE_DOWN.
528 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
529 * the clients in one of 2 situations:
530 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
531 * - a vty command modifying the bandwidth of an interface is received.
532 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
535 zsend_interface_update (int cmd
, struct zserv
*client
, struct interface
*ifp
)
542 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
543 zserv_encode_interface (s
, ifp
);
545 if (cmd
== ZEBRA_INTERFACE_UP
)
548 client
->ifdown_cnt
++;
550 return zebra_server_send_message(client
);
554 * This is the new function to announce and withdraw redistributed routes, used
555 * by Zebra. This is the old zsend_route_multipath() function. That function
556 * was duplicating code to send a lot of information that was essentially thrown
557 * away or ignored by the receiver. This is the leaner function that is not a
558 * duplicate of the zapi_ipv4_route_add/del.
560 * The primary difference is that this function merely sends a single NH instead of
564 zsend_redistribute_route (int cmd
, struct zserv
*client
, struct prefix
*p
,
569 struct nexthop
*nexthop
;
570 unsigned long nhnummark
= 0, messmark
= 0;
572 u_char zapi_flags
= 0;
573 struct nexthop dummy_nh
;
575 /* Came from VRF lib patch, is this really needed? callers of this routine
576 do check for redist.., so may be its not needed.
577 Check this client need this route.
578 if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
581 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
587 memset(&dummy_nh
, 0, sizeof(struct nexthop
));
589 zserv_create_header (s
, cmd
, rib
->vrf_id
);
591 /* Put type and nexthop. */
592 stream_putc (s
, rib
->type
);
593 stream_putw (s
, rib
->instance
);
594 stream_putc (s
, rib
->flags
);
596 /* marker for message flags field */
597 messmark
= stream_get_endp (s
);
601 psize
= PSIZE (p
->prefixlen
);
602 stream_putc (s
, p
->prefixlen
);
603 stream_write (s
, (u_char
*) & p
->u
.prefix
, psize
);
605 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
607 /* We don't send any nexthops when there's a multipath */
608 if (rib
->nexthop_active_num
> 1)
610 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
611 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
614 if (p
->family
== AF_INET
)
616 stream_put_in_addr (s
, &dummy_nh
.gate
.ipv4
);
618 else if (p
->family
== AF_INET6
)
620 stream_write (s
, (u_char
*) &dummy_nh
.gate
.ipv6
, 16);
624 /* We don't handle anything else now, abort */
625 zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
626 __func__
, p
->family
);
630 stream_putl (s
, 0); /* dummy ifindex */
634 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
635 || nexthop_has_fib_child(nexthop
))
637 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
638 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
641 nhnummark
= stream_get_endp (s
);
642 stream_putc (s
, 1); /* placeholder */
646 switch(nexthop
->type
)
648 case NEXTHOP_TYPE_IPV4
:
649 case NEXTHOP_TYPE_IPV4_IFINDEX
:
650 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
652 case NEXTHOP_TYPE_IPV6
:
653 case NEXTHOP_TYPE_IPV6_IFINDEX
:
654 /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
655 if (p
->family
== AF_INET
)
656 stream_put_in_addr(s
, &dummy_nh
.gate
.ipv4
);
658 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
661 if (cmd
== ZEBRA_REDISTRIBUTE_IPV4_ADD
662 || cmd
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
664 struct in_addr empty
;
665 memset (&empty
, 0, sizeof (struct in_addr
));
666 stream_write (s
, (u_char
*) &empty
, IPV4_MAX_BYTELEN
);
670 struct in6_addr empty
;
671 memset (&empty
, 0, sizeof (struct in6_addr
));
672 stream_write (s
, (u_char
*) &empty
, IPV6_MAX_BYTELEN
);
676 /* Interface index. */
678 stream_putl (s
, nexthop
->ifindex
);
685 if (cmd
== ZEBRA_REDISTRIBUTE_IPV4_ADD
|| cmd
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
687 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_DISTANCE
);
688 stream_putc (s
, rib
->distance
);
689 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_METRIC
);
690 stream_putl (s
, rib
->metric
);
695 SET_FLAG(zapi_flags
, ZAPI_MESSAGE_TAG
);
696 stream_putw(s
, rib
->tag
);
700 /* write real message flags value */
701 stream_putc_at (s
, messmark
, zapi_flags
);
703 /* Write next-hop number */
705 stream_putc_at (s
, nhnummark
, nhnum
);
707 /* Write packet size. */
708 stream_putw_at (s
, 0, stream_get_endp (s
));
710 return zebra_server_send_message(client
);
715 zsend_ipv6_nexthop_lookup (struct zserv
*client
, struct in6_addr
*addr
,
722 struct nexthop
*nexthop
;
724 /* Lookup nexthop. */
725 rib
= rib_match_ipv6 (addr
, vrf_id
);
727 /* Get output stream. */
731 /* Fill in result. */
732 zserv_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
, vrf_id
);
733 stream_put (s
, addr
, 16);
737 stream_putl (s
, rib
->metric
);
739 nump
= stream_get_endp(s
);
741 /* Only non-recursive routes are elegible to resolve nexthop we
742 * are looking up. Therefore, we will just iterate over the top
743 * chain of nexthops. */
744 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
745 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
747 stream_putc (s
, nexthop
->type
);
748 switch (nexthop
->type
)
750 case ZEBRA_NEXTHOP_IPV6
:
751 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
753 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
754 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
755 stream_putl (s
, nexthop
->ifindex
);
757 case ZEBRA_NEXTHOP_IFINDEX
:
758 stream_putl (s
, nexthop
->ifindex
);
766 stream_putc_at (s
, nump
, num
);
774 stream_putw_at (s
, 0, stream_get_endp (s
));
776 return zebra_server_send_message(client
);
778 #endif /* HAVE_IPV6 */
781 zsend_ipv4_nexthop_lookup (struct zserv
*client
, struct in_addr addr
,
788 struct nexthop
*nexthop
;
790 /* Lookup nexthop. */
791 rib
= rib_match_ipv4 (addr
, SAFI_UNICAST
, vrf_id
, NULL
);
793 /* Get output stream. */
797 /* Fill in result. */
798 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
, vrf_id
);
799 stream_put_in_addr (s
, &addr
);
803 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
804 zlog_debug("%s: Matching rib entry found.", __func__
);
805 stream_putl (s
, rib
->metric
);
807 nump
= stream_get_endp(s
);
809 /* Only non-recursive routes are elegible to resolve the nexthop we
810 * are looking up. Therefore, we will just iterate over the top
811 * chain of nexthops. */
812 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
813 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
815 stream_putc (s
, nexthop
->type
);
816 switch (nexthop
->type
)
818 case ZEBRA_NEXTHOP_IPV4
:
819 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
821 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
822 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
823 stream_putl (s
, nexthop
->ifindex
);
825 case ZEBRA_NEXTHOP_IFINDEX
:
826 stream_putl (s
, nexthop
->ifindex
);
834 stream_putc_at (s
, nump
, num
);
838 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
839 zlog_debug("%s: No matching rib entry found.", __func__
);
844 stream_putw_at (s
, 0, stream_get_endp (s
));
846 return zebra_server_send_message(client
);
849 /* Nexthop register */
851 zserv_rnh_register (struct zserv
*client
, int sock
, u_short length
,
852 rnh_type_t type
, struct zebra_vrf
*zvrf
)
860 if (IS_ZEBRA_DEBUG_NHT
)
861 zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
862 zebra_route_string(client
->proto
), length
,
863 (type
== RNH_NEXTHOP_TYPE
) ? "nexthop" : "route");
867 client
->nh_reg_time
= quagga_monotime();
871 flags
= stream_getc(s
);
872 p
.family
= stream_getw(s
);
873 p
.prefixlen
= stream_getc(s
);
875 if (p
.family
== AF_INET
)
877 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
878 l
+= IPV4_MAX_BYTELEN
;
880 else if (p
.family
== AF_INET6
)
882 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
883 l
+= IPV6_MAX_BYTELEN
;
887 zlog_err("rnh_register: Received unknown family type %d\n",
891 rnh
= zebra_add_rnh(&p
, zvrf
->vrf_id
, type
);
892 if (type
== RNH_NEXTHOP_TYPE
)
894 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
895 SET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
896 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
897 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
899 else if (type
== RNH_IMPORT_CHECK_TYPE
)
901 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
902 SET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
903 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
904 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
907 zebra_add_rnh_client(rnh
, client
, type
, zvrf
->vrf_id
);
908 /* Anything not AF_INET/INET6 has been filtered out above */
909 zebra_evaluate_rnh(zvrf
->vrf_id
, p
.family
, 1, type
, &p
);
914 /* Nexthop register */
916 zserv_rnh_unregister (struct zserv
*client
, int sock
, u_short length
,
917 rnh_type_t type
, struct zebra_vrf
*zvrf
)
924 if (IS_ZEBRA_DEBUG_NHT
)
925 zlog_debug("rnh_unregister msg from client %s: length=%d\n",
926 zebra_route_string(client
->proto
), length
);
932 (void)stream_getc(s
); //Connected or not. Not used in this function
933 p
.family
= stream_getw(s
);
934 p
.prefixlen
= stream_getc(s
);
936 if (p
.family
== AF_INET
)
938 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
939 l
+= IPV4_MAX_BYTELEN
;
941 else if (p
.family
== AF_INET6
)
943 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
944 l
+= IPV6_MAX_BYTELEN
;
948 zlog_err("rnh_register: Received unknown family type %d\n",
952 rnh
= zebra_lookup_rnh(&p
, zvrf
->vrf_id
, type
);
955 client
->nh_dereg_time
= quagga_monotime();
956 zebra_remove_rnh_client(rnh
, client
, type
);
963 Modified version of zsend_ipv4_nexthop_lookup():
964 Query unicast rib if nexthop is not found on mrib.
965 Returns both route metric and protocol distance.
968 zsend_ipv4_nexthop_lookup_mrib (struct zserv
*client
, struct in_addr addr
, struct rib
*rib
, struct zebra_vrf
*zvrf
)
973 struct nexthop
*nexthop
;
975 /* Get output stream. */
979 /* Fill in result. */
980 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
, zvrf
->vrf_id
);
981 stream_put_in_addr (s
, &addr
);
985 stream_putc (s
, rib
->distance
);
986 stream_putl (s
, rib
->metric
);
988 nump
= stream_get_endp(s
); /* remember position for nexthop_num */
989 stream_putc (s
, 0); /* reserve room for nexthop_num */
990 /* Only non-recursive routes are elegible to resolve the nexthop we
991 * are looking up. Therefore, we will just iterate over the top
992 * chain of nexthops. */
993 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
994 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
996 stream_putc (s
, nexthop
->type
);
997 switch (nexthop
->type
)
999 case ZEBRA_NEXTHOP_IPV4
:
1000 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1002 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
1003 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1004 stream_putl (s
, nexthop
->ifindex
);
1006 case ZEBRA_NEXTHOP_IFINDEX
:
1007 stream_putl (s
, nexthop
->ifindex
);
1016 stream_putc_at (s
, nump
, num
); /* store nexthop_num */
1020 stream_putc (s
, 0); /* distance */
1021 stream_putl (s
, 0); /* metric */
1022 stream_putc (s
, 0); /* nexthop_num */
1025 stream_putw_at (s
, 0, stream_get_endp (s
));
1027 return zebra_server_send_message(client
);
1031 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
,
1038 struct nexthop
*nexthop
;
1040 /* Lookup nexthop. */
1041 rib
= rib_lookup_ipv4 (p
, vrf_id
);
1043 /* Get output stream. */
1047 /* Fill in result. */
1048 zserv_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
, vrf_id
);
1049 stream_put_in_addr (s
, &p
->prefix
);
1053 stream_putl (s
, rib
->metric
);
1055 nump
= stream_get_endp(s
);
1057 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1058 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1059 || nexthop_has_fib_child(nexthop
))
1061 stream_putc (s
, nexthop
->type
);
1062 switch (nexthop
->type
)
1064 case ZEBRA_NEXTHOP_IPV4
:
1065 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1067 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
1068 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
1069 stream_putl (s
, nexthop
->ifindex
);
1071 case ZEBRA_NEXTHOP_IFINDEX
:
1072 stream_putl (s
, nexthop
->ifindex
);
1080 stream_putc_at (s
, nump
, num
);
1088 stream_putw_at (s
, 0, stream_get_endp (s
));
1090 return zebra_server_send_message(client
);
1093 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
1095 zsend_router_id_update (struct zserv
*client
, struct prefix
*p
,
1101 /* Check this client need interface information. */
1102 if (! vrf_bitmap_check (client
->ridinfo
, vrf_id
))
1109 zserv_create_header (s
, ZEBRA_ROUTER_ID_UPDATE
, vrf_id
);
1111 /* Prefix information. */
1112 stream_putc (s
, p
->family
);
1113 blen
= prefix_blen (p
);
1114 stream_put (s
, &p
->u
.prefix
, blen
);
1115 stream_putc (s
, p
->prefixlen
);
1117 /* Write packet size. */
1118 stream_putw_at (s
, 0, stream_get_endp (s
));
1120 return zebra_server_send_message(client
);
1123 /* Register zebra server interface information. Send current all
1124 interface and address information. */
1126 zread_interface_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1128 struct listnode
*ifnode
, *ifnnode
;
1130 struct interface
*ifp
;
1131 struct zebra_vrf
*zvrf_iter
;
1133 /* Interface information is needed. */
1134 vrf_bitmap_set (client
->ifinfo
, zvrf
->vrf_id
);
1136 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
1138 zvrf_iter
= vrf_iter2info (iter
);
1139 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter
->vrf_id
), ifnode
, ifnnode
, ifp
))
1141 /* Skip pseudo interface. */
1142 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1145 if (zsend_interface_add (client
, ifp
) < 0)
1148 if (zsend_interface_addresses (client
, ifp
) < 0)
1155 /* Unregister zebra server interface information. */
1157 zread_interface_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1159 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1164 zserv_nexthop_num_warn (const char *caller
, const struct prefix
*p
, const unsigned int nexthop_num
)
1166 if (nexthop_num
> MULTIPATH_NUM
)
1168 char buff
[PREFIX2STR_BUFFER
];
1169 prefix2str(p
, buff
, sizeof (buff
));
1170 zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
1171 caller
, buff
, nexthop_num
, MULTIPATH_NUM
);
1175 /* This function support multiple nexthop. */
1177 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
1181 zread_ipv4_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1185 struct prefix_ipv4 p
;
1187 struct in_addr nexthop
;
1189 u_char nexthop_type
;
1195 /* Get input stream. */
1198 /* Allocate new rib. */
1199 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1201 /* Type, flags, message. */
1202 rib
->type
= stream_getc (s
);
1203 rib
->instance
= stream_getw (s
);
1204 rib
->flags
= stream_getc (s
);
1205 message
= stream_getc (s
);
1206 safi
= stream_getw (s
);
1207 rib
->uptime
= time (NULL
);
1210 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1212 p
.prefixlen
= stream_getc (s
);
1213 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1216 rib
->vrf_id
= zvrf
->vrf_id
;
1218 /* Nexthop parse. */
1219 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1221 nexthop_num
= stream_getc (s
);
1222 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1224 for (i
= 0; i
< nexthop_num
; i
++)
1226 nexthop_type
= stream_getc (s
);
1228 switch (nexthop_type
)
1230 case ZEBRA_NEXTHOP_IFINDEX
:
1231 ifindex
= stream_getl (s
);
1232 rib_nexthop_ifindex_add (rib
, ifindex
);
1234 case ZEBRA_NEXTHOP_IPV4
:
1235 nexthop
.s_addr
= stream_get_ipv4 (s
);
1236 rib_nexthop_ipv4_add (rib
, &nexthop
, NULL
);
1238 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
1239 nexthop
.s_addr
= stream_get_ipv4 (s
);
1240 ifindex
= stream_getl (s
);
1241 rib_nexthop_ipv4_ifindex_add (rib
, &nexthop
, NULL
, ifindex
);
1243 case ZEBRA_NEXTHOP_IPV6
:
1244 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1246 case ZEBRA_NEXTHOP_BLACKHOLE
:
1247 rib_nexthop_blackhole_add (rib
);
1254 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1255 rib
->distance
= stream_getc (s
);
1258 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1259 rib
->metric
= stream_getl (s
);
1262 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1263 rib
->tag
= stream_getw (s
);
1268 rib
->table
= zvrf
->table_id
;
1270 ret
= rib_add_ipv4_multipath (&p
, rib
, safi
);
1274 client
->v4_route_add_cnt
++;
1276 client
->v4_route_upd8_cnt
++;
1280 /* Zebra server IPv4 prefix delete function. */
1282 zread_ipv4_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1286 struct zapi_ipv4 api
;
1287 struct in_addr nexthop
, *nexthop_p
;
1288 unsigned long ifindex
;
1289 struct prefix_ipv4 p
;
1291 u_char nexthop_type
;
1299 /* Type, flags, message. */
1300 api
.type
= stream_getc (s
);
1301 api
.instance
= stream_getw (s
);
1302 api
.flags
= stream_getc (s
);
1303 api
.message
= stream_getc (s
);
1304 api
.safi
= stream_getw (s
);
1307 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1309 p
.prefixlen
= stream_getc (s
);
1310 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1312 /* Nexthop, ifindex, distance, metric. */
1313 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1315 nexthop_num
= stream_getc (s
);
1317 for (i
= 0; i
< nexthop_num
; i
++)
1319 nexthop_type
= stream_getc (s
);
1321 switch (nexthop_type
)
1323 case ZEBRA_NEXTHOP_IFINDEX
:
1324 ifindex
= stream_getl (s
);
1326 case ZEBRA_NEXTHOP_IPV4
:
1327 nexthop
.s_addr
= stream_get_ipv4 (s
);
1328 nexthop_p
= &nexthop
;
1330 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
1331 nexthop
.s_addr
= stream_get_ipv4 (s
);
1332 nexthop_p
= &nexthop
;
1333 ifindex
= stream_getl (s
);
1335 case ZEBRA_NEXTHOP_IPV6
:
1336 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1343 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1344 api
.distance
= stream_getc (s
);
1349 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1350 api
.metric
= stream_getl (s
);
1355 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1356 api
.tag
= stream_getw (s
);
1360 table_id
= zvrf
->table_id
;
1362 rib_delete_ipv4 (api
.type
, api
.instance
, api
.flags
, &p
, nexthop_p
, ifindex
,
1363 zvrf
->vrf_id
, table_id
, api
.safi
);
1364 client
->v4_route_del_cnt
++;
1368 /* Nexthop lookup for IPv4. */
1370 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
,
1371 struct zebra_vrf
*zvrf
)
1373 struct in_addr addr
;
1376 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1377 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1378 zlog_debug("%s: looking up %s", __func__
,
1379 inet_ntop (AF_INET
, &addr
, buf
, BUFSIZ
));
1380 return zsend_ipv4_nexthop_lookup (client
, addr
, zvrf
->vrf_id
);
1383 /* MRIB Nexthop lookup for IPv4. */
1385 zread_ipv4_nexthop_lookup_mrib (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1387 struct in_addr addr
;
1390 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1391 rib
= rib_match_ipv4_multicast (addr
, NULL
);
1392 return zsend_ipv4_nexthop_lookup_mrib (client
, addr
, rib
, zvrf
);
1395 /* Nexthop lookup for IPv4. */
1397 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
,
1398 struct zebra_vrf
*zvrf
)
1400 struct prefix_ipv4 p
;
1403 p
.prefixlen
= stream_getc (client
->ibuf
);
1404 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1406 return zsend_ipv4_import_lookup (client
, &p
, zvrf
->vrf_id
);
1409 /* Zebra server IPv6 prefix add function. */
1411 zread_ipv4_route_ipv6_nexthop_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1415 struct in6_addr nexthop
;
1419 u_char nexthop_type
;
1420 unsigned long ifindex
;
1421 struct prefix_ipv4 p
;
1423 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1424 static unsigned int ifindices
[MULTIPATH_NUM
];
1427 /* Get input stream. */
1431 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1433 /* Allocate new rib. */
1434 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1436 /* Type, flags, message. */
1437 rib
->type
= stream_getc (s
);
1438 rib
->instance
= stream_getw (s
);
1439 rib
->flags
= stream_getc (s
);
1440 message
= stream_getc (s
);
1441 safi
= stream_getw (s
);
1442 rib
->uptime
= time (NULL
);
1445 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1447 p
.prefixlen
= stream_getc (s
);
1448 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1451 rib
->vrf_id
= zvrf
->vrf_id
;
1453 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1454 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1455 * these. Clients should send the same number of paired set of
1456 * next-hop-addr/next-hop-ifindices. */
1457 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1463 nexthop_num
= stream_getc (s
);
1464 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1465 for (i
= 0; i
< nexthop_num
; i
++)
1467 nexthop_type
= stream_getc (s
);
1469 switch (nexthop_type
)
1471 case ZEBRA_NEXTHOP_IPV6
:
1472 stream_get (&nexthop
, s
, 16);
1473 if (nh_count
< MULTIPATH_NUM
) {
1474 nexthops
[nh_count
++] = nexthop
;
1477 case ZEBRA_NEXTHOP_IFINDEX
:
1478 if (if_count
< MULTIPATH_NUM
) {
1479 ifindices
[if_count
++] = stream_getl (s
);
1482 case ZEBRA_NEXTHOP_BLACKHOLE
:
1483 rib_nexthop_blackhole_add (rib
);
1488 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1489 for (i
= 0; i
< max_nh_if
; i
++)
1491 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1492 if ((i
< if_count
) && ifindices
[i
]) {
1493 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1496 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1500 if ((i
< if_count
) && ifindices
[i
]) {
1501 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1508 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1509 rib
->distance
= stream_getc (s
);
1512 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1513 rib
->metric
= stream_getl (s
);
1516 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1517 rib
->tag
= stream_getw (s
);
1522 rib
->table
= zvrf
->table_id
;
1524 ret
= rib_add_ipv6_multipath ((struct prefix
*)&p
, rib
, safi
, ifindex
);
1527 client
->v4_route_add_cnt
++;
1529 client
->v4_route_upd8_cnt
++;
1535 zread_ipv6_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1539 struct in6_addr nexthop
;
1543 u_char nexthop_type
;
1544 unsigned long ifindex
;
1545 struct prefix_ipv6 p
;
1547 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1548 static unsigned int ifindices
[MULTIPATH_NUM
];
1551 /* Get input stream. */
1555 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1557 /* Allocate new rib. */
1558 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1560 /* Type, flags, message. */
1561 rib
->type
= stream_getc (s
);
1562 rib
->instance
= stream_getw (s
);
1563 rib
->flags
= stream_getc (s
);
1564 message
= stream_getc (s
);
1565 safi
= stream_getw (s
);
1566 rib
->uptime
= time (NULL
);
1569 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1570 p
.family
= AF_INET6
;
1571 p
.prefixlen
= stream_getc (s
);
1572 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1574 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1575 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1576 * these. Clients should send the same number of paired set of
1577 * next-hop-addr/next-hop-ifindices. */
1578 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1584 nexthop_num
= stream_getc (s
);
1585 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1586 for (i
= 0; i
< nexthop_num
; i
++)
1588 nexthop_type
= stream_getc (s
);
1590 switch (nexthop_type
)
1592 case ZEBRA_NEXTHOP_IPV6
:
1593 stream_get (&nexthop
, s
, 16);
1594 if (nh_count
< MULTIPATH_NUM
) {
1595 nexthops
[nh_count
++] = nexthop
;
1598 case ZEBRA_NEXTHOP_IFINDEX
:
1599 if (if_count
< MULTIPATH_NUM
) {
1600 ifindices
[if_count
++] = stream_getl (s
);
1603 case ZEBRA_NEXTHOP_BLACKHOLE
:
1604 rib_nexthop_blackhole_add (rib
);
1609 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1610 for (i
= 0; i
< max_nh_if
; i
++)
1612 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1613 if ((i
< if_count
) && ifindices
[i
])
1614 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1616 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1619 if ((i
< if_count
) && ifindices
[i
])
1620 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1626 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1627 rib
->distance
= stream_getc (s
);
1630 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1631 rib
->metric
= stream_getl (s
);
1634 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1635 rib
->tag
= stream_getw (s
);
1640 rib
->vrf_id
= zvrf
->vrf_id
;
1641 rib
->table
= zvrf
->table_id
;
1643 ret
= rib_add_ipv6_multipath ((struct prefix
*)&p
, rib
, safi
, ifindex
);
1646 client
->v6_route_add_cnt
++;
1648 client
->v6_route_upd8_cnt
++;
1653 /* Zebra server IPv6 prefix delete function. */
1655 zread_ipv6_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1659 struct zapi_ipv6 api
;
1660 struct in6_addr nexthop
;
1661 unsigned long ifindex
;
1662 struct prefix_ipv6 p
;
1666 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1668 /* Type, flags, message. */
1669 api
.type
= stream_getc (s
);
1670 api
.instance
= stream_getw (s
);
1671 api
.flags
= stream_getc (s
);
1672 api
.message
= stream_getc (s
);
1673 api
.safi
= stream_getw (s
);
1676 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1677 p
.family
= AF_INET6
;
1678 p
.prefixlen
= stream_getc (s
);
1679 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1681 /* Nexthop, ifindex, distance, metric. */
1682 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1684 u_char nexthop_type
;
1686 api
.nexthop_num
= stream_getc (s
);
1687 for (i
= 0; i
< api
.nexthop_num
; i
++)
1689 nexthop_type
= stream_getc (s
);
1691 switch (nexthop_type
)
1693 case ZEBRA_NEXTHOP_IPV6
:
1694 stream_get (&nexthop
, s
, 16);
1696 case ZEBRA_NEXTHOP_IFINDEX
:
1697 ifindex
= stream_getl (s
);
1704 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1705 api
.distance
= stream_getc (s
);
1710 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1711 api
.metric
= stream_getl (s
);
1716 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1717 api
.tag
= stream_getw (s
);
1721 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1722 rib_delete_ipv6 (api
.type
, api
.instance
, api
.flags
, &p
, NULL
, ifindex
,
1723 zvrf
->vrf_id
, client
->rtm_table
, api
.safi
);
1725 rib_delete_ipv6 (api
.type
, api
.instance
, api
.flags
, &p
, &nexthop
, ifindex
,
1726 zvrf
->vrf_id
, client
->rtm_table
, api
.safi
);
1728 client
->v6_route_del_cnt
++;
1733 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
,
1734 struct zebra_vrf
*zvrf
)
1736 struct in6_addr addr
;
1739 stream_get (&addr
, client
->ibuf
, 16);
1740 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1741 zlog_debug("%s: looking up %s", __func__
,
1742 inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1744 return zsend_ipv6_nexthop_lookup (client
, &addr
, zvrf
->vrf_id
);
1747 /* Register zebra server router-id information. Send current router-id */
1749 zread_router_id_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1753 /* Router-id information is needed. */
1754 vrf_bitmap_set (client
->ridinfo
, zvrf
->vrf_id
);
1756 router_id_get (&p
, zvrf
->vrf_id
);
1758 return zsend_router_id_update (client
, &p
, zvrf
->vrf_id
);
1761 /* Unregister zebra server router-id information. */
1763 zread_router_id_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1765 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1769 /* Tie up route-type and client->sock */
1771 zread_hello (struct zserv
*client
)
1773 /* type of protocol (lib/zebra.h) */
1777 proto
= stream_getc (client
->ibuf
);
1778 instance
= stream_getw (client
->ibuf
);
1780 /* accept only dynamic routing protocols */
1781 if ((proto
< ZEBRA_ROUTE_MAX
)
1782 && (proto
> ZEBRA_ROUTE_STATIC
))
1784 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1785 client
->sock
, zebra_route_string(proto
));
1787 zlog_notice ("client protocol instance %d", instance
);
1789 client
->proto
= proto
;
1790 client
->instance
= instance
;
1794 /* Unregister all information in a VRF. */
1796 zread_vrf_unregister (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1801 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1802 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1803 vrf_bitmap_unset (client
->redist
[afi
][i
], zvrf
->vrf_id
);
1804 vrf_bitmap_unset (client
->redist_default
, zvrf
->vrf_id
);
1805 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1806 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1811 /* Cleanup registered nexthops (across VRFs) upon client disconnect. */
1813 zebra_client_close_cleanup_rnh (struct zserv
*client
)
1816 struct zebra_vrf
*zvrf
;
1818 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
1820 if ((zvrf
= vrf_iter2info (iter
)) != NULL
)
1822 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_NEXTHOP_TYPE
);
1823 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_NEXTHOP_TYPE
);
1824 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_IMPORT_CHECK_TYPE
);
1825 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_IMPORT_CHECK_TYPE
);
1830 /* Close zebra client. */
1832 zebra_client_close (struct zserv
*client
)
1834 /* Send client de-registration to BFD */
1835 zebra_ptm_bfd_client_deregister(client
->proto
);
1837 /* Cleanup any registered nexthops - across all VRFs. */
1838 zebra_client_close_cleanup_rnh (client
);
1840 /* Close file descriptor. */
1843 unsigned long nroutes
;
1845 close (client
->sock
);
1846 nroutes
= rib_score_proto (client
->proto
, client
->instance
);
1847 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1848 client
->sock
, nroutes
, zebra_route_string (client
->proto
));
1852 /* Free stream buffers. */
1854 stream_free (client
->ibuf
);
1856 stream_free (client
->obuf
);
1858 buffer_free(client
->wb
);
1860 /* Release threads. */
1862 thread_cancel (client
->t_read
);
1863 if (client
->t_write
)
1864 thread_cancel (client
->t_write
);
1865 if (client
->t_suicide
)
1866 thread_cancel (client
->t_suicide
);
1868 /* Free client structure. */
1869 listnode_delete (zebrad
.client_list
, client
);
1870 XFREE (MTYPE_TMP
, client
);
1873 /* Make new client. */
1875 zebra_client_create (int sock
)
1877 struct zserv
*client
;
1881 client
= XCALLOC (MTYPE_TMP
, sizeof (struct zserv
));
1883 /* Make client input/output buffer. */
1884 client
->sock
= sock
;
1885 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1886 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1887 client
->wb
= buffer_new(0);
1889 /* Set table number. */
1890 client
->rtm_table
= zebrad
.rtm_table_default
;
1892 client
->connect_time
= quagga_monotime();
1893 /* Initialize flags */
1894 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1895 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1896 client
->redist
[afi
][i
] = vrf_bitmap_init ();
1897 client
->redist_default
= vrf_bitmap_init ();
1898 client
->ifinfo
= vrf_bitmap_init ();
1899 client
->ridinfo
= vrf_bitmap_init ();
1901 /* Add this client to linked list. */
1902 listnode_add (zebrad
.client_list
, client
);
1904 /* Make new read thread. */
1905 zebra_event (ZEBRA_READ
, sock
, client
);
1907 zebra_vrf_update_all (client
);
1910 /* Handler of zebra service request. */
1912 zebra_client_read (struct thread
*thread
)
1915 struct zserv
*client
;
1917 uint16_t length
, command
;
1918 uint8_t marker
, version
;
1920 struct zebra_vrf
*zvrf
;
1922 /* Get thread data. Reset reading thread because I'm running. */
1923 sock
= THREAD_FD (thread
);
1924 client
= THREAD_ARG (thread
);
1925 client
->t_read
= NULL
;
1927 if (client
->t_suicide
)
1929 zebra_client_close(client
);
1933 /* Read length and command (if we don't have it already). */
1934 if ((already
= stream_get_endp(client
->ibuf
)) < ZEBRA_HEADER_SIZE
)
1937 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1938 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
1941 if (IS_ZEBRA_DEBUG_EVENT
)
1942 zlog_debug ("connection closed socket [%d]", sock
);
1943 zebra_client_close (client
);
1946 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
1948 /* Try again later. */
1949 zebra_event (ZEBRA_READ
, sock
, client
);
1952 already
= ZEBRA_HEADER_SIZE
;
1955 /* Reset to read from the beginning of the incoming packet. */
1956 stream_set_getp(client
->ibuf
, 0);
1958 /* Fetch header values */
1959 length
= stream_getw (client
->ibuf
);
1960 marker
= stream_getc (client
->ibuf
);
1961 version
= stream_getc (client
->ibuf
);
1962 vrf_id
= stream_getw (client
->ibuf
);
1963 command
= stream_getw (client
->ibuf
);
1965 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
1967 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1968 __func__
, sock
, marker
, version
);
1969 zebra_client_close (client
);
1972 if (length
< ZEBRA_HEADER_SIZE
)
1974 zlog_warn("%s: socket %d message length %u is less than header size %d",
1975 __func__
, sock
, length
, ZEBRA_HEADER_SIZE
);
1976 zebra_client_close (client
);
1979 if (length
> STREAM_SIZE(client
->ibuf
))
1981 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1982 __func__
, sock
, length
, (u_long
)STREAM_SIZE(client
->ibuf
));
1983 zebra_client_close (client
);
1987 /* Read rest of data. */
1988 if (already
< length
)
1991 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1992 length
-already
)) == 0) ||
1995 if (IS_ZEBRA_DEBUG_EVENT
)
1996 zlog_debug ("connection closed [%d] when reading zebra data", sock
);
1997 zebra_client_close (client
);
2000 if (nbyte
!= (ssize_t
)(length
-already
))
2002 /* Try again later. */
2003 zebra_event (ZEBRA_READ
, sock
, client
);
2008 length
-= ZEBRA_HEADER_SIZE
;
2010 /* Debug packet information. */
2011 if (IS_ZEBRA_DEBUG_EVENT
)
2012 zlog_debug ("zebra message comes from socket [%d]", sock
);
2014 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
2015 zlog_debug ("zebra message received [%s] %d in VRF %u",
2016 zserv_command_string (command
), length
, vrf_id
);
2018 client
->last_read_time
= quagga_monotime();
2019 client
->last_read_cmd
= command
;
2021 zvrf
= zebra_vrf_lookup (vrf_id
);
2024 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
2025 zlog_debug ("zebra received unknown VRF[%u]", vrf_id
);
2026 goto zclient_read_out
;
2031 case ZEBRA_ROUTER_ID_ADD
:
2032 zread_router_id_add (client
, length
, zvrf
);
2034 case ZEBRA_ROUTER_ID_DELETE
:
2035 zread_router_id_delete (client
, length
, zvrf
);
2037 case ZEBRA_INTERFACE_ADD
:
2038 zread_interface_add (client
, length
, zvrf
);
2040 case ZEBRA_INTERFACE_DELETE
:
2041 zread_interface_delete (client
, length
, zvrf
);
2043 case ZEBRA_IPV4_ROUTE_ADD
:
2044 zread_ipv4_add (client
, length
, zvrf
);
2046 case ZEBRA_IPV4_ROUTE_DELETE
:
2047 zread_ipv4_delete (client
, length
, zvrf
);
2049 case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD
:
2050 zread_ipv4_route_ipv6_nexthop_add (client
, length
, zvrf
);
2052 case ZEBRA_IPV6_ROUTE_ADD
:
2053 zread_ipv6_add (client
, length
, zvrf
);
2055 case ZEBRA_IPV6_ROUTE_DELETE
:
2056 zread_ipv6_delete (client
, length
, zvrf
);
2058 case ZEBRA_REDISTRIBUTE_ADD
:
2059 zebra_redistribute_add (command
, client
, length
, zvrf
);
2061 case ZEBRA_REDISTRIBUTE_DELETE
:
2062 zebra_redistribute_delete (command
, client
, length
, zvrf
);
2064 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
2065 zebra_redistribute_default_add (command
, client
, length
, zvrf
);
2067 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
2068 zebra_redistribute_default_delete (command
, client
, length
, zvrf
);
2070 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
2071 zread_ipv4_nexthop_lookup (client
, length
, zvrf
);
2073 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
:
2074 zread_ipv4_nexthop_lookup_mrib (client
, length
, zvrf
);
2076 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
2077 zread_ipv6_nexthop_lookup (client
, length
, zvrf
);
2079 case ZEBRA_IPV4_IMPORT_LOOKUP
:
2080 zread_ipv4_import_lookup (client
, length
, zvrf
);
2083 zread_hello (client
);
2085 case ZEBRA_NEXTHOP_REGISTER
:
2086 zserv_rnh_register(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
2088 case ZEBRA_NEXTHOP_UNREGISTER
:
2089 zserv_rnh_unregister(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
2091 case ZEBRA_IMPORT_ROUTE_REGISTER
:
2092 zserv_rnh_register(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
2094 case ZEBRA_IMPORT_ROUTE_UNREGISTER
:
2095 zserv_rnh_unregister(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
2097 case ZEBRA_BFD_DEST_UPDATE
:
2098 case ZEBRA_BFD_DEST_REGISTER
:
2099 zebra_ptm_bfd_dst_register(client
, sock
, length
, command
, zvrf
);
2101 case ZEBRA_BFD_DEST_DEREGISTER
:
2102 zebra_ptm_bfd_dst_deregister(client
, sock
, length
, zvrf
);
2104 case ZEBRA_VRF_UNREGISTER
:
2105 zread_vrf_unregister (client
, length
, zvrf
);
2107 case ZEBRA_BFD_CLIENT_REGISTER
:
2108 zebra_ptm_bfd_client_register(client
, sock
, length
);
2110 case ZEBRA_INTERFACE_ENABLE_RADV
:
2111 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 1);
2113 case ZEBRA_INTERFACE_DISABLE_RADV
:
2114 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 0);
2117 zlog_info ("Zebra received unknown command %d", command
);
2121 if (client
->t_suicide
)
2123 /* No need to wait for thread callback, just kill immediately. */
2124 zebra_client_close(client
);
2129 stream_reset (client
->ibuf
);
2130 zebra_event (ZEBRA_READ
, sock
, client
);
2135 /* Accept code of zebra server socket. */
2137 zebra_accept (struct thread
*thread
)
2141 struct sockaddr_in client
;
2144 accept_sock
= THREAD_FD (thread
);
2146 /* Reregister myself. */
2147 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2149 len
= sizeof (struct sockaddr_in
);
2150 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
2152 if (client_sock
< 0)
2154 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno
));
2158 /* Make client socket non-blocking. */
2159 set_nonblocking(client_sock
);
2161 /* Create new zebra client. */
2162 zebra_client_create (client_sock
);
2167 #ifdef HAVE_TCP_ZEBRA
2168 /* Make zebra's server socket. */
2174 struct sockaddr_in addr
;
2176 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
2178 if (accept_sock
< 0)
2180 zlog_warn ("Can't create zserv stream socket: %s",
2181 safe_strerror (errno
));
2182 zlog_warn ("zebra can't provice full functionality due to above error");
2186 memset (&addr
, 0, sizeof (struct sockaddr_in
));
2187 addr
.sin_family
= AF_INET
;
2188 addr
.sin_port
= htons (ZEBRA_PORT
);
2189 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2190 addr
.sin_len
= sizeof (struct sockaddr_in
);
2191 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
2192 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
2194 sockopt_reuseaddr (accept_sock
);
2195 sockopt_reuseport (accept_sock
);
2197 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
2198 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
2200 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
2201 sizeof (struct sockaddr_in
));
2204 zlog_warn ("Can't bind to stream socket: %s",
2205 safe_strerror (errno
));
2206 zlog_warn ("zebra can't provice full functionality due to above error");
2207 close (accept_sock
); /* Avoid sd leak. */
2211 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
2212 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
2214 ret
= listen (accept_sock
, 1);
2217 zlog_warn ("Can't listen to stream socket: %s",
2218 safe_strerror (errno
));
2219 zlog_warn ("zebra can't provice full functionality due to above error");
2220 close (accept_sock
); /* Avoid sd leak. */
2224 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2226 #else /* HAVE_TCP_ZEBRA */
2228 /* For sockaddr_un. */
2231 /* zebra server UNIX domain socket. */
2233 zebra_serv_un (const char *path
)
2237 struct sockaddr_un serv
;
2240 /* First of all, unlink existing socket */
2244 old_mask
= umask (0077);
2246 /* Make UNIX domain socket. */
2247 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
2250 zlog_warn ("Can't create zserv unix socket: %s",
2251 safe_strerror (errno
));
2252 zlog_warn ("zebra can't provide full functionality due to above error");
2256 /* Make server socket. */
2257 memset (&serv
, 0, sizeof (struct sockaddr_un
));
2258 serv
.sun_family
= AF_UNIX
;
2259 strncpy (serv
.sun_path
, path
, strlen (path
));
2260 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2261 len
= serv
.sun_len
= SUN_LEN(&serv
);
2263 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
2264 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2266 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
2269 zlog_warn ("Can't bind to unix socket %s: %s",
2270 path
, safe_strerror (errno
));
2271 zlog_warn ("zebra can't provide full functionality due to above error");
2276 ret
= listen (sock
, 5);
2279 zlog_warn ("Can't listen to unix socket %s: %s",
2280 path
, safe_strerror (errno
));
2281 zlog_warn ("zebra can't provide full functionality due to above error");
2288 zebra_event (ZEBRA_SERV
, sock
, NULL
);
2290 #endif /* HAVE_TCP_ZEBRA */
2294 zebra_event (enum event event
, int sock
, struct zserv
*client
)
2299 thread_add_read (zebrad
.master
, zebra_accept
, client
, sock
);
2303 thread_add_read (zebrad
.master
, zebra_client_read
, client
, sock
);
2311 #define ZEBRA_TIME_BUF 32
2313 zserv_time_buf(time_t *time1
, char *buf
, int buflen
)
2318 assert (buf
!= NULL
);
2319 assert (buflen
>= ZEBRA_TIME_BUF
);
2320 assert (time1
!= NULL
);
2324 snprintf(buf
, buflen
, "never ");
2328 now
= quagga_monotime();
2332 /* Making formatted timer strings. */
2333 #define ONE_DAY_SECOND 60*60*24
2334 #define ONE_WEEK_SECOND 60*60*24*7
2336 if (now
< ONE_DAY_SECOND
)
2337 snprintf (buf
, buflen
, "%02d:%02d:%02d",
2338 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
2339 else if (now
< ONE_WEEK_SECOND
)
2340 snprintf (buf
, buflen
, "%dd%02dh%02dm",
2341 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
2343 snprintf (buf
, buflen
, "%02dw%dd%02dh",
2344 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
2349 zebra_show_client_detail (struct vty
*vty
, struct zserv
*client
)
2351 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2352 char wbuf
[ZEBRA_TIME_BUF
], nhbuf
[ZEBRA_TIME_BUF
], mbuf
[ZEBRA_TIME_BUF
];
2354 vty_out (vty
, "Client: %s", zebra_route_string(client
->proto
));
2355 if (client
->instance
)
2356 vty_out (vty
, " Instance: %d", client
->instance
);
2357 vty_out (vty
, "%s", VTY_NEWLINE
);
2359 vty_out (vty
, "------------------------ %s", VTY_NEWLINE
);
2360 vty_out (vty
, "FD: %d %s", client
->sock
, VTY_NEWLINE
);
2361 vty_out (vty
, "Route Table ID: %d %s", client
->rtm_table
, VTY_NEWLINE
);
2363 vty_out (vty
, "Connect Time: %s %s",
2364 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2366 if (client
->nh_reg_time
)
2368 vty_out (vty
, "Nexthop Registry Time: %s %s",
2369 zserv_time_buf(&client
->nh_reg_time
, nhbuf
, ZEBRA_TIME_BUF
),
2371 if (client
->nh_last_upd_time
)
2372 vty_out (vty
, "Nexthop Last Update Time: %s %s",
2373 zserv_time_buf(&client
->nh_last_upd_time
, mbuf
, ZEBRA_TIME_BUF
),
2376 vty_out (vty
, "No Nexthop Update sent%s", VTY_NEWLINE
);
2379 vty_out (vty
, "Not registered for Nexthop Updates%s", VTY_NEWLINE
);
2381 vty_out (vty
, "Last Msg Rx Time: %s %s",
2382 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2384 vty_out (vty
, "Last Msg Tx Time: %s %s",
2385 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2387 if (client
->last_read_time
)
2388 vty_out (vty
, "Last Rcvd Cmd: %s %s",
2389 zserv_command_string(client
->last_read_cmd
), VTY_NEWLINE
);
2390 if (client
->last_write_time
)
2391 vty_out (vty
, "Last Sent Cmd: %s %s",
2392 zserv_command_string(client
->last_write_cmd
), VTY_NEWLINE
);
2393 vty_out (vty
, "%s", VTY_NEWLINE
);
2395 vty_out (vty
, "Type Add Update Del %s", VTY_NEWLINE
);
2396 vty_out (vty
, "================================================== %s", VTY_NEWLINE
);
2397 vty_out (vty
, "IPv4 %-12d%-12d%-12d%s", client
->v4_route_add_cnt
,
2398 client
->v4_route_upd8_cnt
, client
->v4_route_del_cnt
, VTY_NEWLINE
);
2399 vty_out (vty
, "IPv6 %-12d%-12d%-12d%s", client
->v6_route_add_cnt
,
2400 client
->v6_route_upd8_cnt
, client
->v6_route_del_cnt
, VTY_NEWLINE
);
2401 vty_out (vty
, "Redist:v4 %-12d%-12d%-12d%s", client
->redist_v4_add_cnt
, 0,
2402 client
->redist_v4_del_cnt
, VTY_NEWLINE
);
2403 vty_out (vty
, "Redist:v6 %-12d%-12d%-12d%s", client
->redist_v6_add_cnt
, 0,
2404 client
->redist_v6_del_cnt
, VTY_NEWLINE
);
2405 vty_out (vty
, "Connected %-12d%-12d%-12d%s", client
->ifadd_cnt
, 0,
2406 client
->ifdel_cnt
, VTY_NEWLINE
);
2407 vty_out (vty
, "BFD peer %-12d%-12d%-12d%s", client
->bfd_peer_add_cnt
,
2408 client
->bfd_peer_upd8_cnt
, client
->bfd_peer_del_cnt
, VTY_NEWLINE
);
2409 vty_out (vty
, "Interface Up Notifications: %d%s", client
->ifup_cnt
,
2411 vty_out (vty
, "Interface Down Notifications: %d%s", client
->ifdown_cnt
,
2414 vty_out (vty
, "%s", VTY_NEWLINE
);
2419 zebra_show_client_brief (struct vty
*vty
, struct zserv
*client
)
2421 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2422 char wbuf
[ZEBRA_TIME_BUF
];
2424 vty_out (vty
, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
2425 zebra_route_string(client
->proto
),
2426 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2427 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2428 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2429 client
->v4_route_add_cnt
+client
->v4_route_upd8_cnt
,
2430 client
->v4_route_del_cnt
,
2431 client
->v6_route_add_cnt
+client
->v6_route_upd8_cnt
,
2432 client
->v6_route_del_cnt
, VTY_NEWLINE
);
2437 /* Display default rtm_table for all clients. */
2442 "default routing table to use for all clients\n")
2444 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2449 DEFUN (config_table
,
2452 "Configure target kernel routing table\n"
2455 zebrad
.rtm_table_default
= strtol (argv
[0], (char**)0, 10);
2459 DEFUN (no_config_table
,
2460 no_config_table_cmd
,
2463 "Configure target kernel routing table\n"
2466 zebrad
.rtm_table_default
= 0;
2470 DEFUN (ip_forwarding
,
2474 "Turn on IP forwarding")
2480 ret
= ipforward_on ();
2484 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
2491 DEFUN (no_ip_forwarding
,
2492 no_ip_forwarding_cmd
,
2496 "Turn off IP forwarding")
2502 ret
= ipforward_off ();
2506 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
2513 /* This command is for debugging purpose. */
2514 DEFUN (show_zebra_client
,
2515 show_zebra_client_cmd
,
2516 "show zebra client",
2519 "Client information")
2521 struct listnode
*node
;
2522 struct zserv
*client
;
2524 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2525 zebra_show_client_detail(vty
, client
);
2530 /* This command is for debugging purpose. */
2531 DEFUN (show_zebra_client_summary
,
2532 show_zebra_client_summary_cmd
,
2533 "show zebra client summary",
2535 "Zebra information brief"
2536 "Client information brief")
2538 struct listnode
*node
;
2539 struct zserv
*client
;
2541 vty_out (vty
, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
2543 vty_out (vty
,"--------------------------------------------------------------------------------%s",
2546 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2547 zebra_show_client_brief(vty
, client
);
2549 vty_out (vty
, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE
);
2553 /* Table configuration write function. */
2555 config_write_table (struct vty
*vty
)
2557 if (zebrad
.rtm_table_default
)
2558 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2563 /* table node for routing tables. */
2564 static struct cmd_node table_node
=
2567 "", /* This node has no interface. */
2571 /* Only display ip forwarding is enabled or not. */
2572 DEFUN (show_ip_forwarding
,
2573 show_ip_forwarding_cmd
,
2574 "show ip forwarding",
2577 "IP forwarding status\n")
2584 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
2586 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
2591 /* Only display ipv6 forwarding is enabled or not. */
2592 DEFUN (show_ipv6_forwarding
,
2593 show_ipv6_forwarding_cmd
,
2594 "show ipv6 forwarding",
2596 "IPv6 information\n"
2597 "Forwarding status\n")
2601 ret
= ipforward_ipv6 ();
2606 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
2609 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2612 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
2615 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2621 DEFUN (ipv6_forwarding
,
2622 ipv6_forwarding_cmd
,
2625 "Turn on IPv6 forwarding")
2629 ret
= ipforward_ipv6 ();
2631 ret
= ipforward_ipv6_on ();
2635 vty_out (vty
, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE
);
2642 DEFUN (no_ipv6_forwarding
,
2643 no_ipv6_forwarding_cmd
,
2644 "no ipv6 forwarding",
2647 "Turn off IPv6 forwarding")
2651 ret
= ipforward_ipv6 ();
2653 ret
= ipforward_ipv6_off ();
2657 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
2664 #endif /* HAVE_IPV6 */
2666 /* IPForwarding configuration write function. */
2668 config_write_forwarding (struct vty
*vty
)
2670 /* FIXME: Find better place for that. */
2671 router_id_write (vty
);
2674 vty_out (vty
, "no ip forwarding%s", VTY_NEWLINE
);
2676 if (!ipforward_ipv6 ())
2677 vty_out (vty
, "no ipv6 forwarding%s", VTY_NEWLINE
);
2678 #endif /* HAVE_IPV6 */
2679 vty_out (vty
, "!%s", VTY_NEWLINE
);
2683 /* table node for routing tables. */
2684 static struct cmd_node forwarding_node
=
2687 "", /* This node has no interface. */
2692 /* Initialisation of zebra and installation of commands. */
2696 /* Client list init. */
2697 zebrad
.client_list
= list_new ();
2699 /* Install configuration write function. */
2700 install_node (&table_node
, config_write_table
);
2701 install_node (&forwarding_node
, config_write_forwarding
);
2703 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
2704 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
2705 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
2706 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
2707 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
2708 install_element (ENABLE_NODE
, &show_zebra_client_summary_cmd
);
2711 install_element (VIEW_NODE
, &show_table_cmd
);
2712 install_element (ENABLE_NODE
, &show_table_cmd
);
2713 install_element (CONFIG_NODE
, &config_table_cmd
);
2714 install_element (CONFIG_NODE
, &no_config_table_cmd
);
2715 #endif /* HAVE_NETLINK */
2718 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2719 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
2720 install_element (CONFIG_NODE
, &ipv6_forwarding_cmd
);
2721 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2722 #endif /* HAVE_IPV6 */
2725 zebra_route_map_init ();
2728 /* Make zebra server socket, wiping any existing one (see bug #403). */
2730 zebra_zserv_socket_init (char *path
)
2732 #ifdef HAVE_TCP_ZEBRA
2735 zebra_serv_un (path
? path
: ZEBRA_SERV_PATH
);
2736 #endif /* HAVE_TCP_ZEBRA */