fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / decnet / dn_route.c
index 743e9fc..9881933 100644 (file)
@@ -80,6 +80,7 @@
 #include <net/neighbour.h>
 #include <net/dst.h>
 #include <net/flow.h>
+#include <net/fib_rules.h>
 #include <net/dn.h>
 #include <net/dn_dev.h>
 #include <net/dn_nsp.h>
@@ -266,9 +267,12 @@ static void dn_dst_link_failure(struct sk_buff *skb)
 
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
-       return memcmp(&fl1->nl_u.dn_u, &fl2->nl_u.dn_u, sizeof(fl1->nl_u.dn_u)) == 0 &&
-               fl1->oif == fl2->oif &&
-               fl1->iif == fl2->iif;
+       return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
+               (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
+               (fl1->mark ^ fl2->mark) |
+               (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
+               (fl1->oif ^ fl2->oif) |
+               (fl1->iif ^ fl2->iif)) == 0;
 }
 
 static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
@@ -876,10 +880,8 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
                                      { .daddr = oldflp->fld_dst,
                                        .saddr = oldflp->fld_src,
                                        .scope = RT_SCOPE_UNIVERSE,
-#ifdef CONFIG_DECNET_ROUTE_FWMARK
-                                       .fwmark = oldflp->fld_fwmark
-#endif
                                     } },
+                           .mark = oldflp->mark,
                            .iif = loopback_dev.ifindex,
                            .oif = oldflp->oif };
        struct dn_route *rt = NULL;
@@ -897,7 +899,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
                       "dn_route_output_slow: dst=%04x src=%04x mark=%d"
                       " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
                       dn_ntohs(oldflp->fld_src),
-                       oldflp->fld_fwmark, loopback_dev.ifindex, oldflp->oif);
+                       oldflp->mark, loopback_dev.ifindex, oldflp->oif);
 
        /* If we have an output interface, verify its a DECnet device */
        if (oldflp->oif) {
@@ -1102,9 +1104,7 @@ make_route:
        rt->fl.fld_dst    = oldflp->fld_dst;
        rt->fl.oif        = oldflp->oif;
        rt->fl.iif        = 0;
-#ifdef CONFIG_DECNET_ROUTE_FWMARK
-       rt->fl.fld_fwmark = oldflp->fld_fwmark;
-#endif
+       rt->fl.mark       = oldflp->mark;
 
        rt->rt_saddr      = fl.fld_src;
        rt->rt_daddr      = fl.fld_dst;
@@ -1172,9 +1172,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
                        rt = rcu_dereference(rt->u.rt_next)) {
                        if ((flp->fld_dst == rt->fl.fld_dst) &&
                            (flp->fld_src == rt->fl.fld_src) &&
-#ifdef CONFIG_DECNET_ROUTE_FWMARK
-                           (flp->fld_fwmark == rt->fl.fld_fwmark) &&
-#endif
+                           (flp->mark == rt->fl.mark) &&
                            (rt->fl.iif == 0) &&
                            (rt->fl.oif == flp->oif)) {
                                rt->u.dst.lastuse = jiffies;
@@ -1229,10 +1227,8 @@ static int dn_route_input_slow(struct sk_buff *skb)
                                     { .daddr = cb->dst,
                                       .saddr = cb->src,
                                       .scope = RT_SCOPE_UNIVERSE,
-#ifdef CONFIG_DECNET_ROUTE_FWMARK
-                                      .fwmark = skb->nfmark
-#endif
                                    } },
+                           .mark = skb->mark,
                            .iif = skb->dev->ifindex };
        struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
        int err = -EINVAL;
@@ -1269,7 +1265,6 @@ static int dn_route_input_slow(struct sk_buff *skb)
                        goto e_inval;
 
                res.type = RTN_LOCAL;
-               flags |= RTCF_DIRECTSRC;
        } else {
                __le16 src_map = fl.fld_src;
                free_res = 1;
@@ -1284,7 +1279,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
                dev_hold(out_dev);
 
                if (res.r)
-                       src_map = dn_fib_rules_policy(fl.fld_src, &res, &flags);
+                       src_map = fl.fld_src; /* no NAT support for now */
 
                gateway = DN_FIB_RES_GW(res);
                if (res.type == RTN_NAT) {
@@ -1340,7 +1335,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
                        goto make_route;
 
                /* Packet was intra-ethernet, so we know its on-link */
-               if (cb->rt_flags | DN_RT_F_IE) {
+               if (cb->rt_flags & DN_RT_F_IE) {
                        gateway = cb->src;
                        flags |= RTCF_DIRECTSRC;
                        goto make_route;
@@ -1380,7 +1375,7 @@ make_route:
        rt->fl.fld_dst    = cb->dst;
        rt->fl.oif        = 0;
        rt->fl.iif        = in_dev->ifindex;
-       rt->fl.fld_fwmark = fl.fld_fwmark;
+       rt->fl.mark       = fl.mark;
 
        rt->u.dst.flags = DST_HOST;
        rt->u.dst.neighbour = neigh;
@@ -1452,9 +1447,7 @@ int dn_route_input(struct sk_buff *skb)
                if ((rt->fl.fld_src == cb->src) &&
                    (rt->fl.fld_dst == cb->dst) &&
                    (rt->fl.oif == 0) &&
-#ifdef CONFIG_DECNET_ROUTE_FWMARK
-                   (rt->fl.fld_fwmark == skb->nfmark) &&
-#endif
+                   (rt->fl.mark == skb->mark) &&
                    (rt->fl.iif == cb->iif)) {
                        rt->u.dst.lastuse = jiffies;
                        dst_hold(&rt->u.dst);
@@ -1476,7 +1469,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        struct rtmsg *r;
        struct nlmsghdr *nlh;
        unsigned char *b = skb->tail;
-       struct rta_cacheinfo ci;
+       long expires;
 
        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
        r = NLMSG_DATA(nlh);
@@ -1485,6 +1478,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        r->rtm_src_len = 0;
        r->rtm_tos = 0;
        r->rtm_table = RT_TABLE_MAIN;
+       RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
        r->rtm_type = rt->rt_type;
        r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
        r->rtm_scope = RT_SCOPE_UNIVERSE;
@@ -1508,16 +1502,10 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
                RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
        if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
                goto rtattr_failure;
-       ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
-       ci.rta_used     = rt->u.dst.__use;
-       ci.rta_clntref  = atomic_read(&rt->u.dst.__refcnt);
-       if (rt->u.dst.expires)
-               ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
-       else
-               ci.rta_expires = 0;
-       ci.rta_error    = rt->u.dst.error;
-       ci.rta_id       = ci.rta_ts = ci.rta_tsage = 0;
-       RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
+       expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
+       if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, expires,
+                              rt->u.dst.error) < 0)
+               goto rtattr_failure;
        if (rt->fl.iif)
                RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
 
@@ -1598,8 +1586,6 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
-       NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
-
        err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
 
        if (err == 0)
@@ -1609,9 +1595,7 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
                goto out_free;
        }
 
-       err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
-
-       return err;
+       return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
 
 out_free:
        kfree_skb(skb);
@@ -1781,14 +1765,9 @@ void __init dn_route_init(void)
 {
        int i, goal, order;
 
-       dn_dst_ops.kmem_cachep = kmem_cache_create("dn_dst_cache",
-                                                  sizeof(struct dn_route),
-                                                  0, SLAB_HWCACHE_ALIGN,
-                                                  NULL, NULL);
-
-       if (!dn_dst_ops.kmem_cachep)
-               panic("DECnet: Failed to allocate dn_dst_cache\n");
-
+       dn_dst_ops.kmem_cachep =
+               kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
+                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
        init_timer(&dn_route_timer);
        dn_route_timer.function = dn_dst_check_expire;
        dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;