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
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);
}
/* "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));
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
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])