当前位置: 首页 > Linux

linux网卡混杂模式下,mac地址不是自己的mac会不会被送到网络层处理

时间:2023-04-06 21:26:05 Linux

实验环境注:在ubuntu18:04环境下,创建一个networknamespacemac,veth网卡用于连接到系统。对端是veth1,本端是eth0。CNOOC在系统中有一块docker0网卡,具体参数如上图所示。配置如下sudoipnetnsaddmacsudoiplinkaddveth1typevethpeernameeth0netnsmacsudoiplinksetveth1upsudoipaddradd10.10.10.1/24devveth1sudoiplinksetveth1address00:01:02:03:04:05sudoipnetnsexecmaciplinksudoipnetnsexecmaciplinksetloupsudoipnetnsexecmaciplinkseteth0upsudoipnetnsexecmacipaddradd10.10.10.2/24deveth0sudoipnetnsexecmaciproute通过10添加默认值01。10.1deveth0experimentexperiment1pinggatewayadmin@ubuntu:~$sudoipnetnsexecmacping10.10.10.1PING10.10.10.1(10.10.10.1)56(84)字节数据。64字节来自10.10.10.1:icmp_seq=1ttl=64time=0.050ms---10.10.10.1pingstatistics---1packetstransmitted,1received,0%packetloss,time0msrttmin/avg/max/mdev=0.050/0.050/0.050/0.000msadmin@ubuntu:~$#查看邻居,是我们网关的地址veth0admin@ubuntu:~$sudoipnetnsexecmacipneigh10.10.10.1deveth0lladdr00:01:02:03:04:05REACHABLEadmin@ubuntu:~$实验二修改邻居表,将网关地址改为系统中另一台设备docker0的mac地址admin@ubuntu:~$iplinkshowdocker07:docker0:mtu1500qdiscnoqueue状态UP模式DEFAULT组默认链接/ether02:42:83:ca:a5:f3brdff:ff:ff:ff:ff:ffadmin@ubuntu:~$admin@ubuntu:~$sudoipnetnsexecmacipneigh替换10.10.10.1lladdr02:42:83:ca:a5:f3deveth0admin@ubuntu:~$sudoipnetnsexecmacipneigh10.10.10.1deveth0lladdr02:42:83:ca:a5:f3PERMANENTadmin@ubuntu:~$#继续ping网关,但是ping不通admin@ubuntu:~$sudoipnetnsexecmacping10.10.10.1-c1PING10.10.10.1(10.10.10.1)56(84)bytesofdata.---10.10.10.1pingstatistics---1packetstransmitted,0received,100%packetloss,time0msadmin@ubuntu:~$#onport可以看到目标mac是02:42:83:ca:a5:f3admin@ubuntu:~$sudotcpdump-iveth1-eevvnntcpdump:listeningonveth1,link-typeEN10MB(Ethernet),capturesize262144bytes03:57:23.746932aa:1b:28:83:ee:b5>02:42:83:ca:a5:f3,ethertypeIPv4(0x0800),长度98:(tos0x0,ttl64,id7402,offset0,flags[东风],protoICMP(1),length84)10.10.10.2>10.10.10.1:ICMPechorequest,id10034,seq12,length643packetscaptured3packetsreceivedbyfilter0packetsdroppedbykerneladmin@ubuntu:~$experiment3onwrongmac下的地址,pingdocker0上的IP:172.17.0.1,即发送的报文是docker0的IP地址和mac地址#可以看到无法ping通admin@ubuntu:~$sudoipnetnsexecmacping172.17.0.1-c1PING172.17.0.1(172.17.0.1)56(84)bytesofdata.---172.17.0.1pingstatistics---1packetstransmitted,0received,100%packetloss,time0msadmin@ubuntu:~$#报告如我们所料admin@ubuntu:~$sudotcpdump-iveth1-eevvnntcpdump:侦听veth1,链接类型EN10MB(以太网),捕获大小262144bytes04:01:39.957123aa:1b:28:83:ee:b5>02:42:83:ca:a5:f3,ethertypeIPv4(0x0800),长度98:(tos0x0,ttl64,id65477,offset0,flags[DF],protoICMP(1),length84)10.10.10.2>172.17.0.1:ICMPechorequest,id10113,seq1,length64结论当网卡处于混杂模式时,网卡可以收到目的MAC地址不是本地的数据包,数据包只会被在链路层处理,不会传送到网络层。即使对应的mac地址是系统中另一块网卡的mac地址。查看代码,我们以Intel的igb网卡为例进行分析。网卡的驱动程序代码中有以下函数:/***igb_process_skb_fields-从Rx描述符填充skb头字段*@rx_ring:rx描述符环数据包正在处理*@rx_desc:指向EOPRx描述符的指针*@skb:指向正在填充的当前skb的指针**此函数按顺序检查环、描述符和数据包信息,以填充哈希、校验和、VLAN、时间戳、协议和*skb中的其他字段。**/staticvoidigb_process_skb_fields(structigb_ring*rx_ring,unione1000_adv_rx_desc*rx_desc,structsk_buff*skb){structnet_device*dev=rx_ring->netdev;igb_rx_hash(rx_ring,rx_desc,skb);igb_rx_checksum(rx_ring,rx_desc,skb);如果(igb_test_staterr(rx_desc,E1000_RXDADV_STAT_TS)&&!igb_test_staterr(rx_desc,E1000_RXDADV_STAT_TSIP))igb_ptp_rx_rgtstamp(rx_ring->q_vector-Wif_dev(IF_skb);_VLAN_CTAG_RX)&&igb_test_staterr(rx_desc,E1000_RXD_STAT_VP)){u16vid;如果(igb_test_staterr(rx_desc,E1000_RXDEXT_STATERR_LB)&&test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP,&rx_ring->flags))vid=be16_to_cpu(rx_desc->wb.upper.vlan);elsevid=le16_to_cpu(rx_desc->wb.upper.vlan);__vlan_hwaccel_put_tag(skb,htons(ETH_P_8021Q),vid);}skb_record_rx_queue(skb,rx_ring->queue_index);//调用eth_type_trans任数确定网络协议类型skb->protocol=eth_type_trans(skb,rx_ring->netdev);}/***eth_type_trans-确定数据包的协议ID。*@skb:接收套接字数据*@dev:接收网络设备**这里的规则是,如果类型字段短到足以成为一个长度,我们*假设802.3。*这是正常做法,适用于任何“正在使用”的协议。*/__be16eth_type_trans(structsk_buff*skb,structnet_device*dev){unsignedshort_服务访问点;constunsignedshort*sap;构造结构ethhdr*eth;skb->dev=dev;skb_reset_mac_header(skb);eth=(structethhdr*)skb->data;skb_pull_inline(skb,ETH_HLEN);广播的类型,多播,单播否则skb->pkt_type=PACKET_MULTICAST;}//单播报文,比较是否与设备mac地址一致,不一致则设置skb->pkt_type=PACKET_OTHERHOST;elseif(unlikely(!ether_addr_equal_64bits(eth->h_dest,dev->dev_addr)))skb->pkt_type=PACKET_OTHERHOST;......}EXPORT_SYMBOL(eth_type_trans);从上面的代码可以看出,对于目的MAC不是本地的单播包,会设置skb->pkt_type=PACKET_OTHERHOST让我们继续看看网络层是如何处理这个字段的:/**MainIPReceive例程。*/intip_rcv(structsk_buff*skb,structnet_device*dev,structpacket_type*pt,structnet_device*orig_dev){conststructiphdr*iph;结构网络*网络;u32长度;/*当接口混杂时。模式,丢弃它收到的所有废话*,不要试图分析它。*对于skb->pkt_type==PACKET_OTHERHOST(目标MAC不是本机)的消息,直接在NF_INET_PRE_ROUTING节点之前丢弃*。*/if(skb->pkt_type==PACKET_OTHERHOST)gotodrop;......returnNF_HOOK(NFPROTO_IPV4,NF_INET_PRE_ROUTING,net,NULL,skb,dev,NULL,ip_rcv_finish);csum_error:__IP_INC_STATS(net,IPSTATS_MIB_CSUMERRORS);inhdr_error:__IP_INC_STATS(net,IPSTATS_MIB_INHDRERRORS);drop:kfree_skb(skb);out:returnNET_RX_DROP;}