//使用veth //1.创建两块虚拟网卡veth1、veth2,然后点对点连接,此后两块网卡的数据会互相发送到对方 $ ip link add veth1 type veth peer name veth2 //2.创建网络命名空间t1 $ ip netns add t1 //3.将veth0加入t1,此时veth0便看不到了,因为被加入到其他命名空间中了 $ ip link set veth0 netns t1 //4.配置veth0的ip地址 $ ip netns exec t1 ifconfig eth0 192.168.1.200/24 //5.设置t1网络的默认路由 $ ip netns exec t1 route add default gw 192.168.1.1 //6.此时将veth2加入本地网桥中,便可以实现veth1在t1中访问外部网络了,过程略,可参考docker中的网络配置步骤 //veth的实现方法(drivers/net/veth.c) //向ip link注册服务 1.1 static __init int veth_init(void) { return rtnl_link_register(&veth_link_ops); } //处理ip link命令 2.1 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, }; //新加入一条veth链接 2.2 static int veth_newlink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { int err; struct net_device *peer; struct veth_priv *priv; char ifname[IFNAMSIZ]; struct nlattr *peer_tb[IFLA_MAX + 1], **tbp; //首先创建并注册peer if (data != NULL && data[VETH_INFO_PEER] != NULL) { struct nlattr *nla_peer; //解析命令行参数 nla_peer = data[VETH_INFO_PEER]; err = nla_parse(peer_tb, IFLA_MAX, nla_data(nla_peer) + sizeof(struct ifinfomsg), nla_len(nla_peer) - sizeof(struct ifinfomsg), ifla_policy); ... } else tbp = tb; //初始化peer ... //注册peer err = register_netdevice(peer); if (err < 0) goto err_register_peer; //初始化peer的对等端 ... //注册peer的对等端 err = register_netdevice(dev); if (err < 0) goto err_register_dev; //互相将peer保存到private中,在xmit的时候使用 priv = netdev_priv(dev); priv->peer = peer; priv = netdev_priv(peer); priv->peer = dev; return 0; err_register_dev: err_alloc_name: unregister_netdevice(peer); return err; err_register_peer: free_netdev(peer); return err; } //初始化veth设备 2.3 static void veth_setup(struct net_device *dev) { //以太网设备的通用初始化 ether_setup(dev); //veth的操作列表 dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; dev->destructor = veth_dev_free; } //通过veth发送skb 2.4 static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device *rcv = NULL; struct veth_priv *priv, *rcv_priv; struct veth_net_stats *stats, *rcv_stats; int length, cpu; //获取对等端 priv = netdev_priv(dev); rcv = priv->peer; rcv_priv = netdev_priv(rcv); ... //设置skb的设备为对等端 skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, rcv); if (dev->features & NETIF_F_NO_CSUM) skb->ip_summed = rcv_priv->ip_summed; ... //将skb放入到对等端的接收队列中,从此完成了skb向对等端的发送 netif_rx(skb); return NETDEV_TX_OK; tx_drop: kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; rx_drop: kfree_skb(skb); rcv_stats->rx_dropped++; return NETDEV_TX_OK; }
网络子系统87_veth实现
时间: 2024-11-04 10:21:13