summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ethernet/interface.c11
-rw-r--r--test/test_neighbor.py106
2 files changed, 113 insertions, 4 deletions
diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c
index bf2256630f0..849024238bd 100644
--- a/src/vnet/ethernet/interface.c
+++ b/src/vnet/ethernet/interface.c
@@ -303,8 +303,17 @@ ethernet_mac_change (vnet_hw_interface_t * hi,
{
ethernet_address_change_ctx_t *cb;
+ u32 id, sw_if_index;
vec_foreach (cb, em->address_change_callbacks)
- cb->function (em, hi->sw_if_index, cb->function_opaque);
+ {
+ cb->function (em, hi->sw_if_index, cb->function_opaque);
+ /* clang-format off */
+ hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id,
+ ({
+ cb->function (em, sw_if_index, cb->function_opaque);
+ }));
+ /* clang-format on */
+ }
}
return (NULL);
diff --git a/test/test_neighbor.py b/test/test_neighbor.py
index 24737da0eca..041d78245a5 100644
--- a/test/test_neighbor.py
+++ b/test/test_neighbor.py
@@ -16,8 +16,9 @@ from vpp_ip_route import (
FibPathType,
VppIpInterfaceAddress,
)
-from vpp_papi import VppEnum
+from vpp_papi import VppEnum, MACAddress
from vpp_ip import VppIpPuntRedirect
+from vpp_sub_interface import VppDot1ADSubint
import scapy.compat
from scapy.packet import Raw
@@ -86,11 +87,11 @@ class ARPTestCase(VppTestCase):
super(ARPTestCase, self).tearDown()
- def verify_arp_req(self, rx, smac, sip, dip):
+ def verify_arp_req(self, rx, smac, sip, dip, etype=0x0806):
ether = rx[Ether]
self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
self.assertEqual(ether.src, smac)
- self.assertEqual(ether.type, 0x0806)
+ self.assertEqual(ether.type, etype)
arp = rx[ARP]
self.assertEqual(arp.hwtype, 1)
@@ -845,6 +846,105 @@ class ARPTestCase(VppTestCase):
self.pg2.admin_down()
self.pg1.admin_down()
+ def test_arp_after_mac_change(self):
+ """ARP (after MAC address change)"""
+
+ #
+ # Prepare a subinterface
+ #
+ subif0 = VppDot1ADSubint(self, self.pg1, 0, 300, 400)
+ subif0.admin_up()
+ subif0.config_ip4()
+
+ #
+ # Send a packet to cause ARP generation for the parent interface's remote host
+ #
+ p1 = (
+ Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
+ / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4)
+ / UDP(sport=1234, dport=1234)
+ / Raw()
+ )
+
+ self.pg0.add_stream(p1)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ rx = self.pg1.get_capture(1)
+
+ self.verify_arp_req(
+ rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1.remote_ip4
+ )
+
+ #
+ # Send a packet to cause ARP generation for the subinterface's remote host
+ #
+ p2 = (
+ Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
+ / IP(src=self.pg0.remote_ip4, dst=subif0.remote_ip4)
+ / UDP(sport=1234, dport=1234)
+ / Raw()
+ )
+
+ self.pg0.add_stream(p2)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ rx = self.pg1.get_capture(1)
+
+ self.verify_arp_req(
+ rx[0],
+ self.pg1.local_mac,
+ subif0.local_ip4,
+ subif0.remote_ip4,
+ subif0.DOT1AD_TYPE,
+ )
+
+ #
+ # Change MAC address of the parent interface
+ #
+ pg1_mac_saved = self.pg1.local_mac
+ self.pg1.set_mac(MACAddress("00:00:00:11:22:33"))
+
+ #
+ # Send a packet to cause ARP generation for the parent interface's remote host
+ # - expect new MAC address is used as the source
+ #
+ self.pg0.add_stream(p1)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ rx = self.pg1.get_capture(1)
+
+ self.verify_arp_req(
+ rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1.remote_ip4
+ )
+
+ #
+ # Send a packet to cause ARP generation for the subinterface's remote host
+ # - expect new MAC address is used as the source
+ #
+
+ self.pg0.add_stream(p2)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ rx = self.pg1.get_capture(1)
+
+ self.verify_arp_req(
+ rx[0],
+ self.pg1.local_mac,
+ subif0.local_ip4,
+ subif0.remote_ip4,
+ subif0.DOT1AD_TYPE,
+ )
+
+ #
+ # Cleanup
+ #
+ subif0.remove_vpp_config()
+ self.pg1.set_mac(MACAddress(pg1_mac_saved))
+
def test_proxy_mirror_arp(self):
"""Interface Mirror Proxy ARP"""