X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;ds=sidebyside;f=net%2Fdecnet%2Fdn_route.c;h=dd0761e3d280cc311cbdf88b278b5e91cd4951ab;hb=331c4ee7faa4ee1e1404c872a139784753100498;hp=3407f190afe8892699025bf504c73111a082b8b5;hpb=8d06afab73a75f40ae2864e6c296356bab1ab473;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 3407f19..dd0761e 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -55,7 +55,6 @@ GNU General Public License for more details. *******************************************************************************/ -#include #include #include #include @@ -81,6 +80,7 @@ #include #include #include +#include #include #include #include @@ -133,9 +133,9 @@ static struct dst_ops dn_dst_ops = { .entries = ATOMIC_INIT(0), }; -static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst) +static __inline__ unsigned dn_hash(__le16 src, __le16 dst) { - unsigned short tmp = src ^ dst; + __u16 tmp = (__u16 __force)(src ^ dst); tmp ^= (tmp >> 3); tmp ^= (tmp >> 5); tmp ^= (tmp >> 10); @@ -149,8 +149,7 @@ static inline void dnrt_free(struct dn_route *rt) static inline void dnrt_drop(struct dn_route *rt) { - if (rt) - dst_release(&rt->u.dst); + dst_release(&rt->u.dst); call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free); } @@ -379,9 +378,9 @@ static int dn_return_short(struct sk_buff *skb) { struct dn_skb_cb *cb; unsigned char *ptr; - dn_address *src; - dn_address *dst; - dn_address tmp; + __le16 *src; + __le16 *dst; + __le16 tmp; /* Add back headers */ skb_push(skb, skb->data - skb->nh.raw); @@ -394,9 +393,9 @@ static int dn_return_short(struct sk_buff *skb) ptr = skb->data + 2; *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS; - dst = (dn_address *)ptr; + dst = (__le16 *)ptr; ptr += 2; - src = (dn_address *)ptr; + src = (__le16 *)ptr; ptr += 2; *ptr = 0; /* Zero hop count */ @@ -475,7 +474,8 @@ static int dn_route_rx_packet(struct sk_buff *skb) struct dn_skb_cb *cb = DN_SKB_CB(skb); printk(KERN_DEBUG "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n", - (int)cb->rt_flags, devname, skb->len, cb->src, cb->dst, + (int)cb->rt_flags, devname, skb->len, + dn_ntohs(cb->src), dn_ntohs(cb->dst), err, skb->pkt_type); } @@ -505,7 +505,7 @@ static int dn_route_rx_long(struct sk_buff *skb) /* Destination info */ ptr += 2; - cb->dst = dn_htons(dn_eth2dn(ptr)); + cb->dst = dn_eth2dn(ptr); if (memcmp(ptr, dn_hiord_addr, 4) != 0) goto drop_it; ptr += 6; @@ -513,7 +513,7 @@ static int dn_route_rx_long(struct sk_buff *skb) /* Source info */ ptr += 2; - cb->src = dn_htons(dn_eth2dn(ptr)); + cb->src = dn_eth2dn(ptr); if (memcmp(ptr, dn_hiord_addr, 4) != 0) goto drop_it; ptr += 6; @@ -541,9 +541,9 @@ static int dn_route_rx_short(struct sk_buff *skb) skb_pull(skb, 5); skb->h.raw = skb->data; - cb->dst = *(dn_address *)ptr; + cb->dst = *(__le16 *)ptr; ptr += 2; - cb->src = *(dn_address *)ptr; + cb->src = *(__le16 *)ptr; ptr += 2; cb->hops = *ptr & 0x3f; @@ -575,7 +575,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type { struct dn_skb_cb *cb; unsigned char flags = 0; - __u16 len = dn_ntohs(*(__u16 *)skb->data); + __u16 len = dn_ntohs(*(__le16 *)skb->data); struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr; unsigned char padlen = 0; @@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type padlen); if (flags & DN_RT_PKT_CNTL) { - if (unlikely(skb_is_nonlinear(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) + if (unlikely(skb_linearize(skb))) goto dump_it; switch(flags & DN_RT_CNTL_MSK) { @@ -782,7 +781,7 @@ static int dn_rt_bug(struct sk_buff *skb) struct dn_skb_cb *cb = DN_SKB_CB(skb); printk(KERN_DEBUG "dn_rt_bug: skb from:%04x to:%04x\n", - cb->src, cb->dst); + dn_ntohs(cb->src), dn_ntohs(cb->dst)); } kfree_skb(skb); @@ -823,7 +822,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) return 0; } -static inline int dn_match_addr(__u16 addr1, __u16 addr2) +static inline int dn_match_addr(__le16 addr1, __le16 addr2) { __u16 tmp = dn_ntohs(addr1) ^ dn_ntohs(addr2); int match = 16; @@ -834,9 +833,9 @@ static inline int dn_match_addr(__u16 addr1, __u16 addr2) return match; } -static __u16 dnet_select_source(const struct net_device *dev, __u16 daddr, int scope) +static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope) { - __u16 saddr = 0; + __le16 saddr = 0; struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; int best_match = 0; @@ -861,14 +860,14 @@ static __u16 dnet_select_source(const struct net_device *dev, __u16 daddr, int s return saddr; } -static inline __u16 __dn_fib_res_prefsrc(struct dn_fib_res *res) +static inline __le16 __dn_fib_res_prefsrc(struct dn_fib_res *res) { return dnet_select_source(DN_FIB_RES_DEV(*res), DN_FIB_RES_GW(*res), res->scope); } -static inline __u16 dn_fib_rules_map_destination(__u16 daddr, struct dn_fib_res *res) +static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_res *res) { - __u16 mask = dnet_make_mask(res->prefixlen); + __le16 mask = dnet_make_mask(res->prefixlen); return (daddr&~mask)|res->fi->fib_nh->nh_gw; } @@ -892,12 +891,13 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old struct dn_fib_res res = { .fi = NULL, .type = RTN_UNICAST }; int err; int free_res = 0; - __u16 gateway = 0; + __le16 gateway = 0; if (decnet_debug_level & 16) printk(KERN_DEBUG "dn_route_output_slow: dst=%04x src=%04x mark=%d" - " iif=%d oif=%d\n", oldflp->fld_dst, oldflp->fld_src, + " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), + dn_ntohs(oldflp->fld_src), oldflp->fld_fwmark, loopback_dev.ifindex, oldflp->oif); /* If we have an output interface, verify its a DECnet device */ @@ -926,8 +926,13 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { if (!dev_out->dn_ptr) continue; - if (dn_dev_islocal(dev_out, oldflp->fld_src)) - break; + if (!dn_dev_islocal(dev_out, oldflp->fld_src)) + continue; + if ((dev_out->flags & IFF_LOOPBACK) && + oldflp->fld_dst && + !dn_dev_islocal(dev_out, oldflp->fld_dst)) + continue; + break; } read_unlock(&dev_base_lock); if (dev_out == NULL) @@ -961,8 +966,9 @@ source_ok: if (decnet_debug_level & 16) printk(KERN_DEBUG "dn_route_output_slow: initial checks complete." - " dst=%o4x src=%04x oif=%d try_hard=%d\n", fl.fld_dst, - fl.fld_src, fl.oif, try_hard); + " dst=%o4x src=%04x oif=%d try_hard=%d\n", + dn_ntohs(fl.fld_dst), dn_ntohs(fl.fld_src), + fl.oif, try_hard); /* * N.B. If the kernel is compiled without router support then @@ -1218,8 +1224,8 @@ static int dn_route_input_slow(struct sk_buff *skb) struct neighbour *neigh = NULL; unsigned hash; int flags = 0; - __u16 gateway = 0; - __u16 local_src = 0; + __le16 gateway = 0; + __le16 local_src = 0; struct flowi fl = { .nl_u = { .dn_u = { .daddr = cb->dst, .saddr = cb->src, @@ -1266,7 +1272,7 @@ static int dn_route_input_slow(struct sk_buff *skb) res.type = RTN_LOCAL; flags |= RTCF_DIRECTSRC; } else { - __u16 src_map = fl.fld_src; + __le16 src_map = fl.fld_src; free_res = 1; out_dev = DN_FIB_RES_DEV(res); @@ -1279,7 +1285,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) { @@ -1480,6 +1486,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; @@ -1604,9 +1611,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); @@ -1776,14 +1781,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;