对于2.6的内核,net_device内部存在一个结构体指针,
struct dev_mc_list *dev->mc_list
通过对它的访问,可以循环获取所有的组播MAC地址。
但是,在新的内核中(至少在3.10中)发生了变化,取而代之的是
struct netdev_hw_addr_list mc;
我们可以通过直接对mc进行访问来获取相应的数据,也可以利用Linux内核提供的宏。
netdev_mc_count(dev)
这个宏可以获取当前一共存在多少个组播MAC地址,具体的宏定义见下:
#define netdev_mc_count(dev) netdev_hw_addr_list_count(&(dev)->mc)
netdev_for_each_mc_addr
提供了一个循环的方式来获取所有的组播MAC
具体的宏定义如下:
#define netdev_for_each_mc_addr(ha, dev)netdev_hw_addr_list_for_each(ha, &(dev)->mc)
ha是一个netdev_hw_addr
的结构体,内部有一个unsigned char addr[MAX_ADDR_LEN];
的数组用来存储MAC地址
下面是其中的一部分代码
struct netdev_hw_addr {
struct list_head list;
unsigned char addr[MAX_ADDR_LEN];
unsigned char type;
}
list_head是Linux在内核实现的一个双向链表,而netdev_hw_addr_list_for_each
就是对这样一个链表的访问。
我们可以具体的看一下netdev_hw_addr_list_for_each
#define netdev_hw_addr_list_for_each(ha, l) list_for_each_entry(ha, &(l)->list, list)
而list_for_each_entry
#define list_for_each_entry(pos, list, member) \
for (pos = list_head(list, typeof(*pos), member); \
&pos->member != (list); \
pos = list_next(pos, member))
所以说netdev_for_each_mc_addr
的本质就是一个for循环。