diff options
author | Sridhar Samudrala <sri@us.ibm.com> | 2009-07-09 04:09:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-12 17:29:21 -0400 |
commit | d7ca4cc01fd154f2da30ae6dae160fa5800af758 (patch) | |
tree | 8e772bbb2320f4b109e20e9e588345bd1a51fb12 /net/ipv4/af_inet.c | |
parent | 30ffee8480c13fbcf8ab6c28e31f79dfff683117 (diff) |
udpv4: Handle large incoming UDP/IPv4 packets and support software UFO.
- validate and forward GSO UDP/IPv4 packets from untrusted sources.
- do software UFO if the outgoing device doesn't support UFO.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 566ea6c4321d..197d024b2536 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1187,6 +1187,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) | |||
1187 | int proto; | 1187 | int proto; |
1188 | int ihl; | 1188 | int ihl; |
1189 | int id; | 1189 | int id; |
1190 | unsigned int offset = 0; | ||
1190 | 1191 | ||
1191 | if (!(features & NETIF_F_V4_CSUM)) | 1192 | if (!(features & NETIF_F_V4_CSUM)) |
1192 | features &= ~NETIF_F_SG; | 1193 | features &= ~NETIF_F_SG; |
@@ -1229,7 +1230,14 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) | |||
1229 | skb = segs; | 1230 | skb = segs; |
1230 | do { | 1231 | do { |
1231 | iph = ip_hdr(skb); | 1232 | iph = ip_hdr(skb); |
1232 | iph->id = htons(id++); | 1233 | if (proto == IPPROTO_UDP) { |
1234 | iph->id = htons(id); | ||
1235 | iph->frag_off = htons(offset >> 3); | ||
1236 | if (skb->next != NULL) | ||
1237 | iph->frag_off |= htons(IP_MF); | ||
1238 | offset += (skb->len - skb->mac_len - iph->ihl * 4); | ||
1239 | } else | ||
1240 | iph->id = htons(id++); | ||
1233 | iph->tot_len = htons(skb->len - skb->mac_len); | 1241 | iph->tot_len = htons(skb->len - skb->mac_len); |
1234 | iph->check = 0; | 1242 | iph->check = 0; |
1235 | iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); | 1243 | iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); |
@@ -1425,6 +1433,8 @@ static struct net_protocol tcp_protocol = { | |||
1425 | static struct net_protocol udp_protocol = { | 1433 | static struct net_protocol udp_protocol = { |
1426 | .handler = udp_rcv, | 1434 | .handler = udp_rcv, |
1427 | .err_handler = udp_err, | 1435 | .err_handler = udp_err, |
1436 | .gso_send_check = udp4_ufo_send_check, | ||
1437 | .gso_segment = udp4_ufo_fragment, | ||
1428 | .no_policy = 1, | 1438 | .no_policy = 1, |
1429 | .netns_ok = 1, | 1439 | .netns_ok = 1, |
1430 | }; | 1440 | }; |