ovn: Add l3 port security for IPv4 and IPv6
[cascardo/ovs.git] / ovn / northd / ovn-northd.8.xml
index 4bd1990..7954e22 100644 (file)
 
     <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>
 
@@ -348,20 +487,16 @@ next;
           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> &amp;&amp; arp.tpa ==
-          <var>A</var> &amp;&amp; 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> &amp;&amp;
+          arp.op == 1 &amp;&amp; arp.tpa == <var>A</var></code> (ARP request)
+          with the following actions:
         </p>
 
         <pre>
@@ -373,11 +508,18 @@ arp.sha = <var>E</var>;
 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
@@ -460,7 +602,7 @@ output;
         <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> &amp;&amp; ip4.ttl == {0, 1} &amp;&amp;
+          == <var>P</var> &amp;&amp; ip.ttl == {0, 1} &amp;&amp;
           !ip.later_frag</code> matches packets whose TTL has expired, with the
           following actions to send an ICMP time exceeded reply:
         </p>
@@ -471,7 +613,7 @@ icmp4 {
     icmp4.code = 0;  /* TTL exceeded in transit. */
     ip4.dst = ip4.src;
     ip4.src = <var>A</var>;
-    ip4.ttl = 255;
+    ip.ttl = 255;
     next;
 };
         </pre>
@@ -482,7 +624,7 @@ icmp4 {
       </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).
@@ -502,7 +644,10 @@ icmp4 {
       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>
@@ -513,19 +658,24 @@ icmp4 {
       <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>
 
@@ -549,7 +699,7 @@ icmp4 {
     icmp4.code = 0; /* Network unreachable. */
     ip4.dst = ip4.src;
     ip4.src = <var>A</var>;
-    ip4.ttl = 255;
+    ip.ttl = 255;
     next(2);
 };
         </pre>
@@ -579,65 +729,77 @@ icmp4 {
     <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> &amp;&amp; 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>