void
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
{
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
/* Initialize most of wc. */
flow_wildcards_init_catchall(wc);
}
static bool
-is_delimiter(char c)
+is_delimiter(unsigned char c)
{
return isspace(c) || c == ',';
}
return true;
}
-static bool
-tun_parms_fully_wildcarded(const struct flow_wildcards *wc)
-{
- return (!wc->masks.tunnel.ip_src &&
- !wc->masks.tunnel.ip_dst &&
- !wc->masks.tunnel.ip_ttl &&
- !wc->masks.tunnel.ip_tos &&
- !wc->masks.tunnel.flags);
-}
-
/* Returns a bit-mask of ofputil_protocols that can be used for sending 'match'
* to a switch (e.g. to add or remove a flow). Only NXM can handle tunnel IDs,
* registers, or fixing the Ethernet multicast bit. Otherwise, it's better to
{
const struct flow_wildcards *wc = &match->wc;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
- /* tunnel params other than tun_id can't be sent in a flow_mod */
- if (!tun_parms_fully_wildcarded(wc)) {
+ /* These tunnel params can't be sent in a flow_mod */
+ if (wc->masks.tunnel.ip_ttl
+ || wc->masks.tunnel.ip_tos || wc->masks.tunnel.flags) {
return OFPUTIL_P_NONE;
}
| OFPUTIL_P_OF13_OXM;
}
- /* NXM and OXM support matching tun_id. */
- if (wc->masks.tunnel.tun_id != htonll(0)) {
+ /* NXM and OXM support matching tun_id, tun_src, and tun_dst. */
+ if (wc->masks.tunnel.tun_id != htonll(0)
+ || wc->masks.tunnel.ip_src != htonl(0)
+ || wc->masks.tunnel.ip_dst != htonl(0)) {
return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
| OFPUTIL_P_OF13_OXM;
}
fr->priority = ntohs(nfr->priority);
fr->cookie = nfr->cookie;
fr->reason = nfr->reason;
- fr->table_id = 255;
+ fr->table_id = nfr->table_id ? nfr->table_id - 1 : 255;
fr->duration_sec = ntohl(nfr->duration_sec);
fr->duration_nsec = ntohl(nfr->duration_nsec);
fr->idle_timeout = ntohs(nfr->idle_timeout);
nfr->cookie = fr->cookie;
nfr->priority = htons(fr->priority);
nfr->reason = fr->reason;
+ nfr->table_id = fr->table_id + 1;
nfr->duration_sec = htonl(fr->duration_sec);
nfr->duration_nsec = htonl(fr->duration_nsec);
nfr->idle_timeout = htons(fr->idle_timeout);
pin->fmd.in_port = match->flow.in_port;
pin->fmd.tun_id = match->flow.tunnel.tun_id;
+ pin->fmd.tun_src = match->flow.tunnel.ip_src;
+ pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
pin->fmd.metadata = match->flow.metadata;
memcpy(pin->fmd.regs, match->flow.regs, sizeof pin->fmd.regs);
}
if (pin->fmd.tun_id != htonll(0)) {
match_set_tun_id(match, pin->fmd.tun_id);
}
+ if (pin->fmd.tun_src != htonl(0)) {
+ match_set_tun_src(match, pin->fmd.tun_src);
+ }
+ if (pin->fmd.tun_dst != htonl(0)) {
+ match_set_tun_dst(match, pin->fmd.tun_dst);
+ }
if (pin->fmd.metadata != htonll(0)) {
match_set_metadata(match, pin->fmd.metadata);
}
}
rr->role = ntohl(orr->role);
- if (raw == OFPRAW_OFPT12_ROLE_REPLY
- || orr->role == htonl(OFPCR12_ROLE_NOCHANGE)) {
+ if (raw == OFPRAW_OFPT12_ROLE_REQUEST
+ ? orr->role == htonl(OFPCR12_ROLE_NOCHANGE)
+ : orr->generation_id == htonll(UINT64_MAX)) {
rr->have_generation_id = false;
rr->generation_id = 0;
} else {
buf = ofpraw_alloc_reply(OFPRAW_OFPT12_ROLE_REPLY, request, 0);
orr = ofpbuf_put_zeros(buf, sizeof *orr);
- orr->role = htonl(rr->role);
- /*
- * OpenFlow specification does not specify use of generation_id field
- * on reply messages. Intuitively, it would seem a good idea to return
- * the current value. However, the current value is undefined
- * initially, and there is no way to insert an undefined value in the
- * message. Therefore we leave the generation_id zeroed on reply
- * messages.
- *
- * A request for clarification has been filed with the Open Networking
- * Foundation as EXT-272.
- */
- orr->generation_id = htonll(0);
+ orr->role = htonl(rr->role);
+ orr->generation_id = htonll(rr->have_generation_id
+ ? rr->generation_id
+ : UINT64_MAX);
} else if (raw == OFPRAW_NXT_ROLE_REQUEST) {
struct nx_role_request *nrr;
int
ofputil_action_code_from_name(const char *name)
{
- static const char *names[OFPUTIL_N_ACTIONS] = {
+ static const char *const names[OFPUTIL_N_ACTIONS] = {
NULL,
#define OFPAT10_ACTION(ENUM, STRUCT, NAME) NAME,
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
#include "ofp-util.def"
};
- const char **p;
+ const char *const *p;
for (p = names; p < &names[ARRAY_SIZE(names)]; p++) {
if (*p && !strcasecmp(name, *p)) {
* will be for Open Flow version 'ofp_version'. Returns message
* as a struct ofpbuf. Returns encoded message on success, NULL on error */
struct ofpbuf *
-ofputil_encode_dump_ports_request(enum ofp_version ofp_version, int16_t port)
+ofputil_encode_dump_ports_request(enum ofp_version ofp_version, uint16_t port)
{
struct ofpbuf *request;