Red Hat Training

A Red Hat training course is available for RHEL 8

第27章 Multipath TCP の使用

重要

Multipath TCP はテクノロジープレビューとしてのみ提供されます。テクノロジープレビューの機能は、Red Hat の本番環境のサービスレベルアグリーメント (SLA) ではサポートされず、機能的に完全ではないことがあるため、Red Hat では実稼働環境での使用を推奨していません。これらのプレビューは、近々発表予定の製品機能をリリースに先駆けてご提供します。これにより、お客様は機能性をテストし、開発プロセス中にフィードバックをお寄せいただくことができます。

テクノロジープレビュー機能のサポート範囲については、Red Hat カスタマーポータルの「テクノロジープレビュー機能のサポート範囲」を参照してください。

Multipath TCP (MPTCP) は、Transmission Control Protoco (TCP) の拡張機能です。インターネットプロトコル (IP) を使用すると、ホストはパケットを宛先に送信することができます。TCP は、インターネットを介したデータの信頼できる配信を保証し、ネットワーク負荷に応じて帯域幅を自動的に調整します。

以下は、MPTCP の利点です。

  • これにより、2 つ以上のネットワークインターフェースを持つデバイスで TCP を使用できます。
  • ユーザーは、各種ネットワークインターフェースを同時に使用することも、ある接続から別の接続にシームレスに切り替えることもできます。
  • これはネットワーク内のリソース使用状況を改善し、ネットワーク障害に対する耐障害性を確保します。

本セクションでは、以下を行う方法を説明します。

  • 新しい MPTCP コネクションを作成します。
  • iproute2 を使用して、新しいサブフローと IP アドレスを MPTCP 接続に追加します。
  • MPTCP 接続を使用するアプリケーションを回避するために、カーネルの MPTCP を無効にします。

27.1. MPTCP サポートを有効にするための RHEL の準備

いくつかのアプリケーションは MPTCP をネイティブにサポートしています。多くの場合、接続およびストリーム指向のソケットは、オペレーティングシステムへの socket() 呼び出しで TCP プロトコルを要求します。ネイティブ MPTCP 対応プログラムの sysctl ツールを使用して、RHEL で MPTCP サポートを有効にできます。MPTCP 実装は、カーネルへの IPPROTO_TCP 呼び出しを要求するアプリケーションに MPTCP プロトコルを使用できるように設計されています。

この手順では、MPTCP サポートを有効にし、SystemTap スクリプトを使用して MPTCP のシステム全体のを有効にするように RHEL を準備する方法を説明します。

前提条件

これにより、以下のパッケージがインストールされます。

  • kernel-debuginfo
  • kernel-debuginfo-common
  • systemtap
  • systemtap-devel
  • kernel-devel
  • nmap-ncat

手順

  1. カーネルで MPTCP ソケットを有効にします。

    # echo "net.mptcp.enabled=1" > /etc/sysctl.d/90-enable-MPTCP.conf
    # sysctl -p /etc/sysctl.d/90-enable-MPTCP.conf
  2. 以下の内容を含む mptcp.stap ファイルを作成します。

    #!/usr/bin/env stap
    
    %{
    #include <linux/in.h>
    #include <linux/ip.h>
    %}
    
    /* according to [1], RSI contains 'type' and RDX
     * contains 'protocol'.
     * [1] https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S#L79
     */
    
    function mptcpify () %{
        if (CONTEXT->kregs->si == SOCK_STREAM &&
            (CONTEXT->kregs->dx == IPPROTO_TCP ||
             CONTEXT->kregs->dx == 0)) {
                    CONTEXT->kregs->dx = IPPROTO_MPTCP;
                    STAP_RETVALUE = 1;
        } else {
               STAP_RETVALUE = 0;
        }
    %}
    
    probe kernel.function("__sys_socket") {
            if (mptcpify() == 1) {
                    printf("command %16s mptcpified\n", execname());
            }
    }
  3. TCP ソケットを MPTCP に置き換えます。

    # stap -vg mptcp.stap

    注記: Ctrl+C を使用して接続を MPTCP から TCP に変換します。

  4. TCP ポート 4321 をリッスンするサーバーを起動します。

    # ncat -4 -l 4321

  5. サーバーに接続して、トラフィックを交換します。たとえば、クライアントは「Hello world」をサーバーに 5 回書き込み、接続を終了します。

    # ncat -4 192.0.2.1 4321
    Hello world 1
    Hello world 2
    Hello world 3
    Hello world 4
    Hello world 5

    Ctrl+D を押して終了します。

検証手順

  1. MPTCP がカーネルで有効になっていることを確認します。

    # sysctl -a | grep mptcp.enabled
    net.mptcp.enabled = 1
  2. mptcp.stap スクリプトでカーネルプローブをインストールすると、以下の警告がカーネルの dmesg 出力に表示されます。

    # dmesg
    ...
    [ 1752.694072] Kprobes globally unoptimized
    [ 1752.730147] stap_1ade3b3356f3e68765322e26dec00c3d_1476: module_layout: kernel tainted.
    [ 1752.732162] Disabling lock debugging due to kernel taint
    [ 1752.733468] stap_1ade3b3356f3e68765322e26dec00c3d_1476: loading out-of-tree module taints kernel.
    [ 1752.737219] stap_1ade3b3356f3e68765322e26dec00c3d_1476: module verification failed: signature and/or required key missing - tainting kernel
  3. 接続が確立されたら、ss 出力を確認し、サブフロー固有のステータスを確認します。

    # ss -nti '( dport :4321 )' dst 192.0.2.1
    State Recv-Q Send-Q Local Address:Port    Peer Address:Port Process
    
    ESTAB 0      0          192.0.2.2:60874      192.0.2.1:4321
    cubic wscale:7,7 rto:201 rtt:0.042/0.017 mss:1448 pmtu:1500 rcvmss:536 advmss:1448 cwnd:10 bytes_sent:64 bytes_$cked:65 segs_out:6 segs_in:5 data_segs_out:4 send 2758095238bps lastsnd:57 lastrcv:3054 lastack:57 pacing_rate 540361516$bps delivery_rate 413714280bps delivered:5 rcv_space:29200 rcv_ssthresh:29200 minrtt:0.009 tcp-ulp-mptcp flags:Mmec token:0000(id:0)/4bffe73d(id:0) seq:c11f40d6c5337463 sfseq:1 ssnoff:f7455705 maplen:0
  4. tcpdump を使用してトラフィックをキャプチャーし、MPTCP サブオプションの使用をチェックします。

    # tcpdump -tnni interface TCP ポート 4321
    client Out IP 192.0.2.2.60802 > 192.0.2.1.4321: Flags [S], seq 3420255622, win 29200, options [mss 1460,sackOK,TS val 411 4539945 ecr 0,nop,wscale 7,mptcp capable v1], length 0
    client In  IP 192.0.2.1.4321 > 192.0.2.2.60802: Flags [S.], seq 2619315374, ack 3420255623, win 28960, options [mss 1460 sackOK,TS val 3241564233 ecr 4114539945,nop,wscale 7,mptcp capable v1 {0xb6f8dc721aee7f64}], length 0
    client Out IP 192.0.2.2.60802 > 192.0.2.1.4321: Flags [.], ack 1, win 229, options [nop,nop,TS val 4114539945 ecr 3241564 233,mptcp capable v1 {0xcc58d5d632a32d13,0xb6f8dc721aee7f64}], length 0
    client Out IP 192.0.2.2.60802 > 192.0.2.1.4321: Flags [P.], seq 1:17, ack 1, win 229, options [nop,nop,TS val 4114539945 ecr 3241564233,mptcp capable v1 {0xcc58d5d632a32d13,0xb6f8dc721aee7f64},nop,nop], length 16
    client In  IP 192.0.2.1.4321 > 192.0.2.2.60802: Flags [.], ack 17, win 227, options [nop,nop,TS val 3241564233 ecr 411459945,mptcp dss ack 1105509586894558345], length 0
    client Out IP 192.0.2.2.60802 > 192.0.2.1.4321: Flags [P.], seq 17:33, ack 1, win 229, options [nop,nop,TS val 4114540939 ecr 3241564233,mptcp dss ack 13265586846326199424 seq 105509586894558345 subseq 17 len 16,nop,nop], length 16

    このコマンドを実行するには、tcpdump パッケージが必要です。

関連情報