如何使用 macvlan 实现单 NIC 双 MAC 地址

局域网里有 A B 两个机器:

  • A: raspberrypi 400 (debian 11)
    • IP: 192.168.31.134
    • MAC: 这里简称 A.m
  • B: 自己的笔记本 (MacOS)
    • IP: 192.168.31.198
    • MAC: 这里简称 B.m

我想要在 A 上使用 macvlan 搭建一个 VNIC,最后的效果是访问 A 和 ns0 (A上的虚拟网络) 时就好像在访问两个不同的机器一样。

以下是我的尝试:

  1. create a macvlan interface

    ip link add mvl0 link wlan0 type macvlan mode bridge
    ip netns add ns0
    ip link set macvlan1 netns ns0
    
  2. set the ip address

    ip netns exec ns0 bash
    ip addr add 192.168.31.135/24 dev mvl0
    ip link set dev mvl0 up
    
  3. 到这里先尝试下 ether 层能不能通。

    ip netns exec ns0 bash
    arping -I mvl0 192.168.31.1
    

    发现超时,arping 不通。

  4. 使用 tcpdump 进行监控,思路就是使用 ns0 去 arping B,查看流量可以走到哪一层。

    1. 在 ns0 中的 tcpdump 结果:arp request 发出后就没回复了,且 tcpdump 只能监控到 arp 广播
    2. 在 A 上的 tcpdump 结果:可收到 ns0 的 arp request,但看不到回复
    3. 在 B 上的 tcpdump 结果:可收到 ns0 arp request,但 MAC 头填的是 A.m。 B 最终会将 arp response 发给 ns0.m

综上所述,有以下几种可能:

  • 路由器不支持 macvlan,但没理由啊,交换机应该只关心 MAC 地址而已
  • A 收到了 arp response,但丢弃了,因为 MAC 地址和 A.wlan0 的 MAC 地址不符

问问 ChatGPT,有以下几种解决方案:

  • 没开启混杂模式,遂开启: sudo ip link set wlan0 promisc on,错误依旧
  • sudo sysctl net.ipv4.conf.all.rp_filter=1
  • sudo sysctl net.ipv4.conf.wlan0.rp_filter=1
  • 错误依旧

至此,google / chatGPT 已经搜不到错误原因了,求大lao救人于水火~

关于回答:

  1. 不用赘述上面已经提到过的内容
  2. 不用能够运行,只要能提供解决方案,并且能够解决问题就行

解决以下问题的回答将被采纳:

  1. 如何判定是否为交换机的问题?(B arp response 到达交换机后,交换机丢弃)
  2. 如何判定是否为 A 的问题?(A 收到了 B 的 arp response,但是因为 MAC 地址不符而丢弃)
  3. 修复 arp response 丢失的问题

更进一步的问题(无需作答,但能指导到我更好):

  1. 如何让 ns0 的 arp request 的 ether 头为 ns0 的 MAC 地址,而不是 A.wlan0 的 MAC 地址。

另:

  • 有没有类似这方面系统性学习的书 / 学习路线值得推荐的?万分感谢🙏

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在使用 macvlan 实现单 NIC 双 MAC 地址时,需要注意以下几点:

  1. 要使用 "macvlan mode bridge",这样就可以将数据包转发到父接口(即 wlan0)上。

  2. 需要将 MAC 地址设置成不同的地址,否则在局域网内会发生冲突。

  3. 如果使用 arp 来测试 VNIC 是否可用,需要注意 arp 缓存的问题,可以在测试时禁用 arp 缓存。

根据您提供的信息,以下是实现单 NIC 双 MAC 地址的步骤:

  1. 创建一个 macvlan 接口:
sudo ip link add mvl0 link wlan0 type macvlan mode bridge
  1. 在名为 ns0 的 network namespace 中配置 mvl0:
sudo ip netns add ns0
sudo ip link set mvl0 netns ns0
  1. 在 ns0 中设置 IP 地址和 MAC 地址:
sudo ip netns exec ns0 ip addr add 192.168.31.135/24 dev mvl0
sudo ip netns exec ns0 ip link set dev mvl0 address 00:11:22:33:44:55
sudo ip netns exec ns0 ip link set dev mvl0 up
  1. 禁用 arp 缓存(可选):
sudo ip netns exec ns0 sysctl -w net.ipv4.neigh.default.gc_stale_time=0
  1. 测试连接:
sudo ip netns exec ns0 arping -I mvl0 192.168.31.1

如果出现 “reply from 192.168.31.1” 表示连接正常。如果仍然无法连接,请检查路由表和防火墙设置。

关于学习路线,以下是几个值得推荐的学习资源:

  1. 《Linux 网络编程》一书,该书介绍了 Linux 网络编程的基础知识和实践经验。

  2. Linux 网络学习笔记,该笔记介绍了 Linux 网络编程的各个方面,包括 socket 编程、TCP/IP 协议栈、网络性能调优等。

  3. Linux 网络编程教程,该教程包含了 Linux 网络编程的基础知识和常用技术,适合初学者学习。

希望对您有所帮助!
如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,要实现单NIC双MAC地址,您可以使用macvlan虚拟网络接口来创建一个虚拟子接口,该虚拟子接口具有自己的MAC地址。然后,您可以将虚拟子接口放入一个单独的网络命名空间中,并为其分配一个IP地址,从而使其具有自己的网络栈。

下面是一些步骤,帮助您在Raspberrypi 400上使用macvlan实现单NIC双MAC地址:

1.创建一个名为macvlan0的虚拟网络接口,并将其连接到物理接口wlan0。使用以下命令:

sudo ip link add macvlan0 link wlan0 type macvlan mode bridge

2.创建一个名为ns0的新的网络命名空间。使用以下命令:

sudo ip netns add ns0

3.将虚拟接口macvlan0移到ns0网络命名空间中。使用以下命令:

sudo ip link set macvlan0 netns ns0

4.在ns0网络命名空间中设置IP地址。使用以下命令:

sudo ip netns exec ns0 ip addr add 192.168.31.135/24 dev macvlan0

5.在ns0网络命名空间中启动接口。使用以下命令:

sudo ip netns exec ns0 ip link set dev macvlan0 up

6.现在,您可以在ns0网络命名空间中使用ping命令测试连接是否正常。使用以下命令:

sudo ip netns exec ns0 ping 192.168.31.198

在此测试中,192.168.31.198是B机器的IP地址。

如果连接正常,则您已经成功地在Raspberrypi 400上使用macvlan实现了单NIC双MAC地址。现在,您可以在A机器上访问192.168.31.134,以及在ns0网络命名空间中使用192.168.31.135来访问虚拟接口。