First, some high-level comments. We definitely need a new action at the OpenFlow protocol level, and NXAST_DEC_TTL_CNT_IDS is fine. But at higher levels I do not think that we need to make a sharp distinction. In particular:
- I think that instead of "dec_ttl_cnt_ids=1:2", we could have the user write "dec_ttl(ids=1,2)", since I don't know of a reason to point out that something is different at the OpenFlow level. (We would keep plain "dec_ttl" meaning what it does now.) - I think that instead of adding an ofpact_dec_ttl_cnt_ids, we should modify the existing ofpact_dec_ttl. After all, the existing dec_ttl is equivalent to dec_ttl_cnt_ids=0. (You can use the "compat" member of struct ofpact to distinguish NXAST_DEC_TTL from NXAST_DEC_TTL_CNT_IDS for converting back to OpenFlow actions.) Also, I don't see any tests for the encoding and decoding. You should add some, at least to the "ovs-ofctl parse-flows" test in ovs-ofctl.at. > Subject: Adding Nicira vendor extension action > NXAST_DEC_TTL_CNT_IDS. Could you just make that "Add" rather than "Adding"? That's the usual way for wording commit logs. On Mon, Aug 13, 2012 at 09:51:01PM -0700, Mehak Mahajan wrote: > Currently, if a controller having a non zero id registers to get a s/non zero/nonzero/? > OFPR_INVALID_TTL async message, it will not receive it. This is because > compose_dec_ttl() only sent the invalid ttl packets to the default controller > id. NXAST_DEC_TTL_CNT_IDS is a new action that accepts a list of controller > ids, each separated by `:', to which the OFPR_INVALID_TTL packets must be > sent. > The earlier requirement of the controller having to explicitly register to > receive these asynchronous messages is retained. > The syntax of this action is: > dec_ttl_cnt_ids=id1:id2 > where id1, id2 are valid controller ids. The use of : looks odd to me. How about: dec_ttl(id1,id2) instead. > Signed-off-by: Mehak Mahajan <mmaha...@nicira.com> ... > +struct nx_action_controller_ids { > + ovs_be16 type; /* OFPAT_VENDOR. */ > + ovs_be16 len; /* Length including slaves. */ > + ovs_be32 vendor; /* NX_VENDOR_ID. */ > + ovs_be16 subtype; /* NXAST_DEC_TTL_CNT_IDS. */ > + > + ovs_be16 n_controllers; /* Number of controllers. */ > + uint8_t zeros[4]; /* Must be zero. */ > + /* Followed by 1 or more controller ids. > + * > + * uint16_t *controller_ids; "uint16_t *" is misleading here since there's no pointer. I'd write "uint16_t controller_ids[]" if you want to describe it precisely, or even "uint16_t controller_ids[n_controllers]". I suggest specifying that the padding following the controller ids must also be zero. > static enum ofperr > +dec_ttl_cnt_ids_from_openflow(const struct nx_action_controller_ids *nac_ids, > + struct ofpbuf *out) > +{ > + struct ofpact_controller_ids *ids; > + size_t ids_size; > + enum ofperr error = 0; > + int i; > + > + ids = ofpact_put_DEC_TTL_CNT_IDS(out); > + ids->n_controllers = ntohs(nac_ids->n_controllers); > + ids_size = ntohl(nac_ids->len) - sizeof *nac_ids; > + > + if (!is_all_zeros(nac_ids->zeros, sizeof nac_ids->zeros)) { > + VLOG_WARN_RL(&rl, "reserved field is nonzero"); > + error = OFPERR_OFPBAC_BAD_ARGUMENT; > + VLOG_ERR("Came in here.\n"); Please use OFPERR_NXBRC_MUST_BE_ZERO for this error. Why not just return the error at this point? Also I'd think that both log messages are unnecessary; the caller should log the OFPERR_NXBRC_MUST_BE_ZERO error, to make the problem clear. > + } > + if (ids_size < ids->n_controllers * sizeof(ovs_be16)) { > + VLOG_WARN_RL(&rl, "Nicira action dec_ttl_cnt_ids only has %zu bytes " > + "allocated for controller ids. %zu bytes are required > for " > + "%"PRIu16" controllers.", ids_size, > + ids->n_controllers * sizeof(ovs_be16), > ids->n_controllers); > + error = OFPERR_OFPBAC_BAD_LEN; I'd return the error at this point, otherwise the loop below will read beyond the end of 'nac_ids'. > + } ... > static void > +ofpact_dec_ttl_cnt_ids_to_nxast(const struct ofpact_controller_ids *oc_ids, > + struct ofpbuf *out) > +{ > + struct nx_action_controller_ids *nac_ids; > + int ids_len = ROUND_UP(oc_ids->n_controllers, OFP_ACTION_ALIGN); I think this needs "2 *" since each port number is two bytes. > + ovs_be16 *ids; > + size_t i; > + > + nac_ids = ofputil_put_NXAST_DEC_TTL_CNT_IDS(out); > + nac_ids->len = htons(ntohs(nac_ids->len) + ids_len); > + nac_ids->n_controllers = htons(oc_ids->n_controllers); > + > + ids = ofpbuf_put_zeros(out, ids_len); > + for (i = 0; i < oc_ids->n_controllers; i++) { > + ids[i] = htons(oc_ids->controller_ids[i]); > + } > +} ... print_dec_ttl_cnt_ids() doesn't use the syntax that you documented in the commit message. In ofp-actions.h, since there isn't enough room for ofpact_controller_ids in any case, I don't think I'd reindent all the other lines; it doesn't look any better, especially since the line of \s doesn't line up anyway. (You could rename the 'controller_ids' member of struct ofpact_controller_ids to 'ids', which is easier to read anyway.) > static void > +parse_dec_ttl_cnt_ids(struct ofpbuf *b, char *arg) > +{ > + struct ofpact_controller_ids *ids; > + > + if (*arg == '\0') { > + ovs_fatal(0, "dec_ttl_cnt_ids: expected atleast one controler id."); s/atleast/at least/ s/controler/controller/ But I'd put the check for the number of controllers after the loop instead of here. After all, what if someone just supplies, say, ":" as the argument? Then there'd be no controller id but the argument would not be empty. > + } > + > + ids = ofpact_put_DEC_TTL_CNT_IDS(b); > + while(*arg != '\0') { Add a space following "while", please. > + char *cntr; > + uint16_t id; > + > + cntr = strtok_r(NULL, ": ", &arg); I don't think that this works portably. The first call to strtok_r() is supposed to use the string to parse as the first argument, and NULL only after that. > + id = atoi(cntr); > + ofpbuf_put(b, &id, sizeof id); > + > + ids = b->l2; > + ids->n_controllers++; > + } > + ofpact_update_len(b, &ids->ofpact); > +} _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev