From patchwork Fri Jan 12 20:57:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 860196 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJFSp6SClz9s7c for ; Sat, 13 Jan 2018 07:58:02 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 84276FED; Fri, 12 Jan 2018 20:57:33 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 13292FD2 for ; Fri, 12 Jan 2018 20:57:33 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 531D2473 for ; Fri, 12 Jan 2018 20:57:32 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 30CCB172094; Fri, 12 Jan 2018 21:57:29 +0100 (CET) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 12 Jan 2018 12:57:21 -0800 Message-Id: <20180112205722.25360-3-blp@ovn.org> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20180112205722.25360-1-blp@ovn.org> References: <20180112205722.25360-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH v2 2/3] ofp-util: New data structure for mapping between table names and numbers. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This shares the infrastructure for mapping port names and numbers. It will be used in an upcoming commit. Signed-off-by: Ben Pfaff Reviewed-by: Yifeng Sun --- include/openvswitch/ofp-util.h | 33 +++++++-- lib/ofp-util.c | 150 ++++++++++++++++++++++++++++++----------- 2 files changed, 138 insertions(+), 45 deletions(-) diff --git a/include/openvswitch/ofp-util.h b/include/openvswitch/ofp-util.h index 296078a2fe8b..d9780dd44582 100644 --- a/include/openvswitch/ofp-util.h +++ b/include/openvswitch/ofp-util.h @@ -43,15 +43,24 @@ union ofp_action; struct ofpact_set_field; struct vl_mff_map; -/* Mapping between port numbers and names. */ -struct ofputil_port_map { +/* Name-number mapping. + * + * This is not exported directly but only through specializations for port + * name-number and table name-number mappings. */ +struct ofputil_name_map { struct hmap by_name; struct hmap by_number; }; - -#define OFPUTIL_PORT_MAP_INITIALIZER(MAP) \ +#define OFPUTIL_NAME_MAP_INITIALIZER(MAP) \ { HMAP_INITIALIZER(&(MAP)->by_name), HMAP_INITIALIZER(&(MAP)->by_number) } +/* Mapping between port numbers and names. */ +struct ofputil_port_map { + struct ofputil_name_map map; +}; +#define OFPUTIL_PORT_MAP_INITIALIZER(MAP) \ + { OFPUTIL_NAME_MAP_INITIALIZER(&(MAP)->map) } + void ofputil_port_map_init(struct ofputil_port_map *); const char *ofputil_port_map_get_name(const struct ofputil_port_map *, ofp_port_t); @@ -791,6 +800,22 @@ struct ofputil_table_mod_prop_vacancy { uint8_t vacancy; /* Current vacancy (%). */ }; +/* Mapping between table numbers and names. */ +struct ofputil_table_map { + struct ofputil_name_map map; +}; +#define OFPUTIL_TABLE_MAP_INITIALIZER(MAP) \ + { OFPUTIL_NAME_MAP_INITIALIZER((MAP).map) } + +void ofputil_table_map_init(struct ofputil_table_map *); +const char *ofputil_table_map_get_name(const struct ofputil_table_map *, + uint8_t); +uint8_t ofputil_table_map_get_number(const struct ofputil_table_map *, + const char *name); +void ofputil_table_map_put(struct ofputil_table_map *, + uint8_t, const char *name); +void ofputil_table_map_destroy(struct ofputil_table_map *); + /* Abstract ofp_table_mod. */ struct ofputil_table_mod { uint8_t table_id; /* ID of the table, 0xff indicates all tables. */ diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 597112e4f84e..f3b2e3f6108c 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -7454,12 +7454,14 @@ ofputil_port_to_string(ofp_port_t port, snprintf(namebuf, bufsize, "%"PRIu32, port); } -/* ofputil_port_map. */ -struct ofputil_port_map_node { +/* ofputil_name_map. */ + +struct ofputil_name_map_node { struct hmap_node name_node; struct hmap_node number_node; - ofp_port_t ofp_port; /* Port number. */ - char *name; /* Port name. */ + + uint32_t number; + char *name; /* OpenFlow doesn't require port names to be unique, although that's the * only sensible way. However, even in Open vSwitch it's possible for two @@ -7469,22 +7471,25 @@ struct ofputil_port_map_node { * corner case. * * OpenFlow does require port numbers to be unique. We check for duplicate - * ports numbers just in case a switch has a bug. */ + * ports numbers just in case a switch has a bug. + * + * OpenFlow doesn't require table names to be unique and Open vSwitch + * doesn't try to make them unique. */ bool duplicate; }; -void -ofputil_port_map_init(struct ofputil_port_map *map) +static void +ofputil_name_map_init(struct ofputil_name_map *map) { hmap_init(&map->by_name); hmap_init(&map->by_number); } -static struct ofputil_port_map_node * -ofputil_port_map_find_by_name(const struct ofputil_port_map *map, +static struct ofputil_name_map_node * +ofputil_name_map_find_by_name(const struct ofputil_name_map *map, const char *name) { - struct ofputil_port_map_node *node; + struct ofputil_name_map_node *node; HMAP_FOR_EACH_WITH_HASH (node, name_node, hash_string(name, 0), &map->by_name) { @@ -7495,38 +7500,38 @@ ofputil_port_map_find_by_name(const struct ofputil_port_map *map, return NULL; } -static struct ofputil_port_map_node * -ofputil_port_map_find_by_number(const struct ofputil_port_map *map, - ofp_port_t ofp_port) +static struct ofputil_name_map_node * +ofputil_name_map_find_by_number(const struct ofputil_name_map *map, + uint32_t number) { - struct ofputil_port_map_node *node; + struct ofputil_name_map_node *node; - HMAP_FOR_EACH_IN_BUCKET (node, number_node, hash_ofp_port(ofp_port), + HMAP_FOR_EACH_IN_BUCKET (node, number_node, hash_int(number, 0), &map->by_number) { - if (node->ofp_port == ofp_port) { + if (node->number == number) { return node; } } return NULL; } -void -ofputil_port_map_put(struct ofputil_port_map *map, - ofp_port_t ofp_port, const char *name) +static void +ofputil_name_map_put(struct ofputil_name_map *map, + uint32_t number, const char *name) { - struct ofputil_port_map_node *node; + struct ofputil_name_map_node *node; /* Look for duplicate name. */ - node = ofputil_port_map_find_by_name(map, name); + node = ofputil_name_map_find_by_name(map, name); if (node) { - if (node->ofp_port != ofp_port) { + if (node->number != number) { node->duplicate = true; } return; } /* Look for duplicate number. */ - node = ofputil_port_map_find_by_number(map, ofp_port); + node = ofputil_name_map_find_by_number(map, number); if (node) { node->duplicate = true; return; @@ -7534,19 +7539,53 @@ ofputil_port_map_put(struct ofputil_port_map *map, /* Add new node. */ node = xmalloc(sizeof *node); - hmap_insert(&map->by_number, &node->number_node, hash_ofp_port(ofp_port)); + hmap_insert(&map->by_number, &node->number_node, hash_int(number, 0)); hmap_insert(&map->by_name, &node->name_node, hash_string(name, 0)); - node->ofp_port = ofp_port; + node->number = number; node->name = xstrdup(name); node->duplicate = false; } +static void +ofputil_name_map_destroy(struct ofputil_name_map *map) +{ + if (map) { + struct ofputil_name_map_node *node, *next; + + HMAP_FOR_EACH_SAFE (node, next, name_node, &map->by_name) { + hmap_remove(&map->by_name, &node->name_node); + hmap_remove(&map->by_number, &node->number_node); + free(node->name); + free(node); + } + hmap_destroy(&map->by_name); + hmap_destroy(&map->by_number); + } +} + +/* ofputil_port_map. */ + +void +ofputil_port_map_init(struct ofputil_port_map *map) +{ + ofputil_name_map_init(&map->map); +} + +void +ofputil_port_map_put(struct ofputil_port_map *map, + ofp_port_t ofp_port, const char *name) +{ + ofputil_name_map_put(&map->map, ofp_to_u16(ofp_port), name); +} + const char * ofputil_port_map_get_name(const struct ofputil_port_map *map, ofp_port_t ofp_port) { - struct ofputil_port_map_node *node - = map ? ofputil_port_map_find_by_number(map, ofp_port) : NULL; + struct ofputil_name_map_node *node + = (map + ? ofputil_name_map_find_by_number(&map->map, ofp_to_u16(ofp_port)) + : NULL); return node && !node->duplicate ? node->name : NULL; } @@ -7554,26 +7593,55 @@ ofp_port_t ofputil_port_map_get_number(const struct ofputil_port_map *map, const char *name) { - struct ofputil_port_map_node *node - = map ? ofputil_port_map_find_by_name(map, name) : NULL; - return node && !node->duplicate ? node->ofp_port : OFPP_NONE; + struct ofputil_name_map_node *node + = map ? ofputil_name_map_find_by_name(&map->map, name) : NULL; + return node && !node->duplicate ? u16_to_ofp(node->number) : OFPP_NONE; } void ofputil_port_map_destroy(struct ofputil_port_map *map) { - if (map) { - struct ofputil_port_map_node *node, *next; + ofputil_name_map_destroy(&map->map); +} + + +/* ofputil_table_map. */ - HMAP_FOR_EACH_SAFE (node, next, name_node, &map->by_name) { - hmap_remove(&map->by_name, &node->name_node); - hmap_remove(&map->by_number, &node->number_node); - free(node->name); - free(node); - } - hmap_destroy(&map->by_name); - hmap_destroy(&map->by_number); - } +void +ofputil_table_map_init(struct ofputil_table_map *map) +{ + ofputil_name_map_init(&map->map); +} + +void +ofputil_table_map_put(struct ofputil_table_map *map, + uint8_t table_id, const char *name) +{ + ofputil_name_map_put(&map->map, table_id, name); +} + +const char * +ofputil_table_map_get_name(const struct ofputil_table_map *map, + uint8_t table_id) +{ + struct ofputil_name_map_node *node + = map ? ofputil_name_map_find_by_number(&map->map, table_id) : NULL; + return node && !node->duplicate ? node->name : NULL; +} + +uint8_t +ofputil_table_map_get_number(const struct ofputil_table_map *map, + const char *name) +{ + struct ofputil_name_map_node *node + = map ? ofputil_name_map_find_by_name(&map->map, name) : NULL; + return node && !node->duplicate ? node->number : UINT8_MAX; +} + +void +ofputil_table_map_destroy(struct ofputil_table_map *map) +{ + ofputil_name_map_destroy(&map->map); } /* Stores the group id represented by 's' into '*group_idp'. 's' may be an