diff mbox

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

Message ID 1456727604-15784-5-git-send-email-guru@ovn.org
State Changes Requested
Headers show

Commit Message

Gurucharan Shetty Feb. 29, 2016, 6:33 a.m. UTC
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@ovn.org>
---
 ovn/northd/ovn-northd.8.xml | 33 ++++++++++++++++++++++++---------
 ovn/northd/ovn-northd.c     | 31 +++++++++++++++++++++++++------
 2 files changed, 49 insertions(+), 15 deletions(-)

Comments

Ben Pfaff March 14, 2016, 5:59 p.m. UTC | #1
On Sun, Feb 28, 2016 at 10:33:20PM -0800, Gurucharan Shetty wrote:
> 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@ovn.org>

I am still not sure why STATEFUL is written in all-caps.

We will use up registers very quickly if we use them this way.  It is
easy to use individual bits as flags.  Did you consider using, for
example, reg0[0] and reg0[1] instead of all of reg0 and reg1 for these
hints?

Acked-by: Ben Pfaff <blp@ovn.org>
diff mbox

Patch

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