Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdc9f944 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller
Browse files

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: default avatarYuval Mintz <yuvalm@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 54c4cad9
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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)
+2 −51
Original line number Diff line number Diff line
@@ -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 = {
+42 −0
Original line number Diff line number Diff line
@@ -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);