Skip to content

Commit

Permalink
ipmr: Make ipmr_dump() common
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yuval Mintz authored and David S. Miller committed Mar 26, 2018
1 parent 54c4cad commit cdc9f94
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 51 deletions.
18 changes: 18 additions & 0 deletions include/linux/mroute_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
53 changes: 2 additions & 51 deletions net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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 = {
Expand Down
42 changes: 42 additions & 0 deletions net/ipv4/ipmr_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit cdc9f94

Please sign in to comment.