web-dev-qa-db-ja.com

Linuxのタグなしインターフェース?

タグ付きパケットを送受信するeth1.10のようなvconfigを使用してLinuxでタグ付きインターフェイスを作成する方法を知っています。 VLAN 10のタグなしパケットを送受信するインターフェイスを作成することは可能ですか?

5
user1762571

タグ付けされていないインターフェースがすでに存在します:これは親インターフェースです。つまり、この場合はeth1です。

eth1.10を介してパケットを送信すると、これらのパケットにタグが付けられますが、VLANタグ10で受信されたパケットは、そのインターフェースを介して受信されます。

eth1を介してパケットを送信すると、VLANタグなしで受信されたパケットがそのインターフェイスを介して受信されますが、タグ付けされていないパケットになります。

「vlan 10のタグなしパケットの送信」などはありません。タグなしパケットには、定義上、VLANタグがありません。

4
Celada

この:

# ip link add link eth0 name untagged type vlan id 0

トリックを行うようです。

親インターフェース(eth0)のtcpdumpは、-I untagged(some-ip)をpingすると、タグなしのパケットを表示します。

(新しい論理インターフェイスのtcpdumpはタグなしのトラフィックのみを表示する必要がありますが、親インターフェイスのtcpdumpはタグ付きとタグなしのすべてのトラフィックを、タグ付きのものの802.1qヘッダーとともに表示する必要があります。)

タグ付けされていないARP応答が親インターフェースに関連するARPテーブルに配置されないように、親インターフェースでARPを無効にする必要がある場合があります。

# ip link set eth0 arp off
# ip link set untagged arp on

また、十分な対策として、親インターフェースでIPv6リンクローカルアドレスを無効にし、タグなし論理インターフェースで有効にします。

親インターフェース全体(タグ付きトラフィックを含む)などを殺すことなく、タグなしインターフェースをアップ/ダウンできます。

3
user216484

次の方法が機能することがわかりました。

  • TCを使用してIngresで802.1qなしのパケットを照合し、ID 0のVLANヘッダーをプッシュする
  • TCを使用して、出力のVLAN 0のパケットを照合し、VLANヘッダーをポップする
  • Type = vlanおよびid = 0でタグなしの論理インターフェースを作成します

次に例を示します。

$ tc qdisc del dev eth0 root
$ tc qdisc add dev eth0 handle 1: root prio
$ tc filter add dev eth0 parent 1: protocol 802.1q basic match 'meta(vlan eq 0)' action vlan pop

$ tc qdisc del dev eth0 ingress
$ tc qdisc add dev eth0 handle ffff: ingress
$ tc filter add dev eth0 parent ffff: protocol all basic match 'not meta(protocol eq 0x8100)' action vlan Push id 0

$ ip link add eth0-vlan0 type vlan id 0
$ ip link set eth0-vlan0 up
$ ip addr add 192.168.10.253/24 dev eth0-vlan0

peer$ ping 192.168.10.253
PING 192.168.10.253 (192.168.10.253) 56(84) bytes of data.
64 bytes from 192.168.10.253: icmp_seq=1 ttl=64 time=0.209 ms
64 bytes from 192.168.10.253: icmp_seq=2 ttl=64 time=0.188 ms
^C

出力(上記の「ルート」として知られている)にprio qdiscを追加すると、デフォルトのmq規律が無効になり、複数のCPUスレッドがパケットをプッシュできるように、NICの送信キューの数に従ってパケットが分割されることに注意してください。別のTXキューに。デフォルトの動作に戻すには、次のようにmqprioを使用します。

$ tx_q_count=$(ls -d /sys/class/net/eth0/queues/tx-* | wc -l)

$ tc qdisc del dev eth0 root
$ tc qdisc add dev eth0 handle 1: root prio bands $tx_q_count multiqueue
$ tc filter add dev eth0 parent 1: protocol 802.1q basic match 'meta(vlan eq 0)' action vlan pop
$ for i in $(seq 1 $tx_q_count); do tc qdisc add dev eth0 parent 1:$i pfifo_fast; done

$ tc qdisc del dev eth0 ingress
$ tc qdisc add dev eth0 handle ffff: ingress
$ tc filter add dev eth0 parent ffff: protocol all basic match 'not meta(protocol eq 0x8100)' action vlan Push id 0

$ ip link add eth0-vlan0 type vlan id 0
$ ip link set eth0-vlan0 up
$ ip addr add 192.168.10.253/24 dev eth0-vlan0

peer$ ping 192.168.10.253
PING 192.168.10.253 (192.168.10.253) 56(84) bytes of data.
64 bytes from 192.168.10.253: icmp_seq=1 ttl=64 time=0.230 ms
64 bytes from 192.168.10.253: icmp_seq=2 ttl=64 time=0.198 ms
^C

同様に機能する別のソリューションは、物理インターフェースのVLAN論理インターフェースの横にソフトウェアブリッジを追加することです。ソフトウェアブリッジには、使用可能な限られたvlanリマッピング(Ingresではpvid-> vidおよびegressではvid-> pvidですが、完全なリマッピングではありません)を許可するvlanフィルタリング機能があります。次に例を示します。

$ ip link add eth0-vlan0 type bridge
$ echo 0 > /sys/class/net/eth0-vlan0/bridge/default_pvid
$ echo 1 > /sys/class/net/eth0-vlan0/bridge/vlan_filtering
$ ip link set dev eth0 master eth0-vlan0
$ bridge vlan add vid 4094 dev eth0 pvid untagged
$ bridge vlan add vid 4094 dev eth0-vlan0 untagged pvid self

$ ip link add eth0-vlan4094 link eth0 type vlan id 4094
# ... BEGIN: only if you intend to use vlan 4094 ...
$ ip link set eth0-vlan4094 up
$ ip addr add 10.10.40.253/24 dev eth0-vlan4094
# ... END ...

$ ip link set eth0-vlan0 up
$ ip addr add 192.168.10.253/24 dev eth0-vlan0

peer$ ping 192.168.10.253
PING 192.168.10.253 (192.168.10.253) 56(84) bytes of data.
64 bytes from 192.168.10.253: icmp_seq=1 ttl=64 time=0.238 ms
64 bytes from 192.168.10.253: icmp_seq=2 ttl=64 time=0.215 ms
^C

VLANフィルタリング機能は少しまあまあなので、ブリッジ内で使用されるVID番号と一致するVLANインターフェイスが必要です。 pvid-> vidマッピングを使用して両方のタグなしフレームを受け入れますが、再マッピングされたvidと一致するワイヤ上のVLANタグが付いたフレームも受け入れます。 VLANインターフェースは、代わりにそれらのフレームを使い果たします。特定のVLANが必要ない場合は、ダウン状態のままにします。

ソフトウェアブリッジは最近、「default_pvid」機能を取得しました。これにより、安価なハードウェアスイッチのように機能します。これはVLANを認識しますが、デフォルトで、vid 1へのpvid-> vidマッピングを実行し、すべてのポートでvid 1を許可します。単一の構成ディレクティブを使用せずに、スイッチを接続してタグなしトラフィック用のポートの使用を開始できます。

最後に、より現代的なソリューションは、tc_clsactを使用して、PVIDのタグをプッシュ/ポップする小さなBPFプログラムを作成することです。一部のNICがBPFプログラムのハードウェアオフロードを許可することを除いて、上記のTCの例と同様に機能するため、パフォーマンスが向上します。

2
banankage

これがeBPFを使用したソリューションです。

Bccをインストールしてソースからコードをコンパイルする必要がないように、バイナリは次のとおりです。

$ base64 -d > tag-native-vlan0.o
f0VMRgIBAQAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAALABAAAAAAAAAAAAAEAAAAAA
AEAABwABAGESFAAAAAAAVQIDAAAAAAC3AgAAAIEAALcDAAAAAAAAhQAAABIAAAC3AAAAAAAAAJUA
AAAAAAAAYRIUAAAAAAAVAgMAAAAAAGESGAAAAAAAVQIBAAAAAACFAAAAEwAAALcAAAAAAAAAlQAA
AAAAAABHUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4AAAAAAAMAKAAAAAAAAAAAAAAA
AAAAAFcAAAAAAAQAKAAAAAAAAAAAAAAAAAAAAD0AAAAQAAUAAAAAAAAAAAAAAAAAAAAAACMAAAAQ
AAQAAAAAAAAAAAAAAAAAAAAAAAcAAAAQAAMAAAAAAAAAAAAAAAAAAAAAAAAudGV4dABjbHNhY3Rf
aW5ncmVzcwBwdmlkX2luZ3Jlc3MAY2xzYWN0X2VncmVzcwBwdmlkX2VncmVzcwBfX2xpY2Vuc2UA
LnN0cnRhYgAuc3ltdGFiAExCQjFfMwBMQkIwXzIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcAAAADAAAAAAAAAAAAAAAA
AAAAAAAAAEgBAAAAAAAAZQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAYA
AAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAFgAA
AAEAAAAGAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAA
AAAAADEAAAABAAAABgAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAgAAAAA
AAAAAAAAAAAAAAA/AAAAAQAAAAMAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAQAAAAAAAAAAAAAAAAA
AAABAAAAAAAAAAAAAAAAAAAATwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAuAAAAAAAAACQAAAAAAAA
AAEAAAADAAAACAAAAAAAAAAYAAAAAAAAAA==
^D

特に理由なく、PVIDをVID 10ではなくVID 0にマップするように設定しました。

(VID 10に変更するには、.oファイルで逆アセンブラーとアセンブラー(例:ubpfまたはllvm-objdump)を使用し、VLANタグを変更します。ユーザー空間からeBPFと通信するため、必要に応じて実行時にpvidを再構成可能にすることができます。)

カーネル4.8.0(uname -a)およびiproute2 4.9.0(ip -V)。

EBPFを物理インターフェイスに追加します。

$ tc qdisc add dev eth0 clsact
$ tc filter add dev eth0 ingress bpf object-file tag-native-vlan0.o section pvid_ingress
$ tc filter add dev eth0 egress bpf object-file tag-native-vlan0.o section pvid_egress

論理インターフェイスを作成します。

$ ip link add eth0-vlan0 link eth0 type vlan id 0
$ ip link set eth0-vlan0 up
$ ip addr add 192.168.10.253/24 dev eth0-vlan0

L3は論理インターフェイスで設定され、物理インターフェイスはL2に使用されます。

接続されたボックスからテストする:

peer$ ping 192.168.10.253
PING 192.168.10.253 (192.168.10.253) 56(84) bytes of data.
64 bytes from 192.168.10.253: icmp_seq=1 ttl=64 time=0.380 ms
64 bytes from 192.168.10.253: icmp_seq=2 ttl=64 time=0.240 ms
^C

「Linuxのタグなしインターフェース」があります。

1
banankage

コメントと別の回答で述べたように、タグのないパケットはタグがないため、どのVLANが属するかを説明する方法がないため、特定のVLANに属するタグなしのパケットを送信する方法は特にありません。先にも述べたように、親インターフェース(ここではeth1)はタグなしパケットを送信します。

ただし、これは、Linuxボックスから送信されたタグなしパケットがネットワーク上の特定のVLANに属していないことを意味するものではありません。特定のVLANに特定のポートに到着するタグなしパケットを割り当てるのはスイッチの役割です。通常、スイッチ(VLANに対応)は、デフォルトでタグなしパケットを「デフォルトVLAN(1)」に割り当てます。ただし、スイッチの構成を変更することで、受信したタグなしパケットをVLAN 10に配置し、他のVLAN 10が割り当てられている場所にルーティングするように指示できます。

VLAN 10が別のポートでタグ付きに設定されている場合、それがパケットの宛先であり、VLAN 10に対してタグなしに設定されている別のポートでタグなしの場合、同じパケットにタグが付けられます。

1
user46053