On Thu, Jun 20, 2013 at 05:26:18PM +0300, Jarno Rajahalme wrote: > > Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com>
I'm applied this to master. I'm appending the incremental that I folded in. Most of the changes are minor improvements (some just stylistic). The only important change is that it looked to me like the OpenFlow parsing code in ofp-util.c didn't check that the lengths were valid, so I adjusted them so that they did check. I noticed that the tests seem to use impossible numbers of nanoseconds (greater than 1e9), but I didn't change that other than the formatting. diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index f1f755b..f06edb1 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -48,12 +48,12 @@ static void ofp_fatal(const char *flow, bool verbose, const char *format, ...) static uint8_t str_to_u8(const char *str, const char *name) { - int table_id; + int value; - if (!str_to_int(str, 10, &table_id) || table_id < 0 || table_id > 255) { + if (!str_to_int(str, 10, &value) || value < 0 || value > 255) { ovs_fatal(0, "invalid %s \"%s\"", name, str); } - return table_id; + return value; } static uint16_t @@ -373,16 +373,6 @@ set_field_parse(const char *arg, struct ofpbuf *ofpacts) } static void -parse_meter(struct ofpbuf *b, char *arg) -{ - struct ofpact_meter *om; - - om = ofpact_put_METER(b); - - om->meter_id = str_to_u32(arg); -} - -static void parse_metadata(struct ofpbuf *b, char *arg) { struct ofpact_metadata *om; @@ -717,7 +707,7 @@ parse_named_instruction(enum ovs_instruction_type type, break; case OVSINST_OFPIT13_METER: - parse_meter(ofpacts, arg); + ofpact_put_METER(ofpacts)->meter_id = str_to_u32(arg); break; case OVSINST_OFPIT11_WRITE_METADATA: diff --git a/lib/ofp-print.c b/lib/ofp-print.c index e554828..76bd09c 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1013,8 +1013,9 @@ ofp_print_meter_stats(struct ds *s, const struct ofputil_meter_stats *ms) ds_put_format(s, "flow_count:%"PRIu32" ", ms->flow_count); ds_put_format(s, "packet_in_count:%"PRIu64" ", ms->packet_in_count); ds_put_format(s, "byte_in_count:%"PRIu64" ", ms->byte_in_count); - ds_put_format(s, "duration_sec:%"PRIu32" ", ms->duration_sec); - ds_put_format(s, "duration_nsec:%"PRIu32" ", ms->duration_nsec); + ds_put_cstr(s, "duration:"); + ofp_print_duration(s, ms->duration_sec, ms->duration_nsec); + ds_put_char(s, ' '); ds_put_cstr(s, "bands:\n"); for (i = 0; i < ms->n_bands; ++i) { @@ -1151,7 +1152,6 @@ ofp_print_meter_config_reply(struct ds *s, const struct ofp_header *oh) if (retval) { if (retval != EOF) { ofp_print_error(s, retval); - /* ds_put_cstr(s, " ***parse error***"); */ } break; } @@ -1177,7 +1177,6 @@ ofp_print_meter_stats_reply(struct ds *s, const struct ofp_header *oh) if (retval) { if (retval != EOF) { ofp_print_error(s, retval); - /* ds_put_cstr(s, " ***parse error***"); */ } break; } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 461e138..6c58415 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1639,7 +1639,10 @@ ofputil_pull_bands(struct ofpbuf *msg, size_t len, uint16_t *n_bands, struct ofputil_meter_band *mb; uint16_t n = 0; - ombh = ofpbuf_pull(msg, len); + ombh = ofpbuf_try_pull(msg, len); + if (!ombh) { + return OFPERR_OFPBRC_BAD_LEN; + } while (len >= sizeof (struct ofp13_meter_band_drop)) { size_t ombh_len = ntohs(ombh->len); @@ -1669,7 +1672,12 @@ ofputil_decode_meter_mod(const struct ofp_header *oh, struct ofputil_meter_mod *mm, struct ofpbuf *bands) { - const struct ofp13_meter_mod *omm = ofpmsg_body(oh); + const struct ofp13_meter_mod *omm; + struct ofpbuf b; + + ofpbuf_use_const(&b, oh, ntohs(oh->length)); + ofpraw_pull_assert(&b); + omm = ofpbuf_pull(&b, sizeof *omm); /* Translate the message. */ mm->command = ntohs(omm->command); @@ -1680,15 +1688,11 @@ ofputil_decode_meter_mod(const struct ofp_header *oh, mm->meter.n_bands = 0; mm->meter.bands = NULL; } else { - struct ofpbuf b; enum ofperr error; mm->meter.flags = ntohs(omm->flags); mm->meter.bands = bands->data; - ofpbuf_use_const(&b, omm + 1, - ntohs(oh->length) - sizeof *oh - sizeof *omm); - error = ofputil_pull_bands(&b, b.size, &mm->meter.n_bands, bands); if (error) { @@ -1727,7 +1731,7 @@ ofputil_encode_meter_request(enum ofp_version ofp_version, break; } - msg = ofpraw_alloc(raw, MAX(OFP13_VERSION, ofp_version), 0); + msg = ofpraw_alloc(raw, ofp_version, 0); if (type != OFPUTIL_METER_FEATURES) { struct ofp13_meter_multipart_request *omr; @@ -1741,20 +1745,20 @@ static void ofputil_put_bands(uint16_t n_bands, const struct ofputil_meter_band *mb, struct ofpbuf *msg) { - struct ofp13_meter_band_dscp_remark *ombh; uint16_t n = 0; for (n = 0; n < n_bands; ++n) { /* Currently all band types have same size */ + struct ofp13_meter_band_dscp_remark *ombh; size_t ombh_len = sizeof *ombh; - ombh = ofpbuf_put_uninit(msg, ombh_len); + + ombh = ofpbuf_put_zeros(msg, ombh_len); ombh->type = htons(mb->type); ombh->len = htons(ombh_len); ombh->rate = htonl(mb->rate); ombh->burst_size = htonl(mb->burst_size); ombh->prec_level = mb->prec_level; - memset(ombh->pad, 0, sizeof ombh->pad); mb++; } @@ -1800,15 +1804,18 @@ ofputil_append_meter_stats(struct list *replies, reply->duration_nsec = htonl(ms->duration_nsec); for (n = 0; n < ms->n_bands; ++n) { - reply->band_stats[n].packet_band_count - = htonll(ms->bands[n].packet_count); - reply->band_stats[n].byte_band_count = htonll(ms->bands[n].byte_count); + const struct ofputil_meter_band_stats *src = &ms->bands[n]; + struct ofp13_meter_band_stats *dst = &reply->band_stats[n]; + + dst->packet_band_count = htonll(src->packet_count); + dst->byte_band_count = htonll(src->byte_count); } } /* Converts an OFPMP_METER_CONFIG reply in 'msg' into an abstract - * ofputil_meter_config in 'mc', with mc->bands pointing to bands - * decoded into 'bands'. + * ofputil_meter_config in 'mc', with mc->bands pointing to bands decoded into + * 'bands'. The caller must have initialized 'bands' and retains ownership of + * it across the call. * * Multiple OFPST13_METER_CONFIG replies can be packed into a single OpenFlow * message. Calling this function multiple times for a single 'msg' iterates @@ -1822,12 +1829,10 @@ ofputil_decode_meter_config(struct ofpbuf *msg, struct ofpbuf *bands) { const struct ofp13_meter_config *omc; - uint16_t len; enum ofperr err; - /* pull OpenFlow headers for the first call */ + /* Pull OpenFlow headers for the first call. */ if (!msg->l2) { - msg->l2 = msg->data; ofpraw_pull_assert(msg); } @@ -1837,28 +1842,22 @@ ofputil_decode_meter_config(struct ofpbuf *msg, omc = ofpbuf_try_pull(msg, sizeof *omc); if (!omc) { - goto bad_len; + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_METER_CONFIG reply has %zu " + "leftover bytes at end", msg->size); + return OFPERR_OFPBRC_BAD_LEN; } - len = ntohs(omc->length); - len -= sizeof *omc; ofpbuf_clear(bands); - err = ofputil_pull_bands(msg, len, &mc->n_bands, bands); + err = ofputil_pull_bands(msg, ntohs(omc->length) - sizeof *omc, + &mc->n_bands, bands); if (err) { - goto error; + return err; } mc->meter_id = ntohl(omc->meter_id); mc->flags = ntohs(omc->flags); mc->bands = bands->data; return 0; - - bad_len: - err = OFPERR_OFPBRC_BAD_LEN; - VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_METER_CONFIG reply has %zu leftover " - "bytes at end", msg->size); - error: - return err; } static enum ofperr @@ -1905,9 +1904,8 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, uint16_t len; enum ofperr err; - /* pull OpenFlow headers for the first call */ + /* Pull OpenFlow headers for the first call. */ if (!msg->l2) { - msg->l2 = msg->data; ofpraw_pull_assert(msg); } @@ -1917,7 +1915,9 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, oms = ofpbuf_try_pull(msg, sizeof *oms); if (!oms) { - goto bad_len; + 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; @@ -1925,7 +1925,7 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, ofpbuf_clear(bands); err = ofputil_pull_band_stats(msg, len, &ms->n_bands, bands); if (err) { - goto error; + return err; } ms->meter_id = ntohl(oms->meter_id); ms->flow_count = ntohl(oms->flow_count); @@ -1936,13 +1936,6 @@ ofputil_decode_meter_stats(struct ofpbuf *msg, ms->bands = bands->data; return 0; - - bad_len: - err = OFPERR_OFPBRC_BAD_LEN; - VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_METER reply has %zu leftover " - "bytes at end", msg->size); - error: - return err; } void @@ -1985,8 +1978,7 @@ ofputil_encode_meter_mod(enum ofp_version ofp_version, struct ofp13_meter_mod *omm; - msg = ofpraw_alloc(OFPRAW_OFPT13_METER_MOD, - MAX(OFP13_VERSION, ofp_version), /* FIXME? */ + msg = ofpraw_alloc(OFPRAW_OFPT13_METER_MOD, ofp_version, NXM_TYPICAL_LEN + mm->meter.n_bands * 16); omm = ofpbuf_put_zeros(msg, sizeof *omm); omm->command = htons(mm->command); diff --git a/tests/ofp-print.at b/tests/ofp-print.at index d6cfdf8..b3e3eb5 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -1661,11 +1661,11 @@ AT_CHECK([ovs-ofctl ofp-print "\ 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 04 33 \ "], [0], [dnl OFPST_METER reply (OF1.3) (xid=0x2): -meter:1 flow_count:5 packet_in_count:4096 byte_in_count:143360 duration_sec:394 duration_nsec:2590909252 bands: +meter:1 flow_count:5 packet_in_count:4096 byte_in_count:143360 duration:394.2590909252s bands: 0: packet_count:126 byte_count:13363 1: packet_count:231 byte_count:37934 -meter:2 flow_count:2 packet_in_count:512 byte_in_count:12288 duration_sec:391 duration_nsec:2586013252 bands: +meter:2 flow_count:2 packet_in_count:512 byte_in_count:12288 duration:391.2586013252s bands: 0: packet_count:42 byte_count:1075 ]) AT_CLEANUP _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev