X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-parse.c;h=dedfb7e27ca90e4249a1164633e70c394bd2c7b6;hb=7c690f462fec1af60d76c67fac226fc648ea9149;hp=122f4b36d33fd8e826ee3997fc8566b70a9b834c;hpb=8e61c1104eddbe737a67cbf559fcb48971f59569;p=sliver-openvswitch.git diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 122f4b36d..dedfb7e27 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -279,13 +279,12 @@ parse_controller(struct ofpbuf *b, char *arg) } static void -parse_noargs_dec_ttl(struct ofpbuf *b, enum ofputil_action_code compat) +parse_noargs_dec_ttl(struct ofpbuf *b) { struct ofpact_cnt_ids *ids; uint16_t id = 0; ids = ofpact_put_DEC_TTL(b); - ids->ofpact.compat = compat; ofpbuf_put(b, &id, sizeof id); ids = b->l2; ids->n_controllers++; @@ -293,10 +292,10 @@ parse_noargs_dec_ttl(struct ofpbuf *b, enum ofputil_action_code compat) } static void -parse_dec_ttl(struct ofpbuf *b, char *arg, enum ofputil_action_code compat) +parse_dec_ttl(struct ofpbuf *b, char *arg) { if (*arg == '\0') { - parse_noargs_dec_ttl(b, compat); + parse_noargs_dec_ttl(b); } else { struct ofpact_cnt_ids *ids; char *cntr; @@ -361,12 +360,31 @@ set_field_parse(const char *arg, struct ofpbuf *ofpacts) free(orig); } +static void +parse_metadata(struct ofpbuf *b, char *arg) +{ + struct ofpact_metadata *om; + char *mask = strchr(arg, '/'); + + om = ofpact_put_WRITE_METADATA(b); + + if (mask) { + *mask = '\0'; + om->mask = htonll(str_to_u64(mask + 1)); + } else { + om->mask = htonll(UINT64_MAX); + } + + om->metadata = htonll(str_to_u64(arg)); +} + static void parse_named_action(enum ofputil_action_code code, const struct flow *flow, char *arg, struct ofpbuf *ofpacts) { struct ofpact_tunnel *tunnel; uint16_t vid; + uint16_t ethertype; ovs_be32 ip; uint8_t pcp; uint8_t tos; @@ -407,6 +425,15 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, ofpact_put_STRIP_VLAN(ofpacts); break; + 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 */ + ovs_fatal(0, "%s: not a valid VLAN ethertype", arg); + } + ofpact_put_PUSH_VLAN(ofpacts); + break; + case OFPUTIL_OFPAT10_SET_DL_SRC: case OFPUTIL_OFPAT11_SET_DL_SRC: str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac); @@ -439,8 +466,7 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, break; case OFPUTIL_OFPAT11_DEC_NW_TTL: - parse_noargs_dec_ttl(ofpacts, code); - break; + NOT_REACHED(); case OFPUTIL_OFPAT10_SET_TP_SRC: case OFPUTIL_OFPAT11_SET_TP_SRC: @@ -467,6 +493,10 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, tunnel->tun_id = str_to_u64(arg); break; + case OFPUTIL_NXAST_WRITE_METADATA: + parse_metadata(ofpacts, arg); + break; + case OFPUTIL_NXAST_SET_QUEUE: ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg); break; @@ -517,7 +547,7 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, break; case OFPUTIL_NXAST_DEC_TTL: - parse_dec_ttl(ofpacts, arg, code); + parse_dec_ttl(ofpacts, arg); break; case OFPUTIL_NXAST_FIN_TIMEOUT: @@ -562,6 +592,7 @@ static void str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) { char *pos, *act, *arg; + enum ofperr error; int n_actions; pos = str; @@ -572,6 +603,12 @@ str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) } n_actions++; } + + error = ofpacts_verify(ofpacts->data, ofpacts->size); + if (error) { + ovs_fatal(0, "Incorrect action ordering"); + } + ofpact_pad(ofpacts); } @@ -579,6 +616,8 @@ static void parse_named_instruction(enum ovs_instruction_type type, char *arg, struct ofpbuf *ofpacts) { + enum ofperr error; + switch (type) { case OVSINST_OFPIT11_APPLY_ACTIONS: NOT_REACHED(); /* This case is handled by str_to_inst_ofpacts() */ @@ -594,8 +633,7 @@ parse_named_instruction(enum ovs_instruction_type type, break; case OVSINST_OFPIT11_WRITE_METADATA: - /* TODO:XXX */ - ovs_fatal(0, "instruction write-metadata is not supported yet"); + parse_metadata(ofpacts, arg); break; case OVSINST_OFPIT11_GOTO_TABLE: { @@ -608,6 +646,13 @@ parse_named_instruction(enum ovs_instruction_type type, break; } } + + /* If write_metadata is specified as an action AND an instruction, ofpacts + could be invalid. */ + error = ofpacts_verify(ofpacts->data, ofpacts->size); + if (error) { + ovs_fatal(0, "Incorrect instruction ordering"); + } } static void