LinuxにNEXT-U-Flavorが実装されていたのでMicro SID (uSID)を再現してみたメモ
はじめに
Segment Routing over IPv6 (SRv6)には,Micro Segment (uSID)という拡張されたアーキテクチャがあります.これは,SIDのサイズ圧縮技術であり,SRv6 SIDがIPv6アドレス形式(128bit)であるためSIDのリストのサイズが大きくなるという問題に対処したものです.MicroSIDでは,SRv6のFlavorであるNEXT-U-SID,PSP,USPに対応しておく必要があります.どうやらLinuxには,Flavorの中のNEXT-U-SIDとPSPには対応しているみたいです[1].USPに関する実装はわかりませんでしたが,実装されたFlavorをつかったルートの設定を工夫することで,簡単なuSIDのデモができると考えました.この記事は,mininetで仮想ネットワークを構築し,ルートの設定でuSIDを再現したきのメモです.
uSIDとは?
Micro Segment (uSID)とは,SRv6 のSIDリストを圧縮するためのアーキテクチャです[2][3].SRv6 SIDは,IPv6アドレス形式であり,128bitと大きいサイズとなっています.uSIDは,16bit[2]で表現されたマイクロセグメントを指定する識別子です.SRv6 SIDにエンコードされ,最大6つ格納できます.
uSIDのフォーマットは,以下のようになっています.
<uSID-Block><Active-uSID><Next-uSID>...<Last-uSID><End-of-Container>...<End-of-Container>
例えば,2001:db8:0:0100:0200::
で2001:db8:0::/48
がuSID-Blockの場合,0100
, 0200
がuSIDであり,あとの0がEnd-of-Containerです.
Micro SIDの動作
uSIDの動作には,以下のようなものがあります.
- uN: (NEXT-C-SID,USP,PSPのフレーバの)End動作に対応した動作.
- uA: (NEXT-C-SID,USP,PSPのフレーバの)End.X動作に対応した動作
- uDT: End.DT4/End.DT6/End.DT2の動作に対応した動作.
- uDX: End.DX4/End.DX6?End.DX2の動作に対応した動作
このように,uSIDの動作では,SRv6のFlavorであるNEXT-C-SID,PSP,USPを利用します.それぞれのFlavorの説明を以下に示します.
- NEXT-C-SID: 圧縮されたSID (Compressed-SID, C-SID)に対応した動作に関するFlavor.Internet-Draftのdraft-ietf-spring-srv6-srh-compression-08で定義されており,Linuxではこのcommitで実装されている.
- PSP (Penultimate Segment Pop): 次のSIDが最終であるなら,宛先アドレスを書き換え後,SRHを削除する.
- USP (Ultimate Segment Pop): 自分自身が最後のSIDのノードである場合,SRHを削除して上位の層に渡す.
例えば,uNでは,次のuSID (next uSID)が存在する場合にはNEXT-C-SIDのEnd動作が行われ,存在しない場合(最後のuSID),PSP,USPのEnd動作が行われます.
検証環境
Linuxのupdate
SRv6のFlavorを利用するために,できるだけ新しいLinuxとiproute2をインストールします.
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v6.4.6/amd64/linux-headers-6.4.6-060406-generic_6.4.6-060406.202307241739_amd64.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v6.4.6/amd64/linux-headers-6.4.6-060406_6.4.6-060406.202307241739_all.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v6.4.6/amd64/linux-image-unsigned-6.4.6-060406-generic_6.4.6-060406.202307241739_amd64.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v6.4.6/amd64/linux-modules-6.4.6-060406-generic_6.4.6-060406.202307241739_amd64.deb
sudo apt install -y ./linux-headers-6.4.6*.deb ./linux-image-unsigned-6.4.6*.deb ./linux-modules-6.4.6*.deb
sudo reboot
Linuxがインストールされていることを確認します.
~$ uname -r
6.4.6-060406-generic
iproute2
ここから,新しいものを選んでインストールします.
sudo apt install -y pkg-config bison flex make gcc
cd /tmp
sudo wget -c https://mirrors.edge.kernel.org/pub/linux/utils/net/iproute2/iproute2-6.5.0.tar.gz
sudo tar -xzvf ./iproute2-6.5.0.tar.gz
cd ./iproute2-6.5.0
sudo make && sudo make install
バージョンを確認します.
$ ip -V
ip utility, iproute2-6.5.0
mininet
以上のLinuxとiproute2で,SRv6のNEXT-C-SIDとPSPは利用できます.
また,今回動作環境として,SRv6の設定を含んだmininetを使用しています.
動作環境に使用したコードは以下です.uSIDのネットワークを作ってみる
動作ネットワークは以下のようなネットワークです.
-
fdbb:bbbb::/32
をuSIDブロックとする. - Nをノードの番号にし,uSIDを
0N00
として設定する.この場合,fdbb:bbbb:0N00::/48
でuSIDが更新され,fdbb:bbbb:0N00::/64
でPSPのEnd動作を行う. - ホストにつながるノードでは,End.DT6を行うローカのuSIDを定義する.
また,ISISを使用してルートを設定しています.uSIDではロケータの概念はありませんが,デモの簡略化のためにfdbb:bbbb:0N00::/40
をISISで配布しています.
例えば,n1には,以下の設定を行います.
ip -6 route replace fdbb:bbbb:0100::/48 encap seg6local action End flavors next-csid dev n1_n2
ip -6 route add fdbb:bbbb:0100::/64 encap seg6local action End flavors psp dev n1_n2
ip -6 route add fdbb:bbbb:f00d::/48 encap seg6local action End.DT6 table 0 dev n1_n2
1つ目のルートで,USID-Block(fdbb:bbbb::/32)以下がusidであれば,next-csidのEnd動作を行います.この動作で,uSIDのリストが左に16bitシフトされます.
2つ目のルートで,uSIDのあとが0 (fdbb:bbbb:0100:0000::)の場合,そのuSIDが最後のuSIDになるので,PSPのEnd動作を行います.(なお,Internet-Draftでは,USPとPSPのFlavorですが,今環境のLinuxではUSPに未対応でした.)
3つ目のルートが,End.DT6を行うローカルuSIDです.このuSIDでカプセル化を解除します.
n1以外のノードにも同様の設定を行います.他のノードすべてのEnd動作の設定は以下です.(mininetの起動ログより)
*** n1 : ('ip -6 route add fdbb:bbbb:0100::/48 encap seg6local action End flavors next-csid dev n1_n2',)
*** n1 : ('ip -6 route add fdbb:bbbb:f00d::/48 encap seg6local action End.DT6 table 0 dev n1_n2',)
*** n1 : ('ip -6 route add fdbb:bbbb:0100::/64 encap seg6local action End flavors psp dev n1_n2',)
*** n2 : ('ip -6 route add fdbb:bbbb:0200::/48 encap seg6local action End flavors next-csid dev n2_n1',)
*** n2 : ('ip -6 route add fdbb:bbbb:f00d::/48 encap seg6local action End.DT6 table 0 dev n2_n1',)
*** n2 : ('ip -6 route add fdbb:bbbb:0200::/64 encap seg6local action End flavors psp dev n2_n1',)
*** n3 : ('ip -6 route add fdbb:bbbb:0300::/48 encap seg6local action End flavors next-csid dev n3_n4',)
*** n3 : ('ip -6 route add fdbb:bbbb:0300::/64 encap seg6local action End flavors psp dev n3_n4',)
*** n4 : ('ip -6 route add fdbb:bbbb:0400::/48 encap seg6local action End flavors next-csid dev n4_n3',)
*** n4 : ('ip -6 route add fdbb:bbbb:0400::/64 encap seg6local action End flavors psp dev n4_n3',)
*** n5 : ('ip -6 route add fdbb:bbbb:0500::/48 encap seg6local action End flavors next-csid dev n5_n6',)
*** n5 : ('ip -6 route add fdbb:bbbb:0500::/64 encap seg6local action End flavors psp dev n5_n6',)
*** n6 : ('ip -6 route add fdbb:bbbb:0600::/48 encap seg6local action End flavors next-csid dev n6_n5',)
*** n6 : ('ip -6 route add fdbb:bbbb:0600::/64 encap seg6local action End flavors psp dev n6_n5',)
続いて,Encapの設定です.n1では,h2に向かうパケットをn6 (0600
) を経由するように設定し,n2では,h1に向かうパケットをn5 (0500
) を経由するように設定します.最後にf00d
というローカルuSIDでカプセル化を解除します.
今回は,encap.red
を使用しており,カプセル化時に宛先アドレスに書かれるSIDはSRHのSIDリストに含まれません.
n1: ip -6 route add fd00:b::2/128 encap seg6 mode encap.red segs fdbb:bbbb:0500:0200:f00d:: dev n1_h1
n2: ip -6 route add fd00:a::2/128 encap seg6 mode encap.red segs fdbb:bbbb:0600:0100:f00d:: dev n2_h2
各ノードでtcpdumpを設定し,h1からh2に向けてpingします.
mininet> h1 ping -c 5 fd00:b::2
PING fd00:b::2(fd00:b::2) 56 data bytes
64 bytes from fd00:b::2: icmp_seq=1 ttl=63 time=0.342 ms
64 bytes from fd00:b::2: icmp_seq=2 ttl=63 time=0.336 ms
64 bytes from fd00:b::2: icmp_seq=3 ttl=63 time=0.341 ms
64 bytes from fd00:b::2: icmp_seq=4 ttl=63 time=0.341 ms
64 bytes from fd00:b::2: icmp_seq=5 ttl=63 time=0.343 ms
--- fd00:b::2 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4076ms
rtt min/avg/max/mdev = 0.336/0.340/0.343/0.002 ms
観測されたパケットと経路を以下に示します.
まず,ICMPリクエストの経路です.
n1 → n5 では,アドレスがfdbb:bbbb:0500:0200:f00d::
なのが,n5 → n2で,アドレスがfdbb:bbbb:0200:f00d::
と更新されていることがわかります.
リプライの経路は以下のようになりました.
次に,SIDの更新を確認するために以下のルートを設定します.[3]
n1: **ip -6 route add fd00:b::2/128 encap seg6 mode encap segs fdbb:bbbb:0600::,fdbb:bbbb:0500:0200:f00d:: dev n1_h1**
pingを実行し,ルートとパケットを確認します.
おわりに
今回は,手軽に試せるという点でLinuxでやりましたが,SONiCではuSIDのサポートがあるようなのでそちらも試してみたいですね(https://github.com/sonic-net/sonic-swss/pull/2335).
参考文献
[1] draft-ietf-spring-srv6-srh-compression-08
[2] draft-filsfils-spring-net-pgm-extension-srv6-usid-15
[3] A. Tulumello et al., "Micro SIDs: A Solution for Efficient Representation of Segment IDs in SRv6 Networks," in IEEE Transactions on Network and Service Management, vol. 20, no. 1, pp. 774-786, March 2023, doi: 10.1109/TNSM.2022.3205265.
[4] seg6: add NEXT-C-SID support for SRv6 End behavior
[5] seg6: add PSP flavor support for SRv6 End behavior
[6] index : kernel/git/netdev/net-next.git | search seg6
[7] ask Ubuntu | How Do I update my kernel to the latest one?
-
現状では,End動作に対応しています.また,NEXT-C-SIDフレーバのEnd.Xの動作に関するcommitもあるようです(https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=7458575a07f1c6768e46b8eac6e09a358804c9f6). ↩︎
-
uSIDの長さは,16bit以外の長さにすることも可能です.今回の記事ではわかりやすさのため,LinuxのNEXT-C-SID実装でデフォルトの長さとなっている16bitをuSIDの長さとして説明します. ↩︎
-
encap.redでは,Parameter ProblemのICMPが返答されたので,encapで設定しています. ↩︎
Discussion