mirror of
https://github.com/openvswitch/ovs
synced 2025-10-25 15:07:05 +00:00
ofp-util had been far too large and monolithic for a long time. This commit breaks it up into units that make some logical sense. It also moves the pieces of ofp-parse that were specific to each unit into the relevant unit. Most of this commit is just moving code around. Signed-off-by: Ben Pfaff <blp@ovn.org> Reviewed-by: Yifeng Sun <pkusunyifeng@gmail.com>
133 lines
3.3 KiB
C
133 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2017-2018 Nicira, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "openvswitch/namemap.h"
|
|
#include <ctype.h>
|
|
#include "hash.h"
|
|
#include "openvswitch/dynamic-string.h"
|
|
#include "openvswitch/json.h"
|
|
|
|
void
|
|
namemap_init(struct namemap *map)
|
|
{
|
|
hmap_init(&map->by_name);
|
|
hmap_init(&map->by_number);
|
|
}
|
|
|
|
struct namemap_node *
|
|
namemap_find_by_name(const struct namemap *map, const char *name)
|
|
{
|
|
struct namemap_node *node;
|
|
|
|
HMAP_FOR_EACH_WITH_HASH (node, name_node, hash_string(name, 0),
|
|
&map->by_name) {
|
|
if (!strcmp(name, node->name)) {
|
|
return node;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
struct namemap_node *
|
|
namemap_find_by_number(const struct namemap *map, uint32_t number)
|
|
{
|
|
struct namemap_node *node;
|
|
|
|
HMAP_FOR_EACH_IN_BUCKET (node, number_node, hash_int(number, 0),
|
|
&map->by_number) {
|
|
if (node->number == number) {
|
|
return node;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
namemap_put(struct namemap *map, uint32_t number, const char *name)
|
|
{
|
|
struct namemap_node *node;
|
|
|
|
/* Look for duplicate name. */
|
|
node = namemap_find_by_name(map, name);
|
|
if (node) {
|
|
if (node->number != number) {
|
|
node->duplicate = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* Look for duplicate number. */
|
|
node = namemap_find_by_number(map, number);
|
|
if (node) {
|
|
node->duplicate = true;
|
|
return;
|
|
}
|
|
|
|
/* Add new node. */
|
|
node = xmalloc(sizeof *node);
|
|
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->number = number;
|
|
node->name = xstrdup(name);
|
|
node->duplicate = false;
|
|
}
|
|
|
|
void
|
|
namemap_destroy(struct namemap *map)
|
|
{
|
|
if (map) {
|
|
struct namemap_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);
|
|
}
|
|
}
|
|
|
|
/* A table or port name doesn't need to be quoted if it is alphanumeric and
|
|
* starts with a letter. */
|
|
static bool
|
|
name_needs_quotes(const char *name)
|
|
{
|
|
if (!isalpha((unsigned char) name[0])) {
|
|
return true;
|
|
}
|
|
|
|
for (const char *p = name + 1; *p; p++) {
|
|
if (!isalnum((unsigned char) *p)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* Appends port or table 'name' to 's', quoting it if necessary. */
|
|
void
|
|
namemap_put_name(const char *name, struct ds *s)
|
|
{
|
|
if (name_needs_quotes(name)) {
|
|
json_string_escape(name, s);
|
|
} else {
|
|
ds_put_cstr(s, name);
|
|
}
|
|
}
|