本文共 1592 字,大约阅读时间需要 5 分钟。
veth pari是用于不同nerwork namespace间进行通信的方式。其代码在driver/net/veth.c中其入口函数如下:可以看出这是以模块的形参存在中的static __init int veth_init(void){ return rtnl_link_register(&veth_link_ops);}module_init(veth_init);module_exit(veth_exit);MODULE_DESCRIPTION("Virtual Ethernet Tunnel");从veth_link_ops 的veth_newlink 中可以看到veth 是将两个device绑定在一起static struct rtnl_link_ops veth_link_ops = { .kind = DRV_NAME, .priv_size = sizeof(struct veth_priv), .setup = veth_setup, .validate = veth_validate, .newlink = veth_newlink, .dellink = veth_dellink, .policy = veth_policy, .maxtype = VETH_INFO_MAX, .get_link_net = veth_get_link_net,};static int veth_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack){ /* * tie the deviced together */ priv = netdev_priv(dev); rcu_assign_pointer(priv->peer, peer); priv = netdev_priv(peer); rcu_assign_pointer(priv->peer, dev); return 0;}再看一下最重要的发送函数static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev){ struct veth_priv *priv = netdev_priv(dev); struct net_device *rcv; int length = skb->len; rcu_read_lock();#得到要发送的net_device rcv rcv = rcu_dereference(priv->peer); if (unlikely(!rcv)) { kfree_skb(skb); goto drop; }#通过dev_forward_skb将skb数据发送到rcv中 if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {#发送成功后更新统计信息 struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats); u64_stats_update_begin(&stats->syncp); stats->bytes += length; stats->packets++; u64_stats_update_end(&stats->syncp); } else {drop: atomic64_inc(&priv->dropped); } rcu_read_unlock(); return NETDEV_TX_OK;}
转载地址:http://dsnmi.baihongyu.com/