|
@@ -90,19 +90,21 @@ static struct timer_list ipmr_expire_timer;
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
|
|
struct ipmr_mfc_iter {
|
|
struct ipmr_mfc_iter {
|
|
|
|
+ struct seq_net_private p;
|
|
struct mfc6_cache **cache;
|
|
struct mfc6_cache **cache;
|
|
int ct;
|
|
int ct;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
-static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
|
|
|
|
|
|
+static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
|
|
|
|
+ struct ipmr_mfc_iter *it, loff_t pos)
|
|
{
|
|
{
|
|
struct mfc6_cache *mfc;
|
|
struct mfc6_cache *mfc;
|
|
|
|
|
|
- it->cache = init_net.ipv6.mfc6_cache_array;
|
|
|
|
|
|
+ it->cache = net->ipv6.mfc6_cache_array;
|
|
read_lock(&mrt_lock);
|
|
read_lock(&mrt_lock);
|
|
for (it->ct = 0; it->ct < MFC6_LINES; it->ct++)
|
|
for (it->ct = 0; it->ct < MFC6_LINES; it->ct++)
|
|
- for (mfc = init_net.ipv6.mfc6_cache_array[it->ct];
|
|
|
|
|
|
+ for (mfc = net->ipv6.mfc6_cache_array[it->ct];
|
|
mfc; mfc = mfc->next)
|
|
mfc; mfc = mfc->next)
|
|
if (pos-- == 0)
|
|
if (pos-- == 0)
|
|
return mfc;
|
|
return mfc;
|
|
@@ -111,7 +113,8 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
|
|
it->cache = &mfc_unres_queue;
|
|
it->cache = &mfc_unres_queue;
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
for (mfc = mfc_unres_queue; mfc; mfc = mfc->next)
|
|
for (mfc = mfc_unres_queue; mfc; mfc = mfc->next)
|
|
- if (pos-- == 0)
|
|
|
|
|
|
+ if (net_eq(mfc6_net(mfc), net) &&
|
|
|
|
+ pos-- == 0)
|
|
return mfc;
|
|
return mfc;
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
|
|
|
|
@@ -127,17 +130,19 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
|
|
*/
|
|
*/
|
|
|
|
|
|
struct ipmr_vif_iter {
|
|
struct ipmr_vif_iter {
|
|
|
|
+ struct seq_net_private p;
|
|
int ct;
|
|
int ct;
|
|
};
|
|
};
|
|
|
|
|
|
-static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter,
|
|
|
|
|
|
+static struct mif_device *ip6mr_vif_seq_idx(struct net *net,
|
|
|
|
+ struct ipmr_vif_iter *iter,
|
|
loff_t pos)
|
|
loff_t pos)
|
|
{
|
|
{
|
|
- for (iter->ct = 0; iter->ct < init_net.ipv6.maxvif; ++iter->ct) {
|
|
|
|
- if (!MIF_EXISTS(&init_net, iter->ct))
|
|
|
|
|
|
+ for (iter->ct = 0; iter->ct < net->ipv6.maxvif; ++iter->ct) {
|
|
|
|
+ if (!MIF_EXISTS(net, iter->ct))
|
|
continue;
|
|
continue;
|
|
if (pos-- == 0)
|
|
if (pos-- == 0)
|
|
- return &init_net.ipv6.vif6_table[iter->ct];
|
|
|
|
|
|
+ return &net->ipv6.vif6_table[iter->ct];
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -145,23 +150,26 @@ static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter,
|
|
static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
|
|
static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
|
|
__acquires(mrt_lock)
|
|
__acquires(mrt_lock)
|
|
{
|
|
{
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
+
|
|
read_lock(&mrt_lock);
|
|
read_lock(&mrt_lock);
|
|
- return (*pos ? ip6mr_vif_seq_idx(seq->private, *pos - 1)
|
|
|
|
- : SEQ_START_TOKEN);
|
|
|
|
|
|
+ return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1)
|
|
|
|
+ : SEQ_START_TOKEN;
|
|
}
|
|
}
|
|
|
|
|
|
static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
{
|
|
{
|
|
struct ipmr_vif_iter *iter = seq->private;
|
|
struct ipmr_vif_iter *iter = seq->private;
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
|
|
++*pos;
|
|
++*pos;
|
|
if (v == SEQ_START_TOKEN)
|
|
if (v == SEQ_START_TOKEN)
|
|
- return ip6mr_vif_seq_idx(iter, 0);
|
|
|
|
|
|
+ return ip6mr_vif_seq_idx(net, iter, 0);
|
|
|
|
|
|
- while (++iter->ct < init_net.ipv6.maxvif) {
|
|
|
|
- if (!MIF_EXISTS(&init_net, iter->ct))
|
|
|
|
|
|
+ while (++iter->ct < net->ipv6.maxvif) {
|
|
|
|
+ if (!MIF_EXISTS(net, iter->ct))
|
|
continue;
|
|
continue;
|
|
- return &init_net.ipv6.vif6_table[iter->ct];
|
|
|
|
|
|
+ return &net->ipv6.vif6_table[iter->ct];
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -174,6 +182,8 @@ static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
|
|
|
|
|
|
static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
|
|
static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
+
|
|
if (v == SEQ_START_TOKEN) {
|
|
if (v == SEQ_START_TOKEN) {
|
|
seq_puts(seq,
|
|
seq_puts(seq,
|
|
"Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
|
|
"Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
|
|
@@ -183,7 +193,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
|
|
|
|
|
|
seq_printf(seq,
|
|
seq_printf(seq,
|
|
"%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
|
|
"%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
|
|
- vif - init_net.ipv6.vif6_table,
|
|
|
|
|
|
+ vif - net->ipv6.vif6_table,
|
|
name, vif->bytes_in, vif->pkt_in,
|
|
name, vif->bytes_in, vif->pkt_in,
|
|
vif->bytes_out, vif->pkt_out,
|
|
vif->bytes_out, vif->pkt_out,
|
|
vif->flags);
|
|
vif->flags);
|
|
@@ -200,8 +210,8 @@ static struct seq_operations ip6mr_vif_seq_ops = {
|
|
|
|
|
|
static int ip6mr_vif_open(struct inode *inode, struct file *file)
|
|
static int ip6mr_vif_open(struct inode *inode, struct file *file)
|
|
{
|
|
{
|
|
- return seq_open_private(file, &ip6mr_vif_seq_ops,
|
|
|
|
- sizeof(struct ipmr_vif_iter));
|
|
|
|
|
|
+ return seq_open_net(inode, file, &ip6mr_vif_seq_ops,
|
|
|
|
+ sizeof(struct ipmr_vif_iter));
|
|
}
|
|
}
|
|
|
|
|
|
static struct file_operations ip6mr_vif_fops = {
|
|
static struct file_operations ip6mr_vif_fops = {
|
|
@@ -209,24 +219,27 @@ static struct file_operations ip6mr_vif_fops = {
|
|
.open = ip6mr_vif_open,
|
|
.open = ip6mr_vif_open,
|
|
.read = seq_read,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.llseek = seq_lseek,
|
|
- .release = seq_release_private,
|
|
|
|
|
|
+ .release = seq_release_net,
|
|
};
|
|
};
|
|
|
|
|
|
static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
|
|
static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
|
|
{
|
|
{
|
|
- return (*pos ? ipmr_mfc_seq_idx(seq->private, *pos - 1)
|
|
|
|
- : SEQ_START_TOKEN);
|
|
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
+
|
|
|
|
+ return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
|
|
|
|
+ : SEQ_START_TOKEN;
|
|
}
|
|
}
|
|
|
|
|
|
static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
{
|
|
{
|
|
struct mfc6_cache *mfc = v;
|
|
struct mfc6_cache *mfc = v;
|
|
struct ipmr_mfc_iter *it = seq->private;
|
|
struct ipmr_mfc_iter *it = seq->private;
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
|
|
++*pos;
|
|
++*pos;
|
|
|
|
|
|
if (v == SEQ_START_TOKEN)
|
|
if (v == SEQ_START_TOKEN)
|
|
- return ipmr_mfc_seq_idx(seq->private, 0);
|
|
|
|
|
|
+ return ipmr_mfc_seq_idx(net, seq->private, 0);
|
|
|
|
|
|
if (mfc->next)
|
|
if (mfc->next)
|
|
return mfc->next;
|
|
return mfc->next;
|
|
@@ -234,10 +247,10 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
if (it->cache == &mfc_unres_queue)
|
|
if (it->cache == &mfc_unres_queue)
|
|
goto end_of_list;
|
|
goto end_of_list;
|
|
|
|
|
|
- BUG_ON(it->cache != init_net.ipv6.mfc6_cache_array);
|
|
|
|
|
|
+ BUG_ON(it->cache != net->ipv6.mfc6_cache_array);
|
|
|
|
|
|
while (++it->ct < MFC6_LINES) {
|
|
while (++it->ct < MFC6_LINES) {
|
|
- mfc = init_net.ipv6.mfc6_cache_array[it->ct];
|
|
|
|
|
|
+ mfc = net->ipv6.mfc6_cache_array[it->ct];
|
|
if (mfc)
|
|
if (mfc)
|
|
return mfc;
|
|
return mfc;
|
|
}
|
|
}
|
|
@@ -262,16 +275,18 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
|
|
static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
struct ipmr_mfc_iter *it = seq->private;
|
|
struct ipmr_mfc_iter *it = seq->private;
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
|
|
if (it->cache == &mfc_unres_queue)
|
|
if (it->cache == &mfc_unres_queue)
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
- else if (it->cache == init_net.ipv6.mfc6_cache_array)
|
|
|
|
|
|
+ else if (it->cache == net->ipv6.mfc6_cache_array)
|
|
read_unlock(&mrt_lock);
|
|
read_unlock(&mrt_lock);
|
|
}
|
|
}
|
|
|
|
|
|
static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
|
|
static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
int n;
|
|
int n;
|
|
|
|
+ struct net *net = seq_file_net(seq);
|
|
|
|
|
|
if (v == SEQ_START_TOKEN) {
|
|
if (v == SEQ_START_TOKEN) {
|
|
seq_puts(seq,
|
|
seq_puts(seq,
|
|
@@ -293,7 +308,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
|
|
mfc->mfc_un.res.wrong_if);
|
|
mfc->mfc_un.res.wrong_if);
|
|
for (n = mfc->mfc_un.res.minvif;
|
|
for (n = mfc->mfc_un.res.minvif;
|
|
n < mfc->mfc_un.res.maxvif; n++) {
|
|
n < mfc->mfc_un.res.maxvif; n++) {
|
|
- if (MIF_EXISTS(&init_net, n) &&
|
|
|
|
|
|
+ if (MIF_EXISTS(net, n) &&
|
|
mfc->mfc_un.res.ttls[n] < 255)
|
|
mfc->mfc_un.res.ttls[n] < 255)
|
|
seq_printf(seq,
|
|
seq_printf(seq,
|
|
" %2d:%-3d",
|
|
" %2d:%-3d",
|
|
@@ -319,8 +334,8 @@ static struct seq_operations ipmr_mfc_seq_ops = {
|
|
|
|
|
|
static int ipmr_mfc_open(struct inode *inode, struct file *file)
|
|
static int ipmr_mfc_open(struct inode *inode, struct file *file)
|
|
{
|
|
{
|
|
- return seq_open_private(file, &ipmr_mfc_seq_ops,
|
|
|
|
- sizeof(struct ipmr_mfc_iter));
|
|
|
|
|
|
+ return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
|
|
|
|
+ sizeof(struct ipmr_mfc_iter));
|
|
}
|
|
}
|
|
|
|
|
|
static struct file_operations ip6mr_mfc_fops = {
|
|
static struct file_operations ip6mr_mfc_fops = {
|
|
@@ -328,7 +343,7 @@ static struct file_operations ip6mr_mfc_fops = {
|
|
.open = ipmr_mfc_open,
|
|
.open = ipmr_mfc_open,
|
|
.read = seq_read,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.llseek = seq_lseek,
|
|
- .release = seq_release_private,
|
|
|
|
|
|
+ .release = seq_release_net,
|
|
};
|
|
};
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -983,8 +998,22 @@ static int __net_init ip6mr_net_init(struct net *net)
|
|
#ifdef CONFIG_IPV6_PIMSM_V2
|
|
#ifdef CONFIG_IPV6_PIMSM_V2
|
|
net->ipv6.mroute_reg_vif_num = -1;
|
|
net->ipv6.mroute_reg_vif_num = -1;
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
|
+ err = -ENOMEM;
|
|
|
|
+ if (!proc_net_fops_create(net, "ip6_mr_vif", 0, &ip6mr_vif_fops))
|
|
|
|
+ goto proc_vif_fail;
|
|
|
|
+ if (!proc_net_fops_create(net, "ip6_mr_cache", 0, &ip6mr_mfc_fops))
|
|
|
|
+ goto proc_cache_fail;
|
|
|
|
+#endif
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
|
+proc_cache_fail:
|
|
|
|
+ proc_net_remove(net, "ip6_mr_vif");
|
|
|
|
+proc_vif_fail:
|
|
|
|
+ kfree(net->ipv6.mfc6_cache_array);
|
|
|
|
+#endif
|
|
fail_mfc6_cache:
|
|
fail_mfc6_cache:
|
|
kfree(net->ipv6.vif6_table);
|
|
kfree(net->ipv6.vif6_table);
|
|
fail:
|
|
fail:
|
|
@@ -993,6 +1022,10 @@ fail:
|
|
|
|
|
|
static void __net_exit ip6mr_net_exit(struct net *net)
|
|
static void __net_exit ip6mr_net_exit(struct net *net)
|
|
{
|
|
{
|
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
|
+ proc_net_remove(net, "ip6_mr_cache");
|
|
|
|
+ proc_net_remove(net, "ip6_mr_vif");
|
|
|
|
+#endif
|
|
kfree(net->ipv6.mfc6_cache_array);
|
|
kfree(net->ipv6.mfc6_cache_array);
|
|
kfree(net->ipv6.vif6_table);
|
|
kfree(net->ipv6.vif6_table);
|
|
}
|
|
}
|
|
@@ -1021,21 +1054,7 @@ int __init ip6_mr_init(void)
|
|
err = register_netdevice_notifier(&ip6_mr_notifier);
|
|
err = register_netdevice_notifier(&ip6_mr_notifier);
|
|
if (err)
|
|
if (err)
|
|
goto reg_notif_fail;
|
|
goto reg_notif_fail;
|
|
-#ifdef CONFIG_PROC_FS
|
|
|
|
- err = -ENOMEM;
|
|
|
|
- if (!proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops))
|
|
|
|
- goto proc_vif_fail;
|
|
|
|
- if (!proc_net_fops_create(&init_net, "ip6_mr_cache",
|
|
|
|
- 0, &ip6mr_mfc_fops))
|
|
|
|
- goto proc_cache_fail;
|
|
|
|
-#endif
|
|
|
|
return 0;
|
|
return 0;
|
|
-#ifdef CONFIG_PROC_FS
|
|
|
|
-proc_cache_fail:
|
|
|
|
- proc_net_remove(&init_net, "ip6_mr_vif");
|
|
|
|
-proc_vif_fail:
|
|
|
|
- unregister_netdevice_notifier(&ip6_mr_notifier);
|
|
|
|
-#endif
|
|
|
|
reg_notif_fail:
|
|
reg_notif_fail:
|
|
del_timer(&ipmr_expire_timer);
|
|
del_timer(&ipmr_expire_timer);
|
|
unregister_pernet_subsys(&ip6mr_net_ops);
|
|
unregister_pernet_subsys(&ip6mr_net_ops);
|
|
@@ -1046,10 +1065,6 @@ reg_pernet_fail:
|
|
|
|
|
|
void ip6_mr_cleanup(void)
|
|
void ip6_mr_cleanup(void)
|
|
{
|
|
{
|
|
-#ifdef CONFIG_PROC_FS
|
|
|
|
- proc_net_remove(&init_net, "ip6_mr_cache");
|
|
|
|
- proc_net_remove(&init_net, "ip6_mr_vif");
|
|
|
|
-#endif
|
|
|
|
unregister_netdevice_notifier(&ip6_mr_notifier);
|
|
unregister_netdevice_notifier(&ip6_mr_notifier);
|
|
del_timer(&ipmr_expire_timer);
|
|
del_timer(&ipmr_expire_timer);
|
|
unregister_pernet_subsys(&ip6mr_net_ops);
|
|
unregister_pernet_subsys(&ip6mr_net_ops);
|