Intel网卡的vlan receive filtering特性以及linux内核的netif_f_hw_vlan_ctag_filter接口

December 01, 2018 | 1 Minute Read

vlan-filter # ethtool -k eth0 | grep rx-vlan-filter rx-vlan-filter: on [fixed] # ethtool -k eth0 | grep rx-all rx-all: off # ethtool -k eth0 | grep cha vlan-challenged: off [fixed] vlan-challenged为on表示网卡不支持vlan 硬件寄存器里面的 E1000_RCTL_VFE 标志位控制 进入 IFF_PROMISC 模式或者 rx-all: off 模式,驱动都会自动禁用vlan-filter,但 rx-all还会接受损坏的包 /* According to definition of SI mode, iface in promisc mode * should receive matched and unmatched (in resolution of port) * unicast packets. */ e1000 驱动 只有配置了至少一个 vlan 才会启用E1000_RCTL_VFE, 参考代码 e1000_vlan_filter_on_off e1000_vlan_rx_add_vid e1000e 实际测试默认好像E1000_RCTL_VFE就没开 igb (i210)实际测试默认会打开E1000_RCTL_VFE,不接受任何vlan ixgbe IXGBE_VLNCTRL_VFE vlan filter的配置应该是保存在 adapter->active_vlans 里面通过 for_each_set_bit_from(vid, adapter->active_vlans, VLAN_N_VID) 来设置 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) { u16 vid = 1; ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0); // 这个应该是清空所有vlan filter for_each_set_bit_from(vid, adapter->active_vlans, VLAN_N_VID) ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid); } /** * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set * @netdev: network interface device structure * * The set_rx_method entry point is called whenever the unicast/multicast * address list or the network interface flags are updated. This routine is * responsible for configuring the hardware for proper unicast, multicast and * promiscuous mode. **/ void ixgbe_set_rx_mode(struct net_device *netdev) e1000的硬件 e1000_82543 以后版本都支持 NETIF_F_HW_VLAN_CTAG_FILTER if (hw->mac_type >= e1000_82543) { netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_RX; netdev->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER; } 所有的 e1000e 82571 82572 82573 82574 82583 都支持 NETIF_F_HW_VLAN_CTAG_FILTER; e1000 /* disable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~E1000_RCTL_VFE; ew32(RCTL, rctl); e1000e /* disable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN); ew32(RCTL, rctl); bnx2x 如果不配置 vlan,默认好像也是acdept_any_vlan static const struct net_device_ops e1000e_netdev_ops = { .ndo_set_rx_mode = e1000e_set_rx_mode, /// 可以调用来设置 IFF_PROMISC, 会根据标志位启用还是禁用VLAN receive filtering .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, 添加一个vlan filter .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, 删除一个vlan filter 虚拟vlan 设备的实现 vlan_vid_add里面会这个ndo_vlan_rx_add_vid 根据 int register_netdevice(struct net_device *dev) 代码,只要驱动net_device支持 NETIF_F_HW_VLAN_CTAG_FILTER 都必须提供.ndo_vlan_rx_add_vid .ndo_vlan_rx_kill_vid 这两个接口的 查看各个网卡的规格文档说明 https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/i210-ethernet-controller-datasheet.pdf 7.1.1.2 VLAN Filtering 内核netdev_drivername 函数可以判断网络设备的驱动是不是igb