ofp-util: Update Capabilities for Open Flow 1.2
authorSimon Horman <horms@verge.net.au>
Mon, 30 Jul 2012 02:03:03 +0000 (11:03 +0900)
committerBen Pfaff <blp@nicira.com>
Tue, 31 Jul 2012 04:47:00 +0000 (21:47 -0700)
There are capabilities which are present in one, two and three
of Open Flow 1.0, 1.1 and 1.2. Update OFPC_COMMON to only include
capabilities that are present in all three Open Flow versions and
add ofputil_capabilities_mask() to return the mask of capabilities
for each version.

This does not cover OFPUTIL_C_STP and OFPUTIL_C_GROUP_STATS, which
both use capability bit 3 and are treated as special cases in
ofputil_encode_switch_features() and ofputil_decode_switch_features().

Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ofp-print.c
lib/ofp-util.c
lib/ofp-util.h
tests/ofp-print.at

index 832e008efb3bf73bdd786ad8f1b6d7eab54343d3..e8a928e52770ddb283d48222d0bf70b54380bae3 100644 (file)
@@ -442,6 +442,7 @@ ofputil_capabilities_to_name(uint32_t bit)
     case OFPUTIL_C_ARP_MATCH_IP: return "ARP_MATCH_IP";
     case OFPUTIL_C_STP:          return "STP";
     case OFPUTIL_C_GROUP_STATS:  return "GROUP_STATS";
+    case OFPUTIL_C_PORT_BLOCKED: return "PORT_BLOCKED";
     }
 
     return NULL;
index 85c25ddb82f082b3e9eebdeb0412d39ac835af45..ac12b1b5966197c11d88bafa7517edf1cf99a699 100644 (file)
@@ -2313,7 +2313,7 @@ ofputil_append_port_desc_stats_reply(enum ofp_version ofp_version,
 /* ofputil_switch_features */
 
 #define OFPC_COMMON (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
-                     OFPC_IP_REASM | OFPC_QUEUE_STATS | OFPC_ARP_MATCH_IP)
+                     OFPC_IP_REASM | OFPC_QUEUE_STATS)
 BUILD_ASSERT_DECL((int) OFPUTIL_C_FLOW_STATS == OFPC_FLOW_STATS);
 BUILD_ASSERT_DECL((int) OFPUTIL_C_TABLE_STATS == OFPC_TABLE_STATS);
 BUILD_ASSERT_DECL((int) OFPUTIL_C_PORT_STATS == OFPC_PORT_STATS);
@@ -2403,6 +2403,22 @@ decode_action_bits(ovs_be32 of_actions,
     return ofputil_actions;
 }
 
+static uint32_t
+ofputil_capabilities_mask(enum ofp_version ofp_version)
+{
+    /* Handle capabilities whose bit is unique for all Open Flow versions */
+    switch (ofp_version) {
+    case OFP10_VERSION:
+    case OFP11_VERSION:
+        return OFPC_COMMON | OFPC_ARP_MATCH_IP;
+    case OFP12_VERSION:
+        return OFPC_COMMON | OFPC12_PORT_BLOCKED;
+    default:
+        /* Caller needs to check osf->header.version itself */
+        return 0;
+    }
+}
+
 /* Decodes an OpenFlow 1.0 or 1.1 "switch_features" structure 'osf' into an
  * abstract representation in '*features'.  Initializes '*b' to iterate over
  * the OpenFlow port structures following 'osf' with later calls to
@@ -2424,7 +2440,8 @@ ofputil_decode_switch_features(const struct ofp_header *oh,
     features->n_buffers = ntohl(osf->n_buffers);
     features->n_tables = osf->n_tables;
 
-    features->capabilities = ntohl(osf->capabilities) & OFPC_COMMON;
+    features->capabilities = ntohl(osf->capabilities) &
+        ofputil_capabilities_mask(oh->version);
 
     if (b->size % ofputil_get_phy_port_size(oh->version)) {
         return OFPERR_OFPBRC_BAD_LEN;
@@ -2538,6 +2555,8 @@ ofputil_encode_switch_features(const struct ofputil_switch_features *features,
     osf->n_tables = features->n_tables;
 
     osf->capabilities = htonl(features->capabilities & OFPC_COMMON);
+    osf->capabilities = htonl(features->capabilities &
+                              ofputil_capabilities_mask(version));
     switch (version) {
     case OFP10_VERSION:
         if (features->capabilities & OFPUTIL_C_STP) {
index 9230b36fe7acc8d3c7ee60442d3c1385059ff3ee..032b156dea2091a2a014fbe9592f1e6e61737a5f 100644 (file)
@@ -346,19 +346,24 @@ struct ofputil_phy_port {
 };
 
 enum ofputil_capabilities {
-    /* OpenFlow 1.0 and 1.1 share these values for these capabilities. */
+    /* OpenFlow 1.0, 1.1 and 1.2 share these values for these capabilities. */
     OFPUTIL_C_FLOW_STATS     = 1 << 0,  /* Flow statistics. */
     OFPUTIL_C_TABLE_STATS    = 1 << 1,  /* Table statistics. */
     OFPUTIL_C_PORT_STATS     = 1 << 2,  /* Port statistics. */
     OFPUTIL_C_IP_REASM       = 1 << 5,  /* Can reassemble IP fragments. */
     OFPUTIL_C_QUEUE_STATS    = 1 << 6,  /* Queue statistics. */
+
+    /* OpenFlow 1.0 and 1.1 share this capability. */
     OFPUTIL_C_ARP_MATCH_IP   = 1 << 7,  /* Match IP addresses in ARP pkts. */
 
     /* OpenFlow 1.0 only. */
     OFPUTIL_C_STP            = 1 << 3,  /* 802.1d spanning tree. */
 
-    /* OpenFlow 1.1 only. */
+    /* OpenFlow 1.1 and 1.2 share this capability. */
     OFPUTIL_C_GROUP_STATS    = 1 << 4,  /* Group statistics. */
+
+    /* OpenFlow 1.2 only */
+    OFPUTIL_C_PORT_BLOCKED   = 1 << 8,  /* Switch will block looping ports */
 };
 
 enum ofputil_action_bitmap {
index 21466247a5297b147f04b30d6936979e2984c68f..79516e0feeafda7bed3d173d0c052c1de7408b60 100644 (file)
@@ -245,6 +245,66 @@ received OFPT_FEATURES_REPLY with incorrect length 144 (must be exactly 32 bytes
 ])
 AT_CLEANUP
 
+AT_SETUP([OFPT_FEATURES_REPLY - OF1.2])
+AT_KEYWORDS([ofp-print])
+AT_CHECK([ovs-ofctl ofp-print "\
+03 06 00 a0 00 00 00 01 00 00 50 54 00 00 00 01 \
+00 00 01 00 ff 00 00 00 00 00 01 77 00 00 06 ff \
+ff ff ff fe 00 00 00 00 50 54 00 00 00 01 00 00 \
+62 72 30 0a 00 00 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 00 00 01 86 a0 00 01 86 a0 \
+00 00 00 03 00 00 00 00 50 54 00 00 00 01 00 00 \
+65 74 68 30 00 00 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 00 00 00 20 08 00 00 28 0f \
+00 00 28 0f 00 00 00 00 00 01 86 a0 00 01 86 a0 \
+"], [0], [dnl
+OFPT_FEATURES_REPLY (OF1.2) (xid=0x1): dpid:0000505400000001
+n_tables:255, n_buffers:256
+capabilities: FLOW_STATS TABLE_STATS PORT_STATS IP_REASM QUEUE_STATS PORT_BLOCKED
+ 3(eth0): addr:50:54:00:00:00:01
+     config:     0
+     state:      0
+     current:    100MB-FD AUTO_NEG
+     advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD COPPER AUTO_NEG
+     supported:  10MB-HD 10MB-FD 100MB-HD 100MB-FD COPPER AUTO_NEG
+     speed: 100 Mbps now, 100 Mbps max
+ LOCAL(br0): addr:50:54:00:00:00:01
+     config:     PORT_DOWN
+     state:      LINK_DOWN
+     speed: 100 Mbps now, 100 Mbps max
+])
+AT_CLEANUP
+
+AT_SETUP([OFPT_FEATURES_REPLY cut off mid-port - OF1.2])
+AT_KEYWORDS([ofp-print])
+AT_CHECK([ovs-ofctl ofp-print "\
+03 06 00 a0 00 00 00 01 00 00 50 54 00 00 00 01 \
+00 00 01 00 ff 00 00 00 00 00 01 77 00 00 06 ff \
+ff ff ff fe 00 00 00 00 50 54 00 00 00 01 00 00 \
+62 72 30 0a 00 00 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 00 00 01 86 a0 00 01 86 a0 \
+00 00 00 03 00 00 00 00 50 54 00 00 00 01 00 00 \
+65 74 68 30 00 00 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 00 00 00 20 08 00 00 28 0f \
+"], [0], [dnl
+OFPT_FEATURES_REPLY (OF1.2) (xid=0x1):
+(***truncated to 144 bytes from 160***)
+00000000  03 06 00 a0 00 00 00 01-00 00 50 54 00 00 00 01 |..........PT....|
+00000010  00 00 01 00 ff 00 00 00-00 00 01 77 00 00 06 ff |...........w....|
+00000020  ff ff ff fe 00 00 00 00-50 54 00 00 00 01 00 00 |........PT......|
+00000030  62 72 30 0a 00 00 00 00-00 00 00 00 00 00 00 00 |br0.............|
+00000040  00 00 00 01 00 00 00 01-00 00 00 00 00 00 00 00 |................|
+00000050  00 00 00 00 00 00 00 00-00 01 86 a0 00 01 86 a0 |................|
+00000060  00 00 00 03 00 00 00 00-50 54 00 00 00 01 00 00 |........PT......|
+00000070  65 74 68 30 00 00 00 00-00 00 00 00 00 00 00 00 |eth0............|
+00000080  00 00 00 00 00 00 00 00-00 00 20 08 00 00 28 0f |.......... ...@{:@.|
+], [stderr])
+AT_CHECK([sed 's/.*|//' stderr], [0], [dnl
+])
+AT_CLEANUP
+
 AT_SETUP([OFPT_GET_CONFIG_REQUEST])
 AT_KEYWORDS([ofp-print])
 AT_CHECK([ovs-ofctl ofp-print '0107000800000001'], [0], [dnl