Linux VLAN知识总结(5)

2019-09-01 15:40

3.2 register_pernet_subsys [net\\8021q\\vlan.c]

register_pernet_subsys函数调用关系:

register_pernet_subsys()->register_pernet_operations()->ida_get_new_above() 而ida_get_new_above的作用如它注释所描述的。分配一个新的ID大于等于一个起始ID

ida_get_new_above():ida_get_new_above - allocate new ID above or equal to a start id。

另外register_pernet_operations()中通过调用 __register_pernet_operations函数,再通过调用ops_init(ops, &init_net),调用会调用子空间的初始化函数vlan_init_net(),而vlan_init_net()的作用就是有关vlan的proc文件系统信息。

即register_pernet_operations()的调用关系如下: register_pernet_operations()->__register_pernet_operations()->ops_init()->vlan_init_net() 3.3 register_netdevice_notifier [/net/core/dev.c]

当使用SIOCBRADDBR调用ioctl时,会通过br_add_bridge函数创建新的网桥。在这 err = register_netdevice_notifier(&vlan_notifier_block); static struct notifier_block vlan_notifier_block __read_mostly = { .notifier_call = vlan_device_event, };

参考http://blog.csdn.net/qy532846454/article/details/6529166,分析的很详细

3.4 dev_add_pack [/net/core/dev.c]

void dev_add_pack(struct packet_type *pt) {

struct list_head *head = ptype_head(pt); spin_lock(&ptype_lock); list_add_rcu(&pt->list, head); spin_unlock(&ptype_lock); }

static struct packet_type vlan_packet_type __read_mostly = { .type = cpu_to_be16(ETH_P_8021Q),

.func = vlan_skb_recv, /* VLAN receive method */ };

参考http://blog.csdn.net/qy532846454/article/details/6529166,里面相关部分很详细

3.5 vlan_skb_recv [/net/core/dev.c]

int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) {

struct vlan_hdr *vhdr;

struct vlan_pcpu_stats *rx_stats; struct net_device *vlan_dev; u16 vlan_id; u16 vlan_tci;

skb = skb_share_check(skb, GFP_ATOMIC); //检查skb是否被多个协议模块引用 if (skb == NULL) goto err_free;

if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) goto err_free;

vhdr = (struct vlan_hdr *)skb->data; vlan_tci = ntohs(vhdr->h_vlan_TCI); vlan_id = vlan_tci & VLAN_VID_MASK;

rcu_read_lock();

vlan_dev = vlan_find_dev(dev, vlan_id);

/* If the VLAN device is defined, we use it.

if (!vlan_dev) { if (vlan_id) {

pr_debug(\ __func__, vlan_id, dev->name); goto err_unlock; }

rx_stats = NULL; } else {

skb->dev = vlan_dev; //设置skb->dev为虚拟vlan设备

rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats);

u64_stats_update_begin(&rx_stats->syncp); //更新网卡接收报文的信息 rx_stats->rx_packets++; rx_stats->rx_bytes += skb->len;

skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);

pr_debug(\ __func__, skb->priority, vlan_tci);

switch (skb->pkt_type) { case PACKET_BROADCAST:

* If not, and the VID is 0, it is a 802.1p packet (not * really a VLAN), so we will just netif_rx it later to the * original interface, but with the skb->proto set to the * wrapped proto: we do nothing here. */

/* Yeah, stats collect these together.. */ /* stats->broadcast ++; // no such counter :-( */ break;

case PACKET_MULTICAST: rx_stats->rx_multicast++; break;

case PACKET_OTHERHOST:

/* Our lower layer thinks this is not local, let's make

* sure.

* This allows the VLAN to have a different MAC than the * underlying device, and still route correctly. */

if (!compare_ether_addr(eth_hdr(skb)->h_dest, skb->dev->dev_addr)) skb->pkt_type = PACKET_HOST; break; default: break; }

u64_stats_update_end(&rx_stats->syncp); }

skb_pull_rcsum(skb, VLAN_HLEN); //偏移过vlan标签

vlan_set_encap_proto(skb, vhdr); //重置skb->protocol为vlan标签后面接的协议类型,之前的protocol为0x8100(即ETH_P_8021Q)

if (vlan_dev) {

skb = vlan_check_reorder_header(skb); if (!skb) {

rx_stats->rx_errors++;

goto err_unlock; } }

netif_rx(skb); //将skb重新放入接收队列中,让skb在协议栈中继续向上走

rcu_read_unlock(); return NET_RX_SUCCESS;

err_unlock:

rcu_read_unlock(); err_free:

atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; }

3.5 vlan_ioctl_set [ /net/socket.c]

void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) {

mutex_lock(&vlan_ioctl_mutex); vlan_ioctl_hook = hook;

mutex_unlock(&vlan_ioctl_mutex); }


Linux VLAN知识总结(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:西南交通大学2016年全日制硕士研究生招生复试及拟录取工作实施细

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: