2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00

ovn-controller: Introduce helpers for looking up datapaths.

The new helpers get_local_datapath() and get_patched_datapath() make code
a little shorter and easier to read.  They also avoid a pitfall that was
present in at least a few of the instances: CONTAINER_OF is not safe on a
null pointer, because it does a raw pointer subtraction and will change
NULL to something else.  This wasn't actually a problem in these particular
cases because the value it was subtracting was zero (although arguably it
is still undefined behavior because the compiler is allowed to assume that
a pointer on which arithmetic is performed is nonnull).

Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Russell Bryant <russell@ovn.org>
This commit is contained in:
Ben Pfaff 2016-04-11 18:48:38 -07:00
parent a9360f2ab9
commit e4426e3457
6 changed files with 41 additions and 26 deletions

View File

@ -125,8 +125,8 @@ static void
add_local_datapath(struct hmap *local_datapaths, add_local_datapath(struct hmap *local_datapaths,
const struct sbrec_port_binding *binding_rec) const struct sbrec_port_binding *binding_rec)
{ {
if (hmap_first_with_hash(local_datapaths, if (get_local_datapath(local_datapaths,
binding_rec->datapath->tunnel_key)) { binding_rec->datapath->tunnel_key)) {
return; return;
} }

View File

@ -241,15 +241,12 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
* large lrouters and lswitches. This need to be studied further. * large lrouters and lswitches. This need to be studied further.
*/ */
struct hmap_node *ld; if (!get_local_datapath(local_datapaths, ldp->tunnel_key)) {
ld = hmap_first_with_hash(local_datapaths, ldp->tunnel_key);
if (!ld) {
if (!ingress) { if (!ingress) {
continue; continue;
} }
struct hmap_node *pd; if (!get_patched_datapath(patched_datapaths,
pd = hmap_first_with_hash(patched_datapaths, ldp->tunnel_key); ldp->tunnel_key)) {
if (!pd) {
continue; continue;
} }
} }

View File

@ -62,6 +62,25 @@ OVS_NO_RETURN static void usage(void);
static char *ovs_remote; static char *ovs_remote;
struct local_datapath *
get_local_datapath(const struct hmap *local_datapaths, uint32_t tunnel_key)
{
struct hmap_node *node = hmap_first_with_hash(local_datapaths, tunnel_key);
return (node
? CONTAINER_OF(node, struct local_datapath, hmap_node)
: NULL);
}
struct patched_datapath *
get_patched_datapath(const struct hmap *patched_datapaths, uint32_t tunnel_key)
{
struct hmap_node *node = hmap_first_with_hash(patched_datapaths,
tunnel_key);
return (node
? CONTAINER_OF(node, struct patched_datapath, hmap_node)
: NULL);
}
const struct sbrec_chassis * const struct sbrec_chassis *
get_chassis(struct ovsdb_idl *ovnsb_idl, const char *chassis_id) get_chassis(struct ovsdb_idl *ovnsb_idl, const char *chassis_id)
{ {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015 Nicira, Inc. /* Copyright (c) 2015, 2016 Nicira, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,12 +41,18 @@ struct local_datapath {
const struct sbrec_port_binding *localnet_port; const struct sbrec_port_binding *localnet_port;
}; };
struct local_datapath *get_local_datapath(const struct hmap *,
uint32_t tunnel_key);
/* Contains hmap_node whose hash values are the tunnel_key of datapaths /* Contains hmap_node whose hash values are the tunnel_key of datapaths
* with at least one logical patch port binding. */ * with at least one logical patch port binding. */
struct patched_datapath { struct patched_datapath {
struct hmap_node hmap_node; struct hmap_node hmap_node;
}; };
struct patched_datapath *get_patched_datapath(const struct hmap *,
uint32_t tunnel_key);
const struct ovsrec_bridge *get_bridge(struct ovsdb_idl *, const struct ovsrec_bridge *get_bridge(struct ovsdb_idl *,
const char *br_name); const char *br_name);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015 Nicira, Inc. /* Copyright (c) 2015, 2016 Nicira, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -176,10 +176,9 @@ add_bridge_mappings(struct controller_ctx *ctx,
const struct sbrec_port_binding *binding; const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) { SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
if (!strcmp(binding->type, "localnet")) { if (!strcmp(binding->type, "localnet")) {
struct local_datapath *ld; struct local_datapath *ld
ld = CONTAINER_OF(hmap_first_with_hash(local_datapaths, = get_local_datapath(local_datapaths,
binding->datapath->tunnel_key), binding->datapath->tunnel_key);
struct local_datapath, hmap_node);
if (!ld) { if (!ld) {
/* This localnet port is on a datapath with no /* This localnet port is on a datapath with no
* logical ports bound to this chassis, so there's no need * logical ports bound to this chassis, so there's no need
@ -233,7 +232,7 @@ static void
add_patched_datapath(struct hmap *patched_datapaths, add_patched_datapath(struct hmap *patched_datapaths,
const struct sbrec_port_binding *binding_rec) const struct sbrec_port_binding *binding_rec)
{ {
if (hmap_first_with_hash(patched_datapaths, if (get_patched_datapath(patched_datapaths,
binding_rec->datapath->tunnel_key)) { binding_rec->datapath->tunnel_key)) {
return; return;
} }

View File

@ -138,9 +138,8 @@ put_stack(enum mf_field_id field, struct ofpact_stack *stack)
static const struct sbrec_port_binding* static const struct sbrec_port_binding*
get_localnet_port(struct hmap *local_datapaths, int64_t tunnel_key) get_localnet_port(struct hmap *local_datapaths, int64_t tunnel_key)
{ {
struct local_datapath *ld; struct local_datapath *ld = get_local_datapath(local_datapaths,
ld = CONTAINER_OF(hmap_first_with_hash(local_datapaths, tunnel_key), tunnel_key);
struct local_datapath, hmap_node);
return ld ? ld->localnet_port : NULL; return ld ? ld->localnet_port : NULL;
} }
@ -255,14 +254,9 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
*/ */
uint32_t dp_key = binding->datapath->tunnel_key; uint32_t dp_key = binding->datapath->tunnel_key;
uint32_t port_key = binding->tunnel_key; uint32_t port_key = binding->tunnel_key;
struct hmap_node *ld; if (!get_local_datapath(local_datapaths, dp_key)
ld = hmap_first_with_hash(local_datapaths, dp_key); && !get_patched_datapath(patched_datapaths, dp_key)) {
if (!ld) { continue;
struct hmap_node *pd;
pd = hmap_first_with_hash(patched_datapaths, dp_key);
if (!pd) {
continue;
}
} }
/* Find the OpenFlow port for the logical port, as 'ofport'. This is /* Find the OpenFlow port for the logical port, as 'ofport'. This is