X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-parse.c;h=1c5c761e53ffe14164dd9fbcdb8759e6ca00e89f;hb=a39c3ff9f586d3416976d3c3bd095fa81d73efa0;hp=1d71370d4d0c78455389eba3d8e4537a1af38ec4;hpb=7f05e7abc8fc190c5ff60dd3c3fcd4b9eb5c8dfa;p=sliver-openvswitch.git diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 1d71370d4..1c5c761e5 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -22,7 +22,6 @@ #include #include -#include "autopath.h" #include "bundle.h" #include "byte-order.h" #include "dynamic-string.h" @@ -318,6 +317,18 @@ parse_dec_ttl(struct ofpbuf *b, char *arg) } } +static void +parse_set_mpls_ttl(struct ofpbuf *b, const char *arg) +{ + struct ofpact_mpls_ttl *mpls_ttl = ofpact_put_SET_MPLS_TTL(b); + + if (*arg == '\0') { + ovs_fatal(0, "parse_set_mpls_ttl: expected ttl."); + } + + mpls_ttl->ttl = atoi(arg); +} + static void set_field_parse(const char *arg, struct ofpbuf *ofpacts) { @@ -379,7 +390,35 @@ parse_metadata(struct ofpbuf *b, char *arg) } static void -parse_named_action(enum ofputil_action_code code, const struct flow *flow, +parse_sample(struct ofpbuf *b, char *arg) +{ + struct ofpact_sample *os = ofpact_put_SAMPLE(b); + char *key, *value; + + while (ofputil_parse_key_value(&arg, &key, &value)) { + if (!strcmp(key, "probability")) { + os->probability = str_to_u16(value, "probability"); + if (os->probability == 0) { + ovs_fatal(0, "invalid probability value \"%s\"", value); + } + } else if (!strcmp(key, "collector_set_id")) { + os->collector_set_id = str_to_u32(value); + } else if (!strcmp(key, "obs_domain_id")) { + os->obs_domain_id = str_to_u32(value); + } else if (!strcmp(key, "obs_point_id")) { + os->obs_point_id = str_to_u32(value); + } else { + ovs_fatal(0, "invalid key \"%s\" in \"sample\" argument", + key); + } + } + if (os->probability == 0) { + ovs_fatal(0, "non-zero \"probability\" must be specified on sample"); + } +} + +static void +parse_named_action(enum ofputil_action_code code, char *arg, struct ofpbuf *ofpacts) { struct ofpact_tunnel *tunnel; @@ -428,12 +467,17 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, case OFPUTIL_OFPAT11_PUSH_VLAN: ethertype = str_to_u16(arg, "ethertype"); if (ethertype != ETH_TYPE_VLAN_8021Q) { - /* TODO:XXXX ETH_TYPE_VLAN_8021AD case isn't supported */ + /* XXX ETH_TYPE_VLAN_8021AD case isn't supported */ ovs_fatal(0, "%s: not a valid VLAN ethertype", arg); } ofpact_put_PUSH_VLAN(ofpacts); break; + case OFPUTIL_OFPAT11_SET_QUEUE: + ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg); + break; + + case OFPUTIL_OFPAT10_SET_DL_SRC: case OFPUTIL_OFPAT11_SET_DL_SRC: str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac); @@ -521,10 +565,6 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, multipath_parse(ofpact_put_MULTIPATH(ofpacts), arg); break; - case OFPUTIL_NXAST_AUTOPATH__DEPRECATED: - autopath_parse(ofpact_put_AUTOPATH(ofpacts), arg); - break; - case OFPUTIL_NXAST_BUNDLE: bundle_parse(arg, ofpacts); break; @@ -539,7 +579,7 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, NOT_REACHED(); case OFPUTIL_NXAST_LEARN: - learn_parse(arg, flow, ofpacts); + learn_parse(arg, ofpacts); break; case OFPUTIL_NXAST_EXIT: @@ -550,6 +590,16 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, parse_dec_ttl(ofpacts, arg); break; + case OFPUTIL_NXAST_SET_MPLS_TTL: + case OFPUTIL_OFPAT11_SET_MPLS_TTL: + parse_set_mpls_ttl(ofpacts, arg); + break; + + case OFPUTIL_OFPAT11_DEC_MPLS_TTL: + case OFPUTIL_NXAST_DEC_MPLS_TTL: + ofpact_put_DEC_MPLS_TTL(ofpacts); + break; + case OFPUTIL_NXAST_FIN_TIMEOUT: parse_fin_timeout(ofpacts, arg); break; @@ -557,16 +607,39 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, case OFPUTIL_NXAST_CONTROLLER: parse_controller(ofpacts, arg); break; + + case OFPUTIL_OFPAT11_PUSH_MPLS: + case OFPUTIL_NXAST_PUSH_MPLS: + ofpact_put_PUSH_MPLS(ofpacts)->ethertype = + htons(str_to_u16(arg, "push_mpls")); + break; + + case OFPUTIL_OFPAT11_POP_MPLS: + case OFPUTIL_NXAST_POP_MPLS: + ofpact_put_POP_MPLS(ofpacts)->ethertype = + htons(str_to_u16(arg, "pop_mpls")); + break; + + case OFPUTIL_NXAST_STACK_PUSH: + nxm_parse_stack_action(ofpact_put_STACK_PUSH(ofpacts), arg); + break; + case OFPUTIL_NXAST_STACK_POP: + nxm_parse_stack_action(ofpact_put_STACK_POP(ofpacts), arg); + break; + + case OFPUTIL_NXAST_SAMPLE: + parse_sample(ofpacts, arg); + break; } } static bool -str_to_ofpact__(const struct flow *flow, char *pos, char *act, char *arg, +str_to_ofpact__(char *pos, char *act, char *arg, struct ofpbuf *ofpacts, int n_actions) { int code = ofputil_action_code_from_name(act); if (code >= 0) { - parse_named_action(code, flow, arg, ofpacts); + parse_named_action(code, arg, ofpacts); } else if (!strcasecmp(act, "drop")) { if (n_actions) { ovs_fatal(0, "Drop actions must not be preceded by other " @@ -589,7 +662,7 @@ str_to_ofpact__(const struct flow *flow, char *pos, char *act, char *arg, } static void -str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) +str_to_ofpacts(char *str, struct ofpbuf *ofpacts) { char *pos, *act, *arg; enum ofperr error; @@ -598,7 +671,7 @@ str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) pos = str; n_actions = 0; while (ofputil_parse_key_value(&pos, &act, &arg)) { - if (!str_to_ofpact__(flow, pos, act, arg, ofpacts, n_actions)) { + if (!str_to_ofpact__(pos, act, arg, ofpacts, n_actions)) { break; } n_actions++; @@ -624,7 +697,7 @@ parse_named_instruction(enum ovs_instruction_type type, break; case OVSINST_OFPIT11_WRITE_ACTIONS: - /* TODO:XXX */ + /* XXX */ ovs_fatal(0, "instruction write-actions is not supported yet"); break; @@ -656,7 +729,7 @@ parse_named_instruction(enum ovs_instruction_type type, } static void -str_to_inst_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) +str_to_inst_ofpacts(char *str, struct ofpbuf *ofpacts) { char *pos, *inst, *arg; int type; @@ -668,7 +741,7 @@ str_to_inst_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) while (ofputil_parse_key_value(&pos, &inst, &arg)) { type = ofpact_instruction_type_from_name(inst); if (type < 0) { - if (!str_to_ofpact__(flow, pos, inst, arg, ofpacts, n_actions)) { + if (!str_to_ofpact__(pos, inst, arg, ofpacts, n_actions)) { break; } @@ -721,7 +794,9 @@ parse_protocol(const char *name, const struct protocol **p_out) { "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP }, { "udp6", ETH_TYPE_IPV6, IPPROTO_UDP }, { "rarp", ETH_TYPE_RARP, 0}, -}; + { "mpls", ETH_TYPE_MPLS, 0 }, + { "mplsm", ETH_TYPE_MPLS_MCAST, 0 }, + }; const struct protocol *p; for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) { @@ -858,6 +933,12 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, fm->flags |= OFPFF_SEND_FLOW_REM; } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) { fm->flags |= OFPFF_CHECK_OVERLAP; + } else if (fields & F_FLAGS && !strcmp(name, "reset_counts")) { + fm->flags |= OFPFF12_RESET_COUNTS; + } else if (fields & F_FLAGS && !strcmp(name, "no_packet_counts")) { + fm->flags |= OFPFF13_NO_PKT_COUNTS; + } else if (fields & F_FLAGS && !strcmp(name, "no_byte_counts")) { + fm->flags |= OFPFF13_NO_BYT_COUNTS; } else { char *value; @@ -903,7 +984,9 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, parse_field(mf_from_name(name), value, &fm->match); } else if (!strcmp(name, "duration") || !strcmp(name, "n_packets") - || !strcmp(name, "n_bytes")) { + || !strcmp(name, "n_bytes") + || !strcmp(name, "idle_age") + || !strcmp(name, "hard_age")) { /* Ignore these, so that users can feed the output of * "ovs-ofctl dump-flows" back into commands that parse * flows. */ @@ -921,11 +1004,19 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, } if (fields & F_ACTIONS) { struct ofpbuf ofpacts; + enum ofperr err; ofpbuf_init(&ofpacts, 32); - str_to_inst_ofpacts(&fm->match.flow, act_str, &ofpacts); + str_to_inst_ofpacts(act_str, &ofpacts); fm->ofpacts_len = ofpacts.size; fm->ofpacts = ofpbuf_steal_data(&ofpacts); + + err = ofpacts_check(fm->ofpacts, fm->ofpacts_len, &fm->match.flow, + OFPP_MAX); + if (err) { + exit(EXIT_FAILURE); + } + } else { fm->ofpacts_len = 0; fm->ofpacts = NULL; @@ -1005,7 +1096,7 @@ void parse_ofpacts(const char *s_, struct ofpbuf *ofpacts) { char *s = xstrdup(s_); - str_to_ofpacts(NULL, s, ofpacts); + str_to_ofpacts(s, ofpacts); free(s); } @@ -1138,6 +1229,10 @@ parse_ofp_exact_flow(struct flow *flow, const char *s) } } + if (!flow->in_port) { + flow->in_port = OFPP_NONE; + } + exit: free(copy);