X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fofp-util.c;h=6b78f84c2894310e7b9d396b48289b595eb5b6ba;hb=2c57a420432de88b8a6f9ee54642c3841577ad7b;hp=cd51ef7dd3d9084d8d45416f8a9bf96ec5feb89e;hpb=1bda9b9e1a74ce376a1b51127a7e80640336c715;p=sliver-openvswitch.git diff --git a/lib/ofp-util.c b/lib/ofp-util.c index cd51ef7dd..6b78f84c2 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -84,7 +84,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask) 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); @@ -1058,7 +1058,7 @@ ofputil_usable_protocols(const struct match *match) { 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)) { @@ -2345,7 +2345,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr, 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); @@ -2424,6 +2424,7 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr, 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); @@ -3382,43 +3383,54 @@ enum ofperr ofputil_decode_role_message(const struct ofp_header *oh, struct ofputil_role_request *rr) { - const struct ofp12_role_request *orr = ofpmsg_body(oh); - uint32_t role = ntohl(orr->role); struct ofpbuf b; enum ofpraw raw; - memset(rr, 0, sizeof *rr); - ofpbuf_use_const(&b, oh, ntohs(oh->length)); raw = ofpraw_pull_assert(&b); - if (raw == OFPRAW_OFPT12_ROLE_REQUEST - || raw == OFPRAW_OFPT12_ROLE_REPLY) { + if (raw == OFPRAW_OFPT12_ROLE_REQUEST || + raw == OFPRAW_OFPT12_ROLE_REPLY) { + const struct ofp12_role_request *orr = b.l3; - if (raw == OFPRAW_OFPT12_ROLE_REQUEST) { - if (role == OFPCR12_ROLE_NOCHANGE) { - rr->request_current_role_only = true; - return 0; - } - if (role == OFPCR12_ROLE_MASTER || role == OFPCR12_ROLE_SLAVE) { - rr->generation_id = ntohll(orr->generation_id); - rr->have_generation_id = true; - } + if (orr->role != htonl(OFPCR12_ROLE_NOCHANGE) && + orr->role != htonl(OFPCR12_ROLE_EQUAL) && + orr->role != htonl(OFPCR12_ROLE_MASTER) && + orr->role != htonl(OFPCR12_ROLE_SLAVE)) { + return OFPERR_OFPRRFC_BAD_ROLE; } - /* Map to enum nx_role */ - role -= 1; /* OFPCR12_ROLE_MASTER -> NX_ROLE_MASTER etc. */ - } else if (raw != OFPRAW_NXT_ROLE_REQUEST - && raw != OFPRAW_NXT_ROLE_REPLY) { - return OFPERR_OFPBRC_BAD_TYPE; - } + rr->role = ntohl(orr->role); + 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 { + rr->have_generation_id = true; + rr->generation_id = ntohll(orr->generation_id); + } + } else if (raw == OFPRAW_NXT_ROLE_REQUEST || + raw == OFPRAW_NXT_ROLE_REPLY) { + const struct nx_role_request *nrr = b.l3; + + BUILD_ASSERT(NX_ROLE_OTHER + 1 == OFPCR12_ROLE_EQUAL); + BUILD_ASSERT(NX_ROLE_MASTER + 1 == OFPCR12_ROLE_MASTER); + BUILD_ASSERT(NX_ROLE_SLAVE + 1 == OFPCR12_ROLE_SLAVE); + + if (nrr->role != htonl(NX_ROLE_OTHER) && + nrr->role != htonl(NX_ROLE_MASTER) && + nrr->role != htonl(NX_ROLE_SLAVE)) { + return OFPERR_OFPRRFC_BAD_ROLE; + } - if (role != NX_ROLE_OTHER && role != NX_ROLE_MASTER - && role != NX_ROLE_SLAVE) { - return OFPERR_OFPRRFC_BAD_ROLE; + rr->role = ntohl(nrr->role) + 1; + rr->have_generation_id = false; + rr->generation_id = 0; + } else { + NOT_REACHED(); } - rr->role = role; return 0; } @@ -3426,47 +3438,35 @@ ofputil_decode_role_message(const struct ofp_header *oh, * buffer owned by the caller. */ struct ofpbuf * ofputil_encode_role_reply(const struct ofp_header *request, - enum nx_role role) + const struct ofputil_role_request *rr) { - struct ofp12_role_request *reply; struct ofpbuf *buf; - size_t reply_size; - - struct ofpbuf b; enum ofpraw raw; - ofpbuf_use_const(&b, request, ntohs(request->length)); - raw = ofpraw_pull_assert(&b); + raw = ofpraw_decode_assert(request); if (raw == OFPRAW_OFPT12_ROLE_REQUEST) { - reply_size = sizeof (struct ofp12_role_request); - raw = OFPRAW_OFPT12_ROLE_REPLY; - } - else if (raw == OFPRAW_NXT_ROLE_REQUEST) { - reply_size = sizeof (struct nx_role_request); - raw = OFPRAW_NXT_ROLE_REPLY; - } else { - NOT_REACHED(); - } + struct ofp12_role_request *orr; - buf = ofpraw_alloc_reply(raw, request, 0); - reply = ofpbuf_put_zeros(buf, reply_size); + buf = ofpraw_alloc_reply(OFPRAW_OFPT12_ROLE_REPLY, request, 0); + orr = ofpbuf_put_zeros(buf, sizeof *orr); - if (raw == OFPRAW_OFPT12_ROLE_REPLY) { - /* Map to OpenFlow enum ofp12_controller_role */ - role += 1; /* NX_ROLE_MASTER -> OFPCR12_ROLE_MASTER etc. */ - /* - * 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->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; + + BUILD_ASSERT(NX_ROLE_OTHER == OFPCR12_ROLE_EQUAL - 1); + BUILD_ASSERT(NX_ROLE_MASTER == OFPCR12_ROLE_MASTER - 1); + BUILD_ASSERT(NX_ROLE_SLAVE == OFPCR12_ROLE_SLAVE - 1); + + buf = ofpraw_alloc_reply(OFPRAW_NXT_ROLE_REPLY, request, 0); + nrr = ofpbuf_put_zeros(buf, sizeof *nrr); + nrr->role = htonl(rr->role - 1); + } else { + NOT_REACHED(); } - reply->role = htonl(role); return buf; }