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) flags %ld metric %d mtu %d operative %d",
42 func
, ifp
->name
, ifp
->ifindex
, vrf_id
, (long)ifp
->flags
,
43 ifp
->metric
, ifp
->mtu
, if_is_operative(ifp
));
46 static void vrrp_zebra_debug_if_dump_address(struct interface
*ifp
,
49 struct connected
*ifc
;
50 struct listnode
*node
;
52 DEBUGD(&vrrp_dbg_zebra
, "%s: interface %s addresses:", func
, ifp
->name
);
54 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
55 struct prefix
*p
= ifc
->address
;
57 DEBUGD(&vrrp_dbg_zebra
, "%s: interface %s address %s %s", func
,
58 ifp
->name
, inet_ntoa(p
->u
.prefix4
),
59 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
) ? "secondary"
65 static void vrrp_zebra_connected(struct zclient
*zclient
)
67 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
70 /* Router-id update message from zebra. */
71 static int vrrp_router_id_update_zebra(int command
, struct zclient
*zclient
,
72 zebra_size_t length
, vrf_id_t vrf_id
)
74 struct prefix router_id
;
76 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
81 static int vrrp_zebra_if_add(int command
, struct zclient
*zclient
,
82 zebra_size_t length
, vrf_id_t vrf_id
)
84 struct interface
*ifp
;
87 * zebra api adds/dels interfaces using the same call
88 * interface_add_read below, see comments in lib/zclient.c
90 ifp
= zebra_interface_add_read(zclient
->ibuf
, vrf_id
);
95 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
102 static int vrrp_zebra_if_del(int command
, struct zclient
*zclient
,
103 zebra_size_t length
, vrf_id_t vrf_id
)
105 struct interface
*ifp
;
107 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
112 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
116 if_set_index(ifp
, IFINDEX_INTERNAL
);
121 static int vrrp_zebra_if_state_up(int command
, struct zclient
*zclient
,
122 zebra_size_t length
, vrf_id_t vrf_id
)
124 struct interface
*ifp
;
127 * zebra api notifies interface up/down events by using the same call
128 * zebra_interface_state_read below, see comments in lib/zclient.c ifp =
129 * zebra_interface_state_read(zclient->ibuf, vrf_id);
131 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
136 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
143 static int vrrp_zebra_if_state_down(int command
, struct zclient
*zclient
,
144 zebra_size_t length
, vrf_id_t vrf_id
)
146 struct interface
*ifp
;
149 * zebra api notifies interface up/down events by using the same call
150 * zebra_interface_state_read below, see comments in lib/zclient.c
152 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
157 vrrp_zebra_debug_if_state(ifp
, vrf_id
, __func__
);
164 static int vrrp_zebra_if_address_add(int command
, struct zclient
*zclient
,
165 zebra_size_t length
, vrf_id_t vrf_id
)
170 * zebra api notifies address adds/dels events by using the same call
171 * interface_add_read below, see comments in lib/zclient.c
173 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
174 * will add address to interface list by calling
175 * connected_add_by_prefix()
177 c
= zebra_interface_address_read(command
, zclient
->ibuf
, vrf_id
);
182 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
183 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
185 vrrp_if_address_add(c
->ifp
);
190 static int vrrp_zebra_if_address_del(int command
, struct zclient
*client
,
191 zebra_size_t length
, vrf_id_t vrf_id
)
196 * zebra api notifies address adds/dels events by using the same call
197 * interface_add_read below, see comments in lib/zclient.c
199 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
200 * will remove address from interface list by calling
201 * connected_delete_by_prefix()
203 c
= zebra_interface_address_read(command
, client
->ibuf
, vrf_id
);
208 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
209 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
211 vrrp_if_address_del(c
->ifp
);
216 void vrrp_zebra_radv_set(struct vrrp_router
*r
, bool enable
)
218 DEBUGD(&vrrp_dbg_zebra
,
219 VRRP_LOGPFX VRRP_LOGPFX_VRID
220 "Requesting Zebra to turn router advertisements %s for %s",
221 r
->vr
->vrid
, enable
? "on" : "off", r
->mvl_ifp
->name
);
223 zclient_send_interface_radv_req(zclient
, VRF_DEFAULT
, r
->mvl_ifp
,
224 enable
, VRRP_RADV_INT
);
227 int vrrp_zclient_send_interface_protodown(struct interface
*ifp
, bool down
)
229 DEBUGD(&vrrp_dbg_zebra
,
230 VRRP_LOGPFX
"Requesting Zebra to set %s protodown %s", ifp
->name
,
231 down
? "on" : "off");
233 return zclient_send_interface_protodown(zclient
, VRF_DEFAULT
, ifp
,
237 void vrrp_zebra_init(void)
239 /* Socket for receiving updates from Zebra daemon */
240 zclient
= zclient_new(master
, &zclient_options_default
);
242 zclient
->zebra_connected
= vrrp_zebra_connected
;
243 zclient
->router_id_update
= vrrp_router_id_update_zebra
;
244 zclient
->interface_add
= vrrp_zebra_if_add
;
245 zclient
->interface_delete
= vrrp_zebra_if_del
;
246 zclient
->interface_up
= vrrp_zebra_if_state_up
;
247 zclient
->interface_down
= vrrp_zebra_if_state_down
;
248 zclient
->interface_address_add
= vrrp_zebra_if_address_add
;
249 zclient
->interface_address_delete
= vrrp_zebra_if_address_del
;
251 zclient_init(zclient
, ZEBRA_ROUTE_VRRP
, 0, &vrrp_privs
);
253 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__
);