ipmr: Make ipmr_dump() common

Since all the primitive elements used for the notification done by ipmr
are now common [mr_table, mr_mfc, vif_device] we can refactor the logic
for dumping them to a common file.

Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yuval Mintz 2018-03-26 15:01:33 +03:00 committed by David S. Miller
parent 54c4cad97b
commit cdc9f9443b
3 changed files with 62 additions and 51 deletions

View File

@ -277,6 +277,13 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
u32 portid, u32 seq, struct mr_mfc *c,
int cmd, int flags),
spinlock_t *lock);
int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
int (*rules_dump)(struct net *net,
struct notifier_block *nb),
struct mr_table *(*mr_iter)(struct net *net,
struct mr_table *mrt),
rwlock_t *mrt_lock);
#else
static inline void vif_device_init(struct vif_device *v,
struct net_device *dev,
@ -333,6 +340,17 @@ mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
{
return -EINVAL;
}
static inline int mr_dump(struct net *net, struct notifier_block *nb,
unsigned short family,
int (*rules_dump)(struct net *net,
struct notifier_block *nb),
struct mr_table *(*mr_iter)(struct net *net,
struct mr_table *mrt),
rwlock_t *mrt_lock)
{
return -EINVAL;
}
#endif
static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)

View File

@ -644,16 +644,6 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
}
#endif
static int call_ipmr_vif_entry_notifier(struct notifier_block *nb,
struct net *net,
enum fib_event_type event_type,
struct vif_device *vif,
vifi_t vif_index, u32 tb_id)
{
return mr_call_vif_notifier(nb, net, RTNL_FAMILY_IPMR, event_type,
vif, vif_index, tb_id);
}
static int call_ipmr_vif_entry_notifiers(struct net *net,
enum fib_event_type event_type,
struct vif_device *vif,
@ -664,15 +654,6 @@ static int call_ipmr_vif_entry_notifiers(struct net *net,
&net->ipv4.ipmr_seq);
}
static int call_ipmr_mfc_entry_notifier(struct notifier_block *nb,
struct net *net,
enum fib_event_type event_type,
struct mfc_cache *mfc, u32 tb_id)
{
return mr_call_mfc_notifier(nb, net, RTNL_FAMILY_IPMR,
event_type, &mfc->_c, tb_id);
}
static int call_ipmr_mfc_entry_notifiers(struct net *net,
enum fib_event_type event_type,
struct mfc_cache *mfc, u32 tb_id)
@ -2950,38 +2931,8 @@ static unsigned int ipmr_seq_read(struct net *net)
static int ipmr_dump(struct net *net, struct notifier_block *nb)
{
struct mr_table *mrt;
int err;
err = ipmr_rules_dump(net, nb);
if (err)
return err;
ipmr_for_each_table(mrt, net) {
struct vif_device *v = &mrt->vif_table[0];
struct mr_mfc *mfc;
int vifi;
/* Notifiy on table VIF entries */
read_lock(&mrt_lock);
for (vifi = 0; vifi < mrt->maxvif; vifi++, v++) {
if (!v->dev)
continue;
call_ipmr_vif_entry_notifier(nb, net, FIB_EVENT_VIF_ADD,
v, vifi, mrt->id);
}
read_unlock(&mrt_lock);
/* Notify on table MFC entries */
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
call_ipmr_mfc_entry_notifier(nb, net,
FIB_EVENT_ENTRY_ADD,
(struct mfc_cache *)mfc,
mrt->id);
}
return 0;
return mr_dump(net, nb, RTNL_FAMILY_IPMR, ipmr_rules_dump,
ipmr_mr_table_iter, &mrt_lock);
}
static const struct fib_notifier_ops ipmr_notifier_ops_template = {

View File

@ -321,3 +321,45 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
return skb->len;
}
EXPORT_SYMBOL(mr_rtm_dumproute);
int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
int (*rules_dump)(struct net *net,
struct notifier_block *nb),
struct mr_table *(*mr_iter)(struct net *net,
struct mr_table *mrt),
rwlock_t *mrt_lock)
{
struct mr_table *mrt;
int err;
err = rules_dump(net, nb);
if (err)
return err;
for (mrt = mr_iter(net, NULL); mrt; mrt = mr_iter(net, mrt)) {
struct vif_device *v = &mrt->vif_table[0];
struct mr_mfc *mfc;
int vifi;
/* Notifiy on table VIF entries */
read_lock(mrt_lock);
for (vifi = 0; vifi < mrt->maxvif; vifi++, v++) {
if (!v->dev)
continue;
mr_call_vif_notifier(nb, net, family,
FIB_EVENT_VIF_ADD,
v, vifi, mrt->id);
}
read_unlock(mrt_lock);
/* Notify on table MFC entries */
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
mr_call_mfc_notifier(nb, net, family,
FIB_EVENT_ENTRY_ADD,
mfc, mrt->id);
}
return 0;
}
EXPORT_SYMBOL(mr_dump);