11# SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
22# SPDX-License-Identifier: Apache-2.0
33
4+ import pytest
45from helpers import *
56
67def test_l2_arp (prepare_ifaces ):
@@ -13,3 +14,62 @@ def test_l2_arp(prepare_ifaces):
1314 src_mac = received [ARP ].hwsrc
1415 assert src_mac == VM1 .mac , \
1516 f"Bad ARP response (source mac: { src_mac } )"
17+
18+
19+ def vm_mac_sender ():
20+ pkt = (Ether (dst = PF0 .mac , src = VM1 .mac ) /
21+ IP (dst = VM4 .ip , src = VM1 .ip ) /
22+ UDP (dport = 1234 ))
23+ delayed_sendp (pkt , VM1 .tap )
24+
25+ def test_l2_addr_once (request , prepare_ifaces , grpc_client ):
26+ if request .config .getoption ("--hw" ):
27+ pytest .skip ("Cannot test MAC address change with real hardware" )
28+
29+ grpc_client .addinterface (VM4 .name , VM4 .pci , VM4 .vni , VM4 .ip , VM4 .ipv6 )
30+
31+ # No need to use ARP/DHCP/ND, since dpservice already "guessed" the MAC from the representor
32+
33+ threading .Thread (target = vm_mac_sender ).start ()
34+ pkt = sniff_packet (VM4 .tap , is_udp_pkt )
35+ assert pkt [Ether ].dst == VM4 .mac , \
36+ "Dpservice not using reprentor MAC"
37+
38+ # Now ARP/DHCP/ND happens, discovering the VM actually has a different MAC
39+ # (can happen on newer systemd with MACAddressPolicy != 'persistent')
40+ request_ip (VM4 , "12:34:56:78:9a:bc" )
41+
42+ threading .Thread (target = vm_mac_sender ).start ()
43+ pkt = sniff_packet (VM4 .tap , is_udp_pkt )
44+ assert pkt [Ether ].dst == "12:34:56:78:9a:bc" , \
45+ "Dpservice not using actual VM MAC"
46+
47+ # Additional ARP/DHCP/ND should not be able to change MAC again
48+ request_ip (VM4 )
49+
50+ threading .Thread (target = vm_mac_sender ).start ()
51+ pkt = sniff_packet (VM4 .tap , is_udp_pkt )
52+ assert pkt [Ether ].dst == "12:34:56:78:9a:bc" , \
53+ "Dpservice changed VM MAC"
54+
55+ # Now the VM gets removed and *another one* is put into its place
56+ # This can have different MAC address
57+ grpc_client .delinterface (VM4 .name )
58+ grpc_client .addinterface (VM4 .name , VM4 .pci , VM4 .vni , VM4 .ip , VM4 .ipv6 )
59+
60+ # Without ARP/DHCP/ND dpservice should try the use the old MAC
61+ threading .Thread (target = vm_mac_sender ).start ()
62+ pkt = sniff_packet (VM4 .tap , is_udp_pkt )
63+ assert pkt [Ether ].dst == "12:34:56:78:9a:bc" , \
64+ "Dpservice reset VM MAC"
65+
66+ # Additional ARP/DHCP/ND should be able to change MAC
67+ # because it is the first time after installing the interface
68+ request_ip (VM4 , "01:02:03:04:05:06" )
69+
70+ threading .Thread (target = vm_mac_sender ).start ()
71+ pkt = sniff_packet (VM4 .tap , is_udp_pkt )
72+ assert pkt [Ether ].dst == "01:02:03:04:05:06" , \
73+ "Dpservice did not accept VM MAC"
74+
75+ grpc_client .delinterface (VM4 .name )
0 commit comments