Closed67

TCP/IPをハンズオンで学ぶ[イーサネット]

ハガユウキハガユウキ

一般的な定義ではTCP/IPにイーサネットは含まれませんが、この本では説明の都合から含むように表現する場合があります。

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (p. 8). Kindle Edition.

ハガユウキハガユウキ

イーサネット

  • イーサネットとは、プロトコルを含んだ規格
  • IPのパケットがLANケーブルを通り抜けてルータまで辿り着くのは、イーサネットの力で実現できている。
  • イーサネットには、IPを含む上位層の通信を運ぶという大切な役割がある。
  • イーサネットはプロトコルの階層構造においてIPの下に位置している
    • OSI参照モデルではデータリンク層と物理層に対応する。
    • 物理層に対応する機能では、究極的にはビットを電気や光などでどう扱うかが関心事である。
ハガユウキハガユウキ

OSI参照モデルやTCP/IPの階層構造を、下から順番に番号を振った呼び方をすることがあります。たとえば、IPなら下から3番目にあたるのでレイヤー3のプロトコル、という具合です。イーサネットは、一般的にはレイヤー2のプロトコルと見なされています。

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (pp. 119-120). Kindle Edition.

ハガユウキハガユウキ

なお、もちろん世の中にはイーサネット以外のデータリンク層や物理層に対応するプロトコルや規格も存在します。しかし、現在の家庭やオフィスで用いられるのは、ほとんどイーサネットと考えて良いでしょう

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (p. 120). Kindle Edition.

そうなんや。イーサネットが強いのか。

ハガユウキハガユウキ

今回は物理層におけるイーサネットは取り扱わず、主にデータリンク層におけるイーサネットを扱うそう

ハガユウキハガユウキ

データリンク層におけるイーサネットの役割

  • データリンク層におけるイーサネットの役割を一言で表すとしたら「近隣までの荷物の配達」である。
  • イーサネットはIPを含む上位層のプロトコルのデータを運ぶ。これは、IPのパケットがいわば荷物の入ったダンボール箱だとしたら、イーサネットはそれを運ぶためのトラックある(このトラックは荷物の入った段ボール箱を1台につき1つしか積めない)
  • イーサネットではデータを送る単位、つまりトラック1台分のことを「フレーム(Frame)」と呼ぶ。
  • IPのパケットは異なるフレームに積みかえられながら最終的な目的地まで運ばれていく(同じネットワークにいるノードに送信する場合、フレームは一つあればOK)。
ハガユウキハガユウキ
  • イーサネットではフレームの送信先と送信元を管理する必要がある。この時MACアドレス(ハードウェアアドレスとも呼ばれる)が使われる。このMACアドレスはイーサネットのフレームを送受信するネットワーク機器ごとに付与される。
  • 同じMACアドレスを持つ製品は全世界で一つしかないことが期待される
  • MACアドレスは48ビットの正の整数である。上位24ビットはベンダーごとに割り当てられて、下位24ビットはベンダーが機器の識別子が一意になるように自由に割り当てられる
ハガユウキハガユウキ
# MACアドレス
00:00:5E:00:53:01

MACアドレスは1バイトごとに:または-で区切った16進数で表記する
また、16進数の英字が大文字ではなく、小文字のときもある。ただし、表記が異なっても同じMACアドレスを表現していることに変わりはない。

ハガユウキハガユウキ

MACアドレスはデータリンク層の通信で使われる

データリンク層は、ネットワークで直接隣接しているデバイス間の通信を管理します。データリンク層では、物理的なネットワークインターフェース(イーサネットカードなど)に割り当てられたMACアドレスを使用して通信します。MACアドレスは通常48ビットの固定長のアドレスで、ネットワーク上の各デバイスに一意に割り当てられます。

ハガユウキハガユウキ

イーサネットのフレームを観察する

こんな感じのネットワークをまずは作る。MACアドレスってどうやって設定するんやろ。

ハガユウキハガユウキ

今までの手順を実施すれば、IPの通信はできる状態にすることはできる。
イーサネットの通信を観察したいので、vethインターフェースのmacアドレスを変更する。
vethインターフェイスのMACアドレスは、デフォルトではランダムに割り振られている。それを、こちらで指定したものに変更する。その方が、ランダムな値を扱うよりも、イーサネットの通信を観察しやすい。

ハガユウキハガユウキ

ネットワークインターフェイスのMACアドレスを変更するにはip link setサブコマンドを使う。
addressの後ろにMACアドレスを指定する

sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01
sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
ハガユウキハガユウキ

ip link showでMACアドレスを確認できる。

vagrant@ubuntu-focal:~$ sudo ip netns exec ns1 ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
20: ns1-veth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff link-netns ns2
vagrant@ubuntu-focal:~$ sudo ip netns exec ns2 ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
19: ns2-veth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff link-netns ns1
vagrant@ubuntu-focal:~$
ハガユウキハガユウキ

ns1のvethインターフェースを観察する

# -eはイーサネットのヘッダ情報を表示するために指定する
# -lをつけると、Network Namespaceでtcdumpコマンドの表示がスムーズになる。
sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp
ハガユウキハガユウキ

もっとも左側に表示されているのが送信元のMACアドレスで、不等号(>)をはさんで右側に表示されているのが送信先のMACアドレスである。さらに右側の列には、これまで見てきたのと同じようにIPとICMPに関する情報がある。
これはイーサネットのフレームによってIPのパケットが運ばれる様子を示している
これまで見てきた内容も、実は裏側でイーサネットが活躍していた。

vagrant@ubuntu-focal:~$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 33912, seq 1, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 33912, seq 1, length 64
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 33912, seq 2, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 33912, seq 2, length 64
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 33912, seq 3, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 33912, seq 3, length 64
ハガユウキハガユウキ

この1行1行のイーサネットを用いたやりとりでフレームを使っているのか。なるほど。

ハガユウキハガユウキ

ipコマンド

ipコマンドは、Linuxシステムにおいてネットワーク構成やネットワーク関連の設定を行うためのコマンドである。
ipコマンドは、ifconfigコマンドの代替として導入されたもので、より柔軟かつ高機能なネットワーク管理ツールとして広く使用されています。

ハガユウキハガユウキ

要はネットワークに関する操作をしたかったらipコマンドを使えば良いってことか。

ハガユウキハガユウキ

プロトコルを組み合わせて使う時は、階層構造で、上位にあるものが下位にあるもののペイロードに基本的にはなる。

イーサネットはレイヤー2のプロトコルであって、IPはレイヤー3のプロトコルである。イーサネットのフレームは、ヘッダとペイロードから構成されています。このペイロードにIPのパケットが入る。
ヘッダはイーサネットフレームの先頭に位置し、ヘッダにはフレームの送信元MACアドレスと宛先MACアドレスが含まれている。

ハガユウキハガユウキ

ただし、これにはいくつかの例外もあるため、あくまで「基本的にはそうなる」と考えてください。たとえば、ICMPはOSI参照モデルではネットワーク層に相当するプロトコルと一般的には見なされています。そのため、IPと組み合わせたときにはレイヤー3のヘッダが連続して登場することになります。

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (p. 133). Kindle Edition.

ハガユウキハガユウキ

MACアドレスを知る

192.0.2.2というIPアドレスを持った相手とイーサネットで通信するには、何らかの方法で相手のMACアドレスも知る必要があります。MACアドレスを知らないと、パケットという荷物を載せたトラック、つまりイーサネットのフレームが目的地不明で出発できないからです。今回であれば、IPアドレス192.0.2.2に対応するMACアドレス00:00:5e:00:53:02を、ns1は知る必要があります。

ハガユウキハガユウキ

MACアドレスを知らないと、イーサネットで通信できないのか。イーサネットのフレームが目的地不明で出発できない。なるほど。

ハガユウキハガユウキ

ns1はなぜかns2のvethネットワークインターフェースに付与されているMACアドレスを知っていた。ns1がns2のvethネットワークインターフェースに付与されていたMACアドレスを知っていた理由は、ARP(Address Resolution Protocol)というプロトコルのおかげである。このプロトコルを使うと、IPアドレスに対応するMACアドレスを取得できる。

ハガユウキハガユウキ

MACアドレスのキャッシュを全て削除するコマンド

IPアドレスとMACアドレスの関係は頻繁に変更されないので、MACアドレスはキャッシュされる。キャッシュが残ったままだとキャッシュされたMACアドレスが使われるので、ARPによるアドレスの解決を観察できない。

sudo ip netns exec ns1 ip neigh flush all

ちなみにMACアドレスのキャッシュはip neighサブコマンドで確認できる

sudo ip netns exec ns1 ip neigh
ハガユウキハガユウキ
vagrant@ubuntu-focal:~$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:00:5e:00:53:01 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.2 tell 192.0.2.1, length 28
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Reply 192.0.2.2 is-at 00:00:5e:00:53:02, length 28
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 35996, seq 1, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 35996, seq 1, length 64
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 35996, seq 2, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 35996, seq 2, length 64
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 35996, seq 3, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 35996, seq 3, length 64
00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.1 tell 192.0.2.2, length 28
00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype ARP (0x0806), length 42: Reply 192.0.2.1 is-at 00:00:5e:00:53:01, length 28
ハガユウキハガユウキ

最初のイーサネットのフレームを用いたやりとりで、IPの通信に先駆けて、ARPで192.0.2.2というIPアドレスを持った機器のMACアドレスを192.0.2.1に教えてと要求している。この要求はARPリクエストと呼ぶ

00:00:5e:00:53:01 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.2 tell 192.0.2.1, length 28
ハガユウキハガユウキ

それに対して、次のイーサネットのフレームを用いたやりとりで、返答を得られている。
内容は、192.0.2.2というIPアドレスは00:00:5e:00:53:02というMACアドレスの機器が持っているよというものである。この返答のことをARPリプライと呼ぶ。

00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Reply 192.0.2.2 is-at 00:00:5e:00:53:02, length 28
ハガユウキハガユウキ

ff:ff:ff:ff:ff:ff

ff:ff:ff:ff:ff:ffはブロードキャストアドレスと呼ばれる特殊なMACアドレスである。

送信先がブロードキャストアドレスのフレームは「このフレームが届く限りの範囲で、すべての機器に聞いてほしい」という意味になります。このように、送信先がブロードキャストアドレスになっているフレームのことをブロードキャストフレームといいます。また、ブロードキャストフレームが届く範囲のことをブロードキャストドメインといいます。
momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (p. 139). Kindle Edition.

ハガユウキハガユウキ

ARPリクエストの意味を解釈すると、「通信したいIPアドレスのMACアドレスがわからんから誰か教えて」と自分の声が届くネットワーク機器に呼びかけていた。そして、次のフレームでIPアドレスを持っている機器から「そのIPアドレスに対応するMACアドレスはこれだよ」と渡されている。MACアドレスをよくみると、ARPリプライ時に送信関係が逆転しているのが面白い。

ハガユウキハガユウキ

このARPのやりとりを通して、ns1は通信相手のIPアドレスを持つMACアドレスを取得したので、以降の通信ではMACアドレスを使って組み立てたフレームを使ってIPのパケットを送っている。

ハガユウキハガユウキ

ARPを使ってMACアドレスを解決するのは、ネットワーク層のプロトコルとしてIPv4を使う場合だけ

ARPを使ってMACアドレスを解決するのは、ネットワーク層のプロトコルとしてIPv4を使う場合だけです。IPv6を使うときは、代わりにICMPv6というプロトコルのNeighborDiscovery(近隣探索)7という仕組みが用いられます。

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (p. 140). Kindle Edition.

ハガユウキハガユウキ

用語の整理

MACアドレスにおけるブロードキャストアドレス

フレームの送信先がMACアドレスにおけるブロードキャストアドレスの場合、「このフレームが届く限りの範囲(ブロードキャストドメイン)で、すべての機器に聞いてほしい」という意味になる。

ブロードキャストフレーム

ブロードキャストフレームとは、送信先がブロードキャストアドレスになっているフレームのこと。

ブロードキャストドメイン

ブロードキャストドメインとは、ブロードキャストフレームが届く範囲のことである。
一般的に、ブロードキャストドメインの範囲は、フレームを送信したノードが属しているネットワークである。

ハガユウキハガユウキ

同じブロードキャストドメインにいるノードには、一つのフレームでパケットを直接送ることができる

ハガユウキハガユウキ

てことは、ネットワークが異なるノードにフレームを送る場合、IPパケットのフレームを積み替える必要があるってことか?

ハガユウキハガユウキ

先ほどの例では、同じブロードキャストドメインの範囲だったので、フレームを一つしか使ってない。

ハガユウキハガユウキ

パケットが異なるフレームに積み替えられる様子を観察する

ハガユウキハガユウキ

2つのターミナルでtcpdumpコマンドを使うキャプチャするのは、routerが持つ2つのインターフェース。それぞれのインターフェースはブロードキャストドメインが異なる。

ハガユウキハガユウキ
sudo ip netns exec router tcpdump -tnel -i gw-veth0 icmp or arp
sudo ip netns exec router tcpdump -tnel -i gw-veth1 icmp or arp
ハガユウキハガユウキ

MACアドレスがないと、パケットをのせるフレームが作れません。フレームが作れないとパケットを送れない。

ハガユウキハガユウキ

イーサネットのフレーム(イーサネットにおけるデータを送る単位)は、ヘッダとペイロードから構成されています。このペイロードにIPのパケットが入る。ヘッダはイーサネットフレームの先頭に位置し、ヘッダにはフレームの送信元MACアドレスと宛先MACアドレスが含まれている。

なるほど、ipのパケットが荷物でフレームがトラックって例えがやっとわかった。IPのパケットのヘッダで送信元ノードのIPアドレスと送信先ノードのIPアドレスを管理している。ipのパケットのヘッダは、荷物がどのように届けられるかに関心がない。送信元と送信先にしか関心がない。イーサネットのフレームのヘッダでノード間の送信元のネットワークインターフェースのMACアドレスと送信先のネットワークインターフェースのMACアドレスを管理している。イーサーネットのフレームのヘッダは1組のノード間のやりとりに対して関心がある(1組のノード間のやりとりしか管理してない。全体には興味がない感じ)。1組にしか関心がないから、フレームを受け取ったあるノードが別のノードにパケットを送る時、また新しいフレームを使う。その新しいフレームにパケットを載せ替える。それを繰り返しているうちに、最終的な送信先のIPアドレスを持つホストにフレームが届いて、パケットが届く。ルートテーブルをもとにルーティングが決まってそのノードに対してパケットが含まれているフレームを送る。送る際に送信先のMACアドレスを使う。送信先のMACアドレスを知るには、送信先のIPアドレスに紐づいたMACアドレスを知れるARPというプロトコルを使う

ハガユウキハガユウキ

やりとりのログ。
ノードからノードにフレームを届ける際にARPのプロトコルを使って送信元ノードが、送信先ノードのネットワークインターフェースのMACアドレスを取得しているのが確認できる。

ログ1

vagrant@ubuntu-focal:~$ sudo ip netns exec router tcpdump -tnel -i gw-veth0 icmp or arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on gw-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:00:5e:00:53:11 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.254 tell 192.0.2.1, length 28
00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype ARP (0x0806), length 42: Reply 192.0.2.254 is-at 00:00:5e:00:53:12, length 28
00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 1, length 64
00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 1, length 64
00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 2, length 64
00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 2, length 64
00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 3, length 64
00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 3, length 64
00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.1 tell 192.0.2.254, length 28
00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype ARP (0x0806), length 42: Reply 192.0.2.1 is-at 00:00:5e:00:53:11, length 28

ログ2

vagrant@ubuntu-focal:~$ sudo ip netns exec router tcpdump -tnel -i gw-veth1 icmp or arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on gw-veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
00:00:5e:00:53:21 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 198.51.100.1 tell 198.51.100.254, length 28
00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype ARP (0x0806), length 42: Reply 198.51.100.1 is-at 00:00:5e:00:53:22, length 28
00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 1, length 64
00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 1, length 64
00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 2, length 64
00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 2, length 64
00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 3, length 64
00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 41039, seq 3, length 64
00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype ARP (0x0806), length 42: Request who-has 198.51.100.254 tell 198.51.100.1, length 28
00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype ARP (0x0806), length 42: Reply 198.51.100.254 is-at 00:00:5e:00:53:21, length 28

pingを実行したログ

vagrant@ubuntu-focal:~$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.203 ms
64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=0.133 ms
64 bytes from 198.51.100.1: icmp_seq=3 ttl=63 time=0.132 ms

--- 198.51.100.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.132/0.156/0.203/0.033 ms
ハガユウキハガユウキ

ここに注目する
確かに送信先と送信元のMACアドレスが変わっているので、そこでフレームが新しくなったと考えられる。IPパケットの内容は変わってないので、IPパケットを新しいフレームに移し替えたっていうのも分かる(フレームで運ばれているパケットのIPアドレスは、送信元も送信先も変わっていないので、IPのパケットが変化していないで別のフレームに移し替えられたことが分かる)。

ログ1

00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 1, length 64

ログ2

00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 41039, seq 1, length 64
ハガユウキハガユウキ

セグメントが2つに増えたネットワークでは、異なるフレームにパケットが載せかえられて目的地まで送り届けられています。

momijiame. Learning TCP/IP networking by exercise on Linux (Japanese Edition) (pp. 172-173). Kindle Edition.

ハガユウキハガユウキ

typeは新しく作成するネットワークインターフェースのタイプを指定する

typeは、Linuxのip linkコマンドで使用されるオプションの1つです。typeオプションを使用して、新しいネットワークインターフェースのタイプを指定することができます。
具体的には、ip link addコマンドを使用して新しいネットワークインターフェースを作成する際に、typeオプションを指定してそのインターフェースの種類を指定します。例えば、type vethとすると、仮想イーサネットインターフェース(vethインターフェース)が作成されます。
ネットワークインターフェースの種類にはさまざまなものがあります。代表的なネットワークインターフェースのタイプには以下のようなものがあります:
eth: 物理的なイーサネットインターフェース
veth: 仮想的なイーサネットインターフェースのペア
bridge: ブリッジインターフェース(スイッチング機能を持つ)
bond: ボンディングインターフェース(複数の物理インターフェースを1つの論理インターフェースとして結合する)
tun: タンネルインターフェース(通信を暗号化して別のネットワークにトンネリングする)
など、さまざまなネットワークインターフェースのタイプが存在します。typeオプションを使用することで、必要に応じて適切なタイプのネットワークインターフェースを作成することができます。

ハガユウキハガユウキ

tcpdumpコマンド

  • tcpdumpは、ネットワークパケットをキャプチャして表示するためのコマンドである。
  • tcpdumpを使用すると、実際にネットワーク上を流れるパケットをリアルタイムに監視できる。これにより、ネットワークトラフィックの解析、デバッグ、セキュリティの監視など、さまざまな目的で役立つ。
ハガユウキハガユウキ

-i: 特定のネットワークインターフェースを指定してパケットをキャプチャします。
-n: IPアドレスやポート番号を名前解決せずに表示します。
-c: 指定した数のパケットをキャプチャして終了します。
-s: 表示するパケットの最大バイト数を指定します。
host: 特定のホストの通信を表示します。
port: 特定のポート番号の通信を表示します。
tcpdumpを使うと、TCPやUDPなどのトランスポート層のプロトコルや、ICMPなどのネットワーク層のプロトコルを含むパケットを観察できます

ハガユウキハガユウキ

スイッチングハブ

  • パソコンとブロードバンドルータを一つのLANケーブルで繋いだりしない。
    • もしそれをすると、一台のパソコンしかインターネットに接続できない。
  • 多くの場合、ルータとパソコンの間にLANケーブルがたくさん繋がる箱がある。その箱のことをスイッチングハブ(もしくはスイッチやハブともいう)と呼ぶ。
  • スイッチングハブを使うことで、複数のネットワーク機器が同じブロードキャストドメインに参加して通信できるようになる。 スイッチングハブはUSBハブのイーサネット版として考えるとわかりやすい。
  • 近年のルータにはスイッチングハブがルーターに組み込まれているそう。

ブリッジ

  • スイッチングハブという言葉を、より一般化した用語がブリッジである。
  • ネットワーク層でパケットを転送する機器はルータと呼ばれていた
  • それと同じように、ブリッジとは、データリンク層でフレームを転送する機器のことです。
  • ブリッジを使うことで、同じブロードキャストドメインにたくさんのネットワーク機器をつなげることができるようになる

ブリッジの仕事

  • ブリッジの仕事は、自身のどのポートにどのMACアドレスの機器が繋がっているかを管理すること
  • そして、フレームがやってくると、送信先MACアドレスを読み取って、機器が繋がっているポートにフレームを転送する。ブリッジは、ブリッジ自身のどのポートにどのMACアドレスの機器が繋がっているかをMACアドレステーブルで管理している

ブリッジのポート

ブリッジのポートとは、有線LANであれば機器のケーブルが挿さる口のことを表している。
トランスポート層のプロトコルで扱うポートとは別物である。

ハガユウキハガユウキ

ブリッジの挙動を確認

Linuxにはブリッジの実装として、ネットワークブリッジと呼ばれる機能がある。
これまでの実験で同じセグメントに2つのNetwork Namespaceしか繋がらなかった理由は、vethインターフェースを使って、Network Namespace同士を直接接続していたからである。Linuxのネットワークブリッジを使うことで、Network Namespaceはネットワークブリッジを介してお互い繋がることができて、3つ以上のNetwork Namespaceを同じセグメントに繋げることができる

ハガユウキハガユウキ

ブリッジを取り入れたネットワーク図

ネットワークブリッジはbridgeという名前のNetwork Namespaceの中に作る。
vethインタフェースから伸びる波線は、そのインターフェースがネットワークブリッジに接続されていることを示している。

ハガユウキハガユウキ

通常、高レベルのネットワーク図ではブリッジは省略されることが多く、詳細な設計やトラブルシューティングを目的とした図でブリッジが記載されることがより一般的です。

ハガユウキハガユウキ

ネットワークブリッジを作る

ネットワークブリッジもネットワークインターフェースの一種である。
そのため、状態を保つ。なので、使うならUPにする。

sudo ip netns exec bridge ip link add dev br0 type bridge 
sudo ip netns exec bridge ip link set br0 up

# vethインターフェースの片側をネットワークブリッジに接続する
sudo ip netns exec bridge ip link set ns1-br0 master br0
sudo ip netns exec bridge ip link set ns2-br0 master br0
sudo ip netns exec bridge ip link set ns3-br0 master br0
ハガユウキハガユウキ

通信相手のいないポードに無駄なフレームは流さないです。
スイッチングハブでは当たり前だが、一昔前のリピータハブでは当たり前ではなかったそう。
(今ではリピータハブを手に入れることは難しくなったそう)

ハガユウキハガユウキ

bridge fdb showサブコマンドでMACアドレステーブルを確認できる。

ハガユウキハガユウキ

vethインターフェースについて改めて深ぼる

vethインターフェースは対で作る必要がある。(つまり2つのvethインターフェースが必要)
ペアの一方のデバイスで送信されたパケットは、もう一方のデバイスですぐに受信されます。
https://www.fsi.co.jp/blog/5305/
https://markunet.github.io/blog/Intro_Linux_interfaces_JP/#veth-virtual-ethernet

ハガユウキハガユウキ

ChatGPTにも聞いてみた

vethインターフェース:
vethインターフェース(仮想Ethernetインターフェース)は、Linuxのネットワーク名前空間(Network Namespace)で使用される特殊な仮想インターフェースのペアです。このペアのインターフェースは、ペアとなる2つのvethインターフェース同士が通信できるようになっており、1つのvethインターフェースはホストの名前空間に属し、もう1つのvethインターフェースは別の名前空間(通常はコンテナや仮想マシン)に属しています。vethインターフェースを使うことで、異なるネームスペース内のプロセスやデバイス間で通信することが可能になります。
つまり、vethインターフェースはネットワークインターフェースの一種であり、ホストと別の名前空間(通常はコンテナなど)との間で通信を仲介する役割を持っています。vethインターフェース同士は、ペアとして作成されるため、一方のインターフェースにデータを送信すると、もう一方のインターフェースにデータが到着するような仕組みになっています。

ハガユウキハガユウキ

多分理解は合っていると思うけど、曖昧。コードで確認しているから多分おおよそは合っていると思う。

このスクラップは2023/07/27にクローズされました