[IPV6] ADDRCONF: Convert ipv6_get_saddr() to ipv6_dev_get_saddr().
[safe/jmp/linux-2.6] / net / ipv6 / route.c
index b80ef57..6abe7da 100644 (file)
 
 #define CLONE_OFFLINK_ROUTE 0
 
-static int ip6_rt_max_size = 4096;
-static int ip6_rt_gc_min_interval = HZ / 2;
-static int ip6_rt_gc_timeout = 60*HZ;
-int ip6_rt_gc_interval = 30*HZ;
-static int ip6_rt_gc_elasticity = 9;
-static int ip6_rt_mtu_expires = 10*60*HZ;
-static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
-
 static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void            ip6_dst_destroy(struct dst_entry *);
 static void            ip6_dst_ifdown(struct dst_entry *,
                                       struct net_device *dev, int how);
-static int              ip6_dst_gc(void);
+static int              ip6_dst_gc(struct dst_ops *ops);
 
 static int             ip6_pkt_discard(struct sk_buff *skb);
 static int             ip6_pkt_discard_out(struct sk_buff *skb);
@@ -115,6 +107,7 @@ static struct dst_ops ip6_dst_ops = {
        .update_pmtu            =       ip6_rt_update_pmtu,
        .local_out              =       ip6_local_out,
        .entry_size             =       sizeof(struct rt6_info),
+       .entries                =       ATOMIC_INIT(0),
 };
 
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -128,6 +121,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .check                  =       ip6_dst_check,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .entry_size             =       sizeof(struct rt6_info),
+       .entries                =       ATOMIC_INIT(0),
 };
 
 struct rt6_info ip6_null_entry = {
@@ -609,7 +603,9 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
 
 int ip6_ins_rt(struct rt6_info *rt)
 {
-       struct nl_info info = {};
+       struct nl_info info = {
+               .nl_net = &init_net,
+       };
        return __ip6_ins_rt(rt, &info);
 }
 
@@ -894,8 +890,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
 {
        mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
 
-       if (mtu < ip6_rt_min_advmss)
-               mtu = ip6_rt_min_advmss;
+       if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss)
+               mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss;
 
        /*
         * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
@@ -989,25 +985,25 @@ int ndisc_dst_gc(int *more)
        return freed;
 }
 
-static int ip6_dst_gc(void)
+static int ip6_dst_gc(struct dst_ops *ops)
 {
        static unsigned expire = 30*HZ;
        static unsigned long last_gc;
        unsigned long now = jiffies;
 
-       if (time_after(last_gc + ip6_rt_gc_min_interval, now) &&
-           atomic_read(&ip6_dst_ops.entries) <= ip6_rt_max_size)
+       if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) &&
+           atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size)
                goto out;
 
        expire++;
        fib6_run_gc(expire);
        last_gc = now;
        if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh)
-               expire = ip6_rt_gc_timeout>>1;
+               expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1;
 
 out:
-       expire -= expire>>ip6_rt_gc_elasticity;
-       return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size);
+       expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity;
+       return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size);
 }
 
 /* Clean host part of a prefix. Not necessary in radix tree,
@@ -1267,7 +1263,9 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
 
 int ip6_del_rt(struct rt6_info *rt)
 {
-       struct nl_info info = {};
+       struct nl_info info = {
+               .nl_net = &init_net,
+       };
        return __ip6_del_rt(rt, &info);
 }
 
@@ -1513,7 +1511,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
                rt->u.dst.metrics[RTAX_MTU-1] = pmtu;
                if (allfrag)
                        rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
-               dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires);
+               dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
                rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
                goto out;
        }
@@ -1539,7 +1537,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
                 * which is 10 mins. After 10 mins the decreased pmtu is expired
                 * and detecting PMTU increase will be automatically happened.
                 */
-               dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
+               dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
                nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
 
                ip6_ins_rt(nrt);
@@ -1622,7 +1620,7 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
 {
        struct fib6_config cfg = {
                .fc_table       = RT6_TABLE_INFO,
-               .fc_metric      = 1024,
+               .fc_metric      = IP6_RT_PRIO_USER,
                .fc_ifindex     = ifindex,
                .fc_dst_len     = prefixlen,
                .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
@@ -1672,7 +1670,7 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
 {
        struct fib6_config cfg = {
                .fc_table       = RT6_TABLE_DFLT,
-               .fc_metric      = 1024,
+               .fc_metric      = IP6_RT_PRIO_USER,
                .fc_ifindex     = dev->ifindex,
                .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
                                  RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
@@ -1721,6 +1719,8 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
        cfg->fc_src_len = rtmsg->rtmsg_src_len;
        cfg->fc_flags = rtmsg->rtmsg_flags;
 
+       cfg->fc_nlinfo.nl_net = &init_net;
+
        ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
        ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
        ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
@@ -1767,8 +1767,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
  *     Drop the packet on the floor
  */
 
-static inline int ip6_pkt_drop(struct sk_buff *skb, int code,
-                              int ipstats_mib_noroutes)
+static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes)
 {
        int type;
        switch (ipstats_mib_noroutes) {
@@ -1912,7 +1911,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
         */
        if (rt->rt6i_dev == arg->dev &&
            !dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
-           (dst_mtu(&rt->u.dst) > arg->mtu ||
+           (dst_mtu(&rt->u.dst) >= arg->mtu ||
             (dst_mtu(&rt->u.dst) < arg->mtu &&
              dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) {
                rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu;
@@ -1965,6 +1964,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
        cfg->fc_nlinfo.nlh = nlh;
+       cfg->fc_nlinfo.nl_net = skb->sk->sk_net;
 
        if (tb[RTA_GATEWAY]) {
                nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
@@ -2122,7 +2122,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                NLA_PUT_U32(skb, RTA_IIF, iif);
        else if (dst) {
                struct in6_addr saddr_buf;
-               if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
+               if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
+                                      dst, &saddr_buf) == 0)
                        NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
        }
 
@@ -2395,24 +2396,23 @@ static inline void ipv6_route_proc_fini(struct net *net)
 
 #ifdef CONFIG_SYSCTL
 
-static int flush_delay;
-
 static
 int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
                              void __user *buffer, size_t *lenp, loff_t *ppos)
 {
+       int delay = init_net.ipv6.sysctl.flush_delay;
        if (write) {
                proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-               fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay);
+               fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay);
                return 0;
        } else
                return -EINVAL;
 }
 
-ctl_table ipv6_route_table[] = {
+ctl_table ipv6_route_table_template[] = {
        {
                .procname       =       "flush",
-               .data           =       &flush_delay,
+               .data           =       &init_net.ipv6.sysctl.flush_delay,
                .maxlen         =       sizeof(int),
                .mode           =       0200,
                .proc_handler   =       &ipv6_sysctl_rtcache_flush
@@ -2428,7 +2428,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MAX_SIZE,
                .procname       =       "max_size",
-               .data           =       &ip6_rt_max_size,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_max_size,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec,
@@ -2436,7 +2436,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL,
                .procname       =       "gc_min_interval",
-               .data           =       &ip6_rt_gc_min_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2445,7 +2445,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_TIMEOUT,
                .procname       =       "gc_timeout",
-               .data           =       &ip6_rt_gc_timeout,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2454,7 +2454,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_INTERVAL,
                .procname       =       "gc_interval",
-               .data           =       &ip6_rt_gc_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2463,7 +2463,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_ELASTICITY,
                .procname       =       "gc_elasticity",
-               .data           =       &ip6_rt_gc_elasticity,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2472,7 +2472,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MTU_EXPIRES,
                .procname       =       "mtu_expires",
-               .data           =       &ip6_rt_mtu_expires,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2481,7 +2481,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MIN_ADVMSS,
                .procname       =       "min_adv_mss",
-               .data           =       &ip6_rt_min_advmss,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_min_advmss,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2490,7 +2490,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
                .procname       =       "gc_min_interval_ms",
-               .data           =       &ip6_rt_gc_min_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_ms_jiffies,
@@ -2499,6 +2499,29 @@ ctl_table ipv6_route_table[] = {
        { .ctl_name = 0 }
 };
 
+struct ctl_table *ipv6_route_sysctl_init(struct net *net)
+{
+       struct ctl_table *table;
+
+       table = kmemdup(ipv6_route_table_template,
+                       sizeof(ipv6_route_table_template),
+                       GFP_KERNEL);
+
+       if (table) {
+               table[0].data = &net->ipv6.sysctl.flush_delay;
+               /* table[1].data will be handled when we have
+                  routes per namespace */
+               table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
+               table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
+               table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
+               table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
+               table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
+               table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
+               table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
+       }
+
+       return table;
+}
 #endif
 
 int __init ip6_route_init(void)