On 21/09/17 09:43, Jiri Pirko wrote: > From: Yotam Gigi <yot...@mellanox.com> > > Use the newly introduced notification chain to send events upon VIF and MFC > addition and deletion. The MFC notifications are sent only on resolved MFC > entries, as unresolved cannot be offloaded. > > Signed-off-by: Yotam Gigi <yot...@mellanox.com> > Reviewed-by: Ido Schimmel <ido...@mellanox.com> > Signed-off-by: Jiri Pirko <j...@mellanox.com> > --- > net/ipv4/ipmr.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) >
LGTM, I only wish we could consolidate all of these call_ipmr_mfc_entry_notifiers() calls inside mroute_netlink_event() but it will need an additional argument for the ADD vs REPLACE cases. Anyway, Reviewed-by: Nikolay Aleksandrov <niko...@cumulusnetworks.com> > diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c > index 9d331a74..7891d95 100644 > --- a/net/ipv4/ipmr.c > +++ b/net/ipv4/ipmr.c > @@ -627,6 +627,27 @@ static int call_ipmr_vif_entry_notifier(struct > notifier_block *nb, > return call_fib_notifier(nb, net, event_type, &info.info); > } > > +static int call_ipmr_vif_entry_notifiers(struct net *net, > + enum fib_event_type event_type, > + struct vif_device *vif, > + vifi_t vif_index, u32 tb_id) > +{ > + struct vif_entry_notifier_info info = { > + .info = { > + .family = RTNL_FAMILY_IPMR, > + .net = net, > + }, > + .dev = vif->dev, > + .vif_index = vif_index, > + .vif_flags = vif->flags, > + .tb_id = tb_id, > + }; > + > + ASSERT_RTNL(); > + net->ipv4.ipmr_seq++; > + return call_fib_notifiers(net, event_type, &info.info); > +} > + > static int call_ipmr_mfc_entry_notifier(struct notifier_block *nb, > struct net *net, > enum fib_event_type event_type, > @@ -644,6 +665,24 @@ static int call_ipmr_mfc_entry_notifier(struct > notifier_block *nb, > return call_fib_notifier(nb, net, event_type, &info.info); > } > > +static int call_ipmr_mfc_entry_notifiers(struct net *net, > + enum fib_event_type event_type, > + struct mfc_cache *mfc, u32 tb_id) > +{ > + struct mfc_entry_notifier_info info = { > + .info = { > + .family = RTNL_FAMILY_IPMR, > + .net = net, > + }, > + .mfc = mfc, > + .tb_id = tb_id > + }; > + > + ASSERT_RTNL(); > + net->ipv4.ipmr_seq++; > + return call_fib_notifiers(net, event_type, &info.info); > +} > + > /** > * vif_delete - Delete a VIF entry > * @notify: Set to 1, if the caller is a notifier_call > @@ -651,6 +690,7 @@ static int call_ipmr_mfc_entry_notifier(struct > notifier_block *nb, > static int vif_delete(struct mr_table *mrt, int vifi, int notify, > struct list_head *head) > { > + struct net *net = read_pnet(&mrt->net); > struct vif_device *v; > struct net_device *dev; > struct in_device *in_dev; > @@ -660,6 +700,10 @@ static int vif_delete(struct mr_table *mrt, int vifi, > int notify, > > v = &mrt->vif_table[vifi]; > > + if (VIF_EXISTS(mrt, vifi)) > + call_ipmr_vif_entry_notifiers(net, FIB_EVENT_VIF_DEL, v, vifi, > + mrt->id); > + > write_lock_bh(&mrt_lock); > dev = v->dev; > v->dev = NULL; > @@ -909,6 +953,7 @@ static int vif_add(struct net *net, struct mr_table *mrt, > if (vifi+1 > mrt->maxvif) > mrt->maxvif = vifi+1; > write_unlock_bh(&mrt_lock); > + call_ipmr_vif_entry_notifiers(net, FIB_EVENT_VIF_ADD, v, vifi, mrt->id); > return 0; > } > > @@ -1209,6 +1254,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, > vifi_t vifi, > > static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc, int > parent) > { > + struct net *net = read_pnet(&mrt->net); > struct mfc_cache *c; > > /* The entries are added/deleted only under RTNL */ > @@ -1220,6 +1266,7 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct > mfcctl *mfc, int parent) > return -ENOENT; > rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); > list_del_rcu(&c->list); > + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id); > mroute_netlink_event(mrt, c, RTM_DELROUTE); > ipmr_cache_put(c); > > @@ -1248,6 +1295,8 @@ static int ipmr_mfc_add(struct net *net, struct > mr_table *mrt, > if (!mrtsock) > c->mfc_flags |= MFC_STATIC; > write_unlock_bh(&mrt_lock); > + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, > + mrt->id); > mroute_netlink_event(mrt, c, RTM_NEWROUTE); > return 0; > } > @@ -1297,6 +1346,7 @@ static int ipmr_mfc_add(struct net *net, struct > mr_table *mrt, > ipmr_cache_resolve(net, mrt, uc, c); > ipmr_cache_free(uc); > } > + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_ADD, c, mrt->id); > mroute_netlink_event(mrt, c, RTM_NEWROUTE); > return 0; > } > @@ -1304,6 +1354,7 @@ static int ipmr_mfc_add(struct net *net, struct > mr_table *mrt, > /* Close the multicast socket, and clear the vif tables etc */ > static void mroute_clean_tables(struct mr_table *mrt, bool all) > { > + struct net *net = read_pnet(&mrt->net); > struct mfc_cache *c, *tmp; > LIST_HEAD(list); > int i; > @@ -1322,6 +1373,8 @@ static void mroute_clean_tables(struct mr_table *mrt, > bool all) > continue; > rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); > list_del_rcu(&c->list); > + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, > + mrt->id); > mroute_netlink_event(mrt, c, RTM_DELROUTE); > ipmr_cache_put(c); > } >