2 * VRRP Zebra interfacing.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
6 * This program 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 Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "lib/linklist.h"
25 #include "lib/prefix.h"
27 #include "lib/zclient.h"
30 #include "vrrp_zebra.h"
32 static struct zclient
*zclient
= NULL
;
34 static void vrrp_zebra_connected(struct zclient
*zclient
)
36 fprintf(stderr
, "Zclient connected\n");
37 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
40 /* Router-id update message from zebra. */
41 static int vrrp_router_id_update_zebra(int command
, struct zclient
*zclient
,
42 zebra_size_t length
, vrf_id_t vrf_id
)
44 struct prefix router_id
;
46 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
51 static int vrrp_zebra_if_add(int command
, struct zclient
*zclient
,
52 zebra_size_t length
, vrf_id_t vrf_id
)
54 struct interface
*ifp
;
57 * zebra api adds/dels interfaces using the same call
58 * interface_add_read below, see comments in lib/zclient.c
60 ifp
= zebra_interface_add_read(zclient
->ibuf
, vrf_id
);
69 static int vrrp_zebra_if_del(int command
, struct zclient
*zclient
,
70 zebra_size_t length
, vrf_id_t vrf_id
)
72 struct interface
*ifp
;
74 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
81 if (VRRP_DEBUG_ZEBRA
) {
83 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
84 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
85 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
86 if_is_operative(ifp
));
93 static int vrrp_zebra_if_state_up(int command
, struct zclient
*zclient
,
94 zebra_size_t length
, vrf_id_t vrf_id
)
96 struct interface
*ifp
;
99 * zebra api notifies interface up/down events by using the same call
100 * zebra_interface_state_read below, see comments in lib/zclient.c ifp =
101 * zebra_interface_state_read(zclient->ibuf, vrf_id);
103 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
110 if (VRRP_DEBUG_ZEBRA
) {
112 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
113 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
114 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
115 if_is_operative(ifp
));
122 static int vrrp_zebra_if_state_down(int command
, struct zclient
*zclient
,
123 zebra_size_t length
, vrf_id_t vrf_id
)
125 struct interface
*ifp
;
128 * zebra api notifies interface up/down events by using the same call
129 * zebra_interface_state_read below, see comments in lib/zclient.c
131 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
138 if (VRRP_DEBUG_ZEBRA
) {
140 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
141 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
142 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
143 if_is_operative(ifp
));
150 #ifdef VRRP_DEBUG_IFADDR_DUMP
151 static void dump_if_address(struct interface
*ifp
)
153 struct connected
*ifc
;
154 struct listnode
*node
;
156 zlog_debug("%s %s: interface %s addresses:", __FILE__
,
157 __PRETTY_FUNCTION__
, ifp
->name
);
159 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
160 struct prefix
*p
= ifc
->address
;
162 if (p
->family
!= AF_INET
)
165 zlog_debug("%s %s: interface %s address %s %s", __FILE__
,
166 __PRETTY_FUNCTION__
, ifp
->name
,
167 inet_ntoa(p
->u
.prefix4
),
168 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)
175 static int vrrp_zebra_if_address_add(int command
, struct zclient
*zclient
,
176 zebra_size_t length
, vrf_id_t vrf_id
)
181 * zebra api notifies address adds/dels events by using the same call
182 * interface_add_read below, see comments in lib/zclient.c
184 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
185 * will add address to interface list by calling
186 * connected_add_by_prefix()
188 c
= zebra_interface_address_read(command
, zclient
->ibuf
, vrf_id
);
192 vrrp_if_address_add(c
->ifp
);
195 if (VRRP_DEBUG_ZEBRA
) {
197 prefix2str(p
, buf
, BUFSIZ
);
198 zlog_debug("%s: %s(%u) connected IP address %s flags %u %s",
199 __PRETTY_FUNCTION__
, c
->ifp
->name
, vrf_id
, buf
,
201 CHECK_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
)
211 static int vrrp_zebra_if_address_del(int command
, struct zclient
*client
,
212 zebra_size_t length
, vrf_id_t vrf_id
)
217 * zebra api notifies address adds/dels events by using the same call
218 * interface_add_read below, see comments in lib/zclient.c
220 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
221 * will remove address from interface list by calling
222 * connected_delete_by_prefix()
224 c
= zebra_interface_address_read(command
, client
->ibuf
, vrf_id
);
228 vrrp_if_address_del(c
->ifp
);
233 void vrrp_zebra_radv_set(struct vrrp_router
*r
, bool enable
)
235 zclient_send_interface_radv_req(zclient
, VRF_DEFAULT
, r
->mvl_ifp
,
236 enable
, VRRP_RADV_INT
);
239 int vrrp_zclient_send_interface_protodown(struct interface
*ifp
, bool down
)
241 return zclient_send_interface_protodown(zclient
, VRF_DEFAULT
, ifp
,
245 void vrrp_zebra_init(void)
247 /* Socket for receiving updates from Zebra daemon */
248 zclient
= zclient_new(master
, &zclient_options_default
);
250 zclient
->zebra_connected
= vrrp_zebra_connected
;
251 zclient
->router_id_update
= vrrp_router_id_update_zebra
;
252 zclient
->interface_add
= vrrp_zebra_if_add
;
253 zclient
->interface_delete
= vrrp_zebra_if_del
;
254 zclient
->interface_up
= vrrp_zebra_if_state_up
;
255 zclient
->interface_down
= vrrp_zebra_if_state_down
;
256 zclient
->interface_address_add
= vrrp_zebra_if_address_add
;
257 zclient
->interface_address_delete
= vrrp_zebra_if_address_del
;
259 zclient_init(zclient
, 0, 0, &vrrp_privs
);
261 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__
);