diff --git a/datapath/linux/compat/dev-openvswitch.c b/datapath/linux/compat/dev-openvswitch.c index 72576657410..56e1a5b6804 100644 --- a/datapath/linux/compat/dev-openvswitch.c +++ b/datapath/linux/compat/dev-openvswitch.c @@ -53,6 +53,7 @@ int rpl_rtnl_delete_link(struct net_device *dev) return 0; } +EXPORT_SYMBOL_GPL(rpl_rtnl_delete_link); #ifndef USE_UPSTREAM_TUNNEL int ovs_dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) diff --git a/datapath/vport-geneve.c b/datapath/vport-geneve.c index 5821ef481d8..14a54f1997a 100644 --- a/datapath/vport-geneve.c +++ b/datapath/vport-geneve.c @@ -93,7 +93,14 @@ static struct vport *geneve_tnl_create(const struct vport_parms *parms) return ERR_CAST(dev); } - dev_change_flags(dev, dev->flags | IFF_UP); + err = dev_change_flags(dev, dev->flags | IFF_UP); + if (err < 0) { + rtnl_delete_link(dev); + rtnl_unlock(); + ovs_vport_free(vport); + goto error; + } + rtnl_unlock(); return vport; error: diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index 32d7d9f7939..1d63734f414 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -54,6 +54,7 @@ static struct vport *gre_tnl_create(const struct vport_parms *parms) struct net *net = ovs_dp_get_net(parms->dp); struct net_device *dev; struct vport *vport; + int err; vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms); if (IS_ERR(vport)) @@ -67,9 +68,15 @@ static struct vport *gre_tnl_create(const struct vport_parms *parms) return ERR_CAST(dev); } - dev_change_flags(dev, dev->flags | IFF_UP); - rtnl_unlock(); + err = dev_change_flags(dev, dev->flags | IFF_UP); + if (err < 0) { + rtnl_delete_link(dev); + rtnl_unlock(); + ovs_vport_free(vport); + return ERR_PTR(err); + } + rtnl_unlock(); return vport; } diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c index 9e894e80a7b..27f40ab4272 100644 --- a/datapath/vport-lisp.c +++ b/datapath/vport-lisp.c @@ -92,8 +92,14 @@ static struct vport *lisp_tnl_create(const struct vport_parms *parms) ovs_vport_free(vport); return ERR_CAST(dev); } + err = dev_change_flags(dev, dev->flags | IFF_UP); + if (err < 0) { + rtnl_delete_link(dev); + rtnl_unlock(); + ovs_vport_free(vport); + goto error; + } - dev_change_flags(dev, dev->flags | IFF_UP); rtnl_unlock(); return vport; error: diff --git a/datapath/vport-stt.c b/datapath/vport-stt.c index 1c838de7667..31fa4624550 100644 --- a/datapath/vport-stt.c +++ b/datapath/vport-stt.c @@ -95,7 +95,14 @@ static struct vport *stt_tnl_create(const struct vport_parms *parms) return ERR_CAST(dev); } - dev_change_flags(dev, dev->flags | IFF_UP); + err = dev_change_flags(dev, dev->flags | IFF_UP); + if (err < 0) { + rtnl_delete_link(dev); + rtnl_unlock(); + ovs_vport_free(vport); + goto error; + } + rtnl_unlock(); return vport; error: diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c index b830a463f07..11965c00421 100644 --- a/datapath/vport-vxlan.c +++ b/datapath/vport-vxlan.c @@ -130,7 +130,14 @@ static struct vport *vxlan_tnl_create(const struct vport_parms *parms) return ERR_CAST(dev); } - dev_change_flags(dev, dev->flags | IFF_UP); + err = dev_change_flags(dev, dev->flags | IFF_UP); + if (err < 0) { + rtnl_delete_link(dev); + rtnl_unlock(); + ovs_vport_free(vport); + goto error; + } + rtnl_unlock(); return vport; error: