[ovs-dev] [PATCH] ovn: Fix flows between 2 local ports.

Russell Bryant rbryant at redhat.com
Thu Aug 6 18:51:13 UTC 2015


Packets were always resubmmited to the remote output table, which
handles output to a remote chassis.  Broadcast packets were only sent
remotely and not to local ports on the same logical switch.  Unicast
packets between 2 local ports also didn't work.

This patch makes it so packets are sent to both remote and local
output tables.  It would be a bit cleaner to only submit to the
necessary table(s), but always resubmitting to both and letting the
matching work it out seems to be fine and gets things working again.

Signed-off-by: Russell Bryant <rbryant at redhat.com>
---
 ovn/controller/lflow.c | 14 ++++++++++----
 ovn/lib/actions.c      | 20 +++++++++++++-------
 ovn/lib/actions.h      |  9 +++++----
 tests/test-ovn.c       |  5 +++--
 4 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 9246e61..efa0253 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -271,9 +271,14 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table)
                                                 : OFTABLE_LOG_EGRESS_PIPELINE);
         uint8_t next_phys_table
             = lflow->table_id + 1 < LOG_PIPELINE_LEN ? phys_table + 1 : 0;
-        uint8_t output_phys_table = (ingress
-                                     ? OFTABLE_REMOTE_OUTPUT
-                                     : OFTABLE_LOG_TO_PHY);
+        uint8_t oftable_output[] = { OFTABLE_LOCAL_OUTPUT, OFTABLE_REMOTE_OUTPUT };
+        uint8_t oftable_log_to_phy[] = { OFTABLE_LOG_TO_PHY };
+        uint8_t *output_phys_table = (ingress
+                                     ? oftable_output
+                                     : oftable_log_to_phy);
+        size_t n_output_tables = (ingress
+                                 ? ARRAY_SIZE(oftable_output)
+                                 : ARRAY_SIZE(oftable_log_to_phy));
         /* Translate OVN actions into OpenFlow actions.
          *
          * XXX Deny changes to 'outport' in egress pipeline. */
@@ -284,7 +289,8 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table)
 
         ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
         error = actions_parse_string(lflow->actions, &symtab, &ldp->ports,
-                                     next_phys_table, output_phys_table,
+                                     next_phys_table,
+                                     output_phys_table, n_output_tables,
                                      &ofpacts, &prereqs);
         if (error) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
index 0a0158a..51b04ae 100644
--- a/ovn/lib/actions.c
+++ b/ovn/lib/actions.c
@@ -31,7 +31,8 @@ struct action_context {
     struct lexer *lexer;        /* Lexer for pulling more tokens. */
     const struct shash *symtab; /* Symbol table. */
     uint8_t next_table_id;      /* OpenFlow table for 'next' to resubmit. */
-    uint8_t output_table_id;    /* OpenFlow table for 'output' to resubmit. */
+    uint8_t *output_table_id;   /* OpenFlow tables for 'output' to resubmit. */
+    size_t n_output_table_id;
     const struct simap *ports;  /* Map from port name to number. */
 
     /* State. */
@@ -162,7 +163,10 @@ parse_actions(struct action_context *ctx)
                 action_error(ctx, "\"next\" action not allowed here.");
             }
         } else if (lexer_match_id(ctx->lexer, "output")) {
-            emit_resubmit(ctx, ctx->output_table_id);
+            size_t i;
+            for (i = 0; i < ctx->n_output_table_id; i++) {
+                emit_resubmit(ctx, ctx->output_table_id[i]);
+            }
         } else {
             action_syntax_error(ctx, "expecting action");
         }
@@ -205,8 +209,8 @@ parse_actions(struct action_context *ctx)
 char * OVS_WARN_UNUSED_RESULT
 actions_parse(struct lexer *lexer, const struct shash *symtab,
               const struct simap *ports, uint8_t next_table_id,
-              uint8_t output_table_id, struct ofpbuf *ofpacts,
-              struct expr **prereqsp)
+              uint8_t *output_table_id, size_t n_output_table_id,
+              struct ofpbuf *ofpacts, struct expr **prereqsp)
 {
     size_t ofpacts_start = ofpacts->size;
 
@@ -216,6 +220,7 @@ actions_parse(struct lexer *lexer, const struct shash *symtab,
     ctx.ports = ports;
     ctx.next_table_id = next_table_id;
     ctx.output_table_id = output_table_id;
+    ctx.n_output_table_id = n_output_table_id;
     ctx.error = NULL;
     ctx.ofpacts = ofpacts;
     ctx.prereqs = NULL;
@@ -237,8 +242,8 @@ actions_parse(struct lexer *lexer, const struct shash *symtab,
 char * OVS_WARN_UNUSED_RESULT
 actions_parse_string(const char *s, const struct shash *symtab,
                      const struct simap *ports, uint8_t next_table_id,
-                     uint8_t output_table_id, struct ofpbuf *ofpacts,
-                     struct expr **prereqsp)
+                     uint8_t *output_table_id, size_t n_output_table_id,
+                     struct ofpbuf *ofpacts, struct expr **prereqsp)
 {
     struct lexer lexer;
     char *error;
@@ -246,7 +251,8 @@ actions_parse_string(const char *s, const struct shash *symtab,
     lexer_init(&lexer, s);
     lexer_get(&lexer);
     error = actions_parse(&lexer, symtab, ports, next_table_id,
-                          output_table_id, ofpacts, prereqsp);
+                          output_table_id, n_output_table_id,
+                          ofpacts, prereqsp);
     lexer_destroy(&lexer);
 
     return error;
diff --git a/ovn/lib/actions.h b/ovn/lib/actions.h
index 74cd185..dec2ba1 100644
--- a/ovn/lib/actions.h
+++ b/ovn/lib/actions.h
@@ -17,6 +17,7 @@
 #ifndef OVN_ACTIONS_H
 #define OVN_ACTIONS_H 1
 
+#include <unistd.h>
 #include <stdint.h>
 #include "compiler.h"
 
@@ -28,13 +29,13 @@ struct simap;
 
 char *actions_parse(struct lexer *, const struct shash *symtab,
                     const struct simap *ports, uint8_t next_table_id,
-                    uint8_t output_table_id, struct ofpbuf *ofpacts,
-                    struct expr **prereqsp)
+                    uint8_t *output_table_id, size_t n_output_table_id,
+                    struct ofpbuf *ofpacts, struct expr **prereqsp)
     OVS_WARN_UNUSED_RESULT;
 char *actions_parse_string(const char *s, const struct shash *symtab,
                            const struct simap *ports, uint8_t next_table_id,
-                           uint8_t output_table_id, struct ofpbuf *ofpacts,
-                           struct expr **prereqsp)
+                           uint8_t *output_table_id, size_t n_output_table_id,
+                           struct ofpbuf *ofpacts, struct expr **prereqsp)
     OVS_WARN_UNUSED_RESULT;
 
 #endif /* ovn/actions.h */
diff --git a/tests/test-ovn.c b/tests/test-ovn.c
index 60b87de..60b280d 100644
--- a/tests/test-ovn.c
+++ b/tests/test-ovn.c
@@ -1138,8 +1138,9 @@ test_parse_actions(struct ovs_cmdl_context *ctx OVS_UNUSED)
         char *error;
 
         ofpbuf_init(&ofpacts, 0);
-        error = actions_parse_string(ds_cstr(&input), &symtab, &ports, 11, 64,
-                                     &ofpacts, &prereqs);
+        uint8_t output_table_id = 64;
+        error = actions_parse_string(ds_cstr(&input), &symtab, &ports, 11,
+                                     &output_table_id, 1, &ofpacts, &prereqs);
         if (!error) {
             struct ds output;
 
-- 
2.4.3




More information about the dev mailing list