This commit adds function in lib/netdev.c to check that the interface name is not the same as any of the registered vport providers' dpif_port name (e.g. gre_system) or the datapath's internal port name (e.g. ovs-system).
This function is called in iface_do_create() function in vswitchd/bridge.c. If there is a name conflict, no interface and of_port will be created. And the warning will be given in the ovs-vswitchd.log Signed-off-by: Alex Wang <al...@nicira.com> --- lib/netdev-vport.c | 15 ++++++++++--- lib/netdev-vport.h | 3 ++- lib/netdev.c | 41 ++++++++++++++++++++++++++++++++++ lib/netdev.h | 1 + tests/ovs-vsctl.at | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vswitchd/bridge.c | 5 +++++ 6 files changed, 123 insertions(+), 4 deletions(-) diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 699ed71..d63c6c7 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -115,6 +115,17 @@ netdev_vport_needs_dst_port(const struct netdev *dev) } const char * +netdev_class_get_dpif_port(const struct netdev_class *class) +{ + const char *dpif_port; + + dpif_port = (is_vport_class(class) + ? vport_class_cast(class)->dpif_port + : NULL); + return dpif_port; +} + +const char * netdev_vport_get_dpif_port(const struct netdev *netdev) { const char *dpif_port; @@ -136,9 +147,7 @@ netdev_vport_get_dpif_port(const struct netdev *netdev) return dpif_port_combined; } else { const struct netdev_class *class = netdev_get_class(netdev); - dpif_port = (is_vport_class(class) - ? vport_class_cast(class)->dpif_port - : NULL); + dpif_port = netdev_class_get_dpif_port(class); } return dpif_port ? dpif_port : netdev_get_name(netdev); diff --git a/lib/netdev-vport.h b/lib/netdev-vport.h index c907b0c..7eaf9b2 100644 --- a/lib/netdev-vport.h +++ b/lib/netdev-vport.h @@ -22,6 +22,7 @@ struct dpif_linux_vport; struct dpif_flow_stats; struct netdev; +struct netdev_class; struct netdev_stats; void netdev_vport_tunnel_register(void); @@ -37,5 +38,5 @@ void netdev_vport_inc_tx(const struct netdev *, const struct dpif_flow_stats *); const char *netdev_vport_get_dpif_port(const struct netdev *); - +const char *netdev_class_get_dpif_port(const struct netdev_class *); #endif /* netdev-vport.h */ diff --git a/lib/netdev.c b/lib/netdev.c index d93526a..5b1d208 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -25,6 +25,7 @@ #include <unistd.h> #include "coverage.h" +#include "dpif.h" #include "dynamic-string.h" #include "fatal-signal.h" #include "hash.h" @@ -200,6 +201,46 @@ netdev_enumerate_types(struct sset *types) } } +/* Check that the network device name is not the same as any of the registered + * vport providers' dpif_port name (dpif_port is NULL if the vport provider + * does not define it) or the datapath internal port name (e.g. ovs-system). + * + * 0 is returned if there is no naming conflict. Otherwise, EINVAL is returned. + */ +int +netdev_check_reserved_word(const char *name) +{ + struct shash_node *node; + struct sset types; + const char *dpif_port; + const char *type; + + dpif_port = NULL; + netdev_initialize(); + SHASH_FOR_EACH(node, &netdev_classes) { + dpif_port = netdev_class_get_dpif_port(node->data); + if (dpif_port && !strcmp(dpif_port, name)) { + VLOG_WARN("name \"%s\" is a reserved name (%s)", + name, strerror(EINVAL)); + return EINVAL; + } + } + + sset_init(&types); + dp_enumerate_types(&types); + SSET_FOR_EACH (type, &types) { + if ((strstr(name, "ovs-") == name) + && (strstr(name, type) == (name + 4))) { + VLOG_WARN("name \"%s\" is a reserved name (%s)", + name, strerror(EINVAL)); + sset_destroy(&types); + return EINVAL; + } + } + sset_destroy(&types); + return 0; +} + /* Opens the network device named 'name' (e.g. "eth0") of the specified 'type' * (e.g. "system") and returns zero if successful, otherwise a positive errno * value. On success, sets '*netdevp' to the new network device, otherwise to diff --git a/lib/netdev.h b/lib/netdev.h index 852b75d..08a6e26 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -106,6 +106,7 @@ void netdev_run(void); void netdev_wait(void); void netdev_enumerate_types(struct sset *types); +int netdev_check_reserved_word(const char *name); /* Open and close. */ int netdev_open(const char *name, const char *type, struct netdev **); diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index 439bd2d..2da05b5 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -1185,3 +1185,65 @@ AT_CHECK([RUN_OVS_VSCTL( [-- list Queue])], [0], [], [], [OVS_VSCTL_CLEANUP]) OVS_VSCTL_CLEANUP AT_CLEANUP + +dnl ---------------------------------------------------------------------- +AT_BANNER([ovs-vsctl add-port -- reserved port names]) + +AT_SETUP([add-port -- reserved names 1]) +OVS_VSWITCHD_START + +# Test creating all reserved port names +m4_foreach( +[reserved_name], +[[ovs-netdev], +[ovs-dummy], +[gre_system], +[gre64_system], +[lisp_system], +[vxlan_system]], +[ +# Try creating the port +AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], []) +# Detect the warning log message +AT_CHECK([sed -n "s/^.*\(|netdev|WARN|.*\)$/\1/p" ovs-vswitchd.log], [0], [dnl +|netdev|WARN|name "reserved_name" is a reserved name (Invalid argument) +]) +# Delete the warning log message +AT_CHECK([sed "/|netdev|WARN|/d" ovs-vswitchd.log > ovs-vswitchd.log], [0], [], []) +# Delete the port +AT_CHECK([ovs-vsctl del-port br0 reserved_name], [0], [], [])]) +OVS_VSWITCHD_STOP +AT_CLEANUP + +AT_SETUP([add-port -- reserved names 2]) +# Creates all type of tunnel ports +OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \ + options:remote_ip=1.1.1.1 ofport_request=1\ + -- add-port br0 p2 -- set Interface p2 type=gre64 \ + options:local_ip=2.2.2.2 options:remote_ip=1.1.1.1 \ + ofport_request=2 \ + -- add-port br0 p3 -- set Interface p3 type=lisp \ + options:remote_ip=2.2.2.2 ofport_request=3 \ + -- add-port br0 p4 -- set Interface p4 type=vxlan \ + options:remote_ip=2.2.2.2 ofport_request=4]) + +# Test creating all reserved tunnel port names +m4_foreach( +[reserved_name], +[[gre_system], +[gre64_system], +[lisp_system], +[vxlan_system]], +[ +# Try creating the port +AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], []) +# Detect the warning log message +AT_CHECK([sed -n "s/^.*\(|netdev|WARN|.*\)$/\1/p" ovs-vswitchd.log], [0], [dnl +|netdev|WARN|name "reserved_name" is a reserved name (Invalid argument) +]) +# Delete the warning log message +AT_CHECK([sed "/|netdev|WARN|/d" ovs-vswitchd.log > ovs-vswitchd.log], [0], [], []) +# Delete the port +AT_CHECK([ovs-vsctl del-port br0 reserved_name], [0], [], [])]) +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index cf26e87..beb1462 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1418,6 +1418,11 @@ iface_do_create(const struct bridge *br, struct netdev *netdev; int error; + error = netdev_check_reserved_word(iface_cfg->name); + if (error) { + goto error; + } + error = netdev_open(iface_cfg->name, iface_get_type(iface_cfg, br->cfg), &netdev); if (error) { -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev