diff options
author | Shu Shen <shu.shen@radisys.com> | 2014-11-25 16:32:15 -0800 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2014-12-11 17:32:48 -0800 |
commit | 3a11fd5b2b0fc2511e0fbef465c6ff50b121e519 (patch) | |
tree | 9504fa0b040ea6467f2cfe6919ea207f3318030e | |
parent | 4819e33042bfb8d6262a3c26501f9fbd9ba2c96d (diff) |
ofproto: add support of OFPR_GROUP as packet-in reason for OF1.4+
When the Packet-In message is triggered by a group action, OFPR_GROUP is
passed internally as the reason. The wire_reason() function converts the
reason to OFPR_ACTION if the wire protocol is earlier than OF1.4.
The wire_reason() function also converts other unsupported reasons
(i.e., OFPR_ACTION_SET and OFPR_PACKET_OUT) to OFPR_ACTION if it detects
a wire protocol earlier than OF1.4.
By default reason code OFPR_GROUP for Packet-In will be enabled for
async messages as in ofconn_flush(). Upon a connection being established
with a controller, the protocol version is checked and OFPR_GROUP will
be disabled in async config if the protocol is lower than OF1.4. Any
controller running OF1.4+ is still be able to enable OFPR_GROUP at its
will without being affected by this check.
The patch also includes tests cases for both OF1.3 and OF1.4 to ensure
proper reason code is given for packet-in message triggered by group
action.
Signed-off-by: Shu Shen <shu.shen@radisys.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r-- | DESIGN.md | 1 | ||||
-rw-r--r-- | OPENFLOW-1.1+.md | 1 | ||||
-rw-r--r-- | ofproto/connmgr.c | 48 | ||||
-rw-r--r-- | ofproto/ofproto-dpif-xlate.c | 3 | ||||
-rw-r--r-- | tests/ofproto-dpif.at | 88 |
5 files changed, 132 insertions, 9 deletions
@@ -54,6 +54,7 @@ sent, an entry labeled "---" means that the message is suppressed. OFPR_NO_MATCH yes --- OFPR_ACTION yes --- OFPR_INVALID_TTL --- --- + OFPR_GROUP (OF1.4+) yes --- OFPT_FLOW_REMOVED / NXT_FLOW_REMOVED OFPRR_IDLE_TIMEOUT yes --- diff --git a/OPENFLOW-1.1+.md b/OPENFLOW-1.1+.md index be28f165d..967f90628 100644 --- a/OPENFLOW-1.1+.md +++ b/OPENFLOW-1.1+.md @@ -197,6 +197,7 @@ OpenFlow 1.4 features are listed in the previous section. * More descriptive reasons for packet-in Distinguish OFPR_APPLY_ACTION, OFPR_ACTION_SET, OFPR_GROUP, OFPR_PACKET_OUT. NO_MATCH was renamed to OFPR_TABLE_MISS. + (OFPR_GROUP is now supported) [EXT-136] [required for OF1.4+] diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 46e743192..75f4198a5 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -996,6 +996,14 @@ void ofconn_set_protocol(struct ofconn *ofconn, enum ofputil_protocol protocol) { ofconn->protocol = protocol; + if (!(protocol & OFPUTIL_P_OF14_UP)) { + uint32_t *master = ofconn->master_async_config; + uint32_t *slave = ofconn->slave_async_config; + + /* OFPR_GROUP is not supported before OF1.4 */ + master[OAM_PACKET_IN] &= ~(1u << OFPR_GROUP); + slave [OAM_PACKET_IN] &= ~(1u << OFPR_GROUP); + } } /* Returns the currently configured packet in format for 'ofconn', one of @@ -1056,6 +1064,13 @@ ofconn_get_async_config(struct ofconn *ofconn, uint32_t *master_masks, uint32_t *slave_masks) { size_t size = sizeof ofconn->master_async_config; + + /* Make sure we know the protocol version and the async_config + * masks are properly updated by calling ofconn_get_protocol() */ + if (OFPUTIL_P_NONE == ofconn_get_protocol(ofconn)){ + OVS_NOT_REACHED(); + } + memcpy(master_masks, ofconn->master_async_config, size); memcpy(slave_masks, ofconn->slave_async_config, size); } @@ -1235,7 +1250,9 @@ ofconn_flush(struct ofconn *ofconn) /* "master" and "other" roles get all asynchronous messages by default, * except that the controller needs to enable nonstandard "packet-in" * reasons itself. */ - master[OAM_PACKET_IN] = (1u << OFPR_NO_MATCH) | (1u << OFPR_ACTION); + master[OAM_PACKET_IN] = ((1u << OFPR_NO_MATCH) + | (1u << OFPR_ACTION) + | (1u << OFPR_GROUP)); master[OAM_PORT_STATUS] = ((1u << OFPPR_ADD) | (1u << OFPPR_DELETE) | (1u << OFPPR_MODIFY)); @@ -1651,16 +1668,31 @@ connmgr_send_flow_removed(struct connmgr *mgr, static enum ofp_packet_in_reason wire_reason(struct ofconn *ofconn, const struct ofproto_packet_in *pin) { - if (pin->miss_type == OFPROTO_PACKET_IN_MISS_FLOW - && pin->up.reason == OFPR_ACTION) { - enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); + enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); - if (protocol != OFPUTIL_P_NONE - && ofputil_protocol_to_ofp_version(protocol) >= OFP13_VERSION) { - return OFPR_NO_MATCH; + if (pin->miss_type == OFPROTO_PACKET_IN_MISS_FLOW + && pin->up.reason == OFPR_ACTION + && protocol != OFPUTIL_P_NONE + && ofputil_protocol_to_ofp_version(protocol) >= OFP13_VERSION) { + return OFPR_NO_MATCH; + } + + switch (pin->up.reason) { + case OFPR_ACTION_SET: + case OFPR_GROUP: + case OFPR_PACKET_OUT: + if (!(protocol & OFPUTIL_P_OF14_UP)) { + /* Only supported in OF1.4+ */ + return OFPR_ACTION; } + /* Fall through. */ + case OFPR_NO_MATCH: + case OFPR_ACTION: + case OFPR_INVALID_TTL: + case OFPR_N_REASONS: + default: + return pin->up.reason; } - return pin->up.reason; } /* Given 'pin', sends an OFPT_PACKET_IN message to each OpenFlow controller as diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 8f0a3aa66..9f0fdce5f 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3405,7 +3405,8 @@ xlate_output_action(struct xlate_ctx *ctx, flood_packets(ctx, true); break; case OFPP_CONTROLLER: - execute_controller_action(ctx, max_len, OFPR_ACTION, 0); + execute_controller_action(ctx, max_len, + ctx->in_group ? OFPR_GROUP : OFPR_ACTION, 0); break; case OFPP_NONE: break; diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index fd3f00aa7..baa942fcf 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -2746,6 +2746,94 @@ OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([ofproto-dpif - packet-in reason in group table (Openflow 1.3)]) +OVS_VSWITCHD_START([dnl + add-port br0 p1 -- set Interface p1 type=dummy +]) +ON_EXIT([kill `cat ovs-ofctl.pid`]) + +AT_CAPTURE_FILE([ofctl_monitor.log]) +# A table-miss flow has priority 0 and no match +AT_CHECK([ovs-ofctl --protocols=OpenFlow13 add-group br0 'group_id=1234,type=all,bucket=output:10,bucket=output:CONTROLLER']) +AT_CHECK([ovs-ofctl --protocols=OpenFlow13 add-flow br0 'in_port=1 actions=group:1234']) + +dnl Singleton controller action. +AT_CHECK([ovs-ofctl monitor -P openflow10 --protocols=OpenFlow13 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log]) + +for i in 1 2 3 ; do + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=10),tcp_flags(0x002)' +done +OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 6]) +ovs-appctl -t ovs-ofctl exit + +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore]) + +AT_CHECK([cat ofctl_monitor.log], [0], [dnl +OFPT_PACKET_IN (OF1.3) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +dnl +OFPT_PACKET_IN (OF1.3) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +dnl +OFPT_PACKET_IN (OF1.3) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +]) + +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore]) + +AT_CHECK([ovs-ofctl --protocols=OpenFlow13 dump-flows br0 | ofctl_strip | sort], [0], [dnl + n_packets=3, n_bytes=180, in_port=1 actions=group:1234 +OFPST_FLOW reply (OF1.3): +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + + +AT_SETUP([ofproto-dpif - packet-in reason in group table (Openflow 1.4)]) +OVS_VSWITCHD_START([dnl + add-port br0 p1 -- set Interface p1 type=dummy +]) +ON_EXIT([kill `cat ovs-ofctl.pid`]) + +AT_CAPTURE_FILE([ofctl_monitor.log]) +# A table-miss flow has priority 0 and no match +AT_CHECK([ovs-ofctl --protocols=OpenFlow14 add-group br0 'group_id=1234,type=all,bucket=output:10,bucket=output:CONTROLLER']) +AT_CHECK([ovs-ofctl --protocols=OpenFlow14 add-flow br0 'in_port=1 actions=group:1234']) + +dnl Singleton controller action. +AT_CHECK([ovs-ofctl monitor -P openflow10 --protocols=OpenFlow14 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log]) + +for i in 1 2 3 ; do + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=10),tcp_flags(0x002)' +done +OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 6]) +ovs-appctl -t ovs-ofctl exit + +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore]) + +AT_CHECK([cat ofctl_monitor.log], [0], [dnl +OFPT_PACKET_IN (OF1.4) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via group) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +dnl +OFPT_PACKET_IN (OF1.4) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via group) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +dnl +OFPT_PACKET_IN (OF1.4) (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via group) data_len=60 (unbuffered) +tcp,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=10,tcp_flags=syn tcp_csum:0 +]) + +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore]) + +AT_CHECK([ovs-ofctl --protocols=OpenFlow14 dump-flows br0 | ofctl_strip | sort], [0], [dnl + n_packets=3, n_bytes=180, in_port=1 actions=group:1234 +OFPST_FLOW reply (OF1.4): +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([ofproto-dpif - ARP modification slow-path]) OVS_VSWITCHD_START ADD_OF_PORTS([br0], [1], [2]) |