X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-util.c;h=aa4009d84db1d2b5959467be2311c2fa4396b0ed;hb=2b13d312fc4d6e5eb1d0e3004fa523bb0c0ba544;hp=6c584157ac520a2b213c6ee2dd3d3cba0e40a26d;hpb=638a19b04578669b5d43cb4d91391a9e1da93dc7;p=sliver-openvswitch.git diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 6c584157a..aa4009d84 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1086,8 +1086,19 @@ ofputil_usable_protocols(const struct match *match) | OFPUTIL_P_OF13_OXM; } - /* NXM and OXM support matching IPv6 traffic. */ - if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) { + /* NXM and OXM support matching L3 and L4 fields within IPv6. + * + * (arp_sha, arp_tha, nw_frag, and nw_ttl are covered elsewhere so they + * don't need to be included in this test too.) */ + if (match->flow.dl_type == htons(ETH_TYPE_IPV6) + && (!ipv6_mask_is_any(&wc->masks.ipv6_src) + || !ipv6_mask_is_any(&wc->masks.ipv6_dst) + || !ipv6_mask_is_any(&wc->masks.nd_target) + || wc->masks.ipv6_label + || wc->masks.tp_src + || wc->masks.tp_dst + || wc->masks.nw_proto + || wc->masks.nw_tos)) { return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM; } @@ -1112,12 +1123,6 @@ ofputil_usable_protocols(const struct match *match) | OFPUTIL_P_OF13_OXM; } - /* NXM and OXM support matching IPv6 flow label. */ - if (wc->masks.ipv6_label) { - return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM - | OFPUTIL_P_OF13_OXM; - } - /* NXM and OXM support matching IP ECN bits. */ if (wc->masks.nw_tos & IP_ECN_MASK) { return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM @@ -1502,8 +1507,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, return error; } - error = ofpacts_pull_openflow11_instructions(&b, b.size, ofm->table_id, - ofpacts); + error = ofpacts_pull_openflow11_instructions(&b, b.size, ofpacts); if (error) { return error; } @@ -1646,7 +1650,7 @@ ofputil_pull_bands(struct ofpbuf *msg, size_t len, uint16_t *n_bands, while (len >= sizeof (struct ofp13_meter_band_drop)) { size_t ombh_len = ntohs(ombh->len); - /* All supported band types have the same length */ + /* All supported band types have the same length. */ if (ombh_len != sizeof (struct ofp13_meter_band_drop)) { return OFPERR_OFPBRC_BAD_LEN; } @@ -1693,8 +1697,7 @@ ofputil_decode_meter_mod(const struct ofp_header *oh, mm->meter.flags = ntohs(omm->flags); mm->meter.bands = bands->data; - error = ofputil_pull_bands(&b, b.size, &mm->meter.n_bands, - bands); + error = ofputil_pull_bands(&b, b.size, &mm->meter.n_bands, bands); if (error) { return error; } @@ -1748,7 +1751,7 @@ ofputil_put_bands(uint16_t n_bands, const struct ofputil_meter_band *mb, uint16_t n = 0; for (n = 0; n < n_bands; ++n) { - /* Currently all band types have same size */ + /* Currently all band types have same size. */ struct ofp13_meter_band_dscp_remark *ombh; size_t ombh_len = sizeof *ombh; @@ -1842,8 +1845,9 @@ ofputil_decode_meter_config(struct ofpbuf *msg, omc = ofpbuf_try_pull(msg, sizeof *omc); if (!omc) { - VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_METER_CONFIG reply has %zu " - "leftover bytes at end", msg->size); + VLOG_WARN_RL(&bad_ofmsg_rl, + "OFPMP_METER_CONFIG reply has %zu leftover bytes at end", + msg->size); return OFPERR_OFPBRC_BAD_LEN; } @@ -1868,13 +1872,16 @@ ofputil_pull_band_stats(struct ofpbuf *msg, size_t len, uint16_t *n_bands, struct ofputil_meter_band_stats *mbs; uint16_t n, i; + ombs = ofpbuf_try_pull(msg, len); + if (!ombs) { + return OFPERR_OFPBRC_BAD_LEN; + } + n = len / sizeof *ombs; if (len != n * sizeof *ombs) { return OFPERR_OFPBRC_BAD_LEN; } - ombs = ofpbuf_pull(msg, len); - mbs = ofpbuf_put_uninit(bands, len); for (i = 0; i < n; ++i) { @@ -1901,7 +1908,6 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, struct ofpbuf *bands) { const struct ofp13_meter_stats *oms; - uint16_t len; enum ofperr err; /* Pull OpenFlow headers for the first call. */ @@ -1915,15 +1921,15 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, oms = ofpbuf_try_pull(msg, sizeof *oms); if (!oms) { - VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_METER reply has %zu leftover " - "bytes at end", msg->size); + VLOG_WARN_RL(&bad_ofmsg_rl, + "OFPMP_METER reply has %zu leftover bytes at end", + msg->size); return OFPERR_OFPBRC_BAD_LEN; } - len = ntohs(oms->len); - len -= sizeof *oms; ofpbuf_clear(bands); - err = ofputil_pull_band_stats(msg, len, &ms->n_bands, bands); + err = ofputil_pull_band_stats(msg, ntohs(oms->len) - sizeof *oms, + &ms->n_bands, bands); if (err) { return err; } @@ -2377,8 +2383,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, } if (ofpacts_pull_openflow11_instructions(msg, length - sizeof *ofs - - padded_match_len, - ofs->table_id, ofpacts)) { + padded_match_len, ofpacts)) { VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions"); return EINVAL; }