#include "vlog.h"
#define THIS_MODULE VLM_dpif
+/* A datapath interface. */
+struct dpif {
+ char *name;
+ unsigned int minor;
+ int fd;
+};
+
/* Rate limit for individual messages going to or from the datapath, output at
* DBG level. This is very high because, if these are enabled, it is because
* we really need to see them. */
static int get_minor_from_name(const char *name, unsigned int *minor);
static int name_to_minor(const char *name, unsigned int *minor);
static int lookup_minor(const char *name, unsigned int *minor);
-static int open_by_minor(unsigned int minor, struct dpif *);
+static int open_by_minor(unsigned int minor, struct dpif **dpifp);
static int make_openvswitch_device(unsigned int minor, char **fnp);
static void check_rw_odp_flow(struct odp_flow *);
int
-dpif_open(const char *name, struct dpif *dpif)
+dpif_open(const char *name, struct dpif **dpifp)
{
+ struct dpif *dpif;
+ unsigned int minor;
int listen_mask;
int error;
- dpif->fd = -1;
+ *dpifp = NULL;
- error = name_to_minor(name, &dpif->minor);
+ error = name_to_minor(name, &minor);
if (error) {
return error;
}
- error = open_by_minor(dpif->minor, dpif);
+ error = open_by_minor(minor, &dpif);
if (error) {
return error;
}
dpif_close(dpif);
return error;
}
+ *dpifp = dpif;
return 0;
}
{
if (dpif) {
free(dpif->name);
- dpif->name = NULL;
close(dpif->fd);
- dpif->fd = -1;
+ free(dpif);
}
}
}
int
-dpif_create(const char *name, struct dpif *dpif)
+dpif_create(const char *name, struct dpif **dpifp)
{
unsigned int minor;
int error;
+ *dpifp = NULL;
if (!get_minor_from_name(name, &minor)) {
/* Minor was specified in 'name', go ahead and create it. */
- error = open_by_minor(minor, dpif);
+ struct dpif *dpif;
+
+ error = open_by_minor(minor, &dpif);
if (error) {
return error;
}
} else {
error = ioctl(dpif->fd, ODP_DP_CREATE, name) < 0 ? errno : 0;
}
- if (error) {
+ if (!error) {
+ *dpifp = dpif;
+ } else {
dpif_close(dpif);
}
return error;
} else {
for (minor = 0; minor < ODP_MAX; minor++) {
- error = open_by_minor(minor, dpif);
+ struct dpif *dpif;
+
+ error = open_by_minor(minor, &dpif);
if (error) {
return error;
}
error = ioctl(dpif->fd, ODP_DP_CREATE, name) < 0 ? errno : 0;
if (!error) {
+ *dpifp = dpif;
return 0;
}
dpif_close(dpif);
dpif_name(dpif), devname, port->port);
return 0;
} else {
- VLOG_WARN_RL(&error_rl, "%s: failed to query port %s: %s",
- dpif_name(dpif), devname, strerror(errno));
+ /* Log level is DBG here because all the current callers are interested
+ * in whether 'dpif' actually has a port 'devname', so that it's not an
+ * issue worth logging if it doesn't. */
+ VLOG_DBG_RL(&error_rl, "%s: failed to query port %s: %s",
+ dpif_name(dpif), devname, strerror(errno));
return errno;
}
}
}
\f
struct dpifmon {
- struct dpif dpif;
+ struct dpif *dpif;
struct nl_sock *sock;
int local_ifindex;
};
if (error) {
goto error;
}
- error = dpif_port_get_name(&mon->dpif, ODPP_LOCAL,
+ error = dpif_port_get_name(mon->dpif, ODPP_LOCAL,
local_name, sizeof local_name);
if (error) {
goto error_close_dpif;
return 0;
error_close_dpif:
- dpif_close(&mon->dpif);
+ dpif_close(mon->dpif);
error:
free(mon);
*monp = NULL;
dpifmon_destroy(struct dpifmon *mon)
{
if (mon) {
- dpif_close(&mon->dpif);
+ dpif_close(mon->dpif);
nl_sock_destroy(mon->sock);
}
}
uint32_t master_ifindex = nl_attr_get_u32(attrs[IFLA_MASTER]);
for_us = master_ifindex == mon->local_ifindex;
} else {
- /* It's for us if that device is one of our ports. This is
- * open-coded instead of using dpif_port_query_by_name() to
- * avoid logging a warning on failure. */
+ /* It's for us if that device is one of our ports. */
struct odp_port port;
- memset(&port, 0, sizeof port);
- strncpy(port.devname, devname, sizeof port.devname);
- for_us = !ioctl(mon->dpif.fd, ODP_PORT_QUERY, &port);
+ for_us = !dpif_port_query_by_name(mon->dpif, devname, &port);
}
if (!for_us) {
}
static int
-open_by_minor(unsigned int minor, struct dpif *dpif)
+open_by_minor(unsigned int minor, struct dpif **dpifp)
{
+ struct dpif *dpif;
int error;
char *fn;
int fd;
- dpif->minor = -1;
- dpif->fd = -1;
+ *dpifp = NULL;
error = make_openvswitch_device(minor, &fn);
if (error) {
return error;
free(fn);
return error;
}
-
free(fn);
+
+ dpif = xmalloc(sizeof *dpif);
dpif->name = xasprintf("dp%u", dpif->minor);
dpif->minor = minor;
dpif->fd = fd;
+ *dpifp = dpif;
return 0;
}
\f