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 int vrrp_ifp_create(struct interface
*ifp
)
85 vrrp_zebra_debug_if_state(ifp
, ifp
->vrf_id
, __func__
);
92 int vrrp_ifp_destroy(struct interface
*ifp
)
94 vrrp_zebra_debug_if_state(ifp
, ifp
->vrf_id
, __func__
);
101 int vrrp_ifp_up(struct interface
*ifp
)
103 vrrp_zebra_debug_if_state(ifp
, ifp
->vrf_id
, __func__
);
110 int vrrp_ifp_down(struct interface
*ifp
)
112 vrrp_zebra_debug_if_state(ifp
, ifp
->vrf_id
, __func__
);
119 static int vrrp_zebra_if_address_add(int command
, struct zclient
*zclient
,
120 zebra_size_t length
, vrf_id_t vrf_id
)
125 * zebra api notifies address adds/dels events by using the same call
126 * interface_add_read below, see comments in lib/zclient.c
128 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
129 * will add address to interface list by calling
130 * connected_add_by_prefix()
132 c
= zebra_interface_address_read(command
, zclient
->ibuf
, vrf_id
);
137 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
138 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
140 vrrp_if_address_add(c
->ifp
);
145 static int vrrp_zebra_if_address_del(int command
, struct zclient
*client
,
146 zebra_size_t length
, vrf_id_t vrf_id
)
151 * zebra api notifies address adds/dels events by using the same call
152 * interface_add_read below, see comments in lib/zclient.c
154 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
155 * will remove address from interface list by calling
156 * connected_delete_by_prefix()
158 c
= zebra_interface_address_read(command
, client
->ibuf
, vrf_id
);
163 vrrp_zebra_debug_if_state(c
->ifp
, vrf_id
, __func__
);
164 vrrp_zebra_debug_if_dump_address(c
->ifp
, __func__
);
166 vrrp_if_address_del(c
->ifp
);
171 void vrrp_zebra_radv_set(struct vrrp_router
*r
, bool enable
)
173 DEBUGD(&vrrp_dbg_zebra
,
174 VRRP_LOGPFX VRRP_LOGPFX_VRID
175 "Requesting Zebra to turn router advertisements %s for %s",
176 r
->vr
->vrid
, enable
? "on" : "off", r
->mvl_ifp
->name
);
178 zclient_send_interface_radv_req(zclient
, r
->mvl_ifp
->vrf_id
, r
->mvl_ifp
,
179 enable
, VRRP_RADV_INT
);
182 int vrrp_zclient_send_interface_protodown(struct interface
*ifp
, bool down
)
184 DEBUGD(&vrrp_dbg_zebra
,
185 VRRP_LOGPFX
"Requesting Zebra to set %s protodown %s", ifp
->name
,
186 down
? "on" : "off");
188 return zclient_send_interface_protodown(zclient
, ifp
->vrf_id
, ifp
,
192 void vrrp_zebra_init(void)
194 if_zapi_callbacks(vrrp_ifp_create
, vrrp_ifp_up
,
195 vrrp_ifp_down
, vrrp_ifp_destroy
);
197 /* Socket for receiving updates from Zebra daemon */
198 zclient
= zclient_new(master
, &zclient_options_default
);
200 zclient
->zebra_connected
= vrrp_zebra_connected
;
201 zclient
->router_id_update
= vrrp_router_id_update_zebra
;
202 zclient
->interface_address_add
= vrrp_zebra_if_address_add
;
203 zclient
->interface_address_delete
= vrrp_zebra_if_address_del
;
205 zclient_init(zclient
, ZEBRA_ROUTE_VRRP
, 0, &vrrp_privs
);
207 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__
);