[ovs-dev] [PATCH v3 09/11] lib/ofp-actions: Deprecated actions as set fields.
Jarno Rajahalme
jrajahalme at nicira.com
Wed Oct 23 19:53:04 UTC 2013
Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
lib/ofp-actions.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/ofp-actions.h | 3 +-
tests/ovs-ofctl.at | 12 ++++-
3 files changed, 151 insertions(+), 3 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index c9027f2..1ec6888 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1874,12 +1874,27 @@ ofpact_check__(struct ofpact *a, struct flow *flow, ofp_port_t max_ports,
return 0;
case OFPACT_SET_L4_SRC_PORT:
+ if (!is_ip_any(flow) ||
+ (flow->nw_proto != IPPROTO_TCP && flow->nw_proto != IPPROTO_UDP
+ && flow->nw_proto != IPPROTO_SCTP)) {
+ goto inconsistent;
+ }
+ /* Note on which transport protocol the port numbers are set.
+ * This allows this set action to be converted to an OF1.2 set field
+ * action. */
+ ofpact_get_SET_L4_SRC_PORT(a)->flow_ip_proto = flow->nw_proto;
+ return 0;
+
case OFPACT_SET_L4_DST_PORT:
if (!is_ip_any(flow) ||
(flow->nw_proto != IPPROTO_TCP && flow->nw_proto != IPPROTO_UDP
&& flow->nw_proto != IPPROTO_SCTP)) {
goto inconsistent;
}
+ /* Note on which transport protocol the port numbers are set.
+ * This allows this set action to be converted to an OF1.2 set field
+ * action. */
+ ofpact_get_SET_L4_DST_PORT(a)->flow_ip_proto = flow->nw_proto;
return 0;
case OFPACT_REG_MOVE:
@@ -2637,9 +2652,133 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
}
}
+/* Output deprecated set actions as set_field actions. */
static void
ofpact_to_openflow12(const struct ofpact *a, struct ofpbuf *out)
{
+ enum mf_field_id field;
+ union mf_value value;
+ struct ofpact_l4_port *l4port;
+ uint8_t proto;
+
+ /*
+ * Convert actions deprecated in OpenFlow 1.2 to Set Field actions,
+ * if possible.
+ */
+ switch ((int)a->type) {
+ case OFPACT_SET_VLAN_VID:
+ case OFPACT_SET_VLAN_PCP:
+ case OFPACT_SET_ETH_SRC:
+ case OFPACT_SET_ETH_DST:
+ case OFPACT_SET_IPV4_SRC:
+ case OFPACT_SET_IPV4_DST:
+ case OFPACT_SET_IP_DSCP:
+ case OFPACT_SET_IP_ECN:
+ case OFPACT_SET_L4_SRC_PORT:
+ case OFPACT_SET_L4_DST_PORT:
+ case OFPACT_SET_TUNNEL: /* Convert to a set_field, too. */
+
+ switch ((int)a->type) {
+
+ case OFPACT_SET_VLAN_VID:
+ if (!ofpact_get_SET_VLAN_VID(a)->flow_has_vlan &&
+ ofpact_get_SET_VLAN_VID(a)->push_vlan_if_needed) {
+ ofputil_put_OFPAT11_PUSH_VLAN(out)->ethertype
+ = htons(ETH_TYPE_VLAN_8021Q);
+ }
+ field = MFF_VLAN_VID;
+ value.be16 = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid);
+ break;
+
+ case OFPACT_SET_VLAN_PCP:
+ if (!ofpact_get_SET_VLAN_PCP(a)->flow_has_vlan &&
+ ofpact_get_SET_VLAN_PCP(a)->push_vlan_if_needed) {
+ ofputil_put_OFPAT11_PUSH_VLAN(out)->ethertype
+ = htons(ETH_TYPE_VLAN_8021Q);
+ }
+ field = MFF_VLAN_PCP;
+ value.u8 = ofpact_get_SET_VLAN_PCP(a)->vlan_pcp;
+ break;
+
+ case OFPACT_SET_ETH_SRC:
+ field = MFF_ETH_SRC;
+ memcpy(value.mac, ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN);
+ break;
+
+ case OFPACT_SET_ETH_DST:
+ field = MFF_ETH_DST;
+ memcpy(value.mac, ofpact_get_SET_ETH_DST(a)->mac, ETH_ADDR_LEN);
+ break;
+
+ case OFPACT_SET_IPV4_SRC:
+ field = MFF_IPV4_SRC;
+ value.be32 = ofpact_get_SET_IPV4_SRC(a)->ipv4;
+ break;
+
+ case OFPACT_SET_IPV4_DST:
+ field = MFF_IPV4_DST;
+ value.be32 = ofpact_get_SET_IPV4_DST(a)->ipv4;
+ break;
+
+ case OFPACT_SET_IP_DSCP:
+ field = MFF_IP_DSCP_SHIFTED; /* OXM_OF_IP_DSCP */
+ value.u8 = ofpact_get_SET_IP_DSCP(a)->dscp >> 2;
+ break;
+
+ case OFPACT_SET_IP_ECN:
+ field = MFF_IP_ECN;
+ value.u8 = ofpact_get_SET_IP_ECN(a)->ecn;
+ break;
+
+ case OFPACT_SET_L4_SRC_PORT:
+ /* We keep track of IP protocol while translating actions to be
+ * able to translate to the proper OXM type.
+ * If the IP protocol type is unknown, the translation cannot
+ * be performed and we will send the action using the original
+ * action type. */
+ l4port = ofpact_get_SET_L4_SRC_PORT(a);
+ proto = l4port->flow_ip_proto;
+ field = proto == IPPROTO_TCP ? MFF_TCP_SRC
+ : proto == IPPROTO_UDP ? MFF_UDP_SRC
+ : proto == IPPROTO_SCTP ? MFF_SCTP_SRC
+ : MFF_N_IDS; /* Unknown, IP proto, do not translate. */
+ value.be16 = htons(l4port->port);
+ break;
+
+ case OFPACT_SET_L4_DST_PORT:
+ l4port = ofpact_get_SET_L4_DST_PORT(a);
+ proto = l4port->flow_ip_proto;
+ field = proto == IPPROTO_TCP ? MFF_TCP_DST
+ : proto == IPPROTO_UDP ? MFF_UDP_DST
+ : proto == IPPROTO_SCTP ? MFF_SCTP_DST
+ : MFF_N_IDS; /* Unknown, IP proto, do not translate. */
+ value.be16 = htons(l4port->port);
+ break;
+
+ case OFPACT_SET_TUNNEL:
+ field = MFF_TUN_ID;
+ value.be64 = htonll(ofpact_get_SET_TUNNEL(a)->tun_id);
+ break;
+
+ default:
+ field = MFF_N_IDS;
+ }
+
+ /* Put the action out as a set field action, if possible. */
+ if (field < MFF_N_IDS) {
+ uint64_t ofpacts_stub[128 / 8];
+ struct ofpbuf sf_act;
+ struct ofpact_set_field *sf;
+
+ ofpbuf_use_stub(&sf_act, ofpacts_stub, sizeof ofpacts_stub);
+ sf = ofpact_put_SET_FIELD(&sf_act);
+ sf->field = field;
+ memcpy(&sf->value, &value, mf_from_id(field)->n_bytes);
+ set_field_to_ofast(sf, out);
+ return;
+ }
+ }
+
ofpact_to_openflow11(a, out);
}
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index d25d772..41579ce 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -331,7 +331,8 @@ struct ofpact_ip_ttl {
* Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */
struct ofpact_l4_port {
struct ofpact ofpact;
- uint16_t port; /* TCP or UDP port number. */
+ uint16_t port; /* TCP, UDP or SCTP port number. */
+ uint8_t flow_ip_proto; /* IP proto from corresponding match, or 0 */
};
/* OFPACT_REG_MOVE.
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index b62afec..54cdb2e 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -180,7 +180,7 @@ AT_SETUP([ovs-ofctl parse-flows (OpenFlow 1.2)])
AT_DATA([flows.txt], [[
# comment
tcp,tp_src=123,actions=flood
-in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
+in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=mod_vlan_vid:7,mod_vlan_pcp:2
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
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=pop_queue,output:1
@@ -189,6 +189,10 @@ actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
ipv6,actions=set_field:fe80:0123:4567:890a:a6ba:dbff:fefe:59fa->ipv6_src
sctp actions=set_field:3334->sctp_src
sctp actions=set_field:4445->sctp_dst
+tcp actions=mod_tp_dst:1234
+udp actions=mod_tp_src:1111
+ip actions=mod_nw_src:10.1.1.2,mod_nw_dst:192.168.10.1,mod_nw_ttl:1,mod_nw_tos:16,mod_nw_ecn:2
+in_port=0 actions=mod_dl_src:11:22:33:44:55:66,mod_dl_dst:10:20:30:40:50:60
in_port=0 actions=resubmit:0
actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678)
]])
@@ -199,7 +203,7 @@ AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0],
[[usable protocols: NXM,OXM
chosen protocol: OXM-OpenFlow12
OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp,tp_src=123 actions=FLOOD
-OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
+OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=set_field:7->vlan_vid,set_field:2->vlan_pcp
OFPT_FLOW_MOD (OF1.2): ADD table:255 udp,dl_vlan_pcp=7 idle:5 actions=pop_vlan,output:0
OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
OFPT_FLOW_MOD (OF1.2): ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
@@ -208,6 +212,10 @@ OFPT_FLOW_MOD (OF1.2): ADD table:255 actions=note:41.42.43.00.00.00,note:00.01.0
OFPT_FLOW_MOD (OF1.2): ADD table:255 ipv6 actions=set_field:fe80:123:4567:890a:a6ba:dbff:fefe:59fa->ipv6_src
OFPT_FLOW_MOD (OF1.2): ADD table:255 sctp actions=set_field:3334->sctp_src
OFPT_FLOW_MOD (OF1.2): ADD table:255 sctp actions=set_field:4445->sctp_dst
+OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp actions=set_field:1234->tcp_dst
+OFPT_FLOW_MOD (OF1.2): ADD table:255 udp actions=set_field:1111->udp_src
+OFPT_FLOW_MOD (OF1.2): ADD table:255 ip actions=set_field:10.1.1.2->ip_src,set_field:192.168.10.1->ip_dst,mod_nw_ttl:1,set_field:4->ip_dscp,set_field:2->nw_ecn
+OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=0 actions=set_field:11:22:33:44:55:66->eth_src,set_field:10:20:30:40:50:60->eth_dst
OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=0 actions=resubmit:0
OFPT_FLOW_MOD (OF1.2): ADD table:255 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678)
]])
--
1.7.10.4
More information about the dev
mailing list