🌐

LinuxにNEXT-U-Flavorが実装されていたのでMicro SID (uSID)を再現してみたメモ

2023/09/18に公開

はじめに

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を使用しています.
https://github.com/shu1r0/ipnet_mininet.git
動作環境に使用したコードは以下です.
https://github.com/shu1r0/srv6_next_u_sid_linux_demo.git

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で配布しています.

usid_test_topo.drawio.png

例えば,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::と更新されていることがわかります.
usid_h1toh2.drawio.png

リプライの経路は以下のようになりました.
usid_h2toh1.drawio.png

次に,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を実行し,ルートとパケットを確認します.
usid_h1toh2_psp.drawio.png

おわりに

今回は,手軽に試せるという点で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?

脚注
  1. 現状では,End動作に対応しています.また,NEXT-C-SIDフレーバのEnd.Xの動作に関するcommitもあるようです(https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=7458575a07f1c6768e46b8eac6e09a358804c9f6). ↩︎

  2. uSIDの長さは,16bit以外の長さにすることも可能です.今回の記事ではわかりやすさのため,LinuxのNEXT-C-SID実装でデフォルトの長さとなっている16bitをuSIDの長さとして説明します. ↩︎

  3. encap.redでは,Parameter ProblemのICMPが返答されたので,encapで設定しています. ↩︎

Discussion