From patchwork Thu Dec 21 18:55:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Gobert X-Patchwork-Id: 13502543 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 EB8E56518A; Thu, 21 Dec 2023 18:55:40 +0000 (UTC) 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="OCeeHp6E" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-40d352c826eso13890875e9.0; Thu, 21 Dec 2023 10:55:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703184939; x=1703789739; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=MzRL/kaIkL+FCfYHWzRmGBN8H4sfOu7t1rXgZsR+1BI=; b=OCeeHp6E/s9POgGBtHV81Ovrl6uILmF1bEqlnjjGr+6F6CVslAavmcNQ71qV5EOrgp FKeJy46mwowvvW7S8ssRyGso4V/BCTuzFb8swp9C+aZpLWw3IecDO/901jm7PcE7Y6EP jYvQ5xXR8xHaD0j3WRIszttescjdbaHNG3tKzCHRZCkqhu1aEkXVTMX5msA4zaQW2Fsx LstUcQaSWxd+0SBpJp0+Ide+kimeZ9/OA1pnW69KwyZtVbFRA6CGh8xs5CsmxKWrBPqL /TF4RAvTxPTWf9XOAyMukyymnhQYjcXZbvHCne/kLs0NbxQVV6gQUQed4kSUg3taP8el Ux2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703184939; x=1703789739; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=MzRL/kaIkL+FCfYHWzRmGBN8H4sfOu7t1rXgZsR+1BI=; b=BsCh6K+WriuFnOhq1vpG3akSvhfzFggakma8+pT3s6H3j3r1EAmlCzp7FlXcfx79l3 2vDjRsLaxm/UhFC/qogxmC/bFi57TetlhP0J3MQrbf3nEUsuKwA5gPhUzlFpK8QyyeRB JOlGMuW0NdMhD49gGInv260ERRe0g6mU6GgQNB2GAO6DNkUsJJVBJ/EThgaDSIL2pDy2 cHKKmZBjagApKt8f5mNtAOG3J6DWasWB+aa3DANRY61fjQbz9H2I8chJBwr9GyGLU1w0 Vyvw3gYD/52oRtSjU1cnrDVaq4ahIUxr0BtwZrU7SSghbeY8ZCEb8VOLSanfiYR1ed0d 9PHg== X-Gm-Message-State: AOJu0YxiLbfJ26l3XG3/A5NWqIxEdczLJ792/oKyjoZPQMV4FNCWrrwa KCwGFbYvooCwvLl4mROyhYI= X-Google-Smtp-Source: AGHT+IGFUlVEOxzVfAgpmsAytp27NgQaIZj3k+0l8jqfEuwmqyRYB6ovrt47LAB8sA/sjM71fvPKBg== X-Received: by 2002:a05:600c:3511:b0:40b:5e21:dd34 with SMTP id h17-20020a05600c351100b0040b5e21dd34mr103969wmq.98.1703184939049; Thu, 21 Dec 2023 10:55:39 -0800 (PST) Received: from debian ([146.70.204.204]) by smtp.gmail.com with ESMTPSA id iv11-20020a05600c548b00b0040b4b2a15ebsm4317478wmb.28.2023.12.21.10.55.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 21 Dec 2023 10:55:38 -0800 (PST) Message-ID: Date: Thu, 21 Dec 2023 19:55:09 +0100 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: [PATCH net-next 1/3] net: gso: add HBH extension header offload support From: Richard Gobert To: davem@davemloft.net, dsahern@kernel.org, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, shuah@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org References: In-Reply-To: X-Patchwork-Delegate: kuba@kernel.org This commit adds net_offload to IPv6 Hop-by-Hop extension headers (as it is done for routing and dstopts) since it is supported in GSO and GRO. This allows to remove specific HBH conditionals in GSO and GRO when pulling and parsing an incoming packet. Signed-off-by: Richard Gobert Reviewed-by: Willem de Bruijn --- net/ipv6/exthdrs_offload.c | 11 +++++++++++ net/ipv6/ip6_offload.c | 25 +++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/net/ipv6/exthdrs_offload.c b/net/ipv6/exthdrs_offload.c index 06750d65d480..4c00398f4dca 100644 --- a/net/ipv6/exthdrs_offload.c +++ b/net/ipv6/exthdrs_offload.c @@ -16,6 +16,10 @@ static const struct net_offload dstopt_offload = { .flags = INET6_PROTO_GSO_EXTHDR, }; +static const struct net_offload hbh_offload = { + .flags = INET6_PROTO_GSO_EXTHDR, +}; + int __init ipv6_exthdrs_offload_init(void) { int ret; @@ -28,9 +32,16 @@ int __init ipv6_exthdrs_offload_init(void) if (ret) goto out_rt; + ret = inet6_add_offload(&hbh_offload, IPPROTO_HOPOPTS); + if (ret) + goto out_dstopts; + out: return ret; +out_dstopts: + inet6_del_offload(&dstopt_offload, IPPROTO_DSTOPTS); + out_rt: inet6_del_offload(&rthdr_offload, IPPROTO_ROUTING); goto out; diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index d6314287338d..0e0b5fed0995 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -45,15 +45,13 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) struct ipv6_opt_hdr *opth; int len; - if (proto != NEXTHDR_HOP) { - ops = rcu_dereference(inet6_offloads[proto]); + ops = rcu_dereference(inet6_offloads[proto]); - if (unlikely(!ops)) - break; + if (unlikely(!ops)) + break; - if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) - break; - } + if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) + break; if (unlikely(!pskb_may_pull(skb, 8))) break; @@ -171,13 +169,12 @@ static int ipv6_exthdrs_len(struct ipv6hdr *iph, proto = iph->nexthdr; for (;;) { - if (proto != NEXTHDR_HOP) { - *opps = rcu_dereference(inet6_offloads[proto]); - if (unlikely(!(*opps))) - break; - if (!((*opps)->flags & INET6_PROTO_GSO_EXTHDR)) - break; - } + *opps = rcu_dereference(inet6_offloads[proto]); + if (unlikely(!(*opps))) + break; + if (!((*opps)->flags & INET6_PROTO_GSO_EXTHDR)) + break; + opth = (void *)opth + optlen; optlen = ipv6_optlen(opth); len += optlen; From patchwork Thu Dec 21 18:57:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Gobert X-Patchwork-Id: 13502554 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 CB44A11733; Thu, 21 Dec 2023 18:58:25 +0000 (UTC) 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="d5bmne/a" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-40d4103aed7so7877555e9.3; Thu, 21 Dec 2023 10:58:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703185104; x=1703789904; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=nHklhKkIDpRGAbC6EyVSS7Ick/sDdM+0PSLDLsMKiVc=; b=d5bmne/a4VJxS+hiGc2Yr83v6DnHjuSi75qggz918SXOjma6FXGn9xOiF/ziNlRfF2 vvYbwNwK0MjcgpMpOX7WOH8SfqclxgEshPOVmIzguxU3LvYt9dZrIXDscph6sY+SVHkJ cbjXHYsRiN2u8OXNGn8TT5/d2FhzyrWRAgVy3kXcVlVnnqSP5YVakblBLujr8UnGLrKG vZgb0IUfD/VRKnnbPzrjaxfCtIi0lH4AeRwsi/OjVQ8AfXQMfoER5tSygxx1NQCx8tjO PoA/LCGndHInAeC25zDmii5zmvWR5ZGS8ubWdqsxhral1rH5LoD3lFwtQ5/Cy6MlKze5 0RuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703185104; x=1703789904; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=nHklhKkIDpRGAbC6EyVSS7Ick/sDdM+0PSLDLsMKiVc=; b=qWDjOM2wrHTfwfIBBr/1DuVOIlCaIqAfZxj83t6jJY8XM0OidGMvTsrc+btE9JZRJW JdYnQJ1xZv1c8TwffDejQk5L2xjwruBuwQG4X5VFuMtMKwXBEZr9NYvjFITAzOj+PWD4 rKeHyydrOgd+vI6IXr9GKE8JZTZcgqZMFdXaVLif/RtVe+4dq193HD4Fbxnmt+R4Eya/ FO7FFEq/rHvggLYv9XMbr+DW77S3zau0qmlToUbBtfz4ypvUwdB/ISJ9JqKM2p2sicbF g3tmW7vHj+o/xFkPtqDWTze52vwvGNdUQ/V3KncVU5I9/TqdMOXoa1qlRxOY/RPKq+jh NDaw== X-Gm-Message-State: AOJu0YzLZ93hT1ln8VXu6N5xHKtE7015loQu6sGBHUJeqLM2JtsTwzRH XDRHfY4dzjdq6yCtgHvOTl4= X-Google-Smtp-Source: AGHT+IEZRGhr19YcFmW2jepDNMeTHfZ2bFIrwD4JzHi58QljsW8CqhwZmLFiGx8I968xig1nuKm0UQ== X-Received: by 2002:a05:600c:4496:b0:40d:41d4:d29e with SMTP id e22-20020a05600c449600b0040d41d4d29emr104917wmo.187.1703185103884; Thu, 21 Dec 2023 10:58:23 -0800 (PST) Received: from debian ([146.70.204.204]) by smtp.gmail.com with ESMTPSA id p6-20020a05600c468600b004053e9276easm11868269wmo.32.2023.12.21.10.58.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 21 Dec 2023 10:58:23 -0800 (PST) Message-ID: <32febbc9-e603-4400-addd-bdb97ce56c1d@gmail.com> Date: Thu, 21 Dec 2023 19:57:51 +0100 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: [PATCH net-next 2/3] net: gro: parse ipv6 ext headers without frag0 From: Richard Gobert To: davem@davemloft.net, dsahern@kernel.org, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, shuah@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org References: In-Reply-To: X-Patchwork-Delegate: kuba@kernel.org This commit utilizes a new helper function, ipv6_gro_pull_exthdrs, which is used in ipv6_gro_receive to pull ipv6 ext headers instead of ipv6_gso_pull_exthdrs. To use ipv6_gso_pull_exthdr, pskb_pull and __skb_push must be used, and frag0 must be invalidated. This commit removes unnecessary code around the call to ipv6_gso_pull_exthdrs and enables the frag0 fast path in IPv6 packets with ext headers. Signed-off-by: Richard Gobert Reviewed-by: Willem de Bruijn --- net/ipv6/ip6_offload.c | 51 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 0e0b5fed0995..a3b8d9127dbb 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -37,6 +37,40 @@ INDIRECT_CALL_L4(cb, f2, f1, head, skb); \ }) +static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto) +{ + const struct net_offload *ops = NULL; + struct ipv6_opt_hdr *opth; + + for (;;) { + int len; + + ops = rcu_dereference(inet6_offloads[proto]); + + if (unlikely(!ops)) + break; + + if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) + break; + + opth = skb_gro_header(skb, off + 8, off); + if (unlikely(!opth)) + break; + + len = ipv6_optlen(opth); + + opth = skb_gro_header(skb, off + len, off); + if (unlikely(!opth)) + break; + proto = opth->nexthdr; + + off += len; + } + + skb_gro_pull(skb, off - skb_network_offset(skb)); + return proto; +} + static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) { const struct net_offload *ops = NULL; @@ -203,28 +237,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, goto out; skb_set_network_header(skb, off); - skb_gro_pull(skb, sizeof(*iph)); - skb_set_transport_header(skb, skb_gro_offset(skb)); - flush += ntohs(iph->payload_len) != skb_gro_len(skb); + flush += ntohs(iph->payload_len) != skb->len - hlen; proto = iph->nexthdr; ops = rcu_dereference(inet6_offloads[proto]); if (!ops || !ops->callbacks.gro_receive) { - pskb_pull(skb, skb_gro_offset(skb)); - skb_gro_frag0_invalidate(skb); - proto = ipv6_gso_pull_exthdrs(skb, proto); - skb_gro_pull(skb, -skb_transport_offset(skb)); - skb_reset_transport_header(skb); - __skb_push(skb, skb_gro_offset(skb)); + proto = ipv6_gro_pull_exthdrs(skb, hlen, proto); ops = rcu_dereference(inet6_offloads[proto]); if (!ops || !ops->callbacks.gro_receive) goto out; - iph = ipv6_hdr(skb); + iph = skb_gro_network_header(skb); + } else { + skb_gro_pull(skb, sizeof(*iph)); } + skb_set_transport_header(skb, skb_gro_offset(skb)); + NAPI_GRO_CB(skb)->proto = proto; flush--; From patchwork Thu Dec 21 18:58:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Gobert X-Patchwork-Id: 13502555 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 EDE266518D; Thu, 21 Dec 2023 18:59:30 +0000 (UTC) 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="lHqSD+RS" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-40c339d2b88so11206565e9.3; Thu, 21 Dec 2023 10:59:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703185169; x=1703789969; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=prT5zhWN3Xwvhx/dTTcm4J0NQjHP/BjQ2cfs9rXhsKs=; b=lHqSD+RSsDjFxrJEMe6Qoe0zxcgBrD8zkmFqYW2ePmh1XtshVem307PtC0MQTXorx7 U86y1TFVtneYga/IBKShDqaEuwSPrDMC6hAFRC/XHPOxnZy3ccUUXfCX0LPtiUiTVbef N/QrKNyKvH+POorpXyer4+0kO109HKNfNHAow5jog92QlImDbjlhQDt9mpGlO/pcNYOB fH08xKdweRr/Hw1IpzNvAq70R9Aqh5yvYQueazOVN3DDzoD+Hya2w61IutNPiQqeE5vc m5gra0d/KGRjD3FO1CTVRBISJ6itpbgmVf4jWX2hn1sncKj7H/9rEyn0ZX+aW+WtzpTY yMQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703185169; x=1703789969; h=content-transfer-encoding:in-reply-to:references:to:from:subject :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=prT5zhWN3Xwvhx/dTTcm4J0NQjHP/BjQ2cfs9rXhsKs=; b=M8cY33Dm+uC+WieVo2jfP3FKC+DnHs9FMn94wwXSoHN4LZ+kOdDbNSv1gQqrE2qj1y aqhPc63ppSFL+i9YEAXlSbY2djkys47rJs9qxcAoz4RcT68y8l9cwDR5sli9jmzN5yRy rITspeehYoWPUQRwxttSjzyjNI0WslFymlrynOxfZKe9q98vE2R0/ajCP3DPp1cQTOrJ RNbR99nItDFxENyU6dhLK5tqPE4t8kHmFpvQpgCH+ExKMZyF8YglXJKsn+GQVUeuItti vw/XXofUVSET0ahN0PNY1jLdrMWN2b527NwYW3PxnS/SsYx5kPANwycnp8gadVsa4zcS CLXQ== X-Gm-Message-State: AOJu0Yxk94nxpJg7I/5yi9v20fDJBxdpuE9OIh4EOSE3RBnuVBbkx/uJ Pf29nkewFTQA0JuJJDANAd8= X-Google-Smtp-Source: AGHT+IGcfjzOQgIK3oE5a0xkZ7F3VXQnA2OqVx/WoldDgtxZW8s2O5rFIGVBr5oJ6hVqxbxAUbsFww== X-Received: by 2002:a05:600c:4f0f:b0:40c:2cc5:4539 with SMTP id l15-20020a05600c4f0f00b0040c2cc54539mr99103wmq.23.1703185168870; Thu, 21 Dec 2023 10:59:28 -0800 (PST) Received: from debian ([146.70.204.204]) by smtp.gmail.com with ESMTPSA id p6-20020a05600c468600b004053e9276easm11868269wmo.32.2023.12.21.10.59.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 21 Dec 2023 10:59:28 -0800 (PST) Message-ID: <641157c0-f224-4910-874d-7906a48d914b@gmail.com> Date: Thu, 21 Dec 2023 19:58:59 +0100 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: [PATCH net-next 3/3] selftests/net: fix GRO coalesce test and add ext From: Richard Gobert To: davem@davemloft.net, dsahern@kernel.org, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, shuah@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org References: In-Reply-To: X-Patchwork-Delegate: kuba@kernel.org Currently there is no test which checks that IPv6 extension header packets successfully coalesce. This commit adds a test, which verifies two IPv6 packets with HBH extension headers do coalesce. I changed the receive socket filter to accept a packet with one extension header. This change exposed a bug in the fragment test -- the old BPF did not accept the fragment packet. I updated correct_num_packets in the fragment test accordingly. Signed-off-by: Richard Gobert --- tools/testing/selftests/net/gro.c | 78 ++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/net/gro.c b/tools/testing/selftests/net/gro.c index 30024d0ed373..4ee34dca8e5f 100644 --- a/tools/testing/selftests/net/gro.c +++ b/tools/testing/selftests/net/gro.c @@ -71,6 +71,10 @@ #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 MIN_EXTHDR_SIZE 8 /* minimum size of IPv6 extension header */ + +#define ipv6_optlen(p) (((p)->hdrlen+1) << 3) /* calculate IPv6 extension header len */ + static const char *addr6_src = "fdaa::2"; static const char *addr6_dst = "fdaa::1"; @@ -104,7 +108,7 @@ 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; + int ipproto_off, opt_ipproto_off; int next_off; if (proto == PF_INET) @@ -116,14 +120,27 @@ static void setup_sock_filter(int fd) if (strcmp(testname, "ip") == 0) { if (proto == PF_INET) optlen = sizeof(struct ip_timestamp); - else - optlen = sizeof(struct ip6_frag); + else { + // same size for HBH and Fragment extension header types + optlen = MIN_EXTHDR_SIZE; + opt_ipproto_off = ETH_HLEN + sizeof(struct ipv6hdr) + + offsetof(struct ip6_ext, ip6e_nxt); + } } + /* + * this filter validates the following: + * - packet is IPv4/IPv6 according to the running test. + * - packet is TCP. Also handles the case of one extension header and then TCP. + * - checks the packet tcp dport equals to DPORT. + * (also handles the case of one extension header and then TCP.) + */ struct sock_filter filter[] = { BPF_STMT(BPF_LD + BPF_H + BPF_ABS, ethproto_off), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ntohs(ethhdr_proto), 0, 7), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ntohs(ethhdr_proto), 0, 9), BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ipproto_off), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_TCP, 2, 0), + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, opt_ipproto_off), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_TCP, 0, 5), BPF_STMT(BPF_LD + BPF_H + BPF_ABS, dport_off), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DPORT, 2, 0), @@ -576,6 +593,39 @@ static void add_ipv4_ts_option(void *buf, void *optpkt) iph->check = checksum_fold(iph, sizeof(struct iphdr) + optlen, 0); } +static void add_ipv6_exthdr(void *buf, void *optpkt, __u8 exthdr_type) +{ + struct ipv6_opt_hdr *hbh_hdr = (struct ipv6_opt_hdr *)(optpkt + tcp_offset); + struct ipv6hdr *iph = (struct ipv6hdr *)(optpkt + ETH_HLEN); + int opt_len; + + hbh_hdr->hdrlen = 0; + hbh_hdr->nexthdr = IPPROTO_TCP; + opt_len = ipv6_optlen(hbh_hdr); + + memcpy(optpkt, buf, tcp_offset); + memcpy(optpkt + tcp_offset + MIN_EXTHDR_SIZE, buf + tcp_offset, + sizeof(struct tcphdr) + PAYLOAD_LEN); + + iph->nexthdr = exthdr_type; + iph->payload_len = htons(ntohs(iph->payload_len) + MIN_EXTHDR_SIZE); +} + +/* Send IPv6 packet with extension header */ +static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr) +{ + static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; + static char exthdr_pck[sizeof(buf) + MIN_EXTHDR_SIZE]; + + create_packet(buf, 0, 0, PAYLOAD_LEN, 0); + add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_HOPOPTS); + write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr); + + create_packet(buf, PAYLOAD_LEN * 1, 0, PAYLOAD_LEN, 0); + add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_HOPOPTS); + write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr); +} + /* IPv4 options shouldn't coalesce */ static void send_ip_options(int fd, struct sockaddr_ll *daddr) { @@ -697,7 +747,7 @@ static void send_fragment6(int fd, struct sockaddr_ll *daddr) create_packet(buf, PAYLOAD_LEN * i, 0, PAYLOAD_LEN, 0); write_packet(fd, buf, bufpkt_len, daddr); } - + sleep(1); create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0); memset(extpkt, 0, extpkt_len); @@ -760,6 +810,7 @@ static void check_recv_pkts(int fd, int *correct_payload, vlog("}, Total %d packets\nReceived {", correct_num_pkts); while (1) { + ip_ext_len = 0; pkt_size = recv(fd, buffer, IP_MAXPACKET + ETH_HLEN + 1, 0); if (pkt_size < 0) error(1, errno, "could not receive"); @@ -767,7 +818,7 @@ static void check_recv_pkts(int fd, int *correct_payload, if (iph->version == 4) ip_ext_len = (iph->ihl - 5) * 4; else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP) - ip_ext_len = sizeof(struct ip6_frag); + ip_ext_len = MIN_EXTHDR_SIZE; tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len); @@ -880,7 +931,14 @@ static void gro_sender(void) sleep(1); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); } else if (proto == PF_INET6) { + sleep(1); send_fragment6(txfd, &daddr); + sleep(1); + write_packet(txfd, fin_pkt, total_hdr_len, &daddr); + + sleep(1); + send_ipv6_exthdr(txfd, &daddr); + sleep(1); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); } } else if (strcmp(testname, "large") == 0) { @@ -997,7 +1055,13 @@ static void gro_receiver(void) */ printf("fragmented ip6 doesn't coalesce: "); correct_payload[0] = PAYLOAD_LEN * 2; - check_recv_pkts(rxfd, correct_payload, 2); + correct_payload[1] = PAYLOAD_LEN; + correct_payload[2] = PAYLOAD_LEN; + check_recv_pkts(rxfd, correct_payload, 3); + + correct_payload[0] = PAYLOAD_LEN * 2; + printf("ipv6 with extension header DOES coalesce: "); + check_recv_pkts(rxfd, correct_payload, 1); } } else if (strcmp(testname, "large") == 0) { int offset = proto == PF_INET ? 20 : 0;