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
);
64 /* FIXME: handle subinterface creation here */
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
);
79 if (VRRP_DEBUG_ZEBRA
) {
81 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
82 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
83 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
84 if_is_operative(ifp
));
91 static int vrrp_zebra_if_state_up(int command
, struct zclient
*zclient
,
92 zebra_size_t length
, vrf_id_t vrf_id
)
94 struct interface
*ifp
;
97 * zebra api notifies interface up/down events by using the same call
98 * zebra_interface_state_read below, see comments in lib/zclient.c ifp =
99 * zebra_interface_state_read(zclient->ibuf, vrf_id);
101 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
106 if (VRRP_DEBUG_ZEBRA
) {
108 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
109 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
110 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
111 if_is_operative(ifp
));
118 static int vrrp_zebra_if_state_down(int command
, struct zclient
*zclient
,
119 zebra_size_t length
, vrf_id_t vrf_id
)
121 struct interface
*ifp
;
124 * zebra api notifies interface up/down events by using the same call
125 * zebra_interface_state_read below, see comments in lib/zclient.c
127 ifp
= zebra_interface_state_read(zclient
->ibuf
, vrf_id
);
132 if (VRRP_DEBUG_ZEBRA
) {
134 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
135 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->ifindex
, vrf_id
,
136 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
137 if_is_operative(ifp
));
144 #ifdef VRRP_DEBUG_IFADDR_DUMP
145 static void dump_if_address(struct interface
*ifp
)
147 struct connected
*ifc
;
148 struct listnode
*node
;
150 zlog_debug("%s %s: interface %s addresses:", __FILE__
,
151 __PRETTY_FUNCTION__
, ifp
->name
);
153 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
154 struct prefix
*p
= ifc
->address
;
156 if (p
->family
!= AF_INET
)
159 zlog_debug("%s %s: interface %s address %s %s", __FILE__
,
160 __PRETTY_FUNCTION__
, ifp
->name
,
161 inet_ntoa(p
->u
.prefix4
),
162 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)
169 static int vrrp_zebra_if_address_add(int command
, struct zclient
*zclient
,
170 zebra_size_t length
, vrf_id_t vrf_id
)
175 * zebra api notifies address adds/dels events by using the same call
176 * interface_add_read below, see comments in lib/zclient.c
178 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
179 * will add address to interface list by calling
180 * connected_add_by_prefix()
182 c
= zebra_interface_address_read(command
, zclient
->ibuf
, vrf_id
);
187 if (VRRP_DEBUG_ZEBRA
) {
189 prefix2str(p
, buf
, BUFSIZ
);
190 zlog_debug("%s: %s(%u) connected IP address %s flags %u %s",
191 __PRETTY_FUNCTION__
, c
->ifp
->name
, vrf_id
, buf
,
193 CHECK_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
)
203 static int vrrp_zebra_if_address_del(int command
, struct zclient
*client
,
204 zebra_size_t length
, vrf_id_t vrf_id
)
209 * zebra api notifies address adds/dels events by using the same call
210 * interface_add_read below, see comments in lib/zclient.c
212 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
213 * will remove address from interface list by calling
214 * connected_delete_by_prefix()
216 c
= zebra_interface_address_read(command
, client
->ibuf
, vrf_id
);
223 void vrrp_zebra_radv_set(struct vrrp_router
*r
, bool enable
)
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 return zclient_send_interface_protodown(zclient
, VRF_DEFAULT
, ifp
,
235 void vrrp_zebra_init(void)
237 /* Socket for receiving updates from Zebra daemon */
238 zclient
= zclient_new(master
, &zclient_options_default
);
240 zclient
->zebra_connected
= vrrp_zebra_connected
;
241 zclient
->router_id_update
= vrrp_router_id_update_zebra
;
242 zclient
->interface_add
= vrrp_zebra_if_add
;
243 zclient
->interface_delete
= vrrp_zebra_if_del
;
244 zclient
->interface_up
= vrrp_zebra_if_state_up
;
245 zclient
->interface_down
= vrrp_zebra_if_state_down
;
246 zclient
->interface_address_add
= vrrp_zebra_if_address_add
;
247 zclient
->interface_address_delete
= vrrp_zebra_if_address_del
;
249 zclient_init(zclient
, 0, 0, &vrrp_privs
);
251 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__
);