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
)
60 for (ALL_LIST_ELEMENTS_RO(vrf
->iflist
, node
, ifp
)) {
62 struct zebra_l2info_brslave
*br_slave
;
64 if (ifp
->ifindex
== IFINDEX_INTERNAL
|| !ifp
->info
)
66 if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
))
69 /* NOTE: This assumes 'zebra_l2info_brslave' is the
71 * for any L2 interface.
73 zif
= (struct zebra_if
*)ifp
->info
;
74 br_slave
= &zif
->brslave_info
;
77 if (br_slave
->bridge_ifindex
== br_if
->ifindex
)
78 br_slave
->br_if
= br_if
;
80 if (br_slave
->br_if
== br_if
)
81 br_slave
->br_if
= NULL
;
87 /* Public functions */
88 void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave
*br_slave
)
90 struct interface
*br_if
;
92 /* TODO: Handle change of master */
93 br_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
94 br_slave
->bridge_ifindex
);
96 br_slave
->br_if
= br_if
;
99 void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave
*br_slave
)
101 br_slave
->br_if
= NULL
;
105 * Handle Bridge interface add or update. Update relevant info,
106 * map slaves (if any) to the bridge.
108 void zebra_l2_bridge_add_update(struct interface
*ifp
,
109 struct zebra_l2info_bridge
*bridge_info
,
112 struct zebra_if
*zif
;
117 /* Copy over the L2 information. */
118 memcpy(&zif
->l2info
.br
, bridge_info
, sizeof(*bridge_info
));
120 /* Link all slaves to this bridge */
121 map_slaves_to_bridge(ifp
, 1);
125 * Handle Bridge interface delete.
127 void zebra_l2_bridge_del(struct interface
*ifp
)
129 /* Unlink all slaves to this bridge */
130 map_slaves_to_bridge(ifp
, 0);
134 * Update L2 info for a VLAN interface. Only relevant parameter is the
135 * VLAN Id and this cannot change.
137 void zebra_l2_vlanif_update(struct interface
*ifp
,
138 struct zebra_l2info_vlan
*vlan_info
)
140 struct zebra_if
*zif
;
145 /* Copy over the L2 information. */
146 memcpy(&zif
->l2info
.vl
, vlan_info
, sizeof(*vlan_info
));
150 * Update L2 info for a VxLAN interface. This is called upon interface
151 * addition as well as update. Upon add, need to invoke the VNI create
152 * function. Upon update, the params of interest are the local tunnel
153 * IP and VLAN mapping, but the latter is handled separately.
155 void zebra_l2_vxlanif_add_update(struct interface
*ifp
,
156 struct zebra_l2info_vxlan
*vxlan_info
, int add
)
158 struct zebra_if
*zif
;
159 struct in_addr old_vtep_ip
;
165 memcpy(&zif
->l2info
.vxl
, vxlan_info
, sizeof(*vxlan_info
));
166 zebra_vxlan_if_add(ifp
);
170 old_vtep_ip
= zif
->l2info
.vxl
.vtep_ip
;
171 if (IPV4_ADDR_SAME(&old_vtep_ip
, &vxlan_info
->vtep_ip
))
174 zif
->l2info
.vxl
.vtep_ip
= vxlan_info
->vtep_ip
;
175 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_LOCAL_IP_CHANGE
);
179 * Handle change to VLAN to VNI mapping.
181 void zebra_l2_vxlanif_update_access_vlan(struct interface
*ifp
,
182 vlanid_t access_vlan
)
184 struct zebra_if
*zif
;
185 vlanid_t old_access_vlan
;
190 old_access_vlan
= zif
->l2info
.vxl
.access_vlan
;
191 if (old_access_vlan
== access_vlan
)
194 zif
->l2info
.vxl
.access_vlan
= access_vlan
;
195 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_VLAN_CHANGE
);
199 * Handle VxLAN interface delete.
201 void zebra_l2_vxlanif_del(struct interface
*ifp
)
203 zebra_vxlan_if_del(ifp
);
207 * Map or unmap interface from bridge.
208 * NOTE: It is currently assumped that an interface has to be unmapped
209 * from a bridge before it can be mapped to another bridge.
211 void zebra_l2if_update_bridge_slave(struct interface
*ifp
,
212 ifindex_t bridge_ifindex
)
214 struct zebra_if
*zif
;
215 ifindex_t old_bridge_ifindex
;
220 old_bridge_ifindex
= zif
->brslave_info
.bridge_ifindex
;
221 if (old_bridge_ifindex
== bridge_ifindex
)
224 zif
->brslave_info
.bridge_ifindex
= bridge_ifindex
;
226 /* Set up or remove link with master */
227 if (bridge_ifindex
!= IFINDEX_INTERNAL
) {
228 zebra_l2_map_slave_to_bridge(&zif
->brslave_info
);
229 /* In the case of VxLAN, invoke the handler for EVPN. */
230 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
231 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
232 } else if (old_bridge_ifindex
!= IFINDEX_INTERNAL
) {
234 * In the case of VxLAN, invoke the handler for EVPN.
235 * Note that this should be done *prior*
236 * to unmapping the interface from the bridge.
238 if (zif
->zif_type
== ZEBRA_IF_VXLAN
)
239 zebra_vxlan_if_update(ifp
, ZEBRA_VXLIF_MASTER_CHANGE
);
240 zebra_l2_unmap_slave_from_bridge(&zif
->brslave_info
);