diff options
-rw-r--r-- | include/linux/fib_rules.h | 4 | ||||
-rw-r--r-- | include/linux/rtnetlink.h | 8 | ||||
-rw-r--r-- | include/net/fib_rules.h | 7 | ||||
-rw-r--r-- | net/core/fib_rules.c | 5 | ||||
-rw-r--r-- | net/decnet/dn_fib.c | 7 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 1 | ||||
-rw-r--r-- | net/decnet/dn_table.c | 1 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 7 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 1 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 1 | ||||
-rw-r--r-- | net/ipv4/route.c | 1 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 1 | ||||
-rw-r--r-- | net/ipv6/route.c | 13 |
13 files changed, 45 insertions, 12 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index 5e503f0ca6e4..19a82b6c1c1f 100644 --- a/include/linux/fib_rules.h +++ b/include/linux/fib_rules.h | |||
@@ -36,6 +36,10 @@ enum | |||
36 | FRA_UNUSED5, | 36 | FRA_UNUSED5, |
37 | FRA_FWMARK, /* netfilter mark (IPv4) */ | 37 | FRA_FWMARK, /* netfilter mark (IPv4) */ |
38 | FRA_FLOW, /* flow/class id */ | 38 | FRA_FLOW, /* flow/class id */ |
39 | FRA_UNUSED6, | ||
40 | FRA_UNUSED7, | ||
41 | FRA_UNUSED8, | ||
42 | FRA_TABLE, /* Extended table id */ | ||
39 | __FRA_MAX | 43 | __FRA_MAX |
40 | }; | 44 | }; |
41 | 45 | ||
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 0aaffa2ae666..ea422a539a03 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -264,6 +264,7 @@ enum rtattr_type_t | |||
264 | RTA_CACHEINFO, | 264 | RTA_CACHEINFO, |
265 | RTA_SESSION, | 265 | RTA_SESSION, |
266 | RTA_MP_ALGO, | 266 | RTA_MP_ALGO, |
267 | RTA_TABLE, | ||
267 | __RTA_MAX | 268 | __RTA_MAX |
268 | }; | 269 | }; |
269 | 270 | ||
@@ -717,6 +718,13 @@ extern void __rtnl_unlock(void); | |||
717 | } \ | 718 | } \ |
718 | } while(0) | 719 | } while(0) |
719 | 720 | ||
721 | static inline u32 rtm_get_table(struct rtattr **rta, u8 table) | ||
722 | { | ||
723 | return RTA_GET_U32(rta[RTA_TABLE-1]); | ||
724 | rtattr_failure: | ||
725 | return table; | ||
726 | } | ||
727 | |||
720 | #endif /* __KERNEL__ */ | 728 | #endif /* __KERNEL__ */ |
721 | 729 | ||
722 | 730 | ||
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 61375d9e53f8..8e2f473d3e82 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h | |||
@@ -74,6 +74,13 @@ static inline void fib_rule_put(struct fib_rule *rule) | |||
74 | call_rcu(&rule->rcu, fib_rule_put_rcu); | 74 | call_rcu(&rule->rcu, fib_rule_put_rcu); |
75 | } | 75 | } |
76 | 76 | ||
77 | static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) | ||
78 | { | ||
79 | if (nla[FRA_TABLE]) | ||
80 | return nla_get_u32(nla[FRA_TABLE]); | ||
81 | return frh->table; | ||
82 | } | ||
83 | |||
77 | extern int fib_rules_register(struct fib_rules_ops *); | 84 | extern int fib_rules_register(struct fib_rules_ops *); |
78 | extern int fib_rules_unregister(struct fib_rules_ops *); | 85 | extern int fib_rules_unregister(struct fib_rules_ops *); |
79 | 86 | ||
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 6cdad24038e2..873b04d5df81 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -187,7 +187,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
187 | 187 | ||
188 | rule->action = frh->action; | 188 | rule->action = frh->action; |
189 | rule->flags = frh->flags; | 189 | rule->flags = frh->flags; |
190 | rule->table = frh->table; | 190 | rule->table = frh_get_table(frh, tb); |
191 | 191 | ||
192 | if (!rule->pref && ops->default_pref) | 192 | if (!rule->pref && ops->default_pref) |
193 | rule->pref = ops->default_pref(); | 193 | rule->pref = ops->default_pref(); |
@@ -245,7 +245,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
245 | if (frh->action && (frh->action != rule->action)) | 245 | if (frh->action && (frh->action != rule->action)) |
246 | continue; | 246 | continue; |
247 | 247 | ||
248 | if (frh->table && (frh->table != rule->table)) | 248 | if (frh->table && (frh_get_table(frh, tb) != rule->table)) |
249 | continue; | 249 | continue; |
250 | 250 | ||
251 | if (tb[FRA_PRIORITY] && | 251 | if (tb[FRA_PRIORITY] && |
@@ -291,6 +291,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, | |||
291 | 291 | ||
292 | frh = nlmsg_data(nlh); | 292 | frh = nlmsg_data(nlh); |
293 | frh->table = rule->table; | 293 | frh->table = rule->table; |
294 | NLA_PUT_U32(skb, FRA_TABLE, rule->table); | ||
294 | frh->res1 = 0; | 295 | frh->res1 = 0; |
295 | frh->res2 = 0; | 296 | frh->res2 = 0; |
296 | frh->action = rule->action; | 297 | frh->action = rule->action; |
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 7b3bf5c3d720..fb596373daa8 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -491,7 +491,8 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta) | |||
491 | if (attr) { | 491 | if (attr) { |
492 | if (RTA_PAYLOAD(attr) < 4 && RTA_PAYLOAD(attr) != 2) | 492 | if (RTA_PAYLOAD(attr) < 4 && RTA_PAYLOAD(attr) != 2) |
493 | return -EINVAL; | 493 | return -EINVAL; |
494 | if (i != RTA_MULTIPATH && i != RTA_METRICS) | 494 | if (i != RTA_MULTIPATH && i != RTA_METRICS && |
495 | i != RTA_TABLE) | ||
495 | rta[i-1] = (struct rtattr *)RTA_DATA(attr); | 496 | rta[i-1] = (struct rtattr *)RTA_DATA(attr); |
496 | } | 497 | } |
497 | } | 498 | } |
@@ -508,7 +509,7 @@ int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
508 | if (dn_fib_check_attr(r, rta)) | 509 | if (dn_fib_check_attr(r, rta)) |
509 | return -EINVAL; | 510 | return -EINVAL; |
510 | 511 | ||
511 | tb = dn_fib_get_table(r->rtm_table, 0); | 512 | tb = dn_fib_get_table(rtm_get_table(rta, r->rtm_table), 0); |
512 | if (tb) | 513 | if (tb) |
513 | return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb)); | 514 | return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb)); |
514 | 515 | ||
@@ -524,7 +525,7 @@ int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
524 | if (dn_fib_check_attr(r, rta)) | 525 | if (dn_fib_check_attr(r, rta)) |
525 | return -EINVAL; | 526 | return -EINVAL; |
526 | 527 | ||
527 | tb = dn_fib_get_table(r->rtm_table, 1); | 528 | tb = dn_fib_get_table(rtm_get_table(rta, r->rtm_table), 1); |
528 | if (tb) | 529 | if (tb) |
529 | return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb)); | 530 | return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb)); |
530 | 531 | ||
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 5e6f4616ca10..4c963213fba5 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -1486,6 +1486,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | |||
1486 | r->rtm_src_len = 0; | 1486 | r->rtm_src_len = 0; |
1487 | r->rtm_tos = 0; | 1487 | r->rtm_tos = 0; |
1488 | r->rtm_table = RT_TABLE_MAIN; | 1488 | r->rtm_table = RT_TABLE_MAIN; |
1489 | RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); | ||
1489 | r->rtm_type = rt->rt_type; | 1490 | r->rtm_type = rt->rt_type; |
1490 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; | 1491 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; |
1491 | r->rtm_scope = RT_SCOPE_UNIVERSE; | 1492 | r->rtm_scope = RT_SCOPE_UNIVERSE; |
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 1601ee5406a8..eca7c1e10c80 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -278,6 +278,7 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
278 | rtm->rtm_src_len = 0; | 278 | rtm->rtm_src_len = 0; |
279 | rtm->rtm_tos = 0; | 279 | rtm->rtm_tos = 0; |
280 | rtm->rtm_table = tb_id; | 280 | rtm->rtm_table = tb_id; |
281 | RTA_PUT_U32(skb, RTA_TABLE, tb_id); | ||
281 | rtm->rtm_flags = fi->fib_flags; | 282 | rtm->rtm_flags = fi->fib_flags; |
282 | rtm->rtm_scope = scope; | 283 | rtm->rtm_scope = scope; |
283 | rtm->rtm_type = type; | 284 | rtm->rtm_type = type; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 06f4b23f6f57..2696ede52de2 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -294,7 +294,8 @@ static int inet_check_attr(struct rtmsg *r, struct rtattr **rta) | |||
294 | if (attr) { | 294 | if (attr) { |
295 | if (RTA_PAYLOAD(attr) < 4) | 295 | if (RTA_PAYLOAD(attr) < 4) |
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | if (i != RTA_MULTIPATH && i != RTA_METRICS) | 297 | if (i != RTA_MULTIPATH && i != RTA_METRICS && |
298 | i != RTA_TABLE) | ||
298 | *rta = (struct rtattr*)RTA_DATA(attr); | 299 | *rta = (struct rtattr*)RTA_DATA(attr); |
299 | } | 300 | } |
300 | } | 301 | } |
@@ -310,7 +311,7 @@ int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
310 | if (inet_check_attr(r, rta)) | 311 | if (inet_check_attr(r, rta)) |
311 | return -EINVAL; | 312 | return -EINVAL; |
312 | 313 | ||
313 | tb = fib_get_table(r->rtm_table); | 314 | tb = fib_get_table(rtm_get_table(rta, r->rtm_table)); |
314 | if (tb) | 315 | if (tb) |
315 | return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); | 316 | return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); |
316 | return -ESRCH; | 317 | return -ESRCH; |
@@ -325,7 +326,7 @@ int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
325 | if (inet_check_attr(r, rta)) | 326 | if (inet_check_attr(r, rta)) |
326 | return -EINVAL; | 327 | return -EINVAL; |
327 | 328 | ||
328 | tb = fib_new_table(r->rtm_table); | 329 | tb = fib_new_table(rtm_get_table(rta, r->rtm_table)); |
329 | if (tb) | 330 | if (tb) |
330 | return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); | 331 | return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); |
331 | return -ENOBUFS; | 332 | return -ENOBUFS; |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 58fb91b00fdf..0330b9cc4b58 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -184,6 +184,7 @@ static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | |||
184 | [FRA_DST] = { .type = NLA_U32 }, | 184 | [FRA_DST] = { .type = NLA_U32 }, |
185 | [FRA_FWMARK] = { .type = NLA_U32 }, | 185 | [FRA_FWMARK] = { .type = NLA_U32 }, |
186 | [FRA_FLOW] = { .type = NLA_U32 }, | 186 | [FRA_FLOW] = { .type = NLA_U32 }, |
187 | [FRA_TABLE] = { .type = NLA_U32 }, | ||
187 | }; | 188 | }; |
188 | 189 | ||
189 | static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | 190 | static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index c7a112b5a185..ab753df20a39 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -953,6 +953,7 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
953 | rtm->rtm_src_len = 0; | 953 | rtm->rtm_src_len = 0; |
954 | rtm->rtm_tos = tos; | 954 | rtm->rtm_tos = tos; |
955 | rtm->rtm_table = tb_id; | 955 | rtm->rtm_table = tb_id; |
956 | RTA_PUT_U32(skb, RTA_TABLE, tb_id); | ||
956 | rtm->rtm_type = type; | 957 | rtm->rtm_type = type; |
957 | rtm->rtm_flags = fi->fib_flags; | 958 | rtm->rtm_flags = fi->fib_flags; |
958 | rtm->rtm_scope = scope; | 959 | rtm->rtm_scope = scope; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b873cbcdd0b8..12128b82c9dc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2652,6 +2652,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
2652 | r->rtm_src_len = 0; | 2652 | r->rtm_src_len = 0; |
2653 | r->rtm_tos = rt->fl.fl4_tos; | 2653 | r->rtm_tos = rt->fl.fl4_tos; |
2654 | r->rtm_table = RT_TABLE_MAIN; | 2654 | r->rtm_table = RT_TABLE_MAIN; |
2655 | RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); | ||
2655 | r->rtm_type = rt->rt_type; | 2656 | r->rtm_type = rt->rt_type; |
2656 | r->rtm_scope = RT_SCOPE_UNIVERSE; | 2657 | r->rtm_scope = RT_SCOPE_UNIVERSE; |
2657 | r->rtm_protocol = RTPROT_UNSPEC; | 2658 | r->rtm_protocol = RTPROT_UNSPEC; |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 22a2fdb09831..2c4fbc855e6c 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -129,6 +129,7 @@ static struct nla_policy fib6_rule_policy[RTA_MAX+1] __read_mostly = { | |||
129 | [FRA_PRIORITY] = { .type = NLA_U32 }, | 129 | [FRA_PRIORITY] = { .type = NLA_U32 }, |
130 | [FRA_SRC] = { .minlen = sizeof(struct in6_addr) }, | 130 | [FRA_SRC] = { .minlen = sizeof(struct in6_addr) }, |
131 | [FRA_DST] = { .minlen = sizeof(struct in6_addr) }, | 131 | [FRA_DST] = { .minlen = sizeof(struct in6_addr) }, |
132 | [FRA_TABLE] = { .type = NLA_U32 }, | ||
132 | }; | 133 | }; |
133 | 134 | ||
134 | static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | 135 | static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e08d84063c1f..843c5509fced 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1859,7 +1859,8 @@ int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1859 | 1859 | ||
1860 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) | 1860 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) |
1861 | return -EINVAL; | 1861 | return -EINVAL; |
1862 | return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb), r->rtm_table); | 1862 | return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb), |
1863 | rtm_get_table(arg, r->rtm_table)); | ||
1863 | } | 1864 | } |
1864 | 1865 | ||
1865 | int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 1866 | int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
@@ -1869,7 +1870,8 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1869 | 1870 | ||
1870 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) | 1871 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) |
1871 | return -EINVAL; | 1872 | return -EINVAL; |
1872 | return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb), r->rtm_table); | 1873 | return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb), |
1874 | rtm_get_table(arg, r->rtm_table)); | ||
1873 | } | 1875 | } |
1874 | 1876 | ||
1875 | struct rt6_rtnl_dump_arg | 1877 | struct rt6_rtnl_dump_arg |
@@ -1887,6 +1889,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
1887 | struct nlmsghdr *nlh; | 1889 | struct nlmsghdr *nlh; |
1888 | unsigned char *b = skb->tail; | 1890 | unsigned char *b = skb->tail; |
1889 | struct rta_cacheinfo ci; | 1891 | struct rta_cacheinfo ci; |
1892 | u32 table; | ||
1890 | 1893 | ||
1891 | if (prefix) { /* user wants prefix routes only */ | 1894 | if (prefix) { /* user wants prefix routes only */ |
1892 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { | 1895 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { |
@@ -1902,9 +1905,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
1902 | rtm->rtm_src_len = rt->rt6i_src.plen; | 1905 | rtm->rtm_src_len = rt->rt6i_src.plen; |
1903 | rtm->rtm_tos = 0; | 1906 | rtm->rtm_tos = 0; |
1904 | if (rt->rt6i_table) | 1907 | if (rt->rt6i_table) |
1905 | rtm->rtm_table = rt->rt6i_table->tb6_id; | 1908 | table = rt->rt6i_table->tb6_id; |
1906 | else | 1909 | else |
1907 | rtm->rtm_table = RT6_TABLE_UNSPEC; | 1910 | table = RT6_TABLE_UNSPEC; |
1911 | rtm->rtm_table = table; | ||
1912 | RTA_PUT_U32(skb, RTA_TABLE, table); | ||
1908 | if (rt->rt6i_flags&RTF_REJECT) | 1913 | if (rt->rt6i_flags&RTF_REJECT) |
1909 | rtm->rtm_type = RTN_UNREACHABLE; | 1914 | rtm->rtm_type = RTN_UNREACHABLE; |
1910 | else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) | 1915 | else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) |