]> err.no Git - linux-2.6/blobdiff - net/ipv4/route.c
Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerp...
[linux-2.6] / net / ipv4 / route.c
index 9d8fbf1e5bc3e4200aa60b9967255d176da3ce72..2daa0dc19d339e5dd3659ca63a9118279d4cc039 100644 (file)
@@ -566,9 +566,13 @@ static inline u32 rt_score(struct rtable *rt)
 
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
-       return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 &&
-              fl1->oif     == fl2->oif &&
-              fl1->iif     == fl2->iif;
+       return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
+               (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
+               (fl1->mark ^ fl2->mark) |
+               (*(u16 *)&fl1->nl_u.ip4_u.tos ^
+                *(u16 *)&fl2->nl_u.ip4_u.tos) |
+               (fl1->oif ^ fl2->oif) |
+               (fl1->iif ^ fl2->iif)) == 0;
 }
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
@@ -1078,7 +1082,7 @@ static void ip_select_fb_ident(struct iphdr *iph)
        u32 salt;
 
        spin_lock_bh(&ip_fb_id_lock);
-       salt = secure_ip_id(ip_fallback_id ^ iph->daddr);
+       salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
        iph->id = htons(salt & 0xFFFF);
        ip_fallback_id = salt;
        spin_unlock_bh(&ip_fb_id_lock);
@@ -1321,7 +1325,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
        /* Check for load limit; set rate_last to the latest sent
         * redirect.
         */
-       if (time_after(jiffies,
+       if (rt->u.dst.rate_tokens == 0 ||
+           time_after(jiffies,
                       (rt->u.dst.rate_last +
                        (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
                icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
@@ -1399,8 +1404,8 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
        int i;
        unsigned short old_mtu = ntohs(iph->tot_len);
        struct rtable *rth;
-       u32  skeys[2] = { iph->saddr, 0, };
-       u32  daddr = iph->daddr;
+       __be32  skeys[2] = { iph->saddr, 0, };
+       __be32  daddr = iph->daddr;
        unsigned short est_mtu = 0;
 
        if (ipv4_config.no_pmtu_disc)
@@ -1637,9 +1642,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
 #ifdef CONFIG_NET_CLS_ROUTE
@@ -1722,7 +1725,8 @@ static inline int __mkroute_input(struct sk_buff *skb,
        int err;
        struct in_device *out_dev;
        unsigned flags = 0;
-       u32 spec_dst, itag;
+       __be32 spec_dst;
+       u32 itag;
 
        /* get a working reference to the output device */
        out_dev = in_dev_get(FIB_RES_DEV(*res));
@@ -1777,14 +1781,12 @@ static inline int __mkroute_input(struct sk_buff *skb,
 #endif
        if (in_dev->cnf.no_policy)
                rth->u.dst.flags |= DST_NOPOLICY;
-       if (in_dev->cnf.no_xfrm)
+       if (out_dev->cnf.no_xfrm)
                rth->u.dst.flags |= DST_NOXFRM;
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
        rth->rt_gateway = daddr;
@@ -1913,10 +1915,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                                        .saddr = saddr,
                                        .tos = tos,
                                        .scope = RT_SCOPE_UNIVERSE,
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                                       .fwmark = skb->nfmark
-#endif
                                      } },
+                           .mark = skb->mark,
                            .iif = dev->ifindex };
        unsigned        flags = 0;
        u32             itag = 0;
@@ -1938,7 +1938,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
                goto martian_source;
 
-       if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
+       if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
                goto brd_input;
 
        /* Accept zero addresses only to limited broadcast;
@@ -2027,9 +2027,7 @@ local_input:
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
 #ifdef CONFIG_NET_CLS_ROUTE
@@ -2106,9 +2104,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                    rth->fl.fl4_src == saddr &&
                    rth->fl.iif == iif &&
                    rth->fl.oif == 0 &&
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                   rth->fl.fl4_fwmark == skb->nfmark &&
-#endif
+                   rth->fl.mark == skb->mark &&
                    rth->fl.fl4_tos == tos) {
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
@@ -2171,7 +2167,7 @@ static inline int __mkroute_output(struct rtable **result,
        if (LOOPBACK(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
                return -EINVAL;
 
-       if (fl->fl4_dst == 0xFFFFFFFF)
+       if (fl->fl4_dst == htonl(0xFFFFFFFF))
                res->type = RTN_BROADCAST;
        else if (MULTICAST(fl->fl4_dst))
                res->type = RTN_MULTICAST;
@@ -2232,9 +2228,7 @@ static inline int __mkroute_output(struct rtable **result,
        rth->fl.fl4_tos = tos;
        rth->fl.fl4_src = oldflp->fl4_src;
        rth->fl.oif     = oldflp->oif;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= oldflp->fl4_fwmark;
-#endif
+       rth->fl.mark    = oldflp->mark;
        rth->rt_dst     = fl->fl4_dst;
        rth->rt_src     = fl->fl4_src;
        rth->rt_iif     = oldflp->oif ? : dev_out->ifindex;
@@ -2378,10 +2372,8 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                                        .scope = ((tos & RTO_ONLINK) ?
                                                  RT_SCOPE_LINK :
                                                  RT_SCOPE_UNIVERSE),
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                                       .fwmark = oldflp->fl4_fwmark
-#endif
                                      } },
+                           .mark = oldflp->mark,
                            .iif = loopback_dev.ifindex,
                            .oif = oldflp->oif };
        struct fib_result res;
@@ -2417,7 +2409,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                 */
 
                if (oldflp->oif == 0
-                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF)) {
+                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
                        /* Special hack: user can direct multicasts
                           and limited broadcast via necessary interface
                           without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2454,7 +2446,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        goto out;       /* Wrong error code */
                }
 
-               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF) {
+               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
                        if (!fl.fl4_src)
                                fl.fl4_src = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_LINK);
@@ -2576,9 +2568,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
                    rth->fl.fl4_src == flp->fl4_src &&
                    rth->fl.iif == 0 &&
                    rth->fl.oif == flp->oif &&
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                   rth->fl.fl4_fwmark == flp->fl4_fwmark &&
-#endif
+                   rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
                            (IPTOS_RT_MASK | RTO_ONLINK))) {
 
@@ -2640,7 +2630,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
        struct rtable *rt = (struct rtable*)skb->dst;
        struct rtmsg *r;
        struct nlmsghdr *nlh;
-       struct rta_cacheinfo ci;
+       long expires;
+       u32 id = 0, ts = 0, tsage = 0, error;
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
        if (nlh == NULL)
@@ -2660,11 +2651,11 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
        if (rt->rt_flags & RTCF_NOTIFY)
                r->rtm_flags |= RTM_F_NOTIFY;
 
-       NLA_PUT_U32(skb, RTA_DST, rt->rt_dst);
+       NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
 
        if (rt->fl.fl4_src) {
                r->rtm_src_len = 32;
-               NLA_PUT_U32(skb, RTA_SRC, rt->fl.fl4_src);
+               NLA_PUT_BE32(skb, RTA_SRC, rt->fl.fl4_src);
        }
        if (rt->u.dst.dev)
                NLA_PUT_U32(skb, RTA_OIF, rt->u.dst.dev->ifindex);
@@ -2677,36 +2668,29 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
 #endif
        if (rt->fl.iif)
-               NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_spec_dst);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
        else if (rt->rt_src != rt->fl.fl4_src)
-               NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_src);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
 
        if (rt->rt_dst != rt->rt_gateway)
-               NLA_PUT_U32(skb, RTA_GATEWAY, rt->rt_gateway);
+               NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
 
        if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
                goto nla_put_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;
+       error = rt->u.dst.error;
+       expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
        if (rt->peer) {
-               ci.rta_id = rt->peer->ip_id_count;
+               id = rt->peer->ip_id_count;
                if (rt->peer->tcp_ts_stamp) {
-                       ci.rta_ts = rt->peer->tcp_ts;
-                       ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
+                       ts = rt->peer->tcp_ts;
+                       tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
                }
        }
 
        if (rt->fl.iif) {
 #ifdef CONFIG_IP_MROUTE
-               u32 dst = rt->rt_dst;
+               __be32 dst = rt->rt_dst;
 
                if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
                    ipv4_devconf.mc_forwarding) {
@@ -2719,7 +2703,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                                } else {
                                        if (err == -EMSGSIZE)
                                                goto nla_put_failure;
-                                       ci.rta_error = err;
+                                       error = err;
                                }
                        }
                } else
@@ -2727,7 +2711,9 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                        NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif);
        }
 
-       NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
+       if (rtnl_put_cacheinfo(skb, &rt->u.dst, id, ts, tsage,
+                              expires, error) < 0)
+               goto nla_put_failure;
 
        return nlmsg_end(skb, nlh);
 
@@ -2767,8 +2753,8 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
        skb->nh.iph->protocol = IPPROTO_ICMP;
        skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
 
-       src = tb[RTA_SRC] ? nla_get_u32(tb[RTA_SRC]) : 0;
-       dst = tb[RTA_DST] ? nla_get_u32(tb[RTA_DST]) : 0;
+       src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
+       dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
        iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
 
        if (iif) {
@@ -2887,8 +2873,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
                                                void __user *oldval,
                                                size_t __user *oldlenp,
                                                void __user *newval,
-                                               size_t newlen,
-                                               void **context)
+                                               size_t newlen)
 {
        int delay;
        if (newlen != sizeof(int))