From: Willem de Bruijn <will...@google.com> For configurable gro_receive all callsites need to be updated. Similar to gro_complete, introduce a single shared helper, net_gro_receive.
Signed-off-by: Willem de Bruijn <will...@google.com> --- drivers/net/geneve.c | 2 +- include/linux/netdevice.h | 14 +++++++++++++- net/8021q/vlan.c | 2 +- net/core/dev.c | 20 ++++---------------- net/ethernet/eth.c | 2 +- net/ipv4/af_inet.c | 4 ++-- net/ipv4/fou.c | 8 ++++---- net/ipv4/gre_offload.c | 12 ++++++------ net/ipv6/ip6_offload.c | 8 ++++---- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index a3a4621d9bee..a812a774e5fd 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -467,7 +467,7 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk, type = gh->proto_type; rcu_read_lock(); - ptype = gro_find_receive_by_type(type); + ptype = net_gro_receive(dev_offloads, type); if (!ptype) goto out_unlock; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0d292ea6716e..0be594f8d1ce 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3556,7 +3556,6 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); void napi_gro_flush(struct napi_struct *napi, bool flush_old); struct sk_buff *napi_get_frags(struct napi_struct *napi); gro_result_t napi_gro_frags(struct napi_struct *napi); -struct packet_offload *gro_find_receive_by_type(__be16 type); extern const struct net_offload __rcu *dev_offloads[256]; @@ -3568,6 +3567,19 @@ static inline u8 net_offload_from_type(u16 type) return type & 0xFF; } +static inline const struct net_offload * +net_gro_receive(const struct net_offload __rcu **offs, u16 type) +{ + const struct net_offload *off; + + off = rcu_dereference(offs[net_offload_from_type(type)]); + if (off && off->callbacks.gro_receive && + (!off->type || off->type == type)) + return off; + else + return NULL; +} + static inline int net_gro_complete(const struct net_offload __rcu **offs, u16 type, struct sk_buff *skb, int nhoff) { diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 6ac27aa9f158..a106c5373b1d 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -670,7 +670,7 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head, type = vhdr->h_vlan_encapsulated_proto; rcu_read_lock(); - ptype = gro_find_receive_by_type(type); + ptype = net_gro_receive(dev_offloads, type); if (!ptype) goto out_unlock; diff --git a/net/core/dev.c b/net/core/dev.c index 2c21e507291f..ae5fbd4114d2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5382,7 +5382,7 @@ static void gro_flush_oldest(struct list_head *head) static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1); - const struct packet_offload *ptype; + const struct net_offload *ops; __be16 type = skb->protocol; struct list_head *gro_head; struct sk_buff *pp = NULL; @@ -5396,8 +5396,8 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff gro_head = gro_list_prepare(napi, skb); rcu_read_lock(); - ptype = dev_offloads[net_offload_from_type(type)]; - if (ptype && ptype->callbacks.gro_receive) { + ops = net_gro_receive(dev_offloads, type); + if (ops) { skb_set_network_header(skb, skb_gro_offset(skb)); skb_reset_mac_len(skb); NAPI_GRO_CB(skb)->same_flow = 0; @@ -5425,7 +5425,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff NAPI_GRO_CB(skb)->csum_valid = 0; } - pp = ptype->callbacks.gro_receive(gro_head, skb); + pp = ops->callbacks.gro_receive(gro_head, skb); rcu_read_unlock(); } else { rcu_read_unlock(); @@ -5483,18 +5483,6 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff goto pull; } -struct packet_offload *gro_find_receive_by_type(__be16 type) -{ - struct net_offload *off; - - off = (struct net_offload *) rcu_dereference(dev_offloads[type & 0xFF]); - if (off && off->type == type && off->callbacks.gro_receive) - return off; - else - return NULL; -} -EXPORT_SYMBOL(gro_find_receive_by_type); - static void napi_skb_free_stolen_head(struct sk_buff *skb) { skb_dst_drop(skb); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index fb17a13722e8..542dbc2ec956 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -462,7 +462,7 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb) type = eh->h_proto; rcu_read_lock(); - ptype = gro_find_receive_by_type(type); + ptype = net_gro_receive(dev_offloads, type); if (ptype == NULL) { flush = 1; goto out_unlock; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 1b72ee4a7811..28b7c7671789 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1409,8 +1409,8 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) proto = iph->protocol; rcu_read_lock(); - ops = rcu_dereference(inet_offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) + ops = net_gro_receive(inet_offloads, proto); + if (!ops) goto out_unlock; if (*(u8 *)iph != 0x45) diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index c42a3ef17864..13401cb2e7a4 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -246,8 +246,8 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, rcu_read_lock(); offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; - ops = rcu_dereference(offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) + ops = net_gro_receive(offloads, proto); + if (!ops) goto out_unlock; pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); @@ -428,8 +428,8 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, rcu_read_lock(); offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; - ops = rcu_dereference(offloads[proto]); - if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + ops = net_gro_receive(offloads, proto); + if (WARN_ON_ONCE(!ops)) goto out_unlock; pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index fc8c99e4a058..4f9237a4bea1 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c @@ -111,13 +111,13 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, static struct sk_buff *gre_gro_receive(struct list_head *head, struct sk_buff *skb) { - struct sk_buff *pp = NULL; - struct sk_buff *p; const struct gre_base_hdr *greh; + const struct net_offload *ops; unsigned int hlen, grehlen; + struct sk_buff *pp = NULL; + struct sk_buff *p; unsigned int off; int flush = 1; - struct packet_offload *ptype; __be16 type; if (NAPI_GRO_CB(skb)->encap_mark) @@ -154,8 +154,8 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, type = greh->protocol; rcu_read_lock(); - ptype = gro_find_receive_by_type(type); - if (!ptype) + ops = net_gro_receive(dev_offloads, type); + if (!ops) goto out_unlock; grehlen = GRE_HEADER_SECTION; @@ -217,7 +217,7 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, /* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/ skb_gro_postpull_rcsum(skb, greh, grehlen); - pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); flush = 0; out_unlock: diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index e8bf554ae611..9d301bef0e23 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -194,8 +194,8 @@ static struct sk_buff *ipv6_gro_receive(struct list_head *head, rcu_read_lock(); proto = iph->nexthdr; - ops = rcu_dereference(inet6_offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) { + ops = net_gro_receive(inet6_offloads, proto); + if (!ops) { __pskb_pull(skb, skb_gro_offset(skb)); skb_gro_frag0_invalidate(skb); proto = ipv6_gso_pull_exthdrs(skb, proto); @@ -203,8 +203,8 @@ static struct sk_buff *ipv6_gro_receive(struct list_head *head, skb_reset_transport_header(skb); __skb_push(skb, skb_gro_offset(skb)); - ops = rcu_dereference(inet6_offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) + ops = net_gro_receive(inet6_offloads, proto); + if (!ops) goto out_unlock; iph = ipv6_hdr(skb); -- 2.19.0.397.gdd90340f6a-goog