mirror of
https://github.com/openvswitch/ovs
synced 2025-09-04 00:05:15 +00:00
Add functions to determine how port should be opened based on type.
Depending on the port and type of datapath, a port may need to be opened as a different type of device than it's configured. For example, an "internal" port on a "dummy" datapath should opened as a "dummy" port. This commit adds the ability for a dpif to provide this information to a caller. It will be used in a future commit. Signed-off-by: Justin Pettit <jpettit@nicira.com>
This commit is contained in:
@@ -1281,6 +1281,7 @@ dpif_linux_recv_purge(struct dpif *dpif_)
|
|||||||
const struct dpif_class dpif_linux_class = {
|
const struct dpif_class dpif_linux_class = {
|
||||||
"system",
|
"system",
|
||||||
dpif_linux_enumerate,
|
dpif_linux_enumerate,
|
||||||
|
NULL,
|
||||||
dpif_linux_open,
|
dpif_linux_open,
|
||||||
dpif_linux_close,
|
dpif_linux_close,
|
||||||
dpif_linux_destroy,
|
dpif_linux_destroy,
|
||||||
|
@@ -181,6 +181,14 @@ dpif_netdev_enumerate(struct sset *all_dps)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
dpif_netdev_port_open_type(const struct dpif_class *class, const char *type)
|
||||||
|
{
|
||||||
|
return strcmp(type, "internal") ? type
|
||||||
|
: class != &dpif_netdev_class ? "dummy"
|
||||||
|
: "tap";
|
||||||
|
}
|
||||||
|
|
||||||
static struct dpif *
|
static struct dpif *
|
||||||
create_dpif_netdev(struct dp_netdev *dp)
|
create_dpif_netdev(struct dp_netdev *dp)
|
||||||
{
|
{
|
||||||
@@ -369,9 +377,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
|
|||||||
/* XXX reject devices already in some dp_netdev. */
|
/* XXX reject devices already in some dp_netdev. */
|
||||||
|
|
||||||
/* Open and validate network device. */
|
/* Open and validate network device. */
|
||||||
open_type = (strcmp(type, "internal") ? type
|
open_type = dpif_netdev_port_open_type(dp->class, type);
|
||||||
: dp->class != &dpif_netdev_class ? "dummy"
|
|
||||||
: "tap");
|
|
||||||
error = netdev_open(devname, open_type, &netdev);
|
error = netdev_open(devname, open_type, &netdev);
|
||||||
if (error) {
|
if (error) {
|
||||||
return error;
|
return error;
|
||||||
@@ -1282,6 +1288,7 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
|
|||||||
const struct dpif_class dpif_netdev_class = {
|
const struct dpif_class dpif_netdev_class = {
|
||||||
"netdev",
|
"netdev",
|
||||||
dpif_netdev_enumerate,
|
dpif_netdev_enumerate,
|
||||||
|
dpif_netdev_port_open_type,
|
||||||
dpif_netdev_open,
|
dpif_netdev_open,
|
||||||
dpif_netdev_close,
|
dpif_netdev_close,
|
||||||
dpif_netdev_destroy,
|
dpif_netdev_destroy,
|
||||||
|
@@ -80,6 +80,17 @@ struct dpif_class {
|
|||||||
* case this function may be a null pointer. */
|
* case this function may be a null pointer. */
|
||||||
int (*enumerate)(struct sset *all_dps);
|
int (*enumerate)(struct sset *all_dps);
|
||||||
|
|
||||||
|
/* Returns the type to pass to netdev_open() when a dpif of class
|
||||||
|
* 'dpif_class' has a port of type 'type', for a few special cases
|
||||||
|
* when a netdev type differs from a port type. For example, when
|
||||||
|
* using the userspace datapath, a port of type "internal" needs to
|
||||||
|
* be opened as "tap".
|
||||||
|
*
|
||||||
|
* Returns either 'type' itself or a string literal, which must not
|
||||||
|
* be freed. */
|
||||||
|
const char *(*port_open_type)(const struct dpif_class *dpif_class,
|
||||||
|
const char *type);
|
||||||
|
|
||||||
/* Attempts to open an existing dpif called 'name', if 'create' is false,
|
/* Attempts to open an existing dpif called 'name', if 'create' is false,
|
||||||
* or to open an existing dpif or create a new one, if 'create' is true.
|
* or to open an existing dpif or create a new one, if 'create' is true.
|
||||||
*
|
*
|
||||||
|
17
lib/dpif.c
17
lib/dpif.c
@@ -417,6 +417,23 @@ dpif_get_dp_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
dpif_port_open_type(const char *datapath_type, const char *port_type)
|
||||||
|
{
|
||||||
|
struct registered_dpif_class *registered_class;
|
||||||
|
|
||||||
|
datapath_type = dpif_normalize_type(datapath_type);
|
||||||
|
|
||||||
|
registered_class = shash_find_data(&dpif_classes, datapath_type);
|
||||||
|
if (!registered_class
|
||||||
|
|| !registered_class->dpif_class->port_open_type) {
|
||||||
|
return port_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registered_class->dpif_class->port_open_type(
|
||||||
|
registered_class->dpif_class, port_type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is
|
/* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is
|
||||||
* non-null and its value is not UINT32_MAX, then attempts to use the
|
* non-null and its value is not UINT32_MAX, then attempts to use the
|
||||||
* value as the port number.
|
* value as the port number.
|
||||||
|
@@ -73,6 +73,8 @@ int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *);
|
|||||||
|
|
||||||
/* Port operations. */
|
/* Port operations. */
|
||||||
|
|
||||||
|
const char *dpif_port_open_type(const char *datapath_type,
|
||||||
|
const char *port_type);
|
||||||
int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
|
int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
|
||||||
int dpif_port_del(struct dpif *, uint32_t port_no);
|
int dpif_port_del(struct dpif *, uint32_t port_no);
|
||||||
|
|
||||||
|
@@ -780,6 +780,12 @@ del(const char *type, const char *name)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
port_open_type(const char *datapath_type, const char *port_type)
|
||||||
|
{
|
||||||
|
return dpif_port_open_type(datapath_type, port_type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Type functions. */
|
/* Type functions. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -7865,6 +7871,7 @@ const struct ofproto_class ofproto_dpif_class = {
|
|||||||
enumerate_types,
|
enumerate_types,
|
||||||
enumerate_names,
|
enumerate_names,
|
||||||
del,
|
del,
|
||||||
|
port_open_type,
|
||||||
type_run,
|
type_run,
|
||||||
type_run_fast,
|
type_run_fast,
|
||||||
type_wait,
|
type_wait,
|
||||||
|
@@ -382,6 +382,17 @@ struct ofproto_class {
|
|||||||
*/
|
*/
|
||||||
int (*del)(const char *type, const char *name);
|
int (*del)(const char *type, const char *name);
|
||||||
|
|
||||||
|
/* Returns the type to pass to netdev_open() when a datapath of type
|
||||||
|
* 'datapath_type' has a port of type 'port_type', for a few special
|
||||||
|
* cases when a netdev type differs from a port type. For example,
|
||||||
|
* when using the userspace datapath, a port of type "internal"
|
||||||
|
* needs to be opened as "tap".
|
||||||
|
*
|
||||||
|
* Returns either 'type' itself or a string literal, which must not
|
||||||
|
* be freed. */
|
||||||
|
const char *(*port_open_type)(const char *datapath_type,
|
||||||
|
const char *port_type);
|
||||||
|
|
||||||
/* ## ------------------------ ## */
|
/* ## ------------------------ ## */
|
||||||
/* ## Top-Level type Functions ## */
|
/* ## Top-Level type Functions ## */
|
||||||
/* ## ------------------------ ## */
|
/* ## ------------------------ ## */
|
||||||
|
@@ -1433,6 +1433,30 @@ ofproto_port_dump_done(struct ofproto_port_dump *dump)
|
|||||||
return dump->error == EOF ? 0 : dump->error;
|
return dump->error == EOF ? 0 : dump->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the type to pass to netdev_open() when a datapath of type
|
||||||
|
* 'datapath_type' has a port of type 'port_type', for a few special
|
||||||
|
* cases when a netdev type differs from a port type. For example, when
|
||||||
|
* using the userspace datapath, a port of type "internal" needs to be
|
||||||
|
* opened as "tap".
|
||||||
|
*
|
||||||
|
* Returns either 'type' itself or a string literal, which must not be
|
||||||
|
* freed. */
|
||||||
|
const char *
|
||||||
|
ofproto_port_open_type(const char *datapath_type, const char *port_type)
|
||||||
|
{
|
||||||
|
const struct ofproto_class *class;
|
||||||
|
|
||||||
|
datapath_type = ofproto_normalize_type(datapath_type);
|
||||||
|
class = ofproto_class_find__(datapath_type);
|
||||||
|
if (!class) {
|
||||||
|
return port_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (class->port_open_type
|
||||||
|
? class->port_open_type(datapath_type, port_type)
|
||||||
|
: port_type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Attempts to add 'netdev' as a port on 'ofproto'. If 'ofp_portp' is
|
/* Attempts to add 'netdev' as a port on 'ofproto'. If 'ofp_portp' is
|
||||||
* non-null and '*ofp_portp' is not OFPP_NONE, attempts to use that as
|
* non-null and '*ofp_portp' is not OFPP_NONE, attempts to use that as
|
||||||
* the port's OpenFlow port number.
|
* the port's OpenFlow port number.
|
||||||
|
@@ -207,6 +207,8 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
|
|||||||
#define OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT 1000
|
#define OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT 1000
|
||||||
#define OFPROTO_FLOW_EVICTION_THRESHOLD_MIN 100
|
#define OFPROTO_FLOW_EVICTION_THRESHOLD_MIN 100
|
||||||
|
|
||||||
|
const char *ofproto_port_open_type(const char *datapath_type,
|
||||||
|
const char *port_type);
|
||||||
int ofproto_port_add(struct ofproto *, struct netdev *, uint16_t *ofp_portp);
|
int ofproto_port_add(struct ofproto *, struct netdev *, uint16_t *ofp_portp);
|
||||||
int ofproto_port_del(struct ofproto *, uint16_t ofp_port);
|
int ofproto_port_del(struct ofproto *, uint16_t ofp_port);
|
||||||
int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
|
int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
|
||||||
|
Reference in New Issue
Block a user