[ovs-dev] [RFC 4/8] ovn-northd: Introduce stateful table.

Gurucharan Shetty guru at ovn.org
Mon Feb 29 06:33:20 UTC 2016


Currently, the only use of stateful services in conntrack is
OVN ACLs. In table ACL, we commit the packet to conntrack
via ct_commit action.

As we introduce more stateful services, the ACL feature will
have to share the conntrack module with others. As
preparation for more stateful features like NAT and
loadbalancing, this commit introduces a new stateful table
that is responsible to commit packets to conntrack via
ct_commit action. If ACL table needs to commit a packet,
it sets 'reg1' as 1. Stateful table in-turn will commit
the packet if 'reg1' is 1.

Signed-off-by: Gurucharan Shetty <guru at ovn.org>
---
 ovn/northd/ovn-northd.8.xml | 33 ++++++++++++++++++++++++---------
 ovn/northd/ovn-northd.c     | 31 +++++++++++++++++++++++++------
 2 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index eb80cc0..b764848 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -168,9 +168,10 @@
       for the <code>from-lport</code> direction.  <code>allow</code>
       ACLs translate into logical flows with the <code>next;</code>
       action, <code>allow-related</code> ACLs translate into logical
-      flows with the <code>ct_next;</code> action, other ACLs translate
-      to <code>drop;</code>.  The <code>priority</code> values from the
-      <code>ACL</code> table are used directly.
+      flows with the <code>reg1 = 1;</code> action (which acts as a hint
+      for the next tables to commit the connection to conntrack), other ACLs
+      translate to <code>drop;</code>.  The <code>priority</code> values from
+      the <code>ACL</code> table are used directly.
     </p>
 
     <p>
@@ -182,11 +183,11 @@
 
     <ul>
       <li>
-        A priority-1 flow to commit IP traffic to the connection
-        tracker.  This is needed for the default allow policy because,
-        while the initiater's direction may not have any stateful rules,
-        the server's may and then its return traffic would not be known
-        and marked as invalid.
+        A priority-1 flow that sets the hint to commit IP traffic to the
+        connection tracker (by setting 'reg1 = 1').  This is needed for the
+        default allow policy because, while the initiater's direction may not
+        have any stateful rules, the server's may and then its return traffic
+        would not be known and marked as invalid.
       </li>
 
       <li>
@@ -206,7 +207,15 @@
       </li>
     </ul>
 
-    <h3>Ingress Table 4: Destination Lookup</h3>
+    <h3>Ingress Table 4: STATEFUL</h3>
+
+    <p>
+      It contains a priority-0 flow that simply moves traffic to table 5.
+      A priority-100 flow commits packets to connection tracker based on a hint
+      provided by the previous tables (with a match for reg1 == 1).
+    </p>
+
+    <h3>Ingress Table 5: Destination Lookup</h3>
 
     <p>
       This table implements switching behavior.  It contains these logical
@@ -274,6 +283,12 @@ output;
       This is similar to ingress table 3 except for <code>to-lport</code> ACLs.
     </p>
 
+    <h3>Egress Table 3: STATEFUL</h3>
+
+    <p>
+      This is similar to ingress table 4.
+    </p>
+
     <h3>Egress Table 4: Egress Port Security</h3>
 
     <p>
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index ed7852a..9e30bc0 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -89,13 +89,15 @@ enum ovn_stage {
     PIPELINE_STAGE(SWITCH, IN,  PRE_ACL,      1, "ls_in_pre_acl")       \
     PIPELINE_STAGE(SWITCH, IN,  PRE_STATEFUL, 2, "ls_in_pre_stateful")  \
     PIPELINE_STAGE(SWITCH, IN,  ACL,          3, "ls_in_acl")           \
-    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,      4, "ls_in_l2_lkup")       \
+    PIPELINE_STAGE(SWITCH, IN,  STATEFUL,     4, "ls_in_stateful")      \
+    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,      5, "ls_in_l2_lkup")       \
                                                                         \
     /* Logical switch egress stages. */                                 \
     PIPELINE_STAGE(SWITCH, OUT, PRE_ACL,      0, "ls_out_pre_acl")      \
     PIPELINE_STAGE(SWITCH, OUT, PRE_STATEFUL, 1, "ls_out_pre_stateful") \
     PIPELINE_STAGE(SWITCH, OUT, ACL,          2, "ls_out_acl")          \
-    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC,     3, "ls_out_port_sec")     \
+    PIPELINE_STAGE(SWITCH, OUT, STATEFUL,     3, "ls_out_stateful")     \
+    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC,     4, "ls_out_port_sec")     \
                                                                         \
     /* Logical router ingress stages. */                                \
     PIPELINE_STAGE(ROUTER, IN,  ADMISSION,   0, "lr_in_admission")      \
@@ -1058,9 +1060,9 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows)
          * and then its return traffic would not have an associated
          * conntrack entry and would return "+invalid". */
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, 1, "ip",
-                      "ct_commit; next;");
+                      "reg1 = 1; next;");
         ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, 1, "ip",
-                      "ct_commit; next;");
+                      "reg1 = 1; next;");
 
         /* Ingress and Egress ACL Table (Priority 65535).
          *
@@ -1113,7 +1115,7 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows)
              * direction may not have any stateful rules, the server's
              * may and then its return traffic would not have an
              * associated conntrack entry and would return "+invalid". */
-            const char *actions = has_stateful ? "ct_commit; next;" : "next;";
+            const char *actions = has_stateful ? "reg1 = 1; next;" : "next;";
             ovn_lflow_add(lflows, od, stage,
                           acl->priority + OVN_ACL_PRI_OFFSET,
                           acl->match, actions);
@@ -1126,7 +1128,7 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows)
             ds_put_format(&match, "ct.new && (%s)", acl->match);
             ovn_lflow_add(lflows, od, stage,
                           acl->priority + OVN_ACL_PRI_OFFSET,
-                          ds_cstr(&match), "ct_commit; next;");
+                          ds_cstr(&match), "reg1 = 1; next;");
 
             ds_destroy(&match);
         } else if (!strcmp(acl->action, "drop")) {
@@ -1144,6 +1146,22 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows)
 }
 
 static void
+build_stateful(struct ovn_datapath *od, struct hmap *lflows)
+{
+    /* Ingress and Egress STATEFUL Table (Priority 0): Packets are
+     * allowed by default. */
+    ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 0, "1", "next;");
+    ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 0, "1", "next;");
+
+    /* If reg1 is set as 1, then the packets should be committed to
+     * conntrack. */
+    ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100, "reg1 == 1",
+                  "ct_commit; next;");
+    ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 100, "reg1 == 1",
+                  "ct_commit; next;");
+}
+
+static void
 build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                     struct hmap *lflows, struct hmap *mcgroups)
 {
@@ -1161,6 +1179,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         build_pre_acls(od, lflows, ports);
         build_pre_stateful(od, lflows);
         build_acls(od, lflows);
+        build_stateful(od, lflows);
     }
 
     /* Logical switch ingress table 0: Admission control framework (priority
-- 
1.9.1




More information about the dev mailing list