Add OF11 SET IP TTL action.
authorJarno Rajahalme <jrajahalme@nicira.com>
Wed, 23 Oct 2013 00:20:44 +0000 (17:20 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 23 Oct 2013 17:24:31 +0000 (10:24 -0700)
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ofp-actions.c
lib/ofp-actions.h
lib/ofp-parse.c
lib/ofp-util.def
ofproto/ofproto-dpif-xlate.c
tests/ovs-ofctl.at
utilities/ovs-ofctl.8.in

index 0346591..e7a90b6 100644 (file)
@@ -45,6 +45,7 @@ union ofp_action {
     struct ofp_action_nw_addr nw_addr;
     struct ofp_action_nw_tos nw_tos;
     struct ofp11_action_nw_ecn nw_ecn;
     struct ofp_action_nw_addr nw_addr;
     struct ofp_action_nw_tos nw_tos;
     struct ofp11_action_nw_ecn nw_ecn;
+    struct ofp11_action_nw_ttl nw_ttl;
     struct ofp_action_tp_port tp_port;
 };
 OFP_ASSERT(sizeof(union ofp_action) == 8);
     struct ofp_action_tp_port tp_port;
 };
 OFP_ASSERT(sizeof(union ofp_action) == 8);
@@ -855,6 +856,10 @@ ofpact_from_openflow11(const union ofp_action *a, struct ofpbuf *out)
         ofpact_put_SET_IP_ECN(out)->ecn = a->nw_ecn.nw_ecn;
         break;
 
         ofpact_put_SET_IP_ECN(out)->ecn = a->nw_ecn.nw_ecn;
         break;
 
+    case OFPUTIL_OFPAT11_SET_NW_TTL:
+        ofpact_put_SET_IP_TTL(out)->ttl = a->nw_ttl.nw_ttl;
+        break;
+
     case OFPUTIL_OFPAT11_SET_TP_SRC:
         ofpact_put_SET_L4_SRC_PORT(out)->port = ntohs(a->tp_port.tp_port);
         break;
     case OFPUTIL_OFPAT11_SET_TP_SRC:
         ofpact_put_SET_L4_SRC_PORT(out)->port = ntohs(a->tp_port.tp_port);
         break;
@@ -926,6 +931,7 @@ ofpact_is_set_action(const struct ofpact *a)
     case OFPACT_SET_ETH_SRC:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_ETH_SRC:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_L4_DST_PORT:
@@ -988,6 +994,7 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_SET_ETH_SRC:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_ETH_SRC:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_L4_DST_PORT:
@@ -1259,6 +1266,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_REG_MOVE:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_REG_MOVE:
@@ -1579,6 +1587,7 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports,
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
         return 0;
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
         return 0;
@@ -1966,6 +1975,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_WRITE_ACTIONS:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_WRITE_ACTIONS:
@@ -2081,6 +2091,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
     case OFPACT_STACK_POP:
     case OFPACT_DEC_TTL:
     case OFPACT_SET_IP_ECN:
     case OFPACT_STACK_POP:
     case OFPACT_DEC_TTL:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_MPLS_TTL:
     case OFPACT_DEC_MPLS_TTL:
     case OFPACT_SET_TUNNEL:
     case OFPACT_SET_MPLS_TTL:
     case OFPACT_DEC_MPLS_TTL:
     case OFPACT_SET_TUNNEL:
@@ -2207,6 +2218,11 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
             = ofpact_get_SET_IP_ECN(a)->ecn;
         break;
 
             = ofpact_get_SET_IP_ECN(a)->ecn;
         break;
 
+    case OFPACT_SET_IP_TTL:
+        ofputil_put_OFPAT11_SET_NW_TTL(out)->nw_ttl
+            = ofpact_get_SET_IP_TTL(a)->ttl;
+        break;
+
     case OFPACT_SET_L4_SRC_PORT:
         ofputil_put_OFPAT11_SET_TP_SRC(out)->tp_port
             = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
     case OFPACT_SET_L4_SRC_PORT:
         ofputil_put_OFPAT11_SET_TP_SRC(out)->tp_port
             = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
@@ -2412,6 +2428,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IP_DSCP:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_REG_MOVE:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_REG_MOVE:
@@ -2677,6 +2694,10 @@ ofpact_format(const struct ofpact *a, struct ds *s)
         ds_put_format(s, "mod_nw_ecn:%d", ofpact_get_SET_IP_ECN(a)->ecn);
         break;
 
         ds_put_format(s, "mod_nw_ecn:%d", ofpact_get_SET_IP_ECN(a)->ecn);
         break;
 
+    case OFPACT_SET_IP_TTL:
+        ds_put_format(s, "mod_nw_ttl:%d", ofpact_get_SET_IP_TTL(a)->ttl);
+        break;
+
     case OFPACT_SET_L4_SRC_PORT:
         ds_put_format(s, "mod_tp_src:%d", ofpact_get_SET_L4_SRC_PORT(a)->port);
         break;
     case OFPACT_SET_L4_SRC_PORT:
         ds_put_format(s, "mod_tp_src:%d", ofpact_get_SET_L4_SRC_PORT(a)->port);
         break;
index 13ce460..f7e3540 100644 (file)
@@ -69,6 +69,7 @@
     DEFINE_OFPACT(SET_IPV4_DST,    ofpact_ipv4,          ofpact)    \
     DEFINE_OFPACT(SET_IP_DSCP,     ofpact_dscp,          ofpact)    \
     DEFINE_OFPACT(SET_IP_ECN,      ofpact_ecn,           ofpact)    \
     DEFINE_OFPACT(SET_IPV4_DST,    ofpact_ipv4,          ofpact)    \
     DEFINE_OFPACT(SET_IP_DSCP,     ofpact_dscp,          ofpact)    \
     DEFINE_OFPACT(SET_IP_ECN,      ofpact_ecn,           ofpact)    \
+    DEFINE_OFPACT(SET_IP_TTL,      ofpact_ip_ttl,        ofpact)    \
     DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(REG_MOVE,        ofpact_reg_move,      ofpact)    \
     DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(REG_MOVE,        ofpact_reg_move,      ofpact)    \
@@ -302,6 +303,14 @@ struct ofpact_ecn {
     uint8_t ecn;               /* ECN in low 2 bits, rest ignored. */
 };
 
     uint8_t ecn;               /* ECN in low 2 bits, rest ignored. */
 };
 
+/* OFPACT_SET_IP_TTL.
+ *
+ * Used for OFPAT11_SET_NW_TTL. */
+struct ofpact_ip_ttl {
+    struct ofpact ofpact;
+    uint8_t ttl;
+};
+
 /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT.
  *
  * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */
 /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT.
  *
  * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */
index ee56477..a4b6d2e 100644 (file)
@@ -602,7 +602,7 @@ parse_named_action(enum ofputil_action_code code,
     char *error = NULL;
     uint16_t ethertype = 0;
     uint16_t vid = 0;
     char *error = NULL;
     uint16_t ethertype = 0;
     uint16_t vid = 0;
-    uint8_t tos = 0, ecn;
+    uint8_t tos = 0, ecn, ttl;
     uint8_t pcp = 0;
 
     switch (code) {
     uint8_t pcp = 0;
 
     switch (code) {
@@ -712,6 +712,15 @@ parse_named_action(enum ofputil_action_code code,
         ofpact_put_SET_IP_ECN(ofpacts)->ecn = ecn;
         break;
 
         ofpact_put_SET_IP_ECN(ofpacts)->ecn = ecn;
         break;
 
+    case OFPUTIL_OFPAT11_SET_NW_TTL:
+        error = str_to_u8(arg, "TTL", &ttl);
+        if (error) {
+            return error;
+        }
+
+        ofpact_put_SET_IP_TTL(ofpacts)->ttl = ttl;
+        break;
+
     case OFPUTIL_OFPAT11_DEC_NW_TTL:
         NOT_REACHED();
 
     case OFPUTIL_OFPAT11_DEC_NW_TTL:
         NOT_REACHED();
 
index eb75c2d..752fd06 100644 (file)
@@ -37,7 +37,7 @@ OFPAT11_ACTION(OFPAT11_POP_VLAN,     ofp_action_header,   0, "pop_vlan")
 OFPAT11_ACTION(OFPAT11_PUSH_MPLS,    ofp11_action_push,   0, "push_mpls")
 OFPAT11_ACTION(OFPAT11_POP_MPLS,     ofp11_action_pop_mpls, 0, "pop_mpls")
 OFPAT11_ACTION(OFPAT11_SET_QUEUE,    ofp11_action_set_queue, 0, "set_queue")
 OFPAT11_ACTION(OFPAT11_PUSH_MPLS,    ofp11_action_push,   0, "push_mpls")
 OFPAT11_ACTION(OFPAT11_POP_MPLS,     ofp11_action_pop_mpls, 0, "pop_mpls")
 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_SET_NW_TTL,   ofp11_action_nw_ttl, 0, "mod_nw_ttl")
 OFPAT11_ACTION(OFPAT11_DEC_NW_TTL,   ofp_action_header,   0, NULL)
 OFPAT11_ACTION(OFPAT12_SET_FIELD,    ofp12_action_set_field, 1, "set_field")
 OFPAT11_ACTION(OFPAT11_GROUP,        ofp11_action_group,   0, "group")
 OFPAT11_ACTION(OFPAT11_DEC_NW_TTL,   ofp_action_header,   0, NULL)
 OFPAT11_ACTION(OFPAT12_SET_FIELD,    ofp12_action_set_field, 1, "set_field")
 OFPAT11_ACTION(OFPAT11_GROUP,        ofp11_action_group,   0, "group")
index fd5f0cf..7be691c 100644 (file)
@@ -2384,6 +2384,13 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             }
             break;
 
             }
             break;
 
+        case OFPACT_SET_IP_TTL:
+            if (is_ip_any(flow)) {
+                wc->masks.nw_ttl = 0xff;
+                flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl;
+            }
+            break;
+
         case OFPACT_SET_L4_SRC_PORT:
             if (is_ip_any(flow)) {
                 memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
         case OFPACT_SET_L4_SRC_PORT:
             if (is_ip_any(flow)) {
                 memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
index 4550a8d..f4ca4d5 100644 (file)
@@ -149,7 +149,7 @@ tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
 udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1
 cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
 actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
 udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1
 cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
 actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
-ip,actions=set_field:10.4.3.77->ip_src
+ip,actions=mod_nw_ttl:1,set_field:10.4.3.77->ip_src
 sctp actions=drop
 sctp actions=drop
 in_port=0 actions=resubmit:0
 sctp actions=drop
 sctp actions=drop
 in_port=0 actions=resubmit:0
@@ -168,7 +168,7 @@ OFPT_FLOW_MOD (OF1.1): ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=se
 OFPT_FLOW_MOD (OF1.1): ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1
 OFPT_FLOW_MOD (OF1.1): ADD table:255 priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
 OFPT_FLOW_MOD (OF1.1): ADD table:255 actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00
 OFPT_FLOW_MOD (OF1.1): ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1
 OFPT_FLOW_MOD (OF1.1): ADD table:255 priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
 OFPT_FLOW_MOD (OF1.1): ADD table:255 actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00
-OFPT_FLOW_MOD (OF1.1): ADD table:255 ip actions=load:0xa04034d->NXM_OF_IP_SRC[]
+OFPT_FLOW_MOD (OF1.1): ADD table:255 ip actions=mod_nw_ttl:1,load:0xa04034d->NXM_OF_IP_SRC[]
 OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop
 OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop
 OFPT_FLOW_MOD (OF1.1): ADD table:255 in_port=0 actions=resubmit:0
 OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop
 OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop
 OFPT_FLOW_MOD (OF1.1): ADD table:255 in_port=0 actions=resubmit:0
index 1adff4e..75ea43b 100644 (file)
@@ -1109,6 +1109,13 @@ which must be a value between 0 and 3, inclusive.  This action does not modify
 the six most significant bits of the field (the DSCP bits).
 .IP
 Requires OpenFlow 1.1 or later.
 the six most significant bits of the field (the DSCP bits).
 .IP
 Requires OpenFlow 1.1 or later.
+.
+.IP \fBmod_nw_ttl\fB:\fIttl\fR
+Sets the IPv4 TTL or IPv6 hop limit field to \fIttl\fR, which is specified as
+a decimal number between 0 and 255, inclusive.  Switch behavior when setting
+\fIttl\fR to zero is not well specified, though.
+.IP
+Requires OpenFlow 1.1 or later.
 .RE
 .IP
 The following actions are Nicira vendor extensions that, as of this writing, are
 .RE
 .IP
 The following actions are Nicira vendor extensions that, as of this writing, are
@@ -1400,6 +1407,8 @@ the action set, the one written later replaces the earlier action:
 .IQ
 \fBmod_nw_ecn\fR
 .IQ
 .IQ
 \fBmod_nw_ecn\fR
 .IQ
+\fBmod_nw_ttl\fR
+.IQ
 \fBmod_tp_dst\fR
 .IQ
 \fBmod_tp_src\fR
 \fBmod_tp_dst\fR
 .IQ
 \fBmod_tp_src\fR