]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_l2.c
Merge pull request #8643 from icosahedral/master
[mirror_frr.git] / zebra / zebra_l2.c
CommitLineData
6675513d 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"
6675513d 41#include "zebra/zebra_vrf.h"
42#include "zebra/rt_netlink.h"
c36e442c 43#include "zebra/interface.h"
6675513d 44#include "zebra/zebra_l2.h"
13d60d35 45#include "zebra/zebra_vxlan.h"
ce5160c0 46#include "zebra/zebra_evpn_mh.h"
6675513d 47
48/* definitions */
49
50/* static function declarations */
51
52/* Private functions */
d62a17ae 53static void map_slaves_to_bridge(struct interface *br_if, int link)
6675513d 54{
d62a17ae 55 struct vrf *vrf;
d62a17ae 56 struct interface *ifp;
a6e0edf2
PG
57 struct zebra_vrf *zvrf;
58 struct zebra_ns *zns;
d62a17ae 59
a6e0edf2
PG
60 zvrf = zebra_vrf_lookup_by_id(br_if->vrf_id);
61 assert(zvrf);
62 zns = zvrf->zns;
63 assert(zns);
a2addae8 64 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
451fda4f 65 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 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) {
a6e0edf2
PG
82 if (br_slave->bridge_ifindex == br_if->ifindex &&
83 br_slave->ns_id == zns->ns_id)
d62a17ae 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 }
6675513d 91}
92
93/* Public functions */
9771da71
PG
94void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
95 struct zebra_ns *zns)
6675513d 96{
d62a17ae 97 struct interface *br_if;
6675513d 98
d62a17ae 99 /* TODO: Handle change of master */
9771da71
PG
100 assert(zns);
101 br_if = if_lookup_by_index_per_ns(zebra_ns_lookup(zns->ns_id),
d62a17ae 102 br_slave->bridge_ifindex);
103 if (br_if)
104 br_slave->br_if = br_if;
6675513d 105}
106
d62a17ae 107void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
6675513d 108{
d62a17ae 109 br_slave->br_if = NULL;
6675513d 110}
111
00a7710c
AK
112/* If any of the bond members are in bypass state the bond is placed
113 * in bypass state
114 */
115static void zebra_l2_bond_lacp_bypass_eval(struct zebra_if *bond_zif)
116{
117 struct listnode *node;
118 struct zebra_if *bond_mbr;
119 bool old_bypass = !!(bond_zif->flags & ZIF_FLAG_LACP_BYPASS);
120 bool new_bypass = false;
121
122 if (bond_zif->bond_info.mbr_zifs) {
123 for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node,
124 bond_mbr)) {
125 if (bond_mbr->flags & ZIF_FLAG_LACP_BYPASS) {
126 new_bypass = true;
127 break;
128 }
129 }
130 }
131
132 if (old_bypass == new_bypass)
133 return;
134
135 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
136 zlog_debug("bond %s lacp bypass changed to %s",
137 bond_zif->ifp->name, new_bypass ? "on" : "off");
138
139 if (new_bypass)
140 bond_zif->flags |= ZIF_FLAG_LACP_BYPASS;
141 else
142 bond_zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
143
144 if (bond_zif->es_info.es)
145 zebra_evpn_es_bypass_update(bond_zif->es_info.es, bond_zif->ifp,
146 new_bypass);
147}
148
149/* Returns true if member was newly linked to bond */
c36e442c 150void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id)
b9368db9
DD
151{
152 struct interface *bond_if;
c36e442c
AK
153 struct zebra_if *bond_zif;
154 struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
b9368db9 155
ea7ec261 156 bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex);
c36e442c
AK
157 if (bond_if == bond_slave->bond_if)
158 return;
159
160 /* unlink the slave from the old master */
161 zebra_l2_unmap_slave_from_bond(zif);
162
163 /* If the bond is present and ready link the bond-member
164 * to it
165 */
166 if (bond_if && (bond_zif = bond_if->info)) {
167 if (bond_zif->bond_info.mbr_zifs) {
168 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
169 zlog_debug("bond mbr %s linked to %s",
170 zif->ifp->name, bond_if->name);
171 bond_slave->bond_if = bond_if;
172 /* link the slave to the new bond master */
173 listnode_add(bond_zif->bond_info.mbr_zifs, zif);
174 /* inherit protodown flags from the es-bond */
175 if (zebra_evpn_is_es_bond(bond_if))
176 zebra_evpn_mh_update_protodown_bond_mbr(
177 zif, false /*clear*/, __func__);
00a7710c 178 zebra_l2_bond_lacp_bypass_eval(bond_zif);
c36e442c
AK
179 }
180 } else {
181 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
182 zlog_debug("bond mbr %s link to bond skipped",
183 zif->ifp->name);
184 }
185}
186
187void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif)
188{
189 struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
190 struct zebra_if *bond_zif;
191
192 if (!bond_slave->bond_if) {
193 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
194 zlog_debug("bond mbr %s unlink from bond skipped",
195 zif->ifp->name);
196 return;
197 }
198
199 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
200 zlog_debug("bond mbr %s un-linked from %s", zif->ifp->name,
201 bond_slave->bond_if->name);
202
203 /* unlink the slave from the bond master */
204 bond_zif = bond_slave->bond_if->info;
205 /* clear protodown flags */
206 if (zebra_evpn_is_es_bond(bond_zif->ifp))
207 zebra_evpn_mh_update_protodown_bond_mbr(zif, true /*clear*/,
208 __func__);
209 listnode_delete(bond_zif->bond_info.mbr_zifs, zif);
210 bond_slave->bond_if = NULL;
00a7710c 211 zebra_l2_bond_lacp_bypass_eval(bond_zif);
b9368db9
DD
212}
213
c36e442c 214void zebra_l2if_update_bond(struct interface *ifp, bool add)
b9368db9 215{
c36e442c
AK
216 struct zebra_if *zif;
217 struct zebra_l2info_bond *bond;
218
219 zif = ifp->info;
220 assert(zif);
221 bond = &zif->bond_info;
222
223 if (add) {
224 if (!bond->mbr_zifs) {
225 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
226 zlog_debug("bond %s mbr list create",
227 ifp->name);
228 bond->mbr_zifs = list_new();
229 }
230 } else {
231 struct listnode *node;
232 struct listnode *nnode;
233 struct zebra_if *bond_mbr;
234
235 if (!bond->mbr_zifs)
236 return;
237
238 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
239 zlog_debug("bond %s mbr list delete", ifp->name);
240 for (ALL_LIST_ELEMENTS(bond->mbr_zifs, node, nnode, bond_mbr))
241 zebra_l2_unmap_slave_from_bond(bond_mbr);
242
243 list_delete(&bond->mbr_zifs);
244 }
b9368db9
DD
245}
246
6675513d 247/*
248 * Handle Bridge interface add or update. Update relevant info,
249 * map slaves (if any) to the bridge.
250 */
d62a17ae 251void zebra_l2_bridge_add_update(struct interface *ifp,
252 struct zebra_l2info_bridge *bridge_info,
253 int add)
6675513d 254{
d62a17ae 255 struct zebra_if *zif;
6675513d 256
d62a17ae 257 zif = ifp->info;
258 assert(zif);
6675513d 259
d62a17ae 260 /* Copy over the L2 information. */
261 memcpy(&zif->l2info.br, bridge_info, sizeof(*bridge_info));
6675513d 262
d62a17ae 263 /* Link all slaves to this bridge */
264 map_slaves_to_bridge(ifp, 1);
6675513d 265}
266
267/*
268 * Handle Bridge interface delete.
269 */
d62a17ae 270void zebra_l2_bridge_del(struct interface *ifp)
6675513d 271{
d62a17ae 272 /* Unlink all slaves to this bridge */
273 map_slaves_to_bridge(ifp, 0);
6675513d 274}
275
276/*
277 * Update L2 info for a VLAN interface. Only relevant parameter is the
278 * VLAN Id and this cannot change.
279 */
d62a17ae 280void zebra_l2_vlanif_update(struct interface *ifp,
281 struct zebra_l2info_vlan *vlan_info)
6675513d 282{
d62a17ae 283 struct zebra_if *zif;
6675513d 284
d62a17ae 285 zif = ifp->info;
286 assert(zif);
6675513d 287
d62a17ae 288 /* Copy over the L2 information. */
289 memcpy(&zif->l2info.vl, vlan_info, sizeof(*vlan_info));
6675513d 290}
291
077c07cc
PG
292/*
293 * Update L2 info for a GRE interface. This is called upon interface
294 * addition as well as update. Upon add/update, need to inform
295 * clients about GRE information.
296 */
297void zebra_l2_greif_add_update(struct interface *ifp,
298 struct zebra_l2info_gre *gre_info, int add)
299{
300 struct zebra_if *zif;
301 struct in_addr old_vtep_ip;
302
303 zif = ifp->info;
304 assert(zif);
305
306 if (add) {
307 memcpy(&zif->l2info.gre, gre_info, sizeof(*gre_info));
308 return;
309 }
310
311 old_vtep_ip = zif->l2info.gre.vtep_ip;
312 if (IPV4_ADDR_SAME(&old_vtep_ip, &gre_info->vtep_ip))
313 return;
314
315 zif->l2info.gre.vtep_ip = gre_info->vtep_ip;
316}
317
6675513d 318/*
319 * Update L2 info for a VxLAN interface. This is called upon interface
320 * addition as well as update. Upon add, need to invoke the VNI create
321 * function. Upon update, the params of interest are the local tunnel
322 * IP and VLAN mapping, but the latter is handled separately.
323 */
d62a17ae 324void zebra_l2_vxlanif_add_update(struct interface *ifp,
325 struct zebra_l2info_vxlan *vxlan_info, int add)
6675513d 326{
d62a17ae 327 struct zebra_if *zif;
328 struct in_addr old_vtep_ip;
d7fe235c 329 uint16_t chgflags = 0;
6675513d 330
d62a17ae 331 zif = ifp->info;
332 assert(zif);
6675513d 333
d62a17ae 334 if (add) {
335 memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info));
ce5160c0 336 zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
d62a17ae 337 zebra_vxlan_if_add(ifp);
338 return;
339 }
6675513d 340
d62a17ae 341 old_vtep_ip = zif->l2info.vxl.vtep_ip;
6675513d 342
d7fe235c
AK
343 if (!IPV4_ADDR_SAME(&old_vtep_ip, &vxlan_info->vtep_ip)) {
344 chgflags |= ZEBRA_VXLIF_LOCAL_IP_CHANGE;
345 zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
346 }
347
348 if (!IPV4_ADDR_SAME(&zif->l2info.vxl.mcast_grp,
349 &vxlan_info->mcast_grp)) {
350 chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
351 zif->l2info.vxl.mcast_grp = vxlan_info->mcast_grp;
352 }
353
354 if (chgflags)
355 zebra_vxlan_if_update(ifp, chgflags);
6675513d 356}
357
358/*
359 * Handle change to VLAN to VNI mapping.
360 */
d62a17ae 361void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
362 vlanid_t access_vlan)
6675513d 363{
d62a17ae 364 struct zebra_if *zif;
365 vlanid_t old_access_vlan;
6675513d 366
d62a17ae 367 zif = ifp->info;
368 assert(zif);
6675513d 369
d62a17ae 370 old_access_vlan = zif->l2info.vxl.access_vlan;
371 if (old_access_vlan == access_vlan)
372 return;
13d60d35 373
d62a17ae 374 zif->l2info.vxl.access_vlan = access_vlan;
ce5160c0
AK
375
376 zebra_evpn_vl_vxl_deref(old_access_vlan, zif);
377 zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
d62a17ae 378 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_VLAN_CHANGE);
6675513d 379}
380
381/*
382 * Handle VxLAN interface delete.
383 */
d62a17ae 384void zebra_l2_vxlanif_del(struct interface *ifp)
6675513d 385{
ce5160c0
AK
386 struct zebra_if *zif;
387
388 zif = ifp->info;
389 assert(zif);
390
391 zebra_evpn_vl_vxl_deref(zif->l2info.vxl.access_vlan, zif);
d62a17ae 392 zebra_vxlan_if_del(ifp);
6675513d 393}
394
395/*
396 * Map or unmap interface from bridge.
397 * NOTE: It is currently assumped that an interface has to be unmapped
398 * from a bridge before it can be mapped to another bridge.
399 */
d62a17ae 400void zebra_l2if_update_bridge_slave(struct interface *ifp,
a6e0edf2
PG
401 ifindex_t bridge_ifindex,
402 ns_id_t ns_id)
6675513d 403{
d62a17ae 404 struct zebra_if *zif;
405 ifindex_t old_bridge_ifindex;
a6e0edf2 406 ns_id_t old_ns_id;
9771da71 407 struct zebra_vrf *zvrf;
6675513d 408
d62a17ae 409 zif = ifp->info;
410 assert(zif);
6675513d 411
9771da71
PG
412 zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
413 if (!zvrf)
414 return;
415
d62a17ae 416 old_bridge_ifindex = zif->brslave_info.bridge_ifindex;
a6e0edf2
PG
417 old_ns_id = zif->brslave_info.ns_id;
418 if (old_bridge_ifindex == bridge_ifindex &&
419 old_ns_id == zif->brslave_info.ns_id)
d62a17ae 420 return;
6675513d 421
a6e0edf2 422 zif->brslave_info.ns_id = ns_id;
d62a17ae 423 zif->brslave_info.bridge_ifindex = bridge_ifindex;
d62a17ae 424 /* Set up or remove link with master */
af026ae4 425 if (bridge_ifindex != IFINDEX_INTERNAL) {
9771da71 426 zebra_l2_map_slave_to_bridge(&zif->brslave_info, zvrf->zns);
af026ae4 427 /* In the case of VxLAN, invoke the handler for EVPN. */
428 if (zif->zif_type == ZEBRA_IF_VXLAN)
b682f6de 429 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
72f2674a
AK
430 if (zif->es_info.es)
431 zebra_evpn_es_local_br_port_update(zif);
af026ae4 432 } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
57f7feb6
MK
433 /*
434 * In the case of VxLAN, invoke the handler for EVPN.
435 * Note that this should be done *prior*
436 * to unmapping the interface from the bridge.
af026ae4 437 */
438 if (zif->zif_type == ZEBRA_IF_VXLAN)
b682f6de 439 zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
72f2674a
AK
440 if (zif->es_info.es)
441 zebra_evpn_es_local_br_port_update(zif);
b682f6de 442 zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
af026ae4 443 }
6675513d 444}
b9368db9 445
00a7710c
AK
446void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex,
447 bool new_bypass)
b9368db9
DD
448{
449 struct zebra_if *zif;
450 ifindex_t old_bond_ifindex;
00a7710c
AK
451 bool old_bypass;
452 struct zebra_l2info_bondslave *bond_mbr;
b9368db9
DD
453
454 zif = ifp->info;
455 assert(zif);
456
00a7710c
AK
457 old_bypass = !!(zif->flags & ZIF_FLAG_LACP_BYPASS);
458 if (old_bypass != new_bypass) {
459 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
460 zlog_debug("bond-mbr %s lacp bypass changed to %s",
461 zif->ifp->name, new_bypass ? "on" : "off");
462
463 if (new_bypass)
464 zif->flags |= ZIF_FLAG_LACP_BYPASS;
465 else
466 zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
467
468 bond_mbr = &zif->bondslave_info;
469 if (bond_mbr->bond_if) {
470 struct zebra_if *bond_zif = bond_mbr->bond_if->info;
471
472 zebra_l2_bond_lacp_bypass_eval(bond_zif);
473 }
474 }
475
b9368db9
DD
476 old_bond_ifindex = zif->bondslave_info.bond_ifindex;
477 if (old_bond_ifindex == bond_ifindex)
478 return;
479
480 zif->bondslave_info.bond_ifindex = bond_ifindex;
481
482 /* Set up or remove link with master */
483 if (bond_ifindex != IFINDEX_INTERNAL)
c36e442c 484 zebra_l2_map_slave_to_bond(zif, ifp->vrf_id);
b9368db9 485 else if (old_bond_ifindex != IFINDEX_INTERNAL)
c36e442c 486 zebra_l2_unmap_slave_from_bond(zif);
b9368db9 487}
ce5160c0
AK
488
489void zebra_vlan_bitmap_compute(struct interface *ifp,
490 uint32_t vid_start, uint16_t vid_end)
491{
492 uint32_t vid;
493 struct zebra_if *zif;
494
495 zif = (struct zebra_if *)ifp->info;
496 assert(zif);
497
498 for (vid = vid_start; vid <= vid_end; ++vid)
499 bf_set_bit(zif->vlan_bitmap, vid);
500}
501
502void zebra_vlan_mbr_re_eval(struct interface *ifp, bitfield_t old_vlan_bitmap)
503{
504 uint32_t vid;
505 struct zebra_if *zif;
506
507 zif = (struct zebra_if *)ifp->info;
508 assert(zif);
509
510 if (!bf_cmp(zif->vlan_bitmap, old_vlan_bitmap))
511 /* no change */
512 return;
513
514 bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
515 /* if not already set create new reference */
516 if (!bf_test_index(old_vlan_bitmap, vid))
517 zebra_evpn_vl_mbr_ref(vid, zif);
518
519 /* also clear from the old vlan bitmap */
520 bf_release_index(old_vlan_bitmap, vid);
521 }
522
523 /* any bits remaining in the old vlan bitmap are stale references */
524 bf_for_each_set_bit(old_vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
525 zebra_evpn_vl_mbr_deref(vid, zif);
526 }
527}