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
;
103 * Handle Bridge interface add or update. Update relevant info,
104 * map slaves (if any) to the bridge.
106 void zebra_l2_bridge_add_update(struct interface
*ifp
,
107 struct zebra_l2info_bridge
*bridge_info
,
110 struct zebra_if
*zif
;
115 /* Copy over the L2 information. */
116 memcpy(&zif
->l2info
.br
, bridge_info
, sizeof(*bridge_info
));
118 /* Link all slaves to this bridge */
119 map_slaves_to_bridge(ifp
, 1);
123 * Handle Bridge interface delete.
125 void zebra_l2_bridge_del(struct interface
*ifp
)
127 /* Unlink all slaves to this bridge */
128 map_slaves_to_bridge(ifp
, 0);
132 * Update L2 info for a VLAN interface. Only relevant parameter is the
133 * VLAN Id and this cannot change.
135 void zebra_l2_vlanif_update(struct interface
*ifp
,
136 struct zebra_l2info_vlan
*vlan_info
)
138 struct zebra_if
*zif
;
143 /* Copy over the L2 information. */
144 memcpy(&zif
->l2info
.vl
, vlan_info
, sizeof(*vlan_info
));
148 * Update L2 info for a VxLAN interface. This is called upon interface
149 * addition as well as update. Upon add, need to invoke the VNI create
150 * function. Upon update, the params of interest are the local tunnel
151 * IP and VLAN mapping, but the latter is handled separately.
153 void zebra_l2_vxlanif_add_update(struct interface
*ifp
,
154 struct zebra_l2info_vxlan
*vxlan_info
, int add
)
156 struct zebra_if
*zif
;
157 struct in_addr old_vtep_ip
;
163 memcpy(&zif
->l2info
.vxl
, vxlan_info
, sizeof(*vxlan_info
));
164 zebra_vxlan_if_add(ifp
);
168 old_vtep_ip
= zif
->l2info
.vxl
.vtep_ip
;
169 if (IPV4_ADDR_SAME(&old_vtep_ip
, &vxlan_info
->vtep_ip
))
172 zif
->l2info
.vxl
.vtep_ip
= vxlan_info
->vtep_ip
;
173 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_LOCAL_IP_CHANGE
);
177 * Handle change to VLAN to VNI mapping.
179 void zebra_l2_vxlanif_update_access_vlan(struct interface
*ifp
,
180 vlanid_t access_vlan
)
182 struct zebra_if
*zif
;
183 vlanid_t old_access_vlan
;
188 old_access_vlan
= zif
->l2info
.vxl
.access_vlan
;
189 if (old_access_vlan
== access_vlan
)
192 zif
->l2info
.vxl
.access_vlan
= access_vlan
;
193 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_VLAN_CHANGE
);
197 * Handle VxLAN interface delete.
199 void zebra_l2_vxlanif_del(struct interface
*ifp
)
201 zebra_vxlan_if_del(ifp
);
205 * Map or unmap interface from bridge.
206 * NOTE: It is currently assumped that an interface has to be unmapped
207 * from a bridge before it can be mapped to another bridge.
209 void zebra_l2if_update_bridge_slave(struct interface
*ifp
,
210 ifindex_t bridge_ifindex
)
212 struct zebra_if
*zif
;
213 ifindex_t old_bridge_ifindex
;
218 old_bridge_ifindex
= zif
->brslave_info
.bridge_ifindex
;
219 if (old_bridge_ifindex
== bridge_ifindex
)
222 zif
->brslave_info
.bridge_ifindex
= bridge_ifindex
;
224 /* Set up or remove link with master */
225 if (bridge_ifindex
!= IFINDEX_INTERNAL
) {
226 zebra_l2_map_slave_to_bridge(&zif
->brslave_info
);
227 /* In the case of VxLAN, invoke the handler for EVPN. */
228 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
229 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
230 } else if (old_bridge_ifindex
!= IFINDEX_INTERNAL
) {
232 * In the case of VxLAN, invoke the handler for EVPN.
233 * Note that this should be done *prior*
234 * to unmapping the interface from the bridge.
236 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
237 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
238 zebra_l2_unmap_slave_from_bridge(&zif
->brslave_info
);