diff options
-rw-r--r-- | include/linux/fib_rules.h | 8 | ||||
-rw-r--r-- | include/linux/rtnetlink.h | 6 | ||||
-rw-r--r-- | include/net/fib_rules.h | 2 | ||||
-rw-r--r-- | net/core/fib_rules.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 14 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 4 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 4 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 100 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 4 |
9 files changed, 112 insertions, 32 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index 04a397619ebe..51da65b68b85 100644 --- a/include/linux/fib_rules.h +++ b/include/linux/fib_rules.h | |||
@@ -15,14 +15,6 @@ | |||
15 | /* try to find source address in routing lookups */ | 15 | /* try to find source address in routing lookups */ |
16 | #define FIB_RULE_FIND_SADDR 0x00010000 | 16 | #define FIB_RULE_FIND_SADDR 0x00010000 |
17 | 17 | ||
18 | /* fib_rules families. values up to 127 are reserved for real address | ||
19 | * families, values above 128 may be used arbitrarily. | ||
20 | */ | ||
21 | #define FIB_RULES_IPV4 AF_INET | ||
22 | #define FIB_RULES_IPV6 AF_INET6 | ||
23 | #define FIB_RULES_DECNET AF_DECnet | ||
24 | #define FIB_RULES_IPMR 128 | ||
25 | |||
26 | struct fib_rule_hdr { | 18 | struct fib_rule_hdr { |
27 | __u8 family; | 19 | __u8 family; |
28 | __u8 dst_len; | 20 | __u8 dst_len; |
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d1c7c90e9cd4..5a42c36cb6aa 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -7,6 +7,12 @@ | |||
7 | #include <linux/if_addr.h> | 7 | #include <linux/if_addr.h> |
8 | #include <linux/neighbour.h> | 8 | #include <linux/neighbour.h> |
9 | 9 | ||
10 | /* rtnetlink families. Values up to 127 are reserved for real address | ||
11 | * families, values above 128 may be used arbitrarily. | ||
12 | */ | ||
13 | #define RTNL_FAMILY_IPMR 128 | ||
14 | #define RTNL_FAMILY_MAX 128 | ||
15 | |||
10 | /**** | 16 | /**** |
11 | * Routing/neighbour discovery messages. | 17 | * Routing/neighbour discovery messages. |
12 | ****/ | 18 | ****/ |
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 52bd9e6c9141..e8923bc20f9f 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h | |||
@@ -104,7 +104,7 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) | |||
104 | return frh->table; | 104 | return frh->table; |
105 | } | 105 | } |
106 | 106 | ||
107 | extern struct fib_rules_ops *fib_rules_register(struct fib_rules_ops *, struct net *); | 107 | extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *); |
108 | extern void fib_rules_unregister(struct fib_rules_ops *); | 108 | extern void fib_rules_unregister(struct fib_rules_ops *); |
109 | extern void fib_rules_cleanup_ops(struct fib_rules_ops *); | 109 | extern void fib_rules_cleanup_ops(struct fib_rules_ops *); |
110 | 110 | ||
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 1bc66592453c..42e84e08a1be 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -122,7 +122,7 @@ errout: | |||
122 | } | 122 | } |
123 | 123 | ||
124 | struct fib_rules_ops * | 124 | struct fib_rules_ops * |
125 | fib_rules_register(struct fib_rules_ops *tmpl, struct net *net) | 125 | fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net) |
126 | { | 126 | { |
127 | struct fib_rules_ops *ops; | 127 | struct fib_rules_ops *ops; |
128 | int err; | 128 | int err; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 455e35aefbc2..23a71cb21273 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -98,7 +98,7 @@ int lockdep_rtnl_is_held(void) | |||
98 | EXPORT_SYMBOL(lockdep_rtnl_is_held); | 98 | EXPORT_SYMBOL(lockdep_rtnl_is_held); |
99 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | 99 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ |
100 | 100 | ||
101 | static struct rtnl_link *rtnl_msg_handlers[NPROTO]; | 101 | static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; |
102 | 102 | ||
103 | static inline int rtm_msgindex(int msgtype) | 103 | static inline int rtm_msgindex(int msgtype) |
104 | { | 104 | { |
@@ -118,7 +118,7 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) | |||
118 | { | 118 | { |
119 | struct rtnl_link *tab; | 119 | struct rtnl_link *tab; |
120 | 120 | ||
121 | if (protocol < NPROTO) | 121 | if (protocol <= RTNL_FAMILY_MAX) |
122 | tab = rtnl_msg_handlers[protocol]; | 122 | tab = rtnl_msg_handlers[protocol]; |
123 | else | 123 | else |
124 | tab = NULL; | 124 | tab = NULL; |
@@ -133,7 +133,7 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | |||
133 | { | 133 | { |
134 | struct rtnl_link *tab; | 134 | struct rtnl_link *tab; |
135 | 135 | ||
136 | if (protocol < NPROTO) | 136 | if (protocol <= RTNL_FAMILY_MAX) |
137 | tab = rtnl_msg_handlers[protocol]; | 137 | tab = rtnl_msg_handlers[protocol]; |
138 | else | 138 | else |
139 | tab = NULL; | 139 | tab = NULL; |
@@ -167,7 +167,7 @@ int __rtnl_register(int protocol, int msgtype, | |||
167 | struct rtnl_link *tab; | 167 | struct rtnl_link *tab; |
168 | int msgindex; | 168 | int msgindex; |
169 | 169 | ||
170 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 170 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
171 | msgindex = rtm_msgindex(msgtype); | 171 | msgindex = rtm_msgindex(msgtype); |
172 | 172 | ||
173 | tab = rtnl_msg_handlers[protocol]; | 173 | tab = rtnl_msg_handlers[protocol]; |
@@ -219,7 +219,7 @@ int rtnl_unregister(int protocol, int msgtype) | |||
219 | { | 219 | { |
220 | int msgindex; | 220 | int msgindex; |
221 | 221 | ||
222 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 222 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
223 | msgindex = rtm_msgindex(msgtype); | 223 | msgindex = rtm_msgindex(msgtype); |
224 | 224 | ||
225 | if (rtnl_msg_handlers[protocol] == NULL) | 225 | if (rtnl_msg_handlers[protocol] == NULL) |
@@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(rtnl_unregister); | |||
241 | */ | 241 | */ |
242 | void rtnl_unregister_all(int protocol) | 242 | void rtnl_unregister_all(int protocol) |
243 | { | 243 | { |
244 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 244 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
245 | 245 | ||
246 | kfree(rtnl_msg_handlers[protocol]); | 246 | kfree(rtnl_msg_handlers[protocol]); |
247 | rtnl_msg_handlers[protocol] = NULL; | 247 | rtnl_msg_handlers[protocol] = NULL; |
@@ -1385,7 +1385,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) | |||
1385 | 1385 | ||
1386 | if (s_idx == 0) | 1386 | if (s_idx == 0) |
1387 | s_idx = 1; | 1387 | s_idx = 1; |
1388 | for (idx = 1; idx < NPROTO; idx++) { | 1388 | for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { |
1389 | int type = cb->nlh->nlmsg_type-RTM_BASE; | 1389 | int type = cb->nlh->nlmsg_type-RTM_BASE; |
1390 | if (idx < s_idx || idx == PF_PACKET) | 1390 | if (idx < s_idx || idx == PF_PACKET) |
1391 | continue; | 1391 | continue; |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index af28dcc21844..48fdf10be7a1 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -216,8 +216,8 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops) | |||
216 | dn_rt_cache_flush(-1); | 216 | dn_rt_cache_flush(-1); |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct fib_rules_ops dn_fib_rules_ops_template = { | 219 | static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = { |
220 | .family = FIB_RULES_DECNET, | 220 | .family = AF_DECnet, |
221 | .rule_size = sizeof(struct dn_fib_rule), | 221 | .rule_size = sizeof(struct dn_fib_rule), |
222 | .addr_size = sizeof(u16), | 222 | .addr_size = sizeof(u16), |
223 | .action = dn_fib_rule_action, | 223 | .action = dn_fib_rule_action, |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 3ec84fea5b71..76daeb5ff564 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -245,8 +245,8 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops) | |||
245 | rt_cache_flush(ops->fro_net, -1); | 245 | rt_cache_flush(ops->fro_net, -1); |
246 | } | 246 | } |
247 | 247 | ||
248 | static struct fib_rules_ops fib4_rules_ops_template = { | 248 | static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { |
249 | .family = FIB_RULES_IPV4, | 249 | .family = AF_INET, |
250 | .rule_size = sizeof(struct fib4_rule), | 250 | .rule_size = sizeof(struct fib4_rule), |
251 | .addr_size = sizeof(u32), | 251 | .addr_size = sizeof(u32), |
252 | .action = fib4_rule_action, | 252 | .action = fib4_rule_action, |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index a2df5012a1d0..eddfd12f55b8 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -128,8 +128,8 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, | |||
128 | int local); | 128 | int local); |
129 | static int ipmr_cache_report(struct mr_table *mrt, | 129 | static int ipmr_cache_report(struct mr_table *mrt, |
130 | struct sk_buff *pkt, vifi_t vifi, int assert); | 130 | struct sk_buff *pkt, vifi_t vifi, int assert); |
131 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 131 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
132 | struct mfc_cache *c, struct rtmsg *rtm); | 132 | struct mfc_cache *c, struct rtmsg *rtm); |
133 | static void ipmr_expire_process(unsigned long arg); | 133 | static void ipmr_expire_process(unsigned long arg); |
134 | 134 | ||
135 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | 135 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
@@ -216,8 +216,8 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct fib_rules_ops ipmr_rules_ops_template = { | 219 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { |
220 | .family = FIB_RULES_IPMR, | 220 | .family = RTNL_FAMILY_IPMR, |
221 | .rule_size = sizeof(struct ipmr_rule), | 221 | .rule_size = sizeof(struct ipmr_rule), |
222 | .addr_size = sizeof(u32), | 222 | .addr_size = sizeof(u32), |
223 | .action = ipmr_rule_action, | 223 | .action = ipmr_rule_action, |
@@ -831,7 +831,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, | |||
831 | if (ip_hdr(skb)->version == 0) { | 831 | if (ip_hdr(skb)->version == 0) { |
832 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); | 832 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); |
833 | 833 | ||
834 | if (ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { | 834 | if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { |
835 | nlh->nlmsg_len = (skb_tail_pointer(skb) - | 835 | nlh->nlmsg_len = (skb_tail_pointer(skb) - |
836 | (u8 *)nlh); | 836 | (u8 *)nlh); |
837 | } else { | 837 | } else { |
@@ -1904,9 +1904,8 @@ drop: | |||
1904 | } | 1904 | } |
1905 | #endif | 1905 | #endif |
1906 | 1906 | ||
1907 | static int | 1907 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
1908 | ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, struct mfc_cache *c, | 1908 | struct mfc_cache *c, struct rtmsg *rtm) |
1909 | struct rtmsg *rtm) | ||
1910 | { | 1909 | { |
1911 | int ct; | 1910 | int ct; |
1912 | struct rtnexthop *nhp; | 1911 | struct rtnexthop *nhp; |
@@ -1994,11 +1993,93 @@ int ipmr_get_route(struct net *net, | |||
1994 | 1993 | ||
1995 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) | 1994 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) |
1996 | cache->mfc_flags |= MFC_NOTIFY; | 1995 | cache->mfc_flags |= MFC_NOTIFY; |
1997 | err = ipmr_fill_mroute(mrt, skb, cache, rtm); | 1996 | err = __ipmr_fill_mroute(mrt, skb, cache, rtm); |
1998 | read_unlock(&mrt_lock); | 1997 | read_unlock(&mrt_lock); |
1999 | return err; | 1998 | return err; |
2000 | } | 1999 | } |
2001 | 2000 | ||
2001 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | ||
2002 | u32 pid, u32 seq, struct mfc_cache *c) | ||
2003 | { | ||
2004 | struct nlmsghdr *nlh; | ||
2005 | struct rtmsg *rtm; | ||
2006 | |||
2007 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI); | ||
2008 | if (nlh == NULL) | ||
2009 | return -EMSGSIZE; | ||
2010 | |||
2011 | rtm = nlmsg_data(nlh); | ||
2012 | rtm->rtm_family = RTNL_FAMILY_IPMR; | ||
2013 | rtm->rtm_dst_len = 32; | ||
2014 | rtm->rtm_src_len = 32; | ||
2015 | rtm->rtm_tos = 0; | ||
2016 | rtm->rtm_table = mrt->id; | ||
2017 | NLA_PUT_U32(skb, RTA_TABLE, mrt->id); | ||
2018 | rtm->rtm_type = RTN_MULTICAST; | ||
2019 | rtm->rtm_scope = RT_SCOPE_UNIVERSE; | ||
2020 | rtm->rtm_protocol = RTPROT_UNSPEC; | ||
2021 | rtm->rtm_flags = 0; | ||
2022 | |||
2023 | NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin); | ||
2024 | NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp); | ||
2025 | |||
2026 | if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0) | ||
2027 | goto nla_put_failure; | ||
2028 | |||
2029 | return nlmsg_end(skb, nlh); | ||
2030 | |||
2031 | nla_put_failure: | ||
2032 | nlmsg_cancel(skb, nlh); | ||
2033 | return -EMSGSIZE; | ||
2034 | } | ||
2035 | |||
2036 | static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) | ||
2037 | { | ||
2038 | struct net *net = sock_net(skb->sk); | ||
2039 | struct mr_table *mrt; | ||
2040 | struct mfc_cache *mfc; | ||
2041 | unsigned int t = 0, s_t; | ||
2042 | unsigned int h = 0, s_h; | ||
2043 | unsigned int e = 0, s_e; | ||
2044 | |||
2045 | s_t = cb->args[0]; | ||
2046 | s_h = cb->args[1]; | ||
2047 | s_e = cb->args[2]; | ||
2048 | |||
2049 | read_lock(&mrt_lock); | ||
2050 | ipmr_for_each_table(mrt, net) { | ||
2051 | if (t < s_t) | ||
2052 | goto next_table; | ||
2053 | if (t > s_t) | ||
2054 | s_h = 0; | ||
2055 | for (h = s_h; h < MFC_LINES; h++) { | ||
2056 | list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) { | ||
2057 | if (e < s_e) | ||
2058 | goto next_entry; | ||
2059 | if (ipmr_fill_mroute(mrt, skb, | ||
2060 | NETLINK_CB(cb->skb).pid, | ||
2061 | cb->nlh->nlmsg_seq, | ||
2062 | mfc) < 0) | ||
2063 | goto done; | ||
2064 | next_entry: | ||
2065 | e++; | ||
2066 | } | ||
2067 | e = s_e = 0; | ||
2068 | } | ||
2069 | s_h = 0; | ||
2070 | next_table: | ||
2071 | t++; | ||
2072 | } | ||
2073 | done: | ||
2074 | read_unlock(&mrt_lock); | ||
2075 | |||
2076 | cb->args[2] = e; | ||
2077 | cb->args[1] = h; | ||
2078 | cb->args[0] = t; | ||
2079 | |||
2080 | return skb->len; | ||
2081 | } | ||
2082 | |||
2002 | #ifdef CONFIG_PROC_FS | 2083 | #ifdef CONFIG_PROC_FS |
2003 | /* | 2084 | /* |
2004 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif | 2085 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif |
@@ -2355,6 +2436,7 @@ int __init ip_mr_init(void) | |||
2355 | goto add_proto_fail; | 2436 | goto add_proto_fail; |
2356 | } | 2437 | } |
2357 | #endif | 2438 | #endif |
2439 | rtnl_register(RTNL_FAMILY_IPMR, RTM_GETROUTE, NULL, ipmr_rtm_dumproute); | ||
2358 | return 0; | 2440 | return 0; |
2359 | 2441 | ||
2360 | #ifdef CONFIG_IP_PIMSM_V2 | 2442 | #ifdef CONFIG_IP_PIMSM_V2 |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 8124f16f2ac2..8e44f8f9c188 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -237,8 +237,8 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
237 | + nla_total_size(16); /* src */ | 237 | + nla_total_size(16); /* src */ |
238 | } | 238 | } |
239 | 239 | ||
240 | static struct fib_rules_ops fib6_rules_ops_template = { | 240 | static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = { |
241 | .family = FIB_RULES_IPV6, | 241 | .family = AF_INET6, |
242 | .rule_size = sizeof(struct fib6_rule), | 242 | .rule_size = sizeof(struct fib6_rule), |
243 | .addr_size = sizeof(struct in6_addr), | 243 | .addr_size = sizeof(struct in6_addr), |
244 | .action = fib6_rule_action, | 244 | .action = fib6_rule_action, |