[ovs-dev] [PATCH] ovn: Discard flows for non-local ports.

Russell Bryant russell at ovn.org
Mon Sep 18 15:24:01 UTC 2017


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 at ovn.org>
Tested-by: Miguel Angel Ajo Pelayo <majopela at redhat.com>
---
 ovn/controller/binding.c        | 29 +++++++++++++++++++++++++----
 ovn/controller/binding.h        |  2 +-
 ovn/controller/lflow.c          | 33 +++++++++++++++++++++++++++------
 ovn/controller/lflow.h          |  3 ++-
 ovn/controller/ovn-controller.c |  9 +++++++--
 5 files changed, 62 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..c1f5de2ab 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,22 @@ 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)) {
+                    //VLOG_INFO("Matching on port id %"PRId64" dp %"PRId64", is NOT local", port_id, dp_id);
+                    continue;
+                } else {
+                    //VLOG_INFO("Matching on port id %"PRId64" dp %"PRId64", is local", port_id, dp_id);
+                }
+            }
+        }
         if (!m->n) {
             ofctrl_add_flow(flow_table, ptable, lflow->priority,
                             lflow->header_.uuid.parts[0], &m->match, &ofpacts);
@@ -413,11 +433,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;
-- 
2.13.5



More information about the dev mailing list