From 6020298704dccb6d3f058ae854d00df77126704c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 30 Jul 2012 11:03:03 +0900 Subject: [PATCH] ofp-util: Update Capabilities for Open Flow 1.2 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 Signed-off-by: Ben Pfaff --- lib/ofp-print.c | 1 + lib/ofp-util.c | 23 ++++++++++++++++-- lib/ofp-util.h | 9 +++++-- tests/ofp-print.at | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 832e008e..e8a928e5 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -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; diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 85c25ddb..ac12b1b5 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -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) { diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 9230b36f..032b156d 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -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 { diff --git a/tests/ofp-print.at b/tests/ofp-print.at index 21466247..79516e0f 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -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 -- 2.30.2