diff options
-rw-r--r-- | drivers/net/vxlan.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index e375560cc74e..bdb6ae16d4a8 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -2976,6 +2976,44 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2976 | return 0; | 2976 | return 0; |
2977 | } | 2977 | } |
2978 | 2978 | ||
2979 | static int __vxlan_dev_create(struct net *net, struct net_device *dev, | ||
2980 | struct vxlan_config *conf) | ||
2981 | { | ||
2982 | struct vxlan_net *vn = net_generic(net, vxlan_net_id); | ||
2983 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
2984 | int err; | ||
2985 | |||
2986 | err = vxlan_dev_configure(net, dev, conf, false); | ||
2987 | if (err) | ||
2988 | return err; | ||
2989 | |||
2990 | dev->ethtool_ops = &vxlan_ethtool_ops; | ||
2991 | |||
2992 | /* create an fdb entry for a valid default destination */ | ||
2993 | if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { | ||
2994 | err = vxlan_fdb_create(vxlan, all_zeros_mac, | ||
2995 | &vxlan->default_dst.remote_ip, | ||
2996 | NUD_REACHABLE | NUD_PERMANENT, | ||
2997 | NLM_F_EXCL | NLM_F_CREATE, | ||
2998 | vxlan->cfg.dst_port, | ||
2999 | vxlan->default_dst.remote_vni, | ||
3000 | vxlan->default_dst.remote_vni, | ||
3001 | vxlan->default_dst.remote_ifindex, | ||
3002 | NTF_SELF); | ||
3003 | if (err) | ||
3004 | return err; | ||
3005 | } | ||
3006 | |||
3007 | err = register_netdevice(dev); | ||
3008 | if (err) { | ||
3009 | vxlan_fdb_delete_default(vxlan, vxlan->default_dst.remote_vni); | ||
3010 | return err; | ||
3011 | } | ||
3012 | |||
3013 | list_add(&vxlan->next, &vn->vxlan_list); | ||
3014 | return 0; | ||
3015 | } | ||
3016 | |||
2979 | static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], | 3017 | static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], |
2980 | struct net_device *dev, struct vxlan_config *conf, | 3018 | struct net_device *dev, struct vxlan_config *conf, |
2981 | bool changelink) | 3019 | bool changelink) |
@@ -3172,8 +3210,6 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], | |||
3172 | static int vxlan_newlink(struct net *src_net, struct net_device *dev, | 3210 | static int vxlan_newlink(struct net *src_net, struct net_device *dev, |
3173 | struct nlattr *tb[], struct nlattr *data[]) | 3211 | struct nlattr *tb[], struct nlattr *data[]) |
3174 | { | 3212 | { |
3175 | struct vxlan_net *vn = net_generic(src_net, vxlan_net_id); | ||
3176 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
3177 | struct vxlan_config conf; | 3213 | struct vxlan_config conf; |
3178 | int err; | 3214 | int err; |
3179 | 3215 | ||
@@ -3181,36 +3217,7 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev, | |||
3181 | if (err) | 3217 | if (err) |
3182 | return err; | 3218 | return err; |
3183 | 3219 | ||
3184 | err = vxlan_dev_configure(src_net, dev, &conf, false); | 3220 | return __vxlan_dev_create(src_net, dev, &conf); |
3185 | if (err) | ||
3186 | return err; | ||
3187 | |||
3188 | dev->ethtool_ops = &vxlan_ethtool_ops; | ||
3189 | |||
3190 | /* create an fdb entry for a valid default destination */ | ||
3191 | if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { | ||
3192 | err = vxlan_fdb_create(vxlan, all_zeros_mac, | ||
3193 | &vxlan->default_dst.remote_ip, | ||
3194 | NUD_REACHABLE | NUD_PERMANENT, | ||
3195 | NLM_F_EXCL | NLM_F_CREATE, | ||
3196 | vxlan->cfg.dst_port, | ||
3197 | vxlan->default_dst.remote_vni, | ||
3198 | vxlan->default_dst.remote_vni, | ||
3199 | vxlan->default_dst.remote_ifindex, | ||
3200 | NTF_SELF); | ||
3201 | if (err) | ||
3202 | return err; | ||
3203 | } | ||
3204 | |||
3205 | err = register_netdevice(dev); | ||
3206 | if (err) { | ||
3207 | vxlan_fdb_delete_default(vxlan, vxlan->default_dst.remote_vni); | ||
3208 | return err; | ||
3209 | } | ||
3210 | |||
3211 | list_add(&vxlan->next, &vn->vxlan_list); | ||
3212 | |||
3213 | return 0; | ||
3214 | } | 3221 | } |
3215 | 3222 | ||
3216 | static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], | 3223 | static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], |
@@ -3440,7 +3447,7 @@ struct net_device *vxlan_dev_create(struct net *net, const char *name, | |||
3440 | if (IS_ERR(dev)) | 3447 | if (IS_ERR(dev)) |
3441 | return dev; | 3448 | return dev; |
3442 | 3449 | ||
3443 | err = vxlan_dev_configure(net, dev, conf, false); | 3450 | err = __vxlan_dev_create(net, dev, conf); |
3444 | if (err < 0) { | 3451 | if (err < 0) { |
3445 | free_netdev(dev); | 3452 | free_netdev(dev); |
3446 | return ERR_PTR(err); | 3453 | return ERR_PTR(err); |