uint16_t wc = ntohl(ofmatch->wildcards);
uint8_t dl_src_mask[ETH_ADDR_LEN];
uint8_t dl_dst_mask[ETH_ADDR_LEN];
- bool ipv4, arp;
+ bool ipv4, arp, rarp;
int i;
match_init_catchall(match);
ipv4 = match->flow.dl_type == htons(ETH_TYPE_IP);
arp = match->flow.dl_type == htons(ETH_TYPE_ARP);
+ rarp = match->flow.dl_type == htons(ETH_TYPE_RARP);
if (ipv4 && !(wc & OFPFW11_NW_TOS)) {
if (ofmatch->nw_tos & ~IP_DSCP_MASK) {
match_set_nw_dscp(match, ofmatch->nw_tos);
}
- if (ipv4 || arp) {
+ if (ipv4 || arp || rarp) {
if (!(wc & OFPFW11_NW_PROTO)) {
match_set_nw_proto(match, ofmatch->nw_proto);
}
fm->cookie_mask = htonll(0);
fm->new_cookie = ofm->cookie;
} else {
- /* XXX */
fm->cookie = ofm->cookie;
fm->cookie_mask = ofm->cookie_mask;
fm->new_cookie = htonll(UINT64_MAX);
msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD, OFP12_VERSION,
NXM_TYPICAL_LEN + fm->ofpacts_len);
ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
- ofm->cookie = fm->new_cookie;
+ if (fm->command == OFPFC_ADD) {
+ ofm->cookie = fm->new_cookie;
+ } else {
+ ofm->cookie = fm->cookie;
+ }
ofm->cookie_mask = fm->cookie_mask;
ofm->table_id = fm->table_id;
ofm->command = fm->command;
OFPUTIL_NAMED_PORT(LOCAL) \
OFPUTIL_NAMED_PORT(NONE)
-/* 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").
+/* Stores the port number represented by 's' into '*portp'. 's' 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).
+ * Returns true if successful, false 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)
+bool
+ofputil_port_from_string(const char *s, uint16_t *portp)
{
unsigned int port32;
+ *portp = 0;
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;
+ if (port32 < OFPP_MAX) {
+ *portp = port32;
+ return true;
} 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;
+ *portp = port32;
+ return true;
} else if (port32 <= OFPP_LAST_RESV) {
struct ds s;
ds_cstr(&s), port32);
ds_destroy(&s);
- return port32;
+ *portp = port32;
+ return true;
} 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;
+ return false;
} else {
- return port32 - OFPP11_OFFSET;
+ *portp = port32 - OFPP11_OFFSET;
+ return true;
}
} else {
struct pair {
for (p = pairs; p < &pairs[ARRAY_SIZE(pairs)]; p++) {
if (!strcasecmp(s, p->name)) {
- return p->value;
+ *portp = p->value;
+ return true;
}
}
- return 0;
+ return false;
}
}
may_match |= MAY_ND_TARGET | MAY_ARP_THA;
}
}
- } else if (match->flow.dl_type == htons(ETH_TYPE_ARP)) {
+ } else if (match->flow.dl_type == htons(ETH_TYPE_ARP) ||
+ match->flow.dl_type == htons(ETH_TYPE_RARP)) {
may_match = MAY_NW_PROTO | MAY_NW_ADDR | MAY_ARP_SHA | MAY_ARP_THA;
} else {
may_match = 0;