<h2>Logical Switch Datapaths</h2>
- <h3>Ingress Table 0: Admission Control and Ingress Port Security</h3>
+ <h3>Ingress Table 0: Admission Control and Ingress Port Security - L2</h3>
<p>
Ingress table 0 contains these logical flows:
be dropped.
</p>
- <h3>Ingress Table 1: <code>from-lport</code> Pre-ACLs</h3>
+ <h3>Ingress Table 1: Ingress Port Security - IP</h3>
<p>
- Ingress table 1 prepares flows for possible stateful ACL processing
- in table 2. It contains a priority-0 flow that simply moves
- traffic to table 2. If stateful ACLs are used in the logical
+ Ingress table 1 contains these logical flows:
+ </p>
+
+ <ul>
+ <li>
+ <p>
+ For each element in the port security set having one or more IPv4 or
+ IPv6 addresses (or both),
+ </p>
+
+ <ul>
+ <li>
+ Priority 90 flow to allow IPv4 traffic if it has IPv4 addresses
+ which match the <code>inport</code>, valid <code>eth.src</code>
+ and valid <code>ip4.src</code> address(es).
+ </li>
+
+ <li>
+ Priority 90 flow to allow IPv6 traffic if it has IPv6 addresses
+ which match the <code>inport</code>, valid <code>eth.src</code> and
+ valid <code>ip6.src</code> address(es).
+ </li>
+
+ <li>
+ Priority 80 flow to drop IP (both IPv4 and IPv6) traffic which
+ match the <code>inport</code> and valid <code>eth.src</code>.
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ One priority-0 fallback flow that matches all packets and advances to
+ table 2.
+ </li>
+ </ul>
+
+ <h3>Ingress Table 2: Ingress Port Security - Neighbor discovery</h3>
+
+ <p>
+ Ingress table 2 contains these logical flows:
+ </p>
+
+ <ul>
+ <li>
+ <p>
+ For each element in the port security set,
+ </p>
+
+ <ul>
+ <li>
+ Priority 90 flow to allow ARP traffic which match the
+ <code>inport</code> and valid <code>eth.src</code> and
+ <code>arp.sha</code>. If the element has one or more
+ IPv4 addresses, then it also matches the valid
+ <code>arp.spa</code>.
+ </li>
+
+ <li>
+ Priority 90 flow to allow IPv6 Neighbor Solicitation and
+ Advertisement traffic which match the <code>inport</code>,
+ valid <code>eth.src</code> and
+ <code>nd.sll</code>/<code>nd.tll</code>.
+ If the element has one or more IPv6 addresses, then it also
+ matches the valid <code>nd.target</code> address(es) for Neighbor
+ Advertisement traffic.
+ </li>
+
+ <li>
+ Priority 80 flow to drop ARP and IPv6 Neighbor Solicitation and
+ Advertisement traffic which match the <code>inport</code> and
+ valid <code>eth.src</code>.
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ One priority-0 fallback flow that matches all packets and advances to
+ table 3.
+ </li>
+ </ul>
+
+ <h3>Ingress Table 3: <code>from-lport</code> Pre-ACLs</h3>
+
+ <p>
+ Ingress table 3 prepares flows for possible stateful ACL processing
+ in table 4. It contains a priority-0 flow that simply moves
+ traffic to table 4. 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 table 2.
+ the connection tracker before advancing to table 4.
</p>
- <h3>Ingress table 2: <code>from-lport</code> ACLs</h3>
+ <h3>Ingress table 4: <code>from-lport</code> ACLs</h3>
<p>
Logical flows in this table closely reproduce those in the
</p>
<p>
- Ingress table 2 also contains a priority 0 flow with action
+ Ingress table 4 also contains a priority 0 flow with action
<code>next;</code>, so that ACLs allow packets by default. If the
logical datapath has a statetful ACL, the following flows will
also be added:
</li>
</ul>
- <h3>Ingress Table 3: Destination Lookup</h3>
+ <h3>Ingress Table 5: ARP responder</h3>
+
+ <p>
+ This table implements ARP responder for known IPs. It contains these
+ logical flows:
+ </p>
+
+ <ul>
+ <li>
+ Priority-100 flows to skip ARP responder if inport is of type
+ <code>localnet</code>, and advances directly to table 6.
+ </li>
+
+ <li>
+ <p>
+ Priority-50 flows that matches ARP requests to each known IP address
+ <var>A</var> of logical port <var>P</var>, and respond with ARP
+ replies directly with corresponding Ethernet address <var>E</var>:
+ </p>
+
+ <pre>
+eth.dst = eth.src;
+eth.src = <var>E</var>;
+arp.op = 2; /* ARP reply. */
+arp.tha = arp.sha;
+arp.sha = <var>E</var>;
+arp.tpa = arp.spa;
+arp.spa = <var>A</var>;
+outport = <var>P</var>;
+inport = ""; /* Allow sending out inport. */
+output;
+ </pre>
+
+ <p>
+ These flows are omitted for logical ports (other than router ports)
+ that are down.
+ </p>
+ </li>
+
+ <li>
+ One priority-0 fallback flow that matches all packets and advances to
+ table 6.
+ </li>
+ </ul>
+
+ <h3>Ingress Table 6: Destination Lookup</h3>
<p>
This table implements switching behavior. It contains these logical
<h3>Egress Table 0: <code>to-lport</code> Pre-ACLs</h3>
<p>
- This is similar to ingress table 1 except for <code>to-lport</code>
+ This is similar to ingress table 3 except for <code>to-lport</code>
traffic.
</p>
<h3>Egress Table 1: <code>to-lport</code> ACLs</h3>
<p>
- This is similar to ingress table 2 except for <code>to-lport</code> ACLs.
+ This is similar to ingress table 4 except for <code>to-lport</code> ACLs.
</p>
- <h3>Egress Table 2: Egress Port Security</h3>
+ <h3>Egress Table 2: Egress Port Security - IP</h3>
+
+ <p>
+ This is similar to the ingress port security logic in table 1 except
+ that <code>outport</code>, <code>eth.dst</code>, <code>ip4.dst</code>
+ and <code>ip6.dst</code> are checked instead of <code>inport</code>,
+ <code>eth.src</code>, <code>ip4.src</code> and <code>ip6.src</code>
+ </p>
+
+ <h3>Egress Table 3: Egress Port Security - L2</h3>
<p>
This is similar to the ingress port security logic in ingress table 0,
<pre>
ip4.dst = ip4.src;
ip4.src = <var>S</var>;
-ip4.ttl = 255;
+ip.ttl = 255;
icmp4.type = 0;
+inport = ""; /* Allow sending out inport. */
next;
</pre>
each individual <code>inport</code>, and use the same actions in
which <var>S</var> is a function of <code>inport</code>.
</p>
-
- <p>
- Not yet implemented.
- </p>
</li>
<li>
<p>
- ARP reply. These flows reply to ARP requests for the router's own IP
- address. For each router port <var>P</var> that owns IP address
- <var>A</var> and Ethernet address <var>E</var>, a priority-90 flow
- matches <code>inport == <var>P</var> && arp.tpa ==
- <var>A</var> && arp.op == 1</code> (ARP request) with the
- following actions:
+ Reply to ARP requests. These flows reply to ARP requests for the
+ router's own IP address. For each router port <var>P</var> that owns
+ IP address <var>A</var> and Ethernet address <var>E</var>, a
+ priority-90 flow matches <code>inport == <var>P</var> &&
+ arp.op == 1 && arp.tpa == <var>A</var></code> (ARP request)
+ with the following actions:
</p>
<pre>
arp.tpa = arp.spa;
arp.spa = <var>A</var>;
outport = <var>P</var>;
-inport = \"\"; /* Allow sending out inport. */
+inport = ""; /* Allow sending out inport. */
output;
</pre>
</li>
+ <li>
+ ARP reply handling. These flows use ARP replies to populate the
+ logical router's ARP table. A priority-90 flow with match <code>arp.op
+ == 2</code> has actions <code>put_arp(inport, arp.spa,
+ arp.sha);</code>.
+ </li>
+
<li>
<p>
UDP port unreachable. Priority-80 flows generate ICMP port
<p>
ICMP time exceeded. For each router port <var>P</var>, whose IP
address is <var>A</var>, a priority-40 flow with match <code>inport
- == <var>P</var> && ip4.ttl == {0, 1} &&
+ == <var>P</var> && ip.ttl == {0, 1} &&
!ip.later_frag</code> matches packets whose TTL has expired, with the
following actions to send an ICMP time exceeded reply:
</p>
icmp4.code = 0; /* TTL exceeded in transit. */
ip4.dst = ip4.src;
ip4.src = <var>A</var>;
- ip4.ttl = 255;
+ ip.ttl = 255;
next;
};
</pre>
</li>
<li>
- TTL discard. A priority-30 flow with match <code>ip4.ttl == {0,
+ TTL discard. A priority-30 flow with match <code>ip.ttl == {0,
1}</code> and actions <code>drop;</code> drops other packets whose TTL
has expired, that should not receive a ICMP error reply (i.e. fragments
with nonzero offset).
to the address in <code>ip4.dst</code>. This table implements IP
routing, setting <code>reg0</code> to the next-hop IP address (leaving
<code>ip4.dst</code>, the packet's final destination, unchanged) and
- advances to the next table for ARP resolution.
+ advances to the next table for ARP resolution. It also sets
+ <code>reg1</code> to the IP address owned by the selected router port
+ (which is used later in table 4 as the IP source address for an ARP
+ request, if needed).
</p>
<p>
<li>
<p>
Routing table. For each route to IPv4 network <var>N</var> with
- netmask <var>M</var>, a logical flow with match <code>ip4.dst ==
+ netmask <var>M</var>, on router port <var>P</var> with IP address
+ <var>A</var> and Ethernet
+ address <var>E</var>, a logical flow with match <code>ip4.dst ==
<var>N</var>/<var>M</var></code>, whose priority is the number of
1-bits in <var>M</var>, has the following actions:
</p>
<pre>
-ip4.ttl--;
+ip.ttl--;
reg0 = <var>G</var>;
+reg1 = <var>A</var>;
+eth.src = <var>E</var>;
+outport = <var>P</var>;
next;
</pre>
<p>
- (Ingress table 1 already verified that <code>ip4.ttl--;</code> will
+ (Ingress table 1 already verified that <code>ip.ttl--;</code> will
not yield a TTL exceeded error.)
</p>
icmp4.code = 0; /* Network unreachable. */
ip4.dst = ip4.src;
ip4.src = <var>A</var>;
- ip4.ttl = 255;
+ ip.ttl = 255;
next(2);
};
</pre>
<ul>
<li>
<p>
- Known MAC bindings. For each IP address <var>A</var> whose host is
- known to have Ethernet address <var>HE</var> and reside on router
- port <var>P</var> with Ethernet address <var>PE</var>, a priority-200
- flow with match <code>reg0 == <var>A</var></code> has the following
- actions:
+ Static MAC bindings. MAC bindings can be known statically based on
+ data in the <code>OVN_Northbound</code> database. For router ports
+ connected to logical switches, MAC bindings can be known statically
+ from the <code>addresses</code> column in the
+ <code>Logical_Port</code> table. For router ports connected to other
+ logical routers, MAC bindings can be known statically from the
+ <code>mac</code> and <code>network</code> column in the
+ <code>Logical_Router_Port</code> table.
</p>
- <pre>
-eth.src = <var>PE</var>;
-eth.dst = <var>HE</var>;
-outport = <var>P</var>;
-output;
- </pre>
+ <p>
+ For each IP address <var>A</var> whose host is known to have Ethernet
+ address <var>E</var> on router port <var>P</var>, a priority-100 flow
+ with match <code>outport === <var>P</var> && reg0 ==
+ <var>A</var></code> has actions <code>eth.dst = <var>E</var>;
+ next;</code>.
+ </p>
+ </li>
+ <li>
<p>
- MAC bindings can be known statically based on data in the
- <code>OVN_Northbound</code> database. For router ports connected to
- logical switches, MAC bindings can be known statically from the
- <code>addresses</code> column in the <code>Logical_Port</code> table.
- For router ports connected to other logical routers, MAC bindings can
- be known statically from the <code>mac</code> and
- <code>network</code> column in the <code>Logical_Router_Port</code>
- table.
+ Dynamic MAC bindings. This flows resolves MAC-to-IP bindings that
+ have become known dynamically through ARP. (The next table will
+ issue an ARP request for cases where the binding is not yet known.)
+ </p>
+
+ <p>
+ A priority-0 logical flow with match <code>1</code> has actions
+ <code>get_arp(outport, reg0); next;</code>.
</p>
</li>
+ </ul>
+
+ <h3>Ingress Table 4: ARP Request</h3>
+
+ <p>
+ In the common case where the Ethernet destination has been resolved, this
+ table outputs the packet. Otherwise, it composes and sends an ARP
+ request. It holds the following flows:
+ </p>
+ <ul>
<li>
<p>
- Unknown MAC bindings. For each non-gateway route to IPv4 network
- <var>N</var> with netmask <var>M</var> on router port <var>P</var>
- that owns IP address <var>A</var> and Ethernet address <var>E</var>,
- a logical flow with match <code>ip4.dst ==
- <var>N</var>/<var>M</var></code>, whose priority is the number of
- 1-bits in <var>M</var>, has the following actions:
+ Unknown MAC address. A priority-100 flow with match <code>eth.dst ==
+ 00:00:00:00:00:00</code> has the following actions:
</p>
<pre>
arp {
eth.dst = ff:ff:ff:ff:ff:ff;
- eth.src = <var>E</var>;
- arp.sha = <var>E</var>;
- arp.tha = 00:00:00:00:00:00;
- arp.spa = <var>A</var>;
- arp.tpa = ip4.dst;
+ arp.spa = reg1;
arp.op = 1; /* ARP request. */
- outport = <var>P</var>;
output;
};
</pre>
<p>
- TBD: How to install MAC bindings when an ARP response comes back.
- (Implement a "learn" action?)
+ (Ingress table 2 initialized <code>reg1</code> with the IP address
+ owned by <code>outport</code>.)
</p>
<p>
- Not yet implemented.
+ The IP packet that triggers the ARP request is dropped.
</p>
</li>
+
+ <li>
+ Known MAC address. A priority-0 flow with match <code>1</code> has
+ actions <code>output;</code>.
+ </li>
</ul>
<h3>Egress Table 0: Delivery</h3>