Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenvSwitch で作る透過 L3DSR

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for akam1o akam1o
March 10, 2026

OpenvSwitch で作る透過 L3DSR

Avatar for akam1o

akam1o

March 10, 2026

More Decks by akam1o

Other Decks in Technology

Transcript

  1. whoami 神尾 皓 (Akira KAMIO) •株式会社サイバーエージェント ◦CyberAgent group Infrastructure Unit (CIU)

    ◦Cycloud Div, Compute Team •2020/06 中途入社 ◦入社以来、一貫してIaaS基盤の開発/運用業務に従事 ◦Qemu/KVM や高集約コンピュートノードの最適化に興味がある 2
  2. L3DSR について ・Inline 構成  ・リクエストを LB で NAT して、レスポンスも LB

    を経由する ・L3DSR 構成  ・リクエストを LB で NAT せず real server へ送信  ・レスポンスは real server から直接返す  ・L3 を跨いだ NW 構成が可能 -> 柔軟性が高い 5 LB Client Server
  3. L3DSR の実装方法 ・DSCP (TOS)  ・リクエストパケットに DSCP bit を付与して real server

    へ転送 ・IPIP  ・リクエストパケットを IPIP でカプセルして real server へ転送 ・GRE  ・リクエストパケットを GRE でカプセルして real server へ転送 6 LB Client Server
  4. L3DSR の課題 ・サーバ側に L3DSR の設定が必要  ・DSCP -> iptable で特定の DSCP

    bit が立っているときに曲げる  ・IPIP -> IPIP トンネル I/F を作成  ・GRE -> GRE トンネル I/F を作成 7
  5. L3DSR の課題 ・サーバ側に L3DSR の設定が必要  ・DSCP -> iptable で特定の DSCP

    bit が立っているときに曲げる  ・IPIP -> IPIP トンネル I/F を作成  ・GRE -> GRE トンネル I/F を作成 8 サーバに特別な設定を入れずに L3DSR できたら嬉しい!
  6. 透過 L3DSR の要件 ・サーバに特別な設定を入れなくて良いようにする  =>ハイパーバイザ上で   ・リクエスト:VIP 宛の dsr IP を

    Server IP に変換   ・レスポンス:Client 宛のパケットの src IP を VIP に変換 12 L3DSR 宛の変換したパケットをすべて覚えている必要がある
  7. 第1稿: DSCP パターン ・まずは DSCP パターンについて検討した 14 CLI -> LB

    SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: CLI IP DST IP: VM IP TOS: 32 OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP ・あくまで色付けとしての利用のため既存の NW に影響しないように設定する必要がある  ・IP Precedence 部をフルビットにしない   ・IP Precedence 部フルビットはネットワーク機器によっては制御パケットとして認識されてしまう  ・そのため DSCP は 1-47 (48 から IP Precedence 部がフルビット)を色付け用として用いる 例: CLI IP: 124.0.124.100 VIP: 203.80.24.55 VM IP: 10.200.100.88 TOS: 32 TOS の値が 32 のときに VIP 宛の通信を reg0 に記録 ovs-ofctl add-flow br0 "table=0, priority=100, ip, nw_dst=10.200.100.88 actions=load:NXM_NX_IP_TOS[]->NXM_NX_REG0[], goto_table:1" reg0 が 32(TOS の値)のときに SRC IP を VIP に書き換える ovs-ofctl add-flow br0 "table=1, priority=110, ip, nw_src=10.200.100.88, reg0=0x20 actions=mod_nw_src:203.80.24.55, normal"
  8. 第1稿: DSCP パターン ・まずは DSCP パターンについて検討した 15 CLI -> LB

    SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: CLI IP DST IP: VM IP TOS: 32 OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP ・あくまで色付けとしての利用のため既存の NW に影響しないように設定する必要がある  ・IP Precedence 部をフルビットにしない   ・IP Precedence 部フルビットはネットワーク機器によっては制御パケットとして認識されてしまう  ・そのため DSCP は 1-47 (48 から IP Precedence 部がフルビット)を色付け用として用いる 例: CLI IP: 124.0.124.100 VIP: 203.80.24.55 VM IP: 10.200.100.88 TOS: 32 TOS の値が 32 のときに VIP 宛の通信を reg0 に記録 ovs-ofctl add-flow br0 "table=0, priority=100, ip, nw_dst=10.200.100.88 actions=load:NXM_NX_IP_TOS[]->NXM_NX_REG0[], goto_table:1" reg0 が 32(TOS の値)のときに SRC IP を VIP に書き換える ovs-ofctl add-flow br0 "table=1, priority=110, ip, nw_src=10.200.100.88, reg0=0x20 actions=mod_nw_src:203.80.24.55, normal" LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: CLI IP DST IP: VM IP TOS: 32 (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP
  9. 第1稿: DSCP パターン ・まずは DSCP パターンについて検討した 16 CLI -> LB

    SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: CLI IP DST IP: VM IP TOS: 32 OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP ・あくまで色付けとしての利用のため既存の NW に影響しないように設定する必要がある  ・IP Precedence 部をフルビットにしない   ・IP Precedence 部フルビットはネットワーク機器によっては制御パケットとして認識されてしまう  ・そのため DSCP は 1-47 (48 から IP Precedence 部がフルビット)を色付け用として用いる 例: CLI IP: 124.0.124.100 VIP: 203.80.24.55 VM IP: 10.200.100.88 TOS: 32 TOS の値が 32 のときに VIP 宛の通信を reg0 に記録 ovs-ofctl add-flow br0 "table=0, priority=100, ip, nw_dst=10.200.100.88 actions=load:NXM_NX_IP_TOS[]->NXM_NX_REG0[], goto_table:1" reg0 が 32(TOS の値)のときに SRC IP を VIP に書き換える ovs-ofctl add-flow br0 "table=1, priority=110, ip, nw_src=10.200.100.88, reg0=0x20 actions=mod_nw_src:203.80.24.55, normal"
  10. 第1稿: DSCP パターン ・まずは DSCP パターンについて検討した 17 CLI -> LB

    SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: CLI IP DST IP: VM IP TOS: 32 OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP ・あくまで色付けとしての利用のため既存の NW に影響しないように設定する必要がある  ・IP Precedence 部をフルビットにしない   ・IP Precedence 部フルビットはネットワーク機器によっては制御パケットとして認識されてしまう  ・そのため DSCP は 1-47 (48 から IP Precedence 部がフルビット)を色付け用として用いる 例: CLI IP: 124.0.124.100 VIP: 203.80.24.55 VM IP: 10.200.100.88 TOS: 32 TOS の値が 32 のときに VIP 宛の通信を reg0 に記録 ovs-ofctl add-flow br0 "table=0, priority=100, ip, nw_dst=10.200.100.88 actions=load:NXM_NX_IP_TOS[]->NXM_NX_REG0[], goto_table:1" reg0 が 32(TOS の値)のときに SRC IP を VIP に書き換える ovs-ofctl add-flow br0 "table=1, priority=110, ip, nw_src=10.200.100.88, reg0=0x20 actions=mod_nw_src:203.80.24.55, normal" ボツ
  11. 第1稿: DSCP パターン ・まずは DSCP パターンについて検討した 18 CLI -> LB

    SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: CLI IP DST IP: VM IP TOS: 32 OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP ・あくまで色付けとしての利用のため既存の NW に影響しないように設定する必要がある  ・IP Precedence 部をフルビットにしない   ・IP Precedence 部フルビットはネットワーク機器によっては制御パケットとして認識されてしまう  ・そのため DSCP は 1-47 (48 から IP Precedence 部がフルビット)を色付け用として用いる 例: CLI IP: 124.0.124.100 VIP: 203.80.24.55 VM IP: 10.200.100.88 TOS: 32 TOS の値が 32 のときに VIP 宛の通信を reg0 に記録 ovs-ofctl add-flow br0 "table=0, priority=100, ip, nw_dst=10.200.100.88 actions=load:NXM_NX_IP_TOS[]->NXM_NX_REG0[], goto_table:1" reg0 が 32(TOS の値)のときに SRC IP を VIP に書き換える ovs-ofctl add-flow br0 "table=1, priority=110, ip, nw_src=10.200.100.88, reg0=0x20 actions=mod_nw_src:203.80.24.55, normal" ボツ DSCP bit と VIP の紐づけを管理するエージェントが必要 OVS の flow rule だけで実現する方法があるはず …!
  12. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 19 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: LB IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP
  13. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 20 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: LB IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP
  14. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 21 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP OVS br-int ovs2bpf bpf2ovs gre0 eBPF veth veth tap (1) ip_proto=4, src=LB_IP (2) eBPF で IPIP パケットを GRE パケットに変換、再送 (3) conntrack, ct_mark=0x04 を記録tun_src->reg0 (CLI_IP), tun_dst->reg1 (VIP_IP) SRC: CLI_IP, DST: VM_IP のパケットを action NORMAL に託す OVS に入ってくるパケット SRC IP: LB_IP DST IP: VM_IP inner SRC IP: CLI_IP inner DST IP: VIP_IP (4) 返りのパケットは SRC: VM_IP, DST: CLI_IP conntrack に載っている && ct_mark=0x04 のとき SRC IP を reg0 (VIP IP) に書き換え
  15. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 22 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP OVS br-int ovs2bpf bpf2ovs gre0 eBPF veth veth tap (1) ip_proto=4, src=LB_IP (2) eBPF で IPIP パケットを GRE パケットに変換、再送 (3) conntrack, ct_mark=0x04 を記録tun_src->reg0 (CLI_IP), tun_dst->reg1 (VIP_IP) SRC: CLI_IP, DST: VM_IP のパケットを action NORMAL に託す OVS に入ってくるパケット SRC IP: LB_IP DST IP: VM_IP inner SRC IP: CLI_IP inner DST IP: VIP_IP (4) 返りのパケットは SRC: VM_IP, DST: CLI_IP conntrack に載っている && ct_mark=0x04 のとき SRC IP を reg0 (VIP IP) に書き換え OVS の flow rule だけで完結して上手くいきそう …!
  16. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 23 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP OVS br-int ovs2bpf bpf2ovs gre0 eBPF veth veth tap (1) ip_proto=4, src=LB_IP (2) eBPF で IPIP パケットを GRE パケットに変換、再送 (3) conntrack, ct_mark=0x04 を記録tun_src->reg0 (CLI_IP), tun_dst->reg1 (VIP_IP) SRC: CLI_IP, DST: VM_IP のパケットを action NORMAL に託す OVS に入ってくるパケット SRC IP: LB_IP DST IP: VM_IP inner SRC IP: CLI_IP inner DST IP: VIP_IP (4) 返りのパケットは SRC: VM_IP, DST: CLI_IP conntrack に載っている && ct_mark=0x04 のとき SRC IP を reg0 (VIP IP) に書き換え OVS の flow rule だけで完結して上手くいきそう …! ボツ
  17. 第2稿: IPIP パターン ・IPIP であれば VIP の紐づけを管理しなくて良い…! 24 CLI ->

    LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP OVS br-int ovs2bpf bpf2ovs gre0 eBPF veth veth tap (1) ip_proto=4, src=LB_IP (2) eBPF で IPIP パケットを GRE パケットに変換、再送 (3) conntrack, ct_mark=0x04 を記録tun_src->reg0 (CLI_IP), tun_dst->reg1 (VIP_IP) SRC: CLI_IP, DST: VM_IP のパケットを action NORMAL に託す OVS に入ってくるパケット SRC IP: LB_IP DST IP: VM_IP inner SRC IP: CLI_IP inner DST IP: VIP_IP (4) 返りのパケットは SRC: VM_IP, DST: CLI_IP conntrack に載っている && ct_mark=0x04 のとき SRC IP を reg0 (VIP IP) に書き換え OVS の flow rule だけで完結して上手くいきそう …! ボツ GRE に変換するくらいなら最初から GRE 方式で送ればよい
  18. 第3稿: GRE パターン ・パケットの流れは IPIP とほぼ変わらない(IPIP -> GRE になる) 25

    CLI -> LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: LB IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP
  19. 第3稿: GRE パターン ・パケットの流れは IPIP とほぼ変わらない(IPIP -> GRE になる) 26

    CLI -> LB SRC IP: CLI IP DST IP: VIP LB -> OVS SRC IP: VIP IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP OVS -> VM SRC IP: CLI IP DST IP: VM IP VM -> OVS SRC IP: VM IP DST IP: CLI IP OVS -> CLI SRC IP: VIP DST IP: CLI IP LB Client OVS Server (1) SRC IP: CLI IP DST IP: VIP (2) SRC IP: LB IP DST IP: VM IP inner SRC IP: CLI IP inner DST IP: VIP IP (3) SRC IP: CLI IP DST IP: VM IP (4) SRC IP: VM IP DST IP: CLI IP (5) SRC IP: VIP DST IP: CLI IP
  20. 第3稿: GRE パターン 27 OVS br-phy br-dsr br-ext bond0 (1)

    GRE かつ LB IP の場合 decap アクションで GRE decap ip_proto=47, src=LB_IP, actions=decap (2) conntrack zone=47, VIP を CT_MARK に記録 move:NXM_OF_IP_DST[]->NXM_NX_CT_LABEL[0..31] (3) conntrack zone=47 のものの IP SRC を CT_MARK に記録していた VIP に書き換え move:NXM_NX_CT_LABEL[0..31]->NXM_OF_IP_SRC[]
  21. 第3稿: GRE パターン 28 OVS br-phy br-dsr br-ext bond0 (1)

    GRE かつ LB IP の場合 decap アクションで GRE decap ip_proto=47, src=LB_IP, actions=decap (2) conntrack zone=47, VIP を CT_MARK に記録 move:NXM_OF_IP_DST[]->NXM_NX_CT_LABEL[0..31] (3) conntrack zone=47 のものの IP SRC を CT_MARK に記録していた VIP に書き換え move:NXM_NX_CT_LABEL[0..31]->NXM_OF_IP_SRC[] 机上では上手く行きそう …!
  22. 第3稿: GRE パターン 29 OVS br-phy br-dsr br-ext bond0 (1)

    GRE かつ LB IP の場合 decap アクションで GRE decap ip_proto=47, src=LB_IP, actions=decap (2) conntrack zone=47, VIP を CT_MARK に記録 move:NXM_OF_IP_DST[]->NXM_NX_CT_LABEL[0..31] (3) conntrack zone=47 のものの IP SRC を CT_MARK に記録していた VIP に書き換え move:NXM_NX_CT_LABEL[0..31]->NXM_OF_IP_SRC[] 机上では上手く行きそう …! ボツ
  23. 第3稿: GRE パターン 30 OVS br-phy br-dsr br-ext bond0 (1)

    GRE かつ LB IP の場合 decap アクションで GRE decap ip_proto=47, src=LB_IP, actions=decap (2) conntrack zone=47, VIP を CT_MARK に記録 move:NXM_OF_IP_DST[]->NXM_NX_CT_LABEL[0..31] (3) conntrack zone=47 のものの IP SRC を CT_MARK に記録していた VIP に書き換え move:NXM_NX_CT_LABEL[0..31]->NXM_OF_IP_SRC[] 机上では上手く行きそう …! ボツ GRE のパケットがマッチしていない cookie=0x0, duration=586.160s, table=0, n_packets=0, n_bytes=0, priority=200,ip,in_port="dsr-dhcp",nw_src=10.255.4.0/22,nw_proto=47 actions=decap(),ct(table=1,zone=10)
  24. 第3稿: GRE パターン 31 OVS br-phy br-dsr br-ext bond0 (1)

    GRE かつ LB IP の場合 decap アクションで GRE decap ip_proto=47, src=LB_IP, actions=decap (2) conntrack zone=47, VIP を CT_MARK に記録 move:NXM_OF_IP_DST[]->NXM_NX_CT_LABEL[0..31] (3) conntrack zone=47 のものの IP SRC を CT_MARK に記録していた VIP に書き換え move:NXM_NX_CT_LABEL[0..31]->NXM_OF_IP_SRC[] 机上では上手く行きそう …! ボツ OpenvSwitch で GRE は decap アクションで decap できない GRE のパケットがマッチしていない cookie=0x0, duration=586.160s, table=0, n_packets=0, n_bytes=0, priority=200,ip,in_port="dsr-dhcp",nw_src=10.255.4.0/22,nw_proto=47 actions=decap(),ct(table=1,zone=10)
  25. 第N稿: GRE パターン 32 OVS br-phy br-dsr br-ext bond0 gre0

    (1) GRE を OVS の正攻法で decap type=gre options:remote_ip=flow (2) VIP を CT_MARK に格納、SRC: CLI_IP に書き換え move:NXM_NX_TUN_IPV4_DST[]->NXM_NX_CT_MARK[] move:NXM_NX_TUN_IPV4_SRC[]->NXM_OF_IP_SRC[] (3) CT_MARK が空でないときに CT_MARK に格納した VIP を SRC IP に書き換え move:NXM_NX_CT_MARK[]->NXM_OF_IP_SRC[]
  26. 第N稿: GRE パターン 33 OVS br-phy br-dsr br-ext bond0 gre0

    (1) GRE を OVS の正攻法で decap type=gre options:remote_ip=flow (2) VIP を CT_MARK に格納、SRC: CLI_IP に書き換え move:NXM_NX_TUN_IPV4_DST[]->NXM_NX_CT_MARK[] move:NXM_NX_TUN_IPV4_SRC[]->NXM_OF_IP_SRC[] (3) CT_MARK が空でないときに CT_MARK に格納した VIP を SRC IP に書き換え move:NXM_NX_CT_MARK[]->NXM_OF_IP_SRC[] さすがに上手く行きそう …!
  27. 第N稿: GRE パターン 34 OVS br-phy br-dsr br-ext bond0 gre0

    (1) GRE を OVS の正攻法で decap type=gre options:remote_ip=flow (2) VIP を CT_MARK に格納、SRC: CLI_IP に書き換え move:NXM_NX_TUN_IPV4_DST[]->NXM_NX_CT_MARK[] move:NXM_NX_TUN_IPV4_SRC[]->NXM_OF_IP_SRC[] (3) CT_MARK が空でないときに CT_MARK に格納した VIP を SRC IP に書き換え move:NXM_NX_CT_MARK[]->NXM_OF_IP_SRC[] さすがに上手く行きそう …! ボツ
  28. 第N稿: GRE パターン 35 OVS br-phy br-dsr br-ext bond0 gre0

    (1) GRE を OVS の正攻法で decap type=gre options:remote_ip=flow (2) VIP を CT_MARK に格納、SRC: CLI_IP に書き換え move:NXM_NX_TUN_IPV4_DST[]->NXM_NX_CT_MARK[] move:NXM_NX_TUN_IPV4_SRC[]->NXM_OF_IP_SRC[] (3) CT_MARK が空でないときに CT_MARK に格納した VIP を SRC IP に書き換え move:NXM_NX_CT_MARK[]->NXM_OF_IP_SRC[] さすがに上手く行きそう …! ボツ OpenvSwitch の GRE はトンネリング以外の用途では 上手く decap しないしログにも吐かない
  29. 決定稿: GRE パターン 37 OVS br-phy br-dsr br-ext bond0 veth_rewrite

    veth_decap eBPF (1) ip_proto=47, src=LB_IP (2) GRE と Outer IP ヘッダを decap src MAC の 6 byte のうち 4 byte に VIP のアドレスを格納 本来は pkt_mark 領域に記録したかったが veth から OVS に入ってくるところでその情報が 落ちてしまっており、利用できなかった (3) conntrack の zone=47 の CT_MARK(conntrack mark)の 32 bit に src MAC に書き込んだ VIP のアドレスを記録 ct(commit,zone=47,exec(move:NXM_OF_ETH_SRC[0..31]->NXM_NX_CT_MARK[])) (4) VM のレスポンスパケットで conntrack zone=47 move:NXM_NX_CT_MARK[]->NXM_OF_IP_SRC[] を行い、SRC: VIP_IP, DST: CLI_IP のパケットに書き換える
  30. 性能評価 ・Apache Bench で評価  ・1127.08 req/sec  ・99%ile 157 ms ※この測定後、すぐに環境を壊すことになったので

     負荷を上げた試験やさらに深い試験は実施できず…  負荷はかなり余裕があったので、10倍以上は食えるように見えた  (PMD thread や CPU usage) 38 ・OVS  ・w/ dpdk  ・bridge type: netdev
  31. 大切な教訓 ・OpenvSwitch の GRE 処理はクセが強い  ・今回は制御しきれず eBPF に逃がした ・OpenvSwitch で複雑なパケット処理を行いたい場合は

     flow rule だけで無理せず eBPF に逃がすことを検討するべき ・複雑なパケット処理を行う場合、TCP ヘッダまでであれば  eBPF は高速に処理することができる 39
  32. まとめ ・透過 L3DSR を OpenvSwitch の flow rule + eBPF

    で実現  ・設定を同期する agent などは不要 ・パフォーマンスも 1Kpps 程度までは問題ないことを確認  ・この10倍程度は少なくとも処理できそう ・今後 L3DSR を使うことがあれば積極的に採用したい 41