Some actions require an MPLS dl_type while others require a non-MPLS
dl_type. Enforce this for actions handled in ofpact_check__().
Update the following actions to require an non-MPLS dl_type:
set_ipv4_src
set_ipv4_dst
set_ipv4_dscp
set_l4_src_port
set_l4_dst_port
dec_ttl
Update the following actions to require an MPLS dl_type:
set_mpls_ttl
dec_mpls_ttl
pop_mpls
Update handling of the following actions to use the dl_type set by MPLS
push and pop actions if it differs from the orginal dl_type. This allows
their existing checks to encorce dl_type pre-requisites correctly.
output_reg
bundle
reg_move
stack_push
stack_pop
learn
multipath
Signed-off-by: Simon Horman <[email protected]>
---
lib/ofp-actions.c | 85 +++++++++++++++++++++++++++++++++++++--------------
tests/ofproto-dpif.at | 4 +--
2 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 068699f..2576f20 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1136,6 +1136,18 @@ exit:
return error;
}
+static const struct flow *update_flow(const struct flow *flow,
+ struct flow *flow_storage,
+ ovs_be16 dl_type)
+{
+ if (flow->dl_type == dl_type) {
+ return flow;
+ }
+ *flow_storage = *flow;
+ flow_storage->dl_type = dl_type;
+ return flow_storage;
+}
+
static enum ofperr
ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports,
ovs_be16 *dl_type)
@@ -1158,11 +1170,17 @@ ofpact_check__(const struct ofpact *a, const struct
flow *flow, int max_ports,
}
return 0;
- case OFPACT_OUTPUT_REG:
- return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, flow);
+ case OFPACT_OUTPUT_REG: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, updated_flow);
+ }
- case OFPACT_BUNDLE:
- return bundle_check(ofpact_get_BUNDLE(a), max_ports, flow);
+ case OFPACT_BUNDLE: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return bundle_check(ofpact_get_BUNDLE(a), max_ports, updated_flow);
+ }
case OFPACT_SET_VLAN_VID:
case OFPACT_SET_VLAN_PCP:
@@ -1170,34 +1188,46 @@ ofpact_check__(const struct ofpact *a, const struct
flow *flow, int max_ports,
case OFPACT_PUSH_VLAN:
case OFPACT_SET_ETH_SRC:
case OFPACT_SET_ETH_DST:
+ return 0;
+
case OFPACT_SET_IPV4_SRC:
case OFPACT_SET_IPV4_DST:
case OFPACT_SET_IPV4_DSCP:
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
- return 0;
+ return eth_type_mpls(*dl_type) ? OFPERR_OFPBAC_BAD_ARGUMENT : 0;
- case OFPACT_REG_MOVE:
- return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
+ case OFPACT_REG_MOVE: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return nxm_reg_move_check(ofpact_get_REG_MOVE(a), updated_flow);
+ }
- case OFPACT_REG_LOAD:
- if (*dl_type != flow->dl_type) {
- struct flow updated_flow = *flow;
- updated_flow.dl_type = *dl_type;
- return nxm_reg_load_check(ofpact_get_REG_LOAD(a), &updated_flow);
- } else {
- return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
- }
+ case OFPACT_REG_LOAD: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return nxm_reg_load_check(ofpact_get_REG_LOAD(a), updated_flow);
+ }
- case OFPACT_STACK_PUSH:
- return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
+ case OFPACT_STACK_PUSH: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), updated_flow);
+ }
- case OFPACT_STACK_POP:
- return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow);
+ case OFPACT_STACK_POP: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return nxm_stack_pop_check(ofpact_get_STACK_POP(a), updated_flow);
+ }
case OFPACT_DEC_TTL:
+ return eth_type_mpls(*dl_type) ? OFPERR_OFPBAC_BAD_ARGUMENT : 0;
+
case OFPACT_SET_MPLS_TTL:
case OFPACT_DEC_MPLS_TTL:
+ return eth_type_mpls(*dl_type) ? 0 : OFPERR_OFPBAC_BAD_ARGUMENT;
+
case OFPACT_SET_TUNNEL:
case OFPACT_SET_QUEUE:
case OFPACT_POP_QUEUE:
@@ -1205,11 +1235,17 @@ ofpact_check__(const struct ofpact *a, const struct
flow *flow, int max_ports,
case OFPACT_RESUBMIT:
return 0;
- case OFPACT_LEARN:
- return learn_check(ofpact_get_LEARN(a), flow);
+ case OFPACT_LEARN: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return learn_check(ofpact_get_LEARN(a), updated_flow);
+ }
- case OFPACT_MULTIPATH:
- return multipath_check(ofpact_get_MULTIPATH(a), flow);
+ case OFPACT_MULTIPATH: {
+ struct flow storage;
+ const struct flow *updated_flow = update_flow(flow, &storage,
*dl_type);
+ return multipath_check(ofpact_get_MULTIPATH(a), updated_flow);
+ }
case OFPACT_NOTE:
case OFPACT_EXIT:
@@ -1220,6 +1256,9 @@ ofpact_check__(const struct ofpact *a, const struct flow
*flow, int max_ports,
return 0;
case OFPACT_POP_MPLS:
+ if (!eth_type_mpls(*dl_type)) {
+ return OFPERR_OFPBAC_BAD_ARGUMENT;
+ }
*dl_type = ofpact_get_POP_MPLS(a)->ethertype;
return 0;
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 5903191..3d0f949 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -272,7 +272,7 @@ cookie=0xa dl_src=40:44:44:44:44:46
actions=push_mpls:0x8847,load:10->OXM_OF_MPL
cookie=0xa dl_src=40:44:44:44:44:47
actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),controller
cookie=0xa dl_src=40:44:44:44:44:48
actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,controller
cookie=0xb dl_src=50:55:55:55:55:55 dl_type=0x8847
actions=load:1000->OXM_OF_MPLS_LABEL[[]],controller
-cookie=0xd dl_src=60:66:66:66:66:66 actions=pop_mpls:0x0800,controller
+cookie=0xd dl_src=60:66:66:66:66:66 dl_type=0x8847
actions=pop_mpls:0x0800,controller
cookie=0xc dl_src=70:77:77:77:77:77
actions=push_mpls:0x8848,load:1000->OXM_OF_MPLS_LABEL[[]],load:7->OXM_OF_MPLS_TC[[]],controller
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -628,7 +628,7 @@ AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort],
[0], [dnl
cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:48
actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,CONTROLLER:65535
cookie=0xb, n_packets=3, n_bytes=180, mpls,dl_src=50:55:55:55:55:55
actions=load:0x3e8->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535
cookie=0xc, n_packets=3, n_bytes=180, dl_src=70:77:77:77:77:77
actions=push_mpls:0x8848,load:0x3e8->OXM_OF_MPLS_LABEL[[]],load:0x7->OXM_OF_MPLS_TC[[]],CONTROLLER:65535
- cookie=0xd, n_packets=3, n_bytes=186, dl_src=60:66:66:66:66:66
actions=pop_mpls:0x0800,CONTROLLER:65535
+ cookie=0xd, n_packets=3, n_bytes=186, mpls,dl_src=60:66:66:66:66:66
actions=pop_mpls:0x0800,CONTROLLER:65535
n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
NXST_FLOW reply:
])
--
1.8.2.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev