diff options
author | James Morris <jmorris@namei.org> | 2010-03-30 17:39:27 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-03-30 17:39:27 -0400 |
commit | d25d6fa1a95f465ff1ec4458ca15e30b2c8dffec (patch) | |
tree | 7362b182dedd825fc762ef7706830837e42943af /net/ipv6 | |
parent | 225a9be24d799aa16d543c31fb09f0c9ed1d9caa (diff) | |
parent | 2eaa9cfdf33b8d7fb7aff27792192e0019ae8fc6 (diff) |
Merge branch 'master' into next
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 106 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_raw.c | 2 | ||||
-rw-r--r-- | net/ipv6/route.c | 26 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 | ||||
-rw-r--r-- | net/ipv6/udp.c | 28 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 3 |
8 files changed, 115 insertions, 82 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 88fd8c5877ee..7e567ae5eaab 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1380,6 +1380,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
1380 | if (dad_failed) | 1380 | if (dad_failed) |
1381 | ifp->flags |= IFA_F_DADFAILED; | 1381 | ifp->flags |= IFA_F_DADFAILED; |
1382 | spin_unlock_bh(&ifp->lock); | 1382 | spin_unlock_bh(&ifp->lock); |
1383 | if (dad_failed) | ||
1384 | ipv6_ifa_notify(0, ifp); | ||
1383 | in6_ifa_put(ifp); | 1385 | in6_ifa_put(ifp); |
1384 | #ifdef CONFIG_IPV6_PRIVACY | 1386 | #ifdef CONFIG_IPV6_PRIVACY |
1385 | } else if (ifp->flags&IFA_F_TEMPORARY) { | 1387 | } else if (ifp->flags&IFA_F_TEMPORARY) { |
@@ -2615,7 +2617,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event) | |||
2615 | static int addrconf_ifdown(struct net_device *dev, int how) | 2617 | static int addrconf_ifdown(struct net_device *dev, int how) |
2616 | { | 2618 | { |
2617 | struct inet6_dev *idev; | 2619 | struct inet6_dev *idev; |
2618 | struct inet6_ifaddr *ifa, **bifa; | 2620 | struct inet6_ifaddr *ifa, *keep_list, **bifa; |
2619 | struct net *net = dev_net(dev); | 2621 | struct net *net = dev_net(dev); |
2620 | int i; | 2622 | int i; |
2621 | 2623 | ||
@@ -2649,11 +2651,11 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2649 | write_lock_bh(&addrconf_hash_lock); | 2651 | write_lock_bh(&addrconf_hash_lock); |
2650 | while ((ifa = *bifa) != NULL) { | 2652 | while ((ifa = *bifa) != NULL) { |
2651 | if (ifa->idev == idev && | 2653 | if (ifa->idev == idev && |
2652 | (how || !(ifa->flags&IFA_F_PERMANENT))) { | 2654 | (how || !(ifa->flags&IFA_F_PERMANENT) || |
2655 | ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | ||
2653 | *bifa = ifa->lst_next; | 2656 | *bifa = ifa->lst_next; |
2654 | ifa->lst_next = NULL; | 2657 | ifa->lst_next = NULL; |
2655 | addrconf_del_timer(ifa); | 2658 | __in6_ifa_put(ifa); |
2656 | in6_ifa_put(ifa); | ||
2657 | continue; | 2659 | continue; |
2658 | } | 2660 | } |
2659 | bifa = &ifa->lst_next; | 2661 | bifa = &ifa->lst_next; |
@@ -2689,31 +2691,51 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2689 | write_lock_bh(&idev->lock); | 2691 | write_lock_bh(&idev->lock); |
2690 | } | 2692 | } |
2691 | #endif | 2693 | #endif |
2692 | bifa = &idev->addr_list; | 2694 | keep_list = NULL; |
2693 | while ((ifa = *bifa) != NULL) { | 2695 | bifa = &keep_list; |
2694 | if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) { | 2696 | while ((ifa = idev->addr_list) != NULL) { |
2695 | /* Retain permanent address on admin down */ | 2697 | idev->addr_list = ifa->if_next; |
2698 | ifa->if_next = NULL; | ||
2699 | |||
2700 | addrconf_del_timer(ifa); | ||
2701 | |||
2702 | /* If just doing link down, and address is permanent | ||
2703 | and not link-local, then retain it. */ | ||
2704 | if (how == 0 && | ||
2705 | (ifa->flags&IFA_F_PERMANENT) && | ||
2706 | !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | ||
2707 | |||
2708 | /* Move to holding list */ | ||
2709 | *bifa = ifa; | ||
2696 | bifa = &ifa->if_next; | 2710 | bifa = &ifa->if_next; |
2697 | 2711 | ||
2698 | /* Restart DAD if needed when link comes back up */ | 2712 | /* If not doing DAD on this address, just keep it. */ |
2699 | if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || | 2713 | if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || |
2700 | idev->cnf.accept_dad <= 0 || | 2714 | idev->cnf.accept_dad <= 0 || |
2701 | (ifa->flags & IFA_F_NODAD))) | 2715 | (ifa->flags & IFA_F_NODAD)) |
2702 | ifa->flags |= IFA_F_TENTATIVE; | 2716 | continue; |
2703 | } else { | ||
2704 | *bifa = ifa->if_next; | ||
2705 | ifa->if_next = NULL; | ||
2706 | 2717 | ||
2718 | /* If it was tentative already, no need to notify */ | ||
2719 | if (ifa->flags & IFA_F_TENTATIVE) | ||
2720 | continue; | ||
2721 | |||
2722 | /* Flag it for later restoration when link comes up */ | ||
2723 | ifa->flags |= IFA_F_TENTATIVE; | ||
2724 | in6_ifa_hold(ifa); | ||
2725 | } else { | ||
2707 | ifa->dead = 1; | 2726 | ifa->dead = 1; |
2708 | write_unlock_bh(&idev->lock); | 2727 | } |
2728 | write_unlock_bh(&idev->lock); | ||
2709 | 2729 | ||
2710 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 2730 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
2711 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | 2731 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); |
2712 | in6_ifa_put(ifa); | 2732 | in6_ifa_put(ifa); |
2713 | 2733 | ||
2714 | write_lock_bh(&idev->lock); | 2734 | write_lock_bh(&idev->lock); |
2715 | } | ||
2716 | } | 2735 | } |
2736 | |||
2737 | idev->addr_list = keep_list; | ||
2738 | |||
2717 | write_unlock_bh(&idev->lock); | 2739 | write_unlock_bh(&idev->lock); |
2718 | 2740 | ||
2719 | /* Step 5: Discard multicast list */ | 2741 | /* Step 5: Discard multicast list */ |
@@ -2739,28 +2761,29 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2739 | static void addrconf_rs_timer(unsigned long data) | 2761 | static void addrconf_rs_timer(unsigned long data) |
2740 | { | 2762 | { |
2741 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; | 2763 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; |
2764 | struct inet6_dev *idev = ifp->idev; | ||
2742 | 2765 | ||
2743 | if (ifp->idev->cnf.forwarding) | 2766 | read_lock(&idev->lock); |
2767 | if (idev->dead || !(idev->if_flags & IF_READY)) | ||
2744 | goto out; | 2768 | goto out; |
2745 | 2769 | ||
2746 | if (ifp->idev->if_flags & IF_RA_RCVD) { | 2770 | if (idev->cnf.forwarding) |
2747 | /* | 2771 | goto out; |
2748 | * Announcement received after solicitation | 2772 | |
2749 | * was sent | 2773 | /* Announcement received after solicitation was sent */ |
2750 | */ | 2774 | if (idev->if_flags & IF_RA_RCVD) |
2751 | goto out; | 2775 | goto out; |
2752 | } | ||
2753 | 2776 | ||
2754 | spin_lock(&ifp->lock); | 2777 | spin_lock(&ifp->lock); |
2755 | if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { | 2778 | if (ifp->probes++ < idev->cnf.rtr_solicits) { |
2756 | /* The wait after the last probe can be shorter */ | 2779 | /* The wait after the last probe can be shorter */ |
2757 | addrconf_mod_timer(ifp, AC_RS, | 2780 | addrconf_mod_timer(ifp, AC_RS, |
2758 | (ifp->probes == ifp->idev->cnf.rtr_solicits) ? | 2781 | (ifp->probes == idev->cnf.rtr_solicits) ? |
2759 | ifp->idev->cnf.rtr_solicit_delay : | 2782 | idev->cnf.rtr_solicit_delay : |
2760 | ifp->idev->cnf.rtr_solicit_interval); | 2783 | idev->cnf.rtr_solicit_interval); |
2761 | spin_unlock(&ifp->lock); | 2784 | spin_unlock(&ifp->lock); |
2762 | 2785 | ||
2763 | ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); | 2786 | ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); |
2764 | } else { | 2787 | } else { |
2765 | spin_unlock(&ifp->lock); | 2788 | spin_unlock(&ifp->lock); |
2766 | /* | 2789 | /* |
@@ -2768,10 +2791,11 @@ static void addrconf_rs_timer(unsigned long data) | |||
2768 | * assumption any longer. | 2791 | * assumption any longer. |
2769 | */ | 2792 | */ |
2770 | printk(KERN_DEBUG "%s: no IPv6 routers present\n", | 2793 | printk(KERN_DEBUG "%s: no IPv6 routers present\n", |
2771 | ifp->idev->dev->name); | 2794 | idev->dev->name); |
2772 | } | 2795 | } |
2773 | 2796 | ||
2774 | out: | 2797 | out: |
2798 | read_unlock(&idev->lock); | ||
2775 | in6_ifa_put(ifp); | 2799 | in6_ifa_put(ifp); |
2776 | } | 2800 | } |
2777 | 2801 | ||
@@ -2850,9 +2874,9 @@ static void addrconf_dad_timer(unsigned long data) | |||
2850 | struct inet6_dev *idev = ifp->idev; | 2874 | struct inet6_dev *idev = ifp->idev; |
2851 | struct in6_addr mcaddr; | 2875 | struct in6_addr mcaddr; |
2852 | 2876 | ||
2853 | read_lock_bh(&idev->lock); | 2877 | read_lock(&idev->lock); |
2854 | if (idev->dead) { | 2878 | if (idev->dead || !(idev->if_flags & IF_READY)) { |
2855 | read_unlock_bh(&idev->lock); | 2879 | read_unlock(&idev->lock); |
2856 | goto out; | 2880 | goto out; |
2857 | } | 2881 | } |
2858 | 2882 | ||
@@ -2864,7 +2888,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
2864 | 2888 | ||
2865 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); | 2889 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); |
2866 | spin_unlock(&ifp->lock); | 2890 | spin_unlock(&ifp->lock); |
2867 | read_unlock_bh(&idev->lock); | 2891 | read_unlock(&idev->lock); |
2868 | 2892 | ||
2869 | addrconf_dad_completed(ifp); | 2893 | addrconf_dad_completed(ifp); |
2870 | 2894 | ||
@@ -2874,7 +2898,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
2874 | ifp->probes--; | 2898 | ifp->probes--; |
2875 | addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); | 2899 | addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); |
2876 | spin_unlock(&ifp->lock); | 2900 | spin_unlock(&ifp->lock); |
2877 | read_unlock_bh(&idev->lock); | 2901 | read_unlock(&idev->lock); |
2878 | 2902 | ||
2879 | /* send a neighbour solicitation for our addr */ | 2903 | /* send a neighbour solicitation for our addr */ |
2880 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); | 2904 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); |
@@ -3586,7 +3610,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3586 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 3610 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
3587 | if (idx < s_idx) | 3611 | if (idx < s_idx) |
3588 | goto cont; | 3612 | goto cont; |
3589 | if (idx > s_idx) | 3613 | if (h > s_h || idx > s_idx) |
3590 | s_ip_idx = 0; | 3614 | s_ip_idx = 0; |
3591 | ip_idx = 0; | 3615 | ip_idx = 0; |
3592 | if ((idev = __in6_dev_get(dev)) == NULL) | 3616 | if ((idev = __in6_dev_get(dev)) == NULL) |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 551882b9dfd6..5e463c43fcc2 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
84 | if ((rule->flags & FIB_RULE_FIND_SADDR) && | 84 | if ((rule->flags & FIB_RULE_FIND_SADDR) && |
85 | r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { | 85 | r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { |
86 | struct in6_addr saddr; | 86 | struct in6_addr saddr; |
87 | unsigned int srcprefs = 0; | ||
88 | |||
89 | if (flags & RT6_LOOKUP_F_SRCPREF_TMP) | ||
90 | srcprefs |= IPV6_PREFER_SRC_TMP; | ||
91 | if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC) | ||
92 | srcprefs |= IPV6_PREFER_SRC_PUBLIC; | ||
93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) | ||
94 | srcprefs |= IPV6_PREFER_SRC_COA; | ||
95 | 87 | ||
96 | if (ipv6_dev_get_saddr(net, | 88 | if (ipv6_dev_get_saddr(net, |
97 | ip6_dst_idev(&rt->u.dst)->dev, | 89 | ip6_dst_idev(&rt->u.dst)->dev, |
98 | &flp->fl6_dst, srcprefs, | 90 | &flp->fl6_dst, |
91 | rt6_flags2srcprefs(flags), | ||
99 | &saddr)) | 92 | &saddr)) |
100 | goto again; | 93 | goto again; |
101 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, | 94 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 52e0f74fdfe0..27acfb58650a 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1113,6 +1113,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) | |||
1113 | unsigned char ttls[MAXMIFS]; | 1113 | unsigned char ttls[MAXMIFS]; |
1114 | int i; | 1114 | int i; |
1115 | 1115 | ||
1116 | if (mfc->mf6cc_parent >= MAXMIFS) | ||
1117 | return -ENFILE; | ||
1118 | |||
1116 | memset(ttls, 255, MAXMIFS); | 1119 | memset(ttls, 255, MAXMIFS); |
1117 | for (i = 0; i < MAXMIFS; i++) { | 1120 | for (i = 0; i < MAXMIFS; i++) { |
1118 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) | 1121 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) |
@@ -1692,17 +1695,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1692 | int ct; | 1695 | int ct; |
1693 | struct rtnexthop *nhp; | 1696 | struct rtnexthop *nhp; |
1694 | struct net *net = mfc6_net(c); | 1697 | struct net *net = mfc6_net(c); |
1695 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1696 | u8 *b = skb_tail_pointer(skb); | 1698 | u8 *b = skb_tail_pointer(skb); |
1697 | struct rtattr *mp_head; | 1699 | struct rtattr *mp_head; |
1698 | 1700 | ||
1699 | if (dev) | 1701 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1700 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1702 | if (c->mf6c_parent > MAXMIFS) |
1703 | return -ENOENT; | ||
1704 | |||
1705 | if (MIF_EXISTS(net, c->mf6c_parent)) | ||
1706 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex); | ||
1701 | 1707 | ||
1702 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1708 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1703 | 1709 | ||
1704 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1710 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1705 | if (c->mfc_un.res.ttls[ct] < 255) { | 1711 | if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1706 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1712 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1707 | goto rtattr_failure; | 1713 | goto rtattr_failure; |
1708 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1714 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index aef31a29de9e..b9cf7cd61923 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -13,7 +13,7 @@ static const struct xt_table packet_raw = { | |||
13 | .valid_hooks = RAW_VALID_HOOKS, | 13 | .valid_hooks = RAW_VALID_HOOKS, |
14 | .me = THIS_MODULE, | 14 | .me = THIS_MODULE, |
15 | .af = NFPROTO_IPV6, | 15 | .af = NFPROTO_IPV6, |
16 | .priority = NF_IP6_PRI_FIRST, | 16 | .priority = NF_IP6_PRI_RAW, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | /* The work comes in here from netfilter.c. */ | 19 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b08879e97f22..0d7713c5c206 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, | |||
819 | 819 | ||
820 | if (!ipv6_addr_any(&fl->fl6_src)) | 820 | if (!ipv6_addr_any(&fl->fl6_src)) |
821 | flags |= RT6_LOOKUP_F_HAS_SADDR; | 821 | flags |= RT6_LOOKUP_F_HAS_SADDR; |
822 | else if (sk) { | 822 | else if (sk) |
823 | unsigned int prefs = inet6_sk(sk)->srcprefs; | 823 | flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); |
824 | if (prefs & IPV6_PREFER_SRC_TMP) | ||
825 | flags |= RT6_LOOKUP_F_SRCPREF_TMP; | ||
826 | if (prefs & IPV6_PREFER_SRC_PUBLIC) | ||
827 | flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC; | ||
828 | if (prefs & IPV6_PREFER_SRC_COA) | ||
829 | flags |= RT6_LOOKUP_F_SRCPREF_COA; | ||
830 | } | ||
831 | 824 | ||
832 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); | 825 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); |
833 | } | 826 | } |
@@ -886,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
886 | 879 | ||
887 | rt = (struct rt6_info *) dst; | 880 | rt = (struct rt6_info *) dst; |
888 | 881 | ||
889 | if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) | 882 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
890 | return dst; | 883 | return dst; |
891 | 884 | ||
892 | return NULL; | 885 | return NULL; |
@@ -897,12 +890,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
897 | struct rt6_info *rt = (struct rt6_info *) dst; | 890 | struct rt6_info *rt = (struct rt6_info *) dst; |
898 | 891 | ||
899 | if (rt) { | 892 | if (rt) { |
900 | if (rt->rt6i_flags & RTF_CACHE) | 893 | if (rt->rt6i_flags & RTF_CACHE) { |
901 | ip6_del_rt(rt); | 894 | if (rt6_check_expired(rt)) { |
902 | else | 895 | ip6_del_rt(rt); |
896 | dst = NULL; | ||
897 | } | ||
898 | } else { | ||
903 | dst_release(dst); | 899 | dst_release(dst); |
900 | dst = NULL; | ||
901 | } | ||
904 | } | 902 | } |
905 | return NULL; | 903 | return dst; |
906 | } | 904 | } |
907 | 905 | ||
908 | static void ip6_link_failure(struct sk_buff *skb) | 906 | static void ip6_link_failure(struct sk_buff *skb) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6963a6b6763e..9b6dbba80d31 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1740,8 +1740,11 @@ process: | |||
1740 | if (!tcp_prequeue(sk, skb)) | 1740 | if (!tcp_prequeue(sk, skb)) |
1741 | ret = tcp_v6_do_rcv(sk, skb); | 1741 | ret = tcp_v6_do_rcv(sk, skb); |
1742 | } | 1742 | } |
1743 | } else | 1743 | } else if (unlikely(sk_add_backlog(sk, skb))) { |
1744 | sk_add_backlog(sk, skb); | 1744 | bh_unlock_sock(sk); |
1745 | NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); | ||
1746 | goto discard_and_relse; | ||
1747 | } | ||
1745 | bh_unlock_sock(sk); | 1748 | bh_unlock_sock(sk); |
1746 | 1749 | ||
1747 | sock_put(sk); | 1750 | sock_put(sk); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 52b8347ae3b2..3c0c9c755c92 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -583,16 +583,20 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
583 | bh_lock_sock(sk); | 583 | bh_lock_sock(sk); |
584 | if (!sock_owned_by_user(sk)) | 584 | if (!sock_owned_by_user(sk)) |
585 | udpv6_queue_rcv_skb(sk, skb1); | 585 | udpv6_queue_rcv_skb(sk, skb1); |
586 | else | 586 | else if (sk_add_backlog(sk, skb1)) { |
587 | sk_add_backlog(sk, skb1); | 587 | kfree_skb(skb1); |
588 | bh_unlock_sock(sk); | ||
589 | goto drop; | ||
590 | } | ||
588 | bh_unlock_sock(sk); | 591 | bh_unlock_sock(sk); |
589 | } else { | 592 | continue; |
590 | atomic_inc(&sk->sk_drops); | ||
591 | UDP6_INC_STATS_BH(sock_net(sk), | ||
592 | UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk)); | ||
593 | UDP6_INC_STATS_BH(sock_net(sk), | ||
594 | UDP_MIB_INERRORS, IS_UDPLITE(sk)); | ||
595 | } | 593 | } |
594 | drop: | ||
595 | atomic_inc(&sk->sk_drops); | ||
596 | UDP6_INC_STATS_BH(sock_net(sk), | ||
597 | UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk)); | ||
598 | UDP6_INC_STATS_BH(sock_net(sk), | ||
599 | UDP_MIB_INERRORS, IS_UDPLITE(sk)); | ||
596 | } | 600 | } |
597 | } | 601 | } |
598 | /* | 602 | /* |
@@ -754,8 +758,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
754 | bh_lock_sock(sk); | 758 | bh_lock_sock(sk); |
755 | if (!sock_owned_by_user(sk)) | 759 | if (!sock_owned_by_user(sk)) |
756 | udpv6_queue_rcv_skb(sk, skb); | 760 | udpv6_queue_rcv_skb(sk, skb); |
757 | else | 761 | else if (sk_add_backlog(sk, skb)) { |
758 | sk_add_backlog(sk, skb); | 762 | atomic_inc(&sk->sk_drops); |
763 | bh_unlock_sock(sk); | ||
764 | sock_put(sk); | ||
765 | goto discard; | ||
766 | } | ||
759 | bh_unlock_sock(sk); | 767 | bh_unlock_sock(sk); |
760 | sock_put(sk); | 768 | sock_put(sk); |
761 | return 0; | 769 | return 0; |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index dbdc696f5fc5..ae181651c75a 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, | |||
116 | return 0; | 116 | return 0; |
117 | } | 117 | } |
118 | 118 | ||
119 | static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) | 119 | static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
120 | struct flowi *fl) | ||
120 | { | 121 | { |
121 | struct rt6_info *rt = (struct rt6_info*)xdst->route; | 122 | struct rt6_info *rt = (struct rt6_info*)xdst->route; |
122 | 123 | ||