aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-04-13 01:03:23 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-13 17:49:34 -0400
commitf0ad0860d01e47a3ffd220564c5c653b3afbe962 (patch)
tree91b69423f472b934daa2c18ae3b7ba065b7c7898
parent0c12295a741d3186987f96f518cfbdaf01abb087 (diff)
ipv4: ipmr: support multiple tables
This patch adds support for multiple independant multicast routing instances, named "tables". Userspace multicast routing daemons can bind to a specific table instance by issuing a setsockopt call using a new option MRT_TABLE. The table number is stored in the raw socket data and affects all following ipmr setsockopt(), getsockopt() and ioctl() calls. By default, a single table (RT_TABLE_DEFAULT) is created with a default routing rule pointing to it. Newly created pimreg devices have the table number appended ("pimregX"), with the exception of devices created in the default table, which are named just "pimreg" for compatibility reasons. Packets are directed to a specific table instance using routing rules, similar to how regular routing rules work. Currently iif, oif and mark are supported as keys, source and destination addresses could be supported additionally. Example usage: - bind pimd/xorp/... to a specific table: uint32_t table = 123; setsockopt(fd, IPPROTO_IP, MRT_TABLE, &table, sizeof(table)); - create routing rules directing packets to the new table: # ip mrule add iif eth0 lookup 123 # ip mrule add oif eth0 lookup 123 Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/fib_rules.h1
-rw-r--r--include/linux/mroute.h3
-rw-r--r--include/net/netns/ipv4.h5
-rw-r--r--include/net/raw.h1
-rw-r--r--net/ipv4/Kconfig14
-rw-r--r--net/ipv4/ipmr.c399
6 files changed, 361 insertions, 62 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 405e41139a4..04a397619eb 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -21,6 +21,7 @@
21#define FIB_RULES_IPV4 AF_INET 21#define FIB_RULES_IPV4 AF_INET
22#define FIB_RULES_IPV6 AF_INET6 22#define FIB_RULES_IPV6 AF_INET6
23#define FIB_RULES_DECNET AF_DECnet 23#define FIB_RULES_DECNET AF_DECnet
24#define FIB_RULES_IPMR 128
24 25
25struct fib_rule_hdr { 26struct fib_rule_hdr {
26 __u8 family; 27 __u8 family;
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 7ff6c77d600..fa04b246c9a 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -27,7 +27,8 @@
27#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */ 27#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */
28#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */ 28#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */
29#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */ 29#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */
30#define MRT_PIM (MRT_BASE+8) /* enable PIM code */ 30#define MRT_PIM (MRT_BASE+8) /* enable PIM code */
31#define MRT_TABLE (MRT_BASE+9) /* Specify mroute table ID */
31 32
32#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */ 33#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */
33#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1) 34#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 72e762ab3e5..ae07feec644 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -59,7 +59,12 @@ struct netns_ipv4 {
59 atomic_t rt_genid; 59 atomic_t rt_genid;
60 60
61#ifdef CONFIG_IP_MROUTE 61#ifdef CONFIG_IP_MROUTE
62#ifndef CONFIG_IP_MROUTE_MULTIPLE_TABLES
62 struct mr_table *mrt; 63 struct mr_table *mrt;
64#else
65 struct list_head mr_tables;
66 struct fib_rules_ops *mr_rules_ops;
67#endif
63#endif 68#endif
64}; 69};
65#endif 70#endif
diff --git a/include/net/raw.h b/include/net/raw.h
index 67cc6436943..43c57502659 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -61,6 +61,7 @@ struct raw_sock {
61 /* inet_sock has to be the first member */ 61 /* inet_sock has to be the first member */
62 struct inet_sock inet; 62 struct inet_sock inet;
63 struct icmp_filter filter; 63 struct icmp_filter filter;
64 u32 ipmr_table;
64}; 65};
65 66
66static inline struct raw_sock *raw_sk(const struct sock *sk) 67static inline struct raw_sock *raw_sk(const struct sock *sk)
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index c9a1c68767f..be597749c38 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -250,6 +250,20 @@ config IP_MROUTE
250 <file:Documentation/networking/multicast.txt>. If you haven't heard 250 <file:Documentation/networking/multicast.txt>. If you haven't heard
251 about it, you don't need it. 251 about it, you don't need it.
252 252
253config IP_MROUTE_MULTIPLE_TABLES
254 bool "IP: multicast policy routing"
255 depends on IP_ADVANCED_ROUTER
256 select FIB_RULES
257 help
258 Normally, a multicast router runs a userspace daemon and decides
259 what to do with a multicast packet based on the source and
260 destination addresses. If you say Y here, the multicast router
261 will also be able to take interfaces and packet marks into
262 account and run multiple instances of userspace daemons
263 simultaneously, each one handling a single table.
264
265 If unsure, say N.
266
253config IP_PIMSM_V1 267config IP_PIMSM_V1
254 bool "IP: PIM-SM version 1 support" 268 bool "IP: PIM-SM version 1 support"
255 depends on IP_MROUTE 269 depends on IP_MROUTE
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 498f4e907d5..5df5fd74c6d 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -63,12 +63,15 @@
63#include <net/ipip.h> 63#include <net/ipip.h>
64#include <net/checksum.h> 64#include <net/checksum.h>
65#include <net/netlink.h> 65#include <net/netlink.h>
66#include <net/fib_rules.h>
66 67
67#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) 68#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
68#define CONFIG_IP_PIMSM 1 69#define CONFIG_IP_PIMSM 1
69#endif 70#endif
70 71
71struct mr_table { 72struct mr_table {
73 struct list_head list;
74 u32 id;
72 struct sock *mroute_sk; 75 struct sock *mroute_sk;
73 struct timer_list ipmr_expire_timer; 76 struct timer_list ipmr_expire_timer;
74 struct list_head mfc_unres_queue; 77 struct list_head mfc_unres_queue;
@@ -83,6 +86,14 @@ struct mr_table {
83#endif 86#endif
84}; 87};
85 88
89struct ipmr_rule {
90 struct fib_rule common;
91};
92
93struct ipmr_result {
94 struct mr_table *mrt;
95};
96
86/* Big lock, protecting vif table, mrt cache and mroute socket state. 97/* Big lock, protecting vif table, mrt cache and mroute socket state.
87 Note that the changes are semaphored via rtnl_lock. 98 Note that the changes are semaphored via rtnl_lock.
88 */ 99 */
@@ -108,6 +119,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
108 119
109static struct kmem_cache *mrt_cachep __read_mostly; 120static struct kmem_cache *mrt_cachep __read_mostly;
110 121
122static struct mr_table *ipmr_new_table(struct net *net, u32 id);
111static int ip_mr_forward(struct net *net, struct mr_table *mrt, 123static int ip_mr_forward(struct net *net, struct mr_table *mrt,
112 struct sk_buff *skb, struct mfc_cache *cache, 124 struct sk_buff *skb, struct mfc_cache *cache,
113 int local); 125 int local);
@@ -115,6 +127,206 @@ static int ipmr_cache_report(struct mr_table *mrt,
115 struct sk_buff *pkt, vifi_t vifi, int assert); 127 struct sk_buff *pkt, vifi_t vifi, int assert);
116static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 128static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
117 struct mfc_cache *c, struct rtmsg *rtm); 129 struct mfc_cache *c, struct rtmsg *rtm);
130static void ipmr_expire_process(unsigned long arg);
131
132#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
133#define ipmr_for_each_table(mrt, net) \
134 list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list)
135
136static struct mr_table *ipmr_get_table(struct net *net, u32 id)
137{
138 struct mr_table *mrt;
139
140 ipmr_for_each_table(mrt, net) {
141 if (mrt->id == id)
142 return mrt;
143 }
144 return NULL;
145}
146
147static int ipmr_fib_lookup(struct net *net, struct flowi *flp,
148 struct mr_table **mrt)
149{
150 struct ipmr_result res;
151 struct fib_lookup_arg arg = { .result = &res, };
152 int err;
153
154 err = fib_rules_lookup(net->ipv4.mr_rules_ops, flp, 0, &arg);
155 if (err < 0)
156 return err;
157 *mrt = res.mrt;
158 return 0;
159}
160
161static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp,
162 int flags, struct fib_lookup_arg *arg)
163{
164 struct ipmr_result *res = arg->result;
165 struct mr_table *mrt;
166
167 switch (rule->action) {
168 case FR_ACT_TO_TBL:
169 break;
170 case FR_ACT_UNREACHABLE:
171 return -ENETUNREACH;
172 case FR_ACT_PROHIBIT:
173 return -EACCES;
174 case FR_ACT_BLACKHOLE:
175 default:
176 return -EINVAL;
177 }
178
179 mrt = ipmr_get_table(rule->fr_net, rule->table);
180 if (mrt == NULL)
181 return -EAGAIN;
182 res->mrt = mrt;
183 return 0;
184}
185
186static int ipmr_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
187{
188 return 1;
189}
190
191static const struct nla_policy ipmr_rule_policy[FRA_MAX + 1] = {
192 FRA_GENERIC_POLICY,
193};
194
195static int ipmr_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
196 struct fib_rule_hdr *frh, struct nlattr **tb)
197{
198 return 0;
199}
200
201static int ipmr_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
202 struct nlattr **tb)
203{
204 return 1;
205}
206
207static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
208 struct fib_rule_hdr *frh)
209{
210 frh->dst_len = 0;
211 frh->src_len = 0;
212 frh->tos = 0;
213 return 0;
214}
215
216static struct fib_rules_ops ipmr_rules_ops_template = {
217 .family = FIB_RULES_IPMR,
218 .rule_size = sizeof(struct ipmr_rule),
219 .addr_size = sizeof(u32),
220 .action = ipmr_rule_action,
221 .match = ipmr_rule_match,
222 .configure = ipmr_rule_configure,
223 .compare = ipmr_rule_compare,
224 .default_pref = fib_default_rule_pref,
225 .fill = ipmr_rule_fill,
226 .nlgroup = RTNLGRP_IPV4_RULE,
227 .policy = ipmr_rule_policy,
228 .owner = THIS_MODULE,
229};
230
231static int __net_init ipmr_rules_init(struct net *net)
232{
233 struct fib_rules_ops *ops;
234 struct mr_table *mrt;
235 int err;
236
237 ops = fib_rules_register(&ipmr_rules_ops_template, net);
238 if (IS_ERR(ops))
239 return PTR_ERR(ops);
240
241 INIT_LIST_HEAD(&net->ipv4.mr_tables);
242
243 mrt = ipmr_new_table(net, RT_TABLE_DEFAULT);
244 if (mrt == NULL) {
245 err = -ENOMEM;
246 goto err1;
247 }
248
249 err = fib_default_rule_add(ops, 0x7fff, RT_TABLE_DEFAULT, 0);
250 if (err < 0)
251 goto err2;
252
253 net->ipv4.mr_rules_ops = ops;
254 return 0;
255
256err2:
257 kfree(mrt);
258err1:
259 fib_rules_unregister(ops);
260 return err;
261}
262
263static void __net_exit ipmr_rules_exit(struct net *net)
264{
265 struct mr_table *mrt, *next;
266
267 list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list)
268 kfree(mrt);
269 fib_rules_unregister(net->ipv4.mr_rules_ops);
270}
271#else
272#define ipmr_for_each_table(mrt, net) \
273 for (mrt = net->ipv4.mrt; mrt; mrt = NULL)
274
275static struct mr_table *ipmr_get_table(struct net *net, u32 id)
276{
277 return net->ipv4.mrt;
278}
279
280static int ipmr_fib_lookup(struct net *net, struct flowi *flp,
281 struct mr_table **mrt)
282{
283 *mrt = net->ipv4.mrt;
284 return 0;
285}
286
287static int __net_init ipmr_rules_init(struct net *net)
288{
289 net->ipv4.mrt = ipmr_new_table(net, RT_TABLE_DEFAULT);
290 return net->ipv4.mrt ? 0 : -ENOMEM;
291}
292
293static void __net_exit ipmr_rules_exit(struct net *net)
294{
295 kfree(net->ipv4.mrt);
296}
297#endif
298
299static struct mr_table *ipmr_new_table(struct net *net, u32 id)
300{
301 struct mr_table *mrt;
302 unsigned int i;
303
304 mrt = ipmr_get_table(net, id);
305 if (mrt != NULL)
306 return mrt;
307
308 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
309 if (mrt == NULL)
310 return NULL;
311 mrt->id = id;
312
313 /* Forwarding cache */
314 for (i = 0; i < MFC_LINES; i++)
315 INIT_LIST_HEAD(&mrt->mfc_cache_array[i]);
316
317 INIT_LIST_HEAD(&mrt->mfc_unres_queue);
318
319 setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process,
320 (unsigned long)mrt);
321
322#ifdef CONFIG_IP_PIMSM
323 mrt->mroute_reg_vif_num = -1;
324#endif
325#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
326 list_add_tail_rcu(&mrt->list, &net->ipv4.mr_tables);
327#endif
328 return mrt;
329}
118 330
119/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ 331/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
120 332
@@ -215,7 +427,17 @@ failure:
215static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) 427static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
216{ 428{
217 struct net *net = dev_net(dev); 429 struct net *net = dev_net(dev);
218 struct mr_table *mrt = net->ipv4.mrt; 430 struct mr_table *mrt;
431 struct flowi fl = {
432 .oif = dev->ifindex,
433 .iif = skb->skb_iif,
434 .mark = skb->mark,
435 };
436 int err;
437
438 err = ipmr_fib_lookup(net, &fl, &mrt);
439 if (err < 0)
440 return err;
219 441
220 read_lock(&mrt_lock); 442 read_lock(&mrt_lock);
221 dev->stats.tx_bytes += skb->len; 443 dev->stats.tx_bytes += skb->len;
@@ -240,12 +462,18 @@ static void reg_vif_setup(struct net_device *dev)
240 dev->features |= NETIF_F_NETNS_LOCAL; 462 dev->features |= NETIF_F_NETNS_LOCAL;
241} 463}
242 464
243static struct net_device *ipmr_reg_vif(struct net *net) 465static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
244{ 466{
245 struct net_device *dev; 467 struct net_device *dev;
246 struct in_device *in_dev; 468 struct in_device *in_dev;
469 char name[IFNAMSIZ];
470
471 if (mrt->id == RT_TABLE_DEFAULT)
472 sprintf(name, "pimreg");
473 else
474 sprintf(name, "pimreg%u", mrt->id);
247 475
248 dev = alloc_netdev(0, "pimreg", reg_vif_setup); 476 dev = alloc_netdev(0, name, reg_vif_setup);
249 477
250 if (dev == NULL) 478 if (dev == NULL)
251 return NULL; 479 return NULL;
@@ -461,7 +689,7 @@ static int vif_add(struct net *net, struct mr_table *mrt,
461 */ 689 */
462 if (mrt->mroute_reg_vif_num >= 0) 690 if (mrt->mroute_reg_vif_num >= 0)
463 return -EADDRINUSE; 691 return -EADDRINUSE;
464 dev = ipmr_reg_vif(net); 692 dev = ipmr_reg_vif(net, mrt);
465 if (!dev) 693 if (!dev)
466 return -ENOBUFS; 694 return -ENOBUFS;
467 err = dev_set_allmulti(dev, 1); 695 err = dev_set_allmulti(dev, 1);
@@ -928,17 +1156,19 @@ static void mroute_clean_tables(struct mr_table *mrt)
928static void mrtsock_destruct(struct sock *sk) 1156static void mrtsock_destruct(struct sock *sk)
929{ 1157{
930 struct net *net = sock_net(sk); 1158 struct net *net = sock_net(sk);
931 struct mr_table *mrt = net->ipv4.mrt; 1159 struct mr_table *mrt;
932 1160
933 rtnl_lock(); 1161 rtnl_lock();
934 if (sk == mrt->mroute_sk) { 1162 ipmr_for_each_table(mrt, net) {
935 IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; 1163 if (sk == mrt->mroute_sk) {
1164 IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
936 1165
937 write_lock_bh(&mrt_lock); 1166 write_lock_bh(&mrt_lock);
938 mrt->mroute_sk = NULL; 1167 mrt->mroute_sk = NULL;
939 write_unlock_bh(&mrt_lock); 1168 write_unlock_bh(&mrt_lock);
940 1169
941 mroute_clean_tables(mrt); 1170 mroute_clean_tables(mrt);
1171 }
942 } 1172 }
943 rtnl_unlock(); 1173 rtnl_unlock();
944} 1174}
@@ -956,7 +1186,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
956 struct vifctl vif; 1186 struct vifctl vif;
957 struct mfcctl mfc; 1187 struct mfcctl mfc;
958 struct net *net = sock_net(sk); 1188 struct net *net = sock_net(sk);
959 struct mr_table *mrt = net->ipv4.mrt; 1189 struct mr_table *mrt;
1190
1191 mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
1192 if (mrt == NULL)
1193 return -ENOENT;
960 1194
961 if (optname != MRT_INIT) { 1195 if (optname != MRT_INIT) {
962 if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN)) 1196 if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN))
@@ -1055,6 +1289,27 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
1055 return ret; 1289 return ret;
1056 } 1290 }
1057#endif 1291#endif
1292#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
1293 case MRT_TABLE:
1294 {
1295 u32 v;
1296
1297 if (optlen != sizeof(u32))
1298 return -EINVAL;
1299 if (get_user(v, (u32 __user *)optval))
1300 return -EFAULT;
1301 if (sk == mrt->mroute_sk)
1302 return -EBUSY;
1303
1304 rtnl_lock();
1305 ret = 0;
1306 if (!ipmr_new_table(net, v))
1307 ret = -ENOMEM;
1308 raw_sk(sk)->ipmr_table = v;
1309 rtnl_unlock();
1310 return ret;
1311 }
1312#endif
1058 /* 1313 /*
1059 * Spurious command, or MRT_VERSION which you cannot 1314 * Spurious command, or MRT_VERSION which you cannot
1060 * set. 1315 * set.
@@ -1073,7 +1328,11 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int
1073 int olr; 1328 int olr;
1074 int val; 1329 int val;
1075 struct net *net = sock_net(sk); 1330 struct net *net = sock_net(sk);
1076 struct mr_table *mrt = net->ipv4.mrt; 1331 struct mr_table *mrt;
1332
1333 mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
1334 if (mrt == NULL)
1335 return -ENOENT;
1077 1336
1078 if (optname != MRT_VERSION && 1337 if (optname != MRT_VERSION &&
1079#ifdef CONFIG_IP_PIMSM 1338#ifdef CONFIG_IP_PIMSM
@@ -1115,7 +1374,11 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
1115 struct vif_device *vif; 1374 struct vif_device *vif;
1116 struct mfc_cache *c; 1375 struct mfc_cache *c;
1117 struct net *net = sock_net(sk); 1376 struct net *net = sock_net(sk);
1118 struct mr_table *mrt = net->ipv4.mrt; 1377 struct mr_table *mrt;
1378
1379 mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
1380 if (mrt == NULL)
1381 return -ENOENT;
1119 1382
1120 switch (cmd) { 1383 switch (cmd) {
1121 case SIOCGETVIFCNT: 1384 case SIOCGETVIFCNT:
@@ -1166,17 +1429,20 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v
1166{ 1429{
1167 struct net_device *dev = ptr; 1430 struct net_device *dev = ptr;
1168 struct net *net = dev_net(dev); 1431 struct net *net = dev_net(dev);
1169 struct mr_table *mrt = net->ipv4.mrt; 1432 struct mr_table *mrt;
1170 struct vif_device *v; 1433 struct vif_device *v;
1171 int ct; 1434 int ct;
1172 LIST_HEAD(list); 1435 LIST_HEAD(list);
1173 1436
1174 if (event != NETDEV_UNREGISTER) 1437 if (event != NETDEV_UNREGISTER)
1175 return NOTIFY_DONE; 1438 return NOTIFY_DONE;
1176 v = &mrt->vif_table[0]; 1439
1177 for (ct = 0; ct < mrt->maxvif; ct++, v++) { 1440 ipmr_for_each_table(mrt, net) {
1178 if (v->dev == dev) 1441 v = &mrt->vif_table[0];
1179 vif_delete(mrt, ct, 1, &list); 1442 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1443 if (v->dev == dev)
1444 vif_delete(mrt, ct, 1, &list);
1445 }
1180 } 1446 }
1181 unregister_netdevice_many(&list); 1447 unregister_netdevice_many(&list);
1182 return NOTIFY_DONE; 1448 return NOTIFY_DONE;
@@ -1443,8 +1709,9 @@ int ip_mr_input(struct sk_buff *skb)
1443{ 1709{
1444 struct mfc_cache *cache; 1710 struct mfc_cache *cache;
1445 struct net *net = dev_net(skb->dev); 1711 struct net *net = dev_net(skb->dev);
1446 struct mr_table *mrt = net->ipv4.mrt;
1447 int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; 1712 int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
1713 struct mr_table *mrt;
1714 int err;
1448 1715
1449 /* Packet is looped back after forward, it should not be 1716 /* Packet is looped back after forward, it should not be
1450 forwarded second time, but still can be delivered locally. 1717 forwarded second time, but still can be delivered locally.
@@ -1452,6 +1719,10 @@ int ip_mr_input(struct sk_buff *skb)
1452 if (IPCB(skb)->flags&IPSKB_FORWARDED) 1719 if (IPCB(skb)->flags&IPSKB_FORWARDED)
1453 goto dont_forward; 1720 goto dont_forward;
1454 1721
1722 err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt);
1723 if (err < 0)
1724 return err;
1725
1455 if (!local) { 1726 if (!local) {
1456 if (IPCB(skb)->opt.router_alert) { 1727 if (IPCB(skb)->opt.router_alert) {
1457 if (ip_call_ra_chain(skb)) 1728 if (ip_call_ra_chain(skb))
@@ -1522,12 +1793,11 @@ dont_forward:
1522} 1793}
1523 1794
1524#ifdef CONFIG_IP_PIMSM 1795#ifdef CONFIG_IP_PIMSM
1525static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) 1796static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
1797 unsigned int pimlen)
1526{ 1798{
1527 struct net_device *reg_dev = NULL; 1799 struct net_device *reg_dev = NULL;
1528 struct iphdr *encap; 1800 struct iphdr *encap;
1529 struct net *net = dev_net(skb->dev);
1530 struct mr_table *mrt = net->ipv4.mrt;
1531 1801
1532 encap = (struct iphdr *)(skb_transport_header(skb) + pimlen); 1802 encap = (struct iphdr *)(skb_transport_header(skb) + pimlen);
1533 /* 1803 /*
@@ -1578,18 +1848,21 @@ int pim_rcv_v1(struct sk_buff * skb)
1578{ 1848{
1579 struct igmphdr *pim; 1849 struct igmphdr *pim;
1580 struct net *net = dev_net(skb->dev); 1850 struct net *net = dev_net(skb->dev);
1581 struct mr_table *mrt = net->ipv4.mrt; 1851 struct mr_table *mrt;
1582 1852
1583 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) 1853 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr)))
1584 goto drop; 1854 goto drop;
1585 1855
1586 pim = igmp_hdr(skb); 1856 pim = igmp_hdr(skb);
1587 1857
1858 if (ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt) < 0)
1859 goto drop;
1860
1588 if (!mrt->mroute_do_pim || 1861 if (!mrt->mroute_do_pim ||
1589 pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) 1862 pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER)
1590 goto drop; 1863 goto drop;
1591 1864
1592 if (__pim_rcv(skb, sizeof(*pim))) { 1865 if (__pim_rcv(mrt, skb, sizeof(*pim))) {
1593drop: 1866drop:
1594 kfree_skb(skb); 1867 kfree_skb(skb);
1595 } 1868 }
@@ -1601,6 +1874,8 @@ drop:
1601static int pim_rcv(struct sk_buff * skb) 1874static int pim_rcv(struct sk_buff * skb)
1602{ 1875{
1603 struct pimreghdr *pim; 1876 struct pimreghdr *pim;
1877 struct net *net = dev_net(skb->dev);
1878 struct mr_table *mrt;
1604 1879
1605 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) 1880 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr)))
1606 goto drop; 1881 goto drop;
@@ -1612,7 +1887,10 @@ static int pim_rcv(struct sk_buff * skb)
1612 csum_fold(skb_checksum(skb, 0, skb->len, 0)))) 1887 csum_fold(skb_checksum(skb, 0, skb->len, 0))))
1613 goto drop; 1888 goto drop;
1614 1889
1615 if (__pim_rcv(skb, sizeof(*pim))) { 1890 if (ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt) < 0)
1891 goto drop;
1892
1893 if (__pim_rcv(mrt, skb, sizeof(*pim))) {
1616drop: 1894drop:
1617 kfree_skb(skb); 1895 kfree_skb(skb);
1618 } 1896 }
@@ -1663,10 +1941,14 @@ int ipmr_get_route(struct net *net,
1663 struct sk_buff *skb, struct rtmsg *rtm, int nowait) 1941 struct sk_buff *skb, struct rtmsg *rtm, int nowait)
1664{ 1942{
1665 int err; 1943 int err;
1666 struct mr_table *mrt = net->ipv4.mrt; 1944 struct mr_table *mrt;
1667 struct mfc_cache *cache; 1945 struct mfc_cache *cache;
1668 struct rtable *rt = skb_rtable(skb); 1946 struct rtable *rt = skb_rtable(skb);
1669 1947
1948 mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
1949 if (mrt == NULL)
1950 return -ENOENT;
1951
1670 read_lock(&mrt_lock); 1952 read_lock(&mrt_lock);
1671 cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst); 1953 cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst);
1672 1954
@@ -1717,6 +1999,7 @@ int ipmr_get_route(struct net *net,
1717 */ 1999 */
1718struct ipmr_vif_iter { 2000struct ipmr_vif_iter {
1719 struct seq_net_private p; 2001 struct seq_net_private p;
2002 struct mr_table *mrt;
1720 int ct; 2003 int ct;
1721}; 2004};
1722 2005
@@ -1724,7 +2007,7 @@ static struct vif_device *ipmr_vif_seq_idx(struct net *net,
1724 struct ipmr_vif_iter *iter, 2007 struct ipmr_vif_iter *iter,
1725 loff_t pos) 2008 loff_t pos)
1726{ 2009{
1727 struct mr_table *mrt = net->ipv4.mrt; 2010 struct mr_table *mrt = iter->mrt;
1728 2011
1729 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) { 2012 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) {
1730 if (!VIF_EXISTS(mrt, iter->ct)) 2013 if (!VIF_EXISTS(mrt, iter->ct))
@@ -1738,7 +2021,15 @@ static struct vif_device *ipmr_vif_seq_idx(struct net *net,
1738static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) 2021static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
1739 __acquires(mrt_lock) 2022 __acquires(mrt_lock)
1740{ 2023{
2024 struct ipmr_vif_iter *iter = seq->private;
1741 struct net *net = seq_file_net(seq); 2025 struct net *net = seq_file_net(seq);
2026 struct mr_table *mrt;
2027
2028 mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
2029 if (mrt == NULL)
2030 return ERR_PTR(-ENOENT);
2031
2032 iter->mrt = mrt;
1742 2033
1743 read_lock(&mrt_lock); 2034 read_lock(&mrt_lock);
1744 return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1) 2035 return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1)
@@ -1749,7 +2040,7 @@ static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1749{ 2040{
1750 struct ipmr_vif_iter *iter = seq->private; 2041 struct ipmr_vif_iter *iter = seq->private;
1751 struct net *net = seq_file_net(seq); 2042 struct net *net = seq_file_net(seq);
1752 struct mr_table *mrt = net->ipv4.mrt; 2043 struct mr_table *mrt = iter->mrt;
1753 2044
1754 ++*pos; 2045 ++*pos;
1755 if (v == SEQ_START_TOKEN) 2046 if (v == SEQ_START_TOKEN)
@@ -1771,8 +2062,8 @@ static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
1771 2062
1772static int ipmr_vif_seq_show(struct seq_file *seq, void *v) 2063static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
1773{ 2064{
1774 struct net *net = seq_file_net(seq); 2065 struct ipmr_vif_iter *iter = seq->private;
1775 struct mr_table *mrt = net->ipv4.mrt; 2066 struct mr_table *mrt = iter->mrt;
1776 2067
1777 if (v == SEQ_START_TOKEN) { 2068 if (v == SEQ_START_TOKEN) {
1778 seq_puts(seq, 2069 seq_puts(seq,
@@ -1814,6 +2105,7 @@ static const struct file_operations ipmr_vif_fops = {
1814 2105
1815struct ipmr_mfc_iter { 2106struct ipmr_mfc_iter {
1816 struct seq_net_private p; 2107 struct seq_net_private p;
2108 struct mr_table *mrt;
1817 struct list_head *cache; 2109 struct list_head *cache;
1818 int ct; 2110 int ct;
1819}; 2111};
@@ -1822,7 +2114,7 @@ struct ipmr_mfc_iter {
1822static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net, 2114static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
1823 struct ipmr_mfc_iter *it, loff_t pos) 2115 struct ipmr_mfc_iter *it, loff_t pos)
1824{ 2116{
1825 struct mr_table *mrt = net->ipv4.mrt; 2117 struct mr_table *mrt = it->mrt;
1826 struct mfc_cache *mfc; 2118 struct mfc_cache *mfc;
1827 2119
1828 read_lock(&mrt_lock); 2120 read_lock(&mrt_lock);
@@ -1850,7 +2142,13 @@ static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
1850{ 2142{
1851 struct ipmr_mfc_iter *it = seq->private; 2143 struct ipmr_mfc_iter *it = seq->private;
1852 struct net *net = seq_file_net(seq); 2144 struct net *net = seq_file_net(seq);
2145 struct mr_table *mrt;
2146
2147 mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
2148 if (mrt == NULL)
2149 return ERR_PTR(-ENOENT);
1853 2150
2151 it->mrt = mrt;
1854 it->cache = NULL; 2152 it->cache = NULL;
1855 it->ct = 0; 2153 it->ct = 0;
1856 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1) 2154 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
@@ -1862,7 +2160,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1862 struct mfc_cache *mfc = v; 2160 struct mfc_cache *mfc = v;
1863 struct ipmr_mfc_iter *it = seq->private; 2161 struct ipmr_mfc_iter *it = seq->private;
1864 struct net *net = seq_file_net(seq); 2162 struct net *net = seq_file_net(seq);
1865 struct mr_table *mrt = net->ipv4.mrt; 2163 struct mr_table *mrt = it->mrt;
1866 2164
1867 ++*pos; 2165 ++*pos;
1868 2166
@@ -1903,8 +2201,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1903static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) 2201static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
1904{ 2202{
1905 struct ipmr_mfc_iter *it = seq->private; 2203 struct ipmr_mfc_iter *it = seq->private;
1906 struct net *net = seq_file_net(seq); 2204 struct mr_table *mrt = it->mrt;
1907 struct mr_table *mrt = net->ipv4.mrt;
1908 2205
1909 if (it->cache == &mrt->mfc_unres_queue) 2206 if (it->cache == &mrt->mfc_unres_queue)
1910 spin_unlock_bh(&mfc_unres_lock); 2207 spin_unlock_bh(&mfc_unres_lock);
@@ -1915,8 +2212,6 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
1915static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 2212static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1916{ 2213{
1917 int n; 2214 int n;
1918 struct net *net = seq_file_net(seq);
1919 struct mr_table *mrt = net->ipv4.mrt;
1920 2215
1921 if (v == SEQ_START_TOKEN) { 2216 if (v == SEQ_START_TOKEN) {
1922 seq_puts(seq, 2217 seq_puts(seq,
@@ -1924,6 +2219,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1924 } else { 2219 } else {
1925 const struct mfc_cache *mfc = v; 2220 const struct mfc_cache *mfc = v;
1926 const struct ipmr_mfc_iter *it = seq->private; 2221 const struct ipmr_mfc_iter *it = seq->private;
2222 const struct mr_table *mrt = it->mrt;
1927 2223
1928 seq_printf(seq, "%08lX %08lX %-3hd", 2224 seq_printf(seq, "%08lX %08lX %-3hd",
1929 (unsigned long) mfc->mfc_mcastgrp, 2225 (unsigned long) mfc->mfc_mcastgrp,
@@ -1989,28 +2285,11 @@ static const struct net_protocol pim_protocol = {
1989 */ 2285 */
1990static int __net_init ipmr_net_init(struct net *net) 2286static int __net_init ipmr_net_init(struct net *net)
1991{ 2287{
1992 struct mr_table *mrt; 2288 int err;
1993 unsigned int i;
1994 int err = 0;
1995 2289
1996 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL); 2290 err = ipmr_rules_init(net);
1997 if (mrt == NULL) { 2291 if (err < 0)
1998 err = -ENOMEM;
1999 goto fail; 2292 goto fail;
2000 }
2001
2002 /* Forwarding cache */
2003 for (i = 0; i < MFC_LINES; i++)
2004 INIT_LIST_HEAD(&mrt->mfc_cache_array[i]);
2005
2006 INIT_LIST_HEAD(&mrt->mfc_unres_queue);
2007
2008 setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process,
2009 (unsigned long)net);
2010
2011#ifdef CONFIG_IP_PIMSM
2012 mrt->mroute_reg_vif_num = -1;
2013#endif
2014 2293
2015#ifdef CONFIG_PROC_FS 2294#ifdef CONFIG_PROC_FS
2016 err = -ENOMEM; 2295 err = -ENOMEM;
@@ -2019,15 +2298,13 @@ static int __net_init ipmr_net_init(struct net *net)
2019 if (!proc_net_fops_create(net, "ip_mr_cache", 0, &ipmr_mfc_fops)) 2298 if (!proc_net_fops_create(net, "ip_mr_cache", 0, &ipmr_mfc_fops))
2020 goto proc_cache_fail; 2299 goto proc_cache_fail;
2021#endif 2300#endif
2022
2023 net->ipv4.mrt = mrt;
2024 return 0; 2301 return 0;
2025 2302
2026#ifdef CONFIG_PROC_FS 2303#ifdef CONFIG_PROC_FS
2027proc_cache_fail: 2304proc_cache_fail:
2028 proc_net_remove(net, "ip_mr_vif"); 2305 proc_net_remove(net, "ip_mr_vif");
2029proc_vif_fail: 2306proc_vif_fail:
2030 kfree(mrt); 2307 ipmr_rules_exit(net);
2031#endif 2308#endif
2032fail: 2309fail:
2033 return err; 2310 return err;
@@ -2039,7 +2316,7 @@ static void __net_exit ipmr_net_exit(struct net *net)
2039 proc_net_remove(net, "ip_mr_cache"); 2316 proc_net_remove(net, "ip_mr_cache");
2040 proc_net_remove(net, "ip_mr_vif"); 2317 proc_net_remove(net, "ip_mr_vif");
2041#endif 2318#endif
2042 kfree(net->ipv4.mrt); 2319 ipmr_rules_exit(net);
2043} 2320}
2044 2321
2045static struct pernet_operations ipmr_net_ops = { 2322static struct pernet_operations ipmr_net_ops = {