Nifty patch. This has always been a pain point when implementing new actions. Glad to see it all generated now.
Ethan On Tue, Aug 16, 2011 at 16:29, Ben Pfaff <b...@nicira.com> wrote: > --- > lib/autopath.c | 6 +-- > lib/bundle.c | 7 +-- > lib/multipath.c | 6 +-- > lib/nx-match.c | 10 +---- > lib/ofp-parse.c | 124 > ++++++++++++++++--------------------------------------- > lib/ofp-util.c | 59 ++++++++++++++++++++++++-- > lib/ofp-util.h | 24 +++++++++++ > 7 files changed, 122 insertions(+), 114 deletions(-) > > diff --git a/lib/autopath.c b/lib/autopath.c > index b42826c..9a39c6a 100644 > --- a/lib/autopath.c > +++ b/lib/autopath.c > @@ -67,11 +67,7 @@ autopath_parse(struct nx_action_autopath *ap, const char > *s_) > "less than required 65536", s_, n_bits, 1u << n_bits); > } > > - memset(ap, 0, sizeof *ap); > - ap->type = htons(OFPAT_VENDOR); > - ap->len = htons(sizeof *ap); > - ap->vendor = htonl(NX_VENDOR_ID); > - ap->subtype = htons(NXAST_AUTOPATH); > + ofputil_init_NXAST_AUTOPATH(ap); > ap->id = htonl(id_int); > ap->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits); > ap->dst = htonl(reg); > diff --git a/lib/bundle.c b/lib/bundle.c > index 86762f9..ac0bade 100644 > --- a/lib/bundle.c > +++ b/lib/bundle.c > @@ -193,6 +193,7 @@ bundle_parse__(struct ofpbuf *b, const char *s, char > **save_ptr, > const char *slave_type, const char *dst, > const char *slave_delim) > { > + enum ofputil_action_code code; > struct nx_action_bundle *nab; > uint16_t n_slaves; > > @@ -205,7 +206,8 @@ bundle_parse__(struct ofpbuf *b, const char *s, char > **save_ptr, > s, slave_delim); > } > > - b->l2 = ofpbuf_put_zeros(b, sizeof *nab); > + code = dst ? OFPUTIL_NXAST_BUNDLE_LOAD : OFPUTIL_NXAST_BUNDLE; > + b->l2 = ofputil_put_action(code, b); > > n_slaves = 0; > for (;;) { > @@ -229,10 +231,7 @@ bundle_parse__(struct ofpbuf *b, const char *s, char > **save_ptr, > } > > nab = b->l2; > - nab->type = htons(OFPAT_VENDOR); > nab->len = htons(b->size - ((char *) b->l2 - (char *) b->data)); > - nab->vendor = htonl(NX_VENDOR_ID); > - nab->subtype = htons(dst ? NXAST_BUNDLE_LOAD: NXAST_BUNDLE); > nab->n_slaves = htons(n_slaves); > nab->basis = htons(atoi(basis)); > > diff --git a/lib/multipath.c b/lib/multipath.c > index e85829a..f68dafd 100644 > --- a/lib/multipath.c > +++ b/lib/multipath.c > @@ -180,11 +180,7 @@ multipath_parse(struct nx_action_multipath *mp, const > char *s_) > ovs_fatal(0, "%s: not enough arguments to multipath action", s_); > } > > - memset(mp, 0, sizeof *mp); > - mp->type = htons(OFPAT_VENDOR); > - mp->len = htons(sizeof *mp); > - mp->vendor = htonl(NX_VENDOR_ID); > - mp->subtype = htons(NXAST_MULTIPATH); > + ofputil_init_NXAST_MULTIPATH(mp); > if (!strcasecmp(fields, "eth_src")) { > mp->fields = htons(NX_HASH_FIELDS_ETH_SRC); > } else if (!strcasecmp(fields, "symmetric_l4")) { > diff --git a/lib/nx-match.c b/lib/nx-match.c > index 2654dde..422ce76 100644 > --- a/lib/nx-match.c > +++ b/lib/nx-match.c > @@ -1093,10 +1093,7 @@ nxm_parse_reg_move(struct nx_action_reg_move *move, > const char *s) > "%d bits wide", full_s, src_n_bits, dst_n_bits); > } > > - move->type = htons(OFPAT_VENDOR); > - move->len = htons(sizeof *move); > - move->vendor = htonl(NX_VENDOR_ID); > - move->subtype = htons(NXAST_REG_MOVE); > + ofputil_init_NXAST_REG_MOVE(move); > move->n_bits = htons(src_n_bits); > move->src_ofs = htons(src_ofs); > move->dst_ofs = htons(dst_ofs); > @@ -1127,10 +1124,7 @@ nxm_parse_reg_load(struct nx_action_reg_load *load, > const char *s) > full_s, value, n_bits); > } > > - load->type = htons(OFPAT_VENDOR); > - load->len = htons(sizeof *load); > - load->vendor = htonl(NX_VENDOR_ID); > - load->subtype = htons(NXAST_REG_LOAD); > + ofputil_init_NXAST_REG_LOAD(load); > load->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits); > load->dst = htonl(dst); > load->value = htonll(value); > diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c > index eae5d58..7e38565 100644 > --- a/lib/ofp-parse.c > +++ b/lib/ofp-parse.c > @@ -253,19 +253,12 @@ str_to_ipv6(const char *str_, struct in6_addr *addrp, > struct in6_addr *maskp) > free(str); > } > > -static void * > -put_action(struct ofpbuf *b, size_t size, uint16_t type) > -{ > - struct ofp_action_header *ah = ofpbuf_put_zeros(b, size); > - ah->type = htons(type); > - ah->len = htons(size); > - return ah; > -} > - > static struct ofp_action_output * > put_output_action(struct ofpbuf *b, uint16_t port) > { > - struct ofp_action_output *oao = put_action(b, sizeof *oao, OFPAT_OUTPUT); > + struct ofp_action_output *oao; > + > + oao = ofputil_put_OFPAT_OUTPUT(b); > oao->port = htons(port); > return oao; > } > @@ -282,19 +275,12 @@ parse_enqueue(struct ofpbuf *b, char *arg) > ovs_fatal(0, "\"enqueue\" syntax is \"enqueue:PORT:QUEUE\""); > } > > - oae = put_action(b, sizeof *oae, OFPAT_ENQUEUE); > + oae = ofputil_put_OFPAT_ENQUEUE(b); > oae->port = htons(str_to_u32(port)); > oae->queue_id = htonl(str_to_u32(queue)); > } > > static void > -put_dl_addr_action(struct ofpbuf *b, uint16_t type, const char *addr) > -{ > - struct ofp_action_dl_addr *oada = put_action(b, sizeof *oada, type); > - str_to_mac(addr, oada->dl_addr); > -} > - > -static void > parse_output(struct ofpbuf *b, char *arg) > { > if (strchr(arg, '[')) { > @@ -304,9 +290,7 @@ parse_output(struct ofpbuf *b, char *arg) > > nxm_parse_field_bits(arg, &src, &ofs, &n_bits); > > - naor = put_action(b, sizeof *naor, OFPAT_VENDOR); > - naor->vendor = htonl(NX_VENDOR_ID); > - naor->subtype = htons(NXAST_OUTPUT_REG); > + naor = ofputil_put_NXAST_OUTPUT_REG(b); > naor->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits); > naor->src = htonl(src); > naor->max_len = htons(UINT16_MAX); > @@ -316,8 +300,9 @@ parse_output(struct ofpbuf *b, char *arg) > } > > static void > -parse_resubmit(struct nx_action_resubmit *nar, char *arg) > +parse_resubmit(struct ofpbuf *b, char *arg) > { > + struct nx_action_resubmit *nar; > char *in_port_s, *table_s; > uint16_t in_port; > uint8_t table; > @@ -339,33 +324,23 @@ parse_resubmit(struct nx_action_resubmit *nar, char > *arg) > " on resubmit"); > } > > - nar->vendor = htonl(NX_VENDOR_ID); > - nar->in_port = htons(in_port); > if (in_port != OFPP_IN_PORT && table == 255) { > - nar->subtype = htons(NXAST_RESUBMIT); > + nar = ofputil_put_NXAST_RESUBMIT(b); > } else { > - nar->subtype = htons(NXAST_RESUBMIT_TABLE); > + nar = ofputil_put_NXAST_RESUBMIT_TABLE(b); > nar->table = table; > } > + nar->in_port = htons(in_port); > } > > static void > -parse_set_tunnel(struct ofpbuf *b, enum ofputil_action_code code, > - const char *arg) > +parse_set_tunnel(struct ofpbuf *b, const char *arg) > { > uint64_t tun_id = str_to_u64(arg); > - if (code == OFPUTIL_NXAST_SET_TUNNEL64 || tun_id > UINT32_MAX) { > - struct nx_action_set_tunnel64 *nast64; > - nast64 = put_action(b, sizeof *nast64, OFPAT_VENDOR); > - nast64->vendor = htonl(NX_VENDOR_ID); > - nast64->subtype = htons(NXAST_SET_TUNNEL64); > - nast64->tun_id = htonll(tun_id); > + if (tun_id > UINT32_MAX) { > + ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(tun_id); > } else { > - struct nx_action_set_tunnel *nast; > - nast = put_action(b, sizeof *nast, OFPAT_VENDOR); > - nast->vendor = htonl(NX_VENDOR_ID); > - nast->subtype = htons(NXAST_SET_TUNNEL); > - nast->tun_id = htonl(tun_id); > + ofputil_put_NXAST_SET_TUNNEL(b)->tun_id = htonl(tun_id); > } > } > > @@ -377,9 +352,7 @@ parse_note(struct ofpbuf *b, const char *arg) > int remainder; > size_t len; > > - nan = put_action(b, sizeof *nan, OFPAT_VENDOR); > - nan->vendor = htonl(NX_VENDOR_ID); > - nan->subtype = htons(NXAST_NOTE); > + nan = ofputil_put_NXAST_NOTE(b); > > b->size -= sizeof nan->note; > while (*arg != '\0') { > @@ -414,18 +387,11 @@ parse_note(struct ofpbuf *b, const char *arg) > static void > parse_named_action(enum ofputil_action_code code, struct ofpbuf *b, char > *arg) > { > + struct ofp_action_dl_addr *oada; > struct ofp_action_vlan_pcp *oavp; > struct ofp_action_vlan_vid *oavv; > struct ofp_action_nw_addr *oana; > - struct ofp_action_nw_tos *oant; > struct ofp_action_tp_port *oata; > - struct nx_action_header *nah; > - struct nx_action_resubmit *nar; > - struct nx_action_set_queue *nasq; > - struct nx_action_reg_move *move; > - struct nx_action_reg_load *load; > - struct nx_action_multipath *nam; > - struct nx_action_autopath *naa; > > switch (code) { > case OFPUTIL_OFPAT_OUTPUT: > @@ -433,49 +399,38 @@ parse_named_action(enum ofputil_action_code code, > struct ofpbuf *b, char *arg) > break; > > case OFPUTIL_OFPAT_SET_VLAN_VID: > - oavv = put_action(b, sizeof *oavv, OFPAT_SET_VLAN_VID); > + oavv = ofputil_put_OFPAT_SET_VLAN_VID(b); > oavv->vlan_vid = htons(str_to_u32(arg)); > break; > > case OFPUTIL_OFPAT_SET_VLAN_PCP: > - oavp = put_action(b, sizeof *oavp, OFPAT_SET_VLAN_PCP); > + oavp = ofputil_put_OFPAT_SET_VLAN_PCP(b); > oavp->vlan_pcp = str_to_u32(arg); > break; > > case OFPUTIL_OFPAT_STRIP_VLAN: > - put_action(b, sizeof(struct ofp_action_header), OFPAT_STRIP_VLAN); > + ofputil_put_OFPAT_STRIP_VLAN(b); > break; > > case OFPUTIL_OFPAT_SET_DL_SRC: > - put_dl_addr_action(b, OFPAT_SET_DL_SRC, arg); > - break; > - > case OFPUTIL_OFPAT_SET_DL_DST: > - put_dl_addr_action(b, OFPAT_SET_DL_DST, arg); > + oada = ofputil_put_action(code, b); > + str_to_mac(arg, oada->dl_addr); > break; > > case OFPUTIL_OFPAT_SET_NW_SRC: > - oana = put_action(b, sizeof *oana, OFPAT_SET_NW_SRC); > - str_to_ip(arg, &oana->nw_addr, NULL); > - break; > - > case OFPUTIL_OFPAT_SET_NW_DST: > - oana = put_action(b, sizeof *oana, OFPAT_SET_NW_DST); > + oana = ofputil_put_action(code, b); > str_to_ip(arg, &oana->nw_addr, NULL); > break; > > case OFPUTIL_OFPAT_SET_NW_TOS: > - oant = put_action(b, sizeof *oant, OFPAT_SET_NW_TOS); > - oant->nw_tos = str_to_u32(arg); > + ofputil_put_OFPAT_SET_NW_TOS(b)->nw_tos = str_to_u32(arg); > break; > > case OFPUTIL_OFPAT_SET_TP_SRC: > - oata = put_action(b, sizeof *oata, OFPAT_SET_TP_SRC); > - oata->tp_port = htons(str_to_u32(arg)); > - break; > - > case OFPUTIL_OFPAT_SET_TP_DST: > - oata = put_action(b, sizeof *oata, OFPAT_SET_TP_DST); > + oata = ofputil_put_action(code, b); > oata->tp_port = htons(str_to_u32(arg)); > break; > > @@ -484,50 +439,43 @@ parse_named_action(enum ofputil_action_code code, > struct ofpbuf *b, char *arg) > break; > > case OFPUTIL_NXAST_RESUBMIT: > - nar = put_action(b, sizeof *nar, OFPAT_VENDOR); > - parse_resubmit(nar, arg); > + parse_resubmit(b, arg); > break; > > case OFPUTIL_NXAST_SET_TUNNEL: > - case OFPUTIL_NXAST_SET_TUNNEL64: > - parse_set_tunnel(b, code, arg); > + parse_set_tunnel(b, arg); > break; > > case OFPUTIL_NXAST_SET_QUEUE: > - nasq = put_action(b, sizeof *nasq, OFPAT_VENDOR); > - nasq->vendor = htonl(NX_VENDOR_ID); > - nasq->subtype = htons(NXAST_SET_QUEUE); > - nasq->queue_id = htonl(str_to_u32(arg)); > + ofputil_put_NXAST_SET_QUEUE(b)->queue_id = htonl(str_to_u32(arg)); > break; > > case OFPUTIL_NXAST_POP_QUEUE: > - nah = put_action(b, sizeof *nah, OFPAT_VENDOR); > - nah->vendor = htonl(NX_VENDOR_ID); > - nah->subtype = htons(NXAST_POP_QUEUE); > + ofputil_put_NXAST_POP_QUEUE(b); > break; > > case OFPUTIL_NXAST_REG_MOVE: > - move = ofpbuf_put_uninit(b, sizeof *move); > - nxm_parse_reg_move(move, arg); > + nxm_parse_reg_move(ofputil_put_NXAST_REG_MOVE(b), arg); > break; > > case OFPUTIL_NXAST_REG_LOAD: > - load = ofpbuf_put_uninit(b, sizeof *load); > - nxm_parse_reg_load(load, arg); > + nxm_parse_reg_load(ofputil_put_NXAST_REG_LOAD(b), arg); > break; > > case OFPUTIL_NXAST_NOTE: > parse_note(b, arg); > break; > > + case OFPUTIL_NXAST_SET_TUNNEL64: > + ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(str_to_u64(arg)); > + break; > + > case OFPUTIL_NXAST_MULTIPATH: > - nam = ofpbuf_put_uninit(b, sizeof *nam); > - multipath_parse(nam, arg); > + multipath_parse(ofputil_put_NXAST_MULTIPATH(b), arg); > break; > > case OFPUTIL_NXAST_AUTOPATH: > - naa = ofpbuf_put_uninit(b, sizeof *naa); > - autopath_parse(naa, arg); > + autopath_parse(ofputil_put_NXAST_AUTOPATH(b), arg); > break; > > case OFPUTIL_NXAST_BUNDLE: > diff --git a/lib/ofp-util.c b/lib/ofp-util.c > index 6bee2da..5cc1d40 100644 > --- a/lib/ofp-util.c > +++ b/lib/ofp-util.c > @@ -1825,10 +1825,7 @@ make_add_simple_flow(const struct cls_rule *rule, > struct ofpbuf *buffer; > > buffer = make_add_flow(rule, buffer_id, idle_timeout, sizeof *oao); > - oao = ofpbuf_put_zeros(buffer, sizeof *oao); > - oao->type = htons(OFPAT_OUTPUT); > - oao->len = htons(sizeof *oao); > - oao->port = htons(out_port); > + ofputil_put_OFPAT_OUTPUT(buffer)->port = htons(out_port); > return buffer; > } else { > return make_add_flow(rule, buffer_id, idle_timeout, 0); > @@ -2308,6 +2305,60 @@ ofputil_action_code_from_name(const char *name) > return -1; > } > > +/* Appends an action of the type specified by 'code' to 'buf' and returns the > + * action. Initializes the parts of 'action' that identify it as having type > + * <ENUM> and length 'sizeof *action' and zeros the rest. For actions that > + * have variable length, the length used and cleared is that of struct > + * <STRUCT>. */ > +void * > +ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf) > +{ > + switch (code) { > +#define OFPAT_ACTION(ENUM, STRUCT, NAME) \ > + case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); > +#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ > + case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); > +#include "ofp-util.def" > + } > + NOT_REACHED(); > +} > + > +#define OFPAT_ACTION(ENUM, STRUCT, NAME) \ > + void \ > + ofputil_init_##ENUM(struct STRUCT *s) \ > + { \ > + memset(s, 0, sizeof *s); \ > + s->type = htons(ENUM); \ > + s->len = htons(sizeof *s); \ > + } \ > + \ > + struct STRUCT * \ > + ofputil_put_##ENUM(struct ofpbuf *buf) \ > + { \ > + struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ > + ofputil_init_##ENUM(s); \ > + return s; \ > + } > +#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ > + void \ > + ofputil_init_##ENUM(struct STRUCT *s) \ > + { \ > + memset(s, 0, sizeof *s); \ > + s->type = htons(OFPAT_VENDOR); \ > + s->len = htons(sizeof *s); \ > + s->vendor = htonl(NX_VENDOR_ID); \ > + s->subtype = htons(ENUM); \ > + } \ > + \ > + struct STRUCT * \ > + ofputil_put_##ENUM(struct ofpbuf *buf) \ > + { \ > + struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ > + ofputil_init_##ENUM(s); \ > + return s; \ > + } > +#include "ofp-util.def" > + > /* Returns true if 'action' outputs to 'port', false otherwise. */ > bool > action_outputs_to_port(const union ofp_action *action, ovs_be16 port) > diff --git a/lib/ofp-util.h b/lib/ofp-util.h > index e70d963..3c9b459 100644 > --- a/lib/ofp-util.h > +++ b/lib/ofp-util.h > @@ -334,6 +334,30 @@ enum ofputil_action_code ofputil_decode_action_unsafe( > > int ofputil_action_code_from_name(const char *); > > +void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf); > + > +/* For each OpenFlow action <ENUM> that has a corresponding action structure > + * struct <STRUCT>, this defines two functions: > + * > + * void ofputil_init_<ENUM>(struct <STRUCT> *action); > + * > + * Initializes the parts of 'action' that identify it as having type > <ENUM> > + * and length 'sizeof *action' and zeros the rest. For actions that have > + * variable length, the length used and cleared is that of struct > <STRUCT>. > + * > + * struct <STRUCT> *ofputil_put_<ENUM>(struct ofpbuf *buf); > + * > + * Appends a new 'action', of length 'sizeof(struct <STRUCT>)', to 'buf', > + * initializes it with ofputil_init_<ENUM>(), and returns it. > +*/ > +#define OFPAT_ACTION(ENUM, STRUCT, NAME) \ > + void ofputil_init_##ENUM(struct STRUCT *); \ > + struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *); > +#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ > + void ofputil_init_##ENUM(struct STRUCT *); \ > + struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *); > +#include "ofp-util.def" > + > #define OFP_ACTION_ALIGN 8 /* Alignment of ofp_actions. */ > > static inline union ofp_action * > -- > 1.7.4.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