Red Hat Training

A Red Hat training course is available for RHEL 8

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

デフォルトでは、RHEL で MPTCP サポートが無効になっています。この機能に対応するアプリケーションを使用できるように、MPTCP を有効にします。また、アプリケーションにデフォルトで TCP ソケットがある場合は、MPTCP ソケットを強制的に使用するように、ユーザー空間アプリケーションを設定する必要があります。

sysctl ユーティリティーを使用して MPTCP サポートを有効にし、SystemTap スクリプトを使用してアプリケーション全体で MPTCP を有効にする RHEL を準備することができます。

前提条件

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

  • systemtap
  • iperf3

手順

  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 がカーネルで有効になっていることを確認します。

    # sysctl -a | grep mptcp.enabled
    net.mptcp.enabled = 1
  3. 以下の内容で mptcp-app.stap ファイルを作成します。

    #!/usr/bin/env stap
    
    %{
    #include <linux/in.h>
    #include <linux/ip.h>
    %}
    
    /* RSI contains 'type' and RDX contains 'protocol'.
     */
    
    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());
            }
    }
  4. ユーザー空間のアプリケーションに、TCP ソケットの代わりに MPTCP ソケットを作成させるには、以下のコマンドを実行します。

    # stap -vg mptcp-app.stap

    注意: この操作は、コマンドの後に開始するすべての TCP ソケットに影響します。アプリケーションは、上記のコマンドを Ctrl+C で中断した後も TCP ソケットを使用し続けます。

  5. もしくは、MPTCP の使用を特定のアプリケーションのみに許可する場合は、以下の内容を使用して mptcp-app.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") {
    	cur_proc = execname()
    	if ((cur_proc == @1) && (mptcpify() == 1)) {
    		printf("command %16s mptcpified\n", cur_proc);
    	}
    }
  6. 別の選択肢として、iperf3 ツールで TCP の代わりに MPTCP を強制的に使用する場合を想定します。起動するには、以下のコマンドを実行します。

    # stap -vg mptcp-app.stap iperf3
  7. mptcp-app.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
    [ 1752.737219] stap_1ade3b3356f3e68765322e26dec00c3d_1476 (mptcp-app.stap): systemtap: 4.5/0.185, base: ffffffffc0550000, memory: 224data/32text/57ctx/65638net/367alloc kb, probes: 1
  8. iperf3 サーバーを起動します。

    # iperf3 -s
    
    Server listening on 5201
  9. クライアントをサーバーに接続します。

    # iperf3 -c 127.0.0.1 -t 3
  10. 接続が確立されたら、ss 出力を確認し、サブフロー固有のステータスを確認します。

    # ss -nti '( dport :5201 )'
    
    State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
    ESTAB 0      0      127.0.0.1:41842    127.0.0.1:5201
    cubic wscale:7,7 rto:205 rtt:4.455/8.878 ato:40 mss:21888 pmtu:65535 rcvmss:536 advmss:65483 cwnd:10 bytes_sent:141 bytes_acked:142 bytes_received:4 segs_out:8 segs_in:7 data_segs_out:3 data_segs_in:3 send 393050505bps lastsnd:2813 lastrcv:2772 lastack:2772 pacing_rate 785946640bps delivery_rate 10944000000bps delivered:4 busy:41ms rcv_space:43690 rcv_ssthresh:43690 minrtt:0.008 tcp-ulp-mptcp flags:Mmec token:0000(id:0)/2ff053ec(id:0) seq:3e2cbea12d7673d4 sfseq:3 ssnoff:ad3d00f4 maplen:2
  11. nstat MPTcp* を使用して、MPTCP カウンターを確認します。

    # nstat MPTcp*
    
    #kernel
    MPTcpExtMPCapableSYNRX          2                  0.0
    MPTcpExtMPCapableSYNTX          2                  0.0
    MPTcpExtMPCapableSYNACKRX       2                  0.0
    MPTcpExtMPCapableACKRX          2                  0.0

関連情報