/* Set up our datapath device. */
BUILD_BUG_ON(sizeof(internal_dev_port.devname) != sizeof(devname));
strcpy(internal_dev_port.devname, devname);
- strcpy(internal_dev_port.type, "internal");
+ internal_dev_port.type = ODP_VPORT_TYPE_INTERNAL;
err = new_vport(dp, &internal_dev_port, ODPP_LOCAL);
if (err) {
if (err == -EBUSY)
if (copy_from_user(&port, portp, sizeof(port)))
goto out;
port.devname[IFNAMSIZ - 1] = '\0';
- port.type[VPORT_TYPE_SIZE - 1] = '\0';
rtnl_lock();
dp = get_dp_locked(dp_idx);
{
rcu_read_lock();
strncpy(odp_port->devname, vport_get_name(vport), sizeof(odp_port->devname));
- strncpy(odp_port->type, vport_get_type(vport), sizeof(odp_port->type));
+ odp_port->type = vport_get_type(vport);
vport_get_config(vport, odp_port->config);
odp_port->port = vport->port_no;
odp_port->dp_idx = vport->dp->dp_idx;
/*
- * Copyright (c) 2010 Nicira Networks.
+ * Copyright (c) 2010, 2011 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
}
const struct vport_ops capwap_vport_ops = {
- .type = "capwap",
+ .type = ODP_VPORT_TYPE_CAPWAP,
.flags = VPORT_F_GEN_STATS,
.init = capwap_init,
.exit = capwap_exit,
/*
- * Copyright (c) 2010 Nicira Networks.
+ * Copyright (c) 2010, 2011 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
}
const struct vport_ops gre_vport_ops = {
- .type = "gre",
+ .type = ODP_VPORT_TYPE_GRE,
.flags = VPORT_F_GEN_STATS | VPORT_F_TUN_ID,
.init = gre_init,
.exit = gre_exit,
/*
- * Copyright (c) 2009, 2010 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
}
const struct vport_ops internal_vport_ops = {
- .type = "internal",
+ .type = ODP_VPORT_TYPE_INTERNAL,
.flags = VPORT_F_REQUIRED | VPORT_F_GEN_STATS | VPORT_F_FLOW,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
}
const struct vport_ops netdev_vport_ops = {
- .type = "netdev",
+ .type = ODP_VPORT_TYPE_NETDEV,
.flags = (VPORT_F_REQUIRED |
(USE_VPORT_STATS ? VPORT_F_GEN_STATS : 0)),
.init = netdev_init,
}
const struct vport_ops patch_vport_ops = {
- .type = "patch",
+ .type = ODP_VPORT_TYPE_PATCH,
.flags = VPORT_F_GEN_STATS,
.init = patch_init,
.exit = patch_exit,
ASSERT_VPORT();
for (i = 0; i < n_vport_types; i++) {
- if (!strcmp(vport_ops_list[i]->type, parms->type)) {
+ if (vport_ops_list[i]->type == parms->type) {
vport = vport_ops_list[i]->create(parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
* @vport: vport from which to retrieve the type.
*
* Retrieves the type of the given device. Either RTNL lock or rcu_read_lock
- * must be held for the entire duration that the type is in use.
+ * must be held.
*/
-const char *vport_get_type(const struct vport *vport)
+enum odp_vport_type vport_get_type(const struct vport *vport)
{
return vport->ops->type;
}
int vport_set_stats(struct vport *, struct rtnl_link_stats64 *);
const char *vport_get_name(const struct vport *);
-const char *vport_get_type(const struct vport *);
+enum odp_vport_type vport_get_type(const struct vport *);
const unsigned char *vport_get_addr(const struct vport *);
struct kobject *vport_get_kobj(const struct vport *);
*/
struct vport_parms {
const char *name;
- const char *type;
+ enum odp_vport_type type;
const void *config;
/* For vport_alloc(). */
/**
* struct vport_ops - definition of a type of virtual port
*
- * @type: Name of port type, such as "netdev" or "internal" to be matched
- * against the device type when a new port needs to be created.
+ * @type: %ODP_VPORT_TYPE_* value for this type of virtual port.
* @flags: Flags of type VPORT_F_* that influence how the generic vport layer
* handles this vport.
* @init: Called at module initialization. If VPORT_F_REQUIRED is set then the
* @send: Send a packet on the device. Returns the length of the packet sent.
*/
struct vport_ops {
- const char *type;
+ enum odp_vport_type type;
u32 flags;
/* Called at module init and exit respectively. */
uint32_t len;
};
-#define VPORT_TYPE_SIZE 16
#define VPORT_CONFIG_SIZE 32
struct odp_port {
char devname[16]; /* IFNAMSIZ */
- char type[VPORT_TYPE_SIZE];
+ uint32_t type; /* One of ODP_VPORT_TYPE_*. */
uint16_t port;
uint16_t dp_idx;
uint32_t reserved2;
__aligned_u64 config[VPORT_CONFIG_SIZE / 8]; /* type-specific */
};
+enum odp_vport_type {
+ ODP_VPORT_TYPE_UNSPEC,
+ ODP_VPORT_TYPE_NETDEV, /* network device */
+ ODP_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
+ ODP_VPORT_TYPE_PATCH, /* virtual tunnel connecting two vports */
+ ODP_VPORT_TYPE_GRE, /* GRE tunnel */
+ ODP_VPORT_TYPE_CAPWAP, /* CAPWAP tunnel */
+ __ODP_VPORT_TYPE_MAX
+};
+
+#define ODP_VPORT_TYPE_MAX (__ODP_VPORT_TYPE_MAX - 1)
+
/**
* struct odp_vport_dump - ODP_VPORT_DUMP argument.
* @port: Points to port structure to fill in.
return do_ioctl(dpif_, ODP_SET_DROP_FRAGS, &drop_frags_int);
}
-static void
-translate_vport_type_to_netdev_type(struct odp_port *port)
+static const char *
+vport_type_to_netdev_type(const struct odp_port *odp_port)
{
- char *type = port->type;
+ struct tnl_port_config tnl_config;
- if (!strcmp(type, "netdev")) {
- ovs_strlcpy(type, "system", sizeof port->type);
- } else if (!strcmp(type, "gre")) {
- const struct tnl_port_config *config;
+ switch (odp_port->type) {
+ case ODP_VPORT_TYPE_UNSPEC:
+ break;
- config = (struct tnl_port_config *)port->config;
- if (config->flags & TNL_F_IPSEC) {
- ovs_strlcpy(type, "ipsec_gre", sizeof port->type);
- }
+ case ODP_VPORT_TYPE_NETDEV:
+ return "system";
+
+ case ODP_VPORT_TYPE_INTERNAL:
+ return "internal";
+
+ case ODP_VPORT_TYPE_PATCH:
+ return "patch";
+
+ case ODP_VPORT_TYPE_GRE:
+ memcpy(&tnl_config, odp_port->config, sizeof tnl_config);
+ return tnl_config.flags & TNL_F_IPSEC ? "ipsec_gre" : "gre";
+
+ case ODP_VPORT_TYPE_CAPWAP:
+ return "capwap";
+
+ case __ODP_VPORT_TYPE_MAX:
+ break;
}
+
+ VLOG_WARN_RL(&error_rl, "dp%d: port `%s' has unsupported type %"PRIu32,
+ odp_port->dp_idx, odp_port->devname, odp_port->type);
+ return "unknown";
}
-static void
-translate_netdev_type_to_vport_type(struct odp_port *port)
+static enum odp_vport_type
+netdev_type_to_vport_type(const char *type)
{
- char *type = port->type;
-
- if (!strcmp(type, "system")) {
- ovs_strlcpy(type, "netdev", sizeof port->type);
- } else if (!strcmp(type, "ipsec_gre")) {
- ovs_strlcpy(type, "gre", sizeof port->type);
- }
+ return (!strcmp(type, "system") ? ODP_VPORT_TYPE_NETDEV
+ : !strcmp(type, "internal") ? ODP_VPORT_TYPE_INTERNAL
+ : !strcmp(type, "patch") ? ODP_VPORT_TYPE_PATCH
+ : (!strcmp(type, "gre")
+ || !strcmp(type, "ipsec_gre")) ? ODP_VPORT_TYPE_GRE
+ : !strcmp(type, "capwap") ? ODP_VPORT_TYPE_CAPWAP
+ : ODP_VPORT_TYPE_UNSPEC);
}
static int
memset(&port, 0, sizeof port);
strncpy(port.devname, name, sizeof port.devname);
- strncpy(port.type, type, sizeof port.type);
netdev_vport_get_config(netdev, port.config);
- translate_netdev_type_to_vport_type(&port);
+
+ port.type = netdev_type_to_vport_type(type);
+ if (port.type == ODP_VPORT_TYPE_UNSPEC) {
+ VLOG_WARN_RL(&error_rl, "%s: cannot create port `%s' because it has "
+ "unsupported type `%s'",
+ dpif_name(dpif), name, type);
+ return EINVAL;
+ }
error = do_ioctl(dpif, ODP_VPORT_ATTACH, &port);
if (!error) {
/* A vport named 'port_name' exists but in some other datapath. */
return ENOENT;
} else {
- translate_vport_type_to_netdev_type(&odp_port);
dpif_port->name = xstrdup(odp_port.devname);
- dpif_port->type = xstrdup(odp_port.type);
+ dpif_port->type = xstrdup(vport_type_to_netdev_type(&odp_port));
dpif_port->port_no = odp_port.port;
return 0;
}
} else if (odp_port->devname[0] == '\0') {
return EOF;
} else {
- translate_vport_type_to_netdev_type(odp_port);
dpif_port->name = odp_port->devname;
- dpif_port->type = odp_port->type;
+ dpif_port->type = (char *) vport_type_to_netdev_type(odp_port);
dpif_port->port_no = odp_port->port;
odp_port->port++;
return 0;
name, strerror(errno));
}
return errno;
- } else if (!strcmp(odp_port.type, "internal")) {
+ } else if (odp_port.type == ODP_VPORT_TYPE_INTERNAL) {
*dp_idx = odp_port.dp_idx;
*port_no = odp_port.port;
return 0;
};
struct vport_class {
+ enum odp_vport_type type;
struct netdev_class netdev_class;
int (*parse_config)(const char *name, const char *type,
const struct shash *args, void *config);
memset(&port, 0, sizeof port);
strncpy(port.devname, netdev_dev_get_name(dev_), sizeof port.devname);
- strncpy(port.type, netdev_dev_get_type(dev_), sizeof port.type);
+ port.type = vport_class->type;
error = vport_class->parse_config(netdev_dev_get_name(dev_),
netdev_dev_get_type(dev_),
args, port.config);
netdev_vport_register(void)
{
static const struct vport_class vport_classes[] = {
- { { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+ { ODP_VPORT_TYPE_GRE,
+ { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
parse_tunnel_config, unparse_tunnel_config },
- { { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+
+ { ODP_VPORT_TYPE_GRE,
+ { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
parse_tunnel_config, unparse_tunnel_config },
- { { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
+
+ { ODP_VPORT_TYPE_CAPWAP,
+ { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
parse_tunnel_config, unparse_tunnel_config },
- { { "patch", VPORT_FUNCTIONS(NULL) },
+
+ { ODP_VPORT_TYPE_PATCH,
+ { "patch", VPORT_FUNCTIONS(NULL) },
parse_patch_config, unparse_patch_config }
};