str_to_mac(addr, oada->dl_addr);
}
-static bool
-parse_port_name(const char *name, uint16_t *port)
-{
- struct pair {
- const char *name;
- uint16_t value;
- };
- static const struct pair pairs[] = {
-#define DEF_PAIR(NAME) {#NAME, OFPP_##NAME}
- DEF_PAIR(IN_PORT),
- DEF_PAIR(TABLE),
- DEF_PAIR(NORMAL),
- DEF_PAIR(FLOOD),
- DEF_PAIR(ALL),
- DEF_PAIR(CONTROLLER),
- DEF_PAIR(LOCAL),
- DEF_PAIR(NONE),
-#undef DEF_PAIR
- };
- static const int n_pairs = ARRAY_SIZE(pairs);
- size_t i;
-
- for (i = 0; i < n_pairs; i++) {
- if (!strcasecmp(name, pairs[i].name)) {
- *port = pairs[i].value;
- return true;
- }
- }
- return false;
-}
-
static void
parse_output(struct ofpbuf *b, char *arg)
{
in_port_s = strsep(&arg, ",");
if (in_port_s && in_port_s[0]) {
- if (!parse_port_name(in_port_s, &in_port)) {
+ if (!ofputil_port_from_string(in_port_s, &in_port)) {
in_port = str_to_u32(in_port_s);
}
} else {
} else {
oao->max_len = htons(UINT16_MAX);
}
- } else if (parse_port_name(act, &port)) {
+ } else if (ofputil_port_from_string(act, &port)) {
put_output_action(b, port);
- } else if (strspn(act, "0123456789") == strlen(act)) {
- put_output_action(b, str_to_u32(act));
} else {
ovs_fatal(0, "Unknown action: %s", act);
}
break;
case F_IN_PORT:
- if (!parse_port_name(value, &port_no)) {
+ if (!ofputil_port_from_string(value, &port_no)) {
port_no = atoi(value);
}
cls_rule_set_in_port(rule, port_no);
#include "unaligned.h"
#include "util.h"
-static void ofp_print_port_name(struct ds *string, uint16_t port);
static void ofp_print_queue_name(struct ds *string, uint32_t port);
static void ofp_print_error(struct ds *, int error);
ds_put_format(string, " total_len=%"PRIu16" in_port=",
ntohs(op->total_len));
- ofp_print_port_name(string, ntohs(op->in_port));
+ ofputil_format_port(ntohs(op->in_port), string);
if (op->reason == OFPR_ACTION)
ds_put_cstr(string, " (via action)");
}
}
-static void ofp_print_port_name(struct ds *string, uint16_t port)
-{
- const char *name;
- switch (port) {
- case OFPP_IN_PORT:
- name = "IN_PORT";
- break;
- case OFPP_TABLE:
- name = "TABLE";
- break;
- case OFPP_NORMAL:
- name = "NORMAL";
- break;
- case OFPP_FLOOD:
- name = "FLOOD";
- break;
- case OFPP_ALL:
- name = "ALL";
- break;
- case OFPP_CONTROLLER:
- name = "CONTROLLER";
- break;
- case OFPP_LOCAL:
- name = "LOCAL";
- break;
- case OFPP_NONE:
- name = "NONE";
- break;
- default:
- ds_put_format(string, "%"PRIu16, port);
- return;
- }
- ds_put_cstr(string, name);
-}
-
-
static void
print_note(struct ds *string, const struct nx_action_note *nan)
{
if (port < OFPP_MAX) {
ds_put_format(s, "output:%"PRIu16, port);
} else {
- ofp_print_port_name(s, port);
+ ofputil_format_port(port, s);
if (port == OFPP_CONTROLLER) {
if (a->output.max_len != htons(0)) {
ds_put_format(s, ":%"PRIu16, ntohs(a->output.max_len));
case OFPUTIL_OFPAT_ENQUEUE:
oae = (const struct ofp_action_enqueue *) a;
ds_put_format(s, "enqueue:");
- ofp_print_port_name(s, ntohs(oae->port));
+ ofputil_format_port(ntohs(oae->port), s);
ds_put_format(s, "q%"PRIu32, ntohl(oae->queue_id));
break;
case OFPUTIL_NXAST_RESUBMIT:
nar = (struct nx_action_resubmit *)a;
ds_put_format(s, "resubmit:");
- ofp_print_port_name(s, ntohs(nar->in_port));
+ ofputil_format_port(ntohs(nar->in_port), s);
break;
case OFPUTIL_NXAST_RESUBMIT_TABLE:
nar = (struct nx_action_resubmit *)a;
ds_put_format(s, "resubmit(");
if (nar->in_port != htons(OFPP_IN_PORT)) {
- ofp_print_port_name(s, ntohs(nar->in_port));
+ ofputil_format_port(ntohs(nar->in_port), s);
}
ds_put_char(s, ',');
if (nar->table != 255) {
size_t actions_len = ntohs(opo->actions_len);
ds_put_cstr(string, " in_port=");
- ofp_print_port_name(string, ntohs(opo->in_port));
+ ofputil_format_port(ntohs(opo->in_port), string);
ds_put_format(string, " actions_len=%zu ", actions_len);
if (actions_len > (ntohs(opo->header.length) - sizeof *opo)) {
name[j] = '\0';
ds_put_char(string, ' ');
- ofp_print_port_name(string, ntohs(port->port_no));
+ ofputil_format_port(ntohs(port->port_no), string);
ds_put_format(string, "(%s): addr:"ETH_ADDR_FMT"\n",
name, ETH_ADDR_ARGS(port->hw_addr));
if (fsr.out_port != OFPP_NONE) {
ds_put_cstr(string, " out_port=");
- ofp_print_port_name(string, fsr.out_port);
+ ofputil_format_port(fsr.out_port, string);
}
/* A flow stats request doesn't include a priority, but cls_rule_format()
const struct ofp_queue_stats_request *qsr)
{
ds_put_cstr(string, "port=");
- ofp_print_port_name(string, ntohs(qsr->port_no));
+ ofputil_format_port(ntohs(qsr->port_no), string);
ds_put_cstr(string, " queue=");
ofp_print_queue_name(string, ntohl(qsr->queue_id));
for (; n--; qs++) {
ds_put_cstr(string, " port ");
- ofp_print_port_name(string, ntohs(qs->port_no));
+ ofputil_format_port(ntohs(qs->port_no), string);
ds_put_cstr(string, " queue ");
ofp_print_queue_name(string, ntohl(qs->queue_id));
ds_put_cstr(string, ": ");
}
}
+#define OFPUTIL_NAMED_PORTS \
+ OFPUTIL_NAMED_PORT(IN_PORT) \
+ OFPUTIL_NAMED_PORT(TABLE) \
+ OFPUTIL_NAMED_PORT(NORMAL) \
+ OFPUTIL_NAMED_PORT(FLOOD) \
+ OFPUTIL_NAMED_PORT(ALL) \
+ OFPUTIL_NAMED_PORT(CONTROLLER) \
+ OFPUTIL_NAMED_PORT(LOCAL) \
+ OFPUTIL_NAMED_PORT(NONE)
+
+/* Checks whether 's' is the string representation of an OpenFlow port number,
+ * either as an integer or a string name (e.g. "LOCAL"). If it is, stores the
+ * number in '*port' and returns true. Otherwise, returns false. */
+bool
+ofputil_port_from_string(const char *name, uint16_t *port)
+{
+ struct pair {
+ const char *name;
+ uint16_t value;
+ };
+ static const struct pair pairs[] = {
+#define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME},
+ OFPUTIL_NAMED_PORTS
+#undef OFPUTIL_NAMED_PORT
+ };
+ static const int n_pairs = ARRAY_SIZE(pairs);
+ int i;
+
+ if (str_to_int(name, 0, &i) && i >= 0 && i < UINT16_MAX) {
+ *port = i;
+ return true;
+ }
+
+ for (i = 0; i < n_pairs; i++) {
+ if (!strcasecmp(name, pairs[i].name)) {
+ *port = pairs[i].value;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Appends to 's' a string representation of the OpenFlow port number 'port'.
+ * Most ports' string representation is just the port number, but for special
+ * ports, e.g. OFPP_LOCAL, it is the name, e.g. "LOCAL". */
+void
+ofputil_format_port(uint16_t port, struct ds *s)
+{
+ const char *name;
+
+ switch (port) {
+#define OFPUTIL_NAMED_PORT(NAME) case OFPP_##NAME: name = #NAME; break;
+ OFPUTIL_NAMED_PORTS
+#undef OFPUTIL_NAMED_PORT
+
+ default:
+ ds_put_format(s, "%"PRIu16, port);
+ return;
+ }
+ ds_put_cstr(s, name);
+}
+
static int
check_resubmit_table(const struct nx_action_resubmit *nar)
{