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.
30 #include "zebra_memory.h"
34 #include "sockunion.h"
43 #include "zebra/zserv.h"
44 #include "zebra/zebra_ns.h"
45 #include "zebra/zebra_vrf.h"
46 #include "zebra/router-id.h"
47 #include "zebra/redistribute.h"
48 #include "zebra/debug.h"
49 #include "zebra/ipforward.h"
50 #include "zebra/zebra_rnh.h"
51 #include "zebra/rt_netlink.h"
52 #include "zebra/interface.h"
53 #include "zebra/zebra_ptm.h"
54 #include "zebra/rtadv.h"
55 #include "zebra/zebra_mpls.h"
57 /* Event list of zebra. */
58 enum event
{ ZEBRA_SERV
, ZEBRA_READ
, ZEBRA_WRITE
};
60 static void zebra_event (enum event event
, int sock
, struct zserv
*client
);
62 extern struct zebra_privs_t zserv_privs
;
64 static void zebra_client_close (struct zserv
*client
);
67 zserv_delayed_close(struct thread
*thread
)
69 struct zserv
*client
= THREAD_ARG(thread
);
71 client
->t_suicide
= NULL
;
72 zebra_client_close(client
);
77 zserv_flush_data(struct thread
*thread
)
79 struct zserv
*client
= THREAD_ARG(thread
);
81 client
->t_write
= NULL
;
82 if (client
->t_suicide
)
84 zebra_client_close(client
);
87 switch (buffer_flush_available(client
->wb
, client
->sock
))
90 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
91 "closing", __func__
, client
->sock
);
92 zebra_client_close(client
);
95 client
->t_write
= thread_add_write(zebrad
.master
, zserv_flush_data
,
96 client
, client
->sock
);
102 client
->last_write_time
= quagga_monotime();
107 zebra_server_send_message(struct zserv
*client
)
109 if (client
->t_suicide
)
112 stream_set_getp(client
->obuf
, 0);
113 client
->last_write_cmd
= stream_getw_from(client
->obuf
, 6);
114 switch (buffer_write(client
->wb
, client
->sock
, STREAM_DATA(client
->obuf
),
115 stream_get_endp(client
->obuf
)))
118 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
119 __func__
, client
->sock
);
120 /* Schedule a delayed close since many of the functions that call this
121 one do not check the return code. They do not allow for the
122 possibility that an I/O error may have caused the client to be
124 client
->t_suicide
= thread_add_event(zebrad
.master
, zserv_delayed_close
,
128 THREAD_OFF(client
->t_write
);
131 THREAD_WRITE_ON(zebrad
.master
, client
->t_write
,
132 zserv_flush_data
, client
, client
->sock
);
136 client
->last_write_time
= quagga_monotime();
141 zserv_create_header (struct stream
*s
, uint16_t cmd
, vrf_id_t vrf_id
)
143 /* length placeholder, caller can update */
144 stream_putw (s
, ZEBRA_HEADER_SIZE
);
145 stream_putc (s
, ZEBRA_HEADER_MARKER
);
146 stream_putc (s
, ZSERV_VERSION
);
147 stream_putw (s
, vrf_id
);
148 stream_putw (s
, cmd
);
152 zserv_encode_interface (struct stream
*s
, struct interface
*ifp
)
154 /* Interface information. */
155 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
156 stream_putl (s
, ifp
->ifindex
);
157 stream_putc (s
, ifp
->status
);
158 stream_putq (s
, ifp
->flags
);
159 stream_putc (s
, ifp
->ptm_enable
);
160 stream_putc (s
, ifp
->ptm_status
);
161 stream_putl (s
, ifp
->metric
);
162 stream_putl (s
, ifp
->mtu
);
163 stream_putl (s
, ifp
->mtu6
);
164 stream_putl (s
, ifp
->bandwidth
);
165 stream_putl (s
, ifp
->ll_type
);
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
);
170 /* Then, Traffic Engineering parameters if any */
171 if (HAS_LINK_PARAMS(ifp
) && IS_LINK_PARAMS_SET(ifp
->link_params
))
174 zebra_interface_link_params_write (s
, ifp
);
179 /* Write packet size. */
180 stream_putw_at (s
, 0, stream_get_endp (s
));
184 zserv_encode_vrf (struct stream
*s
, struct zebra_vrf
*zvrf
)
186 /* Interface information. */
187 stream_put (s
, zvrf
->name
, VRF_NAMSIZ
);
189 /* Write packet size. */
190 stream_putw_at (s
, 0, stream_get_endp (s
));
193 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
195 * This function is called in the following situations:
196 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
198 * - at startup, when zebra figures out the available interfaces
199 * - when an interface is added (where support for
200 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
201 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
205 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
212 zserv_create_header (s
, ZEBRA_INTERFACE_ADD
, ifp
->vrf_id
);
213 zserv_encode_interface (s
, ifp
);
216 return zebra_server_send_message(client
);
219 /* Interface deletion from zebra daemon. */
221 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
228 zserv_create_header (s
, ZEBRA_INTERFACE_DELETE
, ifp
->vrf_id
);
229 zserv_encode_interface (s
, ifp
);
232 return zebra_server_send_message (client
);
236 zsend_vrf_add (struct zserv
*client
, struct zebra_vrf
*zvrf
)
243 zserv_create_header (s
, ZEBRA_VRF_ADD
, zvrf
->vrf_id
);
244 zserv_encode_vrf (s
, zvrf
);
246 client
->vrfadd_cnt
++;
247 return zebra_server_send_message(client
);
250 /* VRF deletion from zebra daemon. */
252 zsend_vrf_delete (struct zserv
*client
, struct zebra_vrf
*zvrf
)
259 zserv_create_header (s
, ZEBRA_VRF_DELETE
, zvrf
->vrf_id
);
260 zserv_encode_vrf (s
, zvrf
);
262 client
->vrfdel_cnt
++;
263 return zebra_server_send_message (client
);
267 zsend_interface_link_params (struct zserv
*client
, struct interface
*ifp
)
271 /* Check this client need interface information. */
272 if (! client
->ifinfo
)
275 if (!ifp
->link_params
)
280 zserv_create_header (s
, ZEBRA_INTERFACE_LINK_PARAMS
, ifp
->vrf_id
);
282 /* Add Interface Index */
283 stream_putl (s
, ifp
->ifindex
);
285 /* Then TE Link Parameters */
286 if (zebra_interface_link_params_write (s
, ifp
) == 0)
289 /* Write packet size. */
290 stream_putw_at (s
, 0, stream_get_endp (s
));
292 return zebra_server_send_message (client
);
295 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
296 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
298 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
299 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
300 * from the client, after the ZEBRA_INTERFACE_ADD has been
301 * sent from zebra to the client
302 * - redistribute new address info to all clients in the following situations
303 * - at startup, when zebra figures out the available interfaces
304 * - when an interface is added (where support for
305 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
306 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
308 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
309 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
310 * - when an RTM_NEWADDR message is received from the kernel,
312 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
314 * zsend_interface_address(DELETE)
317 * zebra_interface_address_delete_update
319 * | | if_delete_update
321 * ip_address_uninstall connected_delete_ipv4
322 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
325 * | RTM_NEWADDR on routing/netlink socket
328 * "no ip address A.B.C.D/M [label LINE]"
329 * "no ip address A.B.C.D/M secondary"
330 * ["no ipv6 address X:X::X:X/M"]
334 zsend_interface_address (int cmd
, struct zserv
*client
,
335 struct interface
*ifp
, struct connected
*ifc
)
344 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
345 stream_putl (s
, ifp
->ifindex
);
347 /* Interface address flag. */
348 stream_putc (s
, ifc
->flags
);
350 /* Prefix information. */
352 stream_putc (s
, p
->family
);
353 blen
= prefix_blen (p
);
354 stream_put (s
, &p
->u
.prefix
, blen
);
357 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
358 * but zebra_interface_address_delete_read() in the gnu version
361 stream_putc (s
, p
->prefixlen
);
364 p
= ifc
->destination
;
366 stream_put (s
, &p
->u
.prefix
, blen
);
368 stream_put (s
, NULL
, blen
);
370 /* Write packet size. */
371 stream_putw_at (s
, 0, stream_get_endp (s
));
373 client
->connected_rt_add_cnt
++;
374 return zebra_server_send_message(client
);
378 zsend_interface_nbr_address (int cmd
, struct zserv
*client
,
379 struct interface
*ifp
, struct nbr_connected
*ifc
)
388 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
389 stream_putl (s
, ifp
->ifindex
);
391 /* Prefix information. */
393 stream_putc (s
, p
->family
);
394 blen
= prefix_blen (p
);
395 stream_put (s
, &p
->u
.prefix
, blen
);
398 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
399 * but zebra_interface_address_delete_read() in the gnu version
402 stream_putc (s
, p
->prefixlen
);
404 /* Write packet size. */
405 stream_putw_at (s
, 0, stream_get_endp (s
));
407 return zebra_server_send_message(client
);
410 /* Interface address addition. */
412 zebra_interface_nbr_address_add_update (struct interface
*ifp
,
413 struct nbr_connected
*ifc
)
415 struct listnode
*node
, *nnode
;
416 struct zserv
*client
;
419 if (IS_ZEBRA_DEBUG_EVENT
)
421 char buf
[INET6_ADDRSTRLEN
];
424 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
425 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
426 p
->prefixlen
, ifc
->ifp
->name
);
429 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
430 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
, client
, ifp
, ifc
);
433 /* Interface address deletion. */
435 zebra_interface_nbr_address_delete_update (struct interface
*ifp
,
436 struct nbr_connected
*ifc
)
438 struct listnode
*node
, *nnode
;
439 struct zserv
*client
;
442 if (IS_ZEBRA_DEBUG_EVENT
)
444 char buf
[INET6_ADDRSTRLEN
];
447 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
448 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
449 p
->prefixlen
, ifc
->ifp
->name
);
452 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
453 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE
, client
, ifp
, ifc
);
456 /* Send addresses on interface to client */
458 zsend_interface_addresses (struct zserv
*client
, struct interface
*ifp
)
460 struct listnode
*cnode
, *cnnode
;
462 struct nbr_connected
*nc
;
464 /* Send interface addresses. */
465 for (ALL_LIST_ELEMENTS (ifp
->connected
, cnode
, cnnode
, c
))
467 if (!CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
))
470 if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
,
475 /* Send interface neighbors. */
476 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, cnode
, cnnode
, nc
))
478 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD
,
479 client
, ifp
, nc
) < 0)
486 /* Notify client about interface moving from one VRF to another.
487 * Whether client is interested in old and new VRF is checked by caller.
490 zsend_interface_vrf_update (struct zserv
*client
, struct interface
*ifp
,
498 zserv_create_header (s
, ZEBRA_INTERFACE_VRF_UPDATE
, ifp
->vrf_id
);
500 /* Fill in the ifIndex of the interface and its new VRF (id) */
501 stream_putl (s
, ifp
->ifindex
);
502 stream_putw (s
, vrf_id
);
504 /* Write packet size. */
505 stream_putw_at (s
, 0, stream_get_endp (s
));
507 client
->if_vrfchg_cnt
++;
508 return zebra_server_send_message(client
);
511 /* Add new nbr connected IPv6 address */
513 nbr_connected_add_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
515 struct nbr_connected
*ifc
;
519 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
520 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
522 if (!(ifc
= listnode_head(ifp
->nbr_connected
)))
525 ifc
= nbr_connected_new ();
526 ifc
->address
= prefix_new();
528 listnode_add (ifp
->nbr_connected
, ifc
);
531 prefix_copy(ifc
->address
, &p
);
533 zebra_interface_nbr_address_add_update (ifp
, ifc
);
535 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 1);
539 nbr_connected_delete_ipv6 (struct interface
*ifp
, struct in6_addr
*address
)
541 struct nbr_connected
*ifc
;
545 IPV6_ADDR_COPY (&p
.u
.prefix
, address
);
546 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
548 ifc
= nbr_connected_check(ifp
, &p
);
552 listnode_delete (ifp
->nbr_connected
, ifc
);
554 zebra_interface_nbr_address_delete_update (ifp
, ifc
);
556 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp
, address
, 0);
558 nbr_connected_free (ifc
);
562 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
563 * ZEBRA_INTERFACE_DOWN.
565 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
566 * the clients in one of 2 situations:
567 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
568 * - a vty command modifying the bandwidth of an interface is received.
569 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
572 zsend_interface_update (int cmd
, struct zserv
*client
, struct interface
*ifp
)
579 zserv_create_header (s
, cmd
, ifp
->vrf_id
);
580 zserv_encode_interface (s
, ifp
);
582 if (cmd
== ZEBRA_INTERFACE_UP
)
585 client
->ifdown_cnt
++;
587 return zebra_server_send_message(client
);
591 * This is the new function to announce and withdraw redistributed routes, used
592 * by Zebra. This is the old zsend_route_multipath() function. That function
593 * was duplicating code to send a lot of information that was essentially thrown
594 * away or ignored by the receiver. This is the leaner function that is not a
595 * duplicate of the zapi_ipv4_route_add/del.
597 * The primary difference is that this function merely sends a single NH instead of
601 zsend_redistribute_route (int cmd
, struct zserv
*client
, struct prefix
*p
,
606 struct nexthop
*nexthop
;
607 unsigned long nhnummark
= 0, messmark
= 0;
609 u_char zapi_flags
= 0;
610 struct nexthop dummy_nh
;
612 /* Came from VRF lib patch, is this really needed? callers of this routine
613 do check for redist.., so may be its not needed.
614 Check this client need this route.
615 if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
618 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
624 memset(&dummy_nh
, 0, sizeof(struct nexthop
));
626 zserv_create_header (s
, cmd
, rib
->vrf_id
);
628 /* Put type and nexthop. */
629 stream_putc (s
, rib
->type
);
630 stream_putw (s
, rib
->instance
);
631 stream_putc (s
, rib
->flags
);
633 /* marker for message flags field */
634 messmark
= stream_get_endp (s
);
638 psize
= PSIZE (p
->prefixlen
);
639 stream_putc (s
, p
->prefixlen
);
640 stream_write (s
, (u_char
*) & p
->u
.prefix
, psize
);
642 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
644 /* We don't send any nexthops when there's a multipath */
645 if (rib
->nexthop_active_num
> 1 && client
->proto
!= ZEBRA_ROUTE_LDP
)
647 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
648 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
651 if (p
->family
== AF_INET
)
653 stream_put_in_addr (s
, &dummy_nh
.gate
.ipv4
);
655 else if (p
->family
== AF_INET6
)
657 stream_write (s
, (u_char
*) &dummy_nh
.gate
.ipv6
, 16);
661 /* We don't handle anything else now, abort */
662 zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
663 __func__
, p
->family
);
667 stream_putl (s
, 0); /* dummy ifindex */
671 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
672 || nexthop_has_fib_child(nexthop
))
674 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
675 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
678 nhnummark
= stream_get_endp (s
);
679 stream_putc (s
, 1); /* placeholder */
683 switch(nexthop
->type
)
685 case NEXTHOP_TYPE_IPV4
:
686 case NEXTHOP_TYPE_IPV4_IFINDEX
:
687 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
689 case NEXTHOP_TYPE_IPV6
:
690 case NEXTHOP_TYPE_IPV6_IFINDEX
:
691 /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
692 if (p
->family
== AF_INET
)
693 stream_put_in_addr(s
, &dummy_nh
.gate
.ipv4
);
695 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
698 if (cmd
== ZEBRA_REDISTRIBUTE_IPV4_ADD
699 || cmd
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
701 struct in_addr empty
;
702 memset (&empty
, 0, sizeof (struct in_addr
));
703 stream_write (s
, (u_char
*) &empty
, IPV4_MAX_BYTELEN
);
707 struct in6_addr empty
;
708 memset (&empty
, 0, sizeof (struct in6_addr
));
709 stream_write (s
, (u_char
*) &empty
, IPV6_MAX_BYTELEN
);
713 /* Interface index. */
715 stream_putl (s
, nexthop
->ifindex
);
717 /* ldpd needs all nexthops */
718 if (client
->proto
!= ZEBRA_ROUTE_LDP
)
724 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_DISTANCE
);
725 stream_putc (s
, rib
->distance
);
728 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_METRIC
);
729 stream_putl (s
, rib
->metric
);
734 SET_FLAG(zapi_flags
, ZAPI_MESSAGE_TAG
);
735 stream_putw(s
, rib
->tag
);
739 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_MTU
);
740 stream_putl (s
, rib
->mtu
);
742 /* write real message flags value */
743 stream_putc_at (s
, messmark
, zapi_flags
);
745 /* Write next-hop number */
747 stream_putc_at (s
, nhnummark
, nhnum
);
749 /* Write packet size. */
750 stream_putw_at (s
, 0, stream_get_endp (s
));
752 return zebra_server_send_message(client
);
756 zsend_write_nexthop (struct stream
*s
, struct nexthop
*nexthop
)
758 stream_putc (s
, nexthop
->type
);
759 switch (nexthop
->type
)
761 case NEXTHOP_TYPE_IPV4
:
762 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
764 case NEXTHOP_TYPE_IPV4_IFINDEX
:
765 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
766 stream_putl (s
, nexthop
->ifindex
);
768 case NEXTHOP_TYPE_IPV6
:
769 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
771 case NEXTHOP_TYPE_IPV6_IFINDEX
:
772 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
773 stream_putl (s
, nexthop
->ifindex
);
775 case NEXTHOP_TYPE_IFINDEX
:
776 stream_putl (s
, nexthop
->ifindex
);
785 /* Nexthop register */
787 zserv_rnh_register (struct zserv
*client
, int sock
, u_short length
,
788 rnh_type_t type
, struct zebra_vrf
*zvrf
)
796 if (IS_ZEBRA_DEBUG_NHT
)
797 zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
798 zebra_route_string(client
->proto
), length
,
799 (type
== RNH_NEXTHOP_TYPE
) ? "nexthop" : "route");
803 client
->nh_reg_time
= quagga_monotime();
807 flags
= stream_getc(s
);
808 p
.family
= stream_getw(s
);
809 p
.prefixlen
= stream_getc(s
);
811 if (p
.family
== AF_INET
)
813 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
814 l
+= IPV4_MAX_BYTELEN
;
816 else if (p
.family
== AF_INET6
)
818 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
819 l
+= IPV6_MAX_BYTELEN
;
823 zlog_err("rnh_register: Received unknown family type %d\n",
827 rnh
= zebra_add_rnh(&p
, zvrf
->vrf_id
, type
);
828 if (type
== RNH_NEXTHOP_TYPE
)
830 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
831 SET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
832 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
))
833 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_CONNECTED
);
835 else if (type
== RNH_IMPORT_CHECK_TYPE
)
837 if (flags
&& !CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
838 SET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
839 else if (!flags
&& CHECK_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
))
840 UNSET_FLAG(rnh
->flags
, ZEBRA_NHT_EXACT_MATCH
);
843 zebra_add_rnh_client(rnh
, client
, type
, zvrf
->vrf_id
);
844 /* Anything not AF_INET/INET6 has been filtered out above */
845 zebra_evaluate_rnh(zvrf
->vrf_id
, p
.family
, 1, type
, &p
);
850 /* Nexthop register */
852 zserv_rnh_unregister (struct zserv
*client
, int sock
, u_short length
,
853 rnh_type_t type
, struct zebra_vrf
*zvrf
)
860 if (IS_ZEBRA_DEBUG_NHT
)
861 zlog_debug("rnh_unregister msg from client %s: length=%d\n",
862 zebra_route_string(client
->proto
), length
);
868 (void)stream_getc(s
); //Connected or not. Not used in this function
869 p
.family
= stream_getw(s
);
870 p
.prefixlen
= stream_getc(s
);
872 if (p
.family
== AF_INET
)
874 p
.u
.prefix4
.s_addr
= stream_get_ipv4(s
);
875 l
+= IPV4_MAX_BYTELEN
;
877 else if (p
.family
== AF_INET6
)
879 stream_get(&p
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
880 l
+= IPV6_MAX_BYTELEN
;
884 zlog_err("rnh_register: Received unknown family type %d\n",
888 rnh
= zebra_lookup_rnh(&p
, zvrf
->vrf_id
, type
);
891 client
->nh_dereg_time
= quagga_monotime();
892 zebra_remove_rnh_client(rnh
, client
, type
);
899 Modified version of zsend_ipv4_nexthop_lookup():
900 Query unicast rib if nexthop is not found on mrib.
901 Returns both route metric and protocol distance.
904 zsend_ipv4_nexthop_lookup_mrib (struct zserv
*client
, struct in_addr addr
, struct rib
*rib
, struct zebra_vrf
*zvrf
)
909 struct nexthop
*nexthop
;
911 /* Get output stream. */
915 /* Fill in result. */
916 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
, zvrf
->vrf_id
);
917 stream_put_in_addr (s
, &addr
);
921 stream_putc (s
, rib
->distance
);
922 stream_putl (s
, rib
->metric
);
924 nump
= stream_get_endp(s
); /* remember position for nexthop_num */
925 stream_putc (s
, 0); /* reserve room for nexthop_num */
926 /* Only non-recursive routes are elegible to resolve the nexthop we
927 * are looking up. Therefore, we will just iterate over the top
928 * chain of nexthops. */
929 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
930 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
931 num
+= zsend_write_nexthop (s
, nexthop
);
933 stream_putc_at (s
, nump
, num
); /* store nexthop_num */
937 stream_putc (s
, 0); /* distance */
938 stream_putl (s
, 0); /* metric */
939 stream_putc (s
, 0); /* nexthop_num */
942 stream_putw_at (s
, 0, stream_get_endp (s
));
944 return zebra_server_send_message(client
);
947 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
949 zsend_router_id_update (struct zserv
*client
, struct prefix
*p
,
955 /* Check this client need interface information. */
956 if (! vrf_bitmap_check (client
->ridinfo
, vrf_id
))
963 zserv_create_header (s
, ZEBRA_ROUTER_ID_UPDATE
, vrf_id
);
965 /* Prefix information. */
966 stream_putc (s
, p
->family
);
967 blen
= prefix_blen (p
);
968 stream_put (s
, &p
->u
.prefix
, blen
);
969 stream_putc (s
, p
->prefixlen
);
971 /* Write packet size. */
972 stream_putw_at (s
, 0, stream_get_endp (s
));
974 return zebra_server_send_message(client
);
977 /* Register zebra server interface information. Send current all
978 interface and address information. */
980 zread_interface_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
982 struct listnode
*ifnode
, *ifnnode
;
984 struct interface
*ifp
;
985 struct zebra_vrf
*zvrf_iter
;
987 /* Interface information is needed. */
988 vrf_bitmap_set (client
->ifinfo
, zvrf
->vrf_id
);
990 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
992 zvrf_iter
= vrf_iter2info (iter
);
993 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter
->vrf_id
), ifnode
, ifnnode
, ifp
))
995 /* Skip pseudo interface. */
996 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
999 if (zsend_interface_add (client
, ifp
) < 0)
1002 if (zsend_interface_addresses (client
, ifp
) < 0)
1009 /* Unregister zebra server interface information. */
1011 zread_interface_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1013 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1018 zserv_nexthop_num_warn (const char *caller
, const struct prefix
*p
, const unsigned int nexthop_num
)
1020 if (nexthop_num
> MULTIPATH_NUM
)
1022 char buff
[PREFIX2STR_BUFFER
];
1023 prefix2str(p
, buff
, sizeof (buff
));
1024 zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
1025 caller
, buff
, nexthop_num
, MULTIPATH_NUM
);
1029 /* This function support multiple nexthop. */
1031 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
1035 zread_ipv4_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1041 struct in_addr nexthop
;
1043 u_char nexthop_type
;
1049 /* Get input stream. */
1052 /* Allocate new rib. */
1053 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1055 /* Type, flags, message. */
1056 rib
->type
= stream_getc (s
);
1057 rib
->instance
= stream_getw (s
);
1058 rib
->flags
= stream_getc (s
);
1059 message
= stream_getc (s
);
1060 safi
= stream_getw (s
);
1061 rib
->uptime
= time (NULL
);
1064 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1066 p
.prefixlen
= stream_getc (s
);
1067 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1070 rib
->vrf_id
= zvrf
->vrf_id
;
1072 /* Nexthop parse. */
1073 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1075 nexthop_num
= stream_getc (s
);
1076 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1078 for (i
= 0; i
< nexthop_num
; i
++)
1080 nexthop_type
= stream_getc (s
);
1082 switch (nexthop_type
)
1084 case NEXTHOP_TYPE_IFINDEX
:
1085 ifindex
= stream_getl (s
);
1086 rib_nexthop_ifindex_add (rib
, ifindex
);
1088 case NEXTHOP_TYPE_IPV4
:
1089 nexthop
.s_addr
= stream_get_ipv4 (s
);
1090 rib_nexthop_ipv4_add (rib
, &nexthop
, NULL
);
1092 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1093 nexthop
.s_addr
= stream_get_ipv4 (s
);
1094 ifindex
= stream_getl (s
);
1095 rib_nexthop_ipv4_ifindex_add (rib
, &nexthop
, NULL
, ifindex
);
1097 case NEXTHOP_TYPE_IPV6
:
1098 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1100 case NEXTHOP_TYPE_BLACKHOLE
:
1101 rib_nexthop_blackhole_add (rib
);
1108 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1109 rib
->distance
= stream_getc (s
);
1112 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1113 rib
->metric
= stream_getl (s
);
1116 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1117 rib
->tag
= stream_getw (s
);
1121 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1122 rib
->mtu
= stream_getl (s
);
1127 rib
->table
= zvrf
->table_id
;
1129 ret
= rib_add_multipath (AFI_IP
, safi
, &p
, rib
);
1133 client
->v4_route_add_cnt
++;
1135 client
->v4_route_upd8_cnt
++;
1139 /* Zebra server IPv4 prefix delete function. */
1141 zread_ipv4_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1145 struct zapi_ipv4 api
;
1146 struct in_addr nexthop
;
1147 union g_addr
*nexthop_p
;
1148 unsigned long ifindex
;
1151 u_char nexthop_type
;
1159 /* Type, flags, message. */
1160 api
.type
= stream_getc (s
);
1161 api
.instance
= stream_getw (s
);
1162 api
.flags
= stream_getc (s
);
1163 api
.message
= stream_getc (s
);
1164 api
.safi
= stream_getw (s
);
1167 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1169 p
.prefixlen
= stream_getc (s
);
1170 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1172 /* Nexthop, ifindex, distance, metric. */
1173 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1175 nexthop_num
= stream_getc (s
);
1177 for (i
= 0; i
< nexthop_num
; i
++)
1179 nexthop_type
= stream_getc (s
);
1181 switch (nexthop_type
)
1183 case NEXTHOP_TYPE_IFINDEX
:
1184 ifindex
= stream_getl (s
);
1186 case NEXTHOP_TYPE_IPV4
:
1187 nexthop
.s_addr
= stream_get_ipv4 (s
);
1188 nexthop_p
= (union g_addr
*)&nexthop
;
1190 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1191 nexthop
.s_addr
= stream_get_ipv4 (s
);
1192 nexthop_p
= (union g_addr
*)&nexthop
;
1193 ifindex
= stream_getl (s
);
1195 case NEXTHOP_TYPE_IPV6
:
1196 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
1203 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1204 api
.distance
= stream_getc (s
);
1209 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1210 api
.metric
= stream_getl (s
);
1215 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1216 api
.tag
= stream_getw (s
);
1220 table_id
= zvrf
->table_id
;
1222 rib_delete (AFI_IP
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1223 api
.flags
, &p
, nexthop_p
, ifindex
, table_id
);
1224 client
->v4_route_del_cnt
++;
1228 /* MRIB Nexthop lookup for IPv4. */
1230 zread_ipv4_nexthop_lookup_mrib (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1232 struct in_addr addr
;
1235 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1236 rib
= rib_match_ipv4_multicast (zvrf
->vrf_id
, addr
, NULL
);
1237 return zsend_ipv4_nexthop_lookup_mrib (client
, addr
, rib
, zvrf
);
1240 /* Zebra server IPv6 prefix add function. */
1242 zread_ipv4_route_ipv6_nexthop_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1246 struct in6_addr nexthop
;
1250 u_char nexthop_type
;
1253 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1254 static unsigned int ifindices
[MULTIPATH_NUM
];
1257 /* Get input stream. */
1260 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1262 /* Allocate new rib. */
1263 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1265 /* Type, flags, message. */
1266 rib
->type
= stream_getc (s
);
1267 rib
->instance
= stream_getw (s
);
1268 rib
->flags
= stream_getc (s
);
1269 message
= stream_getc (s
);
1270 safi
= stream_getw (s
);
1271 rib
->uptime
= time (NULL
);
1274 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1276 p
.prefixlen
= stream_getc (s
);
1277 stream_get (&p
.u
.prefix4
, s
, PSIZE (p
.prefixlen
));
1280 rib
->vrf_id
= zvrf
->vrf_id
;
1282 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1283 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1284 * these. Clients should send the same number of paired set of
1285 * next-hop-addr/next-hop-ifindices. */
1286 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1292 nexthop_num
= stream_getc (s
);
1293 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1294 for (i
= 0; i
< nexthop_num
; i
++)
1296 nexthop_type
= stream_getc (s
);
1298 switch (nexthop_type
)
1300 case NEXTHOP_TYPE_IPV6
:
1301 stream_get (&nexthop
, s
, 16);
1302 if (nh_count
< MULTIPATH_NUM
) {
1303 nexthops
[nh_count
++] = nexthop
;
1306 case NEXTHOP_TYPE_IFINDEX
:
1307 if (if_count
< MULTIPATH_NUM
) {
1308 ifindices
[if_count
++] = stream_getl (s
);
1311 case NEXTHOP_TYPE_BLACKHOLE
:
1312 rib_nexthop_blackhole_add (rib
);
1317 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1318 for (i
= 0; i
< max_nh_if
; i
++)
1320 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1321 if ((i
< if_count
) && ifindices
[i
]) {
1322 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1325 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1329 if ((i
< if_count
) && ifindices
[i
]) {
1330 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1337 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1338 rib
->distance
= stream_getc (s
);
1341 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1342 rib
->metric
= stream_getl (s
);
1345 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1346 rib
->tag
= stream_getw (s
);
1350 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1351 rib
->mtu
= stream_getl (s
);
1356 rib
->table
= zvrf
->table_id
;
1358 ret
= rib_add_multipath (AFI_IP6
, safi
, &p
, rib
);
1361 client
->v4_route_add_cnt
++;
1363 client
->v4_route_upd8_cnt
++;
1369 zread_ipv6_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1373 struct in6_addr nexthop
;
1377 u_char nexthop_type
;
1380 static struct in6_addr nexthops
[MULTIPATH_NUM
];
1381 static unsigned int ifindices
[MULTIPATH_NUM
];
1384 /* Get input stream. */
1387 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1389 /* Allocate new rib. */
1390 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1392 /* Type, flags, message. */
1393 rib
->type
= stream_getc (s
);
1394 rib
->instance
= stream_getw (s
);
1395 rib
->flags
= stream_getc (s
);
1396 message
= stream_getc (s
);
1397 safi
= stream_getw (s
);
1398 rib
->uptime
= time (NULL
);
1401 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1402 p
.family
= AF_INET6
;
1403 p
.prefixlen
= stream_getc (s
);
1404 stream_get (&p
.u
.prefix6
, s
, PSIZE (p
.prefixlen
));
1406 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1407 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1408 * these. Clients should send the same number of paired set of
1409 * next-hop-addr/next-hop-ifindices. */
1410 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1416 nexthop_num
= stream_getc (s
);
1417 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
, nexthop_num
);
1418 for (i
= 0; i
< nexthop_num
; i
++)
1420 nexthop_type
= stream_getc (s
);
1422 switch (nexthop_type
)
1424 case NEXTHOP_TYPE_IPV6
:
1425 stream_get (&nexthop
, s
, 16);
1426 if (nh_count
< MULTIPATH_NUM
) {
1427 nexthops
[nh_count
++] = nexthop
;
1430 case NEXTHOP_TYPE_IFINDEX
:
1431 if (if_count
< MULTIPATH_NUM
) {
1432 ifindices
[if_count
++] = stream_getl (s
);
1435 case NEXTHOP_TYPE_BLACKHOLE
:
1436 rib_nexthop_blackhole_add (rib
);
1441 max_nh_if
= (nh_count
> if_count
) ? nh_count
: if_count
;
1442 for (i
= 0; i
< max_nh_if
; i
++)
1444 if ((i
< nh_count
) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops
[i
])) {
1445 if ((i
< if_count
) && ifindices
[i
])
1446 rib_nexthop_ipv6_ifindex_add (rib
, &nexthops
[i
], ifindices
[i
]);
1448 rib_nexthop_ipv6_add (rib
, &nexthops
[i
]);
1451 if ((i
< if_count
) && ifindices
[i
])
1452 rib_nexthop_ifindex_add (rib
, ifindices
[i
]);
1458 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1459 rib
->distance
= stream_getc (s
);
1462 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1463 rib
->metric
= stream_getl (s
);
1466 if (CHECK_FLAG (message
, ZAPI_MESSAGE_TAG
))
1467 rib
->tag
= stream_getw (s
);
1471 if (CHECK_FLAG (message
, ZAPI_MESSAGE_MTU
))
1472 rib
->mtu
= stream_getl (s
);
1477 rib
->vrf_id
= zvrf
->vrf_id
;
1478 rib
->table
= zvrf
->table_id
;
1480 ret
= rib_add_multipath (AFI_IP6
, safi
, &p
, rib
);
1483 client
->v6_route_add_cnt
++;
1485 client
->v6_route_upd8_cnt
++;
1490 /* Zebra server IPv6 prefix delete function. */
1492 zread_ipv6_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1496 struct zapi_ipv6 api
;
1497 struct in6_addr nexthop
;
1498 union g_addr
*pnexthop
;
1499 unsigned long ifindex
;
1504 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1506 /* Type, flags, message. */
1507 api
.type
= stream_getc (s
);
1508 api
.instance
= stream_getw (s
);
1509 api
.flags
= stream_getc (s
);
1510 api
.message
= stream_getc (s
);
1511 api
.safi
= stream_getw (s
);
1514 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1515 p
.family
= AF_INET6
;
1516 p
.prefixlen
= stream_getc (s
);
1517 stream_get (&p
.u
.prefix6
, s
, PSIZE (p
.prefixlen
));
1519 /* Nexthop, ifindex, distance, metric. */
1520 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1522 u_char nexthop_type
;
1524 api
.nexthop_num
= stream_getc (s
);
1525 for (i
= 0; i
< api
.nexthop_num
; i
++)
1527 nexthop_type
= stream_getc (s
);
1529 switch (nexthop_type
)
1531 case NEXTHOP_TYPE_IPV6
:
1532 stream_get (&nexthop
, s
, 16);
1533 pnexthop
= (union g_addr
*)&nexthop
;
1535 case NEXTHOP_TYPE_IFINDEX
:
1536 ifindex
= stream_getl (s
);
1543 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1544 api
.distance
= stream_getc (s
);
1549 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1550 api
.metric
= stream_getl (s
);
1555 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
1556 api
.tag
= stream_getw (s
);
1560 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1561 rib_delete (AFI_IP6
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1562 api
.flags
, &p
, NULL
, ifindex
, client
->rtm_table
);
1564 rib_delete (AFI_IP6
, api
.safi
, zvrf
->vrf_id
, api
.type
, api
.instance
,
1565 api
.flags
, &p
, pnexthop
, ifindex
, client
->rtm_table
);
1567 client
->v6_route_del_cnt
++;
1571 /* Register zebra server router-id information. Send current router-id */
1573 zread_router_id_add (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1577 /* Router-id information is needed. */
1578 vrf_bitmap_set (client
->ridinfo
, zvrf
->vrf_id
);
1580 router_id_get (&p
, zvrf
->vrf_id
);
1582 return zsend_router_id_update (client
, &p
, zvrf
->vrf_id
);
1585 /* Unregister zebra server router-id information. */
1587 zread_router_id_delete (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1589 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1593 /* Tie up route-type and client->sock */
1595 zread_hello (struct zserv
*client
)
1597 /* type of protocol (lib/zebra.h) */
1601 proto
= stream_getc (client
->ibuf
);
1602 instance
= stream_getw (client
->ibuf
);
1604 /* accept only dynamic routing protocols */
1605 if ((proto
< ZEBRA_ROUTE_MAX
)
1606 && (proto
> ZEBRA_ROUTE_STATIC
))
1608 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1609 client
->sock
, zebra_route_string(proto
));
1611 zlog_notice ("client protocol instance %d", instance
);
1613 client
->proto
= proto
;
1614 client
->instance
= instance
;
1618 /* Unregister all information in a VRF. */
1620 zread_vrf_unregister (struct zserv
*client
, u_short length
, struct zebra_vrf
*zvrf
)
1625 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1626 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1627 vrf_bitmap_unset (client
->redist
[afi
][i
], zvrf
->vrf_id
);
1628 vrf_bitmap_unset (client
->redist_default
, zvrf
->vrf_id
);
1629 vrf_bitmap_unset (client
->ifinfo
, zvrf
->vrf_id
);
1630 vrf_bitmap_unset (client
->ridinfo
, zvrf
->vrf_id
);
1636 zread_mpls_labels (int command
, struct zserv
*client
, u_short length
,
1640 enum lsp_types_t type
;
1641 struct prefix prefix
;
1642 enum nexthop_types_t gtype
;
1644 mpls_label_t in_label
, out_label
;
1646 struct zebra_vrf
*zvrf
;
1648 zvrf
= vrf_info_lookup (vrf_id
);
1652 /* Get input stream. */
1656 type
= stream_getc (s
);
1657 prefix
.family
= stream_getl (s
);
1658 switch (prefix
.family
)
1661 prefix
.u
.prefix4
.s_addr
= stream_get_ipv4 (s
);
1662 prefix
.prefixlen
= stream_getc (s
);
1663 gtype
= NEXTHOP_TYPE_IPV4
;
1664 gate
.ipv4
.s_addr
= stream_get_ipv4 (s
);
1667 stream_get (&prefix
.u
.prefix6
, s
, 16);
1668 prefix
.prefixlen
= stream_getc (s
);
1669 gtype
= NEXTHOP_TYPE_IPV6
;
1670 stream_get (&gate
.ipv6
, s
, 16);
1675 distance
= stream_getc (s
);
1676 in_label
= stream_getl (s
);
1677 out_label
= stream_getl (s
);
1682 if (command
== ZEBRA_MPLS_LABELS_ADD
)
1684 mpls_lsp_install (zvrf
, type
, in_label
, out_label
, gtype
, &gate
,
1686 if (out_label
!= MPLS_IMP_NULL_LABEL
)
1687 mpls_ftn_update (1, zvrf
, type
, &prefix
, &gate
, distance
, out_label
);
1689 else if (command
== ZEBRA_MPLS_LABELS_DELETE
)
1691 mpls_lsp_uninstall (zvrf
, type
, in_label
, gtype
, &gate
, NULL
, 0);
1692 if (out_label
!= MPLS_IMP_NULL_LABEL
)
1693 mpls_ftn_update (0, zvrf
, type
, &prefix
, &gate
, distance
, out_label
);
1697 /* Cleanup registered nexthops (across VRFs) upon client disconnect. */
1699 zebra_client_close_cleanup_rnh (struct zserv
*client
)
1702 struct zebra_vrf
*zvrf
;
1704 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
1706 if ((zvrf
= vrf_iter2info (iter
)) != NULL
)
1708 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_NEXTHOP_TYPE
);
1709 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_NEXTHOP_TYPE
);
1710 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET
, client
, RNH_IMPORT_CHECK_TYPE
);
1711 zebra_cleanup_rnh_client(zvrf
->vrf_id
, AF_INET6
, client
, RNH_IMPORT_CHECK_TYPE
);
1712 if (client
->proto
== ZEBRA_ROUTE_LDP
)
1714 hash_iterate(zvrf
->lsp_table
, mpls_ldp_lsp_uninstall_all
,
1716 mpls_ldp_ftn_uninstall_all (zvrf
, AFI_IP
);
1717 mpls_ldp_ftn_uninstall_all (zvrf
, AFI_IP6
);
1723 /* Close zebra client. */
1725 zebra_client_close (struct zserv
*client
)
1727 /* Send client de-registration to BFD */
1728 zebra_ptm_bfd_client_deregister(client
->proto
);
1730 /* Cleanup any registered nexthops - across all VRFs. */
1731 zebra_client_close_cleanup_rnh (client
);
1733 /* Close file descriptor. */
1736 unsigned long nroutes
;
1738 close (client
->sock
);
1739 nroutes
= rib_score_proto (client
->proto
, client
->instance
);
1740 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1741 client
->sock
, nroutes
, zebra_route_string (client
->proto
));
1745 /* Free stream buffers. */
1747 stream_free (client
->ibuf
);
1749 stream_free (client
->obuf
);
1751 buffer_free(client
->wb
);
1753 /* Release threads. */
1755 thread_cancel (client
->t_read
);
1756 if (client
->t_write
)
1757 thread_cancel (client
->t_write
);
1758 if (client
->t_suicide
)
1759 thread_cancel (client
->t_suicide
);
1761 /* Free client structure. */
1762 listnode_delete (zebrad
.client_list
, client
);
1763 XFREE (MTYPE_TMP
, client
);
1766 /* Make new client. */
1768 zebra_client_create (int sock
)
1770 struct zserv
*client
;
1774 client
= XCALLOC (MTYPE_TMP
, sizeof (struct zserv
));
1776 /* Make client input/output buffer. */
1777 client
->sock
= sock
;
1778 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1779 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1780 client
->wb
= buffer_new(0);
1782 /* Set table number. */
1783 client
->rtm_table
= zebrad
.rtm_table_default
;
1785 client
->connect_time
= quagga_monotime();
1786 /* Initialize flags */
1787 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1788 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1789 client
->redist
[afi
][i
] = vrf_bitmap_init ();
1790 client
->redist_default
= vrf_bitmap_init ();
1791 client
->ifinfo
= vrf_bitmap_init ();
1792 client
->ridinfo
= vrf_bitmap_init ();
1794 /* Add this client to linked list. */
1795 listnode_add (zebrad
.client_list
, client
);
1797 /* Make new read thread. */
1798 zebra_event (ZEBRA_READ
, sock
, client
);
1800 zebra_vrf_update_all (client
);
1803 /* Handler of zebra service request. */
1805 zebra_client_read (struct thread
*thread
)
1808 struct zserv
*client
;
1810 uint16_t length
, command
;
1811 uint8_t marker
, version
;
1813 struct zebra_vrf
*zvrf
;
1815 /* Get thread data. Reset reading thread because I'm running. */
1816 sock
= THREAD_FD (thread
);
1817 client
= THREAD_ARG (thread
);
1818 client
->t_read
= NULL
;
1820 if (client
->t_suicide
)
1822 zebra_client_close(client
);
1826 /* Read length and command (if we don't have it already). */
1827 if ((already
= stream_get_endp(client
->ibuf
)) < ZEBRA_HEADER_SIZE
)
1830 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1831 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
1834 if (IS_ZEBRA_DEBUG_EVENT
)
1835 zlog_debug ("connection closed socket [%d]", sock
);
1836 zebra_client_close (client
);
1839 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
1841 /* Try again later. */
1842 zebra_event (ZEBRA_READ
, sock
, client
);
1845 already
= ZEBRA_HEADER_SIZE
;
1848 /* Reset to read from the beginning of the incoming packet. */
1849 stream_set_getp(client
->ibuf
, 0);
1851 /* Fetch header values */
1852 length
= stream_getw (client
->ibuf
);
1853 marker
= stream_getc (client
->ibuf
);
1854 version
= stream_getc (client
->ibuf
);
1855 vrf_id
= stream_getw (client
->ibuf
);
1856 command
= stream_getw (client
->ibuf
);
1858 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
1860 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1861 __func__
, sock
, marker
, version
);
1862 zebra_client_close (client
);
1865 if (length
< ZEBRA_HEADER_SIZE
)
1867 zlog_warn("%s: socket %d message length %u is less than header size %d",
1868 __func__
, sock
, length
, ZEBRA_HEADER_SIZE
);
1869 zebra_client_close (client
);
1872 if (length
> STREAM_SIZE(client
->ibuf
))
1874 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1875 __func__
, sock
, length
, (u_long
)STREAM_SIZE(client
->ibuf
));
1876 zebra_client_close (client
);
1880 /* Read rest of data. */
1881 if (already
< length
)
1884 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1885 length
-already
)) == 0) ||
1888 if (IS_ZEBRA_DEBUG_EVENT
)
1889 zlog_debug ("connection closed [%d] when reading zebra data", sock
);
1890 zebra_client_close (client
);
1893 if (nbyte
!= (ssize_t
)(length
-already
))
1895 /* Try again later. */
1896 zebra_event (ZEBRA_READ
, sock
, client
);
1901 length
-= ZEBRA_HEADER_SIZE
;
1903 /* Debug packet information. */
1904 if (IS_ZEBRA_DEBUG_EVENT
)
1905 zlog_debug ("zebra message comes from socket [%d]", sock
);
1907 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1908 zlog_debug ("zebra message received [%s] %d in VRF %u",
1909 zserv_command_string (command
), length
, vrf_id
);
1911 client
->last_read_time
= quagga_monotime();
1912 client
->last_read_cmd
= command
;
1914 zvrf
= zebra_vrf_lookup (vrf_id
);
1917 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1918 zlog_debug ("zebra received unknown VRF[%u]", vrf_id
);
1919 goto zclient_read_out
;
1924 case ZEBRA_ROUTER_ID_ADD
:
1925 zread_router_id_add (client
, length
, zvrf
);
1927 case ZEBRA_ROUTER_ID_DELETE
:
1928 zread_router_id_delete (client
, length
, zvrf
);
1930 case ZEBRA_INTERFACE_ADD
:
1931 zread_interface_add (client
, length
, zvrf
);
1933 case ZEBRA_INTERFACE_DELETE
:
1934 zread_interface_delete (client
, length
, zvrf
);
1936 case ZEBRA_IPV4_ROUTE_ADD
:
1937 zread_ipv4_add (client
, length
, zvrf
);
1939 case ZEBRA_IPV4_ROUTE_DELETE
:
1940 zread_ipv4_delete (client
, length
, zvrf
);
1942 case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD
:
1943 zread_ipv4_route_ipv6_nexthop_add (client
, length
, zvrf
);
1945 case ZEBRA_IPV6_ROUTE_ADD
:
1946 zread_ipv6_add (client
, length
, zvrf
);
1948 case ZEBRA_IPV6_ROUTE_DELETE
:
1949 zread_ipv6_delete (client
, length
, zvrf
);
1951 case ZEBRA_REDISTRIBUTE_ADD
:
1952 zebra_redistribute_add (command
, client
, length
, zvrf
);
1954 case ZEBRA_REDISTRIBUTE_DELETE
:
1955 zebra_redistribute_delete (command
, client
, length
, zvrf
);
1957 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
1958 zebra_redistribute_default_add (command
, client
, length
, zvrf
);
1960 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
1961 zebra_redistribute_default_delete (command
, client
, length
, zvrf
);
1963 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB
:
1964 zread_ipv4_nexthop_lookup_mrib (client
, length
, zvrf
);
1967 zread_hello (client
);
1969 case ZEBRA_NEXTHOP_REGISTER
:
1970 zserv_rnh_register(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
1972 case ZEBRA_NEXTHOP_UNREGISTER
:
1973 zserv_rnh_unregister(client
, sock
, length
, RNH_NEXTHOP_TYPE
, zvrf
);
1975 case ZEBRA_IMPORT_ROUTE_REGISTER
:
1976 zserv_rnh_register(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
1978 case ZEBRA_IMPORT_ROUTE_UNREGISTER
:
1979 zserv_rnh_unregister(client
, sock
, length
, RNH_IMPORT_CHECK_TYPE
, zvrf
);
1981 case ZEBRA_BFD_DEST_UPDATE
:
1982 case ZEBRA_BFD_DEST_REGISTER
:
1983 zebra_ptm_bfd_dst_register(client
, sock
, length
, command
, zvrf
);
1985 case ZEBRA_BFD_DEST_DEREGISTER
:
1986 zebra_ptm_bfd_dst_deregister(client
, sock
, length
, zvrf
);
1988 case ZEBRA_VRF_UNREGISTER
:
1989 zread_vrf_unregister (client
, length
, zvrf
);
1991 case ZEBRA_BFD_CLIENT_REGISTER
:
1992 zebra_ptm_bfd_client_register(client
, sock
, length
);
1994 case ZEBRA_INTERFACE_ENABLE_RADV
:
1995 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 1);
1997 case ZEBRA_INTERFACE_DISABLE_RADV
:
1998 zebra_interface_radv_set (client
, sock
, length
, zvrf
, 0);
2000 case ZEBRA_MPLS_LABELS_ADD
:
2001 case ZEBRA_MPLS_LABELS_DELETE
:
2002 zread_mpls_labels (command
, client
, length
, vrf_id
);
2005 zlog_info ("Zebra received unknown command %d", command
);
2009 if (client
->t_suicide
)
2011 /* No need to wait for thread callback, just kill immediately. */
2012 zebra_client_close(client
);
2017 stream_reset (client
->ibuf
);
2018 zebra_event (ZEBRA_READ
, sock
, client
);
2023 /* Accept code of zebra server socket. */
2025 zebra_accept (struct thread
*thread
)
2029 struct sockaddr_in client
;
2032 accept_sock
= THREAD_FD (thread
);
2034 /* Reregister myself. */
2035 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2037 len
= sizeof (struct sockaddr_in
);
2038 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
2040 if (client_sock
< 0)
2042 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno
));
2046 /* Make client socket non-blocking. */
2047 set_nonblocking(client_sock
);
2049 /* Create new zebra client. */
2050 zebra_client_create (client_sock
);
2055 #ifdef HAVE_TCP_ZEBRA
2056 /* Make zebra's server socket. */
2062 struct sockaddr_in addr
;
2064 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
2066 if (accept_sock
< 0)
2068 zlog_warn ("Can't create zserv stream socket: %s",
2069 safe_strerror (errno
));
2070 zlog_warn ("zebra can't provice full functionality due to above error");
2074 memset (&addr
, 0, sizeof (struct sockaddr_in
));
2075 addr
.sin_family
= AF_INET
;
2076 addr
.sin_port
= htons (ZEBRA_PORT
);
2077 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2078 addr
.sin_len
= sizeof (struct sockaddr_in
);
2079 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
2080 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
2082 sockopt_reuseaddr (accept_sock
);
2083 sockopt_reuseport (accept_sock
);
2085 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
2086 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
2088 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
2089 sizeof (struct sockaddr_in
));
2092 zlog_warn ("Can't bind to stream socket: %s",
2093 safe_strerror (errno
));
2094 zlog_warn ("zebra can't provice full functionality due to above error");
2095 close (accept_sock
); /* Avoid sd leak. */
2099 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
2100 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
2102 ret
= listen (accept_sock
, 1);
2105 zlog_warn ("Can't listen to stream socket: %s",
2106 safe_strerror (errno
));
2107 zlog_warn ("zebra can't provice full functionality due to above error");
2108 close (accept_sock
); /* Avoid sd leak. */
2112 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
2114 #else /* HAVE_TCP_ZEBRA */
2116 /* For sockaddr_un. */
2119 /* zebra server UNIX domain socket. */
2121 zebra_serv_un (const char *path
)
2125 struct sockaddr_un serv
;
2128 /* First of all, unlink existing socket */
2132 old_mask
= umask (0077);
2134 /* Make UNIX domain socket. */
2135 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
2138 zlog_warn ("Can't create zserv unix socket: %s",
2139 safe_strerror (errno
));
2140 zlog_warn ("zebra can't provide full functionality due to above error");
2144 /* Make server socket. */
2145 memset (&serv
, 0, sizeof (struct sockaddr_un
));
2146 serv
.sun_family
= AF_UNIX
;
2147 strncpy (serv
.sun_path
, path
, strlen (path
));
2148 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2149 len
= serv
.sun_len
= SUN_LEN(&serv
);
2151 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
2152 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2154 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
2157 zlog_warn ("Can't bind to unix socket %s: %s",
2158 path
, safe_strerror (errno
));
2159 zlog_warn ("zebra can't provide full functionality due to above error");
2164 ret
= listen (sock
, 5);
2167 zlog_warn ("Can't listen to unix socket %s: %s",
2168 path
, safe_strerror (errno
));
2169 zlog_warn ("zebra can't provide full functionality due to above error");
2176 zebra_event (ZEBRA_SERV
, sock
, NULL
);
2178 #endif /* HAVE_TCP_ZEBRA */
2182 zebra_event (enum event event
, int sock
, struct zserv
*client
)
2187 thread_add_read (zebrad
.master
, zebra_accept
, client
, sock
);
2191 thread_add_read (zebrad
.master
, zebra_client_read
, client
, sock
);
2199 #define ZEBRA_TIME_BUF 32
2201 zserv_time_buf(time_t *time1
, char *buf
, int buflen
)
2206 assert (buf
!= NULL
);
2207 assert (buflen
>= ZEBRA_TIME_BUF
);
2208 assert (time1
!= NULL
);
2212 snprintf(buf
, buflen
, "never ");
2216 now
= quagga_monotime();
2220 /* Making formatted timer strings. */
2221 #define ONE_DAY_SECOND 60*60*24
2222 #define ONE_WEEK_SECOND 60*60*24*7
2224 if (now
< ONE_DAY_SECOND
)
2225 snprintf (buf
, buflen
, "%02d:%02d:%02d",
2226 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
2227 else if (now
< ONE_WEEK_SECOND
)
2228 snprintf (buf
, buflen
, "%dd%02dh%02dm",
2229 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
2231 snprintf (buf
, buflen
, "%02dw%dd%02dh",
2232 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
2237 zebra_show_client_detail (struct vty
*vty
, struct zserv
*client
)
2239 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2240 char wbuf
[ZEBRA_TIME_BUF
], nhbuf
[ZEBRA_TIME_BUF
], mbuf
[ZEBRA_TIME_BUF
];
2242 vty_out (vty
, "Client: %s", zebra_route_string(client
->proto
));
2243 if (client
->instance
)
2244 vty_out (vty
, " Instance: %d", client
->instance
);
2245 vty_out (vty
, "%s", VTY_NEWLINE
);
2247 vty_out (vty
, "------------------------ %s", VTY_NEWLINE
);
2248 vty_out (vty
, "FD: %d %s", client
->sock
, VTY_NEWLINE
);
2249 vty_out (vty
, "Route Table ID: %d %s", client
->rtm_table
, VTY_NEWLINE
);
2251 vty_out (vty
, "Connect Time: %s %s",
2252 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2254 if (client
->nh_reg_time
)
2256 vty_out (vty
, "Nexthop Registry Time: %s %s",
2257 zserv_time_buf(&client
->nh_reg_time
, nhbuf
, ZEBRA_TIME_BUF
),
2259 if (client
->nh_last_upd_time
)
2260 vty_out (vty
, "Nexthop Last Update Time: %s %s",
2261 zserv_time_buf(&client
->nh_last_upd_time
, mbuf
, ZEBRA_TIME_BUF
),
2264 vty_out (vty
, "No Nexthop Update sent%s", VTY_NEWLINE
);
2267 vty_out (vty
, "Not registered for Nexthop Updates%s", VTY_NEWLINE
);
2269 vty_out (vty
, "Last Msg Rx Time: %s %s",
2270 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2272 vty_out (vty
, "Last Msg Tx Time: %s %s",
2273 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2275 if (client
->last_read_time
)
2276 vty_out (vty
, "Last Rcvd Cmd: %s %s",
2277 zserv_command_string(client
->last_read_cmd
), VTY_NEWLINE
);
2278 if (client
->last_write_time
)
2279 vty_out (vty
, "Last Sent Cmd: %s %s",
2280 zserv_command_string(client
->last_write_cmd
), VTY_NEWLINE
);
2281 vty_out (vty
, "%s", VTY_NEWLINE
);
2283 vty_out (vty
, "Type Add Update Del %s", VTY_NEWLINE
);
2284 vty_out (vty
, "================================================== %s", VTY_NEWLINE
);
2285 vty_out (vty
, "IPv4 %-12d%-12d%-12d%s", client
->v4_route_add_cnt
,
2286 client
->v4_route_upd8_cnt
, client
->v4_route_del_cnt
, VTY_NEWLINE
);
2287 vty_out (vty
, "IPv6 %-12d%-12d%-12d%s", client
->v6_route_add_cnt
,
2288 client
->v6_route_upd8_cnt
, client
->v6_route_del_cnt
, VTY_NEWLINE
);
2289 vty_out (vty
, "Redist:v4 %-12d%-12d%-12d%s", client
->redist_v4_add_cnt
, 0,
2290 client
->redist_v4_del_cnt
, VTY_NEWLINE
);
2291 vty_out (vty
, "Redist:v6 %-12d%-12d%-12d%s", client
->redist_v6_add_cnt
, 0,
2292 client
->redist_v6_del_cnt
, VTY_NEWLINE
);
2293 vty_out (vty
, "Connected %-12d%-12d%-12d%s", client
->ifadd_cnt
, 0,
2294 client
->ifdel_cnt
, VTY_NEWLINE
);
2295 vty_out (vty
, "BFD peer %-12d%-12d%-12d%s", client
->bfd_peer_add_cnt
,
2296 client
->bfd_peer_upd8_cnt
, client
->bfd_peer_del_cnt
, VTY_NEWLINE
);
2297 vty_out (vty
, "Interface Up Notifications: %d%s", client
->ifup_cnt
,
2299 vty_out (vty
, "Interface Down Notifications: %d%s", client
->ifdown_cnt
,
2302 vty_out (vty
, "%s", VTY_NEWLINE
);
2307 zebra_show_client_brief (struct vty
*vty
, struct zserv
*client
)
2309 char cbuf
[ZEBRA_TIME_BUF
], rbuf
[ZEBRA_TIME_BUF
];
2310 char wbuf
[ZEBRA_TIME_BUF
];
2312 vty_out (vty
, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
2313 zebra_route_string(client
->proto
),
2314 zserv_time_buf(&client
->connect_time
, cbuf
, ZEBRA_TIME_BUF
),
2315 zserv_time_buf(&client
->last_read_time
, rbuf
, ZEBRA_TIME_BUF
),
2316 zserv_time_buf(&client
->last_write_time
, wbuf
, ZEBRA_TIME_BUF
),
2317 client
->v4_route_add_cnt
+client
->v4_route_upd8_cnt
,
2318 client
->v4_route_del_cnt
,
2319 client
->v6_route_add_cnt
+client
->v6_route_upd8_cnt
,
2320 client
->v6_route_del_cnt
, VTY_NEWLINE
);
2325 /* Display default rtm_table for all clients. */
2330 "default routing table to use for all clients\n")
2332 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2337 DEFUN (config_table
,
2340 "Configure target kernel routing table\n"
2343 zebrad
.rtm_table_default
= strtol (argv
[0], (char**)0, 10);
2347 DEFUN (no_config_table
,
2348 no_config_table_cmd
,
2351 "Configure target kernel routing table\n"
2354 zebrad
.rtm_table_default
= 0;
2358 DEFUN (ip_forwarding
,
2362 "Turn on IP forwarding")
2368 ret
= ipforward_on ();
2372 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
2379 DEFUN (no_ip_forwarding
,
2380 no_ip_forwarding_cmd
,
2384 "Turn off IP forwarding")
2390 ret
= ipforward_off ();
2394 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
2401 /* This command is for debugging purpose. */
2402 DEFUN (show_zebra_client
,
2403 show_zebra_client_cmd
,
2404 "show zebra client",
2407 "Client information")
2409 struct listnode
*node
;
2410 struct zserv
*client
;
2412 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2413 zebra_show_client_detail(vty
, client
);
2418 /* This command is for debugging purpose. */
2419 DEFUN (show_zebra_client_summary
,
2420 show_zebra_client_summary_cmd
,
2421 "show zebra client summary",
2423 "Zebra information brief"
2424 "Client information brief")
2426 struct listnode
*node
;
2427 struct zserv
*client
;
2429 vty_out (vty
, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
2431 vty_out (vty
,"--------------------------------------------------------------------------------%s",
2434 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
2435 zebra_show_client_brief(vty
, client
);
2437 vty_out (vty
, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE
);
2441 /* Table configuration write function. */
2443 config_write_table (struct vty
*vty
)
2445 if (zebrad
.rtm_table_default
)
2446 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
2451 /* table node for routing tables. */
2452 static struct cmd_node table_node
=
2455 "", /* This node has no interface. */
2459 /* Only display ip forwarding is enabled or not. */
2460 DEFUN (show_ip_forwarding
,
2461 show_ip_forwarding_cmd
,
2462 "show ip forwarding",
2465 "IP forwarding status\n")
2472 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
2474 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
2479 /* Only display ipv6 forwarding is enabled or not. */
2480 DEFUN (show_ipv6_forwarding
,
2481 show_ipv6_forwarding_cmd
,
2482 "show ipv6 forwarding",
2484 "IPv6 information\n"
2485 "Forwarding status\n")
2489 ret
= ipforward_ipv6 ();
2494 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
2497 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2500 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
2503 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
2509 DEFUN (ipv6_forwarding
,
2510 ipv6_forwarding_cmd
,
2513 "Turn on IPv6 forwarding")
2517 ret
= ipforward_ipv6 ();
2519 ret
= ipforward_ipv6_on ();
2523 vty_out (vty
, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE
);
2530 DEFUN (no_ipv6_forwarding
,
2531 no_ipv6_forwarding_cmd
,
2532 "no ipv6 forwarding",
2535 "Turn off IPv6 forwarding")
2539 ret
= ipforward_ipv6 ();
2541 ret
= ipforward_ipv6_off ();
2545 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
2552 #endif /* HAVE_IPV6 */
2554 /* IPForwarding configuration write function. */
2556 config_write_forwarding (struct vty
*vty
)
2558 /* FIXME: Find better place for that. */
2559 router_id_write (vty
);
2562 vty_out (vty
, "no ip forwarding%s", VTY_NEWLINE
);
2564 if (!ipforward_ipv6 ())
2565 vty_out (vty
, "no ipv6 forwarding%s", VTY_NEWLINE
);
2566 #endif /* HAVE_IPV6 */
2567 vty_out (vty
, "!%s", VTY_NEWLINE
);
2571 /* table node for routing tables. */
2572 static struct cmd_node forwarding_node
=
2575 "", /* This node has no interface. */
2580 /* Initialisation of zebra and installation of commands. */
2584 /* Client list init. */
2585 zebrad
.client_list
= list_new ();
2587 /* Install configuration write function. */
2588 install_node (&table_node
, config_write_table
);
2589 install_node (&forwarding_node
, config_write_forwarding
);
2591 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
2592 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
2593 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
2594 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
2595 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
2596 install_element (ENABLE_NODE
, &show_zebra_client_summary_cmd
);
2599 install_element (VIEW_NODE
, &show_table_cmd
);
2600 install_element (ENABLE_NODE
, &show_table_cmd
);
2601 install_element (CONFIG_NODE
, &config_table_cmd
);
2602 install_element (CONFIG_NODE
, &no_config_table_cmd
);
2603 #endif /* HAVE_NETLINK */
2606 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2607 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
2608 install_element (CONFIG_NODE
, &ipv6_forwarding_cmd
);
2609 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2610 #endif /* HAVE_IPV6 */
2613 zebra_route_map_init ();
2616 /* Make zebra server socket, wiping any existing one (see bug #403). */
2618 zebra_zserv_socket_init (char *path
)
2620 #ifdef HAVE_TCP_ZEBRA
2623 zebra_serv_un (path
? path
: ZEBRA_SERV_PATH
);
2624 #endif /* HAVE_TCP_ZEBRA */