diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 70011e029ac1..19ab78aca547 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -126,9 +126,6 @@ | |||
126 | static struct list_head inetsw[SOCK_MAX]; | 126 | static struct list_head inetsw[SOCK_MAX]; |
127 | static DEFINE_SPINLOCK(inetsw_lock); | 127 | static DEFINE_SPINLOCK(inetsw_lock); |
128 | 128 | ||
129 | struct ipv4_config ipv4_config; | ||
130 | EXPORT_SYMBOL(ipv4_config); | ||
131 | |||
132 | /* New destruction routine */ | 129 | /* New destruction routine */ |
133 | 130 | ||
134 | void inet_sock_destruct(struct sock *sk) | 131 | void inet_sock_destruct(struct sock *sk) |
@@ -342,7 +339,7 @@ lookup_protocol: | |||
342 | inet->hdrincl = 1; | 339 | inet->hdrincl = 1; |
343 | } | 340 | } |
344 | 341 | ||
345 | if (ipv4_config.no_pmtu_disc) | 342 | if (net->ipv4.sysctl_ip_no_pmtu_disc) |
346 | inet->pmtudisc = IP_PMTUDISC_DONT; | 343 | inet->pmtudisc = IP_PMTUDISC_DONT; |
347 | else | 344 | else |
348 | inet->pmtudisc = IP_PMTUDISC_WANT; | 345 | inet->pmtudisc = IP_PMTUDISC_WANT; |
@@ -1133,7 +1130,7 @@ static int inet_sk_reselect_saddr(struct sock *sk) | |||
1133 | fl4 = &inet->cork.fl.u.ip4; | 1130 | fl4 = &inet->cork.fl.u.ip4; |
1134 | rt = ip_route_connect(fl4, daddr, 0, RT_CONN_FLAGS(sk), | 1131 | rt = ip_route_connect(fl4, daddr, 0, RT_CONN_FLAGS(sk), |
1135 | sk->sk_bound_dev_if, sk->sk_protocol, | 1132 | sk->sk_bound_dev_if, sk->sk_protocol, |
1136 | inet->inet_sport, inet->inet_dport, sk, false); | 1133 | inet->inet_sport, inet->inet_dport, sk); |
1137 | if (IS_ERR(rt)) | 1134 | if (IS_ERR(rt)) |
1138 | return PTR_ERR(rt); | 1135 | return PTR_ERR(rt); |
1139 | 1136 | ||
@@ -1299,8 +1296,11 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1299 | 1296 | ||
1300 | segs = ERR_PTR(-EPROTONOSUPPORT); | 1297 | segs = ERR_PTR(-EPROTONOSUPPORT); |
1301 | 1298 | ||
1302 | /* Note : following gso_segment() might change skb->encapsulation */ | 1299 | if (skb->encapsulation && |
1303 | udpfrag = !skb->encapsulation && proto == IPPROTO_UDP; | 1300 | skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP)) |
1301 | udpfrag = proto == IPPROTO_UDP && encap; | ||
1302 | else | ||
1303 | udpfrag = proto == IPPROTO_UDP && !skb->encapsulation; | ||
1304 | 1304 | ||
1305 | ops = rcu_dereference(inet_offloads[proto]); | 1305 | ops = rcu_dereference(inet_offloads[proto]); |
1306 | if (likely(ops && ops->callbacks.gso_segment)) | 1306 | if (likely(ops && ops->callbacks.gso_segment)) |
@@ -1377,8 +1377,12 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1377 | if (!NAPI_GRO_CB(p)->same_flow) | 1377 | if (!NAPI_GRO_CB(p)->same_flow) |
1378 | continue; | 1378 | continue; |
1379 | 1379 | ||
1380 | iph2 = ip_hdr(p); | 1380 | iph2 = (struct iphdr *)(p->data + off); |
1381 | 1381 | /* The above works because, with the exception of the top | |
1382 | * (inner most) layer, we only aggregate pkts with the same | ||
1383 | * hdr length so all the hdrs we'll need to verify will start | ||
1384 | * at the same offset. | ||
1385 | */ | ||
1382 | if ((iph->protocol ^ iph2->protocol) | | 1386 | if ((iph->protocol ^ iph2->protocol) | |
1383 | ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | | 1387 | ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | |
1384 | ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { | 1388 | ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { |
@@ -1390,13 +1394,24 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1390 | NAPI_GRO_CB(p)->flush |= | 1394 | NAPI_GRO_CB(p)->flush |= |
1391 | (iph->ttl ^ iph2->ttl) | | 1395 | (iph->ttl ^ iph2->ttl) | |
1392 | (iph->tos ^ iph2->tos) | | 1396 | (iph->tos ^ iph2->tos) | |
1393 | (__force int)((iph->frag_off ^ iph2->frag_off) & htons(IP_DF)) | | 1397 | ((iph->frag_off ^ iph2->frag_off) & htons(IP_DF)); |
1394 | ((u16)(ntohs(iph2->id) + NAPI_GRO_CB(p)->count) ^ id); | ||
1395 | 1398 | ||
1399 | /* Save the IP ID check to be included later when we get to | ||
1400 | * the transport layer so only the inner most IP ID is checked. | ||
1401 | * This is because some GSO/TSO implementations do not | ||
1402 | * correctly increment the IP ID for the outer hdrs. | ||
1403 | */ | ||
1404 | NAPI_GRO_CB(p)->flush_id = | ||
1405 | ((u16)(ntohs(iph2->id) + NAPI_GRO_CB(p)->count) ^ id); | ||
1396 | NAPI_GRO_CB(p)->flush |= flush; | 1406 | NAPI_GRO_CB(p)->flush |= flush; |
1397 | } | 1407 | } |
1398 | 1408 | ||
1399 | NAPI_GRO_CB(skb)->flush |= flush; | 1409 | NAPI_GRO_CB(skb)->flush |= flush; |
1410 | skb_set_network_header(skb, off); | ||
1411 | /* The above will be needed by the transport layer if there is one | ||
1412 | * immediately following this IP hdr. | ||
1413 | */ | ||
1414 | |||
1400 | skb_gro_pull(skb, sizeof(*iph)); | 1415 | skb_gro_pull(skb, sizeof(*iph)); |
1401 | skb_set_transport_header(skb, skb_gro_offset(skb)); | 1416 | skb_set_transport_header(skb, skb_gro_offset(skb)); |
1402 | 1417 | ||
@@ -1411,10 +1426,10 @@ out: | |||
1411 | return pp; | 1426 | return pp; |
1412 | } | 1427 | } |
1413 | 1428 | ||
1414 | static int inet_gro_complete(struct sk_buff *skb) | 1429 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) |
1415 | { | 1430 | { |
1416 | __be16 newlen = htons(skb->len - skb_network_offset(skb)); | 1431 | __be16 newlen = htons(skb->len - nhoff); |
1417 | struct iphdr *iph = ip_hdr(skb); | 1432 | struct iphdr *iph = (struct iphdr *)(skb->data + nhoff); |
1418 | const struct net_offload *ops; | 1433 | const struct net_offload *ops; |
1419 | int proto = iph->protocol; | 1434 | int proto = iph->protocol; |
1420 | int err = -ENOSYS; | 1435 | int err = -ENOSYS; |
@@ -1427,7 +1442,11 @@ static int inet_gro_complete(struct sk_buff *skb) | |||
1427 | if (WARN_ON(!ops || !ops->callbacks.gro_complete)) | 1442 | if (WARN_ON(!ops || !ops->callbacks.gro_complete)) |
1428 | goto out_unlock; | 1443 | goto out_unlock; |
1429 | 1444 | ||
1430 | err = ops->callbacks.gro_complete(skb); | 1445 | /* Only need to add sizeof(*iph) to get to the next hdr below |
1446 | * because any hdr with option will have been flushed in | ||
1447 | * inet_gro_receive(). | ||
1448 | */ | ||
1449 | err = ops->callbacks.gro_complete(skb, nhoff + sizeof(*iph)); | ||
1431 | 1450 | ||
1432 | out_unlock: | 1451 | out_unlock: |
1433 | rcu_read_unlock(); | 1452 | rcu_read_unlock(); |
@@ -1529,6 +1548,7 @@ static const struct net_protocol tcp_protocol = { | |||
1529 | .err_handler = tcp_v4_err, | 1548 | .err_handler = tcp_v4_err, |
1530 | .no_policy = 1, | 1549 | .no_policy = 1, |
1531 | .netns_ok = 1, | 1550 | .netns_ok = 1, |
1551 | .icmp_strict_tag_validation = 1, | ||
1532 | }; | 1552 | }; |
1533 | 1553 | ||
1534 | static const struct net_protocol udp_protocol = { | 1554 | static const struct net_protocol udp_protocol = { |