netfilter: add nf_ipv6_ops hook to fix xt_addrtype with IPv6
[linux-3.10.git] / net / ipv6 / route.c
index 2d94d5a..ad0aa6b 100644 (file)
@@ -287,6 +287,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
 {
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct inet6_dev *idev = rt->rt6i_idev;
+       struct dst_entry *from = dst->from;
 
        if (!(rt->dst.flags & DST_HOST))
                dst_destroy_metrics_generic(dst);
@@ -296,8 +297,8 @@ static void ip6_dst_destroy(struct dst_entry *dst)
                in6_dev_put(idev);
        }
 
-       if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
-               dst_release(dst->from);
+       dst->from = NULL;
+       dst_release(from);
 
        if (rt6_has_peer(rt)) {
                struct inet_peer *peer = rt6_peer_ptr(rt);
@@ -492,10 +493,10 @@ static void rt6_probe(struct rt6_info *rt)
                struct in6_addr mcaddr;
                struct in6_addr *target;
 
-               neigh->updated = jiffies;
-
-               if (neigh)
+               if (neigh) {
+                       neigh->updated = jiffies;
                        write_unlock(&neigh->lock);
+               }
 
                target = (struct in6_addr *)&rt->rt6i_gateway;
                addrconf_addr_solict_mult(target, &mcaddr);
@@ -1010,7 +1011,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
 
                rt->rt6i_gateway = ort->rt6i_gateway;
                rt->rt6i_flags = ort->rt6i_flags;
-               rt6_clean_expires(rt);
                rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -1784,8 +1784,6 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
                if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
                    (RTF_DEFAULT | RTF_ADDRCONF))
                        rt6_set_from(rt, ort);
-               else
-                       rt6_clean_expires(rt);
                rt->rt6i_metric = 0;
 
 #ifdef CONFIG_IPV6_SUBTREES
@@ -1917,7 +1915,8 @@ void rt6_purge_dflt_routers(struct net *net)
 restart:
        read_lock_bh(&table->tb6_lock);
        for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
-               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
+               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
+                   (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
                        dst_hold(&rt->dst);
                        read_unlock_bh(&table->tb6_lock);
                        ip6_del_rt(rt);
@@ -2356,7 +2355,7 @@ beginning:
        return last_err;
 }
 
-static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh)
 {
        struct fib6_config cfg;
        int err;
@@ -2371,7 +2370,7 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
                return ip6_route_del(&cfg);
 }
 
-static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh)
 {
        struct fib6_config cfg;
        int err;
@@ -2563,7 +2562,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
                     prefix, 0, NLM_F_MULTI);
 }
 
-static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
+static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)
 {
        struct net *net = sock_net(in_skb->sk);
        struct nlattr *tb[RTA_MAX+1];
@@ -2995,8 +2994,8 @@ static void __net_exit ip6_route_net_exit(struct net *net)
 static int __net_init ip6_route_net_init_late(struct net *net)
 {
 #ifdef CONFIG_PROC_FS
-       proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
-       proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
+       proc_create("ipv6_route", 0, net->proc_net, &ipv6_route_proc_fops);
+       proc_create("rt6_stats", S_IRUGO, net->proc_net, &rt6_stats_seq_fops);
 #endif
        return 0;
 }
@@ -3004,8 +3003,8 @@ static int __net_init ip6_route_net_init_late(struct net *net)
 static void __net_exit ip6_route_net_exit_late(struct net *net)
 {
 #ifdef CONFIG_PROC_FS
-       proc_net_remove(net, "ipv6_route");
-       proc_net_remove(net, "rt6_stats");
+       remove_proc_entry("ipv6_route", net->proc_net);
+       remove_proc_entry("rt6_stats", net->proc_net);
 #endif
 }