2 * Zebra Layer-2 interface handling code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
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
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.
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
35 #include "zebra/rib.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"
49 /* static function declarations */
51 /* Private functions */
52 static void map_slaves_to_bridge(struct interface
*br_if
, int link
)
55 struct interface
*ifp
;
57 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
58 FOR_ALL_INTERFACES (vrf
, ifp
) {
60 struct zebra_l2info_brslave
*br_slave
;
62 if (ifp
->ifindex
== IFINDEX_INTERNAL
|| !ifp
->info
)
64 if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
))
67 /* NOTE: This assumes 'zebra_l2info_brslave' is the
69 * for any L2 interface.
71 zif
= (struct zebra_if
*)ifp
->info
;
72 br_slave
= &zif
->brslave_info
;
75 if (br_slave
->bridge_ifindex
== br_if
->ifindex
)
76 br_slave
->br_if
= br_if
;
78 if (br_slave
->br_if
== br_if
)
79 br_slave
->br_if
= NULL
;
85 /* Public functions */
86 void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave
*br_slave
)
88 struct interface
*br_if
;
90 /* TODO: Handle change of master */
91 br_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
92 br_slave
->bridge_ifindex
);
94 br_slave
->br_if
= br_if
;
97 void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave
*br_slave
)
99 br_slave
->br_if
= NULL
;
102 void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave
*bond_slave
,
105 struct interface
*bond_if
;
107 /* TODO: Handle change of master */
108 bond_if
= if_lookup_by_index_all_vrf(bond_slave
->bond_ifindex
);
110 bond_slave
->bond_if
= bond_if
;
112 bond_slave
->bond_if
= if_create_ifindex(bond_slave
->bond_ifindex
,
116 void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave
*bond_slave
)
118 if (bond_slave
!= NULL
)
119 bond_slave
->bond_if
= NULL
;
123 * Handle Bridge interface add or update. Update relevant info,
124 * map slaves (if any) to the bridge.
126 void zebra_l2_bridge_add_update(struct interface
*ifp
,
127 struct zebra_l2info_bridge
*bridge_info
,
130 struct zebra_if
*zif
;
135 /* Copy over the L2 information. */
136 memcpy(&zif
->l2info
.br
, bridge_info
, sizeof(*bridge_info
));
138 /* Link all slaves to this bridge */
139 map_slaves_to_bridge(ifp
, 1);
143 * Handle Bridge interface delete.
145 void zebra_l2_bridge_del(struct interface
*ifp
)
147 /* Unlink all slaves to this bridge */
148 map_slaves_to_bridge(ifp
, 0);
152 * Update L2 info for a VLAN interface. Only relevant parameter is the
153 * VLAN Id and this cannot change.
155 void zebra_l2_vlanif_update(struct interface
*ifp
,
156 struct zebra_l2info_vlan
*vlan_info
)
158 struct zebra_if
*zif
;
163 /* Copy over the L2 information. */
164 memcpy(&zif
->l2info
.vl
, vlan_info
, sizeof(*vlan_info
));
168 * Update L2 info for a VxLAN interface. This is called upon interface
169 * addition as well as update. Upon add, need to invoke the VNI create
170 * function. Upon update, the params of interest are the local tunnel
171 * IP and VLAN mapping, but the latter is handled separately.
173 void zebra_l2_vxlanif_add_update(struct interface
*ifp
,
174 struct zebra_l2info_vxlan
*vxlan_info
, int add
)
176 struct zebra_if
*zif
;
177 struct in_addr old_vtep_ip
;
178 uint16_t chgflags
= 0;
184 memcpy(&zif
->l2info
.vxl
, vxlan_info
, sizeof(*vxlan_info
));
185 zebra_vxlan_if_add(ifp
);
189 old_vtep_ip
= zif
->l2info
.vxl
.vtep_ip
;
191 if (!IPV4_ADDR_SAME(&old_vtep_ip
, &vxlan_info
->vtep_ip
)) {
192 chgflags
|= ZEBRA_VXLIF_LOCAL_IP_CHANGE
;
193 zif
->l2info
.vxl
.vtep_ip
= vxlan_info
->vtep_ip
;
196 if (!IPV4_ADDR_SAME(&zif
->l2info
.vxl
.mcast_grp
,
197 &vxlan_info
->mcast_grp
)) {
198 chgflags
|= ZEBRA_VXLIF_MCAST_GRP_CHANGE
;
199 zif
->l2info
.vxl
.mcast_grp
= vxlan_info
->mcast_grp
;
203 zebra_vxlan_if_update(ifp
, chgflags
);
207 * Handle change to VLAN to VNI mapping.
209 void zebra_l2_vxlanif_update_access_vlan(struct interface
*ifp
,
210 vlanid_t access_vlan
)
212 struct zebra_if
*zif
;
213 vlanid_t old_access_vlan
;
218 old_access_vlan
= zif
->l2info
.vxl
.access_vlan
;
219 if (old_access_vlan
== access_vlan
)
222 zif
->l2info
.vxl
.access_vlan
= access_vlan
;
223 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_VLAN_CHANGE
);
227 * Handle VxLAN interface delete.
229 void zebra_l2_vxlanif_del(struct interface
*ifp
)
231 zebra_vxlan_if_del(ifp
);
235 * Map or unmap interface from bridge.
236 * NOTE: It is currently assumped that an interface has to be unmapped
237 * from a bridge before it can be mapped to another bridge.
239 void zebra_l2if_update_bridge_slave(struct interface
*ifp
,
240 ifindex_t bridge_ifindex
)
242 struct zebra_if
*zif
;
243 ifindex_t old_bridge_ifindex
;
248 old_bridge_ifindex
= zif
->brslave_info
.bridge_ifindex
;
249 if (old_bridge_ifindex
== bridge_ifindex
)
252 zif
->brslave_info
.bridge_ifindex
= bridge_ifindex
;
254 /* Set up or remove link with master */
255 if (bridge_ifindex
!= IFINDEX_INTERNAL
) {
256 zebra_l2_map_slave_to_bridge(&zif
->brslave_info
);
257 /* In the case of VxLAN, invoke the handler for EVPN. */
258 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
259 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
260 } else if (old_bridge_ifindex
!= IFINDEX_INTERNAL
) {
262 * In the case of VxLAN, invoke the handler for EVPN.
263 * Note that this should be done *prior*
264 * to unmapping the interface from the bridge.
266 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
267 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
268 zebra_l2_unmap_slave_from_bridge(&zif
->brslave_info
);
272 void zebra_l2if_update_bond_slave(struct interface
*ifp
, ifindex_t bond_ifindex
)
274 struct zebra_if
*zif
;
275 ifindex_t old_bond_ifindex
;
280 old_bond_ifindex
= zif
->bondslave_info
.bond_ifindex
;
281 if (old_bond_ifindex
== bond_ifindex
)
284 zif
->bondslave_info
.bond_ifindex
= bond_ifindex
;
286 /* Set up or remove link with master */
287 if (bond_ifindex
!= IFINDEX_INTERNAL
)
288 zebra_l2_map_slave_to_bond(&zif
->bondslave_info
, ifp
->vrf_id
);
289 else if (old_bond_ifindex
!= IFINDEX_INTERNAL
)
290 zebra_l2_unmap_slave_from_bond(&zif
->bondslave_info
);