X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-util.c;h=fc988946dadf8c1cb91719acd2fe9a78d746ab09;hb=c6100d92142bc3dd325180cb4e10553eb4341731;hp=300ef4c09cd152b60e59cb9c21d4c634dfa4ebc4;hpb=2ac3c572267c550302eee88d4f584b3694d88f88;p=sliver-openvswitch.git diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 300ef4c09..fc988946d 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -3536,36 +3536,72 @@ ofputil_check_output_port(uint16_t port, int max_ports) 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) +/* Returns the port number represented by 's', which may be an integer or, for + * reserved ports, the standard OpenFlow name for the port (e.g. "LOCAL"). + * + * Returns 0 if 's' is not a valid OpenFlow port number or name. The caller + * should issue an error message in this case, because this function usually + * does not. (This gives the caller an opportunity to look up the port name + * another way, e.g. by contacting the switch and listing the names of all its + * ports). + * + * This function accepts OpenFlow 1.0 port numbers. It also accepts a subset + * of OpenFlow 1.1+ port numbers, mapping those port numbers into the 16-bit + * range as described in include/openflow/openflow-1.1.h. */ +uint16_t +ofputil_port_from_string(const char *s) { - struct pair { - const char *name; - uint16_t value; - }; - static const struct pair pairs[] = { + unsigned int port32; + + if (str_to_uint(s, 10, &port32)) { + if (port32 == 0) { + VLOG_WARN("port 0 is not a valid OpenFlow port number"); + return 0; + } else if (port32 < OFPP_MAX) { + return port32; + } else if (port32 < OFPP_FIRST_RESV) { + VLOG_WARN("port %u is a reserved OF1.0 port number that will " + "be translated to %u when talking to an OF1.1 or " + "later controller", port32, port32 + OFPP11_OFFSET); + return port32; + } else if (port32 <= OFPP_LAST_RESV) { + struct ds s; + + ds_init(&s); + ofputil_format_port(port32, &s); + VLOG_WARN("port %u is better referred to as %s, for compatibility " + "with future versions of OpenFlow", + port32, ds_cstr(&s)); + ds_destroy(&s); + + return port32; + } else if (port32 < OFPP11_MAX) { + VLOG_WARN("port %u is outside the supported range 0 through " + "%"PRIx16"or 0x%x through 0x%"PRIx32, port32, + UINT16_MAX, (unsigned int) OFPP11_MAX, UINT32_MAX); + return 0; + } else { + return port32 - OFPP11_OFFSET; + } + } else { + struct pair { + const char *name; + uint16_t value; + }; + static const struct pair pairs[] = { #define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME}, - OFPUTIL_NAMED_PORTS + 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; - } + }; + const struct pair *p; - for (i = 0; i < n_pairs; i++) { - if (!strcasecmp(name, pairs[i].name)) { - *port = pairs[i].value; - return true; + for (p = pairs; p < &pairs[ARRAY_SIZE(pairs)]; p++) { + if (!strcasecmp(s, p->name)) { + return p->value; + } } + return 0; } - return false; } /* Appends to 's' a string representation of the OpenFlow port number 'port'.