0

Linux カーネルの vxlan ドライバー コードを理解しようとしています。カーネルのバージョン: 3.16.0-29-generic

これを見るとvxlan.c、VNI ごとに vxlan dev が作成され、netdevice が属する netns に関連付けられており、dev ごとに udp ソケットが作成されているように見えます。

ethxただし、物理デバイスは vxlan デバイスと同じ netns に属している必要があるため、グローバル netns を除いて、vxlan デバイスを物理デバイス ( ) に実際に接続することはできないため、これには少し困惑しています。

例: グローバル netns に vxlan リンクを作成すると、期待どおりに動作します。

ip link add vxlan0 type vxlan id 10 dev eth0
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 10.10.100.51/24 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:22:4d:99:32:6b brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.25/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::222:4dff:fe99:326b/64 scope link 
       valid_lft forever preferred_lft forever
15: vxlan0: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN group default 
    link/ether fe:9c:49:26:ba:63 brd ff:ff:ff:ff:ff:ff

ネットワーク名前空間で同じことをしようとしても、うまくいきません:

ip netns exec test0 ip link add vxlan1 type vxlan id 20 dev eth0
ip netns exec test0 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

ここでの問題は、追加されるリンクと同じ netns に eth0 があるかどうかをコードがチェックするため、「dev eth0」が気に入らないことです。

eth0 なしで同じデバイスを作成すると、正常に動作します。

ip netns exec test0 ip link add vxlan1 type vxlan id 20 
ip netns exec test0 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: vxlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 46:7a:5b:87:7d:2f brd ff:ff:ff:ff:ff:ff

キャリアを vxlan デバイスに接続できない場合、どうすればホストの外部との間で本当に tx/rx パケットを送受信できますか?

現実的には、グローバル netns でのみ vxlan ドライバーを使用できるということですか、それともブリッジで使用する必要があるということですか?

vxlan パケットには VNI が関連付けられています。これを使用して、実際に macvlans で可能なことと同様に、非グローバル netns の dev にパケットを直接送信できるはずです。

何か不足していますか?

4

3 に答える 3

1

Thomas Richter による Software Defined Networking using VXLAN (LinuxCon 2013 で発表) を見ることができると思います。

グローバル netns にないデバイスの電源をオンにしl2missて、ARP および FDB エントリを手動で設定できます。l3missvxlan

次の例は、これを実現する方法を示しています。

function setup_overlay() {
    docker run -d --net=none --name=test-overlay ubuntu sleep 321339
    sleep 3
    pid=`docker inspect -f '{{.State.Pid}}' test-overlay`
    ip netns add overlay
    ip netns exec overlay ip li ad dev br0 type bridge
    ip li add dev vxlan212 type vxlan id 42 l2miss l3miss proxy learning dstport 4789
    ip link set vxlan212 netns overlay
    ip netns exec overlay ip li set dev vxlan212 name vxlan1
    ip netns exec overlay brctl addif br0 vxlan1
    ip li add dev vetha1 mtu 1450 type veth peer name vetha2 mtu 1450
    ip li set dev vetha1 netns overlay
    ip netns exec overlay ip -d li set dev vetha1 name veth2
    ip netns exec overlay brctl addif br0 veth2
    ip netns exec overlay ip ad add dev br0 $bridge_gatway_cidr
    ip netns exec overlay ip li set vxlan1 up
    ip netns exec overlay ip li set veth2 up
    ip netns exec overlay ip li set br0 up
    ln -sfn /proc/$pid/ns/net /var/run/netns/$pid
    ip li set dev vetha2 netns $pid
    ip netns exec $pid ip li set dev vetha2 name eth1 address $container1_mac_addr
    ip netns exec $pid ip ad add dev eth1 $container1_ip_cidr
    ip netns exec $pid ip li set dev eth1 up

    ip netns exec overlay ip neighbor add $container2_ip lladdr $container2_mac_addr dev vxlan1 nud permanent
    ip netns exec overlay bridge fdb add $container2_mac_addr dev vxlan1 self dst $container2_host_ip vni 42 port 4789
}

# setup overlay on host1
bridge_gatway_cidr='10.0.0.1/24'
container1_ip_cidr='10.0.0.2/24'
container1_mac_addr='02:42:0a:00:00:02'
container2_ip='10.0.0.3'
container2_mac_addr='02:42:0a:00:00:03'
container2_host_ip='192.168.10.22'
setup_overlay

# setup overlay on host2
bridge_gatway_cidr='10.0.0.1/24'
container1_ip_cidr='10.0.0.3/24'
container1_mac_addr='02:42:0a:00:00:03'
container2_ip='10.0.0.2'
container2_mac_addr='02:42:0a:00:00:02'
container2_host_ip='192.168.10.21'
setup_overlay

上記のスクリプトは、2 つのホスト上の 2 つの Docker コンテナー間にオーバーレイ ネットワークをセットアップします。Vxlan デバイスは netns でブリッジに接続し、veth デバイスのペアでコンテナー netns にbr0接続します。overlaybr0

新しく設定したオーバーレイ ネットワークを確認します。

# ping container2 on host1
ip netns exec $pid ping -c 10 10.0.0.3
## successful output
root@docker-1:/home/vagrant# ip netns exec $pid ping -c 10 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.879 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.558 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.576 ms
64 bytes from 10.0.0.3: icmp_seq=4 ttl=64 time=0.614 ms
64 bytes from 10.0.0.3: icmp_seq=5 ttl=64 time=0.521 ms
64 bytes from 10.0.0.3: icmp_seq=6 ttl=64 time=0.389 ms
64 bytes from 10.0.0.3: icmp_seq=7 ttl=64 time=0.551 ms
64 bytes from 10.0.0.3: icmp_seq=8 ttl=64 time=0.565 ms
64 bytes from 10.0.0.3: icmp_seq=9 ttl=64 time=0.488 ms
64 bytes from 10.0.0.3: icmp_seq=10 ttl=64 time=0.531 ms

--- 10.0.0.3 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9008ms
rtt min/avg/max/mdev = 0.389/0.567/0.879/0.119 ms

## tcpdump sample on host1
root@docker-1:/home/vagrant# tcpdump -vv -n -s 0 -e -i eth1
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
12:09:35.589244 08:00:27:00:4a:3a > 08:00:27:82:e5:ca, ethertype IPv4 (0x0800), length 148: (tos 0x0, ttl 64, id 59751, offset 0, flags [none], proto UDP (17), length 134)
    192.168.0.11.42791 > 192.168.0.12.4789: [no cksum] VXLAN, flags [I] (0x08), vni 42
02:42:0a:00:00:02 > 02:42:0a:00:00:03, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 49924, offset 0, flags [DF], proto ICMP (1), length 84)
    10.0.0.2 > 10.0.0.3: ICMP echo request, id 1908, seq 129, length 64
12:09:35.589559 08:00:27:82:e5:ca > 08:00:27:00:4a:3a, ethertype IPv4 (0x0800), length 148: (tos 0x0, ttl 64, id 38389, offset 0, flags [none], proto UDP (17), length 134)
    192.168.0.12.56727 > 192.168.0.11.4789: [no cksum] VXLAN, flags [I] (0x08), vni 42
02:42:0a:00:00:03 > 02:42:0a:00:00:02, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 19444, offset 0, flags [none], proto ICMP (1), length 84)
    10.0.0.3 > 10.0.0.2: ICMP echo reply, id 1908, seq 129, length 64
12:09:36.590840 08:00:27:00:4a:3a > 08:00:27:82:e5:ca, ethertype IPv4 (0x0800), length 148: (tos 0x0, ttl 64, id 59879, offset 0, flags [none], proto UDP (17), length 134)
    192.168.0.11.42791 > 192.168.0.12.4789: [no cksum] VXLAN, flags [I] (0x08), vni 42
02:42:0a:00:00:02 > 02:42:0a:00:00:03, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 49951, offset 0, flags [DF], proto ICMP (1), length 84)
    10.0.0.2 > 10.0.0.3: ICMP echo request, id 1908, seq 130, length 64
12:09:36.591328 08:00:27:82:e5:ca > 08:00:27:00:4a:3a, ethertype IPv4 (0x0800), length 148: (tos 0x0, ttl 64, id 38437, offset 0, flags [none], proto UDP (17), length 134)
    192.168.0.12.56727 > 192.168.0.11.4789: [no cksum] VXLAN, flags [I] (0x08), vni 42
02:42:0a:00:00:03 > 02:42:0a:00:00:02, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 19687, offset 0, flags [none], proto ICMP (1), length 84)
    10.0.0.3 > 10.0.0.2: ICMP echo reply, id 1908, seq 130, length 64

各ホストでのクリーンアップ

ip netns del overlay
ip netns del $pid
docker rm -v -f test-overlay

vxlan デバイスが非グローバル netns で受信機なしで動作する理由を説明するには:

最初に vxlan デバイスをグローバル netns に作成し、それを netns に移動することに注意してoverlayください。vxlan デバイスの作成時に、カーネルの vxlan ドライバーが src netns への参照を保持するため、これは実際に必要です。の次のコードを参照してくださいdrivers/net/vxlan.c

static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
     
        struct vxlan_config *conf)
     {
    //...
    vxlan->net = src_net;
    
    //...
}

vxlan ドライバーは、src netns に udp ソケットを作成します。

vxlan_sock_add(vxlan->net, vxlan->cfg.dst_port, vxlan->cfg.no_share, vxlan->flags);

于 2015-11-06T06:55:48.487 に答える
0

カーネル 4.3 には、単一の VXLAN netdev を使用し、ルーティング ルールを使用してトンネル情報を追加する、VXLAN を操作する新しい方法を追加するパッチがあります。

パッチによると、次のようなトンネル情報を参照するルーティング ルールを作成できます。

ip rule add from all tunnel-id 100 lookup 100
ip rule add from all tunnel-id 200 lookup 200

そして、次のようなルールでカプセル化ヘッダーを追加します。

ip route add 40.1.1.1/32 encap vxlan id 10 dst 50.1.1.2 dev vxlan0
于 2015-10-21T12:12:14.183 に答える
0

物理デバイスを非グローバル netns に追加できることが判明しました。したがって、質問は無意味です。グローバル netns 内の 1 つの vxlan デバイスが、macvlans tho の場合と同様に、VNI に基づいて適切な netns にパケットを送信するのを見たいと思います。

于 2015-02-05T09:16:05.700 に答える