Applied, thanks!
On Mon, Aug 11, 2014 at 11:39:41AM -0700, Jarno Rajahalme wrote: > Acked-by: Jarno Rajahalme <jrajaha...@nicira.com> > > On Aug 7, 2014, at 4:14 PM, Ben Pfaff <b...@nicira.com> wrote: > > > Until now, there were four of these commands: parse-ofp10-actions, > > parse-ofp10-instructions, parse-ofp11-actions, parse-ofp11-instructions. > > This is painful to add support for new OpenFlow versions and has a ton of > > cut-and-paste code. This commit generalizes the code to improve on both > > of those points. > > > > Signed-off-by: Ben Pfaff <b...@nicira.com> > > --- > > tests/ofp-actions.at | 34 +++---- > > utilities/ovs-ofctl.c | 242 > > ++++++++++++++----------------------------------- > > 2 files changed, 86 insertions(+), 190 deletions(-) > > > > diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at > > index 73b7dc6..9c6f228 100644 > > --- a/tests/ofp-actions.at > > +++ b/tests/ofp-actions.at > > @@ -69,11 +69,11 @@ ffff 0018 00002320 0009 000000000000 c426384d49c53d60 > > # actions=set_tunnel64:0x885f3298 > > ffff 0018 00002320 0009 000000000000 00000000885f3298 > > > > -# bad OF1.0 actions: OFPBIC_UNSUP_INST > > +# bad OpenFlow10 actions: OFPBIC_UNSUP_INST > > & ofp_actions|WARN|write_metadata instruction not allowed here > > ffff 0020 00002320 0016 000000000000 fedcba9876543210 ffffffffffffffff > > > > -# bad OF1.0 actions: OFPBIC_UNSUP_INST > > +# bad OpenFlow10 actions: OFPBIC_UNSUP_INST > > & ofp_actions|WARN|write_metadata instruction not allowed here > > ffff 0020 00002320 0016 000000000000 fedcba9876543210 ffff0000ffff0000 > > > > @@ -127,7 +127,7 @@ AT_CAPTURE_FILE([input.txt]) > > AT_CAPTURE_FILE([expout]) > > AT_CAPTURE_FILE([experr]) > > AT_CHECK( > > - [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-ofp10-actions < input.txt], > > + [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-actions OpenFlow10 < > > input.txt], > > [0], [expout], [experr]) > > AT_CLEANUP > > > > @@ -157,7 +157,7 @@ AT_CAPTURE_FILE([input.txt]) > > AT_CAPTURE_FILE([expout]) > > AT_CAPTURE_FILE([experr]) > > AT_CHECK( > > - [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-ofp10-instructions < > > input.txt], > > + [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-instructions OpenFlow10 < > > input.txt], > > [0], [expout], [experr]) > > AT_CLEANUP > > > > @@ -235,7 +235,7 @@ ffff 0018 00002320 0009 000000000000 00000000885f3298 > > > > dnl Write-Metadata is only allowed in contexts that allow instructions. > > & ofp_actions|WARN|write_metadata instruction not allowed here > > -# bad OF1.1 actions: OFPBIC_UNSUP_INST > > +# bad OpenFlow11 actions: OFPBIC_UNSUP_INST > > ffff 0020 00002320 0016 000000000000 fedcba9876543210 ffffffffffffffff > > > > # actions=multipath(eth_src,50,modulo_n,1,0,NXM_NX_REG0[]) > > @@ -289,7 +289,7 @@ AT_CAPTURE_FILE([input.txt]) > > AT_CAPTURE_FILE([expout]) > > AT_CAPTURE_FILE([experr]) > > AT_CHECK( > > - [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-ofp11-actions < input.txt], > > + [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-actions OpenFlow11 < > > input.txt], > > [0], [expout], [experr]) > > AT_CLEANUP > > > > @@ -325,16 +325,16 @@ dnl Check that an empty Apply-Actions instruction > > gets dropped. > > 0004 0008 00000000 > > > > dnl Duplicate instruction type: > > -# bad OF1.1 instructions: OFPBIC_DUP_INST > > +# bad OpenFlow11 instructions: OFPBIC_DUP_INST > > 0004 0008 00000000 0004 0008 00000000 > > > > dnl Instructions not multiple of 8 in length. > > & ofp_actions|WARN|OpenFlow message instructions length 9 is not a multiple > > of 8 > > -# bad OF1.1 instructions: OFPBIC_BAD_LEN > > +# bad OpenFlow11 instructions: OFPBIC_BAD_LEN > > 0004 0009 01 00000000 > > > > dnl Goto-Table instruction too long. > > -# bad OF1.1 instructions: OFPBIC_BAD_LEN > > +# bad OpenFlow11 instructions: OFPBIC_BAD_LEN > > 0001 0010 01 000000 0000000000000000 > > > > dnl Goto-Table 1 instruction non-zero padding > > @@ -343,7 +343,7 @@ dnl Goto-Table 1 instruction non-zero padding > > 0001 0008 01 000001 > > > > dnl Goto-Table 1 instruction go back to the previous table. > > -# bad OF1.1 instructions: OFPBRC_BAD_TABLE_ID > > +# bad OpenFlow11 instructions: OFPBRC_BAD_TABLE_ID > > 2,0001 0008 01 000000 > > > > dnl Goto-Table 1 > > @@ -397,15 +397,15 @@ dnl Write-Metadata with mask. > > 0002 0018 00000000 fedcba9876543210 ff00ff00ff00ff00 > > > > dnl Write-Metadata too short. > > -# bad OF1.1 instructions: OFPBIC_BAD_LEN > > +# bad OpenFlow11 instructions: OFPBIC_BAD_LEN > > 0002 0010 00000000 fedcba9876543210 > > > > dnl Write-Metadata too long. > > -# bad OF1.1 instructions: OFPBIC_BAD_LEN > > +# bad OpenFlow11 instructions: OFPBIC_BAD_LEN > > 0002 0020 00000000 fedcba9876543210 ffffffffffffffff 0000000000000000 > > > > dnl Write-Metadata duplicated. > > -# bad OF1.1 instructions: OFPBIC_DUP_INST > > +# bad OpenFlow11 instructions: OFPBIC_DUP_INST > > 0002 0018 00000000 fedcba9876543210 ff00ff00ff00ff00 0002 0018 00000000 > > fedcba9876543210 ff00ff00ff00ff00 > > > > dnl Write-Metadata in wrong position (OpenFlow 1.1+ disregards the order > > @@ -465,7 +465,7 @@ dnl Check that an empty Write-Actions instruction gets > > dropped. > > 0003 0008 00000000 > > > > dnl Clear-Actions too-long > > -# bad OF1.1 instructions: OFPBIC_BAD_LEN > > +# bad OpenFlow11 instructions: OFPBIC_BAD_LEN > > 0005 0010 00000000 0000000000000000 > > > > dnl Clear-Actions non-zero padding > > @@ -483,11 +483,11 @@ dnl Clear-Actions > > 0005 0008 00000000 > > > > dnl Experimenter actions not supported yet. > > -# bad OF1.1 instructions: OFPBIC_BAD_EXPERIMENTER > > +# bad OpenFlow11 instructions: OFPBIC_BAD_EXPERIMENTER > > ffff 0008 01 000000 > > > > dnl Bad instruction number (0 not assigned). > > -# bad OF1.1 instructions: OFPBIC_UNKNOWN_INST > > +# bad OpenFlow11 instructions: OFPBIC_UNKNOWN_INST > > 0000 0008 01 000000 > > > > ]) > > @@ -498,7 +498,7 @@ AT_CAPTURE_FILE([input.txt]) > > AT_CAPTURE_FILE([expout]) > > AT_CAPTURE_FILE([experr]) > > AT_CHECK( > > - [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-ofp11-instructions < > > input.txt], > > + [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-instructions OpenFlow11 < > > input.txt], > > [0], [expout], [experr]) > > AT_CLEANUP > > > > diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c > > index c05197a..cd8f840 100644 > > --- a/utilities/ovs-ofctl.c > > +++ b/utilities/ovs-ofctl.c > > @@ -2936,39 +2936,70 @@ print_differences(const char *prefix, > > } > > > > static void > > -ofctl_parse_ofp10_actions__(bool instructions) > > +ofctl_parse_actions__(const char *version_s, bool instructions) > > { > > + enum ofp_version version; > > struct ds in; > > > > + version = ofputil_version_from_string(version_s); > > + if (!version) { > > + ovs_fatal(0, "%s: not a valid OpenFlow version", version_s); > > + } > > + > > ds_init(&in); > > while (!ds_get_preprocessed_line(&in, stdin, NULL)) { > > - struct ofpbuf of10_out; > > - struct ofpbuf of10_in; > > + struct ofpbuf of_out; > > + struct ofpbuf of_in; > > struct ofpbuf ofpacts; > > + const char *table_id; > > + char *actions; > > enum ofperr error; > > size_t size; > > struct ds s; > > > > + /* Parse table_id separated with the follow-up actions by ",", if > > + * any. */ > > + actions = ds_cstr(&in); > > + table_id = NULL; > > + if (strstr(actions, ",")) { > > + table_id = strsep(&actions, ","); > > + } > > + > > /* Parse hex bytes. */ > > - ofpbuf_init(&of10_in, 0); > > - if (ofpbuf_put_hex(&of10_in, ds_cstr(&in), NULL)[0] != '\0') { > > + ofpbuf_init(&of_in, 0); > > + if (ofpbuf_put_hex(&of_in, actions, NULL)[0] != '\0') { > > ovs_fatal(0, "Trailing garbage in hex data"); > > } > > > > /* Convert to ofpacts. */ > > ofpbuf_init(&ofpacts, 0); > > - size = ofpbuf_size(&of10_in); > > + size = ofpbuf_size(&of_in); > > error = (instructions > > ? ofpacts_pull_openflow_instructions > > : ofpacts_pull_openflow_actions)( > > - &of10_in, ofpbuf_size(&of10_in), OFP10_VERSION, > > &ofpacts); > > + &of_in, ofpbuf_size(&of_in), version, &ofpacts); > > + if (!error && instructions) { > > + /* Verify actions, enforce consistency. */ > > + enum ofputil_protocol protocol; > > + struct flow flow; > > + > > + memset(&flow, 0, sizeof flow); > > + protocol = ofputil_protocols_from_ofp_version(version); > > + error = ofpacts_check_consistency(ofpbuf_data(&ofpacts), > > + ofpbuf_size(&ofpacts), > > + &flow, OFPP_MAX, > > + table_id ? atoi(table_id) : > > 0, > > + 255, protocol); > > + } > > if (error) { > > - printf("bad OF1.0 actions: %s\n\n", ofperr_get_name(error)); > > + printf("bad %s %s: %s\n\n", > > + version_s, instructions ? "instructions" : "actions", > > + ofperr_get_name(error)); > > ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of10_in); > > + ofpbuf_uninit(&of_in); > > continue; > > } > > - ofpbuf_push_uninit(&of10_in, size); > > + ofpbuf_push_uninit(&of_in, size); > > > > /* Print cls_rule. */ > > ds_init(&s); > > @@ -2978,39 +3009,46 @@ ofctl_parse_ofp10_actions__(bool instructions) > > ds_destroy(&s); > > > > /* Convert back to ofp10 actions and print differences from input. > > */ > > - ofpbuf_init(&of10_out, 0); > > - ofpacts_put_openflow_actions(ofpbuf_data(&ofpacts), > > ofpbuf_size(&ofpacts), &of10_out, > > - OFP10_VERSION); > > + ofpbuf_init(&of_out, 0); > > + if (instructions) { > > + ofpacts_put_openflow_instructions( ofpbuf_data(&ofpacts), > > + ofpbuf_size(&ofpacts), > > + &of_out, version); > > + } else { > > + ofpacts_put_openflow_actions( ofpbuf_data(&ofpacts), > > + ofpbuf_size(&ofpacts), > > + &of_out, version); > > + } > > > > - print_differences("", ofpbuf_data(&of10_in), ofpbuf_size(&of10_in), > > - ofpbuf_data(&of10_out), ofpbuf_size(&of10_out)); > > + print_differences("", ofpbuf_data(&of_in), ofpbuf_size(&of_in), > > + ofpbuf_data(&of_out), ofpbuf_size(&of_out)); > > putchar('\n'); > > > > ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of10_in); > > - ofpbuf_uninit(&of10_out); > > + ofpbuf_uninit(&of_in); > > + ofpbuf_uninit(&of_out); > > } > > ds_destroy(&in); > > } > > > > -/* "parse-ofp10-actions": reads a series of OpenFlow 1.0 action > > specifications > > - * as hex bytes from stdin, converts them to ofpacts, prints them as > > strings > > - * on stdout, and then converts them back to hex bytes and prints any > > - * differences from the input. */ > > +/* "parse-actions VERSION": reads a series of action specifications for the > > + * given OpenFlow VERSION as hex bytes from stdin, converts them to > > ofpacts, > > + * prints them as strings on stdout, and then converts them back to hex > > bytes > > + * and prints any differences from the input. */ > > static void > > -ofctl_parse_ofp10_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) > > +ofctl_parse_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) > > { > > - ofctl_parse_ofp10_actions__(false); > > + ofctl_parse_actions__(argv[1], false); > > } > > > > -/* "parse-ofp10-instructions": reads a series of OpenFlow 1.0 action > > - * specifications as hex bytes from stdin, converts them to ofpacts, prints > > - * them as strings on stdout, and then converts them back to hex bytes and > > - * prints any differences from the input. */ > > +/* "parse-actions VERSION": reads a series of instruction specifications > > for > > + * the given OpenFlow VERSION as hex bytes from stdin, converts them to > > + * ofpacts, prints them as strings on stdout, and then converts them back > > to > > + * hex bytes and prints any differences from the input. */ > > static void > > -ofctl_parse_ofp10_instructions(int argc OVS_UNUSED, char *argv[] > > OVS_UNUSED) > > +ofctl_parse_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) > > { > > - ofctl_parse_ofp10_actions__(true); > > + ofctl_parse_actions__(argv[1], true); > > } > > > > /* "parse-ofp10-match": reads a series of ofp10_match specifications as hex > > @@ -3141,146 +3179,6 @@ ofctl_parse_ofp11_match(int argc OVS_UNUSED, char > > *argv[] OVS_UNUSED) > > ds_destroy(&in); > > } > > > > -/* "parse-ofp11-actions": reads a series of OpenFlow 1.1 action > > specifications > > - * as hex bytes from stdin, converts them to ofpacts, prints them as > > strings > > - * on stdout, and then converts them back to hex bytes and prints any > > - * differences from the input. */ > > -static void > > -ofctl_parse_ofp11_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) > > -{ > > - struct ds in; > > - > > - ds_init(&in); > > - while (!ds_get_preprocessed_line(&in, stdin, NULL)) { > > - struct ofpbuf of11_out; > > - struct ofpbuf of11_in; > > - struct ofpbuf ofpacts; > > - enum ofperr error; > > - size_t size; > > - struct ds s; > > - > > - /* Parse hex bytes. */ > > - ofpbuf_init(&of11_in, 0); > > - if (ofpbuf_put_hex(&of11_in, ds_cstr(&in), NULL)[0] != '\0') { > > - ovs_fatal(0, "Trailing garbage in hex data"); > > - } > > - > > - /* Convert to ofpacts. */ > > - ofpbuf_init(&ofpacts, 0); > > - size = ofpbuf_size(&of11_in); > > - error = ofpacts_pull_openflow_actions(&of11_in, > > ofpbuf_size(&of11_in), > > - OFP11_VERSION, &ofpacts); > > - if (error) { > > - printf("bad OF1.1 actions: %s\n\n", ofperr_get_name(error)); > > - ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of11_in); > > - continue; > > - } > > - ofpbuf_push_uninit(&of11_in, size); > > - > > - /* Print cls_rule. */ > > - ds_init(&s); > > - ds_put_cstr(&s, "actions="); > > - ofpacts_format(ofpbuf_data(&ofpacts), ofpbuf_size(&ofpacts), &s); > > - puts(ds_cstr(&s)); > > - ds_destroy(&s); > > - > > - /* Convert back to ofp11 actions and print differences from input. > > */ > > - ofpbuf_init(&of11_out, 0); > > - ofpacts_put_openflow_actions(ofpbuf_data(&ofpacts), > > ofpbuf_size(&ofpacts), &of11_out, > > - OFP11_VERSION); > > - > > - print_differences("", ofpbuf_data(&of11_in), ofpbuf_size(&of11_in), > > - ofpbuf_data(&of11_out), ofpbuf_size(&of11_out)); > > - putchar('\n'); > > - > > - ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of11_in); > > - ofpbuf_uninit(&of11_out); > > - } > > - ds_destroy(&in); > > -} > > - > > -/* "parse-ofp11-instructions": reads a series of OpenFlow 1.1 instruction > > - * specifications as hex bytes from stdin, converts them to ofpacts, prints > > - * them as strings on stdout, and then converts them back to hex bytes and > > - * prints any differences from the input. */ > > -static void > > -ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] > > OVS_UNUSED) > > -{ > > - struct ds in; > > - > > - ds_init(&in); > > - while (!ds_get_preprocessed_line(&in, stdin, NULL)) { > > - struct ofpbuf of11_out; > > - struct ofpbuf of11_in; > > - struct ofpbuf ofpacts; > > - enum ofperr error; > > - size_t size; > > - struct ds s; > > - const char *table_id; > > - char *instructions; > > - > > - /* Parse table_id separated with the follow-up instructions by > > ",", if > > - * any. */ > > - instructions = ds_cstr(&in); > > - table_id = NULL; > > - if (strstr(instructions, ",")) { > > - table_id = strsep(&instructions, ","); > > - } > > - > > - /* Parse hex bytes. */ > > - ofpbuf_init(&of11_in, 0); > > - if (ofpbuf_put_hex(&of11_in, instructions, NULL)[0] != '\0') { > > - ovs_fatal(0, "Trailing garbage in hex data"); > > - } > > - > > - /* Convert to ofpacts. */ > > - ofpbuf_init(&ofpacts, 0); > > - size = ofpbuf_size(&of11_in); > > - error = ofpacts_pull_openflow_instructions(&of11_in, > > ofpbuf_size(&of11_in), > > - OFP11_VERSION, > > &ofpacts); > > - if (!error) { > > - /* Verify actions, enforce consistency. */ > > - struct flow flow; > > - memset(&flow, 0, sizeof flow); > > - error = ofpacts_check_consistency(ofpbuf_data(&ofpacts), > > ofpbuf_size(&ofpacts), > > - &flow, OFPP_MAX, > > - table_id ? atoi(table_id) : > > 0, > > - 255, OFPUTIL_P_OF11_STD); > > - } > > - if (error) { > > - printf("bad OF1.1 instructions: %s\n\n", > > ofperr_get_name(error)); > > - ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of11_in); > > - continue; > > - } > > - ofpbuf_push_uninit(&of11_in, size); > > - > > - /* Print cls_rule. */ > > - ds_init(&s); > > - ds_put_cstr(&s, "actions="); > > - ofpacts_format(ofpbuf_data(&ofpacts), ofpbuf_size(&ofpacts), &s); > > - puts(ds_cstr(&s)); > > - ds_destroy(&s); > > - > > - /* Convert back to ofp11 instructions and print differences from > > - * input. */ > > - ofpbuf_init(&of11_out, 0); > > - ofpacts_put_openflow_instructions(ofpbuf_data(&ofpacts), > > ofpbuf_size(&ofpacts), > > - &of11_out, OFP13_VERSION); > > - > > - print_differences("", ofpbuf_data(&of11_in), ofpbuf_size(&of11_in), > > - ofpbuf_data(&of11_out), ofpbuf_size(&of11_out)); > > - putchar('\n'); > > - > > - ofpbuf_uninit(&ofpacts); > > - ofpbuf_uninit(&of11_in); > > - ofpbuf_uninit(&of11_out); > > - } > > - ds_destroy(&in); > > -} > > - > > /* "parse-pcap PCAP": read packets from PCAP and print their flows. */ > > static void > > ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[]) > > @@ -3587,12 +3485,10 @@ static const struct command all_commands[] = { > > { "parse-nx-match", 0, 0, ofctl_parse_nxm }, > > { "parse-nxm", 0, 0, ofctl_parse_nxm }, > > { "parse-oxm", 1, 1, ofctl_parse_oxm }, > > - { "parse-ofp10-actions", 0, 0, ofctl_parse_ofp10_actions }, > > - { "parse-ofp10-instructions", 0, 0, ofctl_parse_ofp10_instructions }, > > + { "parse-actions", 1, 1, ofctl_parse_actions }, > > + { "parse-instructions", 1, 1, ofctl_parse_instructions }, > > { "parse-ofp10-match", 0, 0, ofctl_parse_ofp10_match }, > > { "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match }, > > - { "parse-ofp11-actions", 0, 0, ofctl_parse_ofp11_actions }, > > - { "parse-ofp11-instructions", 0, 0, ofctl_parse_ofp11_instructions }, > > { "parse-pcap", 1, 1, ofctl_parse_pcap }, > > { "check-vlan", 2, 2, ofctl_check_vlan }, > > { "print-error", 1, 1, ofctl_print_error }, > > -- > > 1.7.10.4 > > > > _______________________________________________ > > dev mailing list > > dev@openvswitch.org > > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev