]> git.proxmox.com Git - mirror_frr.git/blob - vrrpd/vrrp_zebra.c
Merge pull request #4649 from ton31337/feature/access-list_sequence
[mirror_frr.git] / vrrpd / vrrp_zebra.c
1 /*
2 * VRRP Zebra interfacing.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
5 *
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)
9 * any later version.
10 *
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
14 * more details.
15 *
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
19 */
20 #include <zebra.h>
21
22 #include "lib/if.h"
23 #include "lib/linklist.h"
24 #include "lib/log.h"
25 #include "lib/prefix.h"
26 #include "lib/vty.h"
27 #include "lib/zclient.h"
28
29 #include "vrrp.h"
30 #include "vrrp_debug.h"
31 #include "vrrp_zebra.h"
32
33 #define VRRP_LOGPFX "[ZEBRA] "
34
35 static struct zclient *zclient;
36
37 static void vrrp_zebra_debug_if_state(struct interface *ifp, vrf_id_t vrf_id,
38 const char *func)
39 {
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));
44 }
45
46 static void vrrp_zebra_debug_if_dump_address(struct interface *ifp,
47 const char *func)
48 {
49 struct connected *ifc;
50 struct listnode *node;
51
52 DEBUGD(&vrrp_dbg_zebra, "%s: interface %s addresses:", func, ifp->name);
53
54 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
55 struct prefix *p = ifc->address;
56
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"
60 : "primary");
61 }
62 }
63
64
65 static void vrrp_zebra_connected(struct zclient *zclient)
66 {
67 zclient_send_reg_requests(zclient, VRF_DEFAULT);
68 }
69
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)
73 {
74 struct prefix router_id;
75
76 zebra_router_id_update_read(zclient->ibuf, &router_id);
77
78 return 0;
79 }
80
81 static int vrrp_zebra_if_add(int command, struct zclient *zclient,
82 zebra_size_t length, vrf_id_t vrf_id)
83 {
84 struct interface *ifp;
85
86 /*
87 * zebra api adds/dels interfaces using the same call
88 * interface_add_read below, see comments in lib/zclient.c
89 */
90 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
91
92 if (!ifp)
93 return 0;
94
95 vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
96
97 vrrp_if_add(ifp);
98
99 return 0;
100 }
101
102 static int vrrp_zebra_if_del(int command, struct zclient *zclient,
103 zebra_size_t length, vrf_id_t vrf_id)
104 {
105 struct interface *ifp;
106
107 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
108
109 if (!ifp)
110 return 0;
111
112 vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
113
114 vrrp_if_del(ifp);
115
116 if_set_index(ifp, IFINDEX_INTERNAL);
117
118 return 0;
119 }
120
121 static int vrrp_zebra_if_state_up(int command, struct zclient *zclient,
122 zebra_size_t length, vrf_id_t vrf_id)
123 {
124 struct interface *ifp;
125
126 /*
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);
130 */
131 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
132
133 if (!ifp)
134 return 0;
135
136 vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
137
138 vrrp_if_up(ifp);
139
140 return 0;
141 }
142
143 static int vrrp_zebra_if_state_down(int command, struct zclient *zclient,
144 zebra_size_t length, vrf_id_t vrf_id)
145 {
146 struct interface *ifp;
147
148 /*
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
151 */
152 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
153
154 if (!ifp)
155 return 0;
156
157 vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
158
159 vrrp_if_down(ifp);
160
161 return 0;
162 }
163
164 static int vrrp_zebra_if_address_add(int command, struct zclient *zclient,
165 zebra_size_t length, vrf_id_t vrf_id)
166 {
167 struct connected *c;
168
169 /*
170 * zebra api notifies address adds/dels events by using the same call
171 * interface_add_read below, see comments in lib/zclient.c
172 *
173 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
174 * will add address to interface list by calling
175 * connected_add_by_prefix()
176 */
177 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
178
179 if (!c)
180 return 0;
181
182 vrrp_zebra_debug_if_state(c->ifp, vrf_id, __func__);
183 vrrp_zebra_debug_if_dump_address(c->ifp, __func__);
184
185 vrrp_if_address_add(c->ifp);
186
187 return 0;
188 }
189
190 static int vrrp_zebra_if_address_del(int command, struct zclient *client,
191 zebra_size_t length, vrf_id_t vrf_id)
192 {
193 struct connected *c;
194
195 /*
196 * zebra api notifies address adds/dels events by using the same call
197 * interface_add_read below, see comments in lib/zclient.c
198 *
199 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
200 * will remove address from interface list by calling
201 * connected_delete_by_prefix()
202 */
203 c = zebra_interface_address_read(command, client->ibuf, vrf_id);
204
205 if (!c)
206 return 0;
207
208 vrrp_zebra_debug_if_state(c->ifp, vrf_id, __func__);
209 vrrp_zebra_debug_if_dump_address(c->ifp, __func__);
210
211 vrrp_if_address_del(c->ifp);
212
213 return 0;
214 }
215
216 void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable)
217 {
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);
222
223 zclient_send_interface_radv_req(zclient, VRF_DEFAULT, r->mvl_ifp,
224 enable, VRRP_RADV_INT);
225 }
226
227 int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
228 {
229 DEBUGD(&vrrp_dbg_zebra,
230 VRRP_LOGPFX "Requesting Zebra to set %s protodown %s", ifp->name,
231 down ? "on" : "off");
232
233 return zclient_send_interface_protodown(zclient, VRF_DEFAULT, ifp,
234 down);
235 }
236
237 void vrrp_zebra_init(void)
238 {
239 /* Socket for receiving updates from Zebra daemon */
240 zclient = zclient_new(master, &zclient_options_default);
241
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;
250
251 zclient_init(zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs);
252
253 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__);
254 }