aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--net/ipv4/fou.c48
-rw-r--r--net/ipv4/udp_offload.c1
-rw-r--r--net/ipv6/udp_offload.c1
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
67static struct sk_buff **fou_gro_receive(struct sk_buff **head, 67static 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
88static int fou_gro_complete(struct sk_buff *skb, int nhoff, 89static 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
108static 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
114static int fou4_gro_complete(struct sk_buff *skb, int nhoff)
115{
116 return fou_gro_complete(skb, nhoff, inet_offloads);
117}
118
119static 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
125static int fou6_gro_complete(struct sk_buff *skb, int nhoff)
126{
127 return fou_gro_complete(skb, nhoff, inet6_offloads);
128}
129
130static int fou_add_to_port_list(struct fou *fou) 110static 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);
336skip: 336skip:
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
339flush: 340flush:
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
142skip: 142skip:
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
145flush: 146flush: