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

L2 WireGuard

Fadis
July 10, 2021

L2 WireGuard

次世代VPN WireGuardを改造して作ったL2VPN、L2 WireGuardの話をします
これは2021年7月10日に行われた カーネル/VM探検隊 online part3での発表動画です

参考文献
発表動画: https://youtu.be/8UIieDEk5k8
WireGuard自体のプロトコルについて: https://speakerdeck.com/fadis/zuo-tuteli-jie-suruwireguard
ソースコード: https://github.com/Fadis/l2wg

Fadis

July 10, 2021
Tweet

More Decks by Fadis

Other Decks in Programming

Transcript

  1. NAOMASA MATSUBAYASHI
    Twitter: @fadis_
    https://github.com/Fadis/l2wg
    αϯϓϧίʔυ
    L2 WireGuard

    View Slide

  2. WireGuard
    ࣍ੈ୅VPN
    https://www.wireguard.com/

    View Slide

  3. WireGuard
    ࣍ੈ୅VPN
    https://www.wireguard.com/
    ϝοηʔδ4छྨ͚ͩͷ
    ۃΊͯγϯϓϧͳ
    ϓϩτίϧ
    0x01 Handshake Initiation
    0x02 Handshake Response
    0x03 Cookie Reply
    0x04 Transport Data

    View Slide

  4. WireGuard
    ࣍ੈ୅VPN
    https://www.wireguard.com/
    ΞλοΫαʔϑΣεΛ࠷খԽ
    ࠷খݶͷ௨৴ͷΦʔόʔϔου
    શͯΛΧʔωϧۭؒͰ࣮૷
    ϝοηʔδ4छྨ͚ͩͷ
    ۃΊͯγϯϓϧͳ
    ϓϩτίϧ
    ݕূ͠΍͍͢؆ૉͳίʔυ

    View Slide

  5. WireGuard
    ࣍ੈ୅VPN
    https://www.wireguard.com/
    ݎ࿚
    ߴ଎
    ΞλοΫαʔϑΣεΛ࠷খԽ
    ࠷খݶͷ௨৴ͷΦʔόʔϔου
    શͯΛΧʔωϧۭؒͰ࣮૷
    छྨ͚ͩͷ
    ϓϧͳ
    ίϧ
    ݕূ͠΍͍͢؆ૉͳίʔυ

    View Slide

  6. WireGuard ͷܽ఺
    L3 VPNઐ༻

    View Slide

  7. L3 VPN





    ηάϝϯτ
    192.168.0.0/24
    ηάϝϯτ
    192.168.1.0/24
    ηάϝϯτ 192.168.2.0/30
    ϧʔςΟϯά ϧʔςΟϯά

    View Slide

  8. L2 VPN




    ηάϝϯτ 192.168.0.0/24

    View Slide

  9. ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚6%1
    ηογϣϯ૚0QFO71/
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚6%1
    ηογϣϯ૚0QFO71/
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    σʔλϦϯΫ૚&UIFSOFU
    VPNΛ௨Βͳ͍௨৴ OpenVPNͷL3 VPN OpenVPNͷL2 VPN
    OpenVPNͷ৔߹
    ͕͜͜૿͑ͨ

    View Slide

  10. ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚6%1
    ηογϣϯ૚0QFO71/
    σʔλϦϯΫ૚111P&
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    Ethernetʹ৐Δ෺͸ԿͰ΋৐ΔͷͰ͜͏͍͏ࣄΛͯ͠΋ྑ͍
    ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚6%1
    ηογϣϯ૚0QFO71/
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    σʔλϦϯΫ૚&UIFSOFU
    ͕͜͜૿͑ͨ
    OpenVPNͷL2 VPN

    View Slide

  11. ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    ෺ཧ૚3+#BTF59
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚6%1
    ηογϣϯ૚8JSF(VBSE
    ωοτϫʔΫ૚*1
    τϥϯεϙʔτ૚5$1
    ηογϣϯ૚)551
    VPNΛ௨Βͳ͍௨৴ WireGuard
    WireGuardͷ৔߹ WireGuardͷ
    ্ʹ৐Δϓϩτίϧ͸
    IPv4·ͨ͸
    IPv6Ͱͳ͚Ε͹
    ͳΒͳ͍
    Կނ?
    Ethernet͸
    ৐ͤΒΕͳ͍

    View Slide

  12. Poly1305͸128bitΛ1ϒϩοΫͱͯ͠ϋογϡΛܭࢉ͢Δ
    CJU CJU CJU CJU

    ϋογϡ

    View Slide

  13. 45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37
    ฏจͷύέοτ௕͕128bitͷ੔਺ഒʹͳ͍ͬͯͳ͍৔߹

    View Slide

  14. 45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37
    45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 00 00 00 00 00 00 00 00 00 00 00 00
    ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ...
    ҉߸Խ
    ฏจͷύέοτ௕͕128bitͷ੔਺ഒʹͳ͍ͬͯͳ͍৔߹
    ύσΟϯάΛ௥Ճͯ͠128bitͷ੔਺ഒʹ͢Δ

    View Slide

  15. ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ...
    ҉߸Խ
    45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 00 00 00 00 00 00 00 00 00 00 00 00
    ෮߸
    ΋ͱͷύέοτͷ௕͕͞Θ͔ΒΜ

    View Slide

  16. 45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 00 00 00 00 00 00 00 00 00 00 00 00
    ෮߸
    WireGuardͰ҉߸Խ͞Ε͍ͯΔ෺͕
    IPv4ͷύέοτͰ͋Δ৔߹
    ͜ͷ෦෼ʹ͸ઈରʹIPϔομ͕ೖ͍ͬͯΔ

    View Slide

  17. 45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 00 00 00 00 00 00 00 00 00 00 00 00
    ͭ·Γ͜ͷ෦෼ʹ͸ઈରʹIPϔομͷύέοτ௕͕ೖ͍ͬͯΔ

    View Slide

  18. 45 00 00 54 4e 68 00 00 40 01 72 ec c0 a8 9c 02
    c0 a8 9c 01 00 00 ca 3e 00 02 00 01 3c 6b a5 60
    00 00 00 00 8c 1f 09 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 00 00 00 00 00 00 00 00 00 00 00 00
    ύέοτ௕͕0x0054ͳͷͰ
    ͜͜·Ͱ͕΋ͱͷύέοτͰ͋Δࣄ͕Θ͔Δ

    View Slide

  19. 60 0a f8 fd 00 40 3a 40 fe 80 00 00 00 00 00 00
    00 00 00 00 00 00 12 35 fe 80 00 00 00 00 00 00
    00 00 00 00 00 00 12 34 80 00 fa a3 00 04 00 19
    1e 81 a6 60 00 00 00 00 d6 a4 09 00 00 00 00 00
    10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
    30 31 32 33 34 35 36 37 00 00 00 00 00 00 00 00
    ϖΠϩʔυ௕͕0x0040ͳͷͰϔομ0x28όΠτͱ߹Θͤͯ
    ͜͜·Ͱ͕΋ͱͷύέοτͰ͋Δࣄ͕Θ͔Δ
    IPv6Ͱ΋

    View Slide

  20. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ͜ͷMACΞυϨε΁ ͜ͷMACΞυϨε͔Β IPv4Λ
    ͔͜͜Βઌ͸IPv4
    EthernetϑϨʔϜʹ͸ύέοτ௕ͷ৘ใ͕ͳ͍ͷͰ
    ΋ͱͷύέοτͷ௕͕͞෼͔Βͳ͘ͳΔ

    View Slide

  21. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ΋ͱͷύέοτͷ௕͕͞෼͔Βͳ͘ͳΔ
    ∴WireGuard͸
    ύέοτͷ௕͞ΛऔΕΔIPv4·ͨ͸IPv6ͷύέοτ͕
    ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍

    View Slide

  22. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ΋ͱͷύέοτͷ௕͕͞෼͔Βͳ͘ͳΔ
    ∴WireGuard͸
    ύέοτͷ௕͞ΛऔΕΔIPv4·ͨ͸IPv6ͷύέοτ͕
    ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍
    ຊ౰ʹ෼͔Βͳ͍ͩΖ͏͔

    View Slide

  23. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    EthernetϑϨʔϜ IPϔομ
    ηογϣϯ૚8JSF(VBSE
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    WireGuardͷ্ͷ্ʹ৐͍ͬͯΔͷ͕IPͷ৔߹
    EthernetϑϨʔϜͷޙΖʹ͋Δͷ͸IPϔομ

    View Slide

  24. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    IPϔομ
    ηογϣϯ૚8JSF(VBSE
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    WireGuardͷ্ͷ্ʹ৐͍ͬͯΔͷ͕IPͷ৔߹
    EthernetϑϨʔϜͷޙΖʹ͋Δͷ͸IPϔομ
    ͳΒ͜͜ʹ͋Δͷ͸ύέοτ௕Ͱ͸?

    View Slide

  25. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 08 00 45 00
    00 54 36 06 40 00 40 01 49 4e c0 a8 9d 01 c0 a8
    9d 02 08 00 d7 14 00 04 00 01 ef 95 a6 60 00 00
    00 00 be 1c 0e 00 00 00 00 00 10 11 12 13 14 15
    16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
    26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
    36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    IPϔομ
    ηογϣϯ૚8JSF(VBSE
    σʔλϦϯΫ૚&UIFSOFU
    ωοτϫʔΫ૚*1
    WireGuardͷ্ͷ্ʹ৐͍ͬͯΔͷ͕IPͷ৔߹
    ͳΒ͜͜ʹ͋Δͷ͸ύέοτ௕Ͱ͸?
    ͍͚Δؾ͕͢Δ
    EthernetϑϨʔϜͷޙΖʹ͋Δͷ͸IPϔομ

    View Slide

  26. static void wg_setup(struct net_device *dev)
    {
    struct wg_device *wg = netdev_priv(dev);
    enum { WG_NETDEV_FEATURES = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
    NETIF_F_SG | NETIF_F_GSO |
    NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA };
    const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
    max(sizeof(struct ipv6hdr), sizeof(struct iphdr));
    dev->netdev_ops = &netdev_ops;
    dev->header_ops = &ip_tunnel_header_ops;
    dev->hard_header_len = 0;
    dev->addr_len = 0;
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->type = ARPHRD_NONE;
    dev->flags = IFF_POINTOPOINT | IFF_NOARP;
    dev->priv_flags |= IFF_NO_QUEUE;
    Linux༻ͷWireGuardͷιʔε͸linux-5.6Ҏ߱ͷ
    drivers/net/wireguardҎԼʹશͯೖ͍ͬͯΔ

    View Slide

  27. const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
    max(sizeof(struct ipv6hdr), sizeof(struct iphdr));
    dev->netdev_ops = &netdev_ops;
    dev->header_ops = &ip_tunnel_header_ops;
    dev->hard_header_len = 0;
    dev->addr_len = 0;
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->type = ARPHRD_NONE;
    dev->flags = IFF_POINTOPOINT | IFF_NOARP;
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    dev->hw_enc_features |= WG_NETDEV_FEATURES;
    dev->mtu = ETH_DATA_LEN - overhead;
    dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
    SET_NETDEV_DEVTYPE(dev, &device_type);
    /* We need to keep the dst around in case of icmp replies. */
    ৽͍͠ωοτϫʔΫσόΠεͷ࡞੒෦෼
    ϋʔυ΢ΣΞͷϔομͷ௕͞͸0όΠτͰ
    ϋʔυ΢ΣΞͷΞυϨεͷ௕͞΋0όΠτ
    ϋʔυ΢ΣΞͷϔομͷܗࣜ͸NONE
    Point to PointͳωοτϫʔΫͰ͋Γ
    ARPʹΑΔΞυϨεղܾ͸ඞཁͳ͍
    ͜ͷΑ͏ͳઃఆͰσόΠε͕࡞ΒΕ͍ͯΔͨΊ

    View Slide

  28. const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
    max(sizeof(struct ipv6hdr), sizeof(struct iphdr));
    dev->netdev_ops = &netdev_ops;
    dev->header_ops = &ip_tunnel_header_ops;
    dev->hard_header_len = 0;
    dev->addr_len = 0;
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->type = ARPHRD_NONE;
    dev->flags = IFF_POINTOPOINT | IFF_NOARP;
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    dev->hw_enc_features |= WG_NETDEV_FEATURES;
    dev->mtu = ETH_DATA_LEN - overhead;
    dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
    SET_NETDEV_DEVTYPE(dev, &device_type);
    /* We need to keep the dst around in case of icmp replies. */
    ৽͍͠ωοτϫʔΫσόΠεͷ࡞੒෦෼
    ͜ͷΑ͏ͳઃఆͰσόΠε͕࡞ΒΕ͍ͯΔͨΊ
    6: wg0: mtu 1420 qdisc noqueue state
    UNKNOWN mode DEFAULT group default qlen 1000
    link/none
    WireGuardͷσόΠεʹ͸MACΞυϨε͕ͳ͍
    LinuxͷωοτϫʔΫελοΫ͸
    ͜͏ͨ͠ઃఆͷσόΠε͔ΒύέοτΛૹΔ৔߹
    ϋʔυ΢ΣΞͷϔομΛ෇͚ͣʹ
    network_header(≒IPϔομ)Ҏ͔߱͠ͳ͍sk_buffΛ౉ͯ͘͠Δ
    ·ͣ͸Զ͸EthernetͩͱΧʔωϧʹओு͢Δඞཁ͕͋Δ

    View Slide

  29. static void l2wg_setup(struct net_device *dev)
    {
    struct wg_device *wg = netdev_priv(dev);
    enum { WG_NETDEV_FEATURES = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
    NETIF_F_SG | NETIF_F_GSO |
    NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA };
    const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
    max(sizeof(struct ipv6hdr), sizeof(struct iphdr)) +
    ETH_HLEN;
    dev->netdev_ops = &l2netdev_ops;
    dev->header_ops = &ip_tunnel_header_ops;
    ether_setup( dev );
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    wg_setupΛมߋͨ͠l2wg_setupΛ༻ҙ

    View Slide

  30. dev->header_ops = &ip_tunnel_header_ops;
    ether_setup( dev );
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    dev->hw_enc_features |= WG_NETDEV_FEATURES;
    dev->mtu = ETH_DATA_LEN - overhead;
    dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
    SET_NETDEV_DEVTYPE(dev, &device_type);
    * We need to keep the dst around in case of icmp replies. */
    netif_keep_dst(dev);
    memset(wg, 0, sizeof(*wg));
    wg->dev = dev;
    wg->l2 = true;
    wg->allowedips_lookup_src = l2wg_allowedips_lookup_src;
    void ether_setup(struct net_device *dev)
    {
    dev->header_ops = &eth_header_ops;
    dev->type = ARPHRD_ETHER;
    dev->hard_header_len = ETH_HLEN;
    dev->min_header_len = ETH_HLEN;
    dev->mtu = ETH_DATA_LEN;
    dev->min_mtu = ETH_MIN_MTU;
    dev->max_mtu = ETH_DATA_LEN;
    dev->addr_len = ETH_ALEN;
    dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
    dev->flags = IFF_BROADCAST|IFF_MULTICAST;
    dev->priv_flags |= IFF_TX_SKB_SHARING;
    eth_broadcast_addr(dev->broadcast);
    }
    net/ethernet/eth.c
    Զ͸Ethernetͩ

    View Slide

  31. enum { WG_NETDEV_FEATURES = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
    NETIF_F_SG | NETIF_F_GSO |
    NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA };
    const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
    max(sizeof(struct ipv6hdr), sizeof(struct iphdr)) +
    ETH_HLEN;
    dev->netdev_ops = &l2netdev_ops;
    dev->header_ops = &ip_tunnel_header_ops;
    ether_setup( dev );
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    dev->hw_enc_features |= WG_NETDEV_FEATURES;
    dev->mtu = ETH_DATA_LEN - overhead;
    dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
    SET_NETDEV_DEVTYPE(dev, &device_type);
    ͜ͷΠϯλʔϑΣʔεͷMTUΛ
    WireGuard͕ݩʑ࢖͏෼+Ethernetϔομ͕ࡌΔ෼͚ͩݮΒ͢

    View Slide

  32. static struct rtnl_link_ops link_ops __read_mostly = {
    .kind = KBUILD_MODNAME,
    .priv_size = sizeof(struct wg_device),
    .setup = wg_setup,
    .newlink = wg_newlink,
    };
    static struct rtnl_link_ops l2link_ops __read_mostly = {
    .kind = "l2" KBUILD_MODNAME,
    .priv_size = sizeof(struct wg_device),
    .setup = l2wg_setup,
    .newlink = wg_newlink,
    };
    L3༻
    L2༻
    l2wireguard ͱ͍͏໊લͷσόΠεΛ࡞Δͱ
    wg_setupʹมߋΛՃ͑ͨ
    l2wg_setup͕ݺ͹ΕΔΑ͏ʹ͓ͯ͘͠

    View Slide

  33. static const struct net_device_ops netdev_ops = {
    .ndo_open = wg_open,
    .ndo_stop = wg_stop,
    .ndo_start_xmit = wg_xmit,
    .ndo_get_stats64 = dev_get_tstats64
    };
    static const struct net_device_ops l2netdev_ops = {
    .ndo_open = wg_open,
    .ndo_stop = wg_stop,
    .ndo_start_xmit = wg_xmit,
    .ndo_get_stats64 = dev_get_tstats64,
    .ndo_set_mac_address = eth_mac_addr,
    .ndo_validate_addr = eth_validate_addr
    };
    L3༻
    L2༻
    MACΞυϨεΛ࣋ͭEthernetσόΠεͳͷͰ
    MACΞυϨεͷมߋΛड͚෇͚ΔΑ͏ʹ͓ͯ͘͠

    View Slide

  34. $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.1/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    7: wg1: mtu 1406 qdisc noqueue state
    UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 02:ca:fe:f0:0e:04 brd ff:ff:ff:ff:ff:ff
    ࣗশEthernetͷWireGuardσόΠε͕ੜ͑ͨ
    l2wiregardσόΠεΛ࡞Δ
    ΧʔωϧΛϏϧυͯ͠ىಈ͠

    View Slide

  35. PING 192.168.157.2 (192.168.157.2) 56(84) bytes of data.
    From 192.168.157.1 icmp_seq=1 Destination Host Unreachable
    --- 192.168.157.2 ping statistics ---
    1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
    wireguard: wg1: Invalid IP packet
    ͔͠͠ping͸௨Βͳ͍
    ࣗশEthernetͷWireGuardσόΠε͕ੜ͑ͨ
    ʮෆਖ਼ͳIPύέοτʯ
    ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

    View Slide

  36. wireguard: wg1: Invalid IP packet
    ʮෆਖ਼ͳIPύέοτʯ
    static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev)
    {
    struct wg_device *wg = netdev_priv(dev);
    struct sk_buff_head packets;
    struct wg_peer *peer;
    struct sk_buff *next;
    sa_family_t family;
    u32 mtu;
    int ret;
    if (unlikely(!wg_check_packet_protocol(skb))) {
    ret = -EPROTONOSUPPORT;
    net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name);
    goto err;
    }
    drivers/net/wireguard/device.c
    ͜ͷ෼ذʹೖͬͯ
    ͜Ε͕ग़͍ͯΔ
    ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

    View Slide

  37. static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev)
    {
    struct wg_device *wg = netdev_priv(dev);
    struct sk_buff_head packets;
    struct wg_peer *peer;
    struct sk_buff *next;
    sa_family_t family;
    u32 mtu;
    int ret;
    if (unlikely(!wg_check_packet_protocol(skb))) {
    ret = -EPROTONOSUPPORT;
    net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name);
    goto err;
    }
    drivers/net/wireguard/device.c
    wireguard: wg1: Invalid IP packet
    ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ
    ʮෆਖ਼ͳIPύέοτʯ
    static inline bool wg_check_packet_protocol(struct sk_buff *skb)
    {
    __be16 real_protocol = ip_tunnel_parse_protocol(skb);
    return real_protocol && skb->protocol == real_protocol;
    }
    drivers/net/wireguard/queueing.h

    View Slide

  38. static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev)
    {
    struct wg_device *wg = netdev_priv(dev);
    struct sk_buff_head packets;
    struct wg_peer *peer;
    struct sk_buff *next;
    sa_family_t family;
    u32 mtu;
    int ret;
    if (unlikely(!wg_check_packet_protocol(skb))) {
    ret = -EPROTONOSUPPORT;
    net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name);
    goto err;
    }
    drivers/net/wireguard/device.c
    wireguard: wg1: Invalid IP packet
    ʮෆਖ਼ͳIPύέοτʯ
    static inline bool wg_check_packet_protocol(struct sk_buff *skb)
    {
    __be16 real_protocol = ip_tunnel_parse_protocol(skb);
    return real_protocol && skb->protocol == real_protocol;
    }
    drivers/net/wireguard/queueing.h
    __be16 ip_tunnel_parse_protocol(const struct sk_buff *skb)
    {
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct iphdr)) <= skb_tail_pointer(skb) &&
    ip_hdr(skb)->version == 4)
    return htons(ETH_P_IP);
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct ipv6hdr)) <= skb_tail_pointer(skb) &&
    ipv6_hdr(skb)->version == 6)
    return htons(ETH_P_IPV6);
    return 0;
    }
    net/ipv4/ip_tunnel_core.c
    ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

    View Slide

  39. __be16 ip_tunnel_parse_protocol(const struct sk_buff *skb)
    {
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct iphdr)) <= skb_tail_pointer(skb) &&
    ip_hdr(skb)->version == 4)
    return htons(ETH_P_IP);
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct ipv6hdr)) <= skb_tail_pointer(skb) &&
    ipv6_hdr(skb)->version == 6)
    return htons(ETH_P_IPV6);
    return 0;
    }
    net/ipv4/ip_tunnel_core.c
    IPv4ϔομͷversion͕4ͳΒETH_P_IPΛ
    IPv6ϔομͷversion͕6ͳΒETH_P_IPV6Λฦ͢
    IPv4Ͱ΋IPv6Ͱ΋ͳ͍Կ͔Λඈ͹ͦ͏ͱ͍ͯ͠Δ

    View Slide

  40. __be16 ip_tunnel_parse_protocol(const struct sk_buff *skb)
    {
    skb_dump( KERN_WARNING, skb, false );
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct iphdr)) <= skb_tail_pointer(skb) &&
    ip_hdr(skb)->version == 4)
    return htons(ETH_P_IP);
    if (skb_network_header(skb) >= skb->head &&
    (skb_network_header(skb) + sizeof(struct ipv6hdr)) <= skb_tail_pointer(skb) &&
    ipv6_hdr(skb)->version == 6)
    return htons(ETH_P_IPV6);
    return 0;
    }
    net/ipv4/ip_tunnel_core.c
    μϯϓͯ͠ΈΑ͏
    ff ff ff ff ff ff 02 ca fe f0 0e 04 08 06 00 01
    08 00 06 04 00 01 02 ca fe f0 0e 04 c0 a8 9d 01
    00 00 00 00 00 00 c0 a8 9d 02

    View Slide

  41. ff ff ff ff ff ff 02 ca fe f0 0e 04 08 06 00 01
    08 00 06 04 00 01 02 ca fe f0 0e 04 c0 a8 9d 01
    00 00 00 00 00 00 c0 a8 9d 02
    EthernetϑϨʔϜ proto: 0x0806
    ͜Ε͸
    ͦ͏͍͑͹IP͡Όͳ͔ͬͨ
    ARP
    ARPͱ͸: Address Resolution ProtocolɻωοτϫʔΫ૚ͷ͋ΔΞυϨε
    (͜ͷ৔߹IPΞυϨε)ΛͲͷϋʔυ΢ΣΞ͕͍࣋ͬͯΔ͔Λ໰͍߹ΘͤΔ

    View Slide

  42. dev->header_ops = &ip_tunnel_header_ops;
    ether_setup( dev );
    dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
    dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE);
    dev->priv_flags |= IFF_NO_QUEUE;
    dev->features |= NETIF_F_LLTX;
    dev->features |= WG_NETDEV_FEATURES;
    dev->hw_features |= WG_NETDEV_FEATURES;
    dev->hw_enc_features |= WG_NETDEV_FEATURES;
    dev->mtu = ETH_DATA_LEN - overhead;
    dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
    SET_NETDEV_DEVTYPE(dev, &device_type);
    * We need to keep the dst around in case of icmp replies. */
    netif_keep_dst(dev);
    memset(wg, 0, sizeof(*wg));
    wg->dev = dev;
    wg->l2 = true;
    wg->allowedips_lookup_src = l2wg_allowedips_lookup_src;
    void ether_setup(struct net_device *dev)
    {
    dev->header_ops = &eth_header_ops;
    dev->type = ARPHRD_ETHER;
    dev->hard_header_len = ETH_HLEN;
    dev->min_header_len = ETH_HLEN;
    dev->mtu = ETH_DATA_LEN;
    dev->min_mtu = ETH_MIN_MTU;
    dev->max_mtu = ETH_DATA_LEN;
    dev->addr_len = ETH_ALEN;
    dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
    dev->flags = IFF_BROADCAST|IFF_MULTICAST;
    dev->priv_flags |= IFF_TX_SKB_SHARING;
    eth_broadcast_addr(dev->broadcast);
    }
    net/ethernet/eth.c
    Զ͸Ethernetͩ
    Χʔωϧ͕ARPͰ
    pingઌͷIPΞυϨεΛ࣋ͭ௨৴૬खΛ୳͠ʹ͖͍ͯΔ
    ͜ͷσόΠε͸Ethernet
    (=ಉ͡ηάϝϯτʹෳ਺ͷ௨৴૬ख͕ଘࡏͰ͖ͯɺϒϩʔυΩϟετ͕͋Δ)
    ͩͱΧʔωϧʹ఻͑ͨͷͰ

    View Slide

  43. static inline bool wg_check_packet_protocol(struct sk_buff *skb)
    {
    __be16 real_protocol = ip_tunnel_parse_protocol(skb);
    return real_protocol && skb->protocol == real_protocol;
    }
    drivers/net/wireguard/queueing.h
    static inline bool wg_check_packet_protocol(struct sk_buff *skb)
    {
    if( skb->mac_header == skb->network_header ) {
    __be16 real_protocol = ip_tunnel_parse_protocol(skb);
    return real_protocol && skb->protocol == real_protocol;
    }
    else {
    __be16 real_protocol = eth_hdr( skb )->h_proto;
    return real_protocol && skb->protocol == real_protocol;
    }
    }
    drivers/net/wireguard/queueing.h
    EthernetϑϨʔϜ͕͋ͬͨΒͦͪΒͷprotoΛ༏ઌ
    ARP͕௨ΕΔΑ͏ʹ͢Δඞཁ͕͋Δ

    View Slide

  44. struct wg_peer *wg_allowedips_lookup_dst(struct allowedips *table,
    struct sk_buff *skb)
    {
    if (skb->protocol == htons(ETH_P_IP))
    return lookup(table->root4, 32, &ip_hdr(skb)->daddr);
    else if (skb->protocol == htons(ETH_P_IPV6))
    return lookup(table->root6, 128, &ipv6_hdr(skb)->daddr);
    return NULL;
    }
    struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table,
    struct sk_buff *skb)
    {
    if (skb->protocol == htons(ETH_P_IP))
    return lookup(table->root4, 32, &ip_hdr(skb)->saddr);
    else if (skb->protocol == htons(ETH_P_IPV6))
    return lookup(table->root6, 128, &ipv6_hdr(skb)->saddr);
    return NULL;
    drivers/net/wireguard/allowedips.c
    WireGuard͸ૹ৴࣌ٴͼड৴࣌ʹύέοτͷૹ৴ઌΞυϨε͕
    ڐՄ͞ΕͨΞυϨεͰ͋ΔࣄΛ֬ೝ͍ͯ͠Δ

    View Slide

  45. struct wg_peer *l2wg_allowedips_lookup_dst(struct allowedips *table,
    struct sk_buff *skb)
    {
    static const __be16 dummy = 0;
    if (skb->protocol == htons(ETH_P_IP))
    return lookup(table->root4, 32, &ip_hdr(skb)->daddr);
    else if (skb->protocol == htons(ETH_P_IPV6))
    return lookup(table->root6, 128, &ipv6_hdr(skb)->daddr);
    return lookup(table->root4, 32, &dummy);
    }
    struct wg_peer *l2wg_allowedips_lookup_src(struct allowedips *table,
    struct sk_buff *skb)
    {
    static const __be16 dummy = 0;
    if (skb->protocol == htons(ETH_P_IP))
    return lookup(table->root4, 32, &ip_hdr(skb)->saddr);
    else if (skb->protocol == htons(ETH_P_IPV6))
    return lookup(table->root6, 128, &ipv6_hdr(skb)->saddr);
    return lookup(table->root4, 32, &dummy);
    drivers/net/wireguard/allowedips.c
    ΞυϨεͷͳ͍ύέοτ͸0.0.0.0͕ڐՄ͞Ε͍ͯΕ͹௨Δࣄʹ͢Δ

    View Slide

  46. if (skb->protocol == htons(ETH_P_IP)) {
    if(ip_hdr(skb)->version != 4)
    return false;
    if (unlikely(!(pskb_network_may_pull(skb, sizeof(struct iphdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof( struct iphdr ) );
    }
    else if (skb->protocol == htons(ETH_P_IPV6)) {
    if(ipv6_hdr(skb)->version != 6)
    return false;
    if (unlikely(!(pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof( struct ipv6hdr ) );
    }
    else if (skb->protocol == htons(ETH_P_ARP)) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct arphdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof( struct arphdr ) );
    }
    else if (skb->protocol == htons(ETH_P_RARP)) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct arphdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof( struct arphdr ) );
    গͳ͘ͱ΋ϔομαΠζҎ্ͷ௕͕͋͞ΔࣄΛ֬ೝ͢Δ෦෼
    ARPͱ
    RARPͷ
    ৔߹Λ
    ௥Ճ

    View Slide

  47. unsigned int l2wg_get_packet_length(
    struct sk_buff *skb
    ) {
    unsigned int len;
    u8 slow_sub_type
    u8 *cur;
    unsigned int tlv_type;
    unsigned int tlv_length;
    if (skb->protocol == htons(ETH_P_IP)) {
    len = ntohs(ip_hdr(skb)->tot_len);
    if (unlikely(len < sizeof(struct iphdr)))
    return 0u;
    INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ip_hdr(skb)->tos);
    } else if (skb->protocol == htons(ETH_P_IPV6)) {
    len = ntohs(ipv6_hdr(skb)->payload_len) +
    sizeof(struct ipv6hdr);
    INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ipv6_get_dsfield(ipv6_hdr(skb)));
    } else if (skb->protocol == htons(ETH_P_ARP)) {
    len = sizeof( struct arphdr ) + arp_hdr(skb)->ar_hln * 2 + arp_hdr(skb)->ar_pln * 2;
    } else if (skb->protocol == htons(ETH_P_RARP)) {
    len = sizeof( struct arphdr ) + arp_hdr(skb)->ar_hln * 2 + arp_hdr(skb)->ar_pln * 2;
    } else {
    return 0u;
    }
    return len;
    IPϔομ͔Β΋ͱͷύέοτͷ௕͞ΛऔΓग़͢෦෼
    ARPͱRARPͷ௕͞ΛٻΊΔॲཧΛ௥Ճ

    View Slide

  48. $ ip link
    ...
    7: wg1: mtu 1406 qdisc noqueue state
    UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 02:ca:fe:f0:0e:04 brd ff:ff:ff:ff:ff:ff
    $ ip addr
    ...
    7: wg1: mtu 1406 qdisc noqueue state
    UNKNOWN group default qlen 1000
    link/ether 02:ca:fe:f0:0e:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.157.1/24 scope global wg1
    valid_lft forever preferred_lft forever
    $ ping 192.168.157.2 -c 3
    PING 192.168.157.2 (192.168.157.2) 56(84) bytes of data.
    64 bytes from 192.168.157.2: icmp_seq=1 ttl=64 time=0.355 ms
    64 bytes from 192.168.157.2: icmp_seq=2 ttl=64 time=0.466 ms
    64 bytes from 192.168.157.2: icmp_seq=3 ttl=64 time=94.4 ms
    --- 192.168.157.2 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2081ms
    rtt min/avg/max/mdev = 0.355/31.729/94.367/44.291 ms
    ಈ͍ͨ!

    View Slide

  49. L2 WireGuard͸EthernetσόΠεͳͷͰ
    IEEE 802.1d MAC Bridgesʹ૊ΈࠐΊΔ

    View Slide


  50. Ethernet
    L2 WireGuard
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ ip link set enp0s3 up
    $ brctl addbr br0
    $ brctl addif br0 wg1
    $ brctl addif br0 enp0s3
    $ ip link set dev br0 address 0e:0c:c4:16:d3:ac
    $ ip address add dev br0 192.168.157.1/24
    $ ip link set br0 up $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.2/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up

    View Slide


  51. Ethernet
    L2 WireGuard
    $ ping 192.168.157.2 -c 3
    PING 192.168.157.2 (192.168.157.2) 56(84) bytes of data.
    64 bytes from 192.168.157.2: icmp_seq=1 ttl=64 time=1.42 ms
    64 bytes from 192.168.157.2: icmp_seq=2 ttl=64 time=0.760 ms
    64 bytes from 192.168.157.2: icmp_seq=3 ttl=64 time=0.654 ms
    --- 192.168.157.2 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2048ms
    rtt min/avg/max/mdev = 0.654/0.944/1.419/0.338 ms
    ping

    View Slide


  52. Ethernet
    L2 WireGuard
    $ ping 192.168.157.3 -c 3
    PING 192.168.157.3 (192.168.157.3) 56(84) bytes of data.
    64 bytes from 192.168.157.3: icmp_seq=1 ttl=64 time=0.497 ms
    64 bytes from 192.168.157.3: icmp_seq=2 ttl=64 time=0.619 ms
    64 bytes from 192.168.157.3: icmp_seq=3 ttl=64 time=0.779 ms
    --- 192.168.157.3 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2065ms
    rtt min/avg/max/mdev = 0.497/0.631/0.779/0.115 ms
    ping

    View Slide

  53. IPͰͳ͍෺ΛӡͿ

    View Slide

  54. AppleTalk
    ଠݹͷϚοΩϯτογϡͰ࢖ΘΕ͍ͯͨ௨৴ϓϩτίϧ
    Ethernet
    Ethernet্Ͱ
    DDPͱݺ͹ΕΔIPͰ͸ͳ͍ύέοτΛ౤͛߹͏

    ηάϝϯτ 65364

    View Slide

  55. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 80 f3 00 01
    80 9b 06 04 00 03 00 0c 29 0d 56 e3 00 ff 54 44
    00 00 00 00 00 00 00 ff 54 44
    EthernetϑϨʔϜ
    AARPϔομ
    IPʹ͓͚ΔARPʹ૬౰͢Δ΋ͷ
    ௕͞͸28όΠτݻఆ

    Ͱ͢
    Λ࢖͍ͬͯΔਓ
    ฦࣄ͍ͯͩ͘͠͞
    ΞυϨεͷҰҙੑΛ֬ೝ

    AppleTalk AARP
    proto: 0x80f3

    View Slide

  56. } else if (skb->protocol == htons(ETH_P_AARP)) {
    len = sizeof( struct elapaarp );
    }
    } else if (skb->protocol == htons(ETH_P_AARP)) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct elapaarp))) ) )
    return false;
    skb_set_transport_header( skb, ETH_HLEN );
    }
    drivers/net/wireguard/receive.c
    drivers/net/wireguard/receive.c
    IPʹ͓͚ΔARPʹ૬౰͢Δ΋ͷ
    ௕͞͸28όΠτݻఆ
    গͳ͘ͱ΋28όΠτಡΊΔ͜ͱΛ֬ೝ
    AppleTalk AARP
    AARPͩͬͨΒύέοτͷ௕͞͸ৗʹ28Λฦ͢

    View Slide

  57. AARPͰΞυϨεΛղܾͨ͠Β
    DDPͰσʔλΛ౤͛߹͏
    02 ca fe f0 0e 05 02 ca fe f0 0e 04 80 9b 00 54
    00 00 00 00 ff 54 ff 44 02 fe 02 21 01 ff 54 44
    fe 00 20 30 41 45 30 34 39 36 30 33 30 44 42 43
    34 30 34 31 38 30 30 41 44 43 44 30 34 37 40 4d
    4f 52 4f 1c 4d 69 63 72 6f 73 6f 66 74 a8 20 57
    69 6e 64 6f 77 73 20 32 30 30 30 aa 20 50 72 74
    01 2a
    EthernetϑϨʔϜ proto: 0x809b
    DDPϔομ
    AppleTalk DDP
    ͔͜͜ΒϖΠϩʔυ

    View Slide

  58. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 80 9b 00 54
    00 00 00 00 ff 54 ff 44 02 fe 02 21 01 ff 54 44
    fe 00 20 30 41 45 30 34 39 36 30 33 30 44 42 43
    34 30 34 31 38 30 30 41 44 43 44 30 34 37 40 4d
    4f 52 4f 1c 4d 69 63 72 6f 73 6f 66 74 a8 20 57
    69 6e 64 6f 77 73 20 32 30 30 30 aa 20 50 72 74
    01 2a
    EthernetϑϨʔϜ proto: 0x809b
    DDPϔομ
    AppleTalk DDP
    ͔͜͜ΒϖΠϩʔυ
    ͜͜ͷԼҐ10bitʹDDPϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ

    View Slide

  59. } else if (skb->protocol == htons(ETH_P_ATALK)) {
    len = ( ntohs( ddp_hdr( skb )->deh_len_hops ) & 0x3FFu );
    }
    } else if (skb->protocol == htons(ETH_P_ATALK)) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct ddpehdr))) ) )
    return false;
    skb_set_transport_header( skb, 0 );
    }
    drivers/net/wireguard/receive.c
    drivers/net/wireguard/receive.c
    গͳ͘ͱ΋DDPϔομΛಡΊΔ௕͞͸͋Δ͜ͱΛ֬ೝ
    DDPϔομͷύέοτ௕Λ࢖ͬͯύέοτͷ௕͞Λऔಘ
    AppleTalk DDP

    View Slide

  60. L2 WireGuard
    AppleTalkͷωοτϫʔΫΛ༻ҙ͢Δͷ͕͠ΜͲ͍
    WireSharkͷެࣜαΠτʹ͋Δ
    AppleTalkͷ௨৴ͷΩϟϓνϟ͕ྲྀΕΔ͜ͱΛ֬ೝ͢Δ



    View Slide

  61. $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    L2 WireGuard



    View Slide

  62. $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length
    262144 bytes
    19:20:38.450039 aarp probe 65364.68 tell 65364.68
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 80f3 0001
    0x0010: 809b 0604 0003 000c 290d 56e3 00ff 5444
    0x0020: 0000 0000 0000 00ff 5444 0000 0000 0000
    0x0030: 0000 0000 0000 0000 0000 0000
    $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length
    262144 bytes
    19:20:38.608877 aarp probe 65364.68 tell 65364.68
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 80f3 0001
    0x0010: 809b 0604 0003 000c 290d 56e3 00ff 5444
    0x0020: 0000 0000 0000 00ff 5444 0000 0000 0000
    0x0030: 0000 0000 0000 0000 0000 0000
    ૹ৴ଆ ड৴ଆ
    AARP

    View Slide

  63. $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    19:26:52.975014 et1 AT 65364.68.254 > 0.nis: nbp-lkup 1:
    "[email protected]:MicrosoftM-( Windows 2000M-* [email protected]*"
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 809b 0054
    0x0010: 0000 0000 ff54 ff44 02fe 0221 01ff 5444
    0x0020: fe00 2030 4145 3034 3936 3033 3044 4243
    0x0030: 3430 3431 3830 3041 4443 4430 3437 404d
    0x0040: 4f52 4f1c 4d69 6372 6f73 6f66 74a8 2057
    0x0050: 696e 646f 7773 2032 3030 30aa 2050 7274
    0x0060: 012a
    $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    19:26:53.139155 et1 AT 65364.68.254 > 0.nis: nbp-lkup 1:
    "[email protected]:MicrosoftM-( Windows 2000M-* [email protected]*"
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 809b 0054
    0x0010: 0000 0000 ff54 ff44 02fe 0221 01ff 5444
    0x0020: fe00 2030 4145 3034 3936 3033 3044 4243
    0x0030: 3430 3431 3830 3041 4443 4430 3437 404d
    0x0040: 4f52 4f1c 4d69 6372 6f73 6f66 74a8 2057
    0x0050: 696e 646f 7773 2032 3030 30aa 2050 7274
    0x0060: 012a
    ૹ৴ଆ ड৴ଆ
    DDP

    View Slide

  64. IPX
    Novell NetWareͰ࢖ΘΕͨଠݹͷ௨৴ϓϩτίϧ
    Ethernet
    Ethernet্Ͱ
    IPXͱݺ͹ΕΔIPͰ͸ͳ͍ύέοτΛ౤͛߹͏
    DBGFGF DBGFGF
    ηάϝϯτ 00000000

    View Slide

  65. IPX
    02 ca fe f0 0e 05 02 ca fe f0 0e 04 81 37 ff ff
    00 28 00 01 00 00 00 00 ff ff ff ff ff ff 04 53
    00 00 00 00 00 0c 29 0d 56 e3 04 53 00 01 ff ff
    ff ff ff ff ff ff
    EthernetϑϨʔϜ proto: 0x8137
    IPXϔομ
    ͔͜͜ΒϖΠϩʔυ

    View Slide

  66. IPX
    02 ca fe f0 0e 05 02 ca fe f0 0e 04 81 37 ff ff
    00 28 00 01 00 00 00 00 ff ff ff ff ff ff 04 53
    00 00 00 00 00 0c 29 0d 56 e3 04 53 00 01 ff ff
    ff ff ff ff ff ff
    EthernetϑϨʔϜ proto: 0x8137
    IPXϔομ
    ͔͜͜ΒϖΠϩʔυ
    ͜͜ʹIPXϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ

    View Slide

  67. IPX
    } else if (skb->protocol == htons(ETH_P_IPX)) {
    len = ntohs(((struct ipxhdr*)skb_network_header(skb))->ipx_pktsize);
    }
    } else if (skb->protocol == htons(ETH_P_IPX)) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof( struct ipxhdr ) )) ) )
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof( struct ipxhdr ) );
    }
    drivers/net/wireguard/receive.c
    drivers/net/wireguard/receive.c
    গͳ͘ͱ΋IPXϔομҎ্ͷ௕͕͋͞ΔࣄΛ֬ೝ
    IPXϔομͷύέοτ௕Λ࢖ͬͯύέοτͷ௕͞Λऔಘ

    View Slide

  68. $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    L2 WireGuard



    AppleTalkಉ༷ɺύέοτΩϟϓνϟ͕ྲྀΕΔࣄΛ֬ೝ͢Δ

    View Slide

  69. $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144
    bytes
    02:05:20.314064 (NOV-ETHII) IPX 00000000.00:0c:29:0d:56:e3.0453 >
    00000000.ff:ff:ff:ff:ff:ff.0453: ipx-rip-req ffffffff/65535.65535
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8137 ffff
    0x0010: 0028 0001 0000 0000 ffff ffff ffff 0453
    0x0020: 0000 0000 000c 290d 56e3 0453 0001 ffff
    0x0030: ffff ffff ffff 0000 0000 0000
    $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144
    bytes
    02:05:20.522479 (NOV-ETHII) IPX 00000000.00:0c:29:0d:56:e3.0453 >
    00000000.ff:ff:ff:ff:ff:ff.0453: ipx-rip-req ffffffff/65535.65535
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8137 ffff
    0x0010: 0028 0001 0000 0000 ffff ffff ffff 0453
    0x0020: 0000 0000 000c 290d 56e3 0453 0001 ffff
    0x0030: ffff ffff ffff 0000 0000 0000
    ૹ৴ଆ ड৴ଆ
    IPX

    View Slide

  70. IEEE 802.3x PAUSEϑϨʔϜ
    όοϑΝ͕ᷓΕͦ͏ͳػث͕
    ௨৴૬खʹରͯ͠ૹ৴ͷҰ࣌ఀࢭΛٻΊΔ
    0e 92 48 84 72 3d 02 ca fe f0 0e 05 88 08 00 01
    ff ff
    EthernetϑϨʔϜ proto: 0x8808
    0xffff bitૹΕͨഺͷ͚࣌ؒͩૹ৴ΛఀࢭͤΑ
    × 512
    L2 WireGuardࣗମ͸
    PAUSEϑϨʔϜΛड͚෇͚ΔΑ͏ʹ͍ͯ͠ͳ͍͕
    ผͷػث΁ͷPAUSEϑϨʔϜ͸ਖ਼ৗʹதܧ͍ͨ͠

    View Slide

  71. unsigned int l2wg_get_packet_length(
    struct sk_buff *skb
    ) {
    ...
    else if (skb->protocol == htons(ETH_P_PAUSE)) {
    if( unlikely(!(pskb_network_may_pull(skb, 4))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + 4 );
    }
    ...
    }
    ...
    bool l2wg_check_packet_length_internal(
    struct sk_buff *skb, struct net_device *dev
    ) {
    ...
    } else if (skb->protocol == htons(ETH_P_PAUSE)) {
    len = 4u;
    }
    ...
    drivers/net/wireguard/receive.c
    PAUSEϑϨʔϜ͸ৗʹEthernetϑϨʔϜ+4όΠτ

    View Slide


  72. L2 WireGuard
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.2/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.1/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ ./send_pause -i wg1 -d 02:ca:fe:f0:0e:05

    View Slide

  73. $ ip address add dev wg1 192.168.157.2/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.1/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ ./send_pause -i wg1 -d 02:ca:fe:f0:0e:05
    $ tcpdump -i wg1 -xx
    dropped privs to pcap
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    01:33:29.278202 MPCP, Opcode Pause, length 60
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8808 0001
    0x0010: ffff 0000 0000 0000 0000 0000 0000 0000
    0x0020: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0030: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0040: 0000 0000 0000 0000 0000

    View Slide

  74. RFC2516 PPPoE
    Ethernet্ͰPPPΛ஻Δ
    02 ca fe f0 0e 04 02 ca fe f0 0e 05 88 64 11 00
    00 02 00 56 00 21 45 00 00 54 03 84 40 00 40 01
    77 d0 c0 a8 9f 02 c0 a8 9f 01 08 00 c5 cf 00 04
    00 01 01 89 aa 60 00 00 00 00 be 6e 09 00 00 00
    00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d
    1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d
    2e 2f 30 31 32 33 34 35 36 37
    EthernetϑϨʔϜ
    IPv4
    IPv4Ͱ ͔͜͜Βઌ͸IPv4
    PPPoEϔομ
    proto: 0x8864

    View Slide

  75. Ethernet্ͰPPPΛ஻Δ
    02 ca fe f0 0e 04 02 ca fe f0 0e 05 88 64 11 00
    00 02 00 56 00 21 45 00 00 54 03 84 40 00 40 01
    77 d0 c0 a8 9f 02 c0 a8 9f 01 08 00 c5 cf 00 04
    00 01 01 89 aa 60 00 00 00 00 be 6e 09 00 00 00
    00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d
    1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d
    2e 2f 30 31 32 33 34 35 36 37
    EthernetϑϨʔϜ
    ϖΠϩʔυ௕: 0x0056
    PPPoEϔομ
    RFC2516 PPPoE

    View Slide

  76. ) {
    ...
    } else if (skb->protocol == htons(ETH_P_PPP_DISC)) {
    len = sizeof( struct pppoe_hdr ) + ntohs( pppoe_hdr( skb )->length );
    } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
    len = sizeof( struct pppoe_hdr ) + ntohs( pppoe_hdr( skb )->length );
    }
    ...
    }
    ...
    bool l2wg_check_packet_length_internal(
    struct sk_buff *skb, struct net_device *dev
    ) {
    ...
    } else if (skb->protocol == htons(ETH_P_PPP_DISC)) {
    if(unlikely(!(pskb_network_may_pull(skb, sizeof(struct pppoe_hdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof(struct pppoe_hdr));
    } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
    if(unlikely(!(pskb_network_may_pull(skb, sizeof(struct pppoe_hdr)))))
    return false;
    skb_set_transport_header( skb, ETH_HLEN + sizeof(struct pppoe_hdr));
    }
    ...
    PPPoEϔομͷϖΠϩʔυ௕Λ࢖༻

    View Slide

  77. L2 WireGuard
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ pppoe-start
    $ ping 192.168.159.1 -c 1
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ pppoe-server -I wg1 -L 192.168.159.1 \
    -R 192.168.159.2 -k -O /etc/ppp/options
    ping

    View Slide

  78. $ tcpdump -i wg1 -xx
    dropped privs to pcap
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    01:48:17.081620 PPPoE PADI [Service-Name] [Host-Uniq "15a"]
    0x0000: ffff ffff ffff 02ca fef0 0e05 8863 1109
    0x0010: 0000 000b 0101 0000 0103 0003 3135 6100
    0x0020: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0030: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0040: 0000 0000 0000 0000 0000
    01:48:17.081656 PPPoE PADO [AC-Name "l2wg0"] [Service-Name "hoge"] [AC-
    Cookie 0xD84292E67FF33DD9C1C08C985E1C49C7D8000000
    ] [Host-Uniq "15a"]
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8863 1107
    0x0010: 0000 0030 0102 0005 6c32 7767 3001 0100
    0x0020: 0468 6f67 6501 0400 14d8 4292 e67f f33d
    0x0030: d9c1 c08c 985e 1c49 c7d8 0000 0001 0300
    0x0040: 0331 3561
    01:48:17.082205 PPPoE PADR [Service-Name] [Host-Uniq "15a"] [AC-Cookie
    0xD84292E67FF33DD9C1C08C985E1C49C7D8000000]
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8863 1119

    View Slide

  79. 0x0010: 0000 0023 0101 0000 0103 0003 3135 6101
    0x0020: 0400 14d8 4292 e67f f33d d9c1 c08c 985e
    0x0030: 1c49 c7d8 0000 0000 0000 0000 0000 0000
    0x0040: 0000 0000 0000 0000 0000
    01:48:17.082371 PPPoE PADS [ses 0x2] [Service-Name "hoge"] [Host-Uniq
    "15a"]
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8863 1165
    0x0010: 0002 000f 0101 0004 686f 6765 0103 0003
    0x0020: 3135 61
    01:48:17.119340 PPPoE [ses 0x2] LCP, Conf-Request (0x01), id 1, length 20
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8864 1100
    0x0010: 0002 0014 c021 0101 0012 0104 0576 0304
    0x0020: c023 0506 46de 052f
    01:48:17.120245 PPPoE [ses 0x2] LCP, Conf-Request (0x01), id 1, length 16
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8864 1100
    0x0010: 0002 0010 c021 0101 000e 0104 05d4 0506
    0x0020: 4a8c e1ed 0000 0000 0000 0000 0000 0000
    0x0030: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0040: 0000 0000 0000 0000 0000
    01:48:17.120246 PPPoE [ses 0x2] LCP, Conf-Ack (0x02), id 1, length 20
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8864 1100

    View Slide

  80. 01:55:30.177099 PPPoE [ses 0x2] IP 192.168.159.2 > 192.168.159.1: ICMP
    echo request, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8864 1100
    0x0010: 0002 0056 0021 4500 0054 0384 4000 4001
    0x0020: 77d0 c0a8 9f02 c0a8 9f01 0800 c5cf 0004
    0x0030: 0001 0189 aa60 0000 0000 be6e 0900 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    01:55:30.177117 PPPoE [ses 0x2] IP 192.168.159.1 > 192.168.159.2: ICMP
    echo reply, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8864 1100
    0x0010: 0002 0056 0021 4500 0054 863c 0000 4001
    0x0020: 3518 c0a8 9f01 c0a8 9f02 0000 cdcf 0004
    0x0030: 0001 0189 aa60 0000 0000 be6e 0900 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637

    View Slide

  81. 0x0020: 77d0 c0a8 9f02 c0a8 9f01 0800 c5cf 0004
    0x0030: 0001 0189 aa60 0000 0000 be6e 0900 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    01:55:30.177117 PPPoE [ses 0x2] IP 192.168.159.1 > 192.168.159.2: ICMP
    echo reply, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8864 1100
    0x0010: 0002 0056 0021 4500 0054 863c 0000 4001
    0x0020: 3518 c0a8 9f01 c0a8 9f02 0000 cdcf 0004
    0x0030: 0001 0189 aa60 0000 0000 be6e 0900 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    PING 192.168.159.1 (192.168.159.1) 56(84) bytes of data.
    64 bytes from 192.168.159.1: icmp_seq=1 ttl=64 time=0.429 ms
    --- 192.168.159.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.429/0.429/0.429/0.000 ms

    View Slide

  82. 802.1q VLAN Tagging
    ෺ཧతʹ1ͭͷηάϝϯτΛ
    Ծ૝తʹෳ਺ͷಠཱͨ͠ηάϝϯτʹݟ͔͚ͤΔ


    ෺ཧతͳ઀ଓ

    View Slide

  83. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 81 00 00 80
    08 00 45 00 00 54 d4 96 40 00 40 01 a8 bd c0 a8
    9e 01 c0 a8 9e 02 08 00 33 a5 00 04 00 01 6e 46
    ad 60 00 00 00 00 e6 db 03 00 00 00 00 00 10 11
    12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21
    22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
    32 33 34 35 36 37
    EthernetϑϨʔϜ proto: 0x8100
    VLANϔομ
    802.1q VLAN Tagging

    View Slide

  84. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 81 00 00 80
    08 00 45 00 00 54 d4 96 40 00 40 01 a8 bd c0 a8
    9e 01 c0 a8 9e 02 08 00 33 a5 00 04 00 01 6e 46
    ad 60 00 00 00 00 e6 db 03 00 00 00 00 00 10 11
    12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21
    22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
    32 33 34 35 36 37
    EthernetϑϨʔϜ VLANϔομ
    IPv4Ͱ ͔͜͜Βઌ͸IPv4
    λάͷޙΖʹprotoͱͦͷ಺༰͕ೖ͍ͬͯΔ
    λάͷޙΖͷ৘ใͰύέοτ௕Λऔಘ͠ͳ͓ͤ͹ྑ͍

    View Slide

  85. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 a8 00 80
    81 00 00 7f 08 00 45 00 00 54 a6 f7 40 00 40 01
    d4 5c c0 a8 9f 01 c0 a8 9f 02 08 00 bf 74 00 03
    00 01 28 91 ae 60 00 00 00 00 9c c2 06 00 00 00
    00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d
    1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d
    2e 2f 30 31 32 33 34 35 36 37
    2ஈ໨ͷ
    VLANϔομ
    1ஈ໨ͷ
    VLANϔομ
    EthernetϑϨʔϜ
    802.1ad QinQ
    λάVLANͷதʹλάVLANΛ࡞ΕΔΑ͏ʹ͢Δ

    View Slide

  86. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 a8 00 80
    81 00 00 7f 08 00 45 00 00 54 a6 f7 40 00 40 01
    d4 5c c0 a8 9f 01 c0 a8 9f 02 08 00 bf 74 00 03
    00 01 28 91 ae 60 00 00 00 00 9c c2 06 00 00 00
    00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d
    1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d
    2e 2f 30 31 32 33 34 35 36 37
    802.1ad QinQ
    2ஈ໨ͷ
    VLANϔομ
    1ஈ໨ͷ
    VLANϔομ
    ͔͜͜Βઌ͸IPv4
    IPv4Ͱ
    VLANͰͳ͍ϓϩτίϧʹḷΓண͘·Ͱ4όΠτͮͭಡΈඈ͹ͤ͹
    IPϔομʹͨͲΓண͖ύέοτ௕͕औΕΔ
    EthernetϑϨʔϜ

    View Slide

  87. } else if (
    skb->protocol == htons(ETH_P_8021Q) ||
    skb->protocol == htons(ETH_P_8021AD) ||
    skb->protocol == htons(ETH_P_QINQ1) ||
    skb->protocol == htons(ETH_P_QINQ2) ||
    skb->protocol == htons(ETH_P_QINQ3)
    ) {
    if( unlikely(!(pskb_network_may_pull(
    skb, sizeof(struct vlan_hdr)
    )) ) )
    return false;
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct vlan_hdr*)skb_network_header( skb ))->
    h_vlan_encapsulated_proto;
    skb->network_header += sizeof( struct vlan_hdr );;
    skb->data += sizeof( struct vlan_hdr );;
    skb->len -= sizeof( struct vlan_hdr );;
    valid = l2wg_check_packet_length_internal( skb, dev, true );
    skb->network_header -= sizeof( struct vlan_hdr );;
    skb->data -= sizeof( struct vlan_hdr );;
    drivers/net/wireguard/receive.c

    View Slide

  88. } else if (
    skb->protocol == htons(ETH_P_8021Q) ||
    skb->protocol == htons(ETH_P_8021AD) ||
    skb->protocol == htons(ETH_P_QINQ1) ||
    skb->protocol == htons(ETH_P_QINQ2) ||
    skb->protocol == htons(ETH_P_QINQ3)
    ) {
    if( unlikely(!(pskb_network_may_pull(
    skb, sizeof(struct vlan_hdr)
    )) ) )
    return false;
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct vlan_hdr*)skb_network_header( skb ))->
    h_vlan_encapsulated_proto;
    skb->network_header += sizeof( struct vlan_hdr );;
    skb->data += sizeof( struct vlan_hdr );;
    skb->len -= sizeof( struct vlan_hdr );;
    valid = l2wg_check_packet_length_internal( skb, dev, true );
    skb->network_header -= sizeof( struct vlan_hdr );;
    skb->data -= sizeof( struct vlan_hdr );;
    skb->len += sizeof( struct vlan_hdr );;
    • 802.1q
    • 802.1ad
    • 802.1ad͕ඪ४Խ͞ΕΔલʹ࢖ΘΕ͍ͯͨඇඪ४ͷtype
    ͷ͍ͣΕ͔͕protocolʹઃఆ͞Ε͍ͯͨΒ

    View Slide

  89. ) {
    if( unlikely(!(pskb_network_may_pull(
    skb, sizeof(struct vlan_hdr)
    )) ) )
    return false;
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct vlan_hdr*)skb_network_header( skb ))->
    h_vlan_encapsulated_proto;
    skb->network_header += sizeof( struct vlan_hdr );;
    skb->data += sizeof( struct vlan_hdr );;
    skb->len -= sizeof( struct vlan_hdr );;
    valid = l2wg_check_packet_length_internal( skb, dev, true );
    skb->network_header -= sizeof( struct vlan_hdr );;
    skb->data -= sizeof( struct vlan_hdr );;
    skb->len += sizeof( struct vlan_hdr );;
    skb->protocol = vlan_protocol;
    if( !wrapped )
    skb_set_transport_header( skb, ETH_HLEN );
    return valid;
    }
    গͳ͘ͱ΋4όΠτ(VLANϔομͷαΠζ)෼ಡΊΔ͜ͱΛ֬ೝ

    View Slide

  90. return false;
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct vlan_hdr*)skb_network_header( skb ))->
    h_vlan_encapsulated_proto;
    skb->network_header += sizeof( struct vlan_hdr );;
    skb->data += sizeof( struct vlan_hdr );;
    skb->len -= sizeof( struct vlan_hdr );;
    valid = l2wg_check_packet_length_internal( skb, dev, true );
    skb->network_header -= sizeof( struct vlan_hdr );;
    skb->data -= sizeof( struct vlan_hdr );;
    skb->len += sizeof( struct vlan_hdr );;
    skb->protocol = vlan_protocol;
    if( !wrapped )
    skb_set_transport_header( skb, ETH_HLEN );
    return valid;
    }
    VLANϔομʹઃఆ͞ΕͨprotocolΛskbͷprotocolʹઃఆ͠
    ωοτϫʔΫϔομͷ։࢝ҐஔΛ4όΠτޙΖʹͣΒͯ͠
    ύέοτ௕ͷνΣοΫΛ࠶ؼݺͼग़͠

    View Slide

  91. )) ) )
    return false;
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct vlan_hdr*)skb_network_header( skb ))->
    h_vlan_encapsulated_proto;
    skb->network_header += sizeof( struct vlan_hdr );;
    skb->data += sizeof( struct vlan_hdr );;
    skb->len -= sizeof( struct vlan_hdr );;
    valid = l2wg_check_packet_length_internal( skb, dev, true );
    skb->network_header -= sizeof( struct vlan_hdr );;
    skb->data -= sizeof( struct vlan_hdr );;
    skb->len += sizeof( struct vlan_hdr );;
    skb->protocol = vlan_protocol;
    if( !wrapped )
    skb_set_transport_header( skb, ETH_HLEN );
    return valid;
    }
    ωοτϫʔΫϔομͷ։࢝ҐஔͱprotocolΛ໭ͯ͠
    VLANͷத਎ͷνΣοΫͷ݁ՌΛฦ͢

    View Slide


  92. L2 WireGuard
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.2/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add link wg1 name wg1.128 type vlan id 128
    $ ip address add dev wg1.128 192.168.158.2/24
    $ ip link set wg1.128 up
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.1/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ ./send_pause -i wg1 -d 02:ca:fe:f0:0e:05
    $ ip link add link wg1 name wg1.128 type vlan id 128
    $ ip address add dev wg1.128 192.168.158.1/24
    $ ip link set wg1.128 up

    VLAN 1ஈ

    View Slide

  93. $ tcpdump -i wg1 -xx
    dropped privs to pcap
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    22:31:09.368026 ARP, Request who-has 192.168.158.1 tell 192.168.158.2, length 28
    22:31:10.357841 IP 192.168.158.1 > 192.168.158.2: ICMP echo request, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8100 0080
    0x0010: 0800 4500 0054 f132 4000 4001 8c21 c0a8
    0x0020: 9e01 c0a8 9e02 0800 98d2 0004 0001 1e9f
    0x0030: af60 0000 0000 cf55 0300 0000 0000 1011
    0x0040: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
    0x0050: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
    0x0060: 3233 3435 3637
    22:31:10.357856 IP 192.168.158.2 > 192.168.158.1: ICMP echo reply, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8100 0080
    0x0010: 0800 4500 0054 fd10 0000 4001 c043 c0a8
    0x0020: 9e02 c0a8 9e01 0000 a0d2 0004 0001 1e9f
    0x0030: af60 0000 0000 cf55 0300 0000 0000 1011
    0x0040: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
    0x0050: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
    0x0060: 3233 3435 3637
    VLAN 1ஈ

    View Slide

  94. $ ping 192.168.158.2 -c 1
    PING 192.168.158.2 (192.168.158.2) 56(84) bytes of data.
    64 bytes from 192.168.158.2: icmp_seq=1 ttl=64 time=0.503 ms
    --- 192.168.158.2 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.503/0.503/0.503/0.000 ms
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8100 0080
    0x0010: 0800 4500 0054 f132 4000 4001 8c21 c0a8
    0x0020: 9e01 c0a8 9e02 0800 98d2 0004 0001 1e9f
    0x0030: af60 0000 0000 cf55 0300 0000 0000 1011
    0x0040: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
    0x0050: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
    0x0060: 3233 3435 3637
    22:31:10.357856 IP 192.168.158.2 > 192.168.158.1: ICMP echo reply, id 4, seq 1, length 64
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8100 0080
    0x0010: 0800 4500 0054 fd10 0000 4001 c043 c0a8
    0x0020: 9e02 c0a8 9e01 0000 a0d2 0004 0001 1e9f
    0x0030: af60 0000 0000 cf55 0300 0000 0000 1011
    0x0040: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
    0x0050: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
    0x0060: 3233 3435 3637

    View Slide


  95. L2 WireGuard
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.2/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add link wg1 name wg1.128 type vlan id 128
    $ ip address add dev wg1.128 192.168.158.2/24
    $ ip link set wg1.128 up
    $ ip link add link wg1.128 name wg1.128.127 type vlan id 127
    $ ip address add dev wg1.128.127 192.168.159.2/24
    $ ip link set wg1.128.127 up
    $ ip link add dev wg1 type l2wireguard
    $ ip address add dev wg1 192.168.157.1/24
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    $ ./send_pause -i wg1 -d 02:ca:fe:f0:0e:05
    $ ip link add link wg1 name wg1.128 type vlan id 128
    $ ip address add dev wg1.128 192.168.158.1/24
    $ ip link set wg1.128 up
    $ ip link add link wg1.128 name wg1.128.127 type vlan id 127
    $ ip address add dev wg1.128.127 192.168.159.1/24
    $ ip link set wg1.128.127 up

    VLAN 2ஈ

    View Slide

  96. $ tcpdump -i wg1 -xx
    dropped privs to pcap
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    22:33:11.737027 ARP, Request who-has 192.168.159.1 tell 192.168.159.2, length 28
    22:33:13.008611 IP 192.168.159.1 > 192.168.159.2: ICMP echo request, id 8, seq 1, length 64
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8100 0080
    0x0010: 8100 007f 0800 4500 0054 db50 4000 4001
    0x0020: a003 c0a8 9f01 c0a8 9f02 0800 e1de 0008
    0x0030: 0001 989f af60 0000 0000 0245 0d00 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    22:33:13.008626 IP 192.168.159.2 > 192.168.159.1: ICMP echo reply, id 8, seq 1, length 64
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8100 0080
    0x0010: 8100 007f 0800 4500 0054 9a6d 0000 4001
    0x0020: 20e7 c0a8 9f02 c0a8 9f01 0000 e9de 0008
    0x0030: 0001 989f af60 0000 0000 0245 0d00 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    VLAN 2ஈ

    View Slide

  97. $ ping 192.168.159.2 -c 1
    PING 192.168.159.2 (192.168.159.2) 56(84) bytes of data.
    64 bytes from 192.168.159.2: icmp_seq=1 ttl=64 time=0.435 ms
    --- 192.168.159.2 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.435/0.435/0.435/0.000 ms
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8100 0080
    0x0010: 8100 007f 0800 4500 0054 db50 4000 4001
    0x0020: a003 c0a8 9f01 c0a8 9f02 0800 e1de 0008
    0x0030: 0001 989f af60 0000 0000 0245 0d00 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637
    22:33:13.008626 IP 192.168.159.2 > 192.168.159.1: ICMP echo reply, id 8, seq 1, length 64
    0x0000: 02ca fef0 0e04 02ca fef0 0e05 8100 0080
    0x0010: 8100 007f 0800 4500 0054 9a6d 0000 4001
    0x0020: 20e7 c0a8 9f02 c0a8 9f01 0000 e9de 0008
    0x0030: 0001 989f af60 0000 0000 0245 0d00 0000
    0x0040: 0000 1011 1213 1415 1617 1819 1a1b 1c1d
    0x0050: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d
    0x0060: 2e2f 3031 3233 3435 3637

    View Slide

  98. IEEE 802.1ah Provider Backbone Bridges
    2ॏVLANͷ಺ଆʹMACΞυϨεΛ࣋ͨͤͯ
    ্ҐͷϒϦοδ͕຤୺ͷσόΠεͷ
    MACΞυϨεΛ஌Βͳͯ͘ྑ͘͢Δ

    View Slide

  99. ͔͜͜Βઌ͸IPv4
    IPv4Ͱ
    02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 a8 00 80
    88 e7 00 00 00 01 02 ca fe f0 0e 15 02 ca fe f0
    0e 14 08 00 00 01 45 00 00 54 a6 f7 40 00 40 01
    d4 5c c0 a8 9f 01 c0 a8 9f 02 08 00 bf 74 00 03
    00 01 28 91 ae 60 00 00 00 00 9c c2 06 00 00 00
    00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d
    1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d
    2e 2f 30 31 32 33 34 35 36 37
    EthernetϑϨʔϜ proto: 0x8100
    VLANϔομ
    proto: 0x88e7
    PBBϔομ

    View Slide

  100. struct ieee8021ah_hdr {
    __be32 itag;
    unsigned char h_dest[ETH_ALEN];
    unsigned char h_source[ETH_ALEN];
    __be16 h_proto;
    } __attribute__((packed));
    ...
    unsigned int l2wg_get_packet_length(
    struct sk_buff *skb
    ) {
    ...
    } else if ( skb->protocol == htons(ETH_P_8021AH) ) {
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct ieee8021ah_hdr*)skb_network_header( skb ))->h_proto;
    skb->network_header += sizeof( struct ieee8021ah_hdr );
    skb->data += sizeof( struct ieee8021ah_hdr );
    skb->len -= sizeof( struct ieee8021ah_hdr );
    len = l2wg_get_packet_length( skb );
    skb->network_header -= sizeof( struct ieee8021ah_hdr );
    skb->data -= sizeof( struct ieee8021ah_hdr );
    skb->len += sizeof( struct ieee8021ah_hdr );
    skb->protocol = vlan_protocol;
    drivers/net/wireguard/receive.c
    PBBϔομͷܕΛ༻ҙͯ͠

    View Slide

  101. __be32 itag;
    unsigned char h_dest[ETH_ALEN];
    unsigned char h_source[ETH_ALEN];
    __be16 h_proto;
    } __attribute__((packed));
    ...
    unsigned int l2wg_get_packet_length(
    struct sk_buff *skb
    ) {
    ...
    } else if ( skb->protocol == htons(ETH_P_8021AH) ) {
    vlan_protocol = skb->protocol;
    skb->protocol = ((struct ieee8021ah_hdr*)skb_network_header( skb ))->h_proto;
    skb->network_header += sizeof( struct ieee8021ah_hdr );
    skb->data += sizeof( struct ieee8021ah_hdr );
    skb->len -= sizeof( struct ieee8021ah_hdr );
    len = l2wg_get_packet_length( skb );
    skb->network_header -= sizeof( struct ieee8021ah_hdr );
    skb->data -= sizeof( struct ieee8021ah_hdr );
    skb->len += sizeof( struct ieee8021ah_hdr );
    skb->protocol = vlan_protocol;
    if( unlikely(!len) ) return 0u;
    len += sizeof( struct ieee8021ah_hdr );
    }
    PBBϔομΛݟ͚ͭͨΒ
    PBBϔομͷαΠζ෼ਐΜͩҐஔ͔Β
    ύέοτ௕ͷऔಘΛ΍Γ௚͢

    View Slide

  102. L2 WireGuard



    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    PBBΛ஻Δػث͕ແ͍ͷͰͦΕͬΆ͍ύέοτΛ፻଄ͯ͠ྲྀ͢

    View Slide

  103. $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    17:14:06.328029 02:ca:fe:f0:0e:04 (oui Unknown) > 02:ca:fe:f0:0e:05 (oui Unknown), ethertype
    Unknown (0x88e7), length 120:
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 88a8 0080
    0x0010: 88e7 0000 0001 02ca fef0 0e15 02ca fef0
    0x0020: 0e14 0800 4500 0054 a6f7 4000 4001 d45c
    0x0030: c0a8 9f01 c0a8 9f02 0800 bf74 0003 0001
    0x0040: 2891 ae60 0000 0000 9cc2 0600 0000 0000
    0x0050: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
    0x0060: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f
    0x0070: 3031 3233 3435 3637
    $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    17:14:06.529713 02:ca:fe:f0:0e:04 (oui Unknown) > 02:ca:fe:f0:0e:05 (oui Unknown), ethertype
    Unknown (0x88e7), length 120:
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 88a8 0080
    0x0010: 88e7 0000 0001 02ca fef0 0e15 02ca fef0
    0x0020: 0e14 0800 4500 0054 a6f7 4000 4001 d45c
    0x0030: c0a8 9f01 c0a8 9f02 0800 bf74 0003 0001
    0x0040: 2891 ae60 0000 0000 9cc2 0600 0000 0000
    0x0050: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
    0x0060: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f
    0x0070: 3031 3233 3435 3637
    ૹ৴ଆ ड৴ଆ
    PBB
    ਖ਼͘͠ಧ͍͍ͯΔ͕
    tcpdump͸͜ͷछͷύέοτΛ
    ύʔεͰ͖ͳ͍Β͍͠

    View Slide

  104. WireShark͸ύʔεग़དྷ͍ͯΔͷͰύέοτͷϑΥʔϚοτ͸ਖ਼ͦ͠͏

    View Slide

  105. L2 WireGuard
    L2 WireGuard
    802.3ad Link Aggregation Control Protocol(LACP)
    team
    ৑௕Խ΍ଳҬΛՔ͙໨తͰ
    ෳ਺ͷϦϯΫΛଋͶͯԾ૝తͳ1ͭͷϦϯΫ(team)ͱͯ͠࢖͏
    LACP͸ݸʑͷϦϯΫͷੜଘ֬ೝΛܧଓతʹߦ͍
    ௨৴Ͱ͖ͳ͘ͳͬͨϦϯΫΛteam͔Β֎͢
    team
    ͪ͜Β͚ͩΛ࢖ͬͯ
    ௨৴ΛܧଓͰ͖Δ

    View Slide

  106. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 09 01 01
    01 14 80 00 00 13 c4 12 0f 00 00 0d 80 00 00 16
    85 00 00 00 02 14 80 00 00 0e 83 16 f5 00 00 0d
    80 00 00 19 36 00 00 00 03 10 80 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00
    EthernetϑϨʔϜ proto: 0x8809
    LACP
    LACP͸ϓϩτίϧ൪߸0x8809 SLOW ProtocolͷҰछ

    View Slide

  107. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 09 01 01
    01 14 80 00 00 13 c4 12 0f 00 00 0d 80 00 00 16
    85 00 00 00 02 14 80 00 00 0e 83 16 f5 00 00 0d
    80 00 00 19 36 00 00 00 03 10 80 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00
    EthernetϑϨʔϜ proto: 0x8809
    LACP
    LACPͷύέοτ͸ෳ਺ͷνϟϯΫʹ෼͔Ε͍ͯΔ

    View Slide

  108. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 09 01 01
    01 14 80 00 00 13 c4 12 0f 00 00 0d 80 00 00 16
    85 00 00 00 02 14 80 00 00 0e 83 16 f5 00 00 0d
    80 00 00 19 36 00 00 00 03 10 80 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00
    νϟϯΫͷλΠϓ
    νϟϯΫͷ௕͞
    νϟϯΫͷઌ಄ʹ͸λΠϓͱ௕͕֤͞1όΠτͰೖ͍ͬͯΔ

    View Slide

  109. 02 ca fe f0 0e 05 02 ca fe f0 0e 04 88 09 01 01
    01 14 80 00 00 13 c4 12 0f 00 00 0d 80 00 00 16
    85 00 00 00 02 14 80 00 00 0e 83 16 f5 00 00 0d
    80 00 00 19 36 00 00 00 03 10 80 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00
    ऴ୺
    λΠϓ0x00ͷνϟϯΫͰऴ୺Λද͢
    ͦͷޙΖʹ͸Ұఆ਺ͷύσΟϯάΛೖΕΔࣄʹͳ͍ͬͯΔ

    View Slide

  110. typedef struct lacpdu {
    u8 subtype; /* = LACP(= 0x01) */
    u8 version_number;
    u8 tlv_type_actor_info; /* = actor information(type/length/value) */
    u8 actor_information_length; /* = 20 */
    __be16 actor_system_priority;
    struct mac_addr actor_system;
    __be16 actor_key;
    __be16 actor_port_priority;
    __be16 actor_port;
    u8 actor_state;
    u8 reserved_3_1[3]; /* = 0 */
    u8 tlv_type_partner_info; /* = partner information */
    u8 partner_information_length; /* = 20 */
    __be16 partner_system_priority;
    struct mac_addr partner_system;
    __be16 partner_key;
    __be16 partner_port_priority;
    __be16 partner_port;
    u8 partner_state;
    u8 reserved_3_2[3]; /* = 0 */
    u8 tlv_type_collector_info; /* = collector information */
    u8 collector_information_length;/* = 16 */
    __be16 collector_max_delay;
    u8 reserved_12[12];
    u8 tlv_type_terminator; /* = terminator */
    u8 terminator_length; /* = 0 */
    u8 reserved_50[50]; /* = 0 */
    } __packed lacpdu_t;
    drivers/net/wireguard/receive.c
    ͔͠͠
    ࣮͸LACPͷνϟϯΫͷ
    αΠζ͸มԽ͠ͳ͍

    View Slide

  111. } else if (skb->protocol == htons(ETH_P_SLOW)) {
    slow_sub_type = *(u8*)skb_network_header(skb);
    if ( slow_sub_type == AD_TYPE_LACPDU ) {
    len = sizeof( struct lacpdu );
    }
    else if ( slow_sub_type == AD_TYPE_MARKER ) {
    len = sizeof( struct bond_marker );
    }
    else return 0u;
    }
    ...
    } else if (skb->protocol == htons(ETH_P_SLOW)) {
    if( unlikely(!(pskb_network_may_pull(skb, 1u)) ) )
    return false;
    slow_sub_type = *(u8*)skb_network_header(skb);
    if ( slow_sub_type == AD_TYPE_LACPDU ) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct lacpdu))) ) )
    return false;
    skb_set_transport_header( skb, ETH_HLEN );
    }
    else if ( slow_sub_type == AD_TYPE_MARKER ) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct bond_marker))) ) )
    drivers/net/wireguard/receive.c
    LACPͩͬͨΒLACPͷύέοτ෼ͷ௕͞Λฦ͢

    View Slide

  112. else if ( slow_sub_type == AD_TYPE_MARKER ) {
    len = sizeof( struct bond_marker );
    }
    else return 0u;
    }
    ...
    } else if (skb->protocol == htons(ETH_P_SLOW)) {
    if( unlikely(!(pskb_network_may_pull(skb, 1u)) ) )
    return false;
    slow_sub_type = *(u8*)skb_network_header(skb);
    if ( slow_sub_type == AD_TYPE_LACPDU ) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct lacpdu))) ) )
    return false;
    skb_set_transport_header( skb, ETH_HLEN );
    }
    else if ( slow_sub_type == AD_TYPE_MARKER ) {
    if( unlikely(!(pskb_network_may_pull(skb, sizeof(struct bond_marker))) ) )
    return false;
    skb_set_transport_header( skb, ETH_HLEN );
    }
    else return false;
    skb_set_transport_header( skb, ETH_HLEN );
    }
    ࠷ॳʹ1όΠτಡΊΔࣄΛ֬ೝͯ͠LACPͰ͋ΔࣄΛ֬ೝ
    ࣍ʹLACPͷύέοτ෼ͷ௕͞ಡΊΔࣄΛ֬ೝ

    View Slide

  113. L2 WireGuard



    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:05
    $ ip link set wg1 up
    $ ip link add dev wg1 type l2wireguard
    $ wg setconf wg1 /etc/wg/wg1.conf
    $ ip link set dev wg1 address 02:ca:fe:f0:0e:04
    $ ip link set wg1 up
    LACPͷύέοτΛྲྀͯ͠൓ରଆʹಉ͡಺༰͕ಧ͘ࣄΛ֬ೝ͢Δ

    View Slide

  114. $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet),
    snapshot length 262144 bytes
    18:53:45.270041 LACPv1, length 110
    Actor Information TLV (0x01), length 20
    System 00:13:c4:12:0f:00 (oui Unknown), System
    Priority 32768, Key 13, Port 22, Port Priority 32768
    State Flags [Activity, Aggregation, Expired]
    0x0000: 8000 0013 c412 0f00 000d 8000 0016 8500
    0x0010: 0000
    Partner Information TLV (0x02), length 20
    System 00:0e:83:16:f5:00 (oui Unknown), System
    Priority 32768, Key 13, Port 25, Port Priority 32768
    State Flags [Timeout, Aggregation, Collecting,
    Distributing]
    0x0000: 8000 000e 8316 f500 000d 8000 0019 3600
    0x0010: 0000
    Collector Information TLV (0x03), length 16
    Max Delay 32768
    0x0000: 8000 0000 0000 0000 0000 0000 0000
    Terminator TLV (0x00), length 0
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8809 0101
    0x0010: 0114 8000 0013 c412 0f00 000d 8000 0016
    0x0020: 8500 0000 0214 8000 000e 8316 f500 000d
    0x0030: 8000 0019 3600 0000 0310 8000 0000 0000
    0x0040: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0050: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0060: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0070: 0000 0000 0000 0000 0000 0000
    $ tcpdump -i wg1 -xx -vv
    dropped privs to pcap
    tcpdump: listening on wg1, link-type EN10MB (Ethernet),
    snapshot length 262144 bytes
    18:53:45.466845 LACPv1, length 110
    Actor Information TLV (0x01), length 20
    System 00:13:c4:12:0f:00 (oui Unknown), System
    Priority 32768, Key 13, Port 22, Port Priority 32768
    State Flags [Activity, Aggregation, Expired]
    0x0000: 8000 0013 c412 0f00 000d 8000 0016 8500
    0x0010: 0000
    Partner Information TLV (0x02), length 20
    System 00:0e:83:16:f5:00 (oui Unknown), System
    Priority 32768, Key 13, Port 25, Port Priority 32768
    State Flags [Timeout, Aggregation, Collecting,
    Distributing]
    0x0000: 8000 000e 8316 f500 000d 8000 0019 3600
    0x0010: 0000
    Collector Information TLV (0x03), length 16
    Max Delay 32768
    0x0000: 8000 0000 0000 0000 0000 0000 0000
    Terminator TLV (0x00), length 0
    0x0000: 02ca fef0 0e05 02ca fef0 0e04 8809 0101
    0x0010: 0114 8000 0013 c412 0f00 000d 8000 0016
    0x0020: 8500 0000 0214 8000 000e 8316 f500 000d
    0x0030: 8000 0019 3600 0000 0310 8000 0000 0000
    0x0040: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0050: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0060: 0000 0000 0000 0000 0000 0000 0000 0000
    0x0070: 0000 0000 0000 0000 0000 0000
    ૹ৴ଆ ड৴ଆ
    LACP

    View Slide

  115. ·ͱΊ
    WireGuard͸
    L3VPNʹ͔͠࢖͑ͳ͍
    ύέοτͷ௕͑͞͞औΕΕ͹
    L2VPNʹԠ༻͢Δ͜ͱ΋ग़དྷΔ

    View Slide