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

L2 WireGuard

635e53b96114c922fa5486b418895960?s=47 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

635e53b96114c922fa5486b418895960?s=128

Fadis

July 10, 2021
Tweet

Transcript

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

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

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

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

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

    ίϧ ݕূ͠΍͍͢؆ૉͳίʔυ
  6. WireGuard ͷܽ఺ L3 VPNઐ༻

  7. L3 VPN        

      ηάϝϯτ 192.168.0.0/24 ηάϝϯτ 192.168.1.0/24 ηάϝϯτ 192.168.2.0/30 ϧʔςΟϯά ϧʔςΟϯά
  8. L2 VPN        

    ηάϝϯτ 192.168.0.0/24
  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ͷ৔߹ ͕͜͜૿͑ͨ
  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
  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͸ ৐ͤΒΕͳ͍
  12. Poly1305͸128bitΛ1ϒϩοΫͱͯ͠ϋογϡΛܭࢉ͢Δ CJU CJU CJU CJU 伴 ϋογϡ

  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ͷ੔਺ഒʹͳ͍ͬͯͳ͍৔߹
  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ͷ੔਺ഒʹ͢Δ
  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 ෮߸ ΋ͱͷύέοτͷ௕͕͞Θ͔ΒΜ
  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ϔομ͕ೖ͍ͬͯΔ
  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ϔομͷύέοτ௕͕ೖ͍ͬͯΔ
  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ͳͷͰ ͜͜·Ͱ͕΋ͱͷύέοτͰ͋Δࣄ͕Θ͔Δ
  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Ͱ΋
  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ϑϨʔϜʹ͸ύέοτ௕ͷ৘ใ͕ͳ͍ͷͰ ΋ͱͷύέοτͷ௕͕͞෼͔Βͳ͘ͳΔ
  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ͷύέοτ͕ ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍
  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ͷύέοτ͕ ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍ ຊ౰ʹ෼͔Βͳ͍ͩΖ͏͔
  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ϔομ
  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ϔομ ͳΒ͜͜ʹ͋Δͷ͸ύέοτ௕Ͱ͸?
  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ϔομ
  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ҎԼʹશͯೖ͍ͬͯΔ
  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ʹΑΔΞυϨεղܾ͸ඞཁͳ͍ ͜ͷΑ͏ͳઃఆͰσόΠε͕࡞ΒΕ͍ͯΔͨΊ
  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: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/none WireGuardͷσόΠεʹ͸MACΞυϨε͕ͳ͍ LinuxͷωοτϫʔΫελοΫ͸ ͜͏ͨ͠ઃఆͷσόΠε͔ΒύέοτΛૹΔ৔߹ ϋʔυ΢ΣΞͷϔομΛ෇͚ͣʹ network_header(≒IPϔομ)Ҏ͔߱͠ͳ͍sk_buffΛ౉ͯ͘͠Δ ·ͣ͸Զ͸EthernetͩͱΧʔωϧʹओு͢Δඞཁ͕͋Δ
  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Λ༻ҙ
  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ͩ
  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ϔομ͕ࡌΔ෼͚ͩݮΒ͢
  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͕ݺ͹ΕΔΑ͏ʹ͓ͯ͘͠
  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ΞυϨεͷมߋΛड͚෇͚ΔΑ͏ʹ͓ͯ͘͠
  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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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σόΠεΛ࡞Δ ΧʔωϧΛϏϧυͯ͠ىಈ͠
  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ύέοτʯ ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ
  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 ͜ͷ෼ذʹೖͬͯ ͜Ε͕ग़͍ͯΔ ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ
  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
  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 ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ
  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Ͱ΋ͳ͍Կ͔Λඈ͹ͦ͏ͱ͍ͯ͠Δ
  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
  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ΞυϨε)ΛͲͷϋʔυ΢ΣΞ͕͍࣋ͬͯΔ͔Λ໰͍߹ΘͤΔ
  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 (=ಉ͡ηάϝϯτʹෳ਺ͷ௨৴૬ख͕ଘࡏͰ͖ͯɺϒϩʔυΩϟετ͕͋Δ) ͩͱΧʔωϧʹ఻͑ͨͷͰ
  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͕௨ΕΔΑ͏ʹ͢Δඞཁ͕͋Δ
  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͸ૹ৴࣌ٴͼड৴࣌ʹύέοτͷૹ৴ઌΞυϨε͕ ڐՄ͞ΕͨΞυϨεͰ͋ΔࣄΛ֬ೝ͍ͯ͠Δ
  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͕ڐՄ͞Ε͍ͯΕ͹௨Δࣄʹ͢Δ
  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ͷ ৔߹Λ ௥Ճ
  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ͷ௕͞ΛٻΊΔॲཧΛ௥Ճ
  48. $ ip link ... 7: wg1: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 ಈ͍ͨ!
  49. L2 WireGuard͸EthernetσόΠεͳͷͰ IEEE 802.1d MAC Bridgesʹ૊ΈࠐΊΔ

  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
  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
  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
  53. IPͰͳ͍෺ΛӡͿ

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

  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
  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Λฦ͢
  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 ͔͜͜ΒϖΠϩʔυ
  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ϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ
  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
  60. L2 WireGuard AppleTalkͷωοτϫʔΫΛ༻ҙ͢Δͷ͕͠ΜͲ͍ WireSharkͷެࣜαΠτʹ͋Δ AppleTalkͷ௨৴ͷΩϟϓνϟ͕ྲྀΕΔ͜ͱΛ֬ೝ͢Δ   

  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   
  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
  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: "0AE0496030DBC4041800ADCD047@MORO:MicrosoftM-( Windows 2000M-* Prt@*" 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: "0AE0496030DBC4041800ADCD047@MORO:MicrosoftM-( Windows 2000M-* Prt@*" 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
  64. IPX Novell NetWareͰ࢖ΘΕͨଠݹͷ௨৴ϓϩτίϧ Ethernet Ethernet্Ͱ IPXͱݺ͹ΕΔIPͰ͸ͳ͍ύέοτΛ౤͛߹͏ DBGFGF DBGFGF ηάϝϯτ 00000000

  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ϔομ ͔͜͜ΒϖΠϩʔυ
  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ϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ
  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ϔομͷύέοτ௕Λ࢖ͬͯύέοτͷ௕͞Λऔಘ
  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ಉ༷ɺύέοτΩϟϓνϟ͕ྲྀΕΔࣄΛ֬ೝ͢Δ
  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
  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ϑϨʔϜ͸ਖ਼ৗʹதܧ͍ͨ͠
  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όΠτ
  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
  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
  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
  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
  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ϔομͷϖΠϩʔυ௕Λ࢖༻
  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
  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
  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
  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
  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
  82. 802.1q VLAN Tagging ෺ཧతʹ1ͭͷηάϝϯτΛ Ծ૝తʹෳ਺ͷಠཱͨ͠ηάϝϯτʹݟ͔͚ͤΔ     

      ෺ཧతͳ઀ଓ
  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
  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ͱͦͷ಺༰͕ೖ͍ͬͯΔ λάͷޙΖͷ৘ใͰύέοτ௕Λऔಘ͠ͳ͓ͤ͹ྑ͍
  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Λ࡞ΕΔΑ͏ʹ͢Δ
  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ϑϨʔϜ
  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
  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ʹઃఆ͞Ε͍ͯͨΒ
  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ϔομͷαΠζ)෼ಡΊΔ͜ͱΛ֬ೝ
  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όΠτޙΖʹͣΒͯ͠ ύέοτ௕ͷνΣοΫΛ࠶ؼݺͼग़͠
  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ͷத਎ͷνΣοΫͷ݁ՌΛฦ͢
  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ஈ
  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ஈ
  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
  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ஈ  
  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ஈ
  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
  98. IEEE 802.1ah Provider Backbone Bridges 2ॏVLANͷ಺ଆʹMACΞυϨεΛ࣋ͨͤͯ ্ҐͷϒϦοδ͕຤୺ͷσόΠεͷ MACΞυϨεΛ஌Βͳͯ͘ྑ͘͢Δ

  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ϔομ
  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ϔομͷܕΛ༻ҙͯ͠
  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ϔομͷαΠζ෼ਐΜͩҐஔ͔Β ύέοτ௕ͷऔಘΛ΍Γ௚͢
  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Λ஻Δػث͕ແ͍ͷͰͦΕͬΆ͍ύέοτΛ፻଄ͯ͠ྲྀ͢
  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͸͜ͷछͷύέοτΛ ύʔεͰ͖ͳ͍Β͍͠
  104. WireShark͸ύʔεग़དྷ͍ͯΔͷͰύέοτͷϑΥʔϚοτ͸ਖ਼ͦ͠͏

  105. L2 WireGuard L2 WireGuard 802.3ad Link Aggregation Control Protocol(LACP) team

    ৑௕Խ΍ଳҬΛՔ͙໨తͰ ෳ਺ͷϦϯΫΛଋͶͯԾ૝తͳ1ͭͷϦϯΫ(team)ͱͯ͠࢖͏ LACP͸ݸʑͷϦϯΫͷੜଘ֬ೝΛܧଓతʹߦ͍ ௨৴Ͱ͖ͳ͘ͳͬͨϦϯΫΛteam͔Β֎͢ team ͪ͜Β͚ͩΛ࢖ͬͯ ௨৴ΛܧଓͰ͖Δ
  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ͷҰछ
  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ͷύέοτ͸ෳ਺ͷνϟϯΫʹ෼͔Ε͍ͯΔ
  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όΠτͰೖ͍ͬͯΔ
  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ͷνϟϯΫͰऴ୺Λද͢ ͦͷޙΖʹ͸Ұఆ਺ͷύσΟϯάΛೖΕΔࣄʹͳ͍ͬͯΔ
  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ͷνϟϯΫͷ αΠζ͸มԽ͠ͳ͍
  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ͷύέοτ෼ͷ௕͞Λฦ͢
  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ͷύέοτ෼ͷ௕͞ಡΊΔࣄΛ֬ೝ
  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ͷύέοτΛྲྀͯ͠൓ରଆʹಉ͡಺༰͕ಧ͘ࣄΛ֬ೝ͢Δ
  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
  115. ·ͱΊ WireGuard͸ L3VPNʹ͔͠࢖͑ͳ͍ ύέοτͷ௕͑͞͞औΕΕ͹ L2VPNʹԠ༻͢Δ͜ͱ΋ग़དྷΔ