This table prepares flows for possible stateful ACL processing in
ingress table <code>ACLs</code>. It contains a priority-0 flow that
simply moves traffic to the next table. If stateful ACLs are used in the
- logical datapath, a priority-100 flow is added that sends IP packets to
- the connection tracker before advancing to ingress table
- <code>ACLs</code>.
+ logical datapath, a priority-100 flow is added that sets a hint
+ (with <code>reg0[0] = 1; next;</code>) for table
+ <code>Pre-stateful</code> to send IP packets to the connection tracker
+ before eventually advancing to ingress table <code>ACLs</code>.
</p>
- <h3>Ingress table 4: <code>from-lport</code> ACLs</h3>
+ <h3>Ingress Table 4: Pre-stateful</h3>
+
+ <p>
+ This table prepares flows for all possible stateful processing
+ in next tables. It contains a priority-0 flow that simply moves
+ traffic to the next table. A priority-100 flow sends the packets to
+ connection tracker based on a hint provided by the previous tables
+ (with a match for <code>reg0[0] == 1</code>) by using the
+ <code>ct_next;</code> action.
+ </p>
+
+ <h3>Ingress table 5: <code>from-lport</code> ACLs</h3>
<p>
Logical flows in this table closely reproduce those in the
</li>
</ul>
- <h3>Ingress Table 5: ARP responder</h3>
+ <h3>Ingress Table 6: ARP responder</h3>
<p>
This table implements ARP responder for known IPs. It contains these
</li>
</ul>
- <h3>Ingress Table 6: Destination Lookup</h3>
+ <h3>Ingress Table 7: Destination Lookup</h3>
<p>
This table implements switching behavior. It contains these logical
<code>to-lport</code> traffic.
</p>
- <h3>Egress Table 1: <code>to-lport</code> ACLs</h3>
+ <h3>Egress Table 1: Pre-stateful</h3>
+
+ <p>
+ This is similar to ingress table <code>Pre-stateful</code>.
+ </p>
+
+ <h3>Egress Table 2: <code>to-lport</code> ACLs</h3>
<p>
This is similar to ingress table <code>ACLs</code> except for
<code>to-lport</code> ACLs.
</p>
- <h3>Egress Table 2: Egress Port Security - IP</h3>
+ <h3>Egress Table 3: Egress Port Security - IP</h3>
<p>
This is similar to the port security logic in table
<code>ip4.src</code> and <code>ip6.src</code>
</p>
- <h3>Egress Table 3: Egress Port Security - L2</h3>
+ <h3>Egress Table 4: Egress Port Security - L2</h3>
<p>
This is similar to the ingress port security logic in ingress table
PIPELINE_STAGE(SWITCH, IN, PORT_SEC_IP, 1, "ls_in_port_sec_ip") \
PIPELINE_STAGE(SWITCH, IN, PORT_SEC_ND, 2, "ls_in_port_sec_nd") \
PIPELINE_STAGE(SWITCH, IN, PRE_ACL, 3, "ls_in_pre_acl") \
- PIPELINE_STAGE(SWITCH, IN, ACL, 4, "ls_in_acl") \
- PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 5, "ls_in_arp_nd_rsp") \
- PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 6, "ls_in_l2_lkup") \
+ PIPELINE_STAGE(SWITCH, IN, PRE_STATEFUL, 4, "ls_in_pre_stateful") \
+ PIPELINE_STAGE(SWITCH, IN, ACL, 5, "ls_in_acl") \
+ PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 6, "ls_in_arp_nd_rsp") \
+ PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 7, "ls_in_l2_lkup") \
\
/* Logical switch egress stages. */ \
- PIPELINE_STAGE(SWITCH, OUT, PRE_ACL, 0, "ls_out_pre_acl") \
- PIPELINE_STAGE(SWITCH, OUT, ACL, 1, "ls_out_acl") \
- PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_IP, 2, "ls_out_port_sec_ip") \
- PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2, 3, "ls_out_port_sec_l2") \
+ 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_IP, 3, "ls_out_port_sec_ip") \
+ PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2, 4, "ls_out_port_sec_l2") \
\
/* Logical router ingress stages. */ \
PIPELINE_STAGE(ROUTER, IN, ADMISSION, 0, "lr_in_admission") \
* priority to determine the ACL's logical flow priority. */
#define OVN_ACL_PRI_OFFSET 1000
+#define REGBIT_CONNTRACK_DEFRAG "reg0[0]"
+
/* Returns an "enum ovn_stage" built from the arguments. */
static enum ovn_stage
ovn_stage_build(enum ovn_datapath_type dp_type, enum ovn_pipeline pipeline,
*
* Regardless of whether the ACL is "from-lport" or "to-lport",
* we need rules in both the ingress and egress table, because
- * the return traffic needs to be followed. */
- ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 100, "ip", "ct_next;");
- ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 100, "ip", "ct_next;");
+ * the return traffic needs to be followed.
+ *
+ * 'REGBIT_CONNTRACK_DEFRAG' is set to let the pre-stateful table send
+ * it to conntrack for tracking and defragmentation. */
+ ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 100, "ip",
+ REGBIT_CONNTRACK_DEFRAG" = 1; next;");
+ ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 100, "ip",
+ REGBIT_CONNTRACK_DEFRAG" = 1; next;");
}
}
+static void
+build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows)
+{
+ /* Ingress and Egress pre-stateful Table (Priority 0): Packets are
+ * allowed by default. */
+ ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 0, "1", "next;");
+ ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 0, "1", "next;");
+
+ /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be
+ * sent to conntrack for tracking and defragmentation. */
+ ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 100,
+ REGBIT_CONNTRACK_DEFRAG" == 1", "ct_next;");
+ ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 100,
+ REGBIT_CONNTRACK_DEFRAG" == 1", "ct_next;");
+}
+
static void
build_acls(struct ovn_datapath *od, struct hmap *lflows)
{
}
build_pre_acls(od, lflows, ports);
+ build_pre_stateful(od, lflows);
build_acls(od, lflows);
}