/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
&dpif_linux_class,
#endif
&dpif_netdev_class,
+ &dpif_planetlab_class,
};
struct registered_dpif_class {
static void log_flow_message(const struct dpif *dpif, int error,
const char *operation,
const struct nlattr *key, size_t key_len,
+ const struct nlattr *mask, size_t mask_len,
const struct dpif_flow_stats *stats,
const struct nlattr *actions, size_t actions_len);
static void log_operation(const struct dpif *, const char *operation,
if (error) {
VLOG_WARN("failed to enumerate %s datapaths: %s", dpif_class->type,
- strerror(error));
+ ovs_strerror(error));
}
return error;
error = dpif_open(name, type, dpifp);
if (error) {
VLOG_WARN("datapath %s already exists but cannot be opened: %s",
- name, strerror(error));
+ name, ovs_strerror(error));
}
} else if (error) {
- VLOG_WARN("failed to create datapath %s: %s", name, strerror(error));
+ VLOG_WARN("failed to create datapath %s: %s",
+ name, ovs_strerror(error));
}
return error;
}
dpif_name(dpif), netdev_name, port_no);
} else {
VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s",
- dpif_name(dpif), netdev_name, strerror(error));
+ dpif_name(dpif), netdev_name, ovs_strerror(error));
port_no = ODPP_NONE;
}
if (port_nop) {
int error = dpif->dpif_class->port_query_by_name(dpif, devname, NULL);
if (error != 0 && error != ENOENT && error != ENODEV) {
VLOG_WARN_RL(&error_rl, "%s: failed to query port %s: %s",
- dpif_name(dpif), devname, strerror(error));
+ dpif_name(dpif), devname, ovs_strerror(error));
}
return !error;
} else {
memset(port, 0, sizeof *port);
VLOG_WARN_RL(&error_rl, "%s: failed to query port %"PRIu32": %s",
- dpif_name(dpif), port_no, strerror(error));
+ dpif_name(dpif), port_no, ovs_strerror(error));
}
return error;
}
VLOG_RL(&error_rl,
error == ENOENT || error == ENODEV ? VLL_DBG : VLL_WARN,
"%s: failed to query port %s: %s",
- dpif_name(dpif), devname, strerror(error));
+ dpif_name(dpif), devname, ovs_strerror(error));
}
return error;
}
actions = NULL;
actions_len = 0;
}
- log_flow_message(dpif, error, "flow_get", key, key_len, stats,
- actions, actions_len);
+ log_flow_message(dpif, error, "flow_get", key, key_len,
+ NULL, 0, stats, actions, actions_len);
}
return error;
}
} else if (should_log_flow_message(error)) {
log_flow_message(dpif, error, "flow_dump",
key ? *key : NULL, key ? *key_len : 0,
+ mask ? *mask : NULL, mask ? *mask_len : 0,
stats ? *stats : NULL, actions ? *actions : NULL,
actions ? *actions_len : 0);
}
dpif_name(dpif), operation, ofperr_get_name(error));
} else {
VLOG_WARN_RL(&error_rl, "%s: %s failed (%s)",
- dpif_name(dpif), operation, strerror(error));
+ dpif_name(dpif), operation, ovs_strerror(error));
}
}
static enum vlog_level
flow_message_log_level(int error)
{
- return error ? VLL_WARN : VLL_DBG;
+ /* If flows arrive in a batch, userspace may push down multiple
+ * unique flow definitions that overlap when wildcards are applied.
+ * Kernels that support flow wildcarding will reject these flows as
+ * duplicates (EEXIST), so lower the log level to debug for these
+ * types of messages. */
+ return (error && error != EEXIST) ? VLL_WARN : VLL_DBG;
}
static bool
static void
log_flow_message(const struct dpif *dpif, int error, const char *operation,
const struct nlattr *key, size_t key_len,
+ const struct nlattr *mask, size_t mask_len,
const struct dpif_flow_stats *stats,
const struct nlattr *actions, size_t actions_len)
{
}
ds_put_format(&ds, "%s ", operation);
if (error) {
- ds_put_format(&ds, "(%s) ", strerror(error));
+ ds_put_format(&ds, "(%s) ", ovs_strerror(error));
}
- odp_flow_key_format(key, key_len, &ds);
+ odp_flow_format(key, key_len, mask, mask_len, &ds);
if (stats) {
ds_put_cstr(&ds, ", ");
dpif_flow_stats_format(stats, &ds);
ds_put_cstr(&s, "[zero]");
}
log_flow_message(dpif, error, ds_cstr(&s),
- put->key, put->key_len, put->stats,
- put->actions, put->actions_len);
+ put->key, put->key_len, put->mask, put->mask_len,
+ put->stats, put->actions, put->actions_len);
ds_destroy(&s);
}
}
{
if (should_log_flow_message(error)) {
log_flow_message(dpif, error, "flow_del", del->key, del->key_len,
- !error ? del->stats : NULL, NULL, 0);
+ NULL, 0, !error ? del->stats : NULL, NULL, 0);
}
}
ds_put_format(&ds, "%s: execute ", dpif_name(dpif));
format_odp_actions(&ds, execute->actions, execute->actions_len);
if (error) {
- ds_put_format(&ds, " failed (%s)", strerror(error));
+ ds_put_format(&ds, " failed (%s)", ovs_strerror(error));
}
ds_put_format(&ds, " on packet %s", packet);
vlog(THIS_MODULE, error ? VLL_WARN : VLL_DBG, "%s", ds_cstr(&ds));