]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_zebra.c
vrrpd: add support for VRRPv2
[mirror_frr.git] / vrrpd / vrrp_zebra.c
CommitLineData
5435a2bf 1/*
63d4bd12
QY
2 * VRRP Zebra interfacing.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
5435a2bf
QY
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
b6029d6a 22#include "lib/if.h"
63d4bd12 23#include "lib/linklist.h"
b6029d6a
QY
24#include "lib/log.h"
25#include "lib/prefix.h"
b6029d6a 26#include "lib/vty.h"
63d4bd12 27#include "lib/zclient.h"
5435a2bf 28
b6029d6a 29#include "vrrp.h"
5435a2bf
QY
30#include "vrrp_zebra.h"
31
b6029d6a
QY
32static struct zclient *zclient = NULL;
33
34static 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. */
41static 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
51static 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
69static 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
91static 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
118static 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
145static 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
169static 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
203static 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}
5435a2bf 222
f3fe0047
QY
223void 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
5435a2bf
QY
229void vrrp_zebra_init(void)
230{
b6029d6a
QY
231 /* Socket for receiving updates from Zebra daemon */
232 zclient = zclient_new(master, &zclient_options_default);
5435a2bf 233
b6029d6a
QY
234 zclient->zebra_connected = vrrp_zebra_connected;
235 zclient->router_id_update = vrrp_router_id_update_zebra;
236 zclient->interface_add = vrrp_zebra_if_add;
237 zclient->interface_delete = vrrp_zebra_if_del;
238 zclient->interface_up = vrrp_zebra_if_state_up;
239 zclient->interface_down = vrrp_zebra_if_state_down;
240 zclient->interface_address_add = vrrp_zebra_if_address_add;
241 zclient->interface_address_delete = vrrp_zebra_if_address_del;
5435a2bf
QY
242
243 zclient_init(zclient, 0, 0, &vrrp_privs);
5435a2bf 244
b6029d6a
QY
245 zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__);
246}