I am using
tc
to change the MAC address of incoming packets on a TAP interface (tap0
) as follows where mac_org
is the MAC address of a guest in a QEMU virtual machine and mac_new
is a different MAC address that mac_org
should be replaced with.
tc qdisc add dev tap0 ingress handle ffff:
tc filter add dev tap0 protocol ip parent ffff: \
flower src_mac ${mac_org} \
action pedit ex munge eth src set ${mac_new} pipe \
action csum ip pipe \
action xt -j LOG
I also add an iptables rule to log UDP packets on the input hook.
iptables -A INPUT -p udp -j LOG
syslog shows that indeed the DHCP discover packet is changed accordingly. The tc
log entry looks as follows:
IN=tap0 OUT= MAC=ff:ff:ff:ff:ff:ff:${mac_new}:08:00 SRC=0.0.0.0 DST=255.255.255.255 LEN=338 TOS=0x00 PREC=0xC0 TTL=64 ID=0 DF PROTO=UDP SPT=68 DPT=67 LEN=318
and the log entry of the netfilter input hook which follows the tc
ingress hook as the locally incoming packet is passed towards the socket shows the same result slightly differently formatted.
IN=tap0 OUT= MACSRC=${mac_new} MACDST=ff:ff:ff:ff:ff:ff MACPROTO=0800 SRC=0.0.0.0 DST=255.255.255.255 LEN=338 TOS=0x00 PREC=0xC0 TTL=64 ID=0 DF PROTO=UDP SPT=68 DPT=67 LEN=318
Before starting QEMU I run dnsmasq
on tap0
which surprisingly shows the output:
DHCPDISCOVER(tap0) ${mac_org}
Running strace -f -x -s 10000 -e trace=network dnsmasq ...
shows a recvmsg
call that contains ${mac_org}
instead of ${mac_new}
.
recvmsg(4, {msg_name={sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, msg_namelen=16, msg_iov=[{iov_base="... ${mac_org} ..." ...
How can that happen? It almost appears as if the packet is altered after the netfilter input hook.
Asked by qemvirt
(13 rep)
Oct 15, 2023, 10:18 PM
Last activity: Oct 16, 2023, 12:06 AM
Last activity: Oct 16, 2023, 12:06 AM