]> git.proxmox.com Git - mirror_frr.git/blob - vrrpd/vrrp_zebra.c
vrrpd: protodown macvlan in backup state
[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_zebra.h"
31
32 static struct zclient *zclient = NULL;
33
34 static void vrrp_zebra_connected(struct zclient *zclient)
35 {
36 fprintf(stderr, "Zclient connected\n");
37 zclient_send_reg_requests(zclient, VRF_DEFAULT);
38 }
39
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)
43 {
44 struct prefix router_id;
45
46 zebra_router_id_update_read(zclient->ibuf, &router_id);
47
48 return 0;
49 }
50
51 static int vrrp_zebra_if_add(int command, struct zclient *zclient,
52 zebra_size_t length, vrf_id_t vrf_id)
53 {
54 struct interface *ifp;
55
56 /*
57 * zebra api adds/dels interfaces using the same call
58 * interface_add_read below, see comments in lib/zclient.c
59 */
60 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
61 if (!ifp)
62 return 0;
63
64 /* FIXME: handle subinterface creation here */
65
66 return 0;
67 }
68
69 static int vrrp_zebra_if_del(int command, struct zclient *zclient,
70 zebra_size_t length, vrf_id_t vrf_id)
71 {
72 struct interface *ifp;
73
74 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
75 if (!ifp)
76 return 0;
77
78 #if 0
79 if (VRRP_DEBUG_ZEBRA) {
80 zlog_debug(
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));
85 }
86 #endif
87
88 return 0;
89 }
90
91 static int vrrp_zebra_if_state_up(int command, struct zclient *zclient,
92 zebra_size_t length, vrf_id_t vrf_id)
93 {
94 struct interface *ifp;
95
96 /*
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);
100 */
101 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
102 if (!ifp)
103 return 0;
104
105 #if 0
106 if (VRRP_DEBUG_ZEBRA) {
107 zlog_debug(
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));
112 }
113 #endif
114
115 return 0;
116 }
117
118 static int vrrp_zebra_if_state_down(int command, struct zclient *zclient,
119 zebra_size_t length, vrf_id_t vrf_id)
120 {
121 struct interface *ifp;
122
123 /*
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
126 */
127 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
128 if (!ifp)
129 return 0;
130
131 #if 0
132 if (VRRP_DEBUG_ZEBRA) {
133 zlog_debug(
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));
138 }
139 #endif
140
141 return 0;
142 }
143
144 #ifdef VRRP_DEBUG_IFADDR_DUMP
145 static void dump_if_address(struct interface *ifp)
146 {
147 struct connected *ifc;
148 struct listnode *node;
149
150 zlog_debug("%s %s: interface %s addresses:", __FILE__,
151 __PRETTY_FUNCTION__, ifp->name);
152
153 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
154 struct prefix *p = ifc->address;
155
156 if (p->family != AF_INET)
157 continue;
158
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)
163 ? "secondary"
164 : "primary");
165 }
166 }
167 #endif
168
169 static int vrrp_zebra_if_address_add(int command, struct zclient *zclient,
170 zebra_size_t length, vrf_id_t vrf_id)
171 {
172 struct connected *c;
173
174 /*
175 * zebra api notifies address adds/dels events by using the same call
176 * interface_add_read below, see comments in lib/zclient.c
177 *
178 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
179 * will add address to interface list by calling
180 * connected_add_by_prefix()
181 */
182 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
183 if (!c)
184 return 0;
185
186 #if 0
187 if (VRRP_DEBUG_ZEBRA) {
188 char buf[BUFSIZ];
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,
192 c->flags,
193 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
194 ? "secondary"
195 : "primary");
196
197 }
198 #endif
199
200 return 0;
201 }
202
203 static int vrrp_zebra_if_address_del(int command, struct zclient *client,
204 zebra_size_t length, vrf_id_t vrf_id)
205 {
206 struct connected *c;
207
208 /*
209 * zebra api notifies address adds/dels events by using the same call
210 * interface_add_read below, see comments in lib/zclient.c
211 *
212 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
213 * will remove address from interface list by calling
214 * connected_delete_by_prefix()
215 */
216 c = zebra_interface_address_read(command, client->ibuf, vrf_id);
217 if (!c)
218 return 0;
219
220 return 0;
221 }
222
223 void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable)
224 {
225 zclient_send_interface_radv_req(zclient, VRF_DEFAULT, r->mvl_ifp,
226 enable, VRRP_RADV_INT);
227 }
228
229 int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
230 {
231 return zclient_send_interface_protodown(zclient, VRF_DEFAULT, ifp,
232 down);
233 }
234
235 void vrrp_zebra_init(void)
236 {
237 /* Socket for receiving updates from Zebra daemon */
238 zclient = zclient_new(master, &zclient_options_default);
239
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;
248
249 zclient_init(zclient, 0, 0, &vrrp_privs);
250
251 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__);
252 }