X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Fofp-parse.c;h=24f6876bc8ab5203f8f54a1c83ee6cf82c44fc29;hb=541bc79f73add327072470c9bc3febb4195cdb3c;hp=67224eb63b69401667aaa8d1bd3dfa52394c9f4d;hpb=c3636ffc10a2a016b89d05c9456b3fdc030d444c;p=openvswitch diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 67224eb6..24f6876b 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011 Nicira Networks. + * Copyright (c) 2010, 2011, 2012 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -151,14 +151,13 @@ parse_output(struct ofpbuf *b, char *arg) { if (strchr(arg, '[')) { struct nx_action_output_reg *naor; - int ofs, n_bits; - uint32_t src; + struct mf_subfield src; - nxm_parse_field_bits(arg, &src, &ofs, &n_bits); + mf_parse_subfield(&src, arg); naor = ofputil_put_NXAST_OUTPUT_REG(b); - naor->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits); - naor->src = htonl(src); + naor->ofs_nbits = nxm_encode_ofs_nbits(src.ofs, src.n_bits); + naor->src = htonl(src.field->nxm_header); naor->max_len = htons(UINT16_MAX); } else { put_output_action(b, str_to_u32(arg)); @@ -250,6 +249,24 @@ parse_note(struct ofpbuf *b, const char *arg) nan->len = htons(b->size - start_ofs); } +static void +parse_fin_timeout(struct ofpbuf *b, char *arg) +{ + struct nx_action_fin_timeout *naft; + char *key, *value; + + naft = ofputil_put_NXAST_FIN_TIMEOUT(b); + while (ofputil_parse_key_value(&arg, &key, &value)) { + if (!strcmp(key, "idle_timeout")) { + naft->fin_idle_timeout = htons(str_to_u16(value, key)); + } else if (!strcmp(key, "hard_timeout")) { + naft->fin_hard_timeout = htons(str_to_u16(value, key)); + } else { + ovs_fatal(0, "invalid key '%s' in 'fin_timeout' argument", key); + } + } +} + static void parse_named_action(enum ofputil_action_code code, const struct flow *flow, struct ofpbuf *b, char *arg) @@ -360,6 +377,18 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, case OFPUTIL_NXAST_LEARN: learn_parse(b, arg, flow); break; + + case OFPUTIL_NXAST_EXIT: + ofputil_put_NXAST_EXIT(b); + break; + + case OFPUTIL_NXAST_DEC_TTL: + ofputil_put_NXAST_DEC_TTL(b); + break; + + case OFPUTIL_NXAST_FIN_TIMEOUT: + parse_fin_timeout(b, arg); + break; } } @@ -484,9 +513,9 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, enum { F_OUT_PORT = 1 << 0, F_ACTIONS = 1 << 1, - F_COOKIE = 1 << 2, F_TIMEOUT = 1 << 3, - F_PRIORITY = 1 << 4 + F_PRIORITY = 1 << 4, + F_FLAGS = 1 << 5, } fields; char *string = xstrdup(str_); char *save_ptr = NULL; @@ -499,7 +528,7 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, break; case OFPFC_ADD: - fields = F_ACTIONS | F_COOKIE | F_TIMEOUT | F_PRIORITY; + fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; case OFPFC_DELETE: @@ -511,11 +540,11 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, break; case OFPFC_MODIFY: - fields = F_ACTIONS | F_COOKIE; + fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; case OFPFC_MODIFY_STRICT: - fields = F_ACTIONS | F_COOKIE | F_PRIORITY; + fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; default: @@ -524,6 +553,7 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, cls_rule_init_catchall(&fm->cr, OFP_DEFAULT_PRIORITY); fm->cookie = htonll(0); + fm->cookie_mask = htonll(0); fm->table_id = 0xff; fm->command = command; fm->idle_timeout = OFP_FLOW_PERMANENT; @@ -554,6 +584,10 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, if (p->nw_proto) { cls_rule_set_nw_proto(&fm->cr, p->nw_proto); } + } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) { + fm->flags |= OFPFF_SEND_FLOW_REM; + } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) { + fm->flags |= OFPFF_CHECK_OVERLAP; } else { char *value; @@ -572,7 +606,18 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, fm->idle_timeout = str_to_u16(value, name); } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) { fm->hard_timeout = str_to_u16(value, name); - } else if (fields & F_COOKIE && !strcmp(name, "cookie")) { + } else if (!strcmp(name, "cookie")) { + char *mask = strchr(value, '/'); + if (mask) { + if (command == OFPFC_ADD) { + ofp_fatal(str_, verbose, "flow additions cannot use " + "a cookie mask"); + } + *mask = '\0'; + fm->cookie_mask = htonll(str_to_u64(mask+1)); + } else { + fm->cookie_mask = htonll(UINT64_MAX); + } fm->cookie = htonll(str_to_u64(value)); } else if (mf_from_name(name)) { parse_field(mf_from_name(name), value, &fm->cr); @@ -602,6 +647,19 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, free(string); } +/* Parses 's' as a set of OpenFlow actions and appends the actions to + * 'actions'. + * + * Prints an error on stderr and aborts the program if 's' syntax is + * invalid. */ +void +parse_ofp_actions(const char *s_, struct ofpbuf *actions) +{ + char *s = xstrdup(s_); + str_to_action(NULL, s, actions); + free(s); +} + /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command' * (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'. * '*cur_format' should initially contain the flow format currently configured @@ -621,6 +679,9 @@ parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format, parse_ofp_str(&fm, command, string, verbose); min_format = ofputil_min_flow_format(&fm.cr); + if (command != OFPFC_ADD && fm.cookie_mask != htonll(0)) { + min_format = NXFF_NXM; + } next_format = MAX(*cur_format, min_format); if (next_format != *cur_format) { struct ofpbuf *sff = ofputil_make_set_flow_format(next_format); @@ -674,6 +735,8 @@ parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr, parse_ofp_str(&fm, -1, string, false); fsr->aggregate = aggregate; + fsr->cookie = fm.cookie; + fsr->cookie_mask = fm.cookie_mask; fsr->match = fm.cr; fsr->out_port = fm.out_port; fsr->table_id = fm.table_id;