トップ «前の日記(12/31/2018) 最新 編集

本 日 の h o g e

hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。

更新情報の取得には rdflirs を使ってもらえると嬉しいです.


01/23/2019 うむ [長年日記]

tDiary 5935日目

[Linux][小ネタ] Linux で Private VLAN (pvlan) もどき

本物の pvlan を実装するのはちょっと面倒な気がしたので,簡単にできそうな擬似的な "もどき" を作ってみる.ひとまず Cisco で言うところの switchport mode private-vlan trunk promiscuous な uplink を想定.

実現には,ブリッジにおいて uplink 想定のポートとの通信以外を遮断して,uplink との通信時にはネットワーク毎に primary vlan 相当のタグを付加してやれば良いはずなので,vlan_filtering と ebtables を用いて実装してみる.テストのためのお膳立てが多いので長くなってしまっているが,メインは "# create nsx" というコメントから.

ip netns add nsx  # pseudo pvlan box
ip netns add ns1  # uplink (trunk)
ip netns add ns2  # downlink (10)
ip netns add ns3  # downlink (10)
ip netns add ns4  # downlink (20)
ip netns add ns5  # downlink (20)

# create ns1
ip link add veth0 type veth peer name veth1
ip link set veth0 netns ns1
ip link set veth1 netns nsx
ip -n ns1 link add veth0.10 link veth0 type vlan id 10
ip -n ns1 link add veth0.20 link veth0 type vlan id 20
ip -n ns1 addr add 10.0.10.1/24 dev veth0.10
ip -n ns1 addr add 10.0.20.1/24 dev veth0.20
for dev in lo veth0 veth0.10 veth0.20; do
       ip -n ns1 link set "${dev}" up
done

# create ns2
ip link add veth0 type veth peer name veth2
ip link set veth0 netns ns2
ip link set veth2 netns nsx
ip -n ns2 addr add 10.0.10.2/24 dev veth0
for dev in lo veth0; do
       ip -n ns2 link set "${dev}" up
done

# create ns3
ip link add veth0 type veth peer name veth3
ip link set veth0 netns ns3
ip link set veth3 netns nsx
ip -n ns3 addr add 10.0.10.3/24 dev veth0
for dev in lo veth0; do
       ip -n ns3 link set "${dev}" up
done

# create ns4
ip link add veth0 type veth peer name veth4
ip link set veth0 netns ns4
ip link set veth4 netns nsx
ip -n ns4 addr add 10.0.20.4/24 dev veth0
for dev in lo veth0; do
       ip -n ns4 link set "${dev}" up
done

# create ns5
ip link add veth0 type veth peer name veth5
ip link set veth0 netns ns5
ip link set veth5 netns nsx
ip -n ns5 addr add 10.0.20.5/24 dev veth0
for dev in lo veth0; do
       ip -n ns5 link set "${dev}" up
done

# create nsx
ip -n nsx link add brx  type bridge vlan_filtering 1
ip -n nsx link add br10 type bridge
ip -n nsx link add br20 type bridge
ip -n nsx link add p10a type veth peer name p10b
ip -n nsx link add p20a type veth peer name p20b
for dev in lo brx br10 br20 p10a p10b p20a p20b veth1 veth2 veth3 veth4 veth5; do
       ip -n nsx link set "${dev}" up
done

ip -n nsx link set veth1 master brx
ip -n nsx link set p10a  master brx
ip -n nsx link set p20a  master brx

ip -n nsx link set p10b  master br10
ip -n nsx link set veth2 master br10
ip -n nsx link set veth3 master br10

ip -n nsx link set p20b  master br20
ip -n nsx link set veth4 master br20
ip -n nsx link set veth5 master br20

# allow vid 10,20 as tagged on veth1 (uplink)
bridge -n nsx vlan add dev veth1 vid 10
bridge -n nsx vlan add dev veth1 vid 20
bridge -n nsx vlan del dev veth1 vid 1

# allow vid 10 as untagged on p10a (veth2,3)
bridge -n nsx vlan add dev p10a vid 10 pvid untagged
bridge -n nsx vlan del dev p10a vid 1

# allow vid 20 as untagged on p20a (veth4,5)
bridge -n nsx vlan add dev p20a vid 20 pvid untagged
bridge -n nsx vlan del dev p20a vid 1

# deny downlink-to-downlink communication on br10
ip netns exec nsx ebtables -A FORWARD --logical-in  br10 -i p10b -j ACCEPT
ip netns exec nsx ebtables -A FORWARD --logical-out br10 -o p10b -j ACCEPT
ip netns exec nsx ebtables -A FORWARD --logical-in  br10 -j DROP
ip netns exec nsx ebtables -A FORWARD --logical-out br10 -j DROP

# deny downlink-to-downlink communication on br20
ip netns exec nsx ebtables -A FORWARD --logical-in  br20 -i p20b -j ACCEPT
ip netns exec nsx ebtables -A FORWARD --logical-out br20 -o p20b -j ACCEPT
ip netns exec nsx ebtables -A FORWARD --logical-in  br20 -j DROP
ip netns exec nsx ebtables -A FORWARD --logical-out br20 -j DROP

そんなに大したことをやっているわけではなく,ブリッジを 2段に分けて,上位ブリッジでは下位ブリッジとやりとりするフレームにタグ付けを行い,下位ブリッジではポート間通信制御を行っているだけ.

当然 "もどき" であって本物の pvlan ではないので,例えば trunk port を用意して延伸するとかはできない.何せこの実装には secondary vlan が存在しないので当たり前である.

かしこ

追記

ちなみにわざわざブリッジを分けずとも,downlink port 毎に pvid を指定していけばブリッジ 1つで済ませることもできる.のだが,そうすると downlink port が増えるごとに,ブリッジへの参加だけでなく pvid の設定もやる必要が出てきて面倒なので,ここでは分離する方式を採っている.例えば libvirt/kvm で VM を生やして,I/F を上記 br10, 20 に参加させるといったことを考えると分かりやすい.