aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-09-06 09:50:26 -0700
committerJohn Lo <loj@cisco.com>2018-09-08 14:51:48 +0000
commit3b81a1e5f205482b8ea30edbfd39559c4368ac4d (patch)
tree345ff2e3d599502852512180e95f21c76ec31f48
parent3348a4cf070b90a9c23bbc0b3752fa2801f832a9 (diff)
L2 BVI/FIB: Update L2 FIB table when BVI's MAC changes
also some moving of l2 headers to reduce dependencies Change-Id: I7a700a411a91451ef13fd65f9c90de2432b793bb Signed-off-by: Neale Ranns <nranns@cisco.com>
-rw-r--r--src/plugins/dpdk/device/device.c3
-rw-r--r--src/plugins/gbp/gbp_classify.c2
-rw-r--r--src/plugins/gbp/gbp_endpoint.c3
-rw-r--r--src/plugins/gbp/gbp_endpoint_group.c2
-rw-r--r--src/plugins/gbp/gbp_fwd.c1
-rw-r--r--src/plugins/l2e/l2e.c1
-rw-r--r--src/vnet/classify/in_out_acl.c2
-rw-r--r--src/vnet/classify/policer_classify.c1
-rw-r--r--src/vnet/classify/vnet_classify.h3
-rw-r--r--src/vnet/devices/af_packet/device.c2
-rw-r--r--src/vnet/ethernet/arp.c1
-rw-r--r--src/vnet/ethernet/interface.c15
-rw-r--r--src/vnet/gre/interface.c1
-rw-r--r--src/vnet/interface.c8
-rw-r--r--src/vnet/interface.h3
-rwxr-xr-xsrc/vnet/ip/ip6_neighbor.c1
-rw-r--r--src/vnet/ipsec-gre/interface.c1
-rw-r--r--src/vnet/l2/l2_fib.c4
-rw-r--r--src/vnet/l2/l2_fib.h8
-rw-r--r--src/vnet/l2/l2_fwd.c1
-rw-r--r--src/vnet/l2/l2_input.c21
-rw-r--r--src/vnet/l2/l2_input.h3
-rw-r--r--src/vnet/l2tp/decap.c1
-rw-r--r--src/vnet/policer/node_funcs.c2
-rw-r--r--src/vnet/qos/qos_record.c2
-rw-r--r--test/test_ip4_irb.py27
-rw-r--r--test/vpp_interface.py9
27 files changed, 104 insertions, 24 deletions
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c
index c38eec09d81..fcabe6e2dd6 100644
--- a/src/plugins/dpdk/device/device.c
+++ b/src/plugins/dpdk/device/device.c
@@ -43,7 +43,8 @@ static char *dpdk_tx_func_error_strings[] = {
};
static clib_error_t *
-dpdk_set_mac_address (vnet_hw_interface_t * hi, char *address)
+dpdk_set_mac_address (vnet_hw_interface_t * hi,
+ const u8 * old_address, const u8 * address)
{
int error;
dpdk_main_t *dm = &dpdk_main;
diff --git a/src/plugins/gbp/gbp_classify.c b/src/plugins/gbp/gbp_classify.c
index 859d4f95173..6b91d8cf099 100644
--- a/src/plugins/gbp/gbp_classify.c
+++ b/src/plugins/gbp/gbp_classify.c
@@ -16,6 +16,8 @@
*/
#include <plugins/gbp/gbp.h>
+#include <vnet/l2/l2_input.h>
+#include <vnet/l2/feat_bitmap.h>
typedef enum gbp_src_classify_type_t_
{
diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c
index cffa6da836c..0522f613f7d 100644
--- a/src/plugins/gbp/gbp_endpoint.c
+++ b/src/plugins/gbp/gbp_endpoint.c
@@ -19,6 +19,9 @@
#include <plugins/gbp/gbp_endpoint_group.h>
#include <vnet/ethernet/arp_packet.h>
+#include <vnet/l2/l2_input.h>
+#include <vnet/l2/l2_output.h>
+#include <vnet/l2/feat_bitmap.h>
/**
* IP4 destintion address to destination EPG mapping table
diff --git a/src/plugins/gbp/gbp_endpoint_group.c b/src/plugins/gbp/gbp_endpoint_group.c
index ed312d305a1..c5c06660f94 100644
--- a/src/plugins/gbp/gbp_endpoint_group.c
+++ b/src/plugins/gbp/gbp_endpoint_group.c
@@ -20,6 +20,8 @@
#include <vnet/dpo/dvr_dpo.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/l2/l2_input.h>
+#include <vnet/l2/feat_bitmap.h>
/**
* Pool of GBP endpoint_groups
diff --git a/src/plugins/gbp/gbp_fwd.c b/src/plugins/gbp/gbp_fwd.c
index fec5703d014..e4814337558 100644
--- a/src/plugins/gbp/gbp_fwd.c
+++ b/src/plugins/gbp/gbp_fwd.c
@@ -14,6 +14,7 @@
*/
#include <plugins/gbp/gbp.h>
+#include <vnet/l2/l2_input.h>
/**
* Grouping of global data for the GBP source EPG classification feature
diff --git a/src/plugins/l2e/l2e.c b/src/plugins/l2e/l2e.c
index e95c281c716..a56c25c54f8 100644
--- a/src/plugins/l2e/l2e.c
+++ b/src/plugins/l2e/l2e.c
@@ -18,6 +18,7 @@
#include <plugins/l2e/l2e.h>
#include <vnet/l2/l2_input.h>
+#include <vnet/l2/feat_bitmap.h>
/**
* Grouping of global data for the L2 emulation feature
diff --git a/src/vnet/classify/in_out_acl.c b/src/vnet/classify/in_out_acl.c
index 2d156ff4373..553c353b7ae 100644
--- a/src/vnet/classify/in_out_acl.c
+++ b/src/vnet/classify/in_out_acl.c
@@ -15,6 +15,8 @@
#include <vnet/ip/ip.h>
#include <vnet/classify/vnet_classify.h>
#include <vnet/classify/in_out_acl.h>
+#include <vnet/l2/l2_output.h>
+#include <vnet/l2/l2_input.h>
in_out_acl_main_t in_out_acl_main;
diff --git a/src/vnet/classify/policer_classify.c b/src/vnet/classify/policer_classify.c
index 542ba1015ed..4cf12a24e9e 100644
--- a/src/vnet/classify/policer_classify.c
+++ b/src/vnet/classify/policer_classify.c
@@ -13,6 +13,7 @@
* limitations under the License.
*/
#include <vnet/classify/policer_classify.h>
+#include <vnet/l2/l2_input.h>
policer_classify_main_t policer_classify_main;
diff --git a/src/vnet/classify/vnet_classify.h b/src/vnet/classify/vnet_classify.h
index 791b8fd18b7..4fea95d5b72 100644
--- a/src/vnet/classify/vnet_classify.h
+++ b/src/vnet/classify/vnet_classify.h
@@ -26,9 +26,6 @@
#include <vnet/ip/ip4_packet.h>
#include <vnet/ip/ip6_packet.h>
#include <vlib/cli.h>
-#include <vnet/l2/l2_input.h>
-#include <vnet/l2/l2_output.h>
-#include <vnet/l2/feat_bitmap.h>
#include <vnet/api_errno.h> /* for API error numbers */
#include <vppinfra/error.h>
diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c
index 0b0697b705f..b8c7501710e 100644
--- a/src/vnet/devices/af_packet/device.c
+++ b/src/vnet/devices/af_packet/device.c
@@ -278,7 +278,7 @@ af_packet_subif_add_del_function (vnet_main_t * vnm,
}
static clib_error_t *af_packet_set_mac_address_function
- (struct vnet_hw_interface_t *hi, char *address)
+ (struct vnet_hw_interface_t *hi, const u8 * old_address, const u8 * address)
{
af_packet_main_t *apm = &af_packet_main;
af_packet_if_t *apif =
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index b5c2e6dc748..275d606266b 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -26,6 +26,7 @@
#include <vnet/adj/adj_nbr.h>
#include <vnet/adj/adj_mcast.h>
#include <vnet/mpls/mpls.h>
+#include <vnet/l2/feat_bitmap.h>
/**
* @file
diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c
index bef13b8672c..d44a8a8ecb0 100644
--- a/src/vnet/ethernet/interface.c
+++ b/src/vnet/ethernet/interface.c
@@ -42,6 +42,7 @@
#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/l2/l2_input.h>
+#include <vnet/l2/l2_bd.h>
#include <vnet/adj/adj.h>
/**
@@ -218,7 +219,8 @@ ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
}
static clib_error_t *
-ethernet_mac_change (vnet_hw_interface_t * hi, char *mac_address)
+ethernet_mac_change (vnet_hw_interface_t * hi,
+ const u8 * old_address, const u8 * mac_address)
{
ethernet_interface_t *ei;
ethernet_main_t *em;
@@ -633,12 +635,23 @@ simulated_ethernet_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
return 0;
}
+static clib_error_t *
+simulated_ethernet_mac_change (vnet_hw_interface_t * hi,
+ const u8 * old_address, const u8 * mac_address)
+{
+ l2input_interface_mac_change (hi->sw_if_index, old_address, mac_address);
+
+ return (NULL);
+}
+
+
/* *INDENT-OFF* */
VNET_DEVICE_CLASS (ethernet_simulated_device_class) = {
.name = "Loopback",
.format_device_name = format_simulated_ethernet_name,
.tx_function = simulated_ethernet_interface_tx,
.admin_up_down_function = simulated_ethernet_admin_up_down,
+ .mac_addr_change_function = simulated_ethernet_mac_change,
};
/* *INDENT-ON* */
diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c
index 70c6c4df3b3..cd7f952cce5 100644
--- a/src/vnet/gre/interface.c
+++ b/src/vnet/gre/interface.c
@@ -24,6 +24,7 @@
#include <vnet/adj/adj_midchain.h>
#include <vnet/adj/adj_nbr.h>
#include <vnet/mpls/mpls.h>
+#include <vnet/l2/l2_input.h>
static const char *gre_tunnel_type_names[] = GRE_TUNNEL_TYPE_NAMES;
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index 1e69ccbf6ea..e04ba9b10af 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -42,6 +42,7 @@
#include <vnet/fib/ip6_fib.h>
#include <vnet/adj/adj.h>
#include <vnet/adj/adj_mcast.h>
+#include <vnet/l2/l2_input.h>
#define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0)
#define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1)
@@ -1501,12 +1502,14 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm,
if (hi->hw_address)
{
+ u8 *old_address = vec_dup (hi->hw_address);
vnet_device_class_t *dev_class =
vnet_get_device_class (vnm, hi->dev_class_index);
if (dev_class->mac_addr_change_function)
{
error =
- dev_class->mac_addr_change_function (hi, (char *) mac_address);
+ dev_class->mac_addr_change_function (hi, old_address,
+ mac_address);
}
if (!error)
{
@@ -1515,7 +1518,7 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm,
hw_class = vnet_get_hw_interface_class (vnm, hi->hw_class_index);
if (NULL != hw_class->mac_addr_change_function)
- hw_class->mac_addr_change_function (hi, (char *) mac_address);
+ hw_class->mac_addr_change_function (hi, old_address, mac_address);
}
else
{
@@ -1523,6 +1526,7 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm,
clib_error_return (0,
"MAC Address Change is not supported on this interface");
}
+ vec_free (old_address);
}
else
{
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index b34d19c55ef..30023ebded3 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -69,7 +69,8 @@ typedef clib_error_t *(vnet_subif_add_del_function_t)
/* Interface set mac address callback. */
typedef clib_error_t *(vnet_interface_set_mac_address_function_t)
- (struct vnet_hw_interface_t * hi, char *address);
+ (struct vnet_hw_interface_t * hi,
+ const u8 * old_address, const u8 * new_address);
/* Interface set rx mode callback. */
typedef clib_error_t *(vnet_interface_set_rx_mode_function_t)
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 1093009dd15..a54f9e91810 100755
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -25,6 +25,7 @@
#include <vnet/fib/ip6_fib.h>
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/ip/ip6_ll_table.h>
+#include <vnet/l2/l2_input.h>
/**
* @file
diff --git a/src/vnet/ipsec-gre/interface.c b/src/vnet/ipsec-gre/interface.c
index 8903df01c04..a51ca7f69dd 100644
--- a/src/vnet/ipsec-gre/interface.c
+++ b/src/vnet/ipsec-gre/interface.c
@@ -27,6 +27,7 @@
#include <vnet/ipsec-gre/ipsec_gre.h>
#include <vnet/ip/format.h>
#include <vnet/ipsec/ipsec.h>
+#include <vnet/l2/l2_input.h>
#include <vnet/ipsec/esp.h>
diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c
index 60d0db56d9d..dcfee7bf6e2 100644
--- a/src/vnet/l2/l2_fib.c
+++ b/src/vnet/l2/l2_fib.c
@@ -376,7 +376,7 @@ l2fib_cur_seq_num (u32 bd_index, u32 sw_if_index)
* If the entry already exists then overwrite it
*/
void
-l2fib_add_entry (u8 * mac, u32 bd_index,
+l2fib_add_entry (const u8 * mac, u32 bd_index,
u32 sw_if_index, l2fib_entry_result_flags_t flags)
{
l2fib_entry_key_t key;
@@ -660,7 +660,7 @@ VLIB_CLI_COMMAND (l2fib_test_command, static) = {
* sw_if_index is non-zero and does not match that in the entry.
*/
u32
-l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index)
+l2fib_del_entry (const u8 * mac, u32 bd_index, u32 sw_if_index)
{
l2fib_entry_result_t result;
l2fib_main_t *mp = &l2fib_main;
diff --git a/src/vnet/l2/l2_fib.h b/src/vnet/l2/l2_fib.h
index a958023eaea..77b5e7b9454 100644
--- a/src/vnet/l2/l2_fib.h
+++ b/src/vnet/l2/l2_fib.h
@@ -218,7 +218,7 @@ l2fib_compute_hash_bucket (l2fib_entry_key_t * key)
* l2fib_make_key() does read those two Bytes but does not use them.
*/
always_inline u64 __attribute__ ((no_sanitize_address))
-l2fib_make_key (u8 * mac_address, u16 bd_index)
+l2fib_make_key (const u8 * mac_address, u16 bd_index)
{
u64 temp;
@@ -440,19 +440,19 @@ l2fib_lookup_4 (BVT (clib_bihash) * mac_table,
void l2fib_clear_table (void);
void
-l2fib_add_entry (u8 * mac,
+l2fib_add_entry (const u8 * mac,
u32 bd_index,
u32 sw_if_index, l2fib_entry_result_flags_t flags);
static inline void
-l2fib_add_filter_entry (u8 * mac, u32 bd_index)
+l2fib_add_filter_entry (const u8 * mac, u32 bd_index)
{
l2fib_add_entry (mac, bd_index, ~0,
(L2FIB_ENTRY_RESULT_FLAG_FILTER |
L2FIB_ENTRY_RESULT_FLAG_STATIC));
}
-u32 l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index);
+u32 l2fib_del_entry (const u8 * mac, u32 bd_index, u32 sw_if_index);
void l2fib_start_ager_scan (vlib_main_t * vm);
diff --git a/src/vnet/l2/l2_fwd.c b/src/vnet/l2/l2_fwd.c
index 8c03683b133..fd7f54b41ef 100644
--- a/src/vnet/l2/l2_fwd.c
+++ b/src/vnet/l2/l2_fwd.c
@@ -25,6 +25,7 @@
#include <vnet/l2/l2_bvi.h>
#include <vnet/l2/l2_fwd.h>
#include <vnet/l2/l2_fib.h>
+#include <vnet/l2/feat_bitmap.h>
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index fd6f9eb462c..7e41c886dec 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -539,6 +539,27 @@ l2input_set_bridge_features (u32 bd_index, u32 feat_mask, u32 feat_value)
return bd_config->feature_bitmap;
}
+void
+l2input_interface_mac_change (u32 sw_if_index,
+ const u8 * old_address, const u8 * new_address)
+{
+ /* check if the sw_if_index passed is a BVI in a BD */
+ l2_input_config_t *intf_config;
+
+ intf_config = l2input_intf_config (sw_if_index);
+
+ if (intf_config->bridge && intf_config->bvi)
+ {
+ /* delete and re-add l2fib entry for the bvi interface */
+ l2fib_del_entry (old_address, intf_config->bd_index, sw_if_index);
+ l2fib_add_entry (new_address,
+ intf_config->bd_index,
+ sw_if_index,
+ L2FIB_ENTRY_RESULT_FLAG_BVI |
+ L2FIB_ENTRY_RESULT_FLAG_STATIC);
+ }
+}
+
/**
* Set the subinterface to run in l2 or l3 mode.
* For L3 mode, just the sw_if_index is specified.
diff --git a/src/vnet/l2/l2_input.h b/src/vnet/l2/l2_input.h
index ea9dcad63e5..4b303482df9 100644
--- a/src/vnet/l2/l2_input.h
+++ b/src/vnet/l2/l2_input.h
@@ -197,6 +197,9 @@ u32 l2input_intf_bitmap_enable (u32 sw_if_index,
/* Sets modifies flags from a bridge domain */
u32 l2input_set_bridge_features (u32 bd_index, u32 feat_mask, u32 feat_value);
+void l2input_interface_mac_change (u32 sw_if_index,
+ const u8 * old_address,
+ const u8 * new_address);
#define MODE_L3 0
#define MODE_L2_BRIDGE 1
diff --git a/src/vnet/l2tp/decap.c b/src/vnet/l2tp/decap.c
index 334f1feca4a..5925cdb7f41 100644
--- a/src/vnet/l2tp/decap.c
+++ b/src/vnet/l2tp/decap.c
@@ -21,6 +21,7 @@
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/l2tp/l2tp.h>
+#include <vnet/l2/l2_input.h>
/* Statistics (not really errors) */
#define foreach_l2t_decap_error \
diff --git a/src/vnet/policer/node_funcs.c b/src/vnet/policer/node_funcs.c
index 9a25dbb3cc6..5c185991e8b 100644
--- a/src/vnet/policer/node_funcs.c
+++ b/src/vnet/policer/node_funcs.c
@@ -22,6 +22,8 @@
#include <vnet/ip/ip.h>
#include <vnet/classify/policer_classify.h>
#include <vnet/classify/vnet_classify.h>
+#include <vnet/l2/feat_bitmap.h>
+#include <vnet/l2/l2_input.h>
/* Dispatch functions meant to be instantiated elsewhere */
diff --git a/src/vnet/qos/qos_record.c b/src/vnet/qos/qos_record.c
index 1433a02527b..3f43f48d8df 100644
--- a/src/vnet/qos/qos_record.c
+++ b/src/vnet/qos/qos_record.c
@@ -18,6 +18,8 @@
#include <vnet/ip/ip6_to_ip4.h>
#include <vnet/feature/feature.h>
#include <vnet/qos/qos_types.h>
+#include <vnet/l2/l2_input.h>
+#include <vnet/l2/feat_bitmap.h>
/**
* Per-interface, per-protocol vector of feature on/off configurations
diff --git a/test/test_ip4_irb.py b/test/test_ip4_irb.py
index 460cb43b726..6aad60a7609 100644
--- a/test/test_ip4_irb.py
+++ b/test/test_ip4_irb.py
@@ -31,6 +31,7 @@ from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from framework import VppTestCase, VppTestRunner
+from util import mactobinary
class TestIpIrb(VppTestCase):
@@ -238,26 +239,36 @@ class TestIpIrb(VppTestCase):
self.assertListEqual(rcvd1.res, rcvd2.res)
- def test_ip4_irb_2(self):
- """ IPv4 IRB test 2
-
- Test scenario:
- - ip traffic from pg0 and pg1 ends on pg2
- """
-
+ def send_and_verify_l2_to_ip(self):
stream1 = self.create_stream_l2_to_ip(
self.pg0, self.loop0, self.pg2, self.pg_if_packet_sizes)
stream2 = self.create_stream_l2_to_ip(
self.pg1, self.loop0, self.pg2, self.pg_if_packet_sizes)
+ self.vapi.cli("clear trace")
self.pg0.add_stream(stream1)
self.pg1.add_stream(stream2)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
- rcvd = self.pg2.get_capture()
+ rcvd = self.pg2.get_capture(514)
self.verify_capture_l2_to_ip(self.pg2, self.loop0, rcvd)
+ def test_ip4_irb_2(self):
+ """ IPv4 IRB test 2
+
+ Test scenario:
+ - ip traffic from pg0 and pg1 ends on pg2
+ """
+ self.send_and_verify_l2_to_ip()
+
+ # change the BVI's mac and resed traffic
+ self.loop0.set_mac("00:00:00:11:11:33")
+
+ self.send_and_verify_l2_to_ip()
+ # check it wasn't flooded
+ self.pg1.assert_nothing_captured(remark="UU Flood")
+
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)
diff --git a/test/vpp_interface.py b/test/vpp_interface.py
index e14a31eb722..1db34ba7958 100644
--- a/test/vpp_interface.py
+++ b/test/vpp_interface.py
@@ -1,7 +1,7 @@
from abc import abstractmethod, ABCMeta
import socket
-from util import Host, mk_ll_addr
+from util import Host, mk_ll_addr, mactobinary
class VppInterface(object):
@@ -170,6 +170,13 @@ class VppInterface(object):
self._hosts_by_ip4 = {}
self._hosts_by_ip6 = {}
+ def set_mac(self, mac):
+ self._local_mac = mac
+ self._local_ip6_ll = mk_ll_addr(mac)
+ self.test.vapi.sw_interface_set_mac_address(
+ self.sw_if_index,
+ mactobinary(self._local_mac))
+
def set_sw_if_index(self, sw_if_index):
self._sw_if_index = sw_if_index