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_commit; next;</code> actions, other ACLs
- translate to <code>drop;</code>. The <code>priority</code> values
- from the <code>ACL</code> table have a limited range and have 1000
+ flows with the <code>reg0[1] = 1; next;</code> actions (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 have a limited range and have 1000
added to them to leave room for OVN default flows at both higher
and lower priorities.
</p>
<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 (with action <code>reg0[1] = 1; next;</code>). This
+ is needed for the default allow policy because, while the initiator'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>
</li>
</ul>
- <h3>Ingress Table 6: ARP responder</h3>
+ <h3>Ingress Table 6: Stateful</h3>
+
+ <p>
+ It contains a priority-0 flow that simply moves traffic to the next
+ table. A priority-100 flow commits packets to connection tracker using
+ <code>ct_commit; next;</code> action based on a hint provided by
+ the previous tables (with a match for <code>reg0[1] == 1</code>).
+ </p>
+
+ <h3>Ingress Table 7: ARP responder</h3>
<p>
This table implements ARP responder for known IPs. It contains these
</li>
</ul>
- <h3>Ingress Table 7: Destination Lookup</h3>
+ <h3>Ingress Table 8: Destination Lookup</h3>
<p>
This table implements switching behavior. It contains these logical
<code>to-lport</code> ACLs.
</p>
- <h3>Egress Table 3: Egress Port Security - IP</h3>
+ <h3>Egress Table 3: Stateful</h3>
+
+ <p>
+ This is similar to ingress table <code>Stateful</code>.
+ </p>
+
+ <h3>Egress Table 4: 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 4: Egress Port Security - L2</h3>
+ <h3>Egress Table 5: Egress Port Security - L2</h3>
<p>
This is similar to the ingress port security logic in ingress table
PIPELINE_STAGE(SWITCH, IN, PRE_ACL, 3, "ls_in_pre_acl") \
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") \
+ PIPELINE_STAGE(SWITCH, IN, STATEFUL, 6, "ls_in_stateful") \
+ PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 7, "ls_in_arp_nd_rsp") \
+ PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 8, "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_IP, 3, "ls_out_port_sec_ip") \
- PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2, 4, "ls_out_port_sec_l2") \
+ PIPELINE_STAGE(SWITCH, OUT, ACL, 2, "ls_out_acl") \
+ PIPELINE_STAGE(SWITCH, OUT, STATEFUL, 3, "ls_out_stateful") \
+ PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_IP, 4, "ls_out_port_sec_ip") \
+ PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2, 5, "ls_out_port_sec_l2") \
\
/* Logical router ingress stages. */ \
PIPELINE_STAGE(ROUTER, IN, ADMISSION, 0, "lr_in_admission") \
#define OVN_ACL_PRI_OFFSET 1000
#define REGBIT_CONNTRACK_DEFRAG "reg0[0]"
+#define REGBIT_CONNTRACK_COMMIT "reg0[1]"
/* Returns an "enum ovn_stage" built from the arguments. */
static enum ovn_stage
* 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;");
+ REGBIT_CONNTRACK_COMMIT" = 1; next;");
ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, 1, "ip",
- "ct_commit; next;");
+ REGBIT_CONNTRACK_COMMIT" = 1; next;");
/* Ingress and Egress ACL Table (Priority 65535).
*
* 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
+ ? REGBIT_CONNTRACK_COMMIT" = 1; next;"
+ : "next;";
ovn_lflow_add(lflows, od, stage,
acl->priority + OVN_ACL_PRI_OFFSET,
acl->match, actions);
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),
+ REGBIT_CONNTRACK_COMMIT" = 1; next;");
ds_destroy(&match);
} else if (!strcmp(acl->action, "drop")) {
}
}
+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 REGBIT_CONNTRACK_COMMIT is set as 1, then the packets should be
+ * committed to conntrack. */
+ ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
+ REGBIT_CONNTRACK_COMMIT" == 1", "ct_commit; next;");
+ ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 100,
+ REGBIT_CONNTRACK_COMMIT" == 1", "ct_commit; next;");
+}
+
static void
build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
struct hmap *lflows, struct hmap *mcgroups)
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