diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b39ae99122d..9f80518aacb 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -440,7 +440,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, if (pref == ICMPV6_ROUTER_PREF_INVALID) pref = ICMPV6_ROUTER_PREF_MEDIUM; - lifetime = htonl(rinfo->lifetime); + lifetime = ntohl(rinfo->lifetime); if (lifetime == 0xffffffff) { /* infinity */ } else if (lifetime > 0x7fffffff/HZ) { @@ -711,12 +711,10 @@ void ip6_route_input(struct sk_buff *skb) .ip6_u = { .daddr = iph->daddr, .saddr = iph->saddr, -#ifdef CONFIG_IPV6_ROUTE_FWMARK - .fwmark = skb->nfmark, -#endif - .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK, + .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, }, }, + .mark = skb->mark, .proto = iph->nexthdr, }; @@ -942,7 +940,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev, fib6_force_start_gc(); out: - return (struct dst_entry *)rt; + return &rt->u.dst; } int ndisc_dst_gc(int *more) @@ -1225,7 +1223,7 @@ out: if (idev) in6_dev_put(idev); if (rt) - dst_free((struct dst_entry *) rt); + dst_free(&rt->u.dst); return err; } @@ -1751,9 +1749,9 @@ static inline int ip6_pkt_drop(struct sk_buff *skb, int code) { int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) - IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); + IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); - IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); + IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES); icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); kfree_skb(skb); return 0; @@ -1824,7 +1822,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->rt6i_flags |= RTF_LOCAL; rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); if (rt->rt6i_nexthop == NULL) { - dst_free((struct dst_entry *) rt); + dst_free(&rt->u.dst); return ERR_PTR(-ENOMEM); } @@ -2008,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) return ip6_route_add(&cfg); } +static inline size_t rt6_nlmsg_size(void) +{ + return NLMSG_ALIGN(sizeof(struct rtmsg)) + + nla_total_size(16) /* RTA_SRC */ + + nla_total_size(16) /* RTA_DST */ + + nla_total_size(16) /* RTA_GATEWAY */ + + nla_total_size(16) /* RTA_PREFSRC */ + + nla_total_size(4) /* RTA_TABLE */ + + nla_total_size(4) /* RTA_IIF */ + + nla_total_size(4) /* RTA_OIF */ + + nla_total_size(4) /* RTA_PRIORITY */ + + nla_total_size(sizeof(struct rta_cacheinfo)); +} + static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, struct in6_addr *dst, struct in6_addr *src, int iif, int type, u32 pid, u32 seq, @@ -2015,7 +2027,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, { struct rtmsg *rtm; struct nlmsghdr *nlh; - struct rta_cacheinfo ci; + long expires; u32 table; if (prefix) { /* user wants prefix routes only */ @@ -2089,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); - ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); - if (rt->rt6i_expires) - ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); - else - ci.rta_expires = 0; - ci.rta_used = rt->u.dst.__use; - ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); - ci.rta_error = rt->u.dst.error; - ci.rta_id = 0; - ci.rta_ts = 0; - ci.rta_tsage = 0; - NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); + + expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0; + if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, + expires, rt->u.dst.error) < 0) + goto nla_put_failure; return nlmsg_end(skb, nlh); @@ -2202,7 +2207,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) struct sk_buff *skb; u32 pid = 0, seq = 0; struct nlmsghdr *nlh = NULL; - int payload = sizeof(struct rtmsg) + 256; int err = -ENOBUFS; if (info) { @@ -2212,15 +2216,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) seq = nlh->nlmsg_seq; } - skb = nlmsg_new(nlmsg_total_size(payload), gfp_any()); + skb = nlmsg_new(rt6_nlmsg_size(), gfp_any()); if (skb == NULL) goto errout; err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); - if (err < 0) { - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in rt6_nlmsg_size() */ + BUG_ON(err < 0); err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); errout: @@ -2248,7 +2250,6 @@ struct rt6_proc_arg static int rt6_info_route(struct rt6_info *rt, void *p_arg) { struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg; - int i; if (arg->skip < arg->offset / RT6_INFO_LEN) { arg->skip++; @@ -2258,38 +2259,28 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) if (arg->len >= arg->length) return 0; - for (i=0; i<16; i++) { - sprintf(arg->buffer + arg->len, "%02x", - rt->rt6i_dst.addr.s6_addr[i]); - arg->len += 2; - } - arg->len += sprintf(arg->buffer + arg->len, " %02x ", + arg->len += sprintf(arg->buffer + arg->len, + NIP6_SEQFMT " %02x ", + NIP6(rt->rt6i_dst.addr), rt->rt6i_dst.plen); #ifdef CONFIG_IPV6_SUBTREES - for (i=0; i<16; i++) { - sprintf(arg->buffer + arg->len, "%02x", - rt->rt6i_src.addr.s6_addr[i]); - arg->len += 2; - } - arg->len += sprintf(arg->buffer + arg->len, " %02x ", + arg->len += sprintf(arg->buffer + arg->len, + NIP6_SEQFMT " %02x ", + NIP6(rt->rt6i_src.addr), rt->rt6i_src.plen); #else - sprintf(arg->buffer + arg->len, - "00000000000000000000000000000000 00 "); - arg->len += 36; + arg->len += sprintf(arg->buffer + arg->len, + "00000000000000000000000000000000 00 "); #endif if (rt->rt6i_nexthop) { - for (i=0; i<16; i++) { - sprintf(arg->buffer + arg->len, "%02x", - rt->rt6i_nexthop->primary_key[i]); - arg->len += 2; - } + arg->len += sprintf(arg->buffer + arg->len, + NIP6_SEQFMT, + NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key))); } else { - sprintf(arg->buffer + arg->len, - "00000000000000000000000000000000"); - arg->len += 32; + arg->len += sprintf(arg->buffer + arg->len, + "00000000000000000000000000000000"); } arg->len += sprintf(arg->buffer + arg->len, " %08x %08x %08x %08x %8s\n", |