diff options
| -rw-r--r-- | include/linux/netdevice.h | 3 | ||||
| -rw-r--r-- | net/ipv4/fou.c | 48 | ||||
| -rw-r--r-- | net/ipv4/udp_offload.c | 1 | ||||
| -rw-r--r-- | net/ipv6/udp_offload.c | 1 |
4 files changed, 13 insertions, 40 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 910fb17ad148..22d54b9b700d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1886,6 +1886,9 @@ struct napi_gro_cb { | |||
| 1886 | /* Number of checksums via CHECKSUM_UNNECESSARY */ | 1886 | /* Number of checksums via CHECKSUM_UNNECESSARY */ |
| 1887 | u8 csum_cnt:3; | 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 | /* used to support CHECKSUM_COMPLETE for tunneling protocols */ | 1892 | /* used to support CHECKSUM_COMPLETE for tunneling protocols */ |
| 1890 | __wsum csum; | 1893 | __wsum csum; |
| 1891 | 1894 | ||
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index dced89fbe480..7e2126a31f2e 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c | |||
| @@ -65,14 +65,15 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static struct sk_buff **fou_gro_receive(struct sk_buff **head, | 67 | static struct sk_buff **fou_gro_receive(struct sk_buff **head, |
| 68 | struct sk_buff *skb, | 68 | struct sk_buff *skb) |
| 69 | const struct net_offload **offloads) | ||
| 70 | { | 69 | { |
| 71 | const struct net_offload *ops; | 70 | const struct net_offload *ops; |
| 72 | struct sk_buff **pp = NULL; | 71 | struct sk_buff **pp = NULL; |
| 73 | u8 proto = NAPI_GRO_CB(skb)->proto; | 72 | u8 proto = NAPI_GRO_CB(skb)->proto; |
| 73 | const struct net_offload **offloads; | ||
| 74 | 74 | ||
| 75 | rcu_read_lock(); | 75 | rcu_read_lock(); |
| 76 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | ||
| 76 | ops = rcu_dereference(offloads[proto]); | 77 | ops = rcu_dereference(offloads[proto]); |
| 77 | if (!ops || !ops->callbacks.gro_receive) | 78 | if (!ops || !ops->callbacks.gro_receive) |
| 78 | goto out_unlock; | 79 | goto out_unlock; |
| @@ -85,14 +86,15 @@ out_unlock: | |||
| 85 | return pp; | 86 | return pp; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | static int fou_gro_complete(struct sk_buff *skb, int nhoff, | 89 | static int fou_gro_complete(struct sk_buff *skb, int nhoff) |
| 89 | const struct net_offload **offloads) | ||
| 90 | { | 90 | { |
| 91 | const struct net_offload *ops; | 91 | const struct net_offload *ops; |
| 92 | u8 proto = NAPI_GRO_CB(skb)->proto; | 92 | u8 proto = NAPI_GRO_CB(skb)->proto; |
| 93 | int err = -ENOSYS; | 93 | int err = -ENOSYS; |
| 94 | const struct net_offload **offloads; | ||
| 94 | 95 | ||
| 95 | rcu_read_lock(); | 96 | rcu_read_lock(); |
| 97 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | ||
| 96 | ops = rcu_dereference(offloads[proto]); | 98 | ops = rcu_dereference(offloads[proto]); |
| 97 | if (WARN_ON(!ops || !ops->callbacks.gro_complete)) | 99 | if (WARN_ON(!ops || !ops->callbacks.gro_complete)) |
| 98 | goto out_unlock; | 100 | goto out_unlock; |
| @@ -105,28 +107,6 @@ out_unlock: | |||
| 105 | return err; | 107 | return err; |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | static struct sk_buff **fou4_gro_receive(struct sk_buff **head, | ||
| 109 | struct sk_buff *skb) | ||
| 110 | { | ||
| 111 | return fou_gro_receive(head, skb, inet_offloads); | ||
| 112 | } | ||
| 113 | |||
| 114 | static int fou4_gro_complete(struct sk_buff *skb, int nhoff) | ||
| 115 | { | ||
| 116 | return fou_gro_complete(skb, nhoff, inet_offloads); | ||
| 117 | } | ||
| 118 | |||
| 119 | static struct sk_buff **fou6_gro_receive(struct sk_buff **head, | ||
| 120 | struct sk_buff *skb) | ||
| 121 | { | ||
| 122 | return fou_gro_receive(head, skb, inet6_offloads); | ||
| 123 | } | ||
| 124 | |||
| 125 | static int fou6_gro_complete(struct sk_buff *skb, int nhoff) | ||
| 126 | { | ||
| 127 | return fou_gro_complete(skb, nhoff, inet6_offloads); | ||
| 128 | } | ||
| 129 | |||
| 130 | static int fou_add_to_port_list(struct fou *fou) | 110 | static int fou_add_to_port_list(struct fou *fou) |
| 131 | { | 111 | { |
| 132 | struct fou *fout; | 112 | struct fou *fout; |
| @@ -199,20 +179,8 @@ static int fou_create(struct net *net, struct fou_cfg *cfg, | |||
| 199 | 179 | ||
| 200 | sk->sk_allocation = GFP_ATOMIC; | 180 | sk->sk_allocation = GFP_ATOMIC; |
| 201 | 181 | ||
| 202 | switch (cfg->udp_config.family) { | 182 | fou->udp_offloads.callbacks.gro_receive = fou_gro_receive; |
| 203 | case AF_INET: | 183 | fou->udp_offloads.callbacks.gro_complete = fou_gro_complete; |
| 204 | fou->udp_offloads.callbacks.gro_receive = fou4_gro_receive; | ||
| 205 | fou->udp_offloads.callbacks.gro_complete = fou4_gro_complete; | ||
| 206 | break; | ||
| 207 | case AF_INET6: | ||
| 208 | fou->udp_offloads.callbacks.gro_receive = fou6_gro_receive; | ||
| 209 | fou->udp_offloads.callbacks.gro_complete = fou6_gro_complete; | ||
| 210 | break; | ||
| 211 | default: | ||
| 212 | err = -EPFNOSUPPORT; | ||
| 213 | goto error; | ||
| 214 | } | ||
| 215 | |||
| 216 | fou->udp_offloads.port = cfg->udp_config.local_udp_port; | 184 | fou->udp_offloads.port = cfg->udp_config.local_udp_port; |
| 217 | fou->udp_offloads.ipproto = cfg->protocol; | 185 | fou->udp_offloads.ipproto = cfg->protocol; |
| 218 | 186 | ||
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 8c35f2c939ee..507310ef4b56 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
| @@ -334,6 +334,7 @@ static struct sk_buff **udp4_gro_receive(struct sk_buff **head, | |||
| 334 | skb_gro_checksum_try_convert(skb, IPPROTO_UDP, uh->check, | 334 | skb_gro_checksum_try_convert(skb, IPPROTO_UDP, uh->check, |
| 335 | inet_gro_compute_pseudo); | 335 | inet_gro_compute_pseudo); |
| 336 | skip: | 336 | skip: |
| 337 | NAPI_GRO_CB(skb)->is_ipv6 = 0; | ||
| 337 | return udp_gro_receive(head, skb, uh); | 338 | return udp_gro_receive(head, skb, uh); |
| 338 | 339 | ||
| 339 | flush: | 340 | flush: |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 8f96988c1db2..6b8f543f6ac6 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
| @@ -140,6 +140,7 @@ static struct sk_buff **udp6_gro_receive(struct sk_buff **head, | |||
| 140 | ip6_gro_compute_pseudo); | 140 | ip6_gro_compute_pseudo); |
| 141 | 141 | ||
| 142 | skip: | 142 | skip: |
| 143 | NAPI_GRO_CB(skb)->is_ipv6 = 1; | ||
| 143 | return udp_gro_receive(head, skb, uh); | 144 | return udp_gro_receive(head, skb, uh); |
| 144 | 145 | ||
| 145 | flush: | 146 | flush: |
