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 b39ae99122d5..9f80518aacbd 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, | |||
440 | if (pref == ICMPV6_ROUTER_PREF_INVALID) | 440 | if (pref == ICMPV6_ROUTER_PREF_INVALID) |
441 | pref = ICMPV6_ROUTER_PREF_MEDIUM; | 441 | pref = ICMPV6_ROUTER_PREF_MEDIUM; |
442 | 442 | ||
443 | lifetime = htonl(rinfo->lifetime); | 443 | lifetime = ntohl(rinfo->lifetime); |
444 | if (lifetime == 0xffffffff) { | 444 | if (lifetime == 0xffffffff) { |
445 | /* infinity */ | 445 | /* infinity */ |
446 | } else if (lifetime > 0x7fffffff/HZ) { | 446 | } else if (lifetime > 0x7fffffff/HZ) { |
@@ -711,12 +711,10 @@ void ip6_route_input(struct sk_buff *skb) | |||
711 | .ip6_u = { | 711 | .ip6_u = { |
712 | .daddr = iph->daddr, | 712 | .daddr = iph->daddr, |
713 | .saddr = iph->saddr, | 713 | .saddr = iph->saddr, |
714 | #ifdef CONFIG_IPV6_ROUTE_FWMARK | 714 | .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, |
715 | .fwmark = skb->nfmark, | ||
716 | #endif | ||
717 | .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK, | ||
718 | }, | 715 | }, |
719 | }, | 716 | }, |
717 | .mark = skb->mark, | ||
720 | .proto = iph->nexthdr, | 718 | .proto = iph->nexthdr, |
721 | }; | 719 | }; |
722 | 720 | ||
@@ -942,7 +940,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev, | |||
942 | fib6_force_start_gc(); | 940 | fib6_force_start_gc(); |
943 | 941 | ||
944 | out: | 942 | out: |
945 | return (struct dst_entry *)rt; | 943 | return &rt->u.dst; |
946 | } | 944 | } |
947 | 945 | ||
948 | int ndisc_dst_gc(int *more) | 946 | int ndisc_dst_gc(int *more) |
@@ -1225,7 +1223,7 @@ out: | |||
1225 | if (idev) | 1223 | if (idev) |
1226 | in6_dev_put(idev); | 1224 | in6_dev_put(idev); |
1227 | if (rt) | 1225 | if (rt) |
1228 | dst_free((struct dst_entry *) rt); | 1226 | dst_free(&rt->u.dst); |
1229 | return err; | 1227 | return err; |
1230 | } | 1228 | } |
1231 | 1229 | ||
@@ -1751,9 +1749,9 @@ static inline int ip6_pkt_drop(struct sk_buff *skb, int code) | |||
1751 | { | 1749 | { |
1752 | int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); | 1750 | int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); |
1753 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) | 1751 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) |
1754 | IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); | 1752 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); |
1755 | 1753 | ||
1756 | IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); | 1754 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES); |
1757 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); | 1755 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); |
1758 | kfree_skb(skb); | 1756 | kfree_skb(skb); |
1759 | return 0; | 1757 | return 0; |
@@ -1824,7 +1822,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1824 | rt->rt6i_flags |= RTF_LOCAL; | 1822 | rt->rt6i_flags |= RTF_LOCAL; |
1825 | rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); | 1823 | rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); |
1826 | if (rt->rt6i_nexthop == NULL) { | 1824 | if (rt->rt6i_nexthop == NULL) { |
1827 | dst_free((struct dst_entry *) rt); | 1825 | dst_free(&rt->u.dst); |
1828 | return ERR_PTR(-ENOMEM); | 1826 | return ERR_PTR(-ENOMEM); |
1829 | } | 1827 | } |
1830 | 1828 | ||
@@ -2008,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
2008 | return ip6_route_add(&cfg); | 2006 | return ip6_route_add(&cfg); |
2009 | } | 2007 | } |
2010 | 2008 | ||
2009 | static inline size_t rt6_nlmsg_size(void) | ||
2010 | { | ||
2011 | return NLMSG_ALIGN(sizeof(struct rtmsg)) | ||
2012 | + nla_total_size(16) /* RTA_SRC */ | ||
2013 | + nla_total_size(16) /* RTA_DST */ | ||
2014 | + nla_total_size(16) /* RTA_GATEWAY */ | ||
2015 | + nla_total_size(16) /* RTA_PREFSRC */ | ||
2016 | + nla_total_size(4) /* RTA_TABLE */ | ||
2017 | + nla_total_size(4) /* RTA_IIF */ | ||
2018 | + nla_total_size(4) /* RTA_OIF */ | ||
2019 | + nla_total_size(4) /* RTA_PRIORITY */ | ||
2020 | + nla_total_size(sizeof(struct rta_cacheinfo)); | ||
2021 | } | ||
2022 | |||
2011 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 2023 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, |
2012 | struct in6_addr *dst, struct in6_addr *src, | 2024 | struct in6_addr *dst, struct in6_addr *src, |
2013 | int iif, int type, u32 pid, u32 seq, | 2025 | 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, | |||
2015 | { | 2027 | { |
2016 | struct rtmsg *rtm; | 2028 | struct rtmsg *rtm; |
2017 | struct nlmsghdr *nlh; | 2029 | struct nlmsghdr *nlh; |
2018 | struct rta_cacheinfo ci; | 2030 | long expires; |
2019 | u32 table; | 2031 | u32 table; |
2020 | 2032 | ||
2021 | if (prefix) { /* user wants prefix routes only */ | 2033 | if (prefix) { /* user wants prefix routes only */ |
@@ -2089,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
2089 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); | 2101 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); |
2090 | 2102 | ||
2091 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); | 2103 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); |
2092 | ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); | 2104 | |
2093 | if (rt->rt6i_expires) | 2105 | expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0; |
2094 | ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); | 2106 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, |
2095 | else | 2107 | expires, rt->u.dst.error) < 0) |
2096 | ci.rta_expires = 0; | 2108 | goto nla_put_failure; |
2097 | ci.rta_used = rt->u.dst.__use; | ||
2098 | ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); | ||
2099 | ci.rta_error = rt->u.dst.error; | ||
2100 | ci.rta_id = 0; | ||
2101 | ci.rta_ts = 0; | ||
2102 | ci.rta_tsage = 0; | ||
2103 | NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); | ||
2104 | 2109 | ||
2105 | return nlmsg_end(skb, nlh); | 2110 | return nlmsg_end(skb, nlh); |
2106 | 2111 | ||
@@ -2202,7 +2207,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2202 | struct sk_buff *skb; | 2207 | struct sk_buff *skb; |
2203 | u32 pid = 0, seq = 0; | 2208 | u32 pid = 0, seq = 0; |
2204 | struct nlmsghdr *nlh = NULL; | 2209 | struct nlmsghdr *nlh = NULL; |
2205 | int payload = sizeof(struct rtmsg) + 256; | ||
2206 | int err = -ENOBUFS; | 2210 | int err = -ENOBUFS; |
2207 | 2211 | ||
2208 | if (info) { | 2212 | if (info) { |
@@ -2212,15 +2216,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2212 | seq = nlh->nlmsg_seq; | 2216 | seq = nlh->nlmsg_seq; |
2213 | } | 2217 | } |
2214 | 2218 | ||
2215 | skb = nlmsg_new(nlmsg_total_size(payload), gfp_any()); | 2219 | skb = nlmsg_new(rt6_nlmsg_size(), gfp_any()); |
2216 | if (skb == NULL) | 2220 | if (skb == NULL) |
2217 | goto errout; | 2221 | goto errout; |
2218 | 2222 | ||
2219 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); | 2223 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); |
2220 | if (err < 0) { | 2224 | /* failure implies BUG in rt6_nlmsg_size() */ |
2221 | kfree_skb(skb); | 2225 | BUG_ON(err < 0); |
2222 | goto errout; | ||
2223 | } | ||
2224 | 2226 | ||
2225 | err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); | 2227 | err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); |
2226 | errout: | 2228 | errout: |
@@ -2248,7 +2250,6 @@ struct rt6_proc_arg | |||
2248 | static int rt6_info_route(struct rt6_info *rt, void *p_arg) | 2250 | static int rt6_info_route(struct rt6_info *rt, void *p_arg) |
2249 | { | 2251 | { |
2250 | struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg; | 2252 | struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg; |
2251 | int i; | ||
2252 | 2253 | ||
2253 | if (arg->skip < arg->offset / RT6_INFO_LEN) { | 2254 | if (arg->skip < arg->offset / RT6_INFO_LEN) { |
2254 | arg->skip++; | 2255 | arg->skip++; |
@@ -2258,38 +2259,28 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
2258 | if (arg->len >= arg->length) | 2259 | if (arg->len >= arg->length) |
2259 | return 0; | 2260 | return 0; |
2260 | 2261 | ||
2261 | for (i=0; i<16; i++) { | 2262 | arg->len += sprintf(arg->buffer + arg->len, |
2262 | sprintf(arg->buffer + arg->len, "%02x", | 2263 | NIP6_SEQFMT " %02x ", |
2263 | rt->rt6i_dst.addr.s6_addr[i]); | 2264 | NIP6(rt->rt6i_dst.addr), |
2264 | arg->len += 2; | ||
2265 | } | ||
2266 | arg->len += sprintf(arg->buffer + arg->len, " %02x ", | ||
2267 | rt->rt6i_dst.plen); | 2265 | rt->rt6i_dst.plen); |
2268 | 2266 | ||
2269 | #ifdef CONFIG_IPV6_SUBTREES | 2267 | #ifdef CONFIG_IPV6_SUBTREES |
2270 | for (i=0; i<16; i++) { | 2268 | arg->len += sprintf(arg->buffer + arg->len, |
2271 | sprintf(arg->buffer + arg->len, "%02x", | 2269 | NIP6_SEQFMT " %02x ", |
2272 | rt->rt6i_src.addr.s6_addr[i]); | 2270 | NIP6(rt->rt6i_src.addr), |
2273 | arg->len += 2; | ||
2274 | } | ||
2275 | arg->len += sprintf(arg->buffer + arg->len, " %02x ", | ||
2276 | rt->rt6i_src.plen); | 2271 | rt->rt6i_src.plen); |
2277 | #else | 2272 | #else |
2278 | sprintf(arg->buffer + arg->len, | 2273 | arg->len += sprintf(arg->buffer + arg->len, |
2279 | "00000000000000000000000000000000 00 "); | 2274 | "00000000000000000000000000000000 00 "); |
2280 | arg->len += 36; | ||
2281 | #endif | 2275 | #endif |
2282 | 2276 | ||
2283 | if (rt->rt6i_nexthop) { | 2277 | if (rt->rt6i_nexthop) { |
2284 | for (i=0; i<16; i++) { | 2278 | arg->len += sprintf(arg->buffer + arg->len, |
2285 | sprintf(arg->buffer + arg->len, "%02x", | 2279 | NIP6_SEQFMT, |
2286 | rt->rt6i_nexthop->primary_key[i]); | 2280 | NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key))); |
2287 | arg->len += 2; | ||
2288 | } | ||
2289 | } else { | 2281 | } else { |
2290 | sprintf(arg->buffer + arg->len, | 2282 | arg->len += sprintf(arg->buffer + arg->len, |
2291 | "00000000000000000000000000000000"); | 2283 | "00000000000000000000000000000000"); |
2292 | arg->len += 32; | ||
2293 | } | 2284 | } |
2294 | arg->len += sprintf(arg->buffer + arg->len, | 2285 | arg->len += sprintf(arg->buffer + arg->len, |
2295 | " %08x %08x %08x %08x %8s\n", | 2286 | " %08x %08x %08x %08x %8s\n", |