aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-05-10 12:39:28 -0400
committerPatrick McHardy <kaber@trash.net>2010-05-10 12:39:28 -0400
commit1e4b1057121bc756b91758a434b504d2010f6088 (patch)
treeb016cf2c728289c7e36d9e4e488f30ab0bd0ae6e /net/ipv6
parent3b254c54ec46eb022cb26ee6ab37fae23f5f7d6a (diff)
parent3ee943728fff536edaf8f59faa58aaa1aa7366e3 (diff)
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts: net/bridge/br_device.c net/bridge/br_forward.c Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c19
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/datagram.c108
-rw-r--r--net/ipv6/fib6_rules.c4
-rw-r--r--net/ipv6/icmp.c5
-rw-r--r--net/ipv6/ip6_fib.c3
-rw-r--r--net/ipv6/ip6_flowlabel.c3
-rw-r--r--net/ipv6/ip6_output.c33
-rw-r--r--net/ipv6/ipv6_sockglue.c61
-rw-r--r--net/ipv6/mcast.c135
-rw-r--r--net/ipv6/raw.c14
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/tcp_ipv6.c25
-rw-r--r--net/ipv6/udp.c41
-rw-r--r--net/ipv6/xfrm6_policy.c2
15 files changed, 312 insertions, 146 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7cba8845242f..3984f52181f4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -588,7 +588,8 @@ static u32 ipv6_addr_hash(const struct in6_addr *addr)
588 * We perform the hash function over the last 64 bits of the address 588 * We perform the hash function over the last 64 bits of the address
589 * This will include the IEEE address token on links that support it. 589 * This will include the IEEE address token on links that support it.
590 */ 590 */
591 return jhash_2words(addr->s6_addr32[2], addr->s6_addr32[3], 0) 591 return jhash_2words((__force u32)addr->s6_addr32[2],
592 (__force u32)addr->s6_addr32[3], 0)
592 & (IN6_ADDR_HSIZE - 1); 593 & (IN6_ADDR_HSIZE - 1);
593} 594}
594 595
@@ -1345,7 +1346,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *add
1345 struct hlist_node *node; 1346 struct hlist_node *node;
1346 1347
1347 rcu_read_lock_bh(); 1348 rcu_read_lock_bh();
1348 hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) { 1349 hlist_for_each_entry_rcu_bh(ifp, node, &inet6_addr_lst[hash], addr_lst) {
1349 if (!net_eq(dev_net(ifp->idev->dev), net)) 1350 if (!net_eq(dev_net(ifp->idev->dev), net))
1350 continue; 1351 continue;
1351 if (ipv6_addr_equal(&ifp->addr, addr)) { 1352 if (ipv6_addr_equal(&ifp->addr, addr)) {
@@ -2958,7 +2959,7 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
2958 2959
2959 for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { 2960 for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
2960 struct hlist_node *n; 2961 struct hlist_node *n;
2961 hlist_for_each_entry_rcu(ifa, n, &inet6_addr_lst[state->bucket], 2962 hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket],
2962 addr_lst) 2963 addr_lst)
2963 if (net_eq(dev_net(ifa->idev->dev), net)) 2964 if (net_eq(dev_net(ifa->idev->dev), net))
2964 return ifa; 2965 return ifa;
@@ -2973,12 +2974,12 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
2973 struct net *net = seq_file_net(seq); 2974 struct net *net = seq_file_net(seq);
2974 struct hlist_node *n = &ifa->addr_lst; 2975 struct hlist_node *n = &ifa->addr_lst;
2975 2976
2976 hlist_for_each_entry_continue_rcu(ifa, n, addr_lst) 2977 hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst)
2977 if (net_eq(dev_net(ifa->idev->dev), net)) 2978 if (net_eq(dev_net(ifa->idev->dev), net))
2978 return ifa; 2979 return ifa;
2979 2980
2980 while (++state->bucket < IN6_ADDR_HSIZE) { 2981 while (++state->bucket < IN6_ADDR_HSIZE) {
2981 hlist_for_each_entry(ifa, n, 2982 hlist_for_each_entry_rcu_bh(ifa, n,
2982 &inet6_addr_lst[state->bucket], addr_lst) { 2983 &inet6_addr_lst[state->bucket], addr_lst) {
2983 if (net_eq(dev_net(ifa->idev->dev), net)) 2984 if (net_eq(dev_net(ifa->idev->dev), net))
2984 return ifa; 2985 return ifa;
@@ -2999,7 +3000,7 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
2999} 3000}
3000 3001
3001static void *if6_seq_start(struct seq_file *seq, loff_t *pos) 3002static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
3002 __acquires(rcu) 3003 __acquires(rcu_bh)
3003{ 3004{
3004 rcu_read_lock_bh(); 3005 rcu_read_lock_bh();
3005 return if6_get_idx(seq, *pos); 3006 return if6_get_idx(seq, *pos);
@@ -3015,7 +3016,7 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3015} 3016}
3016 3017
3017static void if6_seq_stop(struct seq_file *seq, void *v) 3018static void if6_seq_stop(struct seq_file *seq, void *v)
3018 __releases(rcu) 3019 __releases(rcu_bh)
3019{ 3020{
3020 rcu_read_unlock_bh(); 3021 rcu_read_unlock_bh();
3021} 3022}
@@ -3092,7 +3093,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
3092 unsigned int hash = ipv6_addr_hash(addr); 3093 unsigned int hash = ipv6_addr_hash(addr);
3093 3094
3094 rcu_read_lock_bh(); 3095 rcu_read_lock_bh();
3095 hlist_for_each_entry_rcu(ifp, n, &inet6_addr_lst[hash], addr_lst) { 3096 hlist_for_each_entry_rcu_bh(ifp, n, &inet6_addr_lst[hash], addr_lst) {
3096 if (!net_eq(dev_net(ifp->idev->dev), net)) 3097 if (!net_eq(dev_net(ifp->idev->dev), net))
3097 continue; 3098 continue;
3098 if (ipv6_addr_equal(&ifp->addr, addr) && 3099 if (ipv6_addr_equal(&ifp->addr, addr) &&
@@ -3126,7 +3127,7 @@ static void addrconf_verify(unsigned long foo)
3126 3127
3127 for (i = 0; i < IN6_ADDR_HSIZE; i++) { 3128 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
3128restart: 3129restart:
3129 hlist_for_each_entry_rcu(ifp, node, 3130 hlist_for_each_entry_rcu_bh(ifp, node,
3130 &inet6_addr_lst[i], addr_lst) { 3131 &inet6_addr_lst[i], addr_lst) {
3131 unsigned long age; 3132 unsigned long age;
3132 3133
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 3192aa02ba5d..d2df3144429b 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -417,6 +417,9 @@ void inet6_destroy_sock(struct sock *sk)
417 if ((skb = xchg(&np->pktoptions, NULL)) != NULL) 417 if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
418 kfree_skb(skb); 418 kfree_skb(skb);
419 419
420 if ((skb = xchg(&np->rxpmtu, NULL)) != NULL)
421 kfree_skb(skb);
422
420 /* Free flowlabels */ 423 /* Free flowlabels */
421 fl6_free_socklist(sk); 424 fl6_free_socklist(sk);
422 425
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 622dc7939a1b..5959230bc6c1 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -278,6 +278,45 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
278 kfree_skb(skb); 278 kfree_skb(skb);
279} 279}
280 280
281void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu)
282{
283 struct ipv6_pinfo *np = inet6_sk(sk);
284 struct ipv6hdr *iph;
285 struct sk_buff *skb;
286 struct ip6_mtuinfo *mtu_info;
287
288 if (!np->rxopt.bits.rxpmtu)
289 return;
290
291 skb = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
292 if (!skb)
293 return;
294
295 skb_put(skb, sizeof(struct ipv6hdr));
296 skb_reset_network_header(skb);
297 iph = ipv6_hdr(skb);
298 ipv6_addr_copy(&iph->daddr, &fl->fl6_dst);
299
300 mtu_info = IP6CBMTU(skb);
301 if (!mtu_info) {
302 kfree_skb(skb);
303 return;
304 }
305
306 mtu_info->ip6m_mtu = mtu;
307 mtu_info->ip6m_addr.sin6_family = AF_INET6;
308 mtu_info->ip6m_addr.sin6_port = 0;
309 mtu_info->ip6m_addr.sin6_flowinfo = 0;
310 mtu_info->ip6m_addr.sin6_scope_id = fl->oif;
311 ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr);
312
313 __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
314 skb_reset_transport_header(skb);
315
316 skb = xchg(&np->rxpmtu, skb);
317 kfree_skb(skb);
318}
319
281/* 320/*
282 * Handle MSG_ERRQUEUE 321 * Handle MSG_ERRQUEUE
283 */ 322 */
@@ -381,6 +420,54 @@ out:
381 return err; 420 return err;
382} 421}
383 422
423/*
424 * Handle IPV6_RECVPATHMTU
425 */
426int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
427{
428 struct ipv6_pinfo *np = inet6_sk(sk);
429 struct sk_buff *skb;
430 struct sockaddr_in6 *sin;
431 struct ip6_mtuinfo mtu_info;
432 int err;
433 int copied;
434
435 err = -EAGAIN;
436 skb = xchg(&np->rxpmtu, NULL);
437 if (skb == NULL)
438 goto out;
439
440 copied = skb->len;
441 if (copied > len) {
442 msg->msg_flags |= MSG_TRUNC;
443 copied = len;
444 }
445 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
446 if (err)
447 goto out_free_skb;
448
449 sock_recv_timestamp(msg, sk, skb);
450
451 memcpy(&mtu_info, IP6CBMTU(skb), sizeof(mtu_info));
452
453 sin = (struct sockaddr_in6 *)msg->msg_name;
454 if (sin) {
455 sin->sin6_family = AF_INET6;
456 sin->sin6_flowinfo = 0;
457 sin->sin6_port = 0;
458 sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
459 ipv6_addr_copy(&sin->sin6_addr, &mtu_info.ip6m_addr.sin6_addr);
460 }
461
462 put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
463
464 err = copied;
465
466out_free_skb:
467 kfree_skb(skb);
468out:
469 return err;
470}
384 471
385 472
386int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) 473int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
@@ -497,7 +584,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
497int datagram_send_ctl(struct net *net, 584int datagram_send_ctl(struct net *net,
498 struct msghdr *msg, struct flowi *fl, 585 struct msghdr *msg, struct flowi *fl,
499 struct ipv6_txoptions *opt, 586 struct ipv6_txoptions *opt,
500 int *hlimit, int *tclass) 587 int *hlimit, int *tclass, int *dontfrag)
501{ 588{
502 struct in6_pktinfo *src_info; 589 struct in6_pktinfo *src_info;
503 struct cmsghdr *cmsg; 590 struct cmsghdr *cmsg;
@@ -737,6 +824,25 @@ int datagram_send_ctl(struct net *net,
737 824
738 break; 825 break;
739 } 826 }
827
828 case IPV6_DONTFRAG:
829 {
830 int df;
831
832 err = -EINVAL;
833 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
834 goto exit_f;
835 }
836
837 df = *(int *)CMSG_DATA(cmsg);
838 if (df < 0 || df > 1)
839 goto exit_f;
840
841 err = 0;
842 *dontfrag = df;
843
844 break;
845 }
740 default: 846 default:
741 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", 847 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
742 cmsg->cmsg_type); 848 cmsg->cmsg_type);
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 8124f16f2ac2..8e44f8f9c188 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -237,8 +237,8 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
237 + nla_total_size(16); /* src */ 237 + nla_total_size(16); /* src */
238} 238}
239 239
240static struct fib_rules_ops fib6_rules_ops_template = { 240static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = {
241 .family = FIB_RULES_IPV6, 241 .family = AF_INET6,
242 .rule_size = sizeof(struct fib6_rule), 242 .rule_size = sizeof(struct fib6_rule),
243 .addr_size = sizeof(struct in6_addr), 243 .addr_size = sizeof(struct in6_addr),
244 .action = fib6_rule_action, 244 .action = fib6_rule_action,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 12d2fa42657d..ce7992982557 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -481,7 +481,7 @@ route_done:
481 len + sizeof(struct icmp6hdr), 481 len + sizeof(struct icmp6hdr),
482 sizeof(struct icmp6hdr), hlimit, 482 sizeof(struct icmp6hdr), hlimit,
483 np->tclass, NULL, &fl, (struct rt6_info*)dst, 483 np->tclass, NULL, &fl, (struct rt6_info*)dst,
484 MSG_DONTWAIT); 484 MSG_DONTWAIT, np->dontfrag);
485 if (err) { 485 if (err) {
486 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 486 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
487 ip6_flush_pending_frames(sk); 487 ip6_flush_pending_frames(sk);
@@ -561,7 +561,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
561 561
562 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 562 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
563 sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl, 563 sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl,
564 (struct rt6_info*)dst, MSG_DONTWAIT); 564 (struct rt6_info*)dst, MSG_DONTWAIT,
565 np->dontfrag);
565 566
566 if (err) { 567 if (err) {
567 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 568 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index dc6e0b8f260d..92a122b7795d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -144,7 +144,8 @@ static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
144 * htonl(1 << ((~fn_bit)&0x1F)) 144 * htonl(1 << ((~fn_bit)&0x1F))
145 * See include/asm-generic/bitops/le.h. 145 * See include/asm-generic/bitops/le.h.
146 */ 146 */
147 return (1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & addr[fn_bit >> 5]; 147 return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
148 addr[fn_bit >> 5];
148} 149}
149 150
150static __inline__ struct fib6_node * node_alloc(void) 151static __inline__ struct fib6_node * node_alloc(void)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 14e23216eb28..13654686aeab 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -360,7 +360,8 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval,
360 msg.msg_control = (void*)(fl->opt+1); 360 msg.msg_control = (void*)(fl->opt+1);
361 flowi.oif = 0; 361 flowi.oif = 0;
362 362
363 err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, &junk); 363 err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk,
364 &junk, &junk);
364 if (err) 365 if (err)
365 goto done; 366 goto done;
366 err = -EINVAL; 367 err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 7f12e30cfa73..5173acaeb501 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -92,7 +92,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
92 newskb->ip_summed = CHECKSUM_UNNECESSARY; 92 newskb->ip_summed = CHECKSUM_UNNECESSARY;
93 WARN_ON(!skb_dst(newskb)); 93 WARN_ON(!skb_dst(newskb));
94 94
95 netif_rx(newskb); 95 netif_rx_ni(newskb);
96 return 0; 96 return 0;
97} 97}
98 98
@@ -216,8 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
216 } 216 }
217 kfree_skb(skb); 217 kfree_skb(skb);
218 skb = skb2; 218 skb = skb2;
219 if (sk) 219 skb_set_owner_w(skb, sk);
220 skb_set_owner_w(skb, sk);
221 } 220 }
222 if (opt->opt_flen) 221 if (opt->opt_flen)
223 ipv6_push_frag_opts(skb, opt, &proto); 222 ipv6_push_frag_opts(skb, opt, &proto);
@@ -623,7 +622,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
623 /* We must not fragment if the socket is set to force MTU discovery 622 /* We must not fragment if the socket is set to force MTU discovery
624 * or if the skb it not generated by a local socket. 623 * or if the skb it not generated by a local socket.
625 */ 624 */
626 if (!skb->local_df) { 625 if (!skb->local_df && skb->len > mtu) {
627 skb->dev = skb_dst(skb)->dev; 626 skb->dev = skb_dst(skb)->dev;
628 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 627 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
629 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 628 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
@@ -1103,7 +1102,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1103 int offset, int len, int odd, struct sk_buff *skb), 1102 int offset, int len, int odd, struct sk_buff *skb),
1104 void *from, int length, int transhdrlen, 1103 void *from, int length, int transhdrlen,
1105 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, 1104 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
1106 struct rt6_info *rt, unsigned int flags) 1105 struct rt6_info *rt, unsigned int flags, int dontfrag)
1107{ 1106{
1108 struct inet_sock *inet = inet_sk(sk); 1107 struct inet_sock *inet = inet_sk(sk);
1109 struct ipv6_pinfo *np = inet6_sk(sk); 1108 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -1217,15 +1216,23 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1217 */ 1216 */
1218 1217
1219 inet->cork.length += length; 1218 inet->cork.length += length;
1220 if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && 1219 if (length > mtu) {
1221 (rt->u.dst.dev->features & NETIF_F_UFO)) { 1220 int proto = sk->sk_protocol;
1221 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
1222 ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen);
1223 return -EMSGSIZE;
1224 }
1222 1225
1223 err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, 1226 if (proto == IPPROTO_UDP &&
1224 fragheaderlen, transhdrlen, mtu, 1227 (rt->u.dst.dev->features & NETIF_F_UFO)) {
1225 flags); 1228
1226 if (err) 1229 err = ip6_ufo_append_data(sk, getfrag, from, length,
1227 goto error; 1230 hh_len, fragheaderlen,
1228 return 0; 1231 transhdrlen, mtu, flags);
1232 if (err)
1233 goto error;
1234 return 0;
1235 }
1229 } 1236 }
1230 1237
1231 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) 1238 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1160400e9dbd..bd43f0152c21 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
337 retv = 0; 337 retv = 0;
338 break; 338 break;
339 339
340 case IPV6_RECVPATHMTU:
341 if (optlen < sizeof(int))
342 goto e_inval;
343 np->rxopt.bits.rxpmtu = valbool;
344 retv = 0;
345 break;
346
340 case IPV6_HOPOPTS: 347 case IPV6_HOPOPTS:
341 case IPV6_RTHDRDSTOPTS: 348 case IPV6_RTHDRDSTOPTS:
342 case IPV6_RTHDR: 349 case IPV6_RTHDR:
@@ -451,7 +458,8 @@ sticky_done:
451 msg.msg_controllen = optlen; 458 msg.msg_controllen = optlen;
452 msg.msg_control = (void*)(opt+1); 459 msg.msg_control = (void*)(opt+1);
453 460
454 retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); 461 retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk,
462 &junk);
455 if (retv) 463 if (retv)
456 goto done; 464 goto done;
457update: 465update:
@@ -767,6 +775,17 @@ pref_skip_coa:
767 775
768 break; 776 break;
769 } 777 }
778 case IPV6_MINHOPCOUNT:
779 if (optlen < sizeof(int))
780 goto e_inval;
781 if (val < 0 || val > 255)
782 goto e_inval;
783 np->min_hopcount = val;
784 break;
785 case IPV6_DONTFRAG:
786 np->dontfrag = valbool;
787 retv = 0;
788 break;
770 } 789 }
771 790
772 release_sock(sk); 791 release_sock(sk);
@@ -1055,6 +1074,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1055 val = np->rxopt.bits.rxflow; 1074 val = np->rxopt.bits.rxflow;
1056 break; 1075 break;
1057 1076
1077 case IPV6_RECVPATHMTU:
1078 val = np->rxopt.bits.rxpmtu;
1079 break;
1080
1081 case IPV6_PATHMTU:
1082 {
1083 struct dst_entry *dst;
1084 struct ip6_mtuinfo mtuinfo;
1085
1086 if (len < sizeof(mtuinfo))
1087 return -EINVAL;
1088
1089 len = sizeof(mtuinfo);
1090 memset(&mtuinfo, 0, sizeof(mtuinfo));
1091
1092 rcu_read_lock();
1093 dst = __sk_dst_get(sk);
1094 if (dst)
1095 mtuinfo.ip6m_mtu = dst_mtu(dst);
1096 rcu_read_unlock();
1097 if (!mtuinfo.ip6m_mtu)
1098 return -ENOTCONN;
1099
1100 if (put_user(len, optlen))
1101 return -EFAULT;
1102 if (copy_to_user(optval, &mtuinfo, len))
1103 return -EFAULT;
1104
1105 return 0;
1106 break;
1107 }
1108
1058 case IPV6_UNICAST_HOPS: 1109 case IPV6_UNICAST_HOPS:
1059 case IPV6_MULTICAST_HOPS: 1110 case IPV6_MULTICAST_HOPS:
1060 { 1111 {
@@ -1116,6 +1167,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1116 val |= IPV6_PREFER_SRC_HOME; 1167 val |= IPV6_PREFER_SRC_HOME;
1117 break; 1168 break;
1118 1169
1170 case IPV6_MINHOPCOUNT:
1171 val = np->min_hopcount;
1172 break;
1173
1174 case IPV6_DONTFRAG:
1175 val = np->dontfrag;
1176 break;
1177
1119 default: 1178 default:
1120 return -ENOPROTOOPT; 1179 return -ENOPROTOOPT;
1121 } 1180 }
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f9d05ce4e03a..59f1881968c7 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -44,6 +44,7 @@
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/seq_file.h> 45#include <linux/seq_file.h>
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <net/mld.h>
47 48
48#include <linux/netfilter.h> 49#include <linux/netfilter.h>
49#include <linux/netfilter_ipv6.h> 50#include <linux/netfilter_ipv6.h>
@@ -71,54 +72,11 @@
71#define MDBG(x) 72#define MDBG(x)
72#endif 73#endif
73 74
74/* 75/* Ensure that we have struct in6_addr aligned on 32bit word. */
75 * These header formats should be in a separate include file, but icmpv6.h 76static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
76 * doesn't have in6_addr defined in all cases, there is no __u128, and no 77 BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4),
77 * other files reference these. 78 BUILD_BUG_ON_NULL(offsetof(struct mld2_report, mld2r_grec) % 4),
78 * 79 BUILD_BUG_ON_NULL(offsetof(struct mld2_grec, grec_mca) % 4)
79 * +-DLS 4/14/03
80 */
81
82/* Multicast Listener Discovery version 2 headers */
83
84struct mld2_grec {
85 __u8 grec_type;
86 __u8 grec_auxwords;
87 __be16 grec_nsrcs;
88 struct in6_addr grec_mca;
89 struct in6_addr grec_src[0];
90};
91
92struct mld2_report {
93 __u8 type;
94 __u8 resv1;
95 __sum16 csum;
96 __be16 resv2;
97 __be16 ngrec;
98 struct mld2_grec grec[0];
99};
100
101struct mld2_query {
102 __u8 type;
103 __u8 code;
104 __sum16 csum;
105 __be16 mrc;
106 __be16 resv1;
107 struct in6_addr mca;
108#if defined(__LITTLE_ENDIAN_BITFIELD)
109 __u8 qrv:3,
110 suppress:1,
111 resv2:4;
112#elif defined(__BIG_ENDIAN_BITFIELD)
113 __u8 resv2:4,
114 suppress:1,
115 qrv:3;
116#else
117#error "Please fix <asm/byteorder.h>"
118#endif
119 __u8 qqic;
120 __be16 nsrcs;
121 struct in6_addr srcs[0];
122}; 80};
123 81
124static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; 82static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
@@ -157,14 +115,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
157 ((idev)->mc_v1_seen && \ 115 ((idev)->mc_v1_seen && \
158 time_before(jiffies, (idev)->mc_v1_seen))) 116 time_before(jiffies, (idev)->mc_v1_seen)))
159 117
160#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
161#define MLDV2_EXP(thresh, nbmant, nbexp, value) \
162 ((value) < (thresh) ? (value) : \
163 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
164 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
165
166#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
167
168#define IPV6_MLD_MAX_MSF 64 118#define IPV6_MLD_MAX_MSF 64
169 119
170int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; 120int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
@@ -1161,7 +1111,7 @@ int igmp6_event_query(struct sk_buff *skb)
1161 struct in6_addr *group; 1111 struct in6_addr *group;
1162 unsigned long max_delay; 1112 unsigned long max_delay;
1163 struct inet6_dev *idev; 1113 struct inet6_dev *idev;
1164 struct icmp6hdr *hdr; 1114 struct mld_msg *mld;
1165 int group_type; 1115 int group_type;
1166 int mark = 0; 1116 int mark = 0;
1167 int len; 1117 int len;
@@ -1182,8 +1132,8 @@ int igmp6_event_query(struct sk_buff *skb)
1182 if (idev == NULL) 1132 if (idev == NULL)
1183 return 0; 1133 return 0;
1184 1134
1185 hdr = icmp6_hdr(skb); 1135 mld = (struct mld_msg *)icmp6_hdr(skb);
1186 group = (struct in6_addr *) (hdr + 1); 1136 group = &mld->mld_mca;
1187 group_type = ipv6_addr_type(group); 1137 group_type = ipv6_addr_type(group);
1188 1138
1189 if (group_type != IPV6_ADDR_ANY && 1139 if (group_type != IPV6_ADDR_ANY &&
@@ -1197,7 +1147,7 @@ int igmp6_event_query(struct sk_buff *skb)
1197 /* MLDv1 router present */ 1147 /* MLDv1 router present */
1198 1148
1199 /* Translate milliseconds to jiffies */ 1149 /* Translate milliseconds to jiffies */
1200 max_delay = (ntohs(hdr->icmp6_maxdelay)*HZ)/1000; 1150 max_delay = (ntohs(mld->mld_maxdelay)*HZ)/1000;
1201 1151
1202 switchback = (idev->mc_qrv + 1) * max_delay; 1152 switchback = (idev->mc_qrv + 1) * max_delay;
1203 idev->mc_v1_seen = jiffies + switchback; 1153 idev->mc_v1_seen = jiffies + switchback;
@@ -1216,14 +1166,14 @@ int igmp6_event_query(struct sk_buff *skb)
1216 return -EINVAL; 1166 return -EINVAL;
1217 } 1167 }
1218 mlh2 = (struct mld2_query *)skb_transport_header(skb); 1168 mlh2 = (struct mld2_query *)skb_transport_header(skb);
1219 max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; 1169 max_delay = (MLDV2_MRC(ntohs(mlh2->mld2q_mrc))*HZ)/1000;
1220 if (!max_delay) 1170 if (!max_delay)
1221 max_delay = 1; 1171 max_delay = 1;
1222 idev->mc_maxdelay = max_delay; 1172 idev->mc_maxdelay = max_delay;
1223 if (mlh2->qrv) 1173 if (mlh2->mld2q_qrv)
1224 idev->mc_qrv = mlh2->qrv; 1174 idev->mc_qrv = mlh2->mld2q_qrv;
1225 if (group_type == IPV6_ADDR_ANY) { /* general query */ 1175 if (group_type == IPV6_ADDR_ANY) { /* general query */
1226 if (mlh2->nsrcs) { 1176 if (mlh2->mld2q_nsrcs) {
1227 in6_dev_put(idev); 1177 in6_dev_put(idev);
1228 return -EINVAL; /* no sources allowed */ 1178 return -EINVAL; /* no sources allowed */
1229 } 1179 }
@@ -1232,9 +1182,9 @@ int igmp6_event_query(struct sk_buff *skb)
1232 return 0; 1182 return 0;
1233 } 1183 }
1234 /* mark sources to include, if group & source-specific */ 1184 /* mark sources to include, if group & source-specific */
1235 if (mlh2->nsrcs != 0) { 1185 if (mlh2->mld2q_nsrcs != 0) {
1236 if (!pskb_may_pull(skb, srcs_offset + 1186 if (!pskb_may_pull(skb, srcs_offset +
1237 ntohs(mlh2->nsrcs) * sizeof(struct in6_addr))) { 1187 ntohs(mlh2->mld2q_nsrcs) * sizeof(struct in6_addr))) {
1238 in6_dev_put(idev); 1188 in6_dev_put(idev);
1239 return -EINVAL; 1189 return -EINVAL;
1240 } 1190 }
@@ -1270,7 +1220,7 @@ int igmp6_event_query(struct sk_buff *skb)
1270 ma->mca_flags &= ~MAF_GSQUERY; 1220 ma->mca_flags &= ~MAF_GSQUERY;
1271 } 1221 }
1272 if (!(ma->mca_flags & MAF_GSQUERY) || 1222 if (!(ma->mca_flags & MAF_GSQUERY) ||
1273 mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs)) 1223 mld_marksources(ma, ntohs(mlh2->mld2q_nsrcs), mlh2->mld2q_srcs))
1274 igmp6_group_queried(ma, max_delay); 1224 igmp6_group_queried(ma, max_delay);
1275 spin_unlock_bh(&ma->mca_lock); 1225 spin_unlock_bh(&ma->mca_lock);
1276 break; 1226 break;
@@ -1286,9 +1236,8 @@ int igmp6_event_query(struct sk_buff *skb)
1286int igmp6_event_report(struct sk_buff *skb) 1236int igmp6_event_report(struct sk_buff *skb)
1287{ 1237{
1288 struct ifmcaddr6 *ma; 1238 struct ifmcaddr6 *ma;
1289 struct in6_addr *addrp;
1290 struct inet6_dev *idev; 1239 struct inet6_dev *idev;
1291 struct icmp6hdr *hdr; 1240 struct mld_msg *mld;
1292 int addr_type; 1241 int addr_type;
1293 1242
1294 /* Our own report looped back. Ignore it. */ 1243 /* Our own report looped back. Ignore it. */
@@ -1300,10 +1249,10 @@ int igmp6_event_report(struct sk_buff *skb)
1300 skb->pkt_type != PACKET_BROADCAST) 1249 skb->pkt_type != PACKET_BROADCAST)
1301 return 0; 1250 return 0;
1302 1251
1303 if (!pskb_may_pull(skb, sizeof(struct in6_addr))) 1252 if (!pskb_may_pull(skb, sizeof(*mld) - sizeof(struct icmp6hdr)))
1304 return -EINVAL; 1253 return -EINVAL;
1305 1254
1306 hdr = icmp6_hdr(skb); 1255 mld = (struct mld_msg *)icmp6_hdr(skb);
1307 1256
1308 /* Drop reports with not link local source */ 1257 /* Drop reports with not link local source */
1309 addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr); 1258 addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr);
@@ -1311,8 +1260,6 @@ int igmp6_event_report(struct sk_buff *skb)
1311 !(addr_type&IPV6_ADDR_LINKLOCAL)) 1260 !(addr_type&IPV6_ADDR_LINKLOCAL))
1312 return -EINVAL; 1261 return -EINVAL;
1313 1262
1314 addrp = (struct in6_addr *) (hdr + 1);
1315
1316 idev = in6_dev_get(skb->dev); 1263 idev = in6_dev_get(skb->dev);
1317 if (idev == NULL) 1264 if (idev == NULL)
1318 return -ENODEV; 1265 return -ENODEV;
@@ -1323,7 +1270,7 @@ int igmp6_event_report(struct sk_buff *skb)
1323 1270
1324 read_lock_bh(&idev->lock); 1271 read_lock_bh(&idev->lock);
1325 for (ma = idev->mc_list; ma; ma=ma->next) { 1272 for (ma = idev->mc_list; ma; ma=ma->next) {
1326 if (ipv6_addr_equal(&ma->mca_addr, addrp)) { 1273 if (ipv6_addr_equal(&ma->mca_addr, &mld->mld_mca)) {
1327 spin_lock(&ma->mca_lock); 1274 spin_lock(&ma->mca_lock);
1328 if (del_timer(&ma->mca_timer)) 1275 if (del_timer(&ma->mca_timer))
1329 atomic_dec(&ma->mca_refcnt); 1276 atomic_dec(&ma->mca_refcnt);
@@ -1432,11 +1379,11 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1432 skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); 1379 skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data);
1433 skb_put(skb, sizeof(*pmr)); 1380 skb_put(skb, sizeof(*pmr));
1434 pmr = (struct mld2_report *)skb_transport_header(skb); 1381 pmr = (struct mld2_report *)skb_transport_header(skb);
1435 pmr->type = ICMPV6_MLD2_REPORT; 1382 pmr->mld2r_type = ICMPV6_MLD2_REPORT;
1436 pmr->resv1 = 0; 1383 pmr->mld2r_resv1 = 0;
1437 pmr->csum = 0; 1384 pmr->mld2r_cksum = 0;
1438 pmr->resv2 = 0; 1385 pmr->mld2r_resv2 = 0;
1439 pmr->ngrec = 0; 1386 pmr->mld2r_ngrec = 0;
1440 return skb; 1387 return skb;
1441} 1388}
1442 1389
@@ -1458,9 +1405,10 @@ static void mld_sendpack(struct sk_buff *skb)
1458 mldlen = skb->tail - skb->transport_header; 1405 mldlen = skb->tail - skb->transport_header;
1459 pip6->payload_len = htons(payload_len); 1406 pip6->payload_len = htons(payload_len);
1460 1407
1461 pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, 1408 pmr->mld2r_cksum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
1462 IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), 1409 IPPROTO_ICMPV6,
1463 mldlen, 0)); 1410 csum_partial(skb_transport_header(skb),
1411 mldlen, 0));
1464 1412
1465 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); 1413 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1466 1414
@@ -1521,7 +1469,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1521 pgr->grec_nsrcs = 0; 1469 pgr->grec_nsrcs = 0;
1522 pgr->grec_mca = pmc->mca_addr; /* structure copy */ 1470 pgr->grec_mca = pmc->mca_addr; /* structure copy */
1523 pmr = (struct mld2_report *)skb_transport_header(skb); 1471 pmr = (struct mld2_report *)skb_transport_header(skb);
1524 pmr->ngrec = htons(ntohs(pmr->ngrec)+1); 1472 pmr->mld2r_ngrec = htons(ntohs(pmr->mld2r_ngrec)+1);
1525 *ppgr = pgr; 1473 *ppgr = pgr;
1526 return skb; 1474 return skb;
1527} 1475}
@@ -1557,7 +1505,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1557 1505
1558 /* EX and TO_EX get a fresh packet, if needed */ 1506 /* EX and TO_EX get a fresh packet, if needed */
1559 if (truncate) { 1507 if (truncate) {
1560 if (pmr && pmr->ngrec && 1508 if (pmr && pmr->mld2r_ngrec &&
1561 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { 1509 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
1562 if (skb) 1510 if (skb)
1563 mld_sendpack(skb); 1511 mld_sendpack(skb);
@@ -1770,9 +1718,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1770 struct sock *sk = net->ipv6.igmp_sk; 1718 struct sock *sk = net->ipv6.igmp_sk;
1771 struct inet6_dev *idev; 1719 struct inet6_dev *idev;
1772 struct sk_buff *skb; 1720 struct sk_buff *skb;
1773 struct icmp6hdr *hdr; 1721 struct mld_msg *hdr;
1774 const struct in6_addr *snd_addr, *saddr; 1722 const struct in6_addr *snd_addr, *saddr;
1775 struct in6_addr *addrp;
1776 struct in6_addr addr_buf; 1723 struct in6_addr addr_buf;
1777 int err, len, payload_len, full_len; 1724 int err, len, payload_len, full_len;
1778 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1725 u8 ra[8] = { IPPROTO_ICMPV6, 0,
@@ -1820,16 +1767,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1820 1767
1821 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); 1768 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1822 1769
1823 hdr = (struct icmp6hdr *) skb_put(skb, sizeof(struct icmp6hdr)); 1770 hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg));
1824 memset(hdr, 0, sizeof(struct icmp6hdr)); 1771 memset(hdr, 0, sizeof(struct mld_msg));
1825 hdr->icmp6_type = type; 1772 hdr->mld_type = type;
1773 ipv6_addr_copy(&hdr->mld_mca, addr);
1826 1774
1827 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr)); 1775 hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len,
1828 ipv6_addr_copy(addrp, addr); 1776 IPPROTO_ICMPV6,
1829 1777 csum_partial(hdr, len, 0));
1830 hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len,
1831 IPPROTO_ICMPV6,
1832 csum_partial(hdr, len, 0));
1833 1778
1834 idev = in6_dev_get(skb->dev); 1779 idev = in6_dev_get(skb->dev);
1835 1780
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 554b48b6e993..4a4dcbe4f8b2 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -381,7 +381,7 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
381 } 381 }
382 382
383 /* Charge it to the socket. */ 383 /* Charge it to the socket. */
384 if (sock_queue_rcv_skb(sk, skb) < 0) { 384 if (ip_queue_rcv_skb(sk, skb) < 0) {
385 kfree_skb(skb); 385 kfree_skb(skb);
386 return NET_RX_DROP; 386 return NET_RX_DROP;
387 } 387 }
@@ -461,6 +461,9 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
461 if (flags & MSG_ERRQUEUE) 461 if (flags & MSG_ERRQUEUE)
462 return ipv6_recv_error(sk, msg, len); 462 return ipv6_recv_error(sk, msg, len);
463 463
464 if (np->rxpmtu && np->rxopt.bits.rxpmtu)
465 return ipv6_recv_rxpmtu(sk, msg, len);
466
464 skb = skb_recv_datagram(sk, flags, noblock, &err); 467 skb = skb_recv_datagram(sk, flags, noblock, &err);
465 if (!skb) 468 if (!skb)
466 goto out; 469 goto out;
@@ -733,6 +736,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
733 int addr_len = msg->msg_namelen; 736 int addr_len = msg->msg_namelen;
734 int hlimit = -1; 737 int hlimit = -1;
735 int tclass = -1; 738 int tclass = -1;
739 int dontfrag = -1;
736 u16 proto; 740 u16 proto;
737 int err; 741 int err;
738 742
@@ -811,7 +815,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
811 memset(opt, 0, sizeof(struct ipv6_txoptions)); 815 memset(opt, 0, sizeof(struct ipv6_txoptions));
812 opt->tot_len = sizeof(struct ipv6_txoptions); 816 opt->tot_len = sizeof(struct ipv6_txoptions);
813 817
814 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); 818 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
819 &tclass, &dontfrag);
815 if (err < 0) { 820 if (err < 0) {
816 fl6_sock_release(flowlabel); 821 fl6_sock_release(flowlabel);
817 return err; 822 return err;
@@ -880,6 +885,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
880 if (tclass < 0) 885 if (tclass < 0)
881 tclass = np->tclass; 886 tclass = np->tclass;
882 887
888 if (dontfrag < 0)
889 dontfrag = np->dontfrag;
890
883 if (msg->msg_flags&MSG_CONFIRM) 891 if (msg->msg_flags&MSG_CONFIRM)
884 goto do_confirm; 892 goto do_confirm;
885 893
@@ -890,7 +898,7 @@ back_from_confirm:
890 lock_sock(sk); 898 lock_sock(sk);
891 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, 899 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
892 len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst, 900 len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
893 msg->msg_flags); 901 msg->msg_flags, dontfrag);
894 902
895 if (err) 903 if (err)
896 ip6_flush_pending_frames(sk); 904 ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c2438e8cb9d0..05ebd7833043 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -815,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
815{ 815{
816 int flags = 0; 816 int flags = 0;
817 817
818 if (rt6_need_strict(&fl->fl6_dst)) 818 if (fl->oif || rt6_need_strict(&fl->fl6_dst))
819 flags |= RT6_LOOKUP_F_IFACE; 819 flags |= RT6_LOOKUP_F_IFACE;
820 820
821 if (!ipv6_addr_any(&fl->fl6_src)) 821 if (!ipv6_addr_any(&fl->fl6_src))
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index bd5ef7b6e48e..6603511e3673 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -353,6 +353,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
353 if (sk->sk_state == TCP_CLOSE) 353 if (sk->sk_state == TCP_CLOSE)
354 goto out; 354 goto out;
355 355
356 if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
357 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
358 goto out;
359 }
360
356 tp = tcp_sk(sk); 361 tp = tcp_sk(sk);
357 seq = ntohl(th->seq); 362 seq = ntohl(th->seq);
358 if (sk->sk_state != TCP_LISTEN && 363 if (sk->sk_state != TCP_LISTEN &&
@@ -1018,7 +1023,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1018 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 1023 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1019 1024
1020 t1 = (struct tcphdr *) skb_push(buff, tot_len); 1025 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1021 skb_reset_transport_header(skb); 1026 skb_reset_transport_header(buff);
1022 1027
1023 /* Swap the send and the receive. */ 1028 /* Swap the send and the receive. */
1024 memset(t1, 0, sizeof(*t1)); 1029 memset(t1, 0, sizeof(*t1));
@@ -1050,12 +1055,13 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1050 } 1055 }
1051#endif 1056#endif
1052 1057
1053 buff->csum = csum_partial(t1, tot_len, 0);
1054
1055 memset(&fl, 0, sizeof(fl)); 1058 memset(&fl, 0, sizeof(fl));
1056 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); 1059 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
1057 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); 1060 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
1058 1061
1062 buff->ip_summed = CHECKSUM_PARTIAL;
1063 buff->csum = 0;
1064
1059 __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); 1065 __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst);
1060 1066
1061 fl.proto = IPPROTO_TCP; 1067 fl.proto = IPPROTO_TCP;
@@ -1234,12 +1240,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1234 goto drop_and_free; 1240 goto drop_and_free;
1235 1241
1236 /* Secret recipe starts with IP addresses */ 1242 /* Secret recipe starts with IP addresses */
1237 d = &ipv6_hdr(skb)->daddr.s6_addr32[0]; 1243 d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
1238 *mess++ ^= *d++; 1244 *mess++ ^= *d++;
1239 *mess++ ^= *d++; 1245 *mess++ ^= *d++;
1240 *mess++ ^= *d++; 1246 *mess++ ^= *d++;
1241 *mess++ ^= *d++; 1247 *mess++ ^= *d++;
1242 d = &ipv6_hdr(skb)->saddr.s6_addr32[0]; 1248 d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
1243 *mess++ ^= *d++; 1249 *mess++ ^= *d++;
1244 *mess++ ^= *d++; 1250 *mess++ ^= *d++;
1245 *mess++ ^= *d++; 1251 *mess++ ^= *d++;
@@ -1677,6 +1683,7 @@ ipv6_pktoptions:
1677static int tcp_v6_rcv(struct sk_buff *skb) 1683static int tcp_v6_rcv(struct sk_buff *skb)
1678{ 1684{
1679 struct tcphdr *th; 1685 struct tcphdr *th;
1686 struct ipv6hdr *hdr;
1680 struct sock *sk; 1687 struct sock *sk;
1681 int ret; 1688 int ret;
1682 struct net *net = dev_net(skb->dev); 1689 struct net *net = dev_net(skb->dev);
@@ -1703,12 +1710,13 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1703 goto bad_packet; 1710 goto bad_packet;
1704 1711
1705 th = tcp_hdr(skb); 1712 th = tcp_hdr(skb);
1713 hdr = ipv6_hdr(skb);
1706 TCP_SKB_CB(skb)->seq = ntohl(th->seq); 1714 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1707 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + 1715 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1708 skb->len - th->doff*4); 1716 skb->len - th->doff*4);
1709 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); 1717 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1710 TCP_SKB_CB(skb)->when = 0; 1718 TCP_SKB_CB(skb)->when = 0;
1711 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1719 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr);
1712 TCP_SKB_CB(skb)->sacked = 0; 1720 TCP_SKB_CB(skb)->sacked = 0;
1713 1721
1714 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); 1722 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
@@ -1719,6 +1727,11 @@ process:
1719 if (sk->sk_state == TCP_TIME_WAIT) 1727 if (sk->sk_state == TCP_TIME_WAIT)
1720 goto do_time_wait; 1728 goto do_time_wait;
1721 1729
1730 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
1731 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
1732 goto discard_and_relse;
1733 }
1734
1722 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1735 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1723 goto discard_and_relse; 1736 goto discard_and_relse;
1724 1737
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 90824852f598..3d7a2c0b836a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -91,9 +91,9 @@ static unsigned int udp6_portaddr_hash(struct net *net,
91 if (ipv6_addr_any(addr6)) 91 if (ipv6_addr_any(addr6))
92 hash = jhash_1word(0, mix); 92 hash = jhash_1word(0, mix);
93 else if (ipv6_addr_v4mapped(addr6)) 93 else if (ipv6_addr_v4mapped(addr6))
94 hash = jhash_1word(addr6->s6_addr32[3], mix); 94 hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
95 else 95 else
96 hash = jhash2(addr6->s6_addr32, 4, mix); 96 hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);
97 97
98 return hash ^ port; 98 return hash ^ port;
99} 99}
@@ -335,6 +335,9 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
335 if (flags & MSG_ERRQUEUE) 335 if (flags & MSG_ERRQUEUE)
336 return ipv6_recv_error(sk, msg, len); 336 return ipv6_recv_error(sk, msg, len);
337 337
338 if (np->rxpmtu && np->rxopt.bits.rxpmtu)
339 return ipv6_recv_rxpmtu(sk, msg, len);
340
338try_again: 341try_again:
339 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), 342 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
340 &peeked, &err); 343 &peeked, &err);
@@ -421,7 +424,7 @@ out:
421 return err; 424 return err;
422 425
423csum_copy_err: 426csum_copy_err:
424 lock_sock(sk); 427 lock_sock_bh(sk);
425 if (!skb_kill_datagram(sk, skb, flags)) { 428 if (!skb_kill_datagram(sk, skb, flags)) {
426 if (is_udp4) 429 if (is_udp4)
427 UDP_INC_STATS_USER(sock_net(sk), 430 UDP_INC_STATS_USER(sock_net(sk),
@@ -430,7 +433,7 @@ csum_copy_err:
430 UDP6_INC_STATS_USER(sock_net(sk), 433 UDP6_INC_STATS_USER(sock_net(sk),
431 UDP_MIB_INERRORS, is_udplite); 434 UDP_MIB_INERRORS, is_udplite);
432 } 435 }
433 release_sock(sk); 436 unlock_sock_bh(sk);
434 437
435 if (flags & MSG_DONTWAIT) 438 if (flags & MSG_DONTWAIT)
436 return -EAGAIN; 439 return -EAGAIN;
@@ -511,7 +514,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
511 goto drop; 514 goto drop;
512 } 515 }
513 516
514 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { 517 if ((rc = ip_queue_rcv_skb(sk, skb)) < 0) {
515 /* Note that an ENOMEM error is charged twice */ 518 /* Note that an ENOMEM error is charged twice */
516 if (rc == -ENOMEM) 519 if (rc == -ENOMEM)
517 UDP6_INC_STATS_BH(sock_net(sk), 520 UDP6_INC_STATS_BH(sock_net(sk),
@@ -581,6 +584,10 @@ static void flush_stack(struct sock **stack, unsigned int count,
581 584
582 sk = stack[i]; 585 sk = stack[i];
583 if (skb1) { 586 if (skb1) {
587 if (sk_rcvqueues_full(sk, skb)) {
588 kfree_skb(skb1);
589 goto drop;
590 }
584 bh_lock_sock(sk); 591 bh_lock_sock(sk);
585 if (!sock_owned_by_user(sk)) 592 if (!sock_owned_by_user(sk))
586 udpv6_queue_rcv_skb(sk, skb1); 593 udpv6_queue_rcv_skb(sk, skb1);
@@ -692,7 +699,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
692 u32 ulen = 0; 699 u32 ulen = 0;
693 700
694 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 701 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
695 goto short_packet; 702 goto discard;
696 703
697 saddr = &ipv6_hdr(skb)->saddr; 704 saddr = &ipv6_hdr(skb)->saddr;
698 daddr = &ipv6_hdr(skb)->daddr; 705 daddr = &ipv6_hdr(skb)->daddr;
@@ -756,6 +763,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
756 763
757 /* deliver */ 764 /* deliver */
758 765
766 if (sk_rcvqueues_full(sk, skb)) {
767 sock_put(sk);
768 goto discard;
769 }
759 bh_lock_sock(sk); 770 bh_lock_sock(sk);
760 if (!sock_owned_by_user(sk)) 771 if (!sock_owned_by_user(sk))
761 udpv6_queue_rcv_skb(sk, skb); 772 udpv6_queue_rcv_skb(sk, skb);
@@ -770,9 +781,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
770 return 0; 781 return 0;
771 782
772short_packet: 783short_packet:
773 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n", 784 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n",
774 proto == IPPROTO_UDPLITE ? "-Lite" : "", 785 proto == IPPROTO_UDPLITE ? "-Lite" : "",
775 ulen, skb->len); 786 saddr,
787 ntohs(uh->source),
788 ulen,
789 skb->len,
790 daddr,
791 ntohs(uh->dest));
776 792
777discard: 793discard:
778 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 794 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
@@ -919,6 +935,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
919 int ulen = len; 935 int ulen = len;
920 int hlimit = -1; 936 int hlimit = -1;
921 int tclass = -1; 937 int tclass = -1;
938 int dontfrag = -1;
922 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 939 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
923 int err; 940 int err;
924 int connected = 0; 941 int connected = 0;
@@ -1049,7 +1066,8 @@ do_udp_sendmsg:
1049 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1066 memset(opt, 0, sizeof(struct ipv6_txoptions));
1050 opt->tot_len = sizeof(*opt); 1067 opt->tot_len = sizeof(*opt);
1051 1068
1052 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); 1069 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
1070 &tclass, &dontfrag);
1053 if (err < 0) { 1071 if (err < 0) {
1054 fl6_sock_release(flowlabel); 1072 fl6_sock_release(flowlabel);
1055 return err; 1073 return err;
@@ -1120,6 +1138,9 @@ do_udp_sendmsg:
1120 if (tclass < 0) 1138 if (tclass < 0)
1121 tclass = np->tclass; 1139 tclass = np->tclass;
1122 1140
1141 if (dontfrag < 0)
1142 dontfrag = np->dontfrag;
1143
1123 if (msg->msg_flags&MSG_CONFIRM) 1144 if (msg->msg_flags&MSG_CONFIRM)
1124 goto do_confirm; 1145 goto do_confirm;
1125back_from_confirm: 1146back_from_confirm:
@@ -1143,7 +1164,7 @@ do_append_data:
1143 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, 1164 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
1144 sizeof(struct udphdr), hlimit, tclass, opt, &fl, 1165 sizeof(struct udphdr), hlimit, tclass, opt, &fl,
1145 (struct rt6_info*)dst, 1166 (struct rt6_info*)dst,
1146 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 1167 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
1147 if (err) 1168 if (err)
1148 udp_v6_flush_pending_frames(sk); 1169 udp_v6_flush_pending_frames(sk);
1149 else if (!corkreq) 1170 else if (!corkreq)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8c452fd5ceae..4a0e77e14468 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -94,7 +94,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
94 xdst->u.dst.dev = dev; 94 xdst->u.dst.dev = dev;
95 dev_hold(dev); 95 dev_hold(dev);
96 96
97 xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); 97 xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
98 if (!xdst->u.rt6.rt6i_idev) 98 if (!xdst->u.rt6.rt6i_idev)
99 return -ENODEV; 99 return -ENODEV;
100 100