[ovs-dev] [PATCH 4/9] Add OF11 SET IP TTL action.

Jarno Rajahalme jrajahalme at nicira.com
Wed Oct 16 23:16:06 UTC 2013


Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/ofp-actions.c            |   21 +++++++++++++++++++++
 lib/ofp-actions.h            |    9 +++++++++
 lib/ofp-parse.c              |   11 ++++++++++-
 lib/ofp-util.def             |    2 +-
 ofproto/ofproto-dpif-xlate.c |   10 ++++++++++
 tests/ovs-ofctl.at           |    4 ++--
 utilities/ovs-ofctl.8.in     |    9 +++++++++
 7 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index ff691ee..e702bab 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -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 ofp11_action_nw_ttl nw_ttl;
     struct ofp_action_tp_port tp_port;
 };
 OFP_ASSERT(sizeof(union ofp_action) == 8);
@@ -841,6 +842,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;
 
+    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;
@@ -916,6 +921,7 @@ ofpact_is_set_action(const struct ofpact *a)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_MPLS_TTL:
@@ -978,6 +984,7 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_SRC:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_MPLS_TTL:
@@ -1218,6 +1225,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_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:
@@ -1511,6 +1519,7 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports,
     case OFPACT_SET_L4_SRC_PORT:
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_SET_IP_ECN:
+    case OFPACT_SET_IP_TTL:
         return 0;
 
     case OFPACT_REG_MOVE:
@@ -1896,6 +1905,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_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:
@@ -2011,6 +2021,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_SET_IP_TTL:
     case OFPACT_SET_MPLS_TTL:
     case OFPACT_DEC_MPLS_TTL:
     case OFPACT_SET_TUNNEL:
@@ -2137,6 +2148,11 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
             = 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);
@@ -2342,6 +2358,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
     case OFPACT_SET_IPV4_DST:
     case OFPACT_SET_IPV4_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:
@@ -2607,6 +2624,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;
 
+    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;
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index c1172ca..29d9200 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -69,6 +69,7 @@
     DEFINE_OFPACT(SET_IPV4_DST,    ofpact_ipv4,          ofpact)    \
     DEFINE_OFPACT(SET_IPV4_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)    \
@@ -302,6 +303,14 @@ struct ofpact_ecn {
     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. */
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 50a68c4..74538fd 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -601,7 +601,7 @@ parse_named_action(enum ofputil_action_code code,
     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) {
@@ -711,6 +711,15 @@ parse_named_action(enum ofputil_action_code code,
         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();
 
diff --git a/lib/ofp-util.def b/lib/ofp-util.def
index eb75c2d..752fd06 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -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_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")
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index f0c8fde..37472ef 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2465,6 +2465,16 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             }
             break;
 
+        case OFPACT_SET_IP_TTL:
+            if (is_ip_any(flow)) {
+                /* Must set mask, as it is possible that action will not be
+                 * committed due to no change, which means that the committed
+                 * actions depend on the current value of the field. */
+                wc->masks.nw_ttl = 0xff;
+                flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl;
+            }
+            break;
+
         case OFPACT_NOTE:
             /* Nothing to do. */
             break;
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 4550a8d..f4ca4d5 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -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
-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
@@ -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 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
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 4bad990..3a4a4b5 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1106,6 +1106,13 @@ value between 0 and 3, inclusive.  This action does not modify the six most
 significant bits of the ToS field (the DSCP bits).
 .IP
 Requires OpenFlow 1.1 or later.
+.
+.IP \fBmod_nw_ttl\fB:\fIttl\fR
+Sets the IPv4 TTL 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
@@ -1397,6 +1404,8 @@ the action set, the one written later replaces the earlier action:
 .IQ
 \fBmod_nw_ecn\fR
 .IQ
+\fBmod_nw_ttl\fR
+.IQ
 \fBmod_tp_dst\fR
 .IQ
 \fBmod_tp_src\fR
-- 
1.7.10.4




More information about the dev mailing list