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_debug.h"
31 #include "vrrp_zebra.h"
33 #define VRRP_LOGPFX "[ZEBRA] "
35 static struct zclient
*zclient
;
37 static void vrrp_zebra_debug_if_state(struct interface
*ifp
, vrf_id_t vrf_id
,
40 DEBUGD(&vrrp_dbg_zebra
,
41 "%s: %s index %d(%u) parent %d mac %02x:%02x:%02x:%02x:%02x:%02x flags %ld metric %d mtu %d operative %d",
42 func
, ifp
->name
, vrf_id
, ifp
->link_ifindex
, ifp
->ifindex
,
43 ifp
->hw_addr
[0], ifp
->hw_addr
[1], ifp
->hw_addr
[2],
44 ifp
->hw_addr
[3], ifp
->hw_addr
[4], ifp
->hw_addr
[5],
45 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
, if_is_operative(ifp
));
48 static void vrrp_zebra_debug_if_dump_address(struct interface
*ifp
,
51 struct connected
*ifc
;
52 struct listnode
*node
;
54 DEBUGD(&vrrp_dbg_zebra
, "%s: interface %s addresses:", func
, ifp
->name
);
56 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
57 struct prefix
*p
= ifc
->address
;
59 DEBUGD(&vrrp_dbg_zebra
, "%s: interface %s address %s %s", func
,
60 ifp
->name
, inet_ntoa(p
->u
.prefix4
),
61 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
) ? "secondary"
67 static void vrrp_zebra_connected(struct zclient
*zclient
)
69 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
72 /* Router-id update message from zebra. */
73 static int vrrp_router_id_update_zebra(int command
, struct zclient
*zclient
,
74 zebra_size_t length
, vrf_id_t vrf_id
)
76 struct prefix router_id
;
78 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
83 static int vrrp_zebra_if_add(int command
, struct zclient
*zclient
,
84 zebra_size_t length
, vrf_id_t vrf_id
)
86 struct interface
*ifp
;
89 * zebra api adds/dels interfaces using the same call
90 * interface_add_read below, see comments in lib/zclient.c
92 ifp
= zebra_interface_add_read(zclient
->ibuf
, vrf_id
);
97 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
104 static int vrrp_zebra_if_del(int command
, struct zclient
*zclient
,
105 zebra_size_t length
, vrf_id_t vrf_id
)
107 struct interface
*ifp
;
109 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
114 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
118 if_set_index(ifp
, IFINDEX_INTERNAL
);
123 static int vrrp_zebra_if_state_up(int command
, struct zclient
*zclient
,
124 zebra_size_t length
, vrf_id_t vrf_id
)
126 struct interface
*ifp
;
129 * zebra api notifies interface up/down events by using the same call
130 * zebra_interface_state_read below, see comments in lib/zclient.c ifp =
131 * zebra_interface_state_read(zclient->ibuf, vrf_id);
133 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
138 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
145 static int vrrp_zebra_if_state_down(int command
, struct zclient
*zclient
,
146 zebra_size_t length
, vrf_id_t vrf_id
)
148 struct interface
*ifp
;
151 * zebra api notifies interface up/down events by using the same call
152 * zebra_interface_state_read below, see comments in lib/zclient.c
154 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
159 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
166 static int vrrp_zebra_if_address_add(int command
, struct zclient
*zclient
,
167 zebra_size_t length
, vrf_id_t vrf_id
)
172 * zebra api notifies address adds/dels events by using the same call
173 * interface_add_read below, see comments in lib/zclient.c
175 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
176 * will add address to interface list by calling
177 * connected_add_by_prefix()
179 c
= zebra_interface_address_read(command
, zclient
->ibuf
, vrf_id
);
184 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
185 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
187 vrrp_if_address_add(c
->ifp
);
192 static int vrrp_zebra_if_address_del(int command
, struct zclient
*client
,
193 zebra_size_t length
, vrf_id_t vrf_id
)
198 * zebra api notifies address adds/dels events by using the same call
199 * interface_add_read below, see comments in lib/zclient.c
201 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
202 * will remove address from interface list by calling
203 * connected_delete_by_prefix()
205 c
= zebra_interface_address_read(command
, client
->ibuf
, vrf_id
);
210 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
211 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
213 vrrp_if_address_del(c
->ifp
);
218 void vrrp_zebra_radv_set(struct vrrp_router
*r
, bool enable
)
220 DEBUGD(&vrrp_dbg_zebra
,
221 VRRP_LOGPFX VRRP_LOGPFX_VRID
222 "Requesting Zebra to turn router advertisements %s for %s",
223 r
->vr
->vrid
, enable
? "on" : "off", r
->mvl_ifp
->name
);
225 zclient_send_interface_radv_req(zclient
, VRF_DEFAULT
, r
->mvl_ifp
,
226 enable
, VRRP_RADV_INT
);
229 int vrrp_zclient_send_interface_protodown(struct interface
*ifp
, bool down
)
231 DEBUGD(&vrrp_dbg_zebra
,
232 VRRP_LOGPFX
"Requesting Zebra to set %s protodown %s", ifp
->name
,
233 down
? "on" : "off");
235 return zclient_send_interface_protodown(zclient
, VRF_DEFAULT
, ifp
,
239 void vrrp_zebra_init(void)
241 /* Socket for receiving updates from Zebra daemon */
242 zclient
= zclient_new(master
, &zclient_options_default
);
244 zclient
->zebra_connected
= vrrp_zebra_connected
;
245 zclient
->router_id_update
= vrrp_router_id_update_zebra
;
246 zclient
->interface_add
= vrrp_zebra_if_add
;
247 zclient
->interface_delete
= vrrp_zebra_if_del
;
248 zclient
->interface_up
= vrrp_zebra_if_state_up
;
249 zclient
->interface_down
= vrrp_zebra_if_state_down
;
250 zclient
->interface_address_add
= vrrp_zebra_if_address_add
;
251 zclient
->interface_address_delete
= vrrp_zebra_if_address_del
;
253 zclient_init(zclient
, ZEBRA_ROUTE_VRRP
, 0, &vrrp_privs
);
255 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__
);