|
@@ -106,7 +106,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
static int ipmr_cache_report(struct mr_table *mrt,
|
|
static int ipmr_cache_report(struct mr_table *mrt,
|
|
struct sk_buff *pkt, vifi_t vifi, int assert);
|
|
struct sk_buff *pkt, vifi_t vifi, int assert);
|
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
- struct mfc_cache *c, struct rtmsg *rtm);
|
|
|
|
|
|
+ struct mr_mfc *c, struct rtmsg *rtm);
|
|
static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
|
|
static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
|
|
int cmd);
|
|
int cmd);
|
|
static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
|
|
static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
|
|
@@ -343,7 +343,7 @@ static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
|
|
}
|
|
}
|
|
|
|
|
|
static const struct rhashtable_params ipmr_rht_params = {
|
|
static const struct rhashtable_params ipmr_rht_params = {
|
|
- .head_offset = offsetof(struct mfc_cache, mnode),
|
|
|
|
|
|
+ .head_offset = offsetof(struct mr_mfc, mnode),
|
|
.key_offset = offsetof(struct mfc_cache, cmparg),
|
|
.key_offset = offsetof(struct mfc_cache, cmparg),
|
|
.key_len = sizeof(struct mfc_cache_cmp_arg),
|
|
.key_len = sizeof(struct mfc_cache_cmp_arg),
|
|
.nelem_hint = 3,
|
|
.nelem_hint = 3,
|
|
@@ -752,14 +752,14 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
|
|
|
|
|
|
static void ipmr_cache_free_rcu(struct rcu_head *head)
|
|
static void ipmr_cache_free_rcu(struct rcu_head *head)
|
|
{
|
|
{
|
|
- struct mfc_cache *c = container_of(head, struct mfc_cache, rcu);
|
|
|
|
|
|
+ struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
|
|
|
|
|
|
- kmem_cache_free(mrt_cachep, c);
|
|
|
|
|
|
+ kmem_cache_free(mrt_cachep, (struct mfc_cache *)c);
|
|
}
|
|
}
|
|
|
|
|
|
void ipmr_cache_free(struct mfc_cache *c)
|
|
void ipmr_cache_free(struct mfc_cache *c)
|
|
{
|
|
{
|
|
- call_rcu(&c->rcu, ipmr_cache_free_rcu);
|
|
|
|
|
|
+ call_rcu(&c->_c.rcu, ipmr_cache_free_rcu);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(ipmr_cache_free);
|
|
EXPORT_SYMBOL(ipmr_cache_free);
|
|
|
|
|
|
@@ -774,7 +774,7 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
|
|
|
|
|
|
atomic_dec(&mrt->cache_resolve_queue_len);
|
|
atomic_dec(&mrt->cache_resolve_queue_len);
|
|
|
|
|
|
- while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) {
|
|
|
|
|
|
+ while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved))) {
|
|
if (ip_hdr(skb)->version == 0) {
|
|
if (ip_hdr(skb)->version == 0) {
|
|
struct nlmsghdr *nlh = skb_pull(skb,
|
|
struct nlmsghdr *nlh = skb_pull(skb,
|
|
sizeof(struct iphdr));
|
|
sizeof(struct iphdr));
|
|
@@ -798,9 +798,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
|
|
static void ipmr_expire_process(struct timer_list *t)
|
|
static void ipmr_expire_process(struct timer_list *t)
|
|
{
|
|
{
|
|
struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
|
|
struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
|
|
- unsigned long now;
|
|
|
|
|
|
+ struct mr_mfc *c, *next;
|
|
unsigned long expires;
|
|
unsigned long expires;
|
|
- struct mfc_cache *c, *next;
|
|
|
|
|
|
+ unsigned long now;
|
|
|
|
|
|
if (!spin_trylock(&mfc_unres_lock)) {
|
|
if (!spin_trylock(&mfc_unres_lock)) {
|
|
mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10);
|
|
mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10);
|
|
@@ -822,8 +822,8 @@ static void ipmr_expire_process(struct timer_list *t)
|
|
}
|
|
}
|
|
|
|
|
|
list_del(&c->list);
|
|
list_del(&c->list);
|
|
- mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
|
|
- ipmr_destroy_unres(mrt, c);
|
|
|
|
|
|
+ mroute_netlink_event(mrt, (struct mfc_cache *)c, RTM_DELROUTE);
|
|
|
|
+ ipmr_destroy_unres(mrt, (struct mfc_cache *)c);
|
|
}
|
|
}
|
|
|
|
|
|
if (!list_empty(&mrt->mfc_unres_queue))
|
|
if (!list_empty(&mrt->mfc_unres_queue))
|
|
@@ -834,7 +834,7 @@ out:
|
|
}
|
|
}
|
|
|
|
|
|
/* Fill oifs list. It is called under write locked mrt_lock. */
|
|
/* Fill oifs list. It is called under write locked mrt_lock. */
|
|
-static void ipmr_update_thresholds(struct mr_table *mrt, struct mfc_cache *cache,
|
|
|
|
|
|
+static void ipmr_update_thresholds(struct mr_table *mrt, struct mr_mfc *cache,
|
|
unsigned char *ttls)
|
|
unsigned char *ttls)
|
|
{
|
|
{
|
|
int vifi;
|
|
int vifi;
|
|
@@ -974,11 +974,11 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
|
|
.mfc_origin = origin
|
|
.mfc_origin = origin
|
|
};
|
|
};
|
|
struct rhlist_head *tmp, *list;
|
|
struct rhlist_head *tmp, *list;
|
|
- struct mfc_cache *c;
|
|
|
|
|
|
+ struct mr_mfc *c;
|
|
|
|
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
- return c;
|
|
|
|
|
|
+ return (struct mfc_cache *)c;
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -992,12 +992,12 @@ static struct mfc_cache *ipmr_cache_find_any_parent(struct mr_table *mrt,
|
|
.mfc_origin = htonl(INADDR_ANY)
|
|
.mfc_origin = htonl(INADDR_ANY)
|
|
};
|
|
};
|
|
struct rhlist_head *tmp, *list;
|
|
struct rhlist_head *tmp, *list;
|
|
- struct mfc_cache *c;
|
|
|
|
|
|
+ struct mr_mfc *c;
|
|
|
|
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
if (c->mfc_un.res.ttls[vifi] < 255)
|
|
if (c->mfc_un.res.ttls[vifi] < 255)
|
|
- return c;
|
|
|
|
|
|
+ return (struct mfc_cache *)c;
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -1011,20 +1011,22 @@ static struct mfc_cache *ipmr_cache_find_any(struct mr_table *mrt,
|
|
.mfc_origin = htonl(INADDR_ANY)
|
|
.mfc_origin = htonl(INADDR_ANY)
|
|
};
|
|
};
|
|
struct rhlist_head *tmp, *list;
|
|
struct rhlist_head *tmp, *list;
|
|
- struct mfc_cache *c, *proxy;
|
|
|
|
|
|
+ struct mr_mfc *c;
|
|
|
|
|
|
if (mcastgrp == htonl(INADDR_ANY))
|
|
if (mcastgrp == htonl(INADDR_ANY))
|
|
goto skip;
|
|
goto skip;
|
|
|
|
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode) {
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode) {
|
|
|
|
+ struct mfc_cache *proxy;
|
|
|
|
+
|
|
if (c->mfc_un.res.ttls[vifi] < 255)
|
|
if (c->mfc_un.res.ttls[vifi] < 255)
|
|
- return c;
|
|
|
|
|
|
+ return (struct mfc_cache *)c;
|
|
|
|
|
|
/* It's ok if the vifi is part of the static tree */
|
|
/* It's ok if the vifi is part of the static tree */
|
|
proxy = ipmr_cache_find_any_parent(mrt, c->mfc_parent);
|
|
proxy = ipmr_cache_find_any_parent(mrt, c->mfc_parent);
|
|
- if (proxy && proxy->mfc_un.res.ttls[vifi] < 255)
|
|
|
|
- return c;
|
|
|
|
|
|
+ if (proxy && proxy->_c.mfc_un.res.ttls[vifi] < 255)
|
|
|
|
+ return (struct mfc_cache *)c;
|
|
}
|
|
}
|
|
|
|
|
|
skip:
|
|
skip:
|
|
@@ -1041,12 +1043,12 @@ static struct mfc_cache *ipmr_cache_find_parent(struct mr_table *mrt,
|
|
.mfc_origin = origin,
|
|
.mfc_origin = origin,
|
|
};
|
|
};
|
|
struct rhlist_head *tmp, *list;
|
|
struct rhlist_head *tmp, *list;
|
|
- struct mfc_cache *c;
|
|
|
|
|
|
+ struct mr_mfc *c;
|
|
|
|
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
rhl_for_each_entry_rcu(c, tmp, list, mnode)
|
|
if (parent == -1 || parent == c->mfc_parent)
|
|
if (parent == -1 || parent == c->mfc_parent)
|
|
- return c;
|
|
|
|
|
|
+ return (struct mfc_cache *)c;
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -1057,9 +1059,9 @@ static struct mfc_cache *ipmr_cache_alloc(void)
|
|
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
|
|
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
|
|
|
|
|
|
if (c) {
|
|
if (c) {
|
|
- c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
|
|
|
|
- c->mfc_un.res.minvif = MAXVIFS;
|
|
|
|
- refcount_set(&c->mfc_un.res.refcount, 1);
|
|
|
|
|
|
+ c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
|
|
|
|
+ c->_c.mfc_un.res.minvif = MAXVIFS;
|
|
|
|
+ refcount_set(&c->_c.mfc_un.res.refcount, 1);
|
|
}
|
|
}
|
|
return c;
|
|
return c;
|
|
}
|
|
}
|
|
@@ -1069,8 +1071,8 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void)
|
|
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
|
|
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
|
|
|
|
|
|
if (c) {
|
|
if (c) {
|
|
- skb_queue_head_init(&c->mfc_un.unres.unresolved);
|
|
|
|
- c->mfc_un.unres.expires = jiffies + 10*HZ;
|
|
|
|
|
|
+ skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
|
|
|
|
+ c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
|
|
}
|
|
}
|
|
return c;
|
|
return c;
|
|
}
|
|
}
|
|
@@ -1083,12 +1085,13 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
|
|
struct nlmsgerr *e;
|
|
struct nlmsgerr *e;
|
|
|
|
|
|
/* Play the pending entries through our router */
|
|
/* Play the pending entries through our router */
|
|
- while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
|
|
|
|
|
|
+ while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
|
|
if (ip_hdr(skb)->version == 0) {
|
|
if (ip_hdr(skb)->version == 0) {
|
|
struct nlmsghdr *nlh = skb_pull(skb,
|
|
struct nlmsghdr *nlh = skb_pull(skb,
|
|
sizeof(struct iphdr));
|
|
sizeof(struct iphdr));
|
|
|
|
|
|
- if (__ipmr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) {
|
|
|
|
|
|
+ if (__ipmr_fill_mroute(mrt, skb, &c->_c,
|
|
|
|
+ nlmsg_data(nlh)) > 0) {
|
|
nlh->nlmsg_len = skb_tail_pointer(skb) -
|
|
nlh->nlmsg_len = skb_tail_pointer(skb) -
|
|
(u8 *)nlh;
|
|
(u8 *)nlh;
|
|
} else {
|
|
} else {
|
|
@@ -1196,7 +1199,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
|
|
int err;
|
|
int err;
|
|
|
|
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
- list_for_each_entry(c, &mrt->mfc_unres_queue, list) {
|
|
|
|
|
|
+ list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
|
|
if (c->mfc_mcastgrp == iph->daddr &&
|
|
if (c->mfc_mcastgrp == iph->daddr &&
|
|
c->mfc_origin == iph->saddr) {
|
|
c->mfc_origin == iph->saddr) {
|
|
found = true;
|
|
found = true;
|
|
@@ -1215,12 +1218,13 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
|
|
}
|
|
}
|
|
|
|
|
|
/* Fill in the new cache entry */
|
|
/* Fill in the new cache entry */
|
|
- c->mfc_parent = -1;
|
|
|
|
|
|
+ c->_c.mfc_parent = -1;
|
|
c->mfc_origin = iph->saddr;
|
|
c->mfc_origin = iph->saddr;
|
|
c->mfc_mcastgrp = iph->daddr;
|
|
c->mfc_mcastgrp = iph->daddr;
|
|
|
|
|
|
/* Reflect first query at mrouted. */
|
|
/* Reflect first query at mrouted. */
|
|
err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE);
|
|
err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE);
|
|
|
|
+
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
/* If the report failed throw the cache entry
|
|
/* If the report failed throw the cache entry
|
|
out - Brad Parker
|
|
out - Brad Parker
|
|
@@ -1233,15 +1237,16 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
|
|
}
|
|
}
|
|
|
|
|
|
atomic_inc(&mrt->cache_resolve_queue_len);
|
|
atomic_inc(&mrt->cache_resolve_queue_len);
|
|
- list_add(&c->list, &mrt->mfc_unres_queue);
|
|
|
|
|
|
+ list_add(&c->_c.list, &mrt->mfc_unres_queue);
|
|
mroute_netlink_event(mrt, c, RTM_NEWROUTE);
|
|
mroute_netlink_event(mrt, c, RTM_NEWROUTE);
|
|
|
|
|
|
if (atomic_read(&mrt->cache_resolve_queue_len) == 1)
|
|
if (atomic_read(&mrt->cache_resolve_queue_len) == 1)
|
|
- mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires);
|
|
|
|
|
|
+ mod_timer(&mrt->ipmr_expire_timer,
|
|
|
|
+ c->_c.mfc_un.unres.expires);
|
|
}
|
|
}
|
|
|
|
|
|
/* See if we can append the packet */
|
|
/* See if we can append the packet */
|
|
- if (c->mfc_un.unres.unresolved.qlen > 3) {
|
|
|
|
|
|
+ if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
err = -ENOBUFS;
|
|
err = -ENOBUFS;
|
|
} else {
|
|
} else {
|
|
@@ -1249,7 +1254,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
|
|
skb->dev = dev;
|
|
skb->dev = dev;
|
|
skb->skb_iif = dev->ifindex;
|
|
skb->skb_iif = dev->ifindex;
|
|
}
|
|
}
|
|
- skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
|
|
|
|
|
|
+ skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
|
|
err = 0;
|
|
err = 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1271,8 +1276,8 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc, int parent)
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
if (!c)
|
|
if (!c)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
- rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
|
|
|
|
- list_del_rcu(&c->list);
|
|
|
|
|
|
+ rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ipmr_rht_params);
|
|
|
|
+ list_del_rcu(&c->_c.list);
|
|
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id);
|
|
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id);
|
|
mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
ipmr_cache_put(c);
|
|
ipmr_cache_put(c);
|
|
@@ -1284,6 +1289,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
|
|
struct mfcctl *mfc, int mrtsock, int parent)
|
|
struct mfcctl *mfc, int mrtsock, int parent)
|
|
{
|
|
{
|
|
struct mfc_cache *uc, *c;
|
|
struct mfc_cache *uc, *c;
|
|
|
|
+ struct mr_mfc *_uc;
|
|
bool found;
|
|
bool found;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -1297,10 +1303,10 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
if (c) {
|
|
if (c) {
|
|
write_lock_bh(&mrt_lock);
|
|
write_lock_bh(&mrt_lock);
|
|
- c->mfc_parent = mfc->mfcc_parent;
|
|
|
|
- ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls);
|
|
|
|
|
|
+ c->_c.mfc_parent = mfc->mfcc_parent;
|
|
|
|
+ ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
|
|
if (!mrtsock)
|
|
if (!mrtsock)
|
|
- c->mfc_flags |= MFC_STATIC;
|
|
|
|
|
|
+ c->_c.mfc_flags |= MFC_STATIC;
|
|
write_unlock_bh(&mrt_lock);
|
|
write_unlock_bh(&mrt_lock);
|
|
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c,
|
|
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c,
|
|
mrt->id);
|
|
mrt->id);
|
|
@@ -1318,28 +1324,29 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
|
|
|
|
|
|
c->mfc_origin = mfc->mfcc_origin.s_addr;
|
|
c->mfc_origin = mfc->mfcc_origin.s_addr;
|
|
c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
|
|
c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
|
|
- c->mfc_parent = mfc->mfcc_parent;
|
|
|
|
- ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls);
|
|
|
|
|
|
+ c->_c.mfc_parent = mfc->mfcc_parent;
|
|
|
|
+ ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
|
|
if (!mrtsock)
|
|
if (!mrtsock)
|
|
- c->mfc_flags |= MFC_STATIC;
|
|
|
|
|
|
+ c->_c.mfc_flags |= MFC_STATIC;
|
|
|
|
|
|
- ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->mnode,
|
|
|
|
|
|
+ ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
|
|
ipmr_rht_params);
|
|
ipmr_rht_params);
|
|
if (ret) {
|
|
if (ret) {
|
|
pr_err("ipmr: rhtable insert error %d\n", ret);
|
|
pr_err("ipmr: rhtable insert error %d\n", ret);
|
|
ipmr_cache_free(c);
|
|
ipmr_cache_free(c);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
- list_add_tail_rcu(&c->list, &mrt->mfc_cache_list);
|
|
|
|
|
|
+ list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
|
|
/* Check to see if we resolved a queued list. If so we
|
|
/* Check to see if we resolved a queued list. If so we
|
|
* need to send on the frames and tidy up.
|
|
* need to send on the frames and tidy up.
|
|
*/
|
|
*/
|
|
found = false;
|
|
found = false;
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
- list_for_each_entry(uc, &mrt->mfc_unres_queue, list) {
|
|
|
|
|
|
+ list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
|
|
|
|
+ uc = (struct mfc_cache *)_uc;
|
|
if (uc->mfc_origin == c->mfc_origin &&
|
|
if (uc->mfc_origin == c->mfc_origin &&
|
|
uc->mfc_mcastgrp == c->mfc_mcastgrp) {
|
|
uc->mfc_mcastgrp == c->mfc_mcastgrp) {
|
|
- list_del(&uc->list);
|
|
|
|
|
|
+ list_del(&_uc->list);
|
|
atomic_dec(&mrt->cache_resolve_queue_len);
|
|
atomic_dec(&mrt->cache_resolve_queue_len);
|
|
found = true;
|
|
found = true;
|
|
break;
|
|
break;
|
|
@@ -1362,7 +1369,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
|
|
static void mroute_clean_tables(struct mr_table *mrt, bool all)
|
|
static void mroute_clean_tables(struct mr_table *mrt, bool all)
|
|
{
|
|
{
|
|
struct net *net = read_pnet(&mrt->net);
|
|
struct net *net = read_pnet(&mrt->net);
|
|
- struct mfc_cache *c, *tmp;
|
|
|
|
|
|
+ struct mr_mfc *c, *tmp;
|
|
|
|
+ struct mfc_cache *cache;
|
|
LIST_HEAD(list);
|
|
LIST_HEAD(list);
|
|
int i;
|
|
int i;
|
|
|
|
|
|
@@ -1380,18 +1388,20 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
|
|
continue;
|
|
continue;
|
|
rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
|
|
rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
|
|
list_del_rcu(&c->list);
|
|
list_del_rcu(&c->list);
|
|
- call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c,
|
|
|
|
|
|
+ cache = (struct mfc_cache *)c;
|
|
|
|
+ call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
|
|
mrt->id);
|
|
mrt->id);
|
|
- mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
|
|
- ipmr_cache_put(c);
|
|
|
|
|
|
+ mroute_netlink_event(mrt, cache, RTM_DELROUTE);
|
|
|
|
+ ipmr_cache_put(cache);
|
|
}
|
|
}
|
|
|
|
|
|
if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
|
|
if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
|
|
list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
|
|
list_del(&c->list);
|
|
list_del(&c->list);
|
|
- mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
|
|
- ipmr_destroy_unres(mrt, c);
|
|
|
|
|
|
+ cache = (struct mfc_cache *)c;
|
|
|
|
+ mroute_netlink_event(mrt, cache, RTM_DELROUTE);
|
|
|
|
+ ipmr_destroy_unres(mrt, cache);
|
|
}
|
|
}
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
}
|
|
}
|
|
@@ -1683,9 +1693,9 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
|
|
c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
|
|
if (c) {
|
|
if (c) {
|
|
- sr.pktcnt = c->mfc_un.res.pkt;
|
|
|
|
- sr.bytecnt = c->mfc_un.res.bytes;
|
|
|
|
- sr.wrong_if = c->mfc_un.res.wrong_if;
|
|
|
|
|
|
+ sr.pktcnt = c->_c.mfc_un.res.pkt;
|
|
|
|
+ sr.bytecnt = c->_c.mfc_un.res.bytes;
|
|
|
|
+ sr.wrong_if = c->_c.mfc_un.res.wrong_if;
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
if (copy_to_user(arg, &sr, sizeof(sr)))
|
|
if (copy_to_user(arg, &sr, sizeof(sr)))
|
|
@@ -1757,9 +1767,9 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
|
|
c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
|
|
if (c) {
|
|
if (c) {
|
|
- sr.pktcnt = c->mfc_un.res.pkt;
|
|
|
|
- sr.bytecnt = c->mfc_un.res.bytes;
|
|
|
|
- sr.wrong_if = c->mfc_un.res.wrong_if;
|
|
|
|
|
|
+ sr.pktcnt = c->_c.mfc_un.res.pkt;
|
|
|
|
+ sr.bytecnt = c->_c.mfc_un.res.bytes;
|
|
|
|
+ sr.wrong_if = c->_c.mfc_un.res.wrong_if;
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
if (copy_to_user(arg, &sr, sizeof(sr)))
|
|
if (copy_to_user(arg, &sr, sizeof(sr)))
|
|
@@ -1983,18 +1993,18 @@ static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev)
|
|
/* "local" means that we should preserve one skb (for local delivery) */
|
|
/* "local" means that we should preserve one skb (for local delivery) */
|
|
static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
struct net_device *dev, struct sk_buff *skb,
|
|
struct net_device *dev, struct sk_buff *skb,
|
|
- struct mfc_cache *cache, int local)
|
|
|
|
|
|
+ struct mfc_cache *c, int local)
|
|
{
|
|
{
|
|
int true_vifi = ipmr_find_vif(mrt, dev);
|
|
int true_vifi = ipmr_find_vif(mrt, dev);
|
|
int psend = -1;
|
|
int psend = -1;
|
|
int vif, ct;
|
|
int vif, ct;
|
|
|
|
|
|
- vif = cache->mfc_parent;
|
|
|
|
- cache->mfc_un.res.pkt++;
|
|
|
|
- cache->mfc_un.res.bytes += skb->len;
|
|
|
|
- cache->mfc_un.res.lastuse = jiffies;
|
|
|
|
|
|
+ vif = c->_c.mfc_parent;
|
|
|
|
+ c->_c.mfc_un.res.pkt++;
|
|
|
|
+ c->_c.mfc_un.res.bytes += skb->len;
|
|
|
|
+ c->_c.mfc_un.res.lastuse = jiffies;
|
|
|
|
|
|
- if (cache->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
|
|
|
|
|
|
+ if (c->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
|
|
struct mfc_cache *cache_proxy;
|
|
struct mfc_cache *cache_proxy;
|
|
|
|
|
|
/* For an (*,G) entry, we only check that the incomming
|
|
/* For an (*,G) entry, we only check that the incomming
|
|
@@ -2002,7 +2012,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
*/
|
|
*/
|
|
cache_proxy = ipmr_cache_find_any_parent(mrt, vif);
|
|
cache_proxy = ipmr_cache_find_any_parent(mrt, vif);
|
|
if (cache_proxy &&
|
|
if (cache_proxy &&
|
|
- cache_proxy->mfc_un.res.ttls[true_vifi] < 255)
|
|
|
|
|
|
+ cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255)
|
|
goto forward;
|
|
goto forward;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2023,7 +2033,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
goto dont_forward;
|
|
goto dont_forward;
|
|
}
|
|
}
|
|
|
|
|
|
- cache->mfc_un.res.wrong_if++;
|
|
|
|
|
|
+ c->_c.mfc_un.res.wrong_if++;
|
|
|
|
|
|
if (true_vifi >= 0 && mrt->mroute_do_assert &&
|
|
if (true_vifi >= 0 && mrt->mroute_do_assert &&
|
|
/* pimsm uses asserts, when switching from RPT to SPT,
|
|
/* pimsm uses asserts, when switching from RPT to SPT,
|
|
@@ -2032,10 +2042,11 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|
* large chunk of pimd to kernel. Ough... --ANK
|
|
* large chunk of pimd to kernel. Ough... --ANK
|
|
*/
|
|
*/
|
|
(mrt->mroute_do_pim ||
|
|
(mrt->mroute_do_pim ||
|
|
- cache->mfc_un.res.ttls[true_vifi] < 255) &&
|
|
|
|
|
|
+ c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
|
|
time_after(jiffies,
|
|
time_after(jiffies,
|
|
- cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
|
|
|
|
- cache->mfc_un.res.last_assert = jiffies;
|
|
|
|
|
|
+ c->_c.mfc_un.res.last_assert +
|
|
|
|
+ MFC_ASSERT_THRESH)) {
|
|
|
|
+ c->_c.mfc_un.res.last_assert = jiffies;
|
|
ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF);
|
|
ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF);
|
|
}
|
|
}
|
|
goto dont_forward;
|
|
goto dont_forward;
|
|
@@ -2046,33 +2057,33 @@ forward:
|
|
mrt->vif_table[vif].bytes_in += skb->len;
|
|
mrt->vif_table[vif].bytes_in += skb->len;
|
|
|
|
|
|
/* Forward the frame */
|
|
/* Forward the frame */
|
|
- if (cache->mfc_origin == htonl(INADDR_ANY) &&
|
|
|
|
- cache->mfc_mcastgrp == htonl(INADDR_ANY)) {
|
|
|
|
|
|
+ if (c->mfc_origin == htonl(INADDR_ANY) &&
|
|
|
|
+ c->mfc_mcastgrp == htonl(INADDR_ANY)) {
|
|
if (true_vifi >= 0 &&
|
|
if (true_vifi >= 0 &&
|
|
- true_vifi != cache->mfc_parent &&
|
|
|
|
|
|
+ true_vifi != c->_c.mfc_parent &&
|
|
ip_hdr(skb)->ttl >
|
|
ip_hdr(skb)->ttl >
|
|
- cache->mfc_un.res.ttls[cache->mfc_parent]) {
|
|
|
|
|
|
+ c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
|
|
/* It's an (*,*) entry and the packet is not coming from
|
|
/* It's an (*,*) entry and the packet is not coming from
|
|
* the upstream: forward the packet to the upstream
|
|
* the upstream: forward the packet to the upstream
|
|
* only.
|
|
* only.
|
|
*/
|
|
*/
|
|
- psend = cache->mfc_parent;
|
|
|
|
|
|
+ psend = c->_c.mfc_parent;
|
|
goto last_forward;
|
|
goto last_forward;
|
|
}
|
|
}
|
|
goto dont_forward;
|
|
goto dont_forward;
|
|
}
|
|
}
|
|
- for (ct = cache->mfc_un.res.maxvif - 1;
|
|
|
|
- ct >= cache->mfc_un.res.minvif; ct--) {
|
|
|
|
|
|
+ for (ct = c->_c.mfc_un.res.maxvif - 1;
|
|
|
|
+ ct >= c->_c.mfc_un.res.minvif; ct--) {
|
|
/* For (*,G) entry, don't forward to the incoming interface */
|
|
/* For (*,G) entry, don't forward to the incoming interface */
|
|
- if ((cache->mfc_origin != htonl(INADDR_ANY) ||
|
|
|
|
|
|
+ if ((c->mfc_origin != htonl(INADDR_ANY) ||
|
|
ct != true_vifi) &&
|
|
ct != true_vifi) &&
|
|
- ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
|
|
|
|
|
|
+ ip_hdr(skb)->ttl > c->_c.mfc_un.res.ttls[ct]) {
|
|
if (psend != -1) {
|
|
if (psend != -1) {
|
|
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
|
|
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
|
|
|
|
|
|
if (skb2)
|
|
if (skb2)
|
|
ipmr_queue_xmit(net, mrt, true_vifi,
|
|
ipmr_queue_xmit(net, mrt, true_vifi,
|
|
- skb2, cache, psend);
|
|
|
|
|
|
+ skb2, c, psend);
|
|
}
|
|
}
|
|
psend = ct;
|
|
psend = ct;
|
|
}
|
|
}
|
|
@@ -2084,9 +2095,9 @@ last_forward:
|
|
|
|
|
|
if (skb2)
|
|
if (skb2)
|
|
ipmr_queue_xmit(net, mrt, true_vifi, skb2,
|
|
ipmr_queue_xmit(net, mrt, true_vifi, skb2,
|
|
- cache, psend);
|
|
|
|
|
|
+ c, psend);
|
|
} else {
|
|
} else {
|
|
- ipmr_queue_xmit(net, mrt, true_vifi, skb, cache, psend);
|
|
|
|
|
|
+ ipmr_queue_xmit(net, mrt, true_vifi, skb, c, psend);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2285,7 +2296,7 @@ drop:
|
|
#endif
|
|
#endif
|
|
|
|
|
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
- struct mfc_cache *c, struct rtmsg *rtm)
|
|
|
|
|
|
+ struct mr_mfc *c, struct rtmsg *rtm)
|
|
{
|
|
{
|
|
struct rta_mfc_stats mfcs;
|
|
struct rta_mfc_stats mfcs;
|
|
struct nlattr *mp_attr;
|
|
struct nlattr *mp_attr;
|
|
@@ -2401,7 +2412,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
|
|
}
|
|
}
|
|
|
|
|
|
read_lock(&mrt_lock);
|
|
read_lock(&mrt_lock);
|
|
- err = __ipmr_fill_mroute(mrt, skb, cache, rtm);
|
|
|
|
|
|
+ err = __ipmr_fill_mroute(mrt, skb, &cache->_c, rtm);
|
|
read_unlock(&mrt_lock);
|
|
read_unlock(&mrt_lock);
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
return err;
|
|
return err;
|
|
@@ -2429,7 +2440,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
goto nla_put_failure;
|
|
goto nla_put_failure;
|
|
rtm->rtm_type = RTN_MULTICAST;
|
|
rtm->rtm_type = RTN_MULTICAST;
|
|
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
|
|
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
|
|
- if (c->mfc_flags & MFC_STATIC)
|
|
|
|
|
|
+ if (c->_c.mfc_flags & MFC_STATIC)
|
|
rtm->rtm_protocol = RTPROT_STATIC;
|
|
rtm->rtm_protocol = RTPROT_STATIC;
|
|
else
|
|
else
|
|
rtm->rtm_protocol = RTPROT_MROUTED;
|
|
rtm->rtm_protocol = RTPROT_MROUTED;
|
|
@@ -2438,7 +2449,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
if (nla_put_in_addr(skb, RTA_SRC, c->mfc_origin) ||
|
|
if (nla_put_in_addr(skb, RTA_SRC, c->mfc_origin) ||
|
|
nla_put_in_addr(skb, RTA_DST, c->mfc_mcastgrp))
|
|
nla_put_in_addr(skb, RTA_DST, c->mfc_mcastgrp))
|
|
goto nla_put_failure;
|
|
goto nla_put_failure;
|
|
- err = __ipmr_fill_mroute(mrt, skb, c, rtm);
|
|
|
|
|
|
+ err = __ipmr_fill_mroute(mrt, skb, &c->_c, rtm);
|
|
/* do not break the dump if cache is unresolved */
|
|
/* do not break the dump if cache is unresolved */
|
|
if (err < 0 && err != -ENOENT)
|
|
if (err < 0 && err != -ENOENT)
|
|
goto nla_put_failure;
|
|
goto nla_put_failure;
|
|
@@ -2479,7 +2490,8 @@ static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
int err = -ENOBUFS;
|
|
int err = -ENOBUFS;
|
|
|
|
|
|
- skb = nlmsg_new(mroute_msgsize(mfc->mfc_parent >= MAXVIFS, mrt->maxvif),
|
|
|
|
|
|
+ skb = nlmsg_new(mroute_msgsize(mfc->_c.mfc_parent >= MAXVIFS,
|
|
|
|
+ mrt->maxvif),
|
|
GFP_ATOMIC);
|
|
GFP_ATOMIC);
|
|
if (!skb)
|
|
if (!skb)
|
|
goto errout;
|
|
goto errout;
|
|
@@ -2624,10 +2636,10 @@ errout_free:
|
|
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
|
|
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
|
|
{
|
|
{
|
|
struct net *net = sock_net(skb->sk);
|
|
struct net *net = sock_net(skb->sk);
|
|
- struct mr_table *mrt;
|
|
|
|
- struct mfc_cache *mfc;
|
|
|
|
unsigned int t = 0, s_t;
|
|
unsigned int t = 0, s_t;
|
|
unsigned int e = 0, s_e;
|
|
unsigned int e = 0, s_e;
|
|
|
|
+ struct mr_table *mrt;
|
|
|
|
+ struct mr_mfc *mfc;
|
|
|
|
|
|
s_t = cb->args[0];
|
|
s_t = cb->args[0];
|
|
s_e = cb->args[1];
|
|
s_e = cb->args[1];
|
|
@@ -2642,8 +2654,8 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
|
|
if (ipmr_fill_mroute(mrt, skb,
|
|
if (ipmr_fill_mroute(mrt, skb,
|
|
NETLINK_CB(cb->skb).portid,
|
|
NETLINK_CB(cb->skb).portid,
|
|
cb->nlh->nlmsg_seq,
|
|
cb->nlh->nlmsg_seq,
|
|
- mfc, RTM_NEWROUTE,
|
|
|
|
- NLM_F_MULTI) < 0)
|
|
|
|
|
|
+ (struct mfc_cache *)mfc,
|
|
|
|
+ RTM_NEWROUTE, NLM_F_MULTI) < 0)
|
|
goto done;
|
|
goto done;
|
|
next_entry:
|
|
next_entry:
|
|
e++;
|
|
e++;
|
|
@@ -2658,8 +2670,8 @@ next_entry:
|
|
if (ipmr_fill_mroute(mrt, skb,
|
|
if (ipmr_fill_mroute(mrt, skb,
|
|
NETLINK_CB(cb->skb).portid,
|
|
NETLINK_CB(cb->skb).portid,
|
|
cb->nlh->nlmsg_seq,
|
|
cb->nlh->nlmsg_seq,
|
|
- mfc, RTM_NEWROUTE,
|
|
|
|
- NLM_F_MULTI) < 0) {
|
|
|
|
|
|
+ (struct mfc_cache *)mfc,
|
|
|
|
+ RTM_NEWROUTE, NLM_F_MULTI) < 0) {
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
@@ -3051,20 +3063,21 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
|
|
struct ipmr_mfc_iter *it, loff_t pos)
|
|
struct ipmr_mfc_iter *it, loff_t pos)
|
|
{
|
|
{
|
|
struct mr_table *mrt = it->mrt;
|
|
struct mr_table *mrt = it->mrt;
|
|
- struct mfc_cache *mfc;
|
|
|
|
|
|
+ struct mr_mfc *mfc;
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
it->cache = &mrt->mfc_cache_list;
|
|
it->cache = &mrt->mfc_cache_list;
|
|
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
|
|
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
|
|
if (pos-- == 0)
|
|
if (pos-- == 0)
|
|
- return mfc;
|
|
|
|
|
|
+ return (struct mfc_cache *)mfc;
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
it->cache = &mrt->mfc_unres_queue;
|
|
it->cache = &mrt->mfc_unres_queue;
|
|
list_for_each_entry(mfc, it->cache, list)
|
|
list_for_each_entry(mfc, it->cache, list)
|
|
if (pos-- == 0)
|
|
if (pos-- == 0)
|
|
- return mfc;
|
|
|
|
|
|
+ return (struct mfc_cache *)mfc;
|
|
|
|
+
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
|
|
|
|
it->cache = NULL;
|
|
it->cache = NULL;
|
|
@@ -3100,8 +3113,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
if (v == SEQ_START_TOKEN)
|
|
if (v == SEQ_START_TOKEN)
|
|
return ipmr_mfc_seq_idx(net, seq->private, 0);
|
|
return ipmr_mfc_seq_idx(net, seq->private, 0);
|
|
|
|
|
|
- if (mfc->list.next != it->cache)
|
|
|
|
- return list_entry(mfc->list.next, struct mfc_cache, list);
|
|
|
|
|
|
+ if (mfc->_c.list.next != it->cache)
|
|
|
|
+ return (struct mfc_cache *)(list_entry(mfc->_c.list.next,
|
|
|
|
+ struct mr_mfc, list));
|
|
|
|
|
|
if (it->cache == &mrt->mfc_unres_queue)
|
|
if (it->cache == &mrt->mfc_unres_queue)
|
|
goto end_of_list;
|
|
goto end_of_list;
|
|
@@ -3112,7 +3126,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
|
|
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
spin_lock_bh(&mfc_unres_lock);
|
|
if (!list_empty(it->cache))
|
|
if (!list_empty(it->cache))
|
|
- return list_first_entry(it->cache, struct mfc_cache, list);
|
|
|
|
|
|
+ return (struct mfc_cache *)(list_first_entry(it->cache,
|
|
|
|
+ struct mr_mfc,
|
|
|
|
+ list));
|
|
|
|
|
|
end_of_list:
|
|
end_of_list:
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
spin_unlock_bh(&mfc_unres_lock);
|
|
@@ -3147,20 +3163,20 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
|
|
seq_printf(seq, "%08X %08X %-3hd",
|
|
seq_printf(seq, "%08X %08X %-3hd",
|
|
(__force u32) mfc->mfc_mcastgrp,
|
|
(__force u32) mfc->mfc_mcastgrp,
|
|
(__force u32) mfc->mfc_origin,
|
|
(__force u32) mfc->mfc_origin,
|
|
- mfc->mfc_parent);
|
|
|
|
|
|
+ mfc->_c.mfc_parent);
|
|
|
|
|
|
if (it->cache != &mrt->mfc_unres_queue) {
|
|
if (it->cache != &mrt->mfc_unres_queue) {
|
|
seq_printf(seq, " %8lu %8lu %8lu",
|
|
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++) {
|
|
|
|
|
|
+ mfc->_c.mfc_un.res.pkt,
|
|
|
|
+ mfc->_c.mfc_un.res.bytes,
|
|
|
|
+ mfc->_c.mfc_un.res.wrong_if);
|
|
|
|
+ for (n = mfc->_c.mfc_un.res.minvif;
|
|
|
|
+ n < mfc->_c.mfc_un.res.maxvif; n++) {
|
|
if (VIF_EXISTS(mrt, n) &&
|
|
if (VIF_EXISTS(mrt, n) &&
|
|
- mfc->mfc_un.res.ttls[n] < 255)
|
|
|
|
|
|
+ mfc->_c.mfc_un.res.ttls[n] < 255)
|
|
seq_printf(seq,
|
|
seq_printf(seq,
|
|
" %2d:%-3d",
|
|
" %2d:%-3d",
|
|
- n, mfc->mfc_un.res.ttls[n]);
|
|
|
|
|
|
+ n, mfc->_c.mfc_un.res.ttls[n]);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
/* unresolved mfc_caches don't contain
|
|
/* unresolved mfc_caches don't contain
|
|
@@ -3219,7 +3235,7 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
|
|
|
|
|
|
ipmr_for_each_table(mrt, net) {
|
|
ipmr_for_each_table(mrt, net) {
|
|
struct vif_device *v = &mrt->vif_table[0];
|
|
struct vif_device *v = &mrt->vif_table[0];
|
|
- struct mfc_cache *mfc;
|
|
|
|
|
|
+ struct mr_mfc *mfc;
|
|
int vifi;
|
|
int vifi;
|
|
|
|
|
|
/* Notifiy on table VIF entries */
|
|
/* Notifiy on table VIF entries */
|
|
@@ -3236,7 +3252,8 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
|
|
/* Notify on table MFC entries */
|
|
/* Notify on table MFC entries */
|
|
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
|
|
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
|
|
call_ipmr_mfc_entry_notifier(nb, net,
|
|
call_ipmr_mfc_entry_notifier(nb, net,
|
|
- FIB_EVENT_ENTRY_ADD, mfc,
|
|
|
|
|
|
+ FIB_EVENT_ENTRY_ADD,
|
|
|
|
+ (struct mfc_cache *)mfc,
|
|
mrt->id);
|
|
mrt->id);
|
|
}
|
|
}
|
|
|
|
|