summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Bryant <russell@ovn.org>2017-09-14 21:57:00 -0600
committerRussell Bryant <russell@ovn.org>2017-09-19 11:47:28 -0400
commit29e4080777cbd8ea5100f598c6c2e5f065ffbe1d (patch)
treeadde5d218e2a91a61d4665104869c79d73ef4034
parent1ea2184501d43352ec40764f5eaa3cbd07e3fee3 (diff)
downloadopenvswitch-29e4080777cbd8ea5100f598c6c2e5f065ffbe1d.tar.gz
ovn: Discard flows for non-local ports.
Discard some OpenFlow flows that will never match. This includes flows that match on a non-local inport in the ingress pipeline or a non-local outport in the egress pipeline of a logical switch. This is most useful for networks with a large number of ports or ACLs that use large address sets. Signed-off-by: Russell Bryant <russell@ovn.org> Tested-by: Miguel Angel Ajo Pelayo <majopela@redhat.com> Acked-by: Han Zhou <zhouhan@gmail.com>
-rw-r--r--ovn/controller/binding.c29
-rw-r--r--ovn/controller/binding.h2
-rw-r--r--ovn/controller/lflow.c30
-rw-r--r--ovn/controller/lflow.h3
-rw-r--r--ovn/controller/ovn-controller.c9
5 files changed, 59 insertions, 14 deletions
diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index ca1d43395..3532c6014 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -371,6 +371,17 @@ setup_qos(const char *egress_iface, struct hmap *queue_map)
}
static void
+update_local_lport_ids(struct sset *local_lport_ids,
+ const struct sbrec_port_binding *binding_rec)
+{
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%"PRId64"_%"PRId64,
+ binding_rec->datapath->tunnel_key,
+ binding_rec->tunnel_key);
+ sset_add(local_lport_ids, buf);
+}
+
+static void
consider_local_datapath(struct controller_ctx *ctx,
const struct chassis_index *chassis_index,
struct sset *active_tunnels,
@@ -379,7 +390,8 @@ consider_local_datapath(struct controller_ctx *ctx,
struct hmap *qos_map,
struct hmap *local_datapaths,
struct shash *lport_to_iface,
- struct sset *local_lports)
+ struct sset *local_lports,
+ struct sset *local_lport_ids)
{
const struct ovsrec_interface *iface_rec
= shash_find_data(lport_to_iface, binding_rec->logical_port);
@@ -399,7 +411,7 @@ consider_local_datapath(struct controller_ctx *ctx,
get_qos_params(binding_rec, qos_map);
}
/* This port is in our chassis unless it is a localport. */
- if (strcmp(binding_rec->type, "localport")) {
+ if (strcmp(binding_rec->type, "localport")) {
our_chassis = true;
}
} else if (!strcmp(binding_rec->type, "l2gateway")) {
@@ -439,6 +451,14 @@ consider_local_datapath(struct controller_ctx *ctx,
our_chassis = false;
}
+ if (our_chassis
+ || !strcmp(binding_rec->type, "patch")
+ || !strcmp(binding_rec->type, "localport")
+ || !strcmp(binding_rec->type, "vtep")
+ || !strcmp(binding_rec->type, "localnet")) {
+ update_local_lport_ids(local_lport_ids, binding_rec);
+ }
+
if (ctx->ovnsb_idl_txn) {
const char *vif_chassis = smap_get(&binding_rec->options,
"requested-chassis");
@@ -508,7 +528,8 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec,
const struct chassis_index *chassis_index,
struct sset *active_tunnels,
- struct hmap *local_datapaths, struct sset *local_lports)
+ struct hmap *local_datapaths, struct sset *local_lports,
+ struct sset *local_lport_ids)
{
if (!chassis_rec) {
return;
@@ -533,7 +554,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
active_tunnels, chassis_rec, binding_rec,
sset_is_empty(&egress_ifaces) ? NULL :
&qos_map, local_datapaths, &lport_to_iface,
- local_lports);
+ local_lports, local_lport_ids);
}
diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h
index c78f8d932..89fc2ec8f 100644
--- a/ovn/controller/binding.h
+++ b/ovn/controller/binding.h
@@ -32,7 +32,7 @@ void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *,
const struct chassis_index *,
struct sset *active_tunnels, struct hmap *local_datapaths,
- struct sset *all_lports);
+ struct sset *local_lports, struct sset *local_lport_ids);
bool binding_cleanup(struct controller_ctx *, const struct sbrec_chassis *);
#endif /* ovn/binding.h */
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 6d9f02cb2..20a18c259 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -68,7 +68,8 @@ static void consider_logical_flow(struct controller_ctx *ctx,
uint32_t *conj_id_ofs,
const struct shash *addr_sets,
struct hmap *flow_table,
- struct sset *active_tunnels);
+ struct sset *active_tunnels,
+ struct sset *local_lport_ids);
static bool
lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)
@@ -145,7 +146,8 @@ add_logical_flows(struct controller_ctx *ctx,
const struct sbrec_chassis *chassis,
const struct shash *addr_sets,
struct hmap *flow_table,
- struct sset *active_tunnels)
+ struct sset *active_tunnels,
+ struct sset *local_lport_ids)
{
uint32_t conj_id_ofs = 1;
const struct sbrec_logical_flow *lflow;
@@ -170,7 +172,8 @@ add_logical_flows(struct controller_ctx *ctx,
lflow, local_datapaths,
group_table, chassis,
&dhcp_opts, &dhcpv6_opts, &conj_id_ofs,
- addr_sets, flow_table, active_tunnels);
+ addr_sets, flow_table, active_tunnels,
+ local_lport_ids);
}
dhcp_opts_destroy(&dhcp_opts);
@@ -189,7 +192,8 @@ consider_logical_flow(struct controller_ctx *ctx,
uint32_t *conj_id_ofs,
const struct shash *addr_sets,
struct hmap *flow_table,
- struct sset *active_tunnels)
+ struct sset *active_tunnels,
+ struct sset *local_lport_ids)
{
/* Determine translation of logical table IDs to physical table IDs. */
bool ingress = !strcmp(lflow->pipeline, "ingress");
@@ -301,6 +305,19 @@ consider_logical_flow(struct controller_ctx *ctx,
if (m->match.wc.masks.conj_id) {
m->match.flow.conj_id += *conj_id_ofs;
}
+ if (is_switch(ldp)) {
+ unsigned int reg_index
+ = (ingress ? MFF_LOG_INPORT : MFF_LOG_OUTPORT) - MFF_REG0;
+ int64_t port_id = m->match.flow.regs[reg_index];
+ if (port_id) {
+ int64_t dp_id = lflow->logical_datapath->tunnel_key;
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%"PRId64"_%"PRId64, dp_id, port_id);
+ if (!sset_contains(local_lport_ids, buf)) {
+ continue;
+ }
+ }
+ }
if (!m->n) {
ofctrl_add_flow(flow_table, ptable, lflow->priority,
lflow->header_.uuid.parts[0], &m->match, &ofpacts);
@@ -413,11 +430,12 @@ lflow_run(struct controller_ctx *ctx,
struct group_table *group_table,
const struct shash *addr_sets,
struct hmap *flow_table,
- struct sset *active_tunnels)
+ struct sset *active_tunnels,
+ struct sset *local_lport_ids)
{
add_logical_flows(ctx, chassis_index, local_datapaths,
group_table, chassis, addr_sets, flow_table,
- active_tunnels);
+ active_tunnels, local_lport_ids);
add_neighbor_flows(ctx, flow_table);
}
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index 07709fe06..bfb7415e2 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -69,7 +69,8 @@ void lflow_run(struct controller_ctx *,
struct group_table *group_table,
const struct shash *addr_sets,
struct hmap *flow_table,
- struct sset *active_tunnels);
+ struct sset *active_tunnels,
+ struct sset *local_lport_ids);
void lflow_destroy(void);
#endif /* ovn/lflow.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index e2c965290..a935a791c 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -670,6 +670,9 @@ main(int argc, char *argv[])
* l2gateway ports for which options:l2gateway-chassis designates the
* local hypervisor, and localnet ports. */
struct sset local_lports = SSET_INITIALIZER(&local_lports);
+ /* Contains the same ports as local_lports, but in the format:
+ * <datapath-tunnel-key>_<port-tunnel-key> */
+ struct sset local_lport_ids = SSET_INITIALIZER(&local_lport_ids);
struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels);
const struct ovsrec_bridge *br_int = get_br_int(&ctx);
@@ -686,7 +689,7 @@ main(int argc, char *argv[])
bfd_calculate_active_tunnels(br_int, &active_tunnels);
binding_run(&ctx, br_int, chassis,
&chassis_index, &active_tunnels, &local_datapaths,
- &local_lports);
+ &local_lports, &local_lport_ids);
}
if (br_int && chassis) {
struct shash addr_sets = SHASH_INITIALIZER(&addr_sets);
@@ -708,7 +711,8 @@ main(int argc, char *argv[])
struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
lflow_run(&ctx, chassis,
&chassis_index, &local_datapaths, &group_table,
- &addr_sets, &flow_table, &active_tunnels);
+ &addr_sets, &flow_table, &active_tunnels,
+ &local_lport_ids);
if (chassis_id) {
bfd_run(&ctx, br_int, chassis, &local_datapaths,
@@ -764,6 +768,7 @@ main(int argc, char *argv[])
chassis_index_destroy(&chassis_index);
sset_destroy(&local_lports);
+ sset_destroy(&local_lport_ids);
sset_destroy(&active_tunnels);
struct local_datapath *cur_node, *next_node;