Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

WireGuard ͷܽ఺ L3 VPNઐ༻

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

L2 VPN ηάϝϯτ 192.168.0.0/24

Slide 9

Slide 9 text

෺ཧ૚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ͷ৔߹ ͕͜͜૿͑ͨ

Slide 10

Slide 10 text

෺ཧ૚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

Slide 11

Slide 11 text

෺ཧ૚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͸ ৐ͤΒΕͳ͍

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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ͷ੔਺ഒʹͳ͍ͬͯͳ͍৔߹

Slide 14

Slide 14 text

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ͷ੔਺ഒʹ͢Δ

Slide 15

Slide 15 text

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ... ҉߸Խ 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 ෮߸ ΋ͱͷύέοτͷ௕͕͞Θ͔ΒΜ

Slide 16

Slide 16 text

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ϔομ͕ೖ͍ͬͯΔ

Slide 17

Slide 17 text

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ϔομͷύέοτ௕͕ೖ͍ͬͯΔ

Slide 18

Slide 18 text

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ͳͷͰ ͜͜·Ͱ͕΋ͱͷύέοτͰ͋Δࣄ͕Θ͔Δ

Slide 19

Slide 19 text

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Ͱ΋

Slide 20

Slide 20 text

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ϑϨʔϜʹ͸ύέοτ௕ͷ৘ใ͕ͳ͍ͷͰ ΋ͱͷύέοτͷ௕͕͞෼͔Βͳ͘ͳΔ

Slide 21

Slide 21 text

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ͷύέοτ͕ ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍

Slide 22

Slide 22 text

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ͷύέοτ͕ ਅ্ʹ৐͍ͬͯͳ͚Ε͹ͳΒͳ͍ ຊ౰ʹ෼͔Βͳ͍ͩΖ͏͔

Slide 23

Slide 23 text

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ϔομ

Slide 24

Slide 24 text

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ϔομ ͳΒ͜͜ʹ͋Δͷ͸ύέοτ௕Ͱ͸?

Slide 25

Slide 25 text

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ϔομ

Slide 26

Slide 26 text

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ҎԼʹશͯೖ͍ͬͯΔ

Slide 27

Slide 27 text

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ʹΑΔΞυϨεղܾ͸ඞཁͳ͍ ͜ͷΑ͏ͳઃఆͰσόΠε͕࡞ΒΕ͍ͯΔͨΊ

Slide 28

Slide 28 text

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ͩͱΧʔωϧʹओு͢Δඞཁ͕͋Δ

Slide 29

Slide 29 text

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Λ༻ҙ

Slide 30

Slide 30 text

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ͩ

Slide 31

Slide 31 text

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ϔομ͕ࡌΔ෼͚ͩݮΒ͢

Slide 32

Slide 32 text

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͕ݺ͹ΕΔΑ͏ʹ͓ͯ͘͠

Slide 33

Slide 33 text

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ΞυϨεͷมߋΛड͚෇͚ΔΑ͏ʹ͓ͯ͘͠

Slide 34

Slide 34 text

$ 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σόΠεΛ࡞Δ ΧʔωϧΛϏϧυͯ͠ىಈ͠

Slide 35

Slide 35 text

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ύέοτʯ ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

Slide 36

Slide 36 text

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 ͜ͷ෼ذʹೖͬͯ ͜Ε͕ग़͍ͯΔ ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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 ૹ৴ଆͷϗετʹΧʔωϧϩά͕ग़Δ

Slide 39

Slide 39 text

__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Ͱ΋ͳ͍Կ͔Λඈ͹ͦ͏ͱ͍ͯ͠Δ

Slide 40

Slide 40 text

__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

Slide 41

Slide 41 text

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ΞυϨε)ΛͲͷϋʔυ΢ΣΞ͕͍࣋ͬͯΔ͔Λ໰͍߹ΘͤΔ

Slide 42

Slide 42 text

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 (=ಉ͡ηάϝϯτʹෳ਺ͷ௨৴૬ख͕ଘࡏͰ͖ͯɺϒϩʔυΩϟετ͕͋Δ) ͩͱΧʔωϧʹ఻͑ͨͷͰ

Slide 43

Slide 43 text

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͕௨ΕΔΑ͏ʹ͢Δඞཁ͕͋Δ

Slide 44

Slide 44 text

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͸ૹ৴࣌ٴͼड৴࣌ʹύέοτͷૹ৴ઌΞυϨε͕ ڐՄ͞ΕͨΞυϨεͰ͋ΔࣄΛ֬ೝ͍ͯ͠Δ

Slide 45

Slide 45 text

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͕ڐՄ͞Ε͍ͯΕ͹௨Δࣄʹ͢Δ

Slide 46

Slide 46 text

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ͷ ৔߹Λ ௥Ճ

Slide 47

Slide 47 text

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ͷ௕͞ΛٻΊΔॲཧΛ௥Ճ

Slide 48

Slide 48 text

$ 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 ಈ͍ͨ!

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

IPͰͳ͍෺ΛӡͿ

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

} 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Λฦ͢

Slide 57

Slide 57 text

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 ͔͜͜ΒϖΠϩʔυ

Slide 58

Slide 58 text

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ϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ

Slide 59

Slide 59 text

} 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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

$ 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

Slide 62

Slide 62 text

$ 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

Slide 63

Slide 63 text

$ 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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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ϔομ ͔͜͜ΒϖΠϩʔυ

Slide 66

Slide 66 text

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ϔομΛؚΉύέοτ௕͕ೖ͍ͬͯΔ

Slide 67

Slide 67 text

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ϔομͷύέοτ௕Λ࢖ͬͯύέοτͷ௕͞Λऔಘ

Slide 68

Slide 68 text

$ 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ಉ༷ɺύέοτΩϟϓνϟ͕ྲྀΕΔࣄΛ֬ೝ͢Δ

Slide 69

Slide 69 text

$ 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

Slide 70

Slide 70 text

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ϑϨʔϜ͸ਖ਼ৗʹதܧ͍ͨ͠

Slide 71

Slide 71 text

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όΠτ

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

$ 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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

) { ... } 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ϔομͷϖΠϩʔυ௕Λ࢖༻

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

$ 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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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ͱͦͷ಺༰͕ೖ͍ͬͯΔ λάͷޙΖͷ৘ใͰύέοτ௕Λऔಘ͠ͳ͓ͤ͹ྑ͍

Slide 85

Slide 85 text

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Λ࡞ΕΔΑ͏ʹ͢Δ

Slide 86

Slide 86 text

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ϑϨʔϜ

Slide 87

Slide 87 text

} 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

Slide 88

Slide 88 text

} 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ʹઃఆ͞Ε͍ͯͨΒ

Slide 89

Slide 89 text

) { 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ϔομͷαΠζ)෼ಡΊΔ͜ͱΛ֬ೝ

Slide 90

Slide 90 text

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όΠτޙΖʹͣΒͯ͠ ύέοτ௕ͷνΣοΫΛ࠶ؼݺͼग़͠

Slide 91

Slide 91 text

)) ) ) 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ͷத਎ͷνΣοΫͷ݁ՌΛฦ͢

Slide 92

Slide 92 text

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ஈ

Slide 93

Slide 93 text

$ 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ஈ

Slide 94

Slide 94 text

$ 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

Slide 95

Slide 95 text

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ஈ

Slide 96

Slide 96 text

$ 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ஈ

Slide 97

Slide 97 text

$ 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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

͔͜͜Βઌ͸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ϔομ

Slide 100

Slide 100 text

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ϔομͷܕΛ༻ҙͯ͠

Slide 101

Slide 101 text

__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ϔομͷαΠζ෼ਐΜͩҐஔ͔Β ύέοτ௕ͷऔಘΛ΍Γ௚͢

Slide 102

Slide 102 text

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Λ஻Δػث͕ແ͍ͷͰͦΕͬΆ͍ύέοτΛ፻଄ͯ͠ྲྀ͢

Slide 103

Slide 103 text

$ 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͸͜ͷछͷύέοτΛ ύʔεͰ͖ͳ͍Β͍͠

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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ͷҰछ

Slide 107

Slide 107 text

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ͷύέοτ͸ෳ਺ͷνϟϯΫʹ෼͔Ε͍ͯΔ

Slide 108

Slide 108 text

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όΠτͰೖ͍ͬͯΔ

Slide 109

Slide 109 text

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ͷνϟϯΫͰऴ୺Λද͢ ͦͷޙΖʹ͸Ұఆ਺ͷύσΟϯάΛೖΕΔࣄʹͳ͍ͬͯΔ

Slide 110

Slide 110 text

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ͷνϟϯΫͷ αΠζ͸มԽ͠ͳ͍

Slide 111

Slide 111 text

} 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ͷύέοτ෼ͷ௕͞Λฦ͢

Slide 112

Slide 112 text

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ͷύέοτ෼ͷ௕͞ಡΊΔࣄΛ֬ೝ

Slide 113

Slide 113 text

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ͷύέοτΛྲྀͯ͠൓ରଆʹಉ͡಺༰͕ಧ͘ࣄΛ֬ೝ͢Δ

Slide 114

Slide 114 text

$ 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

Slide 115

Slide 115 text

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