ofp-util: Enforce OpenFlow 1.1+ table_id requirements in flow_mod messages.
authorBen Pfaff <blp@nicira.com>
Sat, 2 Nov 2013 05:03:19 +0000 (22:03 -0700)
committerBen Pfaff <blp@nicira.com>
Sat, 2 Nov 2013 05:20:17 +0000 (22:20 -0700)
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ofp-util.c
tests/learn.at
tests/ofp-print.at
tests/ofproto.at
tests/ovs-ofctl.at
utilities/ovs-ofctl.8.in

index 3cffe34..f0cd751 100644 (file)
@@ -1530,7 +1530,19 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
         }
         fm->modify_cookie = false;
         fm->command = ofm->command;
+
+        /* Get table ID.
+         *
+         * OF1.1 entirely forbids table_id == 255.
+         * OF1.2+ allows table_id == 255 only for deletes. */
         fm->table_id = ofm->table_id;
+        if (fm->table_id == 255
+            && (oh->version == OFP11_VERSION
+                || (ofm->command != OFPFC_DELETE &&
+                    ofm->command != OFPFC_DELETE_STRICT))) {
+            return OFPERR_OFPFMFC_BAD_TABLE_ID;
+        }
+
         fm->idle_timeout = ntohs(ofm->idle_timeout);
         fm->hard_timeout = ntohs(ofm->hard_timeout);
         fm->buffer_id = ntohl(ofm->buffer_id);
@@ -2058,7 +2070,14 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
             ofm->cookie = fm->cookie;
         }
         ofm->cookie_mask = fm->cookie_mask;
-        ofm->table_id = fm->table_id;
+        if (fm->table_id != 255
+            || (protocol != OFPUTIL_P_OF11_STD
+                && (fm->command == OFPFC_DELETE ||
+                    fm->command == OFPFC_DELETE_STRICT))) {
+            ofm->table_id = fm->table_id;
+        } else {
+            ofm->table_id = 0;
+        }
         ofm->command = fm->command;
         ofm->idle_timeout = htons(fm->idle_timeout);
         ofm->hard_timeout = htons(fm->hard_timeout);
index 7a4bda5..491cd5e 100644 (file)
@@ -32,8 +32,8 @@ actions=learn(table=1, in_port=1, load:OXM_OF_IN_PORT[]->NXM_NX_REG1[], load:0xf
 AT_CHECK([ovs-ofctl -O OpenFlow12 parse-flows flows.txt], [0],
 [[usable protocols: any
 chosen protocol: OXM-OpenFlow12
-OFPT_FLOW_MOD (OF1.2) (xid=0x1): ADD table:255 actions=learn(table=1,output:OXM_OF_IN_PORT[])
-OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:255 actions=learn(table=1,in_port=1,load:OXM_OF_IN_PORT[]->NXM_NX_REG1[],load:0xfffffffe->OXM_OF_IN_PORT[])
+OFPT_FLOW_MOD (OF1.2) (xid=0x1): ADD actions=learn(table=1,output:OXM_OF_IN_PORT[])
+OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD actions=learn(table=1,in_port=1,load:OXM_OF_IN_PORT[]->NXM_NX_REG1[],load:0xfffffffe->OXM_OF_IN_PORT[])
 ]])
 AT_CLEANUP
 
index 52e6fef..8701f54 100644 (file)
@@ -724,7 +724,7 @@ AT_SETUP([OFPT_FLOW_MOD - OF1.2 - low verbosity])
 AT_KEYWORDS([ofp-print])
 AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
 03 0e 00 90 00 00 00 02 00 00 00 00 00 00 00 00 \
-00 00 00 00 00 00 00 00 ff 00 00 00 00 00 ff ff \
+00 00 00 00 00 00 00 00 01 00 00 00 00 00 ff ff \
 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 \
 00 01 00 42 80 00 00 04 00 00 00 01 80 00 08 06 \
 50 54 00 00 00 06 80 00 06 06 50 54 00 00 00 05 \
@@ -733,7 +733,7 @@ ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 \
 00 01 00 00 00 00 00 00 00 04 00 18 00 00 00 00 \
 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 00 \
 " 2], [0], [dnl
-OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:255 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 actions=output:3
+OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:1 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 actions=output:3
 ], [dnl
 ])
 AT_CLEANUP
@@ -762,7 +762,7 @@ AT_SETUP([OFPT_FLOW_MOD - OF1.2 - low verbosity])
 AT_KEYWORDS([ofp-print])
 AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
 03 0e 00 90 00 00 00 02 00 00 00 00 00 00 00 00 \
-00 00 00 00 00 00 00 00 ff 00 00 00 00 00 ff ff \
+00 00 00 00 00 00 00 00 01 00 00 00 00 00 ff ff \
 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 \
 00 01 00 42 80 00 00 04 00 00 00 01 80 00 08 06 \
 50 54 00 00 00 06 80 00 06 06 50 54 00 00 00 05 \
@@ -771,7 +771,7 @@ ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 \
 00 01 00 00 00 00 00 00 00 04 00 18 00 00 00 00 \
 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 00 \
 " 2], [0], [dnl
-OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:255 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 actions=output:3
+OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:1 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 actions=output:3
 ], [dnl
 ])
 AT_CLEANUP
@@ -781,7 +781,7 @@ AT_SETUP([OFPT_FLOW_MOD - OF1.3 - flags - low verbosity])
 AT_KEYWORDS([ofp-print])
 AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
 04 0e 00 90 00 00 00 02 00 00 00 00 00 00 00 00 \
-00 00 00 00 00 00 00 00 ff 00 00 00 00 00 ff ff \
+00 00 00 00 00 00 00 00 01 00 00 00 00 00 ff ff \
 ff ff ff ff ff ff ff ff ff ff ff ff 00 1f 00 00 \
 00 01 00 42 80 00 00 04 00 00 00 01 80 00 08 06 \
 50 54 00 00 00 06 80 00 06 06 50 54 00 00 00 05 \
@@ -790,7 +790,7 @@ ff ff ff ff ff ff ff ff ff ff ff ff 00 1f 00 00 \
 00 01 00 00 00 00 00 00 00 04 00 18 00 00 00 00 \
 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 00 \
 " 2], [0], [dnl
-OFPT_FLOW_MOD (OF1.3) (xid=0x2): ADD table:255 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 send_flow_rem check_overlap reset_counts no_packet_counts no_byte_counts actions=output:3
+OFPT_FLOW_MOD (OF1.3) (xid=0x2): ADD table:1 priority=65535,arp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,arp_spa=192.168.0.2,arp_tpa=192.168.0.1,arp_op=2 send_flow_rem check_overlap reset_counts no_packet_counts no_byte_counts actions=output:3
 ], [dnl
 ])
 AT_CLEANUP
index 03ad346..68dada9 100644 (file)
@@ -315,6 +315,7 @@ OFPST_AGGREGATE reply (OF1.1): packet_count=0 byte_count=0 flow_count=2
 ])
 AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0])
 AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip], [0], [OFPST_FLOW reply (OF1.1):
+ table=1, in_port=4 actions=output:3
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -323,24 +324,12 @@ AT_SETUP([ofproto - flow_mod negative test (OpenFlow 1.1)])
 OVS_VSWITCHD_START(
   [set bridge br0 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13])
 AT_CHECK([ovs-ofctl add-flow -O OpenFlow11 br0 table=1,action=goto_table:2])
-AT_CHECK([ovs-ofctl add-flow -O OpenFlow11 br0 table=1,action=goto_table:1],
-  [1], [], [stderr])
 
-# The output should look like this:
-#
-# OFPT_ERROR (OF1.1) (xid=0x2): OFPBRC_BAD_TABLE_ID
-# OFPT_FLOW_MOD (OF1.1) (xid=0x2):
-# (***truncated to 64 bytes from 160***)
-# 00000000  02 0e 00 a0 00 00 00 02-00 00 00 00 00 00 00 00 |................|
-# 00000010  00 00 00 00 00 00 00 00-01 00 00 00 00 00 80 00 |................|
-# 00000020  ff ff ff ff ff ff ff ff-ff ff ff ff 00 00 00 00 |................|
-# 00000030  00 00 00 58 00 00 00 00-00 00 03 ff 00 00 00 00 |...X............|
-#
-# This 'sed' command captures the error message but drops details.
-AT_CHECK([sed '/truncated/d
-/^000000.0/d' stderr | STRIP_XIDS], [0],
-  [OFPT_ERROR (OF1.1): OFPBRC_BAD_TABLE_ID
-OFPT_FLOW_MOD (OF1.1):
+# The error message here actually comes from ovs-ofctl, not from ovs-vswitchd,
+# but at least it's the same code in ofpacts_check() that issues the error.
+AT_CHECK([ovs-ofctl add-flow -O OpenFlow11 br0 table=1,action=goto_table:1],
+  [1], [],
+  [ovs-ofctl: actions are invalid with specified match (OFPBRC_BAD_TABLE_ID)
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -725,8 +714,9 @@ AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dn
 OFPST_FLOW reply (OF1.1):
 ])
 AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0])
-AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip], [0], [dnl
 OFPST_FLOW reply (OF1.1):
+ cookie=0x2, table=1, in_port=2 actions=output:1
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
index 9f97043..a0a48e7 100644 (file)
@@ -184,18 +184,18 @@ AT_CHECK([ovs-ofctl --protocols OpenFlow11 parse-flows flows.txt
 AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0],
 [[usable protocols: any
 chosen protocol: OpenFlow11
-OFPT_FLOW_MOD (OF1.1): ADD table:255 tcp,tp_src=123 out_port:5 actions=FLOOD
-OFPT_FLOW_MOD (OF1.1): ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
-OFPT_FLOW_MOD (OF1.1): ADD table:255 udp,dl_vlan_pcp=7 idle:5 actions=pop_vlan,output:0
-OFPT_FLOW_MOD (OF1.1): ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
-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=mod_nw_ttl:1,mod_nw_src:10.4.3.77
-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
-OFPT_FLOW_MOD (OF1.1): ADD table:255 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678)
+OFPT_FLOW_MOD (OF1.1): ADD tcp,tp_src=123 out_port:5 actions=FLOOD
+OFPT_FLOW_MOD (OF1.1): ADD in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
+OFPT_FLOW_MOD (OF1.1): ADD udp,dl_vlan_pcp=7 idle:5 actions=pop_vlan,output:0
+OFPT_FLOW_MOD (OF1.1): ADD tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
+OFPT_FLOW_MOD (OF1.1): ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1
+OFPT_FLOW_MOD (OF1.1): ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
+OFPT_FLOW_MOD (OF1.1): ADD 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 ip actions=mod_nw_ttl:1,mod_nw_src:10.4.3.77
+OFPT_FLOW_MOD (OF1.1): ADD sctp actions=drop
+OFPT_FLOW_MOD (OF1.1): ADD sctp actions=drop
+OFPT_FLOW_MOD (OF1.1): ADD in_port=0 actions=resubmit:0
+OFPT_FLOW_MOD (OF1.1): ADD actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678)
 ]])
 AT_CLEANUP
 
@@ -225,22 +225,22 @@ AT_CHECK([ovs-ofctl --protocols OpenFlow12 parse-flows flows.txt
 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=set_field:4103->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
-OFPT_FLOW_MOD (OF1.2): ADD table:255 priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
-OFPT_FLOW_MOD (OF1.2): 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.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)
+OFPT_FLOW_MOD (OF1.2): ADD tcp,tp_src=123 actions=FLOOD
+OFPT_FLOW_MOD (OF1.2): ADD in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=set_field:4103->vlan_vid,set_field:2->vlan_pcp
+OFPT_FLOW_MOD (OF1.2): ADD udp,dl_vlan_pcp=7 idle:5 actions=pop_vlan,output:0
+OFPT_FLOW_MOD (OF1.2): ADD tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
+OFPT_FLOW_MOD (OF1.2): ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
+OFPT_FLOW_MOD (OF1.2): ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
+OFPT_FLOW_MOD (OF1.2): ADD 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.2): ADD ipv6 actions=set_field:fe80:123:4567:890a:a6ba:dbff:fefe:59fa->ipv6_src
+OFPT_FLOW_MOD (OF1.2): ADD sctp actions=set_field:3334->sctp_src
+OFPT_FLOW_MOD (OF1.2): ADD sctp actions=set_field:4445->sctp_dst
+OFPT_FLOW_MOD (OF1.2): ADD tcp actions=set_field:1234->tcp_dst
+OFPT_FLOW_MOD (OF1.2): ADD udp actions=set_field:1111->udp_src
+OFPT_FLOW_MOD (OF1.2): ADD 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 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 in_port=0 actions=resubmit:0
+OFPT_FLOW_MOD (OF1.2): ADD actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678)
 ]])
 AT_CLEANUP
 
index 168e955..3fcbe7c 100644 (file)
@@ -770,23 +770,60 @@ When \fBdl_type\fR and \fBnw_proto\fR take other values, the values of
 these settings are ignored (see \fBFlow Syntax\fR above).
 .
 .IP \fBtable=\fInumber\fR
-If specified, limits the flow manipulation and flow dump commands to
-only apply to the table with the given \fInumber\fR between 0 and 254.
-.
-Behavior varies if \fBtable\fR is not specified (equivalent to
-specifying 255 as \fInumber\fR).  For flow table
-modification commands without \fB\-\-strict\fR, the switch will choose
-the table for these commands to operate on.  For flow table
-modification commands with \fB\-\-strict\fR, the command will operate
-on any single matching flow in any table; it will do nothing if there
-are matches in more than one table.  The \fBdump-flows\fR and
-\fBdump-aggregate\fR commands will gather statistics about flows from
-all tables.
-.IP
-When this field is specified in \fBadd-flow\fR, \fBadd-flows\fR,
-\fBmod-flows\fR and \fBdel-flows\fR commands, it activates a Nicira
-extension to OpenFlow, which as of this writing is only known to be
-implemented by Open vSwitch.
+For flow dump commands, limits the flows dumped to those in the table
+with the given \fInumber\fR between 0 and 254.  If not specified (or if
+255 is specified as \fInumber\fR), then flows in all tables are
+dumped.
+.
+.IP
+For flow table modification commands, behavior varies based on the
+OpenFlow version used to connect to the switch:
+.
+.RS
+.IP "OpenFlow 1.0"
+OpenFlow 1.0 does not support \fBtable\fR for modifying flows.
+\fBovs\-ofctl\fR will exit with an error if \fBtable\fR (other than
+\fBtable=255\fR) is specified for a switch that only supports OpenFlow
+1.0.
+.IP
+In OpenFlow 1.0, the switch chooses the table into which to insert a
+new flow.  The Open vSwitch software switch always chooses table 0.
+Other Open vSwitch datapaths and other OpenFlow implementations may
+choose different tables.
+.IP
+The OpenFlow 1.0 behavior in Open vSwitch for modifying or removing
+flows depends on whether \fB\-\-strict\fR is used.  Without
+\fB\-\-strict\fR, the command applies to matching flows in all tables.
+With \fB\-\-strict\fR, the command will operate on any single matching
+flow in any table; it will do nothing if there are matches in more
+than one table.  (The distinction between these behaviors only matters
+if non-OpenFlow 1.0 commands were also used, because OpenFlow 1.0
+alone cannot add flows with the same matching criteria to multiple
+tables.)
+.
+.IP "OpenFlow 1.0 with table_id extension"
+Open vSwitch implements an OpenFlow extension that allows the
+controller to specify the table on which to operate.  \fBovs\-ofctl\fR
+automatically enables the extension when \fBtable\fR is specified and
+OpenFlow 1.0 is used.  \fBovs\-ofctl\fR automatically detects whether
+the switch supports the extension.  As of this writing, this extension
+is only known to be implemented by Open vSwitch.
+.
+.IP
+With this extension, \fBovs\-ofctl\fR operates on the requested table
+when \fBtable\fR is specified, and acts as described for OpenFlow 1.0
+above when no \fBtable\fR is specified (or for \fBtable=255\fR).
+.
+.IP "OpenFlow 1.1"
+OpenFlow 1.1 requires flow table modification commands to specify a
+table.  When \fBtable\fR is not specified (or \fBtable=255\fR is
+specified), \fBovs\-ofctl\fR defaults to table 0.
+.
+.IP "OpenFlow 1.2 and later"
+OpenFlow 1.2 and later allow flow deletion commands, but not other
+flow table modification commands, to operate on all flow tables, with
+the behavior described above for OpenFlow 1.0.
+.RE
 .
 .IP \fBmetadata=\fIvalue\fR[\fB/\fImask\fR]
 Matches \fIvalue\fR either exactly or with optional \fImask\fR in the metadata