From: Jarno Rajahalme Date: Wed, 23 Oct 2013 00:20:44 +0000 (-0700) Subject: Add OF11 SET IP TTL action. X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=0c20dbe410f011354dda72e1534b4070e77603d4 Add OF11 SET IP TTL action. Signed-off-by: Jarno Rajahalme Signed-off-by: Ben Pfaff --- diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 034659196..e7a90b6ed 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); @@ -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; + 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; @@ -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_IP_TTL: 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_IP_TTL: 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_IP_TTL: 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_IP_TTL: 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_IP_TTL: 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_SET_IP_TTL: 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; + 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); @@ -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_IP_TTL: 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; + 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 13ce460e2..f7e35402a 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_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) \ @@ -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 ee56477d1..a4b6d2e01 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -602,7 +602,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) { @@ -712,6 +712,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 eb75c2d0e..752fd06a3 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 fd5f0cfc8..7be691c7f 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2384,6 +2384,13 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, } 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); diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 4550a8df6..f4ca4d59b 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 1adff4eb3..75ea43b2c 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -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. +. +.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 @@ -1400,6 +1407,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