From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 027F23AA1B9 for ; Thu, 26 Mar 2026 08:11:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774512709; cv=none; b=P4fnJSXK6Zmox4ZA/REIehDTqDuxfZJboP5CYirfPU7az3+MB908mhAlpfJ81bZ+GqfAjiLRrXZQ0DliK976pWEMsLgHIgwm+kwiO+iO9rfIMejhszT84tGmIJPEhAW13arMhupAGxtwKWN5BkInn9dLaOB4tVHAw48YEnMAU64= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774512709; c=relaxed/simple; bh=HYHW9Q6b8pBslqEf0ZSiMs39dOa8S6wj4vZ/YmVCrAM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gWmV+98VCFxDiTmBZy+zbyABpS72PRySp3657nOLE5L2ZwqLYud+mMyC/YJcqtkN8nQtRmIrwh7erDR6IeynwyhNb+ths2erpuBALGneLoIeZwZGwK+tkklYI2i8Pv9JO7P3QHGf2app84vzyAPkKPqqemDWyrVQPfSBncZioyE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=sM+c+E7s; arc=none smtp.client-ip=209.85.208.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sM+c+E7s" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-660a58841d4so831202a12.0 for ; Thu, 26 Mar 2026 01:11:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774512705; x=1775117505; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fK40iq5Ka5qBY785P0fngLXH8ht5EarxLaoQk9m0Whs=; b=sM+c+E7sFFFIGXK78LWYOdy3KGocbNthH79nNs894EN2gF9mxmeWwE0la39BcMBFbi eIYqiuAwVE8IuUlPAh4YP2r9Nr4vKS5t5cCzwgDfyyviIY5OVjiOMlGYUQuvSchAdTKH BeOb5XiU6Xqpz5webrShQEsfR2iZV6VmbytOqFm6jGoBdFSfM6lPuBSyLj7IFfIP7xm/ Ht+8d/76lhXZo91Pj80tQEQr9bC2rwh8oUCpJomgS7bKUXldtyFrRZqYK/yxGMJKtpvO XKmqsZXdqaQk7soGyHXAPYDo2XoUrhDOvjZ7ZhcbpZr/Oiyp/Z4XeneWhn/dmsI6AD9u LOUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774512705; x=1775117505; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fK40iq5Ka5qBY785P0fngLXH8ht5EarxLaoQk9m0Whs=; b=rJG4NHOrWEtCPm3VCg13EHf0aLBwjTtP14tv6b38/ZjVsq04hDenNHTrxAdeHbzmCs Qeu4xZd5Jrnyx4mtZa3DVG4UVbRK8NkedOXY8aM3rZlH1lTHQOmGW3HPHXUgf1QUjZrm 5gomgMQ8ck02VgdLXY+WQszL9IUKy2a75kZiCV/KXY/tPJZmFwd2evlMg/wgzikeUe30 BfbKfTNThWhXO1DQJbrgdHwNkJb9yimGLNYTZW3icsPoNQQt0pfQUU8ujWOaOYql33Ib RQ2QmSgfTWWbGNgvNNdnJNkQTgXgPzTXMn3+yUkC4Rb0YvVHe5b4lFoVzO6KV9kGlwmA K7Lw== X-Forwarded-Encrypted: i=1; AJvYcCWwoAp91wYfULxqW0U5npb42IHYqvB61tF5XE48yEgXJ26+dr/tzcKRCunHbmVPQDF7ErK3Ihg=@vger.kernel.org X-Gm-Message-State: AOJu0YySEmUU2ffEEqBFA29DTpEhh0U12bsIPSUUKXUT8as6/1eI7TqA K1qoR1eBtCvF0RUYOOjR98lU79YudbU2L+HUOv2UFXVv7KaAI0dTiWWylxtYlLd0NiQ8GQ== X-Gm-Gg: ATEYQzxlBzRKFe4hoQ5h4nAOyRwCMiOWOTi2zo6c9UsrsuYkm4gR7ABrBdQ9sUEhGIF inGdZqHwRvjABjX/urIriS3Q6NKFYchzqcw9cowuKhPHc7Ru+c39OYviQmbYwc07isFD1WyEdAO ORgvqbsJclMB1g87Za5szvdCGZMacczhcYXSyJH3WIcges9jOqDGoPZsPiwAUG8/hLarZEs544P bxt5ju6N/r96nglwMCh7RMr8ngpmLSvemn6oref4rteebG7Wyl6Eymfk5cbbdiHe2QvxvBWHh2M 9qVeI5xfh+pZPpd7TE6g/3PFOf2Ebs9v+R5GkIe07cLyGlgW8bs7YXUPuNir6/jjTRROz319Hkq ssif0VTpKWRiwCyb+/RAVsJFwRL4BaDeJ+blG72bc6Y4pTxHxzWIYcjx+SSb9tsJNVPSCULuokd EMew== X-Received: by 2002:a17:907:7b9d:b0:b98:8f24:b774 with SMTP id a640c23a62f3a-b9b0ef46a82mr448690766b.24.1774512704945; Thu, 26 Mar 2026 01:11:44 -0700 (PDT) Received: from gmail.com ([2a09:bac5:4e23:270f::3e4:5]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9b20267436sm82174666b.26.2026.03.26.01.11.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Mar 2026 01:11:44 -0700 (PDT) From: Qingfang Deng To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan , Simon Horman , Willem de Bruijn , Petr Machata , Richard Gobert , Anubhav Singh , Chia-Yu Chang , netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-ppp@vger.kernel.org Subject: [RFC PATCH net-next v6 2/2] selftests: net: test PPPoE packets in gro.sh Date: Thu, 26 Mar 2026 16:11:18 +0800 Message-ID: <20260326081127.61229-2-dqfext@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260326081127.61229-1-dqfext@gmail.com> References: <20260326081127.61229-1-dqfext@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add PPPoE test-cases to the GRO selftest. Signed-off-by: Qingfang Deng --- v6: new patch I'm not sure if I should include all the existing IPv4/v6 tests for PPPoE. There are tests that hardcode ETH_HLEN as the NH offset, which are meant to test the L3 protocol, not the underlying protocol, and changing all of them seems too invasive. Comments welcome, thanks. --- tools/testing/selftests/drivers/net/config | 2 + tools/testing/selftests/drivers/net/gro.py | 25 +++++- tools/testing/selftests/net/lib/gro.c | 97 ++++++++++++++++------ 3 files changed, 98 insertions(+), 26 deletions(-) diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config index 77ccf83d87e0..caaba209ba3e 100644 --- a/tools/testing/selftests/drivers/net/config +++ b/tools/testing/selftests/drivers/net/config @@ -7,4 +7,6 @@ CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_NETCONSOLE_EXTENDED_LOG=y CONFIG_NETDEVSIM=m +CONFIG_PPP=y +CONFIG_PPPOE=y CONFIG_XDP_SOCKETS=y diff --git a/tools/testing/selftests/drivers/net/gro.py b/tools/testing/selftests/drivers/net/gro.py index 70709bf670c7..eb8306a8f4c4 100755 --- a/tools/testing/selftests/drivers/net/gro.py +++ b/tools/testing/selftests/drivers/net/gro.py @@ -186,8 +186,17 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None, dmac = _resolve_dmac(cfg, ipver) - base_args = [ - f"--{protocol}", + if protocol.startswith("pppoe"): + base_args = [ + f"--ipv{protocol[-1]}", + "--pppoe", + ] + else: + base_args = [ + f"--{protocol}", + ] + + base_args += [ f"--dmac {dmac}", f"--smac {cfg.remote_dev['address']}", f"--daddr {cfg.addr_v[ipver]}", @@ -322,6 +331,18 @@ def _gro_variants(): for test_name in ipv6_tests: yield mode, protocol, test_name + for mode in ["sw"]: + for protocol in ["pppoev4", "pppoev6"]: + for test_name in common_tests: + yield mode, protocol, test_name + + if protocol == "pppoev4": + for test_name in ipv4_tests: + yield mode, protocol, test_name + elif protocol == "pppoev6": + for test_name in ipv6_tests: + yield mode, protocol, test_name + @ksft_variants(_gro_variants()) def test(cfg, mode, protocol, test_name): diff --git a/tools/testing/selftests/net/lib/gro.c b/tools/testing/selftests/net/lib/gro.c index 3e611ae25f61..6148bcdff478 100644 --- a/tools/testing/selftests/net/lib/gro.c +++ b/tools/testing/selftests/net/lib/gro.c @@ -64,12 +64,14 @@ #include #include #include +#include +#include #include #include +#include #include #include -#include -#include +#include #include #include #include @@ -92,11 +94,11 @@ #define START_SEQ 100 #define START_ACK 100 #define ETH_P_NONE 0 -#define TOTAL_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) +#define TOTAL_HDR_LEN (ETH_HLEN + PPPOE_SES_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) #define MSS (4096 - sizeof(struct tcphdr) - sizeof(struct ipv6hdr)) #define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr)) #define NUM_LARGE_PKT (MAX_PAYLOAD / MSS) -#define MAX_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) +#define MAX_HDR_LEN (ETH_HLEN + PPPOE_SES_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) #define MIN_EXTHDR_SIZE 8 #define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00" #define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11" @@ -129,6 +131,7 @@ static int tcp_offset = -1; static int total_hdr_len = -1; static int ethhdr_proto = -1; static bool ipip; +static bool pppoe; static uint64_t txtime_ns; static int num_flows = 4; static bool order_check; @@ -148,12 +151,37 @@ static void vlog(const char *fmt, ...) } } +static void fill_pppoelayer(void *buf, int payload_len) +{ + struct pppoe_ppp_hdr { + struct pppoe_hdr eh; + __be16 proto; + } *ph = buf; + int ppp_payload_len; + + ph->eh.type = 1; + ph->eh.ver = 1; + ph->eh.code = 0; + ph->eh.sid = htons(0x1234); + + if (proto == PF_INET6) { + ph->proto = htons(PPP_IPV6); + ppp_payload_len = sizeof(struct ipv6hdr) + sizeof(struct tcphdr) + payload_len; + } else { + ph->proto = htons(PPP_IP); + ppp_payload_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + payload_len; + } + + ph->eh.length = htons(ppp_payload_len + sizeof(ph->proto)); +} + static void setup_sock_filter(int fd) { const int dport_off = tcp_offset + offsetof(struct tcphdr, dest); const int ethproto_off = offsetof(struct ethhdr, h_proto); int optlen = 0; int ipproto_off, opt_ipproto_off; + int head_len = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0); int next_off; if (ipip) @@ -162,7 +190,7 @@ static void setup_sock_filter(int fd) next_off = offsetof(struct iphdr, protocol); else next_off = offsetof(struct ipv6hdr, nexthdr); - ipproto_off = ETH_HLEN + next_off; + ipproto_off = head_len + next_off; /* Overridden later if exthdrs are used: */ opt_ipproto_off = ipproto_off; @@ -178,7 +206,7 @@ static void setup_sock_filter(int fd) /* same size for HBH and Fragment extension header types */ optlen = MIN_EXTHDR_SIZE; - opt_ipproto_off = ETH_HLEN + sizeof(struct ipv6hdr) + opt_ipproto_off = head_len + sizeof(struct ipv6hdr) + offsetof(struct ip6_ext, ip6e_nxt); } @@ -390,6 +418,10 @@ static void create_packet(void *buf, int seq_offset, int ack_offset, IPPROTO_IPIP); fill_networklayer(buf + ETH_HLEN + sizeof(struct iphdr), payload_len, IPPROTO_TCP); + } else if (pppoe) { + fill_pppoelayer(buf + ETH_HLEN, payload_len); + fill_networklayer(buf + ETH_HLEN + PPPOE_SES_HLEN, + payload_len, IPPROTO_TCP); } else { fill_networklayer(buf + ETH_HLEN, payload_len, IPPROTO_TCP); } @@ -501,7 +533,7 @@ static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn, static void send_data_pkts(int fd, struct sockaddr_ll *daddr, int payload_len1, int payload_len2) { - static char buf[ETH_HLEN + IP_MAXPACKET]; + static char buf[ETH_HLEN + PPPOE_SES_HLEN + IP_MAXPACKET]; create_packet(buf, 0, 0, payload_len1, 0); write_packet(fd, buf, total_hdr_len + payload_len1, daddr); @@ -745,7 +777,7 @@ static void add_ipv4_ts_option(void *buf, void *optpkt) memcpy(optpkt + tcp_offset + optlen, buf + tcp_offset, sizeof(struct tcphdr) + PAYLOAD_LEN); - iph = (struct iphdr *)(optpkt + ETH_HLEN); + iph = (struct iphdr *)(optpkt + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); iph->ihl = 5 + (optlen / 4); iph->tot_len = htons(ntohs(iph->tot_len) + optlen); iph->check = 0; @@ -755,7 +787,7 @@ static void add_ipv4_ts_option(void *buf, void *optpkt) static void add_ipv6_exthdr(void *buf, void *optpkt, __u8 exthdr_type, char *ext_payload) { struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr *)(optpkt + tcp_offset); - struct ipv6hdr *iph = (struct ipv6hdr *)(optpkt + ETH_HLEN); + struct ipv6hdr *iph = (struct ipv6hdr *)(optpkt + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); char *exthdr_payload_start = (char *)(exthdr + 1); exthdr->hdrlen = 0; @@ -908,7 +940,7 @@ static void send_ip_options(int fd, struct sockaddr_ll *daddr) static void send_fragment4(int fd, struct sockaddr_ll *daddr) { static char buf[IP_MAXPACKET]; - struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); + struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); int pkt_size = total_hdr_len + PAYLOAD_LEN; create_packet(buf, 0, 0, PAYLOAD_LEN, 0); @@ -920,7 +952,8 @@ static void send_fragment4(int fd, struct sockaddr_ll *daddr) */ memset(buf + total_hdr_len, 'a', PAYLOAD_LEN * 2); fill_transportlayer(buf + tcp_offset, PAYLOAD_LEN, 0, PAYLOAD_LEN * 2, 0); - fill_networklayer(buf + ETH_HLEN, PAYLOAD_LEN, IPPROTO_TCP); + fill_networklayer(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0), + PAYLOAD_LEN, IPPROTO_TCP); fill_datalinklayer(buf); iph->frag_off = htons(0x6000); // DF = 1, MF = 1 @@ -934,7 +967,7 @@ static void send_changed_ttl(int fd, struct sockaddr_ll *daddr) { int pkt_size = total_hdr_len + PAYLOAD_LEN; static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; - struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); + struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); create_packet(buf, 0, 0, PAYLOAD_LEN, 0); write_packet(fd, buf, pkt_size, daddr); @@ -951,8 +984,8 @@ static void send_changed_tos(int fd, struct sockaddr_ll *daddr) { int pkt_size = total_hdr_len + PAYLOAD_LEN; static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; - struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); - struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN); + struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); + struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); create_packet(buf, 0, 0, PAYLOAD_LEN, 0); write_packet(fd, buf, pkt_size, daddr); @@ -980,7 +1013,8 @@ static void send_changed_ECN(int fd, struct sockaddr_ll *daddr) create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0); if (proto == PF_INET) { - buf[ETH_HLEN + 1] ^= 0x2; // ECN set to 10 + int ecn_off = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0) + 1; + buf[ecn_off] ^= 0x2; // ECN set to 10 iph->check = 0; iph->check = checksum_fold(iph, sizeof(struct iphdr), 0); } else { @@ -995,7 +1029,7 @@ static void send_fragment6(int fd, struct sockaddr_ll *daddr) static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; static char extpkt[MAX_HDR_LEN + PAYLOAD_LEN + sizeof(struct ip6_frag)]; - struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN); + struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0)); struct ip6_frag *frag = (void *)(extpkt + tcp_offset); int extlen = sizeof(struct ip6_frag); int bufpkt_len = total_hdr_len + PAYLOAD_LEN; @@ -1073,9 +1107,10 @@ static void recv_error(int fd, int rcv_errno) static void check_recv_pkts(int fd, int *correct_payload, int correct_num_pkts) { - static char buffer[IP_MAXPACKET + ETH_HLEN + 1]; - struct iphdr *iph = (struct iphdr *)(buffer + ETH_HLEN); - struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + ETH_HLEN); + static char buffer[IP_MAXPACKET + ETH_HLEN + PPPOE_SES_HLEN + 1]; + int nhoff = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0); + struct iphdr *iph = (struct iphdr *)(buffer + nhoff); + struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + nhoff); struct tcphdr *tcph; bool bad_packet = false; int tcp_ext_len = 0; @@ -1092,7 +1127,7 @@ static void check_recv_pkts(int fd, int *correct_payload, while (1) { ip_ext_len = 0; - pkt_size = recv(fd, buffer, IP_MAXPACKET + ETH_HLEN + 1, 0); + pkt_size = recv(fd, buffer, sizeof(buffer), 0); if (pkt_size < 0) recv_error(fd, errno); @@ -1134,9 +1169,10 @@ static void check_recv_pkts(int fd, int *correct_payload, static void check_capacity_pkts(int fd) { - static char buffer[IP_MAXPACKET + ETH_HLEN + 1]; - struct iphdr *iph = (struct iphdr *)(buffer + ETH_HLEN); - struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + ETH_HLEN); + static char buffer[IP_MAXPACKET + ETH_HLEN + PPPOE_SES_HLEN + 1]; + int nhoff = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0); + struct iphdr *iph = (struct iphdr *)(buffer + nhoff); + struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + nhoff); int num_pkt = 0, num_coal = 0, pkt_idx; const char *fail_reason = NULL; int flow_order[num_flows * 2]; @@ -1154,7 +1190,7 @@ static void check_capacity_pkts(int fd) while (total_data < num_flows * CAPACITY_PAYLOAD_LEN * 2) { ip_ext_len = 0; - pkt_size = recv(fd, buffer, IP_MAXPACKET + ETH_HLEN + 1, 0); + pkt_size = recv(fd, buffer, sizeof(buffer), 0); if (pkt_size < 0) recv_error(fd, errno); @@ -1645,6 +1681,7 @@ static void parse_args(int argc, char **argv) { "ipv4", no_argument, NULL, '4' }, { "ipv6", no_argument, NULL, '6' }, { "ipip", no_argument, NULL, 'e' }, + { "pppoe", no_argument, NULL, 'p' }, { "num-flows", required_argument, NULL, 'n' }, { "rx", no_argument, NULL, 'r' }, { "saddr", required_argument, NULL, 's' }, @@ -1671,6 +1708,9 @@ static void parse_args(int argc, char **argv) proto = PF_INET; ethhdr_proto = htons(ETH_P_IP); break; + case 'p': + pppoe = true; + break; case 'd': addr4_dst = addr6_dst = optarg; break; @@ -1715,6 +1755,15 @@ int main(int argc, char **argv) if (ipip) { tcp_offset = ETH_HLEN + sizeof(struct iphdr) * 2; total_hdr_len = tcp_offset + sizeof(struct tcphdr); + } else if (pppoe) { + if (proto == PF_INET) + tcp_offset = ETH_HLEN + PPPOE_SES_HLEN + sizeof(struct iphdr); + else if (proto == PF_INET6) + tcp_offset = ETH_HLEN + PPPOE_SES_HLEN + sizeof(struct ipv6hdr); + else + error(1, 0, "Protocol family is not ipv4 or ipv6"); + total_hdr_len = tcp_offset + sizeof(struct tcphdr); + ethhdr_proto = htons(ETH_P_PPP_SES); } else if (proto == PF_INET) { tcp_offset = ETH_HLEN + sizeof(struct iphdr); total_hdr_len = tcp_offset + sizeof(struct tcphdr); -- 2.43.0