}
static enum ofperr
-dec_ttl_from_openflow(struct ofpbuf *out)
+dec_ttl_from_openflow(struct ofpbuf *out, enum ofputil_action_code compat)
{
uint16_t id = 0;
struct ofpact_cnt_ids *ids;
enum ofperr error = 0;
ids = ofpact_put_DEC_TTL(out);
- ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL;
+ ids->ofpact.compat = compat;
ids->n_controllers = 1;
ofpbuf_put(out, &id, sizeof id);
ids = out->l2;
break;
case OFPUTIL_NXAST_DEC_TTL:
- error = dec_ttl_from_openflow(out);
+ error = dec_ttl_from_openflow(out, code);
break;
case OFPUTIL_NXAST_DEC_TTL_CNT_IDS:
((const struct ofp_action_dl_addr *) a)->dl_addr, ETH_ADDR_LEN);
break;
+ case OFPUTIL_OFPAT11_DEC_NW_TTL:
+ dec_ttl_from_openflow(out, code);
+ break;
+
case OFPUTIL_OFPAT11_SET_NW_SRC:
ofpact_put_SET_IPV4_SRC(out)->ipv4 = a->nw_addr.nw_addr;
break;
= htons(ofpact_get_SET_L4_DST_PORT(a)->port);
break;
+ case OFPACT_DEC_TTL:
+ if (a->compat == OFPUTIL_OFPAT11_DEC_NW_TTL) {
+ ofputil_put_OFPAT11_DEC_NW_TTL(out);
+ } else {
+ ofpact_to_nxast(a, out);
+ }
+ break;
+
case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
case OFPACT_BUNDLE:
case OFPACT_REG_MOVE:
case OFPACT_REG_LOAD:
- case OFPACT_DEC_TTL:
case OFPACT_SET_TUNNEL:
case OFPACT_SET_QUEUE:
case OFPACT_POP_QUEUE:
/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS.
*
- * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT,
+ * Used for OFPAT10_STRIP_VLAN, NXAST_POP_QUEUE, NXAST_EXIT,
* OFPIT11_CLEAR_ACTIONS.
*
* Action structure for actions that do not have any extra data beyond the
/* OFPACT_DEC_TTL.
*
- * Used for NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */
+ * Used for OFPAT11_DEC_NW_TTL, NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */
struct ofpact_cnt_ids {
struct ofpact ofpact;
}
static void
-parse_dec_ttl(struct ofpbuf *b, char *arg)
+parse_noargs_dec_ttl(struct ofpbuf *b, enum ofputil_action_code compat)
{
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++;
+ ofpact_update_len(b, &ids->ofpact);
+}
+static void
+parse_dec_ttl(struct ofpbuf *b, char *arg, enum ofputil_action_code compat)
+{
if (*arg == '\0') {
- uint16_t id = 0;
-
- ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL;
- ofpbuf_put(b, &id, sizeof id);
- ids = b->l2;
- ids->n_controllers++;
+ parse_noargs_dec_ttl(b, compat);
} else {
+ struct ofpact_cnt_ids *ids;
char *cntr;
+ ids = ofpact_put_DEC_TTL(b);
ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL_CNT_IDS;
for (cntr = strtok_r(arg, ", ", &arg); cntr != NULL;
cntr = strtok_r(NULL, ", ", &arg)) {
ovs_fatal(0, "dec_ttl_cnt_ids: expected at least one controller "
"id.");
}
-
+ ofpact_update_len(b, &ids->ofpact);
}
- ofpact_update_len(b, &ids->ofpact);
}
static void
ofpact_put_SET_IPV4_DSCP(ofpacts)->dscp = tos;
break;
+ case OFPUTIL_OFPAT11_DEC_NW_TTL:
+ parse_noargs_dec_ttl(ofpacts, code);
+ break;
+
case OFPUTIL_OFPAT10_SET_TP_SRC:
case OFPUTIL_OFPAT11_SET_TP_SRC:
ofpact_put_SET_L4_SRC_PORT(ofpacts)->port = str_to_u32(arg);
break;
case OFPUTIL_NXAST_DEC_TTL:
- parse_dec_ttl(ofpacts, arg);
+ parse_dec_ttl(ofpacts, arg, code);
break;
case OFPUTIL_NXAST_FIN_TIMEOUT:
//OFPAT11_ACTION(OFPAT11_POP_VLAN, ofp_action_header, 0, "pop_vlan")
//OFPAT11_ACTION(OFPAT11_SET_QUEUE, ofp11_action_set_queue, 0, "set_queue")
//OFPAT11_ACTION(OFPAT11_SET_NW_TTL, ofp11_action_nw_ttl, 0, "set_nw_ttl")
-//OFPAT11_ACTION(OFPAT11_DEC_NW_TTL, ofp_action_header, 0, "dec_ttl")
+OFPAT11_ACTION(OFPAT11_DEC_NW_TTL, ofp_action_header, 0, NULL)
OFPAT11_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, 1, "set_field")
#ifndef NXAST_ACTION
# actions=exit
ffff 0010 00002320 0011 000000000000
+dnl NXAST_DEC_TTL
# actions=dec_ttl
ffff 0010 00002320 0012 000000000000
+dnl OpenFlow 1.1 OFPAT_DEC_TTL
+# actions=dec_ttl
+0018 0008 00000000
+
# actions=fin_timeout(idle_timeout=10,hard_timeout=20)
ffff 0010 00002320 0013 000a 0014 0000