net: gso: add HBH extension header offload support
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 <richardbgobert@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://lore.kernel.org/r/d4f8825a-1d55-4b12-9d67-a254dbbfa6ae@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
cb42010690
commit
f2e3fc2158
@ -16,6 +16,10 @@ static const struct net_offload dstopt_offload = {
|
|||||||
.flags = INET6_PROTO_GSO_EXTHDR,
|
.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 __init ipv6_exthdrs_offload_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -28,9 +32,16 @@ int __init ipv6_exthdrs_offload_init(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out_rt;
|
goto out_rt;
|
||||||
|
|
||||||
|
ret = inet6_add_offload(&hbh_offload, IPPROTO_HOPOPTS);
|
||||||
|
if (ret)
|
||||||
|
goto out_dstopts;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
out_dstopts:
|
||||||
|
inet6_del_offload(&dstopt_offload, IPPROTO_DSTOPTS);
|
||||||
|
|
||||||
out_rt:
|
out_rt:
|
||||||
inet6_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
inet6_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -45,15 +45,13 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
|
|||||||
struct ipv6_opt_hdr *opth;
|
struct ipv6_opt_hdr *opth;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (proto != NEXTHDR_HOP) {
|
ops = rcu_dereference(inet6_offloads[proto]);
|
||||||
ops = rcu_dereference(inet6_offloads[proto]);
|
|
||||||
|
|
||||||
if (unlikely(!ops))
|
if (unlikely(!ops))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
|
if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(!pskb_may_pull(skb, 8)))
|
if (unlikely(!pskb_may_pull(skb, 8)))
|
||||||
break;
|
break;
|
||||||
@ -171,13 +169,12 @@ static int ipv6_exthdrs_len(struct ipv6hdr *iph,
|
|||||||
|
|
||||||
proto = iph->nexthdr;
|
proto = iph->nexthdr;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (proto != NEXTHDR_HOP) {
|
*opps = rcu_dereference(inet6_offloads[proto]);
|
||||||
*opps = rcu_dereference(inet6_offloads[proto]);
|
if (unlikely(!(*opps)))
|
||||||
if (unlikely(!(*opps)))
|
break;
|
||||||
break;
|
if (!((*opps)->flags & INET6_PROTO_GSO_EXTHDR))
|
||||||
if (!((*opps)->flags & INET6_PROTO_GSO_EXTHDR))
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
opth = (void *)opth + optlen;
|
opth = (void *)opth + optlen;
|
||||||
optlen = ipv6_optlen(opth);
|
optlen = ipv6_optlen(opth);
|
||||||
len += optlen;
|
len += optlen;
|
||||||
|
Loading…
Reference in New Issue
Block a user