aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2015-02-10 19:30:33 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-11 18:12:13 -0500
commitfe881ef11cf0220f118816181930494d484c4883 (patch)
treefc3c9744cddeb0bba07c0ed258de06df4eb01487 /net
parent0ace2ca89cbd6bcdf2b9d2df1fa0fa24ea9d1653 (diff)
gue: Use checksum partial with remote checksum offload
Change remote checksum handling to set checksum partial as default behavior. Added an iflink parameter to configure not using checksum partial (calling csum_partial to update checksum). Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/fou.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index d320f575cc62..ff069f6597ac 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -22,14 +22,18 @@ static LIST_HEAD(fou_list);
22struct fou { 22struct fou {
23 struct socket *sock; 23 struct socket *sock;
24 u8 protocol; 24 u8 protocol;
25 u8 flags;
25 u16 port; 26 u16 port;
26 struct udp_offload udp_offloads; 27 struct udp_offload udp_offloads;
27 struct list_head list; 28 struct list_head list;
28}; 29};
29 30
31#define FOU_F_REMCSUM_NOPARTIAL BIT(0)
32
30struct fou_cfg { 33struct fou_cfg {
31 u16 type; 34 u16 type;
32 u8 protocol; 35 u8 protocol;
36 u8 flags;
33 struct udp_port_cfg udp_config; 37 struct udp_port_cfg udp_config;
34}; 38};
35 39
@@ -64,7 +68,8 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
64} 68}
65 69
66static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, 70static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
67 void *data, size_t hdrlen, u8 ipproto) 71 void *data, size_t hdrlen, u8 ipproto,
72 bool nopartial)
68{ 73{
69 __be16 *pd = data; 74 __be16 *pd = data;
70 size_t start = ntohs(pd[0]); 75 size_t start = ntohs(pd[0]);
@@ -75,7 +80,8 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
75 return NULL; 80 return NULL;
76 guehdr = (struct guehdr *)&udp_hdr(skb)[1]; 81 guehdr = (struct guehdr *)&udp_hdr(skb)[1];
77 82
78 skb_remcsum_process(skb, (void *)guehdr + hdrlen, start, offset, true); 83 skb_remcsum_process(skb, (void *)guehdr + hdrlen,
84 start, offset, nopartial);
79 85
80 return guehdr; 86 return guehdr;
81} 87}
@@ -136,7 +142,9 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
136 142
137 if (flags & GUE_PFLAG_REMCSUM) { 143 if (flags & GUE_PFLAG_REMCSUM) {
138 guehdr = gue_remcsum(skb, guehdr, data + doffset, 144 guehdr = gue_remcsum(skb, guehdr, data + doffset,
139 hdrlen, guehdr->proto_ctype); 145 hdrlen, guehdr->proto_ctype,
146 !!(fou->flags &
147 FOU_F_REMCSUM_NOPARTIAL));
140 if (!guehdr) 148 if (!guehdr)
141 goto drop; 149 goto drop;
142 150
@@ -209,7 +217,7 @@ out_unlock:
209static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, 217static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
210 struct guehdr *guehdr, void *data, 218 struct guehdr *guehdr, void *data,
211 size_t hdrlen, u8 ipproto, 219 size_t hdrlen, u8 ipproto,
212 struct gro_remcsum *grc) 220 struct gro_remcsum *grc, bool nopartial)
213{ 221{
214 __be16 *pd = data; 222 __be16 *pd = data;
215 size_t start = ntohs(pd[0]); 223 size_t start = ntohs(pd[0]);
@@ -230,7 +238,7 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
230 } 238 }
231 239
232 skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen, 240 skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen,
233 start, offset, grc, true); 241 start, offset, grc, nopartial);
234 242
235 skb->remcsum_offload = 1; 243 skb->remcsum_offload = 1;
236 244
@@ -250,6 +258,7 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
250 void *data; 258 void *data;
251 u16 doffset = 0; 259 u16 doffset = 0;
252 int flush = 1; 260 int flush = 1;
261 struct fou *fou = container_of(uoff, struct fou, udp_offloads);
253 struct gro_remcsum grc; 262 struct gro_remcsum grc;
254 263
255 skb_gro_remcsum_init(&grc); 264 skb_gro_remcsum_init(&grc);
@@ -294,7 +303,9 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
294 if (flags & GUE_PFLAG_REMCSUM) { 303 if (flags & GUE_PFLAG_REMCSUM) {
295 guehdr = gue_gro_remcsum(skb, off, guehdr, 304 guehdr = gue_gro_remcsum(skb, off, guehdr,
296 data + doffset, hdrlen, 305 data + doffset, hdrlen,
297 guehdr->proto_ctype, &grc); 306 guehdr->proto_ctype, &grc,
307 !!(fou->flags &
308 FOU_F_REMCSUM_NOPARTIAL));
298 if (!guehdr) 309 if (!guehdr)
299 goto out; 310 goto out;
300 311
@@ -455,6 +466,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
455 466
456 sk = sock->sk; 467 sk = sock->sk;
457 468
469 fou->flags = cfg->flags;
458 fou->port = cfg->udp_config.local_udp_port; 470 fou->port = cfg->udp_config.local_udp_port;
459 471
460 /* Initial for fou type */ 472 /* Initial for fou type */
@@ -541,6 +553,7 @@ static struct nla_policy fou_nl_policy[FOU_ATTR_MAX + 1] = {
541 [FOU_ATTR_AF] = { .type = NLA_U8, }, 553 [FOU_ATTR_AF] = { .type = NLA_U8, },
542 [FOU_ATTR_IPPROTO] = { .type = NLA_U8, }, 554 [FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
543 [FOU_ATTR_TYPE] = { .type = NLA_U8, }, 555 [FOU_ATTR_TYPE] = { .type = NLA_U8, },
556 [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, },
544}; 557};
545 558
546static int parse_nl_config(struct genl_info *info, 559static int parse_nl_config(struct genl_info *info,
@@ -571,6 +584,9 @@ static int parse_nl_config(struct genl_info *info,
571 if (info->attrs[FOU_ATTR_TYPE]) 584 if (info->attrs[FOU_ATTR_TYPE])
572 cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]); 585 cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]);
573 586
587 if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL])
588 cfg->flags |= FOU_F_REMCSUM_NOPARTIAL;
589
574 return 0; 590 return 0;
575} 591}
576 592