diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-06-16 05:21:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-16 05:21:27 -0400 |
commit | 688d22e23ab1caacb2c36c615854294b58f2ea47 (patch) | |
tree | 95c8163c0b1f56902f5537bc256d7e5507f56cee /net/ipv6 | |
parent | 7e0edc1bc343231029084761ebf59e522902eb49 (diff) | |
parent | 066519068ad2fbe98c7f45552b1f592903a9c8c8 (diff) |
Merge branch 'linus' into x86/xen
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 107 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 50 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 2 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 33 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 8 | ||||
-rw-r--r-- | net/ipv6/raw.c | 13 | ||||
-rw-r--r-- | net/ipv6/route.c | 20 | ||||
-rw-r--r-- | net/ipv6/sit.c | 89 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 1 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 | ||||
-rw-r--r-- | net/ipv6/tunnel6.c | 2 | ||||
-rw-r--r-- | net/ipv6/udp.c | 8 |
14 files changed, 147 insertions, 191 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3a835578fd1c..147588f4c7c0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -731,8 +731,13 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
731 | onlink = -1; | 731 | onlink = -1; |
732 | 732 | ||
733 | spin_lock(&ifa->lock); | 733 | spin_lock(&ifa->lock); |
734 | lifetime = min_t(unsigned long, | 734 | |
735 | ifa->valid_lft, 0x7fffffffUL/HZ); | 735 | lifetime = addrconf_timeout_fixup(ifa->valid_lft, HZ); |
736 | /* | ||
737 | * Note: Because this address is | ||
738 | * not permanent, lifetime < | ||
739 | * LONG_MAX / HZ here. | ||
740 | */ | ||
736 | if (time_before(expires, | 741 | if (time_before(expires, |
737 | ifa->tstamp + lifetime * HZ)) | 742 | ifa->tstamp + lifetime * HZ)) |
738 | expires = ifa->tstamp + lifetime * HZ; | 743 | expires = ifa->tstamp + lifetime * HZ; |
@@ -1722,7 +1727,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1722 | __u32 valid_lft; | 1727 | __u32 valid_lft; |
1723 | __u32 prefered_lft; | 1728 | __u32 prefered_lft; |
1724 | int addr_type; | 1729 | int addr_type; |
1725 | unsigned long rt_expires; | ||
1726 | struct inet6_dev *in6_dev; | 1730 | struct inet6_dev *in6_dev; |
1727 | 1731 | ||
1728 | pinfo = (struct prefix_info *) opt; | 1732 | pinfo = (struct prefix_info *) opt; |
@@ -1764,28 +1768,23 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1764 | * 2) Configure prefixes with the auto flag set | 1768 | * 2) Configure prefixes with the auto flag set |
1765 | */ | 1769 | */ |
1766 | 1770 | ||
1767 | if (valid_lft == INFINITY_LIFE_TIME) | 1771 | if (pinfo->onlink) { |
1768 | rt_expires = ~0UL; | 1772 | struct rt6_info *rt; |
1769 | else if (valid_lft >= 0x7FFFFFFF/HZ) { | 1773 | unsigned long rt_expires; |
1774 | |||
1770 | /* Avoid arithmetic overflow. Really, we could | 1775 | /* Avoid arithmetic overflow. Really, we could |
1771 | * save rt_expires in seconds, likely valid_lft, | 1776 | * save rt_expires in seconds, likely valid_lft, |
1772 | * but it would require division in fib gc, that it | 1777 | * but it would require division in fib gc, that it |
1773 | * not good. | 1778 | * not good. |
1774 | */ | 1779 | */ |
1775 | rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ); | 1780 | if (HZ > USER_HZ) |
1776 | } else | 1781 | rt_expires = addrconf_timeout_fixup(valid_lft, HZ); |
1777 | rt_expires = valid_lft * HZ; | 1782 | else |
1783 | rt_expires = addrconf_timeout_fixup(valid_lft, USER_HZ); | ||
1778 | 1784 | ||
1779 | /* | 1785 | if (addrconf_finite_timeout(rt_expires)) |
1780 | * We convert this (in jiffies) to clock_t later. | 1786 | rt_expires *= HZ; |
1781 | * Avoid arithmetic overflow there as well. | ||
1782 | * Overflow can happen only if HZ < USER_HZ. | ||
1783 | */ | ||
1784 | if (HZ < USER_HZ && ~rt_expires && rt_expires > 0x7FFFFFFF / USER_HZ) | ||
1785 | rt_expires = 0x7FFFFFFF / USER_HZ; | ||
1786 | 1787 | ||
1787 | if (pinfo->onlink) { | ||
1788 | struct rt6_info *rt; | ||
1789 | rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, | 1788 | rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, |
1790 | dev->ifindex, 1); | 1789 | dev->ifindex, 1); |
1791 | 1790 | ||
@@ -1794,7 +1793,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1794 | if (valid_lft == 0) { | 1793 | if (valid_lft == 0) { |
1795 | ip6_del_rt(rt); | 1794 | ip6_del_rt(rt); |
1796 | rt = NULL; | 1795 | rt = NULL; |
1797 | } else if (~rt_expires) { | 1796 | } else if (addrconf_finite_timeout(rt_expires)) { |
1798 | /* not infinity */ | 1797 | /* not infinity */ |
1799 | rt->rt6i_expires = jiffies + rt_expires; | 1798 | rt->rt6i_expires = jiffies + rt_expires; |
1800 | rt->rt6i_flags |= RTF_EXPIRES; | 1799 | rt->rt6i_flags |= RTF_EXPIRES; |
@@ -1803,9 +1802,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1803 | rt->rt6i_expires = 0; | 1802 | rt->rt6i_expires = 0; |
1804 | } | 1803 | } |
1805 | } else if (valid_lft) { | 1804 | } else if (valid_lft) { |
1806 | int flags = RTF_ADDRCONF | RTF_PREFIX_RT; | ||
1807 | clock_t expires = 0; | 1805 | clock_t expires = 0; |
1808 | if (~rt_expires) { | 1806 | int flags = RTF_ADDRCONF | RTF_PREFIX_RT; |
1807 | if (addrconf_finite_timeout(rt_expires)) { | ||
1809 | /* not infinity */ | 1808 | /* not infinity */ |
1810 | flags |= RTF_EXPIRES; | 1809 | flags |= RTF_EXPIRES; |
1811 | expires = jiffies_to_clock_t(rt_expires); | 1810 | expires = jiffies_to_clock_t(rt_expires); |
@@ -2027,7 +2026,7 @@ err_exit: | |||
2027 | * Manual configuration of address on an interface | 2026 | * Manual configuration of address on an interface |
2028 | */ | 2027 | */ |
2029 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | 2028 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, |
2030 | int plen, __u8 ifa_flags, __u32 prefered_lft, | 2029 | unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, |
2031 | __u32 valid_lft) | 2030 | __u32 valid_lft) |
2032 | { | 2031 | { |
2033 | struct inet6_ifaddr *ifp; | 2032 | struct inet6_ifaddr *ifp; |
@@ -2036,9 +2035,13 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2036 | int scope; | 2035 | int scope; |
2037 | u32 flags; | 2036 | u32 flags; |
2038 | clock_t expires; | 2037 | clock_t expires; |
2038 | unsigned long timeout; | ||
2039 | 2039 | ||
2040 | ASSERT_RTNL(); | 2040 | ASSERT_RTNL(); |
2041 | 2041 | ||
2042 | if (plen > 128) | ||
2043 | return -EINVAL; | ||
2044 | |||
2042 | /* check the lifetime */ | 2045 | /* check the lifetime */ |
2043 | if (!valid_lft || prefered_lft > valid_lft) | 2046 | if (!valid_lft || prefered_lft > valid_lft) |
2044 | return -EINVAL; | 2047 | return -EINVAL; |
@@ -2052,22 +2055,23 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2052 | 2055 | ||
2053 | scope = ipv6_addr_scope(pfx); | 2056 | scope = ipv6_addr_scope(pfx); |
2054 | 2057 | ||
2055 | if (valid_lft == INFINITY_LIFE_TIME) { | 2058 | timeout = addrconf_timeout_fixup(valid_lft, HZ); |
2056 | ifa_flags |= IFA_F_PERMANENT; | 2059 | if (addrconf_finite_timeout(timeout)) { |
2057 | flags = 0; | 2060 | expires = jiffies_to_clock_t(timeout * HZ); |
2058 | expires = 0; | 2061 | valid_lft = timeout; |
2059 | } else { | ||
2060 | if (valid_lft >= 0x7FFFFFFF/HZ) | ||
2061 | valid_lft = 0x7FFFFFFF/HZ; | ||
2062 | flags = RTF_EXPIRES; | 2062 | flags = RTF_EXPIRES; |
2063 | expires = jiffies_to_clock_t(valid_lft * HZ); | 2063 | } else { |
2064 | expires = 0; | ||
2065 | flags = 0; | ||
2066 | ifa_flags |= IFA_F_PERMANENT; | ||
2064 | } | 2067 | } |
2065 | 2068 | ||
2066 | if (prefered_lft == 0) | 2069 | timeout = addrconf_timeout_fixup(prefered_lft, HZ); |
2067 | ifa_flags |= IFA_F_DEPRECATED; | 2070 | if (addrconf_finite_timeout(timeout)) { |
2068 | else if ((prefered_lft >= 0x7FFFFFFF/HZ) && | 2071 | if (timeout == 0) |
2069 | (prefered_lft != INFINITY_LIFE_TIME)) | 2072 | ifa_flags |= IFA_F_DEPRECATED; |
2070 | prefered_lft = 0x7FFFFFFF/HZ; | 2073 | prefered_lft = timeout; |
2074 | } | ||
2071 | 2075 | ||
2072 | ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); | 2076 | ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); |
2073 | 2077 | ||
@@ -2095,12 +2099,15 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2095 | } | 2099 | } |
2096 | 2100 | ||
2097 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, | 2101 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, |
2098 | int plen) | 2102 | unsigned int plen) |
2099 | { | 2103 | { |
2100 | struct inet6_ifaddr *ifp; | 2104 | struct inet6_ifaddr *ifp; |
2101 | struct inet6_dev *idev; | 2105 | struct inet6_dev *idev; |
2102 | struct net_device *dev; | 2106 | struct net_device *dev; |
2103 | 2107 | ||
2108 | if (plen > 128) | ||
2109 | return -EINVAL; | ||
2110 | |||
2104 | dev = __dev_get_by_index(net, ifindex); | 2111 | dev = __dev_get_by_index(net, ifindex); |
2105 | if (!dev) | 2112 | if (!dev) |
2106 | return -ENODEV; | 2113 | return -ENODEV; |
@@ -3169,26 +3176,28 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3169 | { | 3176 | { |
3170 | u32 flags; | 3177 | u32 flags; |
3171 | clock_t expires; | 3178 | clock_t expires; |
3179 | unsigned long timeout; | ||
3172 | 3180 | ||
3173 | if (!valid_lft || (prefered_lft > valid_lft)) | 3181 | if (!valid_lft || (prefered_lft > valid_lft)) |
3174 | return -EINVAL; | 3182 | return -EINVAL; |
3175 | 3183 | ||
3176 | if (valid_lft == INFINITY_LIFE_TIME) { | 3184 | timeout = addrconf_timeout_fixup(valid_lft, HZ); |
3177 | ifa_flags |= IFA_F_PERMANENT; | 3185 | if (addrconf_finite_timeout(timeout)) { |
3178 | flags = 0; | 3186 | expires = jiffies_to_clock_t(timeout * HZ); |
3179 | expires = 0; | 3187 | valid_lft = timeout; |
3180 | } else { | ||
3181 | if (valid_lft >= 0x7FFFFFFF/HZ) | ||
3182 | valid_lft = 0x7FFFFFFF/HZ; | ||
3183 | flags = RTF_EXPIRES; | 3188 | flags = RTF_EXPIRES; |
3184 | expires = jiffies_to_clock_t(valid_lft * HZ); | 3189 | } else { |
3190 | expires = 0; | ||
3191 | flags = 0; | ||
3192 | ifa_flags |= IFA_F_PERMANENT; | ||
3185 | } | 3193 | } |
3186 | 3194 | ||
3187 | if (prefered_lft == 0) | 3195 | timeout = addrconf_timeout_fixup(prefered_lft, HZ); |
3188 | ifa_flags |= IFA_F_DEPRECATED; | 3196 | if (addrconf_finite_timeout(timeout)) { |
3189 | else if ((prefered_lft >= 0x7FFFFFFF/HZ) && | 3197 | if (timeout == 0) |
3190 | (prefered_lft != INFINITY_LIFE_TIME)) | 3198 | ifa_flags |= IFA_F_DEPRECATED; |
3191 | prefered_lft = 0x7FFFFFFF/HZ; | 3199 | prefered_lft = timeout; |
3200 | } | ||
3192 | 3201 | ||
3193 | spin_lock_bh(&ifp->lock); | 3202 | spin_lock_bh(&ifp->lock); |
3194 | ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags; | 3203 | ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3c6aafb02183..e84b3fd17fb4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -191,7 +191,7 @@ lookup_protocol: | |||
191 | np->mcast_hops = -1; | 191 | np->mcast_hops = -1; |
192 | np->mc_loop = 1; | 192 | np->mc_loop = 1; |
193 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 193 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
194 | np->ipv6only = init_net.ipv6.sysctl.bindv6only; | 194 | np->ipv6only = net->ipv6.sysctl.bindv6only; |
195 | 195 | ||
196 | /* Init the ipv4 part of the socket since we can have sockets | 196 | /* Init the ipv4 part of the socket since we can have sockets |
197 | * using v6 API for ipv4. | 197 | * using v6 API for ipv4. |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 94fa6ae77cfe..0f0f94a40335 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -496,7 +496,8 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
496 | return 0; | 496 | return 0; |
497 | } | 497 | } |
498 | 498 | ||
499 | int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | 499 | int datagram_send_ctl(struct net *net, |
500 | struct msghdr *msg, struct flowi *fl, | ||
500 | struct ipv6_txoptions *opt, | 501 | struct ipv6_txoptions *opt, |
501 | int *hlimit, int *tclass) | 502 | int *hlimit, int *tclass) |
502 | { | 503 | { |
@@ -509,7 +510,6 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | |||
509 | 510 | ||
510 | for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { | 511 | for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { |
511 | int addr_type; | 512 | int addr_type; |
512 | struct net_device *dev = NULL; | ||
513 | 513 | ||
514 | if (!CMSG_OK(msg, cmsg)) { | 514 | if (!CMSG_OK(msg, cmsg)) { |
515 | err = -EINVAL; | 515 | err = -EINVAL; |
@@ -522,6 +522,9 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | |||
522 | switch (cmsg->cmsg_type) { | 522 | switch (cmsg->cmsg_type) { |
523 | case IPV6_PKTINFO: | 523 | case IPV6_PKTINFO: |
524 | case IPV6_2292PKTINFO: | 524 | case IPV6_2292PKTINFO: |
525 | { | ||
526 | struct net_device *dev = NULL; | ||
527 | |||
525 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) { | 528 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) { |
526 | err = -EINVAL; | 529 | err = -EINVAL; |
527 | goto exit_f; | 530 | goto exit_f; |
@@ -535,32 +538,32 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | |||
535 | fl->oif = src_info->ipi6_ifindex; | 538 | fl->oif = src_info->ipi6_ifindex; |
536 | } | 539 | } |
537 | 540 | ||
538 | addr_type = ipv6_addr_type(&src_info->ipi6_addr); | 541 | addr_type = __ipv6_addr_type(&src_info->ipi6_addr); |
539 | 542 | ||
540 | if (addr_type == IPV6_ADDR_ANY) | 543 | if (fl->oif) { |
541 | break; | 544 | dev = dev_get_by_index(net, fl->oif); |
545 | if (!dev) | ||
546 | return -ENODEV; | ||
547 | } else if (addr_type & IPV6_ADDR_LINKLOCAL) | ||
548 | return -EINVAL; | ||
542 | 549 | ||
543 | if (addr_type & IPV6_ADDR_LINKLOCAL) { | 550 | if (addr_type != IPV6_ADDR_ANY) { |
544 | if (!src_info->ipi6_ifindex) | 551 | int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; |
545 | return -EINVAL; | 552 | if (!ipv6_chk_addr(net, &src_info->ipi6_addr, |
546 | else { | 553 | strict ? dev : NULL, 0)) |
547 | dev = dev_get_by_index(&init_net, src_info->ipi6_ifindex); | 554 | err = -EINVAL; |
548 | if (!dev) | 555 | else |
549 | return -ENODEV; | 556 | ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr); |
550 | } | ||
551 | } | ||
552 | if (!ipv6_chk_addr(&init_net, &src_info->ipi6_addr, | ||
553 | dev, 0)) { | ||
554 | if (dev) | ||
555 | dev_put(dev); | ||
556 | err = -EINVAL; | ||
557 | goto exit_f; | ||
558 | } | 557 | } |
558 | |||
559 | if (dev) | 559 | if (dev) |
560 | dev_put(dev); | 560 | dev_put(dev); |
561 | 561 | ||
562 | ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr); | 562 | if (err) |
563 | goto exit_f; | ||
564 | |||
563 | break; | 565 | break; |
566 | } | ||
564 | 567 | ||
565 | case IPV6_FLOWINFO: | 568 | case IPV6_FLOWINFO: |
566 | if (cmsg->cmsg_len < CMSG_LEN(4)) { | 569 | if (cmsg->cmsg_len < CMSG_LEN(4)) { |
@@ -702,6 +705,11 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | |||
702 | } | 705 | } |
703 | 706 | ||
704 | *hlimit = *(int *)CMSG_DATA(cmsg); | 707 | *hlimit = *(int *)CMSG_DATA(cmsg); |
708 | if (*hlimit < -1 || *hlimit > 0xff) { | ||
709 | err = -EINVAL; | ||
710 | goto exit_f; | ||
711 | } | ||
712 | |||
705 | break; | 713 | break; |
706 | 714 | ||
707 | case IPV6_TCLASS: | 715 | case IPV6_TCLASS: |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index eb7a940310f4..37a4e777e347 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -354,7 +354,7 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, | |||
354 | msg.msg_control = (void*)(fl->opt+1); | 354 | msg.msg_control = (void*)(fl->opt+1); |
355 | flowi.oif = 0; | 355 | flowi.oif = 0; |
356 | 356 | ||
357 | err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk); | 357 | err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, &junk); |
358 | if (err) | 358 | if (err) |
359 | goto done; | 359 | goto done; |
360 | err = -EINVAL; | 360 | err = -EINVAL; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 2de3c464fe75..14796181e8b5 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -197,7 +197,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) | |||
197 | const char *name = vif->dev ? vif->dev->name : "none"; | 197 | const char *name = vif->dev ? vif->dev->name : "none"; |
198 | 198 | ||
199 | seq_printf(seq, | 199 | seq_printf(seq, |
200 | "%2Zd %-10s %8ld %7ld %8ld %7ld %05X\n", | 200 | "%2td %-10s %8ld %7ld %8ld %7ld %05X\n", |
201 | vif - vif6_table, | 201 | vif - vif6_table, |
202 | name, vif->bytes_in, vif->pkt_in, | 202 | name, vif->bytes_in, vif->pkt_in, |
203 | vif->bytes_out, vif->pkt_out, | 203 | vif->bytes_out, vif->pkt_out, |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 56d55fecf8ec..c042ce19bd14 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -67,7 +67,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
67 | 67 | ||
68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ | 68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ |
69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) | 69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) |
70 | return -EINVAL; | 70 | return -ENOPROTOOPT; |
71 | 71 | ||
72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
73 | 73 | ||
@@ -161,9 +161,17 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
161 | struct ipv6_txoptions *opt; | 161 | struct ipv6_txoptions *opt; |
162 | struct sk_buff *pktopt; | 162 | struct sk_buff *pktopt; |
163 | 163 | ||
164 | if (sk->sk_protocol != IPPROTO_UDP && | 164 | if (sk->sk_type == SOCK_RAW) |
165 | sk->sk_protocol != IPPROTO_UDPLITE && | 165 | break; |
166 | sk->sk_protocol != IPPROTO_TCP) | 166 | |
167 | if (sk->sk_protocol == IPPROTO_UDP || | ||
168 | sk->sk_protocol == IPPROTO_UDPLITE) { | ||
169 | struct udp_sock *up = udp_sk(sk); | ||
170 | if (up->pending == AF_INET6) { | ||
171 | retv = -EBUSY; | ||
172 | break; | ||
173 | } | ||
174 | } else if (sk->sk_protocol != IPPROTO_TCP) | ||
167 | break; | 175 | break; |
168 | 176 | ||
169 | if (sk->sk_state != TCP_ESTABLISHED) { | 177 | if (sk->sk_state != TCP_ESTABLISHED) { |
@@ -416,7 +424,7 @@ sticky_done: | |||
416 | msg.msg_controllen = optlen; | 424 | msg.msg_controllen = optlen; |
417 | msg.msg_control = (void*)(opt+1); | 425 | msg.msg_control = (void*)(opt+1); |
418 | 426 | ||
419 | retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk); | 427 | retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); |
420 | if (retv) | 428 | if (retv) |
421 | goto done; | 429 | goto done; |
422 | update: | 430 | update: |
@@ -438,7 +446,7 @@ done: | |||
438 | 446 | ||
439 | case IPV6_MULTICAST_HOPS: | 447 | case IPV6_MULTICAST_HOPS: |
440 | if (sk->sk_type == SOCK_STREAM) | 448 | if (sk->sk_type == SOCK_STREAM) |
441 | goto e_inval; | 449 | break; |
442 | if (optlen < sizeof(int)) | 450 | if (optlen < sizeof(int)) |
443 | goto e_inval; | 451 | goto e_inval; |
444 | if (val > 255 || val < -1) | 452 | if (val > 255 || val < -1) |
@@ -450,13 +458,15 @@ done: | |||
450 | case IPV6_MULTICAST_LOOP: | 458 | case IPV6_MULTICAST_LOOP: |
451 | if (optlen < sizeof(int)) | 459 | if (optlen < sizeof(int)) |
452 | goto e_inval; | 460 | goto e_inval; |
461 | if (val != valbool) | ||
462 | goto e_inval; | ||
453 | np->mc_loop = valbool; | 463 | np->mc_loop = valbool; |
454 | retv = 0; | 464 | retv = 0; |
455 | break; | 465 | break; |
456 | 466 | ||
457 | case IPV6_MULTICAST_IF: | 467 | case IPV6_MULTICAST_IF: |
458 | if (sk->sk_type == SOCK_STREAM) | 468 | if (sk->sk_type == SOCK_STREAM) |
459 | goto e_inval; | 469 | break; |
460 | if (optlen < sizeof(int)) | 470 | if (optlen < sizeof(int)) |
461 | goto e_inval; | 471 | goto e_inval; |
462 | 472 | ||
@@ -832,7 +842,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, | |||
832 | len = min_t(unsigned int, len, ipv6_optlen(hdr)); | 842 | len = min_t(unsigned int, len, ipv6_optlen(hdr)); |
833 | if (copy_to_user(optval, hdr, len)) | 843 | if (copy_to_user(optval, hdr, len)) |
834 | return -EFAULT; | 844 | return -EFAULT; |
835 | return ipv6_optlen(hdr); | 845 | return len; |
836 | } | 846 | } |
837 | 847 | ||
838 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | 848 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
@@ -852,7 +862,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
852 | if (sk->sk_protocol != IPPROTO_UDP && | 862 | if (sk->sk_protocol != IPPROTO_UDP && |
853 | sk->sk_protocol != IPPROTO_UDPLITE && | 863 | sk->sk_protocol != IPPROTO_UDPLITE && |
854 | sk->sk_protocol != IPPROTO_TCP) | 864 | sk->sk_protocol != IPPROTO_TCP) |
855 | return -EINVAL; | 865 | return -ENOPROTOOPT; |
856 | if (sk->sk_state != TCP_ESTABLISHED) | 866 | if (sk->sk_state != TCP_ESTABLISHED) |
857 | return -ENOTCONN; | 867 | return -ENOTCONN; |
858 | val = sk->sk_family; | 868 | val = sk->sk_family; |
@@ -866,6 +876,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
866 | return -EINVAL; | 876 | return -EINVAL; |
867 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) | 877 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) |
868 | return -EFAULT; | 878 | return -EFAULT; |
879 | if (gsf.gf_group.ss_family != AF_INET6) | ||
880 | return -EADDRNOTAVAIL; | ||
869 | lock_sock(sk); | 881 | lock_sock(sk); |
870 | err = ip6_mc_msfget(sk, &gsf, | 882 | err = ip6_mc_msfget(sk, &gsf, |
871 | (struct group_filter __user *)optval, optlen); | 883 | (struct group_filter __user *)optval, optlen); |
@@ -975,6 +987,9 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
975 | len = ipv6_getsockopt_sticky(sk, np->opt, | 987 | len = ipv6_getsockopt_sticky(sk, np->opt, |
976 | optname, optval, len); | 988 | optname, optval, len); |
977 | release_sock(sk); | 989 | release_sock(sk); |
990 | /* check if ipv6_getsockopt_sticky() returns err code */ | ||
991 | if (len < 0) | ||
992 | return len; | ||
978 | return put_user(len, optlen); | 993 | return put_user(len, optlen); |
979 | } | 994 | } |
980 | 995 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 2dccad48058c..e65e26e210ee 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -209,7 +209,9 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
209 | arg.dst = dst; | 209 | arg.dst = dst; |
210 | hash = ip6qhashfn(id, src, dst); | 210 | hash = ip6qhashfn(id, src, dst); |
211 | 211 | ||
212 | local_bh_disable(); | ||
212 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 213 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
214 | local_bh_enable(); | ||
213 | if (q == NULL) | 215 | if (q == NULL) |
214 | goto oom; | 216 | goto oom; |
215 | 217 | ||
@@ -638,10 +640,10 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) | |||
638 | goto ret_orig; | 640 | goto ret_orig; |
639 | } | 641 | } |
640 | 642 | ||
641 | spin_lock(&fq->q.lock); | 643 | spin_lock_bh(&fq->q.lock); |
642 | 644 | ||
643 | if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) { | 645 | if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) { |
644 | spin_unlock(&fq->q.lock); | 646 | spin_unlock_bh(&fq->q.lock); |
645 | pr_debug("Can't insert skb to queue\n"); | 647 | pr_debug("Can't insert skb to queue\n"); |
646 | fq_put(fq); | 648 | fq_put(fq); |
647 | goto ret_orig; | 649 | goto ret_orig; |
@@ -653,7 +655,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) | |||
653 | if (ret_skb == NULL) | 655 | if (ret_skb == NULL) |
654 | pr_debug("Can't reassemble fragmented packets\n"); | 656 | pr_debug("Can't reassemble fragmented packets\n"); |
655 | } | 657 | } |
656 | spin_unlock(&fq->q.lock); | 658 | spin_unlock_bh(&fq->q.lock); |
657 | 659 | ||
658 | fq_put(fq); | 660 | fq_put(fq); |
659 | return ret_skb; | 661 | return ret_skb; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 232e0dc45bf5..3aee12310d94 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -813,7 +813,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
813 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 813 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
814 | opt->tot_len = sizeof(struct ipv6_txoptions); | 814 | opt->tot_len = sizeof(struct ipv6_txoptions); |
815 | 815 | ||
816 | err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass); | 816 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); |
817 | if (err < 0) { | 817 | if (err < 0) { |
818 | fl6_sock_release(flowlabel); | 818 | fl6_sock_release(flowlabel); |
819 | return err; | 819 | return err; |
@@ -1164,6 +1164,15 @@ static void rawv6_close(struct sock *sk, long timeout) | |||
1164 | sk_common_release(sk); | 1164 | sk_common_release(sk); |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static int raw6_destroy(struct sock *sk) | ||
1168 | { | ||
1169 | lock_sock(sk); | ||
1170 | ip6_flush_pending_frames(sk); | ||
1171 | release_sock(sk); | ||
1172 | |||
1173 | return inet6_destroy_sock(sk); | ||
1174 | } | ||
1175 | |||
1167 | static int rawv6_init_sk(struct sock *sk) | 1176 | static int rawv6_init_sk(struct sock *sk) |
1168 | { | 1177 | { |
1169 | struct raw6_sock *rp = raw6_sk(sk); | 1178 | struct raw6_sock *rp = raw6_sk(sk); |
@@ -1187,11 +1196,11 @@ struct proto rawv6_prot = { | |||
1187 | .name = "RAWv6", | 1196 | .name = "RAWv6", |
1188 | .owner = THIS_MODULE, | 1197 | .owner = THIS_MODULE, |
1189 | .close = rawv6_close, | 1198 | .close = rawv6_close, |
1199 | .destroy = raw6_destroy, | ||
1190 | .connect = ip6_datagram_connect, | 1200 | .connect = ip6_datagram_connect, |
1191 | .disconnect = udp_disconnect, | 1201 | .disconnect = udp_disconnect, |
1192 | .ioctl = rawv6_ioctl, | 1202 | .ioctl = rawv6_ioctl, |
1193 | .init = rawv6_init_sk, | 1203 | .init = rawv6_init_sk, |
1194 | .destroy = inet6_destroy_sock, | ||
1195 | .setsockopt = rawv6_setsockopt, | 1204 | .setsockopt = rawv6_setsockopt, |
1196 | .getsockopt = rawv6_getsockopt, | 1205 | .getsockopt = rawv6_getsockopt, |
1197 | .sendmsg = rawv6_sendmsg, | 1206 | .sendmsg = rawv6_sendmsg, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 48534c6c0735..d1f3e19b06c7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -446,7 +446,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
446 | struct route_info *rinfo = (struct route_info *) opt; | 446 | struct route_info *rinfo = (struct route_info *) opt; |
447 | struct in6_addr prefix_buf, *prefix; | 447 | struct in6_addr prefix_buf, *prefix; |
448 | unsigned int pref; | 448 | unsigned int pref; |
449 | u32 lifetime; | 449 | unsigned long lifetime; |
450 | struct rt6_info *rt; | 450 | struct rt6_info *rt; |
451 | 451 | ||
452 | if (len < sizeof(struct route_info)) { | 452 | if (len < sizeof(struct route_info)) { |
@@ -472,13 +472,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
472 | if (pref == ICMPV6_ROUTER_PREF_INVALID) | 472 | if (pref == ICMPV6_ROUTER_PREF_INVALID) |
473 | pref = ICMPV6_ROUTER_PREF_MEDIUM; | 473 | pref = ICMPV6_ROUTER_PREF_MEDIUM; |
474 | 474 | ||
475 | lifetime = ntohl(rinfo->lifetime); | 475 | lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ); |
476 | if (lifetime == 0xffffffff) { | ||
477 | /* infinity */ | ||
478 | } else if (lifetime > 0x7fffffff/HZ - 1) { | ||
479 | /* Avoid arithmetic overflow */ | ||
480 | lifetime = 0x7fffffff/HZ - 1; | ||
481 | } | ||
482 | 476 | ||
483 | if (rinfo->length == 3) | 477 | if (rinfo->length == 3) |
484 | prefix = (struct in6_addr *)rinfo->prefix; | 478 | prefix = (struct in6_addr *)rinfo->prefix; |
@@ -506,7 +500,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
506 | (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); | 500 | (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); |
507 | 501 | ||
508 | if (rt) { | 502 | if (rt) { |
509 | if (lifetime == 0xffffffff) { | 503 | if (!addrconf_finite_timeout(lifetime)) { |
510 | rt->rt6i_flags &= ~RTF_EXPIRES; | 504 | rt->rt6i_flags &= ~RTF_EXPIRES; |
511 | } else { | 505 | } else { |
512 | rt->rt6i_expires = jiffies + HZ * lifetime; | 506 | rt->rt6i_expires = jiffies + HZ * lifetime; |
@@ -2202,8 +2196,12 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
2202 | 2196 | ||
2203 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); | 2197 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); |
2204 | 2198 | ||
2205 | expires = (rt->rt6i_flags & RTF_EXPIRES) ? | 2199 | if (!(rt->rt6i_flags & RTF_EXPIRES)) |
2206 | rt->rt6i_expires - jiffies : 0; | 2200 | expires = 0; |
2201 | else if (rt->rt6i_expires - jiffies < INT_MAX) | ||
2202 | expires = rt->rt6i_expires - jiffies; | ||
2203 | else | ||
2204 | expires = INT_MAX; | ||
2207 | 2205 | ||
2208 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, | 2206 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, |
2209 | expires, rt->u.dst.error) < 0) | 2207 | expires, rt->u.dst.error) < 0) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 5a6fab95569f..3de6ffdaedf2 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -403,9 +403,8 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
403 | 403 | ||
404 | static int ipip6_err(struct sk_buff *skb, u32 info) | 404 | static int ipip6_err(struct sk_buff *skb, u32 info) |
405 | { | 405 | { |
406 | #ifndef I_WISH_WORLD_WERE_PERFECT | ||
407 | 406 | ||
408 | /* It is not :-( All the routers (except for Linux) return only | 407 | /* All the routers (except for Linux) return only |
409 | 8 bytes of packet payload. It means, that precise relaying of | 408 | 8 bytes of packet payload. It means, that precise relaying of |
410 | ICMP in the real Internet is absolutely infeasible. | 409 | ICMP in the real Internet is absolutely infeasible. |
411 | */ | 410 | */ |
@@ -462,92 +461,6 @@ static int ipip6_err(struct sk_buff *skb, u32 info) | |||
462 | out: | 461 | out: |
463 | read_unlock(&ipip6_lock); | 462 | read_unlock(&ipip6_lock); |
464 | return err; | 463 | return err; |
465 | #else | ||
466 | struct iphdr *iph = (struct iphdr*)dp; | ||
467 | int hlen = iph->ihl<<2; | ||
468 | struct ipv6hdr *iph6; | ||
469 | const int type = icmp_hdr(skb)->type; | ||
470 | const int code = icmp_hdr(skb)->code; | ||
471 | int rel_type = 0; | ||
472 | int rel_code = 0; | ||
473 | int rel_info = 0; | ||
474 | struct sk_buff *skb2; | ||
475 | struct rt6_info *rt6i; | ||
476 | |||
477 | if (len < hlen + sizeof(struct ipv6hdr)) | ||
478 | return; | ||
479 | iph6 = (struct ipv6hdr*)(dp + hlen); | ||
480 | |||
481 | switch (type) { | ||
482 | default: | ||
483 | return; | ||
484 | case ICMP_PARAMETERPROB: | ||
485 | if (icmp_hdr(skb)->un.gateway < hlen) | ||
486 | return; | ||
487 | |||
488 | /* So... This guy found something strange INSIDE encapsulated | ||
489 | packet. Well, he is fool, but what can we do ? | ||
490 | */ | ||
491 | rel_type = ICMPV6_PARAMPROB; | ||
492 | rel_info = icmp_hdr(skb)->un.gateway - hlen; | ||
493 | break; | ||
494 | |||
495 | case ICMP_DEST_UNREACH: | ||
496 | switch (code) { | ||
497 | case ICMP_SR_FAILED: | ||
498 | case ICMP_PORT_UNREACH: | ||
499 | /* Impossible event. */ | ||
500 | return; | ||
501 | case ICMP_FRAG_NEEDED: | ||
502 | /* Too complicated case ... */ | ||
503 | return; | ||
504 | default: | ||
505 | /* All others are translated to HOST_UNREACH. | ||
506 | rfc2003 contains "deep thoughts" about NET_UNREACH, | ||
507 | I believe, it is just ether pollution. --ANK | ||
508 | */ | ||
509 | rel_type = ICMPV6_DEST_UNREACH; | ||
510 | rel_code = ICMPV6_ADDR_UNREACH; | ||
511 | break; | ||
512 | } | ||
513 | break; | ||
514 | case ICMP_TIME_EXCEEDED: | ||
515 | if (code != ICMP_EXC_TTL) | ||
516 | return; | ||
517 | rel_type = ICMPV6_TIME_EXCEED; | ||
518 | rel_code = ICMPV6_EXC_HOPLIMIT; | ||
519 | break; | ||
520 | } | ||
521 | |||
522 | /* Prepare fake skb to feed it to icmpv6_send */ | ||
523 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
524 | if (skb2 == NULL) | ||
525 | return 0; | ||
526 | dst_release(skb2->dst); | ||
527 | skb2->dst = NULL; | ||
528 | skb_pull(skb2, skb->data - (u8*)iph6); | ||
529 | skb_reset_network_header(skb2); | ||
530 | |||
531 | /* Try to guess incoming interface */ | ||
532 | rt6i = rt6_lookup(dev_net(skb->dev), &iph6->saddr, NULL, NULL, 0); | ||
533 | if (rt6i && rt6i->rt6i_dev) { | ||
534 | skb2->dev = rt6i->rt6i_dev; | ||
535 | |||
536 | rt6i = rt6_lookup(dev_net(skb->dev), | ||
537 | &iph6->daddr, &iph6->saddr, NULL, 0); | ||
538 | |||
539 | if (rt6i && rt6i->rt6i_dev && rt6i->rt6i_dev->type == ARPHRD_SIT) { | ||
540 | struct ip_tunnel *t = netdev_priv(rt6i->rt6i_dev); | ||
541 | if (rel_type == ICMPV6_TIME_EXCEED && t->parms.iph.ttl) { | ||
542 | rel_type = ICMPV6_DEST_UNREACH; | ||
543 | rel_code = ICMPV6_ADDR_UNREACH; | ||
544 | } | ||
545 | icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); | ||
546 | } | ||
547 | } | ||
548 | kfree_skb(skb2); | ||
549 | return 0; | ||
550 | #endif | ||
551 | } | 464 | } |
552 | 465 | ||
553 | static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) | 466 | static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 938ce4ecde55..3ecc1157994e 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -198,7 +198,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
198 | ireq = inet_rsk(req); | 198 | ireq = inet_rsk(req); |
199 | ireq6 = inet6_rsk(req); | 199 | ireq6 = inet6_rsk(req); |
200 | treq = tcp_rsk(req); | 200 | treq = tcp_rsk(req); |
201 | ireq6->pktopts = NULL; | ||
202 | 201 | ||
203 | if (security_inet_conn_request(sk, skb, req)) { | 202 | if (security_inet_conn_request(sk, skb, req)) { |
204 | reqsk_free(req); | 203 | reqsk_free(req); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 715965f0fac0..cb46749d4c32 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1299,7 +1299,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1299 | treq = inet6_rsk(req); | 1299 | treq = inet6_rsk(req); |
1300 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); | 1300 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); |
1301 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); | 1301 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); |
1302 | treq->pktopts = NULL; | ||
1303 | if (!want_cookie) | 1302 | if (!want_cookie) |
1304 | TCP_ECN_create_request(req, tcp_hdr(skb)); | 1303 | TCP_ECN_create_request(req, tcp_hdr(skb)); |
1305 | 1304 | ||
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 6323921b40be..669f280989c3 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c | |||
@@ -109,7 +109,7 @@ static int tunnel46_rcv(struct sk_buff *skb) | |||
109 | { | 109 | { |
110 | struct xfrm6_tunnel *handler; | 110 | struct xfrm6_tunnel *handler; |
111 | 111 | ||
112 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) | 112 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
113 | goto drop; | 113 | goto drop; |
114 | 114 | ||
115 | for (handler = tunnel46_handlers; handler; handler = handler->next) | 115 | for (handler = tunnel46_handlers; handler; handler = handler->next) |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 1fd784f3e2ec..dd309626ae9a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -534,7 +534,9 @@ static void udp_v6_flush_pending_frames(struct sock *sk) | |||
534 | { | 534 | { |
535 | struct udp_sock *up = udp_sk(sk); | 535 | struct udp_sock *up = udp_sk(sk); |
536 | 536 | ||
537 | if (up->pending) { | 537 | if (up->pending == AF_INET) |
538 | udp_flush_pending_frames(sk); | ||
539 | else if (up->pending) { | ||
538 | up->len = 0; | 540 | up->len = 0; |
539 | up->pending = 0; | 541 | up->pending = 0; |
540 | ip6_flush_pending_frames(sk); | 542 | ip6_flush_pending_frames(sk); |
@@ -731,7 +733,7 @@ do_udp_sendmsg: | |||
731 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 733 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
732 | opt->tot_len = sizeof(*opt); | 734 | opt->tot_len = sizeof(*opt); |
733 | 735 | ||
734 | err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass); | 736 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); |
735 | if (err < 0) { | 737 | if (err < 0) { |
736 | fl6_sock_release(flowlabel); | 738 | fl6_sock_release(flowlabel); |
737 | return err; | 739 | return err; |
@@ -848,12 +850,14 @@ do_append_data: | |||
848 | } else { | 850 | } else { |
849 | dst_release(dst); | 851 | dst_release(dst); |
850 | } | 852 | } |
853 | dst = NULL; | ||
851 | } | 854 | } |
852 | 855 | ||
853 | if (err > 0) | 856 | if (err > 0) |
854 | err = np->recverr ? net_xmit_errno(err) : 0; | 857 | err = np->recverr ? net_xmit_errno(err) : 0; |
855 | release_sock(sk); | 858 | release_sock(sk); |
856 | out: | 859 | out: |
860 | dst_release(dst); | ||
857 | fl6_sock_release(flowlabel); | 861 | fl6_sock_release(flowlabel); |
858 | if (!err) | 862 | if (!err) |
859 | return len; | 863 | return len; |