diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-10-09 18:35:22 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-10-09 18:35:22 -0400 |
commit | f474af7051212b4efc8267583fad9c4ebf33ccff (patch) | |
tree | 1aa46ebc8065a341f247c2a2d9af2f624ad1d4f8 /net/ipv6/route.c | |
parent | 0d22f68f02c10d5d10ec5712917e5828b001a822 (diff) | |
parent | e3dd9a52cb5552c46c2a4ca7ccdfb4dab5c72457 (diff) |
nfs: disintegrate UAPI for nfs
This is to complete part of the Userspace API (UAPI) disintegration for which
the preparatory patches were pulled recently. After these patches, userspace
headers will be segregated into:
include/uapi/linux/.../foo.h
for the userspace interface stuff, and:
include/linux/.../foo.h
for the strictly kernel internal stuff.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 126 |
1 files changed, 74 insertions, 52 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8e80fd279100..7c7e963260e1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -222,11 +222,11 @@ static const u32 ip6_template_metrics[RTAX_MAX] = { | |||
222 | [RTAX_HOPLIMIT - 1] = 255, | 222 | [RTAX_HOPLIMIT - 1] = 255, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static struct rt6_info ip6_null_entry_template = { | 225 | static const struct rt6_info ip6_null_entry_template = { |
226 | .dst = { | 226 | .dst = { |
227 | .__refcnt = ATOMIC_INIT(1), | 227 | .__refcnt = ATOMIC_INIT(1), |
228 | .__use = 1, | 228 | .__use = 1, |
229 | .obsolete = -1, | 229 | .obsolete = DST_OBSOLETE_FORCE_CHK, |
230 | .error = -ENETUNREACH, | 230 | .error = -ENETUNREACH, |
231 | .input = ip6_pkt_discard, | 231 | .input = ip6_pkt_discard, |
232 | .output = ip6_pkt_discard_out, | 232 | .output = ip6_pkt_discard_out, |
@@ -242,11 +242,11 @@ static struct rt6_info ip6_null_entry_template = { | |||
242 | static int ip6_pkt_prohibit(struct sk_buff *skb); | 242 | static int ip6_pkt_prohibit(struct sk_buff *skb); |
243 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | 243 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); |
244 | 244 | ||
245 | static struct rt6_info ip6_prohibit_entry_template = { | 245 | static const struct rt6_info ip6_prohibit_entry_template = { |
246 | .dst = { | 246 | .dst = { |
247 | .__refcnt = ATOMIC_INIT(1), | 247 | .__refcnt = ATOMIC_INIT(1), |
248 | .__use = 1, | 248 | .__use = 1, |
249 | .obsolete = -1, | 249 | .obsolete = DST_OBSOLETE_FORCE_CHK, |
250 | .error = -EACCES, | 250 | .error = -EACCES, |
251 | .input = ip6_pkt_prohibit, | 251 | .input = ip6_pkt_prohibit, |
252 | .output = ip6_pkt_prohibit_out, | 252 | .output = ip6_pkt_prohibit_out, |
@@ -257,11 +257,11 @@ static struct rt6_info ip6_prohibit_entry_template = { | |||
257 | .rt6i_ref = ATOMIC_INIT(1), | 257 | .rt6i_ref = ATOMIC_INIT(1), |
258 | }; | 258 | }; |
259 | 259 | ||
260 | static struct rt6_info ip6_blk_hole_entry_template = { | 260 | static const struct rt6_info ip6_blk_hole_entry_template = { |
261 | .dst = { | 261 | .dst = { |
262 | .__refcnt = ATOMIC_INIT(1), | 262 | .__refcnt = ATOMIC_INIT(1), |
263 | .__use = 1, | 263 | .__use = 1, |
264 | .obsolete = -1, | 264 | .obsolete = DST_OBSOLETE_FORCE_CHK, |
265 | .error = -EINVAL, | 265 | .error = -EINVAL, |
266 | .input = dst_discard, | 266 | .input = dst_discard, |
267 | .output = dst_discard, | 267 | .output = dst_discard, |
@@ -281,13 +281,14 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net, | |||
281 | struct fib6_table *table) | 281 | struct fib6_table *table) |
282 | { | 282 | { |
283 | struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, | 283 | struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, |
284 | 0, DST_OBSOLETE_NONE, flags); | 284 | 0, DST_OBSOLETE_FORCE_CHK, flags); |
285 | 285 | ||
286 | if (rt) { | 286 | if (rt) { |
287 | struct dst_entry *dst = &rt->dst; | 287 | struct dst_entry *dst = &rt->dst; |
288 | 288 | ||
289 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); | 289 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); |
290 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); | 290 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); |
291 | rt->rt6i_genid = rt_genid(net); | ||
291 | } | 292 | } |
292 | return rt; | 293 | return rt; |
293 | } | 294 | } |
@@ -369,15 +370,11 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
369 | 370 | ||
370 | static bool rt6_check_expired(const struct rt6_info *rt) | 371 | static bool rt6_check_expired(const struct rt6_info *rt) |
371 | { | 372 | { |
372 | struct rt6_info *ort = NULL; | ||
373 | |||
374 | if (rt->rt6i_flags & RTF_EXPIRES) { | 373 | if (rt->rt6i_flags & RTF_EXPIRES) { |
375 | if (time_after(jiffies, rt->dst.expires)) | 374 | if (time_after(jiffies, rt->dst.expires)) |
376 | return true; | 375 | return true; |
377 | } else if (rt->dst.from) { | 376 | } else if (rt->dst.from) { |
378 | ort = (struct rt6_info *) rt->dst.from; | 377 | return rt6_check_expired((struct rt6_info *) rt->dst.from); |
379 | return (ort->rt6i_flags & RTF_EXPIRES) && | ||
380 | time_after(jiffies, ort->dst.expires); | ||
381 | } | 378 | } |
382 | return false; | 379 | return false; |
383 | } | 380 | } |
@@ -451,10 +448,9 @@ static void rt6_probe(struct rt6_info *rt) | |||
451 | * Router Reachability Probe MUST be rate-limited | 448 | * Router Reachability Probe MUST be rate-limited |
452 | * to no more than one per minute. | 449 | * to no more than one per minute. |
453 | */ | 450 | */ |
454 | rcu_read_lock(); | ||
455 | neigh = rt ? rt->n : NULL; | 451 | neigh = rt ? rt->n : NULL; |
456 | if (!neigh || (neigh->nud_state & NUD_VALID)) | 452 | if (!neigh || (neigh->nud_state & NUD_VALID)) |
457 | goto out; | 453 | return; |
458 | read_lock_bh(&neigh->lock); | 454 | read_lock_bh(&neigh->lock); |
459 | if (!(neigh->nud_state & NUD_VALID) && | 455 | if (!(neigh->nud_state & NUD_VALID) && |
460 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 456 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
@@ -470,8 +466,6 @@ static void rt6_probe(struct rt6_info *rt) | |||
470 | } else { | 466 | } else { |
471 | read_unlock_bh(&neigh->lock); | 467 | read_unlock_bh(&neigh->lock); |
472 | } | 468 | } |
473 | out: | ||
474 | rcu_read_unlock(); | ||
475 | } | 469 | } |
476 | #else | 470 | #else |
477 | static inline void rt6_probe(struct rt6_info *rt) | 471 | static inline void rt6_probe(struct rt6_info *rt) |
@@ -498,7 +492,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt) | |||
498 | struct neighbour *neigh; | 492 | struct neighbour *neigh; |
499 | int m; | 493 | int m; |
500 | 494 | ||
501 | rcu_read_lock(); | ||
502 | neigh = rt->n; | 495 | neigh = rt->n; |
503 | if (rt->rt6i_flags & RTF_NONEXTHOP || | 496 | if (rt->rt6i_flags & RTF_NONEXTHOP || |
504 | !(rt->rt6i_flags & RTF_GATEWAY)) | 497 | !(rt->rt6i_flags & RTF_GATEWAY)) |
@@ -516,7 +509,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt) | |||
516 | read_unlock_bh(&neigh->lock); | 509 | read_unlock_bh(&neigh->lock); |
517 | } else | 510 | } else |
518 | m = 0; | 511 | m = 0; |
519 | rcu_read_unlock(); | ||
520 | return m; | 512 | return m; |
521 | } | 513 | } |
522 | 514 | ||
@@ -965,7 +957,7 @@ struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, | |||
965 | { | 957 | { |
966 | int flags = 0; | 958 | int flags = 0; |
967 | 959 | ||
968 | fl6->flowi6_iif = net->loopback_dev->ifindex; | 960 | fl6->flowi6_iif = LOOPBACK_IFINDEX; |
969 | 961 | ||
970 | if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) | 962 | if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) |
971 | flags |= RT6_LOOKUP_F_IFACE; | 963 | flags |= RT6_LOOKUP_F_IFACE; |
@@ -1031,6 +1023,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
1031 | 1023 | ||
1032 | rt = (struct rt6_info *) dst; | 1024 | rt = (struct rt6_info *) dst; |
1033 | 1025 | ||
1026 | /* All IPV6 dsts are created with ->obsolete set to the value | ||
1027 | * DST_OBSOLETE_FORCE_CHK which forces validation calls down | ||
1028 | * into this function always. | ||
1029 | */ | ||
1030 | if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) | ||
1031 | return NULL; | ||
1032 | |||
1034 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { | 1033 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { |
1035 | if (rt->rt6i_peer_genid != rt6_peer_genid()) { | 1034 | if (rt->rt6i_peer_genid != rt6_peer_genid()) { |
1036 | if (!rt6_has_peer(rt)) | 1035 | if (!rt6_has_peer(rt)) |
@@ -1397,8 +1396,6 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1397 | goto out; | 1396 | goto out; |
1398 | } | 1397 | } |
1399 | 1398 | ||
1400 | rt->dst.obsolete = -1; | ||
1401 | |||
1402 | if (cfg->fc_flags & RTF_EXPIRES) | 1399 | if (cfg->fc_flags & RTF_EXPIRES) |
1403 | rt6_set_expires(rt, jiffies + | 1400 | rt6_set_expires(rt, jiffies + |
1404 | clock_t_to_jiffies(cfg->fc_expires)); | 1401 | clock_t_to_jiffies(cfg->fc_expires)); |
@@ -1463,8 +1460,21 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1463 | } | 1460 | } |
1464 | rt->dst.output = ip6_pkt_discard_out; | 1461 | rt->dst.output = ip6_pkt_discard_out; |
1465 | rt->dst.input = ip6_pkt_discard; | 1462 | rt->dst.input = ip6_pkt_discard; |
1466 | rt->dst.error = -ENETUNREACH; | ||
1467 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; | 1463 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; |
1464 | switch (cfg->fc_type) { | ||
1465 | case RTN_BLACKHOLE: | ||
1466 | rt->dst.error = -EINVAL; | ||
1467 | break; | ||
1468 | case RTN_PROHIBIT: | ||
1469 | rt->dst.error = -EACCES; | ||
1470 | break; | ||
1471 | case RTN_THROW: | ||
1472 | rt->dst.error = -EAGAIN; | ||
1473 | break; | ||
1474 | default: | ||
1475 | rt->dst.error = -ENETUNREACH; | ||
1476 | break; | ||
1477 | } | ||
1468 | goto install_route; | 1478 | goto install_route; |
1469 | } | 1479 | } |
1470 | 1480 | ||
@@ -1583,17 +1593,18 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) | |||
1583 | struct fib6_table *table; | 1593 | struct fib6_table *table; |
1584 | struct net *net = dev_net(rt->dst.dev); | 1594 | struct net *net = dev_net(rt->dst.dev); |
1585 | 1595 | ||
1586 | if (rt == net->ipv6.ip6_null_entry) | 1596 | if (rt == net->ipv6.ip6_null_entry) { |
1587 | return -ENOENT; | 1597 | err = -ENOENT; |
1598 | goto out; | ||
1599 | } | ||
1588 | 1600 | ||
1589 | table = rt->rt6i_table; | 1601 | table = rt->rt6i_table; |
1590 | write_lock_bh(&table->tb6_lock); | 1602 | write_lock_bh(&table->tb6_lock); |
1591 | |||
1592 | err = fib6_del(rt, info); | 1603 | err = fib6_del(rt, info); |
1593 | dst_release(&rt->dst); | ||
1594 | |||
1595 | write_unlock_bh(&table->tb6_lock); | 1604 | write_unlock_bh(&table->tb6_lock); |
1596 | 1605 | ||
1606 | out: | ||
1607 | dst_release(&rt->dst); | ||
1597 | return err; | 1608 | return err; |
1598 | } | 1609 | } |
1599 | 1610 | ||
@@ -1829,7 +1840,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net, | |||
1829 | if (!table) | 1840 | if (!table) |
1830 | return NULL; | 1841 | return NULL; |
1831 | 1842 | ||
1832 | write_lock_bh(&table->tb6_lock); | 1843 | read_lock_bh(&table->tb6_lock); |
1833 | fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0); | 1844 | fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0); |
1834 | if (!fn) | 1845 | if (!fn) |
1835 | goto out; | 1846 | goto out; |
@@ -1845,7 +1856,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net, | |||
1845 | break; | 1856 | break; |
1846 | } | 1857 | } |
1847 | out: | 1858 | out: |
1848 | write_unlock_bh(&table->tb6_lock); | 1859 | read_unlock_bh(&table->tb6_lock); |
1849 | return rt; | 1860 | return rt; |
1850 | } | 1861 | } |
1851 | 1862 | ||
@@ -1861,7 +1872,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net, | |||
1861 | .fc_dst_len = prefixlen, | 1872 | .fc_dst_len = prefixlen, |
1862 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | | 1873 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | |
1863 | RTF_UP | RTF_PREF(pref), | 1874 | RTF_UP | RTF_PREF(pref), |
1864 | .fc_nlinfo.pid = 0, | 1875 | .fc_nlinfo.portid = 0, |
1865 | .fc_nlinfo.nlh = NULL, | 1876 | .fc_nlinfo.nlh = NULL, |
1866 | .fc_nlinfo.nl_net = net, | 1877 | .fc_nlinfo.nl_net = net, |
1867 | }; | 1878 | }; |
@@ -1888,7 +1899,7 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev | |||
1888 | if (!table) | 1899 | if (!table) |
1889 | return NULL; | 1900 | return NULL; |
1890 | 1901 | ||
1891 | write_lock_bh(&table->tb6_lock); | 1902 | read_lock_bh(&table->tb6_lock); |
1892 | for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) { | 1903 | for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) { |
1893 | if (dev == rt->dst.dev && | 1904 | if (dev == rt->dst.dev && |
1894 | ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && | 1905 | ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && |
@@ -1897,7 +1908,7 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev | |||
1897 | } | 1908 | } |
1898 | if (rt) | 1909 | if (rt) |
1899 | dst_hold(&rt->dst); | 1910 | dst_hold(&rt->dst); |
1900 | write_unlock_bh(&table->tb6_lock); | 1911 | read_unlock_bh(&table->tb6_lock); |
1901 | return rt; | 1912 | return rt; |
1902 | } | 1913 | } |
1903 | 1914 | ||
@@ -1911,7 +1922,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, | |||
1911 | .fc_ifindex = dev->ifindex, | 1922 | .fc_ifindex = dev->ifindex, |
1912 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | | 1923 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | |
1913 | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), | 1924 | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), |
1914 | .fc_nlinfo.pid = 0, | 1925 | .fc_nlinfo.portid = 0, |
1915 | .fc_nlinfo.nlh = NULL, | 1926 | .fc_nlinfo.nlh = NULL, |
1916 | .fc_nlinfo.nl_net = dev_net(dev), | 1927 | .fc_nlinfo.nl_net = dev_net(dev), |
1917 | }; | 1928 | }; |
@@ -2080,7 +2091,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2080 | rt->dst.input = ip6_input; | 2091 | rt->dst.input = ip6_input; |
2081 | rt->dst.output = ip6_output; | 2092 | rt->dst.output = ip6_output; |
2082 | rt->rt6i_idev = idev; | 2093 | rt->rt6i_idev = idev; |
2083 | rt->dst.obsolete = -1; | ||
2084 | 2094 | ||
2085 | rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; | 2095 | rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; |
2086 | if (anycast) | 2096 | if (anycast) |
@@ -2261,14 +2271,18 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2261 | cfg->fc_src_len = rtm->rtm_src_len; | 2271 | cfg->fc_src_len = rtm->rtm_src_len; |
2262 | cfg->fc_flags = RTF_UP; | 2272 | cfg->fc_flags = RTF_UP; |
2263 | cfg->fc_protocol = rtm->rtm_protocol; | 2273 | cfg->fc_protocol = rtm->rtm_protocol; |
2274 | cfg->fc_type = rtm->rtm_type; | ||
2264 | 2275 | ||
2265 | if (rtm->rtm_type == RTN_UNREACHABLE) | 2276 | if (rtm->rtm_type == RTN_UNREACHABLE || |
2277 | rtm->rtm_type == RTN_BLACKHOLE || | ||
2278 | rtm->rtm_type == RTN_PROHIBIT || | ||
2279 | rtm->rtm_type == RTN_THROW) | ||
2266 | cfg->fc_flags |= RTF_REJECT; | 2280 | cfg->fc_flags |= RTF_REJECT; |
2267 | 2281 | ||
2268 | if (rtm->rtm_type == RTN_LOCAL) | 2282 | if (rtm->rtm_type == RTN_LOCAL) |
2269 | cfg->fc_flags |= RTF_LOCAL; | 2283 | cfg->fc_flags |= RTF_LOCAL; |
2270 | 2284 | ||
2271 | cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; | 2285 | cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid; |
2272 | cfg->fc_nlinfo.nlh = nlh; | 2286 | cfg->fc_nlinfo.nlh = nlh; |
2273 | cfg->fc_nlinfo.nl_net = sock_net(skb->sk); | 2287 | cfg->fc_nlinfo.nl_net = sock_net(skb->sk); |
2274 | 2288 | ||
@@ -2359,7 +2373,7 @@ static inline size_t rt6_nlmsg_size(void) | |||
2359 | static int rt6_fill_node(struct net *net, | 2373 | static int rt6_fill_node(struct net *net, |
2360 | struct sk_buff *skb, struct rt6_info *rt, | 2374 | struct sk_buff *skb, struct rt6_info *rt, |
2361 | struct in6_addr *dst, struct in6_addr *src, | 2375 | struct in6_addr *dst, struct in6_addr *src, |
2362 | int iif, int type, u32 pid, u32 seq, | 2376 | int iif, int type, u32 portid, u32 seq, |
2363 | int prefix, int nowait, unsigned int flags) | 2377 | int prefix, int nowait, unsigned int flags) |
2364 | { | 2378 | { |
2365 | struct rtmsg *rtm; | 2379 | struct rtmsg *rtm; |
@@ -2375,7 +2389,7 @@ static int rt6_fill_node(struct net *net, | |||
2375 | } | 2389 | } |
2376 | } | 2390 | } |
2377 | 2391 | ||
2378 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); | 2392 | nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags); |
2379 | if (!nlh) | 2393 | if (!nlh) |
2380 | return -EMSGSIZE; | 2394 | return -EMSGSIZE; |
2381 | 2395 | ||
@@ -2391,8 +2405,22 @@ static int rt6_fill_node(struct net *net, | |||
2391 | rtm->rtm_table = table; | 2405 | rtm->rtm_table = table; |
2392 | if (nla_put_u32(skb, RTA_TABLE, table)) | 2406 | if (nla_put_u32(skb, RTA_TABLE, table)) |
2393 | goto nla_put_failure; | 2407 | goto nla_put_failure; |
2394 | if (rt->rt6i_flags & RTF_REJECT) | 2408 | if (rt->rt6i_flags & RTF_REJECT) { |
2395 | rtm->rtm_type = RTN_UNREACHABLE; | 2409 | switch (rt->dst.error) { |
2410 | case -EINVAL: | ||
2411 | rtm->rtm_type = RTN_BLACKHOLE; | ||
2412 | break; | ||
2413 | case -EACCES: | ||
2414 | rtm->rtm_type = RTN_PROHIBIT; | ||
2415 | break; | ||
2416 | case -EAGAIN: | ||
2417 | rtm->rtm_type = RTN_THROW; | ||
2418 | break; | ||
2419 | default: | ||
2420 | rtm->rtm_type = RTN_UNREACHABLE; | ||
2421 | break; | ||
2422 | } | ||
2423 | } | ||
2396 | else if (rt->rt6i_flags & RTF_LOCAL) | 2424 | else if (rt->rt6i_flags & RTF_LOCAL) |
2397 | rtm->rtm_type = RTN_LOCAL; | 2425 | rtm->rtm_type = RTN_LOCAL; |
2398 | else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) | 2426 | else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) |
@@ -2465,15 +2493,11 @@ static int rt6_fill_node(struct net *net, | |||
2465 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) | 2493 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) |
2466 | goto nla_put_failure; | 2494 | goto nla_put_failure; |
2467 | 2495 | ||
2468 | rcu_read_lock(); | ||
2469 | n = rt->n; | 2496 | n = rt->n; |
2470 | if (n) { | 2497 | if (n) { |
2471 | if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) { | 2498 | if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) |
2472 | rcu_read_unlock(); | ||
2473 | goto nla_put_failure; | 2499 | goto nla_put_failure; |
2474 | } | ||
2475 | } | 2500 | } |
2476 | rcu_read_unlock(); | ||
2477 | 2501 | ||
2478 | if (rt->dst.dev && | 2502 | if (rt->dst.dev && |
2479 | nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) | 2503 | nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) |
@@ -2506,7 +2530,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
2506 | 2530 | ||
2507 | return rt6_fill_node(arg->net, | 2531 | return rt6_fill_node(arg->net, |
2508 | arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | 2532 | arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, |
2509 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, | 2533 | NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq, |
2510 | prefix, 0, NLM_F_MULTI); | 2534 | prefix, 0, NLM_F_MULTI); |
2511 | } | 2535 | } |
2512 | 2536 | ||
@@ -2586,14 +2610,14 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2586 | skb_dst_set(skb, &rt->dst); | 2610 | skb_dst_set(skb, &rt->dst); |
2587 | 2611 | ||
2588 | err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, | 2612 | err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, |
2589 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, | 2613 | RTM_NEWROUTE, NETLINK_CB(in_skb).portid, |
2590 | nlh->nlmsg_seq, 0, 0, 0); | 2614 | nlh->nlmsg_seq, 0, 0, 0); |
2591 | if (err < 0) { | 2615 | if (err < 0) { |
2592 | kfree_skb(skb); | 2616 | kfree_skb(skb); |
2593 | goto errout; | 2617 | goto errout; |
2594 | } | 2618 | } |
2595 | 2619 | ||
2596 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); | 2620 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); |
2597 | errout: | 2621 | errout: |
2598 | return err; | 2622 | return err; |
2599 | } | 2623 | } |
@@ -2613,14 +2637,14 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2613 | goto errout; | 2637 | goto errout; |
2614 | 2638 | ||
2615 | err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, | 2639 | err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, |
2616 | event, info->pid, seq, 0, 0, 0); | 2640 | event, info->portid, seq, 0, 0, 0); |
2617 | if (err < 0) { | 2641 | if (err < 0) { |
2618 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ | 2642 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ |
2619 | WARN_ON(err == -EMSGSIZE); | 2643 | WARN_ON(err == -EMSGSIZE); |
2620 | kfree_skb(skb); | 2644 | kfree_skb(skb); |
2621 | goto errout; | 2645 | goto errout; |
2622 | } | 2646 | } |
2623 | rtnl_notify(skb, net, info->pid, RTNLGRP_IPV6_ROUTE, | 2647 | rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE, |
2624 | info->nlh, gfp_any()); | 2648 | info->nlh, gfp_any()); |
2625 | return; | 2649 | return; |
2626 | errout: | 2650 | errout: |
@@ -2675,14 +2699,12 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
2675 | #else | 2699 | #else |
2676 | seq_puts(m, "00000000000000000000000000000000 00 "); | 2700 | seq_puts(m, "00000000000000000000000000000000 00 "); |
2677 | #endif | 2701 | #endif |
2678 | rcu_read_lock(); | ||
2679 | n = rt->n; | 2702 | n = rt->n; |
2680 | if (n) { | 2703 | if (n) { |
2681 | seq_printf(m, "%pi6", n->primary_key); | 2704 | seq_printf(m, "%pi6", n->primary_key); |
2682 | } else { | 2705 | } else { |
2683 | seq_puts(m, "00000000000000000000000000000000"); | 2706 | seq_puts(m, "00000000000000000000000000000000"); |
2684 | } | 2707 | } |
2685 | rcu_read_unlock(); | ||
2686 | seq_printf(m, " %08x %08x %08x %08x %8s\n", | 2708 | seq_printf(m, " %08x %08x %08x %08x %8s\n", |
2687 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), | 2709 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), |
2688 | rt->dst.__use, rt->rt6i_flags, | 2710 | rt->dst.__use, rt->rt6i_flags, |