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 listnode
*node
;
56 struct interface
*ifp
;
58 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
59 for (ALL_LIST_ELEMENTS_RO(vrf
->iflist
, node
, ifp
)) {
61 struct zebra_l2info_brslave
*br_slave
;
63 if (ifp
->ifindex
== IFINDEX_INTERNAL
|| !ifp
->info
)
65 if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
))
68 /* NOTE: This assumes 'zebra_l2info_brslave' is the
70 * for any L2 interface.
72 zif
= (struct zebra_if
*)ifp
->info
;
73 br_slave
= &zif
->brslave_info
;
76 if (br_slave
->bridge_ifindex
== br_if
->ifindex
)
77 br_slave
->br_if
= br_if
;
79 if (br_slave
->br_if
== br_if
)
80 br_slave
->br_if
= NULL
;
86 /* Public functions */
87 void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave
*br_slave
)
89 struct interface
*br_if
;
91 /* TODO: Handle change of master */
92 br_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
93 br_slave
->bridge_ifindex
);
95 br_slave
->br_if
= br_if
;
98 void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave
*br_slave
)
100 br_slave
->br_if
= NULL
;
104 * Handle Bridge interface add or update. Update relevant info,
105 * map slaves (if any) to the bridge.
107 void zebra_l2_bridge_add_update(struct interface
*ifp
,
108 struct zebra_l2info_bridge
*bridge_info
,
111 struct zebra_if
*zif
;
116 /* Copy over the L2 information. */
117 memcpy(&zif
->l2info
.br
, bridge_info
, sizeof(*bridge_info
));
119 /* Link all slaves to this bridge */
120 map_slaves_to_bridge(ifp
, 1);
124 * Handle Bridge interface delete.
126 void zebra_l2_bridge_del(struct interface
*ifp
)
128 /* Unlink all slaves to this bridge */
129 map_slaves_to_bridge(ifp
, 0);
133 * Update L2 info for a VLAN interface. Only relevant parameter is the
134 * VLAN Id and this cannot change.
136 void zebra_l2_vlanif_update(struct interface
*ifp
,
137 struct zebra_l2info_vlan
*vlan_info
)
139 struct zebra_if
*zif
;
144 /* Copy over the L2 information. */
145 memcpy(&zif
->l2info
.vl
, vlan_info
, sizeof(*vlan_info
));
149 * Update L2 info for a VxLAN interface. This is called upon interface
150 * addition as well as update. Upon add, need to invoke the VNI create
151 * function. Upon update, the params of interest are the local tunnel
152 * IP and VLAN mapping, but the latter is handled separately.
154 void zebra_l2_vxlanif_add_update(struct interface
*ifp
,
155 struct zebra_l2info_vxlan
*vxlan_info
, int add
)
157 struct zebra_if
*zif
;
158 struct in_addr old_vtep_ip
;
164 memcpy(&zif
->l2info
.vxl
, vxlan_info
, sizeof(*vxlan_info
));
165 zebra_vxlan_if_add(ifp
);
169 old_vtep_ip
= zif
->l2info
.vxl
.vtep_ip
;
170 if (IPV4_ADDR_SAME(&old_vtep_ip
, &vxlan_info
->vtep_ip
))
173 zif
->l2info
.vxl
.vtep_ip
= vxlan_info
->vtep_ip
;
174 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_LOCAL_IP_CHANGE
);
178 * Handle change to VLAN to VNI mapping.
180 void zebra_l2_vxlanif_update_access_vlan(struct interface
*ifp
,
181 vlanid_t access_vlan
)
183 struct zebra_if
*zif
;
184 vlanid_t old_access_vlan
;
189 old_access_vlan
= zif
->l2info
.vxl
.access_vlan
;
190 if (old_access_vlan
== access_vlan
)
193 zif
->l2info
.vxl
.access_vlan
= access_vlan
;
194 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_VLAN_CHANGE
);
198 * Handle VxLAN interface delete.
200 void zebra_l2_vxlanif_del(struct interface
*ifp
)
202 zebra_vxlan_if_del(ifp
);
206 * Map or unmap interface from bridge.
207 * NOTE: It is currently assumped that an interface has to be unmapped
208 * from a bridge before it can be mapped to another bridge.
210 void zebra_l2if_update_bridge_slave(struct interface
*ifp
,
211 ifindex_t bridge_ifindex
)
213 struct zebra_if
*zif
;
214 ifindex_t old_bridge_ifindex
;
219 old_bridge_ifindex
= zif
->brslave_info
.bridge_ifindex
;
220 if (old_bridge_ifindex
== bridge_ifindex
)
223 zif
->brslave_info
.bridge_ifindex
= bridge_ifindex
;
225 /* Set up or remove link with master */
226 if (bridge_ifindex
!= IFINDEX_INTERNAL
) {
227 zebra_l2_map_slave_to_bridge(&zif
->brslave_info
);
228 /* In the case of VxLAN, invoke the handler for EVPN. */
229 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
230 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
231 } else if (old_bridge_ifindex
!= IFINDEX_INTERNAL
) {
233 * In the case of VxLAN, invoke the handler for EVPN.
234 * Note that this should be done *prior*
235 * to unmapping the interface from the bridge.
237 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
238 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
239 zebra_l2_unmap_slave_from_bridge(&zif
->brslave_info
);