#include <net/addrconf.h>
#include <linux/netfilter_ipv6.h>
-struct sock *mroute6_socket;
-
-
/* Big lock, protecting vif table, mrt cache and mroute socket state.
Note that the changes are semaphored via rtnl_lock.
*/
* Multicast router control variables
*/
-static struct mif_device vif6_table[MAXMIFS]; /* Devices */
-static int maxvif;
-
-#define MIF_EXISTS(idx) (vif6_table[idx].dev != NULL)
+#define MIF_EXISTS(_net, _idx) ((_net)->ipv6.vif6_table[_idx].dev != NULL)
static int mroute_do_assert; /* Set in PIM assert */
#ifdef CONFIG_IPV6_PIMSM_V2
#define mroute_do_pim 0
#endif
-static struct mfc6_cache *mfc6_cache_array[MFC6_LINES]; /* Forwarding cache */
-
static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */
-static atomic_t cache_resolve_queue_len; /* Size of unresolved */
/* Special spinlock for queue of unresolved entries */
static DEFINE_SPINLOCK(mfc_unres_lock);
{
struct mfc6_cache *mfc;
- it->cache = mfc6_cache_array;
+ it->cache = init_net.ipv6.mfc6_cache_array;
read_lock(&mrt_lock);
- for (it->ct = 0; it->ct < ARRAY_SIZE(mfc6_cache_array); it->ct++)
- for (mfc = mfc6_cache_array[it->ct]; mfc; mfc = mfc->next)
+ for (it->ct = 0; it->ct < MFC6_LINES; it->ct++)
+ for (mfc = init_net.ipv6.mfc6_cache_array[it->ct];
+ mfc; mfc = mfc->next)
if (pos-- == 0)
return mfc;
read_unlock(&mrt_lock);
static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter,
loff_t pos)
{
- for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) {
- if (!MIF_EXISTS(iter->ct))
+ for (iter->ct = 0; iter->ct < init_net.ipv6.maxvif; ++iter->ct) {
+ if (!MIF_EXISTS(&init_net, iter->ct))
continue;
if (pos-- == 0)
- return &vif6_table[iter->ct];
+ return &init_net.ipv6.vif6_table[iter->ct];
}
return NULL;
}
if (v == SEQ_START_TOKEN)
return ip6mr_vif_seq_idx(iter, 0);
- while (++iter->ct < maxvif) {
- if (!MIF_EXISTS(iter->ct))
+ while (++iter->ct < init_net.ipv6.maxvif) {
+ if (!MIF_EXISTS(&init_net, iter->ct))
continue;
- return &vif6_table[iter->ct];
+ return &init_net.ipv6.vif6_table[iter->ct];
}
return NULL;
}
seq_printf(seq,
"%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
- vif - vif6_table,
+ vif - init_net.ipv6.vif6_table,
name, vif->bytes_in, vif->pkt_in,
vif->bytes_out, vif->pkt_out,
vif->flags);
.open = ip6mr_vif_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_private,
};
static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
if (it->cache == &mfc_unres_queue)
goto end_of_list;
- BUG_ON(it->cache != mfc6_cache_array);
+ BUG_ON(it->cache != init_net.ipv6.mfc6_cache_array);
- while (++it->ct < ARRAY_SIZE(mfc6_cache_array)) {
- mfc = mfc6_cache_array[it->ct];
+ while (++it->ct < MFC6_LINES) {
+ mfc = init_net.ipv6.mfc6_cache_array[it->ct];
if (mfc)
return mfc;
}
if (it->cache == &mfc_unres_queue)
spin_unlock_bh(&mfc_unres_lock);
- else if (it->cache == mfc6_cache_array)
+ else if (it->cache == init_net.ipv6.mfc6_cache_array)
read_unlock(&mrt_lock);
}
const struct mfc6_cache *mfc = v;
const struct ipmr_mfc_iter *it = seq->private;
- seq_printf(seq,
- NIP6_FMT " " NIP6_FMT " %-3d %8ld %8ld %8ld",
- NIP6(mfc->mf6c_mcastgrp), NIP6(mfc->mf6c_origin),
- mfc->mf6c_parent,
- mfc->mfc_un.res.pkt,
- mfc->mfc_un.res.bytes,
- mfc->mfc_un.res.wrong_if);
+ seq_printf(seq, "%pI6 %pI6 %-3hd",
+ &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
+ mfc->mf6c_parent);
if (it->cache != &mfc_unres_queue) {
+ seq_printf(seq, " %8lu %8lu %8lu",
+ mfc->mfc_un.res.pkt,
+ mfc->mfc_un.res.bytes,
+ mfc->mfc_un.res.wrong_if);
for (n = mfc->mfc_un.res.minvif;
n < mfc->mfc_un.res.maxvif; n++) {
- if (MIF_EXISTS(n) &&
+ if (MIF_EXISTS(&init_net, n) &&
mfc->mfc_un.res.ttls[n] < 255)
seq_printf(seq,
" %2d:%-3d",
n, mfc->mfc_un.res.ttls[n]);
}
+ } else {
+ /* unresolved mfc_caches don't contain
+ * pkt, bytes and wrong_if values
+ */
+ seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul);
}
seq_putc(seq, '\n');
}
.open = ipmr_mfc_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_private,
};
#endif
read_lock(&mrt_lock);
if (reg_vif_num >= 0)
- reg_dev = vif6_table[reg_vif_num].dev;
+ reg_dev = init_net.ipv6.vif6_table[reg_vif_num].dev;
if (reg_dev)
dev_hold(reg_dev);
read_unlock(&mrt_lock);
return 0;
}
+static const struct net_device_ops reg_vif_netdev_ops = {
+ .ndo_start_xmit = reg_vif_xmit,
+};
+
static void reg_vif_setup(struct net_device *dev)
{
dev->type = ARPHRD_PIMREG;
dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
dev->flags = IFF_NOARP;
- dev->hard_start_xmit = reg_vif_xmit;
+ dev->netdev_ops = ®_vif_netdev_ops;
dev->destructor = free_netdev;
}
{
struct mif_device *v;
struct net_device *dev;
- if (vifi < 0 || vifi >= maxvif)
+ if (vifi < 0 || vifi >= init_net.ipv6.maxvif)
return -EADDRNOTAVAIL;
- v = &vif6_table[vifi];
+ v = &init_net.ipv6.vif6_table[vifi];
write_lock_bh(&mrt_lock);
dev = v->dev;
reg_vif_num = -1;
#endif
- if (vifi + 1 == maxvif) {
+ if (vifi + 1 == init_net.ipv6.maxvif) {
int tmp;
for (tmp = vifi - 1; tmp >= 0; tmp--) {
- if (MIF_EXISTS(tmp))
+ if (MIF_EXISTS(&init_net, tmp))
break;
}
- maxvif = tmp + 1;
+ init_net.ipv6.maxvif = tmp + 1;
}
write_unlock_bh(&mrt_lock);
return 0;
}
+static inline void ip6mr_cache_free(struct mfc6_cache *c)
+{
+ release_net(mfc6_net(c));
+ kmem_cache_free(mrt_cachep, c);
+}
+
/* Destroy an unresolved cache entry, killing queued skbs
and reporting error to netlink readers.
*/
{
struct sk_buff *skb;
- atomic_dec(&cache_resolve_queue_len);
+ atomic_dec(&init_net.ipv6.cache_resolve_queue_len);
while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) {
if (ipv6_hdr(skb)->version == 0) {
kfree_skb(skb);
}
- kmem_cache_free(mrt_cachep, c);
+ ip6mr_cache_free(c);
}
ip6mr_destroy_unres(c);
}
- if (atomic_read(&cache_resolve_queue_len))
+ if (mfc_unres_queue != NULL)
mod_timer(&ipmr_expire_timer, jiffies + expires);
}
return;
}
- if (atomic_read(&cache_resolve_queue_len))
+ if (mfc_unres_queue != NULL)
ipmr_do_expire_process(dummy);
spin_unlock(&mfc_unres_lock);
cache->mfc_un.res.maxvif = 0;
memset(cache->mfc_un.res.ttls, 255, MAXMIFS);
- for (vifi = 0; vifi < maxvif; vifi++) {
- if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) {
+ for (vifi = 0; vifi < init_net.ipv6.maxvif; vifi++) {
+ if (MIF_EXISTS(&init_net, vifi) &&
+ ttls[vifi] && ttls[vifi] < 255) {
cache->mfc_un.res.ttls[vifi] = ttls[vifi];
if (cache->mfc_un.res.minvif > vifi)
cache->mfc_un.res.minvif = vifi;
static int mif6_add(struct mif6ctl *vifc, int mrtsock)
{
int vifi = vifc->mif6c_mifi;
- struct mif_device *v = &vif6_table[vifi];
+ struct mif_device *v = &init_net.ipv6.vif6_table[vifi];
struct net_device *dev;
int err;
/* Is vif busy ? */
- if (MIF_EXISTS(vifi))
+ if (MIF_EXISTS(&init_net, vifi))
return -EADDRINUSE;
switch (vifc->mif6c_flags) {
if (v->flags & MIFF_REGISTER)
reg_vif_num = vifi;
#endif
- if (vifi + 1 > maxvif)
- maxvif = vifi + 1;
+ if (vifi + 1 > init_net.ipv6.maxvif)
+ init_net.ipv6.maxvif = vifi + 1;
write_unlock_bh(&mrt_lock);
return 0;
}
int line = MFC6_HASH(mcastgrp, origin);
struct mfc6_cache *c;
- for (c = mfc6_cache_array[line]; c; c = c->next) {
+ for (c = init_net.ipv6.mfc6_cache_array[line]; c; c = c->next) {
if (ipv6_addr_equal(&c->mf6c_origin, origin) &&
ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp))
break;
/*
* Allocate a multicast cache entry
*/
-static struct mfc6_cache *ip6mr_cache_alloc(void)
+static struct mfc6_cache *ip6mr_cache_alloc(struct net *net)
{
- struct mfc6_cache *c = kmem_cache_alloc(mrt_cachep, GFP_KERNEL);
+ struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
if (c == NULL)
return NULL;
- memset(c, 0, sizeof(*c));
c->mfc_un.res.minvif = MAXMIFS;
+ mfc6_net_set(c, net);
return c;
}
-static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
+static struct mfc6_cache *ip6mr_cache_alloc_unres(struct net *net)
{
- struct mfc6_cache *c = kmem_cache_alloc(mrt_cachep, GFP_ATOMIC);
+ struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
if (c == NULL)
return NULL;
- memset(c, 0, sizeof(*c));
skb_queue_head_init(&c->mfc_un.unres.unresolved);
c->mfc_un.unres.expires = jiffies + 10 * HZ;
+ mfc6_net_set(c, net);
return c;
}
skb_pull(skb, sizeof(struct ipv6hdr));
}
- if (mroute6_socket == NULL) {
+ if (init_net.ipv6.mroute6_sk == NULL) {
kfree_skb(skb);
return -EINVAL;
}
/*
* Deliver to user space multicast routing algorithms
*/
- if ((ret = sock_queue_rcv_skb(mroute6_socket, skb)) < 0) {
+ ret = sock_queue_rcv_skb(init_net.ipv6.mroute6_sk, skb);
+ if (ret < 0) {
if (net_ratelimit())
printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n");
kfree_skb(skb);
spin_lock_bh(&mfc_unres_lock);
for (c = mfc_unres_queue; c; c = c->next) {
- if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
+ if (net_eq(mfc6_net(c), &init_net) &&
+ ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr))
break;
}
* Create a new entry if allowable
*/
- if (atomic_read(&cache_resolve_queue_len) >= 10 ||
- (c = ip6mr_cache_alloc_unres()) == NULL) {
+ if (atomic_read(&init_net.ipv6.cache_resolve_queue_len) >= 10 ||
+ (c = ip6mr_cache_alloc_unres(&init_net)) == NULL) {
spin_unlock_bh(&mfc_unres_lock);
kfree_skb(skb);
*/
spin_unlock_bh(&mfc_unres_lock);
- kmem_cache_free(mrt_cachep, c);
+ ip6mr_cache_free(c);
kfree_skb(skb);
return err;
}
- atomic_inc(&cache_resolve_queue_len);
+ atomic_inc(&init_net.ipv6.cache_resolve_queue_len);
c->next = mfc_unres_queue;
mfc_unres_queue = c;
line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
- for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) {
+ for (cp = &init_net.ipv6.mfc6_cache_array[line];
+ (c = *cp) != NULL; cp = &c->next) {
if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
write_lock_bh(&mrt_lock);
*cp = c->next;
write_unlock_bh(&mrt_lock);
- kmem_cache_free(mrt_cachep, c);
+ ip6mr_cache_free(c);
return 0;
}
}
if (event != NETDEV_UNREGISTER)
return NOTIFY_DONE;
- v = &vif6_table[0];
- for (ct = 0; ct < maxvif; ct++, v++) {
+ v = &init_net.ipv6.vif6_table[0];
+ for (ct = 0; ct < init_net.ipv6.maxvif; ct++, v++) {
if (v->dev == dev)
mif6_delete(ct);
}
* Setup for IP multicast routing
*/
+static int __net_init ip6mr_net_init(struct net *net)
+{
+ int err = 0;
+
+ net->ipv6.vif6_table = kcalloc(MAXMIFS, sizeof(struct mif_device),
+ GFP_KERNEL);
+ if (!net->ipv6.vif6_table) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ /* Forwarding cache */
+ net->ipv6.mfc6_cache_array = kcalloc(MFC6_LINES,
+ sizeof(struct mfc6_cache *),
+ GFP_KERNEL);
+ if (!net->ipv6.mfc6_cache_array) {
+ err = -ENOMEM;
+ goto fail_mfc6_cache;
+ }
+ return 0;
+
+fail_mfc6_cache:
+ kfree(net->ipv6.vif6_table);
+fail:
+ return err;
+}
+
+static void __net_exit ip6mr_net_exit(struct net *net)
+{
+ kfree(net->ipv6.mfc6_cache_array);
+ kfree(net->ipv6.vif6_table);
+}
+
+static struct pernet_operations ip6mr_net_ops = {
+ .init = ip6mr_net_init,
+ .exit = ip6mr_net_exit,
+};
+
int __init ip6_mr_init(void)
{
int err;
if (!mrt_cachep)
return -ENOMEM;
+ err = register_pernet_subsys(&ip6mr_net_ops);
+ if (err)
+ goto reg_pernet_fail;
+
setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
err = register_netdevice_notifier(&ip6_mr_notifier);
if (err)
goto proc_cache_fail;
#endif
return 0;
-reg_notif_fail:
- kmem_cache_destroy(mrt_cachep);
#ifdef CONFIG_PROC_FS
-proc_vif_fail:
- unregister_netdevice_notifier(&ip6_mr_notifier);
proc_cache_fail:
proc_net_remove(&init_net, "ip6_mr_vif");
+proc_vif_fail:
+ unregister_netdevice_notifier(&ip6_mr_notifier);
#endif
+reg_notif_fail:
+ del_timer(&ipmr_expire_timer);
+ unregister_pernet_subsys(&ip6mr_net_ops);
+reg_pernet_fail:
+ kmem_cache_destroy(mrt_cachep);
return err;
}
#endif
unregister_netdevice_notifier(&ip6_mr_notifier);
del_timer(&ipmr_expire_timer);
+ unregister_pernet_subsys(&ip6mr_net_ops);
kmem_cache_destroy(mrt_cachep);
}
line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
- for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) {
+ for (cp = &init_net.ipv6.mfc6_cache_array[line];
+ (c = *cp) != NULL; cp = &c->next) {
if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr))
break;
if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
return -EINVAL;
- c = ip6mr_cache_alloc();
+ c = ip6mr_cache_alloc(&init_net);
if (c == NULL)
return -ENOMEM;
c->mfc_flags |= MFC_STATIC;
write_lock_bh(&mrt_lock);
- c->next = mfc6_cache_array[line];
- mfc6_cache_array[line] = c;
+ c->next = init_net.ipv6.mfc6_cache_array[line];
+ init_net.ipv6.mfc6_cache_array[line] = c;
write_unlock_bh(&mrt_lock);
/*
spin_lock_bh(&mfc_unres_lock);
for (cp = &mfc_unres_queue; (uc = *cp) != NULL;
cp = &uc->next) {
- if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
+ if (net_eq(mfc6_net(uc), &init_net) &&
+ ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
*cp = uc->next;
- if (atomic_dec_and_test(&cache_resolve_queue_len))
- del_timer(&ipmr_expire_timer);
+ atomic_dec(&init_net.ipv6.cache_resolve_queue_len);
break;
}
}
+ if (mfc_unres_queue == NULL)
+ del_timer(&ipmr_expire_timer);
spin_unlock_bh(&mfc_unres_lock);
if (uc) {
ip6mr_cache_resolve(uc, c);
- kmem_cache_free(mrt_cachep, uc);
+ ip6mr_cache_free(uc);
}
return 0;
}
/*
* Shut down all active vif entries
*/
- for (i = 0; i < maxvif; i++) {
- if (!(vif6_table[i].flags & VIFF_STATIC))
+ for (i = 0; i < init_net.ipv6.maxvif; i++) {
+ if (!(init_net.ipv6.vif6_table[i].flags & VIFF_STATIC))
mif6_delete(i);
}
/*
* Wipe the cache
*/
- for (i = 0; i < ARRAY_SIZE(mfc6_cache_array); i++) {
+ for (i = 0; i < MFC6_LINES; i++) {
struct mfc6_cache *c, **cp;
- cp = &mfc6_cache_array[i];
+ cp = &init_net.ipv6.mfc6_cache_array[i];
while ((c = *cp) != NULL) {
if (c->mfc_flags & MFC_STATIC) {
cp = &c->next;
*cp = c->next;
write_unlock_bh(&mrt_lock);
- kmem_cache_free(mrt_cachep, c);
+ ip6mr_cache_free(c);
}
}
- if (atomic_read(&cache_resolve_queue_len) != 0) {
- struct mfc6_cache *c;
+ if (atomic_read(&init_net.ipv6.cache_resolve_queue_len) != 0) {
+ struct mfc6_cache *c, **cp;
spin_lock_bh(&mfc_unres_lock);
- while (mfc_unres_queue != NULL) {
- c = mfc_unres_queue;
- mfc_unres_queue = c->next;
- spin_unlock_bh(&mfc_unres_lock);
-
+ cp = &mfc_unres_queue;
+ while ((c = *cp) != NULL) {
+ if (!net_eq(mfc6_net(c), &init_net)) {
+ cp = &c->next;
+ continue;
+ }
+ *cp = c->next;
ip6mr_destroy_unres(c);
-
- spin_lock_bh(&mfc_unres_lock);
}
spin_unlock_bh(&mfc_unres_lock);
}
rtnl_lock();
write_lock_bh(&mrt_lock);
- if (likely(mroute6_socket == NULL))
- mroute6_socket = sk;
+ if (likely(init_net.ipv6.mroute6_sk == NULL))
+ init_net.ipv6.mroute6_sk = sk;
else
err = -EADDRINUSE;
write_unlock_bh(&mrt_lock);
int err = 0;
rtnl_lock();
- if (sk == mroute6_socket) {
+ if (sk == init_net.ipv6.mroute6_sk) {
write_lock_bh(&mrt_lock);
- mroute6_socket = NULL;
+ init_net.ipv6.mroute6_sk = NULL;
write_unlock_bh(&mrt_lock);
mroute_clean_tables(sk);
mifi_t mifi;
if (optname != MRT6_INIT) {
- if (sk != mroute6_socket && !capable(CAP_NET_ADMIN))
+ if (sk != init_net.ipv6.mroute6_sk && !capable(CAP_NET_ADMIN))
return -EACCES;
}
if (vif.mif6c_mifi >= MAXMIFS)
return -ENFILE;
rtnl_lock();
- ret = mif6_add(&vif, sk == mroute6_socket);
+ ret = mif6_add(&vif, sk == init_net.ipv6.mroute6_sk);
rtnl_unlock();
return ret;
if (optname == MRT6_DEL_MFC)
ret = ip6mr_mfc_delete(&mfc);
else
- ret = ip6mr_mfc_add(&mfc, sk == mroute6_socket);
+ ret = ip6mr_mfc_add(&mfc, sk == init_net.ipv6.mroute6_sk);
rtnl_unlock();
return ret;
case SIOCGETMIFCNT_IN6:
if (copy_from_user(&vr, arg, sizeof(vr)))
return -EFAULT;
- if (vr.mifi >= maxvif)
+ if (vr.mifi >= init_net.ipv6.maxvif)
return -EINVAL;
read_lock(&mrt_lock);
- vif = &vif6_table[vr.mifi];
- if (MIF_EXISTS(vr.mifi)) {
+ vif = &init_net.ipv6.vif6_table[vr.mifi];
+ if (MIF_EXISTS(&init_net, vr.mifi)) {
vr.icount = vif->pkt_in;
vr.ocount = vif->pkt_out;
vr.ibytes = vif->bytes_in;
static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
{
struct ipv6hdr *ipv6h;
- struct mif_device *vif = &vif6_table[vifi];
+ struct mif_device *vif = &init_net.ipv6.vif6_table[vifi];
struct net_device *dev;
struct dst_entry *dst;
struct flowi fl;
static int ip6mr_find_vif(struct net_device *dev)
{
int ct;
- for (ct = maxvif - 1; ct >= 0; ct--) {
- if (vif6_table[ct].dev == dev)
+ for (ct = init_net.ipv6.maxvif - 1; ct >= 0; ct--) {
+ if (init_net.ipv6.vif6_table[ct].dev == dev)
break;
}
return ct;
/*
* Wrong interface: drop packet and (maybe) send PIM assert.
*/
- if (vif6_table[vif].dev != skb->dev) {
+ if (init_net.ipv6.vif6_table[vif].dev != skb->dev) {
int true_vifi;
cache->mfc_un.res.wrong_if++;
goto dont_forward;
}
- vif6_table[vif].pkt_in++;
- vif6_table[vif].bytes_in += skb->len;
+ init_net.ipv6.vif6_table[vif].pkt_in++;
+ init_net.ipv6.vif6_table[vif].bytes_in += skb->len;
/*
* Forward the frame
{
int ct;
struct rtnexthop *nhp;
- struct net_device *dev = vif6_table[c->mf6c_parent].dev;
+ struct net_device *dev = init_net.ipv6.vif6_table[c->mf6c_parent].dev;
u8 *b = skb_tail_pointer(skb);
struct rtattr *mp_head;
nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
nhp->rtnh_flags = 0;
nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
- nhp->rtnh_ifindex = vif6_table[ct].dev->ifindex;
+ nhp->rtnh_ifindex = init_net.ipv6.vif6_table[ct].dev->ifindex;
nhp->rtnh_len = sizeof(*nhp);
}
}