]>
Commit | Line | Data |
---|---|---|
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 |
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 | } | |
5435a2bf | 222 | |
f3fe0047 QY |
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 | ||
5435a2bf QY |
229 | void 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 | } |