#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);
}
\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);
}
}
}
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