1 /*
2 * Zebra Layer-2 interface handling code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "if.h"
26 #include "prefix.h"
27 #include "table.h"
28 #include "memory.h"
29 #include "log.h"
30 #include "linklist.h"
31 #include "stream.h"
32 #include "hash.h"
33 #include "jhash.h"
34
35 #include "zebra/rib.h"
36 #include "zebra/rt.h"
37 #include "zebra/zebra_ns.h"
38 #include "zebra/zserv.h"
39 #include "zebra/debug.h"
40 #include "zebra/interface.h"
41 #include "zebra/zebra_memory.h"
42 #include "zebra/zebra_vrf.h"
43 #include "zebra/rt_netlink.h"
44 #include "zebra/zebra_l2.h"
45 #include "zebra/zebra_vxlan.h"
46 #include "zebra/zebra_evpn_mh.h"
47
48 /* definitions */
49
50 /* static function declarations */
51
52 /* Private functions */
map_slaves_to_bridge(struct interface * br_if,int link)53 static void map_slaves_to_bridge(struct interface *br_if, int link)
54 {
55 struct vrf *vrf;
56 struct interface *ifp;
57 struct zebra_vrf *zvrf;
58 struct zebra_ns *zns;
59
60 zvrf = zebra_vrf_lookup_by_id(br_if->vrf_id);
61 assert(zvrf);
62 zns = zvrf->zns;
63 assert(zns);
64 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
65 FOR_ALL_INTERFACES (vrf, ifp) {
66 struct zebra_if *zif;
67 struct zebra_l2info_brslave *br_slave;
68
69 if (ifp->ifindex == IFINDEX_INTERNAL || !ifp->info)
70 continue;
71 if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
72 continue;
73
74 /* NOTE: This assumes 'zebra_l2info_brslave' is the
75 * first field
76 * for any L2 interface.
77 */
78 zif = (struct zebra_if *)ifp->info;
79 br_slave = &zif->brslave_info;
80
81 if (link) {
82 if (br_slave->bridge_ifindex == br_if->ifindex &&
83 br_slave->ns_id == zns->ns_id)
84 br_slave->br_if = br_if;
85 } else {
86 if (br_slave->br_if == br_if)
87 br_slave->br_if = NULL;
88 }
89 }
90 }
91 }
92
93 /* Public functions */
zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave * br_slave,struct zebra_ns * zns)94 void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
95 struct zebra_ns *zns)
96 {
97 struct interface *br_if;
98
99 /* TODO: Handle change of master */
100 assert(zns);
101 br_if = if_lookup_by_index_per_ns(zebra_ns_lookup(zns->ns_id),
102 br_slave->bridge_ifindex);
103 if (br_if)
104 br_slave->br_if = br_if;
105 }
106
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave * br_slave)107 void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
108 {
109 br_slave->br_if = NULL;
110 }
111
zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave * bond_slave,vrf_id_t vrf_id)112 void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave,
113 vrf_id_t vrf_id)
114 {
115 struct interface *bond_if;
116
117 /* TODO: Handle change of master */
118 bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex);
119 if (bond_if)
120 bond_slave->bond_if = bond_if;
121 else
122 bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex,
123 vrf_id);
124 }
125
zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave * bond_slave)126 void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
127 {
128 if (bond_slave != NULL)
129 bond_slave->bond_if = NULL;
130 }
131
132 /*
133 * Handle Bridge interface add or update. Update relevant info,
134 * map slaves (if any) to the bridge.
135 */
zebra_l2_bridge_add_update(struct interface * ifp,struct zebra_l2info_bridge * bridge_info,int add)136 void zebra_l2_bridge_add_update(struct interface *ifp,
137 struct zebra_l2info_bridge *bridge_info,
138 int add)
139 {
140 struct zebra_if *zif;
141
142 zif = ifp->info;
143 assert(zif);
144
145 /* Copy over the L2 information. */
146 memcpy(&zif->l2info.br, bridge_info, sizeof(*bridge_info));
147
148 /* Link all slaves to this bridge */
149 map_slaves_to_bridge(ifp, 1);
150 }
151
152 /*
153 * Handle Bridge interface delete.
154 */
zebra_l2_bridge_del(struct interface * ifp)155 void zebra_l2_bridge_del(struct interface *ifp)
156 {
157 /* Unlink all slaves to this bridge */
158 map_slaves_to_bridge(ifp, 0);
159 }
160
161 /*
162 * Update L2 info for a VLAN interface. Only relevant parameter is the
163 * VLAN Id and this cannot change.
164 */
zebra_l2_vlanif_update(struct interface * ifp,struct zebra_l2info_vlan * vlan_info)165 void zebra_l2_vlanif_update(struct interface *ifp,
166 struct zebra_l2info_vlan *vlan_info)
167 {
168 struct zebra_if *zif;
169
170 zif = ifp->info;
171 assert(zif);
172
173 /* Copy over the L2 information. */
174 memcpy(&zif->l2info.vl, vlan_info, sizeof(*vlan_info));
175 }
176
177 /*
178 * Update L2 info for a VxLAN interface. This is called upon interface
179 * addition as well as update. Upon add, need to invoke the VNI create
180 * function. Upon update, the params of interest are the local tunnel
181 * IP and VLAN mapping, but the latter is handled separately.
182 */
zebra_l2_vxlanif_add_update(struct interface * ifp,struct zebra_l2info_vxlan * vxlan_info,int add)183 void zebra_l2_vxlanif_add_update(struct interface *ifp,
184 struct zebra_l2info_vxlan *vxlan_info, int add)
185 {
186 struct zebra_if *zif;
187 struct in_addr old_vtep_ip;
188 uint16_t chgflags = 0;
189
190 zif = ifp->info;
191 assert(zif);
192
193 if (add) {
194 memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info));
195 zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
196 zebra_vxlan_if_add(ifp);
197 return;
198 }
199
200 old_vtep_ip = zif->l2info.vxl.vtep_ip;
201
202 if (!IPV4_ADDR_SAME(&old_vtep_ip, &vxlan_info->vtep_ip)) {
203 chgflags |= ZEBRA_VXLIF_LOCAL_IP_CHANGE;
204 zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
205 }
206
207 if (!IPV4_ADDR_SAME(&zif->l2info.vxl.mcast_grp,
208 &vxlan_info->mcast_grp)) {
209 chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
210 zif->l2info.vxl.mcast_grp = vxlan_info->mcast_grp;
211 }
212
213 if (chgflags)
214 zebra_vxlan_if_update(ifp, chgflags);
215 }
216
217 /*
218 * Handle change to VLAN to VNI mapping.
219 */
zebra_l2_vxlanif_update_access_vlan(struct interface * ifp,vlanid_t access_vlan)220 void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
221 vlanid_t access_vlan)
222 {
223 struct zebra_if *zif;
224 vlanid_t old_access_vlan;
225
226 zif = ifp->info;
227 assert(zif);
228
229 old_access_vlan = zif->l2info.vxl.access_vlan;
230 if (old_access_vlan == access_vlan)
231 return;
232
233 zif->l2info.vxl.access_vlan = access_vlan;
234
235 zebra_evpn_vl_vxl_deref(old_access_vlan, zif);
236 zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
237 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_VLAN_CHANGE);
238 }
239
240 /*
241 * Handle VxLAN interface delete.
242 */
zebra_l2_vxlanif_del(struct interface * ifp)243 void zebra_l2_vxlanif_del(struct interface *ifp)
244 {
245 struct zebra_if *zif;
246
247 zif = ifp->info;
248 assert(zif);
249
250 zebra_evpn_vl_vxl_deref(zif->l2info.vxl.access_vlan, zif);
251 zebra_vxlan_if_del(ifp);
252 }
253
254 /*
255 * Map or unmap interface from bridge.
256 * NOTE: It is currently assumped that an interface has to be unmapped
257 * from a bridge before it can be mapped to another bridge.
258 */
zebra_l2if_update_bridge_slave(struct interface * ifp,ifindex_t bridge_ifindex,ns_id_t ns_id)259 void zebra_l2if_update_bridge_slave(struct interface *ifp,
260 ifindex_t bridge_ifindex,
261 ns_id_t ns_id)
262 {
263 struct zebra_if *zif;
264 ifindex_t old_bridge_ifindex;
265 ns_id_t old_ns_id;
266 struct zebra_vrf *zvrf;
267
268 zif = ifp->info;
269 assert(zif);
270
271 zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
272 if (!zvrf)
273 return;
274
275 old_bridge_ifindex = zif->brslave_info.bridge_ifindex;
276 old_ns_id = zif->brslave_info.ns_id;
277 if (old_bridge_ifindex == bridge_ifindex &&
278 old_ns_id == zif->brslave_info.ns_id)
279 return;
280
281 zif->brslave_info.ns_id = ns_id;
282 zif->brslave_info.bridge_ifindex = bridge_ifindex;
283 /* Set up or remove link with master */
284 if (bridge_ifindex != IFINDEX_INTERNAL) {
285 zebra_l2_map_slave_to_bridge(&zif->brslave_info, zvrf->zns);
286 /* In the case of VxLAN, invoke the handler for EVPN. */
287 if (zif->zif_type == ZEBRA_IF_VXLAN)
288 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
289 } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
290 /*
291 * In the case of VxLAN, invoke the handler for EVPN.
292 * Note that this should be done *prior*
293 * to unmapping the interface from the bridge.
294 */
295 if (zif->zif_type == ZEBRA_IF_VXLAN)
296 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
297 zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
298 }
299 }
300
zebra_l2if_update_bond_slave(struct interface * ifp,ifindex_t bond_ifindex)301 void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
302 {
303 struct zebra_if *zif;
304 ifindex_t old_bond_ifindex;
305
306 zif = ifp->info;
307 assert(zif);
308
309 old_bond_ifindex = zif->bondslave_info.bond_ifindex;
310 if (old_bond_ifindex == bond_ifindex)
311 return;
312
313 zif->bondslave_info.bond_ifindex = bond_ifindex;
314
315 /* Set up or remove link with master */
316 if (bond_ifindex != IFINDEX_INTERNAL)
317 zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id);
318 else if (old_bond_ifindex != IFINDEX_INTERNAL)
319 zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
320 }
321
zebra_vlan_bitmap_compute(struct interface * ifp,uint32_t vid_start,uint16_t vid_end)322 void zebra_vlan_bitmap_compute(struct interface *ifp,
323 uint32_t vid_start, uint16_t vid_end)
324 {
325 uint32_t vid;
326 struct zebra_if *zif;
327
328 zif = (struct zebra_if *)ifp->info;
329 assert(zif);
330
331 for (vid = vid_start; vid <= vid_end; ++vid)
332 bf_set_bit(zif->vlan_bitmap, vid);
333 }
334
zebra_vlan_mbr_re_eval(struct interface * ifp,bitfield_t old_vlan_bitmap)335 void zebra_vlan_mbr_re_eval(struct interface *ifp, bitfield_t old_vlan_bitmap)
336 {
337 uint32_t vid;
338 struct zebra_if *zif;
339
340 zif = (struct zebra_if *)ifp->info;
341 assert(zif);
342
343 if (!bf_cmp(zif->vlan_bitmap, old_vlan_bitmap))
344 /* no change */
345 return;
346
347 bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
348 /* if not already set create new reference */
349 if (!bf_test_index(old_vlan_bitmap, vid))
350 zebra_evpn_vl_mbr_ref(vid, zif);
351
352 /* also clear from the old vlan bitmap */
353 bf_release_index(old_vlan_bitmap, vid);
354 }
355
356 /* any bits remaining in the old vlan bitmap are stale references */
357 bf_for_each_set_bit(old_vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
358 zebra_evpn_vl_mbr_deref(vid, zif);
359 }
360 }
361