aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:06:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:10:36 -0400
commit7b0cfee1a24efdfe0235bac62e53f686fe8a8e24 (patch)
treeeeeb8cc3bf7be5ec0e54b7c4f3808ef88ecca012 /net/ipv6
parent9756fe38d10b2bf90c81dc4d2f17d5632e135364 (diff)
parent6b16351acbd415e66ba16bf7d473ece1574cf0bc (diff)
Merge tag 'v3.5-rc4' into drm-intel-next-queued
I want to merge the "no more fake agp on gen6+" patches into drm-intel-next (well, the last pieces). But a patch in 3.5-rc4 also adds a new use of dev->agp. Hence the backmarge to sort this out, for otherwise drm-intel-next merged into Linus' tree would conflict in the relevant code, things would compile but nicely OOPS at driver load :( Conflicts in this merge are just simple cases of "both branches changed/added lines at the same place". The only tricky part is to keep the order correct wrt the unwind code in case of errors in intel_ringbuffer.c (and the MI_DISPLAY_FLIP #defines in i915_reg.h together, obviously). Conflicts: drivers/gpu/drm/i915/i915_reg.h drivers/gpu/drm/i915/intel_ringbuffer.c Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/esp6.c18
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_output.c69
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/tcp_ipv6.c9
5 files changed, 67 insertions, 33 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 1e62b7557b00..db1521fcda5b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -413,19 +413,15 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
413 struct esp_data *esp = x->data; 413 struct esp_data *esp = x->data;
414 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); 414 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
415 u32 align = max_t(u32, blksize, esp->padlen); 415 u32 align = max_t(u32, blksize, esp->padlen);
416 u32 rem; 416 unsigned int net_adj;
417 417
418 mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); 418 if (x->props.mode != XFRM_MODE_TUNNEL)
419 rem = mtu & (align - 1); 419 net_adj = sizeof(struct ipv6hdr);
420 mtu &= ~(align - 1); 420 else
421 421 net_adj = 0;
422 if (x->props.mode != XFRM_MODE_TUNNEL) {
423 u32 padsize = ((blksize - 1) & 7) + 1;
424 mtu -= blksize - padsize;
425 mtu += min_t(u32, blksize - padsize, rem);
426 }
427 422
428 return mtu - 2; 423 return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
424 net_adj) & ~(align - 1)) + (net_adj - 2);
429} 425}
430 426
431static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 427static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 0c220a416626..74c21b924a79 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1561,7 +1561,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
1561 neigh_flags = neigh->flags; 1561 neigh_flags = neigh->flags;
1562 neigh_release(neigh); 1562 neigh_release(neigh);
1563 } 1563 }
1564 if (neigh_flags & NTF_ROUTER) { 1564 if (!(neigh_flags & NTF_ROUTER)) {
1565 RT6_TRACE("purging route %p via non-router but gateway\n", 1565 RT6_TRACE("purging route %p via non-router but gateway\n",
1566 rt); 1566 rt);
1567 return -1; 1567 return -1;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d99fdc699625..decc21d19c53 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -526,6 +526,7 @@ int ip6_forward(struct sk_buff *skb)
526 hdr->hop_limit--; 526 hdr->hop_limit--;
527 527
528 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); 528 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
529 IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len);
529 return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev, 530 return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
530 ip6_forward_finish); 531 ip6_forward_finish);
531 532
@@ -1187,6 +1188,29 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1187 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; 1188 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
1188} 1189}
1189 1190
1191static void ip6_append_data_mtu(int *mtu,
1192 int *maxfraglen,
1193 unsigned int fragheaderlen,
1194 struct sk_buff *skb,
1195 struct rt6_info *rt)
1196{
1197 if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
1198 if (skb == NULL) {
1199 /* first fragment, reserve header_len */
1200 *mtu = *mtu - rt->dst.header_len;
1201
1202 } else {
1203 /*
1204 * this fragment is not first, the headers
1205 * space is regarded as data space.
1206 */
1207 *mtu = dst_mtu(rt->dst.path);
1208 }
1209 *maxfraglen = ((*mtu - fragheaderlen) & ~7)
1210 + fragheaderlen - sizeof(struct frag_hdr);
1211 }
1212}
1213
1190int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, 1214int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1191 int offset, int len, int odd, struct sk_buff *skb), 1215 int offset, int len, int odd, struct sk_buff *skb),
1192 void *from, int length, int transhdrlen, 1216 void *from, int length, int transhdrlen,
@@ -1196,7 +1220,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1196 struct inet_sock *inet = inet_sk(sk); 1220 struct inet_sock *inet = inet_sk(sk);
1197 struct ipv6_pinfo *np = inet6_sk(sk); 1221 struct ipv6_pinfo *np = inet6_sk(sk);
1198 struct inet_cork *cork; 1222 struct inet_cork *cork;
1199 struct sk_buff *skb; 1223 struct sk_buff *skb, *skb_prev = NULL;
1200 unsigned int maxfraglen, fragheaderlen; 1224 unsigned int maxfraglen, fragheaderlen;
1201 int exthdrlen; 1225 int exthdrlen;
1202 int dst_exthdrlen; 1226 int dst_exthdrlen;
@@ -1253,8 +1277,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1253 inet->cork.fl.u.ip6 = *fl6; 1277 inet->cork.fl.u.ip6 = *fl6;
1254 np->cork.hop_limit = hlimit; 1278 np->cork.hop_limit = hlimit;
1255 np->cork.tclass = tclass; 1279 np->cork.tclass = tclass;
1256 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1280 if (rt->dst.flags & DST_XFRM_TUNNEL)
1257 rt->dst.dev->mtu : dst_mtu(&rt->dst); 1281 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
1282 rt->dst.dev->mtu : dst_mtu(&rt->dst);
1283 else
1284 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
1285 rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1258 if (np->frag_size < mtu) { 1286 if (np->frag_size < mtu) {
1259 if (np->frag_size) 1287 if (np->frag_size)
1260 mtu = np->frag_size; 1288 mtu = np->frag_size;
@@ -1350,25 +1378,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1350 unsigned int fraglen; 1378 unsigned int fraglen;
1351 unsigned int fraggap; 1379 unsigned int fraggap;
1352 unsigned int alloclen; 1380 unsigned int alloclen;
1353 struct sk_buff *skb_prev;
1354alloc_new_skb: 1381alloc_new_skb:
1355 skb_prev = skb;
1356
1357 /* There's no room in the current skb */ 1382 /* There's no room in the current skb */
1358 if (skb_prev) 1383 if (skb)
1359 fraggap = skb_prev->len - maxfraglen; 1384 fraggap = skb->len - maxfraglen;
1360 else 1385 else
1361 fraggap = 0; 1386 fraggap = 0;
1387 /* update mtu and maxfraglen if necessary */
1388 if (skb == NULL || skb_prev == NULL)
1389 ip6_append_data_mtu(&mtu, &maxfraglen,
1390 fragheaderlen, skb, rt);
1391
1392 skb_prev = skb;
1362 1393
1363 /* 1394 /*
1364 * If remaining data exceeds the mtu, 1395 * If remaining data exceeds the mtu,
1365 * we know we need more fragment(s). 1396 * we know we need more fragment(s).
1366 */ 1397 */
1367 datalen = length + fraggap; 1398 datalen = length + fraggap;
1368 if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
1369 datalen = maxfraglen - fragheaderlen;
1370 1399
1371 fraglen = datalen + fragheaderlen; 1400 if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
1401 datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len;
1372 if ((flags & MSG_MORE) && 1402 if ((flags & MSG_MORE) &&
1373 !(rt->dst.dev->features&NETIF_F_SG)) 1403 !(rt->dst.dev->features&NETIF_F_SG))
1374 alloclen = mtu; 1404 alloclen = mtu;
@@ -1377,13 +1407,16 @@ alloc_new_skb:
1377 1407
1378 alloclen += dst_exthdrlen; 1408 alloclen += dst_exthdrlen;
1379 1409
1380 /* 1410 if (datalen != length + fraggap) {
1381 * The last fragment gets additional space at tail. 1411 /*
1382 * Note: we overallocate on fragments with MSG_MODE 1412 * this is not the last fragment, the trailer
1383 * because we have no idea if we're the last one. 1413 * space is regarded as data space.
1384 */ 1414 */
1385 if (datalen == length + fraggap) 1415 datalen += rt->dst.trailer_len;
1386 alloclen += rt->dst.trailer_len; 1416 }
1417
1418 alloclen += rt->dst.trailer_len;
1419 fraglen = datalen + fragheaderlen;
1387 1420
1388 /* 1421 /*
1389 * We just reserve space for fragment header. 1422 * We just reserve space for fragment header.
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index b15dc08643a4..461e47c8e956 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1886,6 +1886,8 @@ static inline int ip6mr_forward2_finish(struct sk_buff *skb)
1886{ 1886{
1887 IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), 1887 IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
1888 IPSTATS_MIB_OUTFORWDATAGRAMS); 1888 IPSTATS_MIB_OUTFORWDATAGRAMS);
1889 IP6_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
1890 IPSTATS_MIB_OUTOCTETS, skb->len);
1889 return dst_output(skb); 1891 return dst_output(skb);
1890} 1892}
1891 1893
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 554d5999abc4..3a9aec29581a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -476,7 +476,8 @@ out:
476 476
477 477
478static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, 478static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
479 struct request_values *rvp) 479 struct request_values *rvp,
480 u16 queue_mapping)
480{ 481{
481 struct inet6_request_sock *treq = inet6_rsk(req); 482 struct inet6_request_sock *treq = inet6_rsk(req);
482 struct ipv6_pinfo *np = inet6_sk(sk); 483 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -513,6 +514,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
513 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 514 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
514 515
515 fl6.daddr = treq->rmt_addr; 516 fl6.daddr = treq->rmt_addr;
517 skb_set_queue_mapping(skb, queue_mapping);
516 err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); 518 err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
517 err = net_xmit_eval(err); 519 err = net_xmit_eval(err);
518 } 520 }
@@ -528,7 +530,7 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
528 struct request_values *rvp) 530 struct request_values *rvp)
529{ 531{
530 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 532 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
531 return tcp_v6_send_synack(sk, req, rvp); 533 return tcp_v6_send_synack(sk, req, rvp, 0);
532} 534}
533 535
534static void tcp_v6_reqsk_destructor(struct request_sock *req) 536static void tcp_v6_reqsk_destructor(struct request_sock *req)
@@ -1213,7 +1215,8 @@ have_isn:
1213 security_inet_conn_request(sk, skb, req); 1215 security_inet_conn_request(sk, skb, req);
1214 1216
1215 if (tcp_v6_send_synack(sk, req, 1217 if (tcp_v6_send_synack(sk, req,
1216 (struct request_values *)&tmp_ext) || 1218 (struct request_values *)&tmp_ext,
1219 skb_get_queue_mapping(skb)) ||
1217 want_cookie) 1220 want_cookie)
1218 goto drop_and_free; 1221 goto drop_and_free;
1219 1222