Skip to content

Commit 61f46fe

Browse files
pmachatadavem330
authored andcommitted
vxlan: Allow vetoing of FDB notifications
Change vxlan_fdb_switchdev_call_notifiers() to return the result from calling switchdev notifiers. Propagate the error number up the stack. In vxlan_fdb_update_existing() and vxlan_fdb_update_create() add rollbacks to clean up the work that was done before the veto. Signed-off-by: Petr Machata <petrm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ccdfd4f commit 61f46fe

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

drivers/net/vxlan.c

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -375,32 +375,38 @@ static void vxlan_fdb_switchdev_notifier_info(const struct vxlan_dev *vxlan,
375375
fdb_info->added_by_user = fdb->flags & NTF_VXLAN_ADDED_BY_USER;
376376
}
377377

378-
static void vxlan_fdb_switchdev_call_notifiers(struct vxlan_dev *vxlan,
379-
struct vxlan_fdb *fdb,
380-
struct vxlan_rdst *rd,
381-
bool adding)
378+
static int vxlan_fdb_switchdev_call_notifiers(struct vxlan_dev *vxlan,
379+
struct vxlan_fdb *fdb,
380+
struct vxlan_rdst *rd,
381+
bool adding)
382382
{
383383
struct switchdev_notifier_vxlan_fdb_info info;
384384
enum switchdev_notifier_type notifier_type;
385+
int ret;
385386

386387
if (WARN_ON(!rd))
387-
return;
388+
return 0;
388389

389390
notifier_type = adding ? SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE
390391
: SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE;
391392
vxlan_fdb_switchdev_notifier_info(vxlan, fdb, rd, &info);
392-
call_switchdev_notifiers(notifier_type, vxlan->dev,
393-
&info.info);
393+
ret = call_switchdev_notifiers(notifier_type, vxlan->dev,
394+
&info.info);
395+
return notifier_to_errno(ret);
394396
}
395397

396-
static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
397-
struct vxlan_rdst *rd, int type, bool swdev_notify)
398+
static int vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
399+
struct vxlan_rdst *rd, int type, bool swdev_notify)
398400
{
401+
int err;
402+
399403
if (swdev_notify) {
400404
switch (type) {
401405
case RTM_NEWNEIGH:
402-
vxlan_fdb_switchdev_call_notifiers(vxlan, fdb, rd,
403-
true);
406+
err = vxlan_fdb_switchdev_call_notifiers(vxlan, fdb, rd,
407+
true);
408+
if (err)
409+
return err;
404410
break;
405411
case RTM_DELNEIGH:
406412
vxlan_fdb_switchdev_call_notifiers(vxlan, fdb, rd,
@@ -410,6 +416,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
410416
}
411417

412418
__vxlan_fdb_notify(vxlan, fdb, rd, type);
419+
return 0;
413420
}
414421

415422
static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
@@ -868,7 +875,8 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
868875
struct vxlan_rdst *rd = NULL;
869876
struct vxlan_rdst oldrd;
870877
int notify = 0;
871-
int rc;
878+
int rc = 0;
879+
int err;
872880

873881
/* Do not allow an externally learned entry to take over an entry added
874882
* by the user.
@@ -915,10 +923,20 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
915923
if (rd == NULL)
916924
rd = first_remote_rtnl(f);
917925

918-
vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH, swdev_notify);
926+
err = vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH,
927+
swdev_notify);
928+
if (err)
929+
goto err_notify;
919930
}
920931

921932
return 0;
933+
934+
err_notify:
935+
if ((flags & NLM_F_REPLACE) && rc)
936+
*rd = oldrd;
937+
else if ((flags & NLM_F_APPEND) && rc)
938+
list_del_rcu(&rd->list);
939+
return err;
922940
}
923941

924942
static int vxlan_fdb_update_create(struct vxlan_dev *vxlan,
@@ -943,9 +961,16 @@ static int vxlan_fdb_update_create(struct vxlan_dev *vxlan,
943961
if (rc < 0)
944962
return rc;
945963

946-
vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH,
947-
swdev_notify);
964+
rc = vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH,
965+
swdev_notify);
966+
if (rc)
967+
goto err_notify;
968+
948969
return 0;
970+
971+
err_notify:
972+
vxlan_fdb_destroy(vxlan, f, false, false);
973+
return rc;
949974
}
950975

951976
/* Add new entry to forwarding table -- assumes lock held */
@@ -3515,9 +3540,12 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
35153540
goto errout;
35163541

35173542
/* notify default fdb entry */
3518-
if (f)
3519-
vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH,
3520-
true);
3543+
if (f) {
3544+
err = vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f),
3545+
RTM_NEWNEIGH, true);
3546+
if (err)
3547+
goto errout;
3548+
}
35213549

35223550
list_add(&vxlan->next, &vn->vxlan_list);
35233551
return 0;

0 commit comments

Comments
 (0)