Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fou: eliminate IPv4,v6 specific GRO functions

This patch removes fou[46]_gro_receive and fou[46]_gro_complete
functions. The v4 or v6 variants were chosen for the UDP offloads
based on the address family of the socket this is not necessary
or correct. Alternatively, this patch adds is_ipv6 to napi_gro_skb.
This is set in udp6_gro_receive and unset in udp4_gro_receive. In
fou_gro_receive the value is used to select the correct inet_offloads
for the protocol of the outer IP header.

Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Tom Herbert and committed by
David S. Miller
efc98d08 7371e022

+13 -40
+3
include/linux/netdevice.h
··· 1886 1886 /* Number of checksums via CHECKSUM_UNNECESSARY */ 1887 1887 u8 csum_cnt:3; 1888 1888 1889 + /* Used in foo-over-udp, set in udp[46]_gro_receive */ 1890 + u8 is_ipv6:1; 1891 + 1889 1892 /* used to support CHECKSUM_COMPLETE for tunneling protocols */ 1890 1893 __wsum csum; 1891 1894
+8 -40
net/ipv4/fou.c
··· 65 65 } 66 66 67 67 static struct sk_buff **fou_gro_receive(struct sk_buff **head, 68 - struct sk_buff *skb, 69 - const struct net_offload **offloads) 68 + struct sk_buff *skb) 70 69 { 71 70 const struct net_offload *ops; 72 71 struct sk_buff **pp = NULL; 73 72 u8 proto = NAPI_GRO_CB(skb)->proto; 73 + const struct net_offload **offloads; 74 74 75 75 rcu_read_lock(); 76 + offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; 76 77 ops = rcu_dereference(offloads[proto]); 77 78 if (!ops || !ops->callbacks.gro_receive) 78 79 goto out_unlock; ··· 86 85 return pp; 87 86 } 88 87 89 - static int fou_gro_complete(struct sk_buff *skb, int nhoff, 90 - const struct net_offload **offloads) 88 + static int fou_gro_complete(struct sk_buff *skb, int nhoff) 91 89 { 92 90 const struct net_offload *ops; 93 91 u8 proto = NAPI_GRO_CB(skb)->proto; 94 92 int err = -ENOSYS; 93 + const struct net_offload **offloads; 95 94 96 95 rcu_read_lock(); 96 + offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; 97 97 ops = rcu_dereference(offloads[proto]); 98 98 if (WARN_ON(!ops || !ops->callbacks.gro_complete)) 99 99 goto out_unlock; ··· 105 103 rcu_read_unlock(); 106 104 107 105 return err; 108 - } 109 - 110 - static struct sk_buff **fou4_gro_receive(struct sk_buff **head, 111 - struct sk_buff *skb) 112 - { 113 - return fou_gro_receive(head, skb, inet_offloads); 114 - } 115 - 116 - static int fou4_gro_complete(struct sk_buff *skb, int nhoff) 117 - { 118 - return fou_gro_complete(skb, nhoff, inet_offloads); 119 - } 120 - 121 - static struct sk_buff **fou6_gro_receive(struct sk_buff **head, 122 - struct sk_buff *skb) 123 - { 124 - return fou_gro_receive(head, skb, inet6_offloads); 125 - } 126 - 127 - static int fou6_gro_complete(struct sk_buff *skb, int nhoff) 128 - { 129 - return fou_gro_complete(skb, nhoff, inet6_offloads); 130 106 } 131 107 132 108 static int fou_add_to_port_list(struct fou *fou) ··· 179 199 180 200 sk->sk_allocation = GFP_ATOMIC; 181 201 182 - switch (cfg->udp_config.family) { 183 - case AF_INET: 184 - fou->udp_offloads.callbacks.gro_receive = fou4_gro_receive; 185 - fou->udp_offloads.callbacks.gro_complete = fou4_gro_complete; 186 - break; 187 - case AF_INET6: 188 - fou->udp_offloads.callbacks.gro_receive = fou6_gro_receive; 189 - fou->udp_offloads.callbacks.gro_complete = fou6_gro_complete; 190 - break; 191 - default: 192 - err = -EPFNOSUPPORT; 193 - goto error; 194 - } 195 - 202 + fou->udp_offloads.callbacks.gro_receive = fou_gro_receive; 203 + fou->udp_offloads.callbacks.gro_complete = fou_gro_complete; 196 204 fou->udp_offloads.port = cfg->udp_config.local_udp_port; 197 205 fou->udp_offloads.ipproto = cfg->protocol; 198 206
+1
net/ipv4/udp_offload.c
··· 334 334 skb_gro_checksum_try_convert(skb, IPPROTO_UDP, uh->check, 335 335 inet_gro_compute_pseudo); 336 336 skip: 337 + NAPI_GRO_CB(skb)->is_ipv6 = 0; 337 338 return udp_gro_receive(head, skb, uh); 338 339 339 340 flush:
+1
net/ipv6/udp_offload.c
··· 140 140 ip6_gro_compute_pseudo); 141 141 142 142 skip: 143 + NAPI_GRO_CB(skb)->is_ipv6 = 1; 143 144 return udp_gro_receive(head, skb, uh); 144 145 145 146 flush: