Provided by: ovn-central_2.9.8-0ubuntu0.18.04.5_amd64 

NAME
ovn-northd - Open Virtual Network central control daemon
SYNOPSIS
ovn-northd [options]
DESCRIPTION
ovn-northd is a centralized daemon responsible for translating the high-level OVN configuration into
logical configuration consumable by daemons such as ovn-controller. It translates the logical network
configuration in terms of conventional network concepts, taken from the OVN Northbound Database (see
ovn-nb(5)), into logical datapath flows in the OVN Southbound Database (see ovn-sb(5)) below it.
OPTIONS
--ovnnb-db=database
The OVSDB database containing the OVN Northbound Database. If the OVN_NB_DB environment variable
is set, its value is used as the default. Otherwise, the default is
unix:/var/run/openvswitch/ovnnb_db.sock.
--ovnsb-db=database
The OVSDB database containing the OVN Southbound Database. If the OVN_SB_DB environment variable
is set, its value is used as the default. Otherwise, the default is
unix:/var/run/openvswitch/ovnsb_db.sock.
database in the above options must be an OVSDB active or passive connection method, as described in
ovsdb(7).
Daemon Options
--pidfile[=pidfile]
Causes a file (by default, program.pid) to be created indicating the PID of the running process.
If the pidfile argument is not specified, or if it does not begin with /, then it is created in
/var/run/openvswitch.
If --pidfile is not specified, no pidfile is created.
--overwrite-pidfile
By default, when --pidfile is specified and the specified pidfile already exists and is locked by
a running process, the daemon refuses to start. Specify --overwrite-pidfile to cause it to instead
overwrite the pidfile.
When --pidfile is not specified, this option has no effect.
--detach
Runs this program as a background process. The process forks, and in the child it starts a new
session, closes the standard file descriptors (which has the side effect of disabling logging to
the console), and changes its current directory to the root (unless --no-chdir is specified).
After the child completes its initialization, the parent exits.
--monitor
Creates an additional process to monitor this program. If it dies due to a signal that indicates a
programming error (SIGABRT, SIGALRM, SIGBUS, SIGFPE, SIGILL, SIGPIPE, SIGSEGV, SIGXCPU, or
SIGXFSZ) then the monitor process starts a new copy of it. If the daemon dies or exits for another
reason, the monitor process exits.
This option is normally used with --detach, but it also functions without it.
--no-chdir
By default, when --detach is specified, the daemon changes its current working directory to the
root directory after it detaches. Otherwise, invoking the daemon from a carelessly chosen
directory would prevent the administrator from unmounting the file system that holds that
directory.
Specifying --no-chdir suppresses this behavior, preventing the daemon from changing its current
working directory. This may be useful for collecting core files, since it is common behavior to
write core dumps into the current working directory and the root directory is not a good directory
to use.
This option has no effect when --detach is not specified.
--no-self-confinement
By default this daemon will try to self-confine itself to work with files under well-known
directories whitelisted at build time. It is better to stick with this default behavior and not to
use this flag unless some other Access Control is used to confine daemon. Note that in contrast to
other access control implementations that are typically enforced from kernel-space (e.g. DAC or
MAC), self-confinement is imposed from the user-space daemon itself and hence should not be
considered as a full confinement strategy, but instead should be viewed as an additional layer of
security.
--user=user:group
Causes this program to run as a different user specified in user:group, thus dropping most of the
root privileges. Short forms user and :group are also allowed, with current user or group assumed,
respectively. Only daemons started by the root user accepts this argument.
On Linux, daemons will be granted CAP_IPC_LOCK and CAP_NET_BIND_SERVICES before dropping root
privileges. Daemons that interact with a datapath, such as ovs-vswitchd, will be granted two
additional capabilities, namely CAP_NET_ADMIN and CAP_NET_RAW. The capability change will apply
even if the new user is root.
On Windows, this option is not currently supported. For security reasons, specifying this option
will cause the daemon process not to start.
Logging Options
-v[spec]
--verbose=[spec]
Sets logging levels. Without any spec, sets the log level for every module and destination to dbg.
Otherwise, spec is a list of words separated by spaces or commas or colons, up to one from each
category below:
• A valid module name, as displayed by the vlog/list command on ovs-appctl(8), limits the log
level change to the specified module.
• syslog, console, or file, to limit the log level change to only to the system log, to the
console, or to a file, respectively. (If --detach is specified, the daemon closes its
standard file descriptors, so logging to the console will have no effect.)
On Windows platform, syslog is accepted as a word and is only useful along with the
--syslog-target option (the word has no effect otherwise).
• off, emer, err, warn, info, or dbg, to control the log level. Messages of the given severity
or higher will be logged, and messages of lower severity will be filtered out. off filters
out all messages. See ovs-appctl(8) for a definition of each log level.
Case is not significant within spec.
Regardless of the log levels set for file, logging to a file will not take place unless --log-file
is also specified (see below).
For compatibility with older versions of OVS, any is accepted as a word but has no effect.
-v
--verbose
Sets the maximum logging verbosity level, equivalent to --verbose=dbg.
-vPATTERN:destination:pattern
--verbose=PATTERN:destination:pattern
Sets the log pattern for destination to pattern. Refer to ovs-appctl(8) for a description of the
valid syntax for pattern.
-vFACILITY:facility
--verbose=FACILITY:facility
Sets the RFC5424 facility of the log message. facility can be one of kern, user, mail, daemon, auth,
syslog, lpr, news, uucp, clock, ftp, ntp, audit, alert, clock2, local0, local1, local2, local3,
local4, local5, local6 or local7. If this option is not specified, daemon is used as the default for
the local system syslog and local0 is used while sending a message to the target provided via the
--syslog-target option.
--log-file[=file]
Enables logging to a file. If file is specified, then it is used as the exact name for the log file.
The default log file name used if file is omitted is /var/log/openvswitch/program.log.
--syslog-target=host:port
Send syslog messages to UDP port on host, in addition to the system syslog. The host must be a
numerical IP address, not a hostname.
--syslog-method=method
Specify method as how syslog messages should be sent to syslog daemon. The following forms are
supported:
• libc, to use the libc syslog() function. This is the default behavior. Downside of using this
options is that libc adds fixed prefix to every message before it is actually sent to the
syslog daemon over /dev/log UNIX domain socket.
• unix:file, to use a UNIX domain socket directly. It is possible to specify arbitrary message
format with this option. However, rsyslogd 8.9 and older versions use hard coded parser
function anyway that limits UNIX domain socket use. If you want to use arbitrary message
format with older rsyslogd versions, then use UDP socket to localhost IP address instead.
• udp:ip:port, to use a UDP socket. With this method it is possible to use arbitrary message
format also with older rsyslogd. When sending syslog messages over UDP socket extra
precaution needs to be taken into account, for example, syslog daemon needs to be configured
to listen on the specified UDP port, accidental iptables rules could be interfering with
local syslog traffic and there are some security considerations that apply to UDP sockets,
but do not apply to UNIX domain sockets.
PKI Options
PKI configuration is required in order to use SSL for the connections to the Northbound and Southbound
databases.
-p privkey.pem
--private-key=privkey.pem
Specifies a PEM file containing the private key used as identity for outgoing SSL
connections.
-c cert.pem
--certificate=cert.pem
Specifies a PEM file containing a certificate that certifies the private key specified on -p
or --private-key to be trustworthy. The certificate must be signed by the certificate
authority (CA) that the peer in SSL connections will use to verify it.
-C cacert.pem
--ca-cert=cacert.pem
Specifies a PEM file containing the CA certificate for verifying certificates presented to
this program by SSL peers. (This may be the same certificate that SSL peers use to verify the
certificate specified on -c or --certificate, or it may be a different one, depending on the
PKI design in use.)
-C none
--ca-cert=none
Disables verification of certificates presented by SSL peers. This introduces a security
risk, because it means that certificates cannot be verified to be those of known trusted
hosts.
Other Options
--unixctl=socket
Sets the name of the control socket on which program listens for runtime management commands (see
RUNTIME MANAGEMENT COMMANDS, below). If socket does not begin with /, it is interpreted as
relative to /var/run/openvswitch. If --unixctl is not used at all, the default socket is
/var/run/openvswitch/program.pid.ctl, where pid is program’s process ID.
On Windows a local named pipe is used to listen for runtime management commands. A file is created
in the absolute path as pointed by socket or if --unixctl is not used at all, a file is created as
program in the configured OVS_RUNDIR directory. The file exists just to mimic the behavior of a
Unix domain socket.
Specifying none for socket disables the control socket feature.
-h
--help
Prints a brief help message to the console.
-V
--version
Prints version information to the console.
RUNTIME MANAGEMENT COMMANDS
ovs-appctl can send commands to a running ovn-northd process. The currently supported commands are
described below.
exit Causes ovn-northd to gracefully terminate.
ACTIVE-STANDBY FOR HIGH AVAILABILITY
You may run ovn-northd more than once in an OVN deployment. OVN will automatically ensure that only one
of them is active at a time. If multiple instances of ovn-northd are running and the active ovn-northd
fails, one of the hot standby instances of ovn-northd will automatically take over.
LOGICAL FLOW TABLE STRUCTURE
One of the main purposes of ovn-northd is to populate the Logical_Flow table in the OVN_Southbound
database. This section describes how ovn-northd does this for switch and router logical datapaths.
Logical Switch Datapaths
Ingress Table 0: Admission Control and Ingress Port Security - L2
Ingress table 0 contains these logical flows:
• Priority 100 flows to drop packets with VLAN tags or multicast Ethernet source addresses.
• Priority 50 flows that implement ingress port security for each enabled logical port. For
logical ports on which port security is enabled, these match the inport and the valid
eth.src address(es) and advance only those packets to the next flow table. For logical
ports on which port security is not enabled, these advance all packets that match the
inport.
There are no flows for disabled logical ports because the default-drop behavior of logical flow tables
causes packets that ingress from them to be dropped.
Ingress Table 1: Ingress Port Security - IP
Ingress table 1 contains these logical flows:
• For each element in the port security set having one or more IPv4 or IPv6 addresses (or
both),
• Priority 90 flow to allow IPv4 traffic if it has IPv4 addresses which match the
inport, valid eth.src and valid ip4.src address(es).
• Priority 90 flow to allow IPv4 DHCP discovery traffic if it has a valid eth.src.
This is necessary since DHCP discovery messages are sent from the unspecified IPv4
address (0.0.0.0) since the IPv4 address has not yet been assigned.
• Priority 90 flow to allow IPv6 traffic if it has IPv6 addresses which match the
inport, valid eth.src and valid ip6.src address(es).
• Priority 90 flow to allow IPv6 DAD (Duplicate Address Detection) traffic if it has a
valid eth.src. This is is necessary since DAD include requires joining an multicast
group and sending neighbor solicitations for the newly assigned address. Since no
address is yet assigned, these are sent from the unspecified IPv6 address (::).
• Priority 80 flow to drop IP (both IPv4 and IPv6) traffic which match the inport and
valid eth.src.
• One priority-0 fallback flow that matches all packets and advances to the next table.
Ingress Table 2: Ingress Port Security - Neighbor discovery
Ingress table 2 contains these logical flows:
• For each element in the port security set,
• Priority 90 flow to allow ARP traffic which match the inport and valid eth.src and
arp.sha. If the element has one or more IPv4 addresses, then it also matches the
valid arp.spa.
• Priority 90 flow to allow IPv6 Neighbor Solicitation and Advertisement traffic which
match the inport, valid eth.src and nd.sll/nd.tll. If the element has one or more
IPv6 addresses, then it also matches the valid nd.target address(es) for Neighbor
Advertisement traffic.
• Priority 80 flow to drop ARP and IPv6 Neighbor Solicitation and Advertisement
traffic which match the inport and valid eth.src.
• One priority-0 fallback flow that matches all packets and advances to the next table.
Ingress Table 3: from-lport Pre-ACLs
This table prepares flows for possible stateful ACL processing in ingress table ACLs. 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 sets a hint (with reg0[0] = 1; next;) for table Pre-stateful
to send IP packets to the connection tracker before eventually advancing to ingress table ACLs. If
special ports such as route ports or localnet ports can’t use ct(), a priority-110 flow is added to skip
over stateful ACLs.
Ingress Table 4: Pre-LB
This table prepares flows for possible stateful load balancing processing in ingress table LB and
Stateful. It contains a priority-0 flow that simply moves traffic to the next table. If load balancing
rules with virtual IP addresses (and ports) are configured in OVN_Northbound database for a logical
switch datapath, a priority-100 flow is added for each configured virtual IP address VIP. For IPv4 VIPs,
the match is ip && ip4.dst == VIP. For IPv6 VIPs, the match is ip && ip6.dst == VIP. The flow sets an
action reg0[0] = 1; next; to act as a hint for table Pre-stateful to send IP packets to the connection
tracker for packet de-fragmentation before eventually advancing to ingress table LB.
Ingress Table 5: Pre-stateful
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 reg0[0] == 1) by using the
ct_next; action.
Ingress table 6: from-lport ACLs
Logical flows in this table closely reproduce those in the ACL table in the OVN_Northbound database for
the from-lport direction. The priority values from the ACL table have a limited range and have 1000 added
to them to leave room for OVN default flows at both higher and lower priorities.
• allow ACLs translate into logical flows with the next; action. If there are any stateful
ACLs on this datapath, then allow ACLs translate to ct_commit; next; (which acts as a hint
for the next tables to commit the connection to conntrack),
• allow-related ACLs translate into logical flows with the ct_commit(ct_label=0/1); next;
actions for new connections and reg0[1] = 1; next; for existing connections.
• Other ACLs translate to drop; for new or untracked connections and ct_commit(ct_label=1/1);
for known connections. Setting ct_label marks a connection as one that was previously
allowed, but should no longer be allowed due to a policy change.
This table also contains a priority 0 flow with action next;, so that ACLs allow packets by default. If
the logical datapath has a statetful ACL, the following flows will also be added:
• A priority-1 flow that sets the hint to commit IP traffic to the connection tracker (with
action reg0[1] = 1; next;). 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.
• A priority-65535 flow that allows any traffic in the reply direction for a connection that
has been committed to the connection tracker (i.e., established flows), as long as the
committed flow does not have ct_label.blocked set. We only handle traffic in the reply
direction here because we want all packets going in the request direction to still go
through the flows that implement the currently defined policy based on ACLs. If a
connection is no longer allowed by policy, ct_label.blocked will get set and packets in the
reply direction will no longer be allowed, either.
• A priority-65535 flow that allows any traffic that is considered related to a committed
flow in the connection tracker (e.g., an ICMP Port Unreachable from a non-listening UDP
port), as long as the committed flow does not have ct_label.blocked set.
• A priority-65535 flow that drops all traffic marked by the connection tracker as invalid.
• A priority-65535 flow that drops all trafic in the reply direction with ct_label.blocked
set meaning that the connection should no longer be allowed due to a policy change. Packets
in the request direction are skipped here to let a newly created ACL re-allow this
connection.
Ingress Table 7: from-lport QoS Marking
Logical flows in this table closely reproduce those in the QoS table with the action column set in the
OVN_Northbound database for the from-lport direction.
• For every qos_rules entry in a logical switch with DSCP marking enabled, a flow will be
added at the priority mentioned in the QoS table.
• One priority-0 fallback flow that matches all packets and advances to the next table.
Ingress Table 8: from-lport QoS Meter
Logical flows in this table closely reproduce those in the QoS table with the bandwidth column set in the
OVN_Northbound database for the from-lport direction.
• For every qos_rules entry in a logical switch with metering enabled, a flow will be added
at the priorirty mentioned in the QoS table.
• One priority-0 fallback flow that matches all packets and advances to the next table.
Ingress Table 9: LB
It contains a priority-0 flow that simply moves traffic to the next table. For established connections a
priority 100 flow matches on ct.est && !ct.rel && !ct.new && !ct.inv and sets an action reg0[2] = 1;
next; to act as a hint for table Stateful to send packets through connection tracker to NAT the packets.
(The packet will automatically get DNATed to the same IP address as the first packet in that connection.)
Ingress Table 10: Stateful
• For all the configured load balancing rules for a switch in OVN_Northbound database that
includes a L4 port PORT of protocol P and IP address VIP, a priority-120 flow is added. For
IPv4 VIPs , the flow matches ct.new && ip && ip4.dst == VIP && P && P.dst == PORT. For IPv6
VIPs, the flow matches ct.new && ip && ip6.dst == VIP && P && P.dst == PORT. The flow’s
action is ct_lb(args) , where args contains comma separated IP addresses (and optional port
numbers) to load balance to. The address family of the IP addresses of args is the same as
the address family of VIP
• For all the configured load balancing rules for a switch in OVN_Northbound database that
includes just an IP address VIP to match on, OVN adds a priority-110 flow. For IPv4 VIPs,
the flow matches ct.new && ip && ip4.dst == VIP. For IPv6 VIPs, the flow matches ct.new &&
ip && ip6.dst == VIP. The action on this flow is ct_lb(args), where args contains comma
separated IP addresses of the same address family as VIP.
• A priority-100 flow commits packets to connection tracker using ct_commit; next; action
based on a hint provided by the previous tables (with a match for reg0[1] == 1).
• A priority-100 flow sends the packets to connection tracker using ct_lb; as the action
based on a hint provided by the previous tables (with a match for reg0[2] == 1).
• A priority-0 flow that simply moves traffic to the next table.
Ingress Table 11: ARP/ND responder
This table implements ARP/ND responder in a logical switch for known IPs. The advantage of the ARP
responder flow is to limit ARP broadcasts by locally responding to ARP requests without the need to send
to other hypervisors. One common case is when the inport is a logical port associated with a VIF and the
broadcast is responded to on the local hypervisor rather than broadcast across the whole network and
responded to by the destination VM. This behavior is proxy ARP.
ARP requests arrive from VMs from a logical switch inport of type default. For this case, the logical
switch proxy ARP rules can be for other VMs or logical router ports. Logical switch proxy ARP rules may
be programmed both for mac binding of IP addresses on other logical switch VIF ports (which are of the
default logical switch port type, representing connectivity to VMs or containers), and for mac binding of
IP addresses on logical switch router type ports, representing their logical router port peers. In order
to support proxy ARP for logical router ports, an IP address must be configured on the logical switch
router type port, with the same value as the peer logical router port. The configured MAC addresses must
match as well. When a VM sends an ARP request for a distributed logical router port and if the peer
router type port of the attached logical switch does not have an IP address configured, the ARP request
will be broadcast on the logical switch. One of the copies of the ARP request will go through the logical
switch router type port to the logical router datapath, where the logical router ARP responder will
generate a reply. The MAC binding of a distributed logical router, once learned by an associated VM, is
used for all that VM’s communication needing routing. Hence, the action of a VM re-arping for the mac
binding of the logical router port should be rare.
Logical switch ARP responder proxy ARP rules can also be hit when receiving ARP requests externally on a
L2 gateway port. In this case, the hypervisor acting as an L2 gateway, responds to the ARP request on
behalf of a destination VM.
Note that ARP requests received from localnet or vtep logical inports can either go directly to VMs, in
which case the VM responds or can hit an ARP responder for a logical router port if the packet is used to
resolve a logical router port next hop address. In either case, logical switch ARP responder rules will
not be hit. It contains these logical flows:
• Priority-100 flows to skip the ARP responder if inport is of type localnet or vtep and
advances directly to the next table. ARP requests sent to localnet or vtep ports can be
received by multiple hypervisors. Now, because the same mac binding rules are downloaded to
all hypervisors, each of the multiple hypervisors will respond. This will confuse L2
learning on the source of the ARP requests. ARP requests received on an inport of type
router are not expected to hit any logical switch ARP responder flows. However, no skip
flows are installed for these packets, as there would be some additional flow cost for this
and the value appears limited.
• Priority-50 flows that match ARP requests to each known IP address A of every logical
switch port, and respond with ARP replies directly with corresponding Ethernet address E:
eth.dst = eth.src;
eth.src = E;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = E;
arp.tpa = arp.spa;
arp.spa = A;
outport = inport;
flags.loopback = 1;
output;
These flows are omitted for logical ports (other than router ports or localport ports) that
are down.
• Priority-50 flows that match IPv6 ND neighbor solicitations to each known IP address A (and
A’s solicited node address) of every logical switch port except of type router, and respond
with neighbor advertisements directly with corresponding Ethernet address E:
nd_na {
eth.src = E;
ip6.src = A;
nd.target = A;
nd.tll = E;
outport = inport;
flags.loopback = 1;
output;
};
Priority-50 flows that match IPv6 ND neighbor solicitations to each known IP address A (and
A’s solicited node address) of logical switch port of type router, and respond with
neighbor advertisements directly with corresponding Ethernet address E:
nd_na_router {
eth.src = E;
ip6.src = A;
nd.target = A;
nd.tll = E;
outport = inport;
flags.loopback = 1;
output;
};
These flows are omitted for logical ports (other than router ports or localport ports) that
are down.
• Priority-100 flows with match criteria like the ARP and ND flows above, except that they
only match packets from the inport that owns the IP addresses in question, with action
next;. These flows prevent OVN from replying to, for example, an ARP request emitted by a
VM for its own IP address. A VM only makes this kind of request to attempt to detect a
duplicate IP address assignment, so sending a reply will prevent the VM from accepting the
IP address that it owns.
In place of next;, it would be reasonable to use drop; for the flows’ actions. If
everything is working as it is configured, then this would produce equivalent results,
since no host should reply to the request. But ARPing for one’s own IP address is intended
to detect situations where the network is not working as configured, so dropping the
request would frustrate that intent.
• One priority-0 fallback flow that matches all packets and advances to the next table.
Ingress Table 12: DHCP option processing
This table adds the DHCPv4 options to a DHCPv4 packet from the logical ports configured with IPv4
address(es) and DHCPv4 options, and similarly for DHCPv6 options.
• A priority-100 logical flow is added for these logical ports which matches the IPv4 packet
with udp.src = 68 and udp.dst = 67 and applies the action put_dhcp_opts and advances the
packet to the next table.
reg0[3] = put_dhcp_opts(offer_ip = ip, options...);
next;
For DHCPDISCOVER and DHCPREQUEST, this transforms the packet into a DHCP reply, adds the
DHCP offer IP ip and options to the packet, and stores 1 into reg0[3]. For other kinds of
packets, it just stores 0 into reg0[3]. Either way, it continues to the next table.
• A priority-100 logical flow is added for these logical ports which matches the IPv6 packet
with udp.src = 546 and udp.dst = 547 and applies the action put_dhcpv6_opts and advances
the packet to the next table.
reg0[3] = put_dhcpv6_opts(ia_addr = ip, options...);
next;
For DHCPv6 Solicit/Request/Confirm packets, this transforms the packet into a DHCPv6
Advertise/Reply, adds the DHCPv6 offer IP ip and options to the packet, and stores 1 into
reg0[3]. For other kinds of packets, it just stores 0 into reg0[3]. Either way, it
continues to the next table.
• A priority-0 flow that matches all packets to advances to table 11.
Ingress Table 13: DHCP responses
This table implements DHCP responder for the DHCP replies generated by the previous table.
• A priority 100 logical flow is added for the logical ports configured with DHCPv4 options
which matches IPv4 packets with udp.src == 68 && udp.dst == 67 && reg0[3] == 1 and responds
back to the inport after applying these actions. If reg0[3] is set to 1, it means that the
action put_dhcp_opts was successful.
eth.dst = eth.src;
eth.src = E;
ip4.dst = A;
ip4.src = S;
udp.src = 67;
udp.dst = 68;
outport = P;
flags.loopback = 1;
output;
where E is the server MAC address and S is the server IPv4 address defined in the DHCPv4
options and A is the IPv4 address defined in the logical port’s addresses column.
(This terminates ingress packet processing; the packet does not go to the next ingress
table.)
• A priority 100 logical flow is added for the logical ports configured with DHCPv6 options
which matches IPv6 packets with udp.src == 546 && udp.dst == 547 && reg0[3] == 1 and
responds back to the inport after applying these actions. If reg0[3] is set to 1, it means
that the action put_dhcpv6_opts was successful.
eth.dst = eth.src;
eth.src = E;
ip6.dst = A;
ip6.src = S;
udp.src = 547;
udp.dst = 546;
outport = P;
flags.loopback = 1;
output;
where E is the server MAC address and S is the server IPv6 LLA address generated from the
server_id defined in the DHCPv6 options and A is the IPv6 address defined in the logical
port’s addresses column.
(This terminates packet processing; the packet does not go on the next ingress table.)
• A priority-0 flow that matches all packets to advances to table 12.
Ingress Table 14 DNS Lookup
This table looks up and resolves the DNS names to the corresponding configured IP address(es).
• A priority-100 logical flow for each logical switch datapath if it is configured with DNS
records, which matches the IPv4 and IPv6 packets with udp.dst = 53 and applies the action
dns_lookup and advances the packet to the next table.
reg0[4] = dns_lookup(); next;
For valid DNS packets, this transforms the packet into a DNS reply if the DNS name can be
resolved, and stores 1 into reg0[4]. For failed DNS resolution or other kinds of packets,
it just stores 0 into reg0[4]. Either way, it continues to the next table.
Ingress Table 15 DNS Responses
This table implements DNS responder for the DNS replies generated by the previous table.
• A priority-100 logical flow for each logical switch datapath if it is configured with DNS
records, which matches the IPv4 and IPv6 packets with udp.dst = 53 && reg0[4] == 1 and
responds back to the inport after applying these actions. If reg0[4] is set to 1, it means
that the action dns_lookup was successful.
eth.dst <-> eth.src;
ip4.src <-> ip4.dst;
udp.dst = udp.src;
udp.src = 53;
outport = P;
flags.loopback = 1;
output;
(This terminates ingress packet processing; the packet does not go to the next ingress
table.)
Ingress Table 16 Destination Lookup
This table implements switching behavior. It contains these logical flows:
• A priority-100 flow that outputs all packets with an Ethernet broadcast or multicast
eth.dst to the MC_FLOOD multicast group, which ovn-northd populates with all enabled
logical ports.
• One priority-50 flow that matches each known Ethernet address against eth.dst and outputs
the packet to the single associated output port.
For the Ethernet address on a logical switch port of type router, when that logical switch
port’s addresses column is set to router and the connected logical router port specifies a
redirect-chassis:
• The flow for the connected logical router port’s Ethernet address is only programmed
on the redirect-chassis.
• If the logical router has rules specified in nat with external_mac, then those
addresses are also used to populate the switch’s destination lookup on the chassis
where logical_port is resident.
• One priority-0 fallback flow that matches all packets and outputs them to the MC_UNKNOWN
multicast group, which ovn-northd populates with all enabled logical ports that accept
unknown destination packets. As a small optimization, if no logical ports accept unknown
destination packets, ovn-northd omits this multicast group and logical flow.
Egress Table 0: Pre-LB
This table is similar to ingress table Pre-LB. It contains a priority-0 flow that simply moves traffic to
the next table. If any load balancing rules exist for the datapath, a priority-100 flow is added with a
match of ip and action of reg0[0] = 1; next; to act as a hint for table Pre-stateful to send IP packets
to the connection tracker for packet de-fragmentation.
Egress Table 1: to-lport Pre-ACLs
This is similar to ingress table Pre-ACLs except for to-lport traffic.
Egress Table 2: Pre-stateful
This is similar to ingress table Pre-stateful.
Egress Table 3: LB
This is similar to ingress table LB.
Egress Table 4: to-lport ACLs
This is similar to ingress table ACLs except for to-lport ACLs.
Egress Table 5: to-lport QoS Marking
This is similar to ingress table QoS marking except they apply to to-lport QoS rules.
Egress Table 6: to-lport QoS Meter
This is similar to ingress table QoS meter except they apply to to-lport QoS rules.
Egress Table 7: Stateful
This is similar to ingress table Stateful except that there are no rules added for load balancing new
connections.
Also the following flows are added.
• A priority 34000 logical flow is added for each logical port which has DHCPv4 options
defined to allow the DHCPv4 reply packet and which has DHCPv6 options defined to allow the
DHCPv6 reply packet from the Ingress Table 13: DHCP responses.
• A priority 34000 logical flow is added for each logical switch datapath configured with DNS
records with the match udp.dst = 53 to allow the DNS reply packet from the Ingress Table
15:DNS responses.
Egress Table 8: Egress Port Security - IP
This is similar to the port security logic in table Ingress Port Security - IP except that outport,
eth.dst, ip4.dst and ip6.dst are checked instead of inport, eth.src, ip4.src and ip6.src
Egress Table 9: Egress Port Security - L2
This is similar to the ingress port security logic in ingress table Admission Control and Ingress Port
Security - L2, but with important differences. Most obviously, outport and eth.dst are checked instead of
inport and eth.src. Second, packets directed to broadcast or multicast eth.dst are always accepted
instead of being subject to the port security rules; this is implemented through a priority-100 flow that
matches on eth.mcast with action output;. Finally, to ensure that even broadcast and multicast packets
are not delivered to disabled logical ports, a priority-150 flow for each disabled logical outport
overrides the priority-100 flow with a drop; action.
Logical Router Datapaths
Logical router datapaths will only exist for Logical_Router rows in the OVN_Northbound database that do
not have enabled set to false
Ingress Table 0: L2 Admission Control
This table drops packets that the router shouldn’t see at all based on their Ethernet headers. It
contains the following flows:
• Priority-100 flows to drop packets with VLAN tags or multicast Ethernet source addresses.
• For each enabled router port P with Ethernet address E, a priority-50 flow that matches
inport == P && (eth.mcast || eth.dst == E), with action next;.
For the gateway port on a distributed logical router (where one of the logical router ports
specifies a redirect-chassis), the above flow matching eth.dst == E is only programmed on
the gateway port instance on the redirect-chassis.
• For each dnat_and_snat NAT rule on a distributed router that specifies an external Ethernet
address E, a priority-50 flow that matches inport == GW && eth.dst == E, where GW is the
logical router gateway port, with action next;.
This flow is only programmed on the gateway port instance on the chassis where the
logical_port specified in the NAT rule resides.
Other packets are implicitly dropped.
Ingress Table 1: IP Input
This table is the core of the logical router datapath functionality. It contains the following flows to
implement very basic IP host functionality.
• L3 admission control: A priority-100 flow drops packets that match any of the following:
• ip4.src[28..31] == 0xe (multicast source)
• ip4.src == 255.255.255.255 (broadcast source)
• ip4.src == 127.0.0.0/8 || ip4.dst == 127.0.0.0/8 (localhost source or destination)
• ip4.src == 0.0.0.0/8 || ip4.dst == 0.0.0.0/8 (zero network source or destination)
• ip4.src or ip6.src is any IP address owned by the router, unless the packet was
recirculated due to egress loopback as indicated by REGBIT_EGRESS_LOOPBACK.
• ip4.src is the broadcast address of any IP network known to the router.
• ICMP echo reply. These flows reply to ICMP echo requests received for the router’s IP
address. Let A be an IP address owned by a router port. Then, for each A that is an IPv4
address, a priority-90 flow matches on ip4.dst == A and icmp4.type == 8 && icmp4.code == 0
(ICMP echo request). For each A that is an IPv6 address, a priority-90 flow matches on
ip6.dst == A and icmp6.type == 128 && icmp6.code == 0 (ICMPv6 echo request). The port of
the router that receives the echo request does not matter. Also, the ip.ttl of the echo
request packet is not checked, so it complies with RFC 1812, section 4.2.2.9. Flows for
ICMPv4 echo requests use the following actions:
ip4.dst <-> ip4.src;
ip.ttl = 255;
icmp4.type = 0;
flags.loopback = 1;
next;
Flows for ICMPv6 echo requests use the following actions:
ip6.dst <-> ip6.src;
ip.ttl = 255;
icmp6.type = 129;
flags.loopback = 1;
next;
• Reply to ARP requests.
These flows reply to ARP requests for the router’s own IP address and populates mac binding
table of the logical router port. The ARP requests are handled only if the requestor’s IP
belongs to the same subnets of the logical router port. For each router port P that owns IP
address A, which belongs to subnet S with prefix length L, and Ethernet address E, a
priority-90 flow matches inport == P && arp.spa == S/L && arp.op == 1 && arp.tpa == A (ARP
request) with the following actions:
put_arp(inport, arp.spa, arp.sha);
eth.dst = eth.src;
eth.src = E;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = E;
arp.tpa = arp.spa;
arp.spa = A;
outport = P;
flags.loopback = 1;
output;
For the gateway port on a distributed logical router (where one of the logical router ports
specifies a redirect-chassis), the above flows are only programmed on the gateway port
instance on the redirect-chassis. This behavior avoids generation of multiple ARP responses
from different chassis, and allows upstream MAC learning to point to the redirect-chassis.
• These flows handles ARP requests not for router’s own IP address. They use the SPA and SHA
to populate the logical router port’s mac binding table, with priority 80. The typical use
case of these flows are GARP requests handling. For the gateway port on a distributed
logical router, these flows are only programmed on the gateway port instance on the
redirect-chassis.
• These flows reply to ARP requests for the virtual IP addresses configured in the router for
DNAT or load balancing. For a configured DNAT IP address or a load balancer IPv4 VIP A, for
each router port P with Ethernet address E, a priority-90 flow matches inport == P &&
arp.op == 1 && arp.tpa == A (ARP request) with the following actions:
eth.dst = eth.src;
eth.src = E;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = E;
arp.tpa = arp.spa;
arp.spa = A;
outport = P;
flags.loopback = 1;
output;
For the gateway port on a distributed logical router with NAT (where one of the logical
router ports specifies a redirect-chassis):
• If the corresponding NAT rule cannot be handled in a distributed manner, then this
flow is only programmed on the gateway port instance on the redirect-chassis. This
behavior avoids generation of multiple ARP responses from different chassis, and
allows upstream MAC learning to point to the redirect-chassis.
• If the corresponding NAT rule can be handled in a distributed manner, then this flow
is only programmed on the gateway port instance where the logical_port specified in
the NAT rule resides.
Some of the actions are different for this case, using the external_mac specified in
the NAT rule rather than the gateway port’s Ethernet address E:
eth.src = external_mac;
arp.sha = external_mac;
This behavior avoids generation of multiple ARP responses from different chassis,
and allows upstream MAC learning to point to the correct chassis.
• ARP reply handling. This flow uses ARP replies to populate the logical router’s ARP table.
A priority-90 flow with match arp.op == 2 has actions put_arp(inport, arp.spa, arp.sha);.
• Reply to IPv6 Neighbor Solicitations. These flows reply to Neighbor Solicitation requests
for the router’s own IPv6 address and load balancing IPv6 VIPs and populate the logical
router’s mac binding table.
For each router port P that owns IPv6 address A, solicited node address S, and Ethernet
address E, a priority-90 flow matches inport == P && nd_ns && ip6.dst == {A, E} &&
nd.target == A with the following actions:
put_nd(inport, ip6.src, nd.sll);
nd_na_router {
eth.src = E;
ip6.src = A;
nd.target = A;
nd.tll = E;
outport = inport;
flags.loopback = 1;
output;
};
For each router port P that has load balancing VIP A, solicited node address S, and
Ethernet address E, a priority-90 flow matches inport == P && nd_ns && ip6.dst == {A, E} &&
nd.target == A with the following actions:
put_nd(inport, ip6.src, nd.sll);
nd_na {
eth.src = E;
ip6.src = A;
nd.target = A;
nd.tll = E;
outport = inport;
flags.loopback = 1;
output;
};
For the gateway port on a distributed logical router (where one of the logical router ports
specifies a redirect-chassis), the above flows replying to IPv6 Neighbor Solicitations are
only programmed on the gateway port instance on the redirect-chassis. This behavior avoids
generation of multiple replies from different chassis, and allows upstream MAC learning to
point to the redirect-chassis.
• IPv6 neighbor advertisement handling. This flow uses neighbor advertisements to populate
the logical router’s mac binding table. A priority-90 flow with match nd_na has actions
put_nd(inport, nd.target, nd.tll);.
• IPv6 neighbor solicitation for non-hosted addresses handling. This flow uses neighbor
solicitations to populate the logical router’s mac binding table (ones that were directed
at the logical router would have matched the priority-90 neighbor solicitation flow
already). A priority-80 flow with match nd_ns has actions put_nd(inport, ip6.src, nd.sll);.
• UDP port unreachable. Priority-80 flows generate ICMP port unreachable messages in reply to
UDP datagrams directed to the router’s IP address. The logical router doesn’t accept any
UDP traffic so it always generates such a reply.
These flows should not match IP fragments with nonzero offset.
Details TBD. Not yet implemented.
• TCP reset. Priority-80 flows generate TCP reset messages in reply to TCP datagrams directed
to the router’s IP address. The logical router doesn’t accept any TCP traffic so it always
generates such a reply.
These flows should not match IP fragments with nonzero offset.
Details TBD. Not yet implemented.
• Protocol unreachable. Priority-70 flows generate ICMP protocol unreachable messages in
reply to packets directed to the router’s IP address on IP protocols other than UDP, TCP,
and ICMP.
These flows should not match IP fragments with nonzero offset.
Details TBD. Not yet implemented.
• Drop other IP traffic to this router. These flows drop any other traffic destined to an IP
address of this router that is not already handled by one of the flows above, which amounts
to ICMP (other than echo requests) and fragments with nonzero offsets. For each IP address
A owned by the router, a priority-60 flow matches ip4.dst == A and drops the traffic. An
exception is made and the above flow is not added if the router port’s own IP address is
used to SNAT packets passing through that router.
The flows above handle all of the traffic that might be directed to the router itself. The following
flows (with lower priorities) handle the remaining traffic, potentially for forwarding:
• Drop Ethernet local broadcast. A priority-50 flow with match eth.bcast drops traffic
destined to the local Ethernet broadcast address. By definition this traffic should not be
forwarded.
• ICMP time exceeded. For each router port P, whose IP address is A, a priority-40 flow with
match inport == P && ip.ttl == {0, 1} && !ip.later_frag matches packets whose TTL has
expired, with the following actions to send an ICMP time exceeded reply:
icmp4 {
icmp4.type = 11; /* Time exceeded. */
icmp4.code = 0; /* TTL exceeded in transit. */
ip4.dst = ip4.src;
ip4.src = A;
ip.ttl = 255;
next;
};
Not yet implemented.
• TTL discard. A priority-30 flow with match ip.ttl == {0, 1} and actions drop; drops other
packets whose TTL has expired, that should not receive a ICMP error reply (i.e. fragments
with nonzero offset).
• Next table. A priority-0 flows match all packets that aren’t already handled and uses
actions next; to feed them to the next table.
Ingress Table 2: DEFRAG
This is to send packets to connection tracker for tracking and defragmentation. It contains a priority-0
flow that simply moves traffic to the next table. If load balancing rules with virtual IP addresses (and
ports) are configured in OVN_Northbound database for a Gateway router, a priority-100 flow is added for
each configured virtual IP address VIP. For IPv4 VIPs the flow matches ip && ip4.dst == VIP. For IPv6
VIPs, the flow matches ip && ip6.dst == VIP. The flow uses the action ct_next; to send IP packets to the
connection tracker for packet de-fragmentation and tracking before sending it to the next table.
Ingress Table 3: UNSNAT
This is for already established connections’ reverse traffic. i.e., SNAT has already been done in egress
pipeline and now the packet has entered the ingress pipeline as part of a reply. It is unSNATted here.
Ingress Table 3: UNSNAT on Gateway Routers
• If the Gateway router has been configured to force SNAT any previously DNATted packets to
B, a priority-110 flow matches ip && ip4.dst == B with an action ct_snat; .
If the Gateway router has been configured to force SNAT any previously load-balanced
packets to B, a priority-100 flow matches ip && ip4.dst == B with an action ct_snat; .
For each NAT configuration in the OVN Northbound database, that asks to change the source
IP address of a packet from A to B, a priority-90 flow matches ip && ip4.dst == B with an
action ct_snat; .
A priority-0 logical flow with match 1 has actions next;.
Ingress Table 3: UNSNAT on Distributed Routers
• For each configuration in the OVN Northbound database, that asks to change the source IP
address of a packet from A to B, a priority-100 flow matches ip && ip4.dst == B && inport
== GW, where GW is the logical router gateway port, with an action ct_snat;.
If the NAT rule cannot be handled in a distributed manner, then the priority-100 flow above
is only programmed on the redirect-chassis.
For each configuration in the OVN Northbound database, that asks to change the source IP
address of a packet from A to B, a priority-50 flow matches ip && ip4.dst == B with an
action REGBIT_NAT_REDIRECT = 1; next;. This flow is for east/west traffic to a NAT
destination IPv4 address. By setting the REGBIT_NAT_REDIRECT flag, in the ingress table
Gateway Redirect this will trigger a redirect to the instance of the gateway port on the
redirect-chassis.
A priority-0 logical flow with match 1 has actions next;.
Ingress Table 4: DNAT
Packets enter the pipeline with destination IP address that needs to be DNATted from a virtual IP address
to a real IP address. Packets in the reverse direction needs to be unDNATed.
Ingress Table 4: Load balancing DNAT rules
Following load balancing DNAT flows are added for Gateway router or Router with gateway port. These flows
are programmed only on the redirect-chassis. These flows do not get programmed for load balancers with
IPv6 VIPs.
• For all the configured load balancing rules for a Gateway router or Router with gateway
port in OVN_Northbound database that includes a L4 port PORT of protocol P and IPv4 address
VIP, a priority-120 flow that matches on ct.new && ip && ip4.dst == VIP && P && P.dst ==
PORT
with an action of ct_lb(args), where args contains comma separated IPv4 addresses (and
optional port numbers) to load balance to. If the router is configured to force SNAT any
load-balanced packets, the above action will be replaced by flags.force_snat_for_lb = 1;
ct_lb(args);.
• For all the configured load balancing rules for a router in OVN_Northbound database that
includes a L4 port PORT of protocol P and IPv4 address VIP, a priority-120 flow that
matches on ct.est && ip && ip4.dst == VIP && P && P.dst == PORT
with an action of ct_dnat;. If the router is configured to force SNAT any load-balanced
packets, the above action will be replaced by flags.force_snat_for_lb = 1; ct_dnat;.
• For all the configured load balancing rules for a router in OVN_Northbound database that
includes just an IP address VIP to match on, a priority-110 flow that matches on ct.new &&
ip && ip4.dst == VIP with an action of ct_lb(args), where args contains comma separated
IPv4 addresses. If the router is configured to force SNAT any load-balanced packets, the
above action will be replaced by flags.force_snat_for_lb = 1; ct_lb(args);.
• For all the configured load balancing rules for a router in OVN_Northbound database that
includes just an IP address VIP to match on, a priority-110 flow that matches on ct.est &&
ip && ip4.dst == VIP with an action of ct_dnat;. If the router is configured to force SNAT
any load-balanced packets, the above action will be replaced by flags.force_snat_for_lb =
1; ct_dnat;.
Ingress Table 4: DNAT on Gateway Routers
• For each configuration in the OVN Northbound database, that asks to change the destination
IP address of a packet from A to B, a priority-100 flow matches ip && ip4.dst == A with an
action flags.loopback = 1; ct_dnat(B);. If the Gateway router is configured to force SNAT
any DNATed packet, the above action will be replaced by flags.force_snat_for_dnat = 1;
flags.loopback = 1; ct_dnat(B);.
• For all IP packets of a Gateway router, a priority-50 flow with an action flags.loopback =
1; ct_dnat;.
• A priority-0 logical flow with match 1 has actions next;.
Ingress Table 4: DNAT on Distributed Routers
On distributed routers, the DNAT table only handles packets with destination IP address that needs to be
DNATted from a virtual IP address to a real IP address. The unDNAT processing in the reverse direction is
handled in a separate table in the egress pipeline.
• For each configuration in the OVN Northbound database, that asks to change the destination
IP address of a packet from A to B, a priority-100 flow matches ip && ip4.dst == B &&
inport == GW, where GW is the logical router gateway port, with an action ct_dnat(B);.
If the NAT rule cannot be handled in a distributed manner, then the priority-100 flow above
is only programmed on the redirect-chassis.
For each configuration in the OVN Northbound database, that asks to change the destination
IP address of a packet from A to B, a priority-50 flow matches ip && ip4.dst == B with an
action REGBIT_NAT_REDIRECT = 1; next;. This flow is for east/west traffic to a NAT
destination IPv4 address. By setting the REGBIT_NAT_REDIRECT flag, in the ingress table
Gateway Redirect this will trigger a redirect to the instance of the gateway port on the
redirect-chassis.
A priority-0 logical flow with match 1 has actions next;.
Ingress Table 5: IPv6 ND RA option processing
• A priority-50 logical flow is added for each logical router port configured with IPv6 ND RA
options which matches IPv6 ND Router Solicitation packet and applies the action
put_nd_ra_opts and advances the packet to the next table.
reg0[5] = put_nd_ra_opts(options);next;
For a valid IPv6 ND RS packet, this transforms the packet into an IPv6 ND RA reply and sets
the RA options to the packet and stores 1 into reg0[5]. For other kinds of packets, it just
stores 0 into reg0[5]. Either way, it continues to the next table.
• A priority-0 logical flow with match 1 has actions next;.
Ingress Table 6: IPv6 ND RA responder
This table implements IPv6 ND RA responder for the IPv6 ND RA replies generated by the previous table.
• A priority-50 logical flow is added for each logical router port configured with IPv6 ND RA
options which matches IPv6 ND RA packets and reg0[5] == 1 and responds back to the inport
after applying these actions. If reg0[5] is set to 1, it means that the action
put_nd_ra_opts was successful.
eth.dst = eth.src;
eth.src = E;
ip6.dst = ip6.src;
ip6.src = I;
outport = P;
flags.loopback = 1;
output;
where E is the MAC address and I is the IPv6 link local address of the logical router port.
(This terminates packet processing in ingress pipeline; the packet does not go to the next
ingress table.)
• A priority-0 logical flow with match 1 has actions next;.
Ingress Table 7: IP Routing
A packet that arrives at this table is an IP packet that should be routed to the address in ip4.dst or
ip6.dst. This table implements IP routing, setting reg0 (or xxreg0 for IPv6) to the next-hop IP address
(leaving ip4.dst or ip6.dst, the packet’s final destination, unchanged) and advances to the next table
for ARP resolution. It also sets reg1 (or xxreg1) to the IP address owned by the selected router port
(ingress table ARP Request will generate an ARP request, if needed, with reg0 as the target protocol
address and reg1 as the source protocol address).
This table contains the following logical flows:
• For distributed logical routers where one of the logical router ports specifies a
redirect-chassis, a priority-300 logical flow with match REGBIT_NAT_REDIRECT == 1 has
actions ip.ttl--; next;. The outport will be set later in the Gateway Redirect table.
• IPv4 routing table. For each route to IPv4 network N with netmask M, on router port P with
IP address A and Ethernet address E, a logical flow with match ip4.dst == N/M, whose
priority is the number of 1-bits in M, has the following actions:
ip.ttl--;
reg0 = G;
reg1 = A;
eth.src = E;
outport = P;
flags.loopback = 1;
next;
(Ingress table 1 already verified that ip.ttl--; will not yield a TTL exceeded error.)
If the route has a gateway, G is the gateway IP address. Instead, if the route is from a
configured static route, G is the next hop IP address. Else it is ip4.dst.
• IPv6 routing table. For each route to IPv6 network N with netmask M, on router port P with
IP address A and Ethernet address E, a logical flow with match in CIDR notation ip6.dst ==
N/M, whose priority is the integer value of M, has the following actions:
ip.ttl--;
xxreg0 = G;
xxreg1 = A;
eth.src = E;
outport = P;
flags.loopback = 1;
next;
(Ingress table 1 already verified that ip.ttl--; will not yield a TTL exceeded error.)
If the route has a gateway, G is the gateway IP address. Instead, if the route is from a
configured static route, G is the next hop IP address. Else it is ip6.dst.
If the address A is in the link-local scope, the route will be limited to sending on the
ingress port.
Ingress Table 8: ARP/ND Resolution
Any packet that reaches this table is an IP packet whose next-hop IPv4 address is in reg0 or IPv6 address
is in xxreg0. (ip4.dst or ip6.dst contains the final destination.) This table resolves the IP address in
reg0 (or xxreg0) into an output port in outport and an Ethernet address in eth.dst, using the following
flows:
• For distributed logical routers where one of the logical router ports specifies a
redirect-chassis, a priority-200 logical flow with match REGBIT_NAT_REDIRECT == 1 has
actions eth.dst = E; next;, where E is the ethernet address of the router’s distributed
gateway port.
• Static MAC bindings. MAC bindings can be known statically based on data in the
OVN_Northbound database. For router ports connected to logical switches, MAC bindings can
be known statically from the addresses column in the Logical_Switch_Port table. For router
ports connected to other logical routers, MAC bindings can be known statically from the mac
and networks column in the Logical_Router_Port table.
For each IPv4 address A whose host is known to have Ethernet address E on router port P, a
priority-100 flow with match outport === P && reg0 == A has actions eth.dst = E; next;.
For each IPv6 address A whose host is known to have Ethernet address E on router port P, a
priority-100 flow with match outport === P && xxreg0 == A has actions eth.dst = E; next;.
For each logical router port with an IPv4 address A and a mac address of E that is
reachable via a different logical router port P, a priority-100 flow with match outport ===
P && reg0 == A has actions eth.dst = E; next;.
For each logical router port with an IPv6 address A and a mac address of E that is
reachable via a different logical router port P, a priority-100 flow with match outport ===
P && xxreg0 == A has actions eth.dst = E; next;.
• Dynamic MAC bindings. These flows resolve MAC-to-IP bindings that have become known
dynamically through ARP or neighbor discovery. (The ingress table ARP Request will issue an
ARP or neighbor solicitation request for cases where the binding is not yet known.)
A priority-0 logical flow with match ip4 has actions get_arp(outport, reg0); next;.
A priority-0 logical flow with match ip6 has actions get_nd(outport, xxreg0); next;.
Ingress Table 9: Gateway Redirect
For distributed logical routers where one of the logical router ports specifies a redirect-chassis, this
table redirects certain packets to the distributed gateway port instance on the redirect-chassis. This
table has the following flows:
• A priority-200 logical flow with match REGBIT_NAT_REDIRECT == 1 has actions outport = CR;
next;, where CR is the chassisredirect port representing the instance of the logical router
distributed gateway port on the redirect-chassis.
• A priority-150 logical flow with match outport == GW && eth.dst == 00:00:00:00:00:00 has
actions outport = CR; next;, where GW is the logical router distributed gateway port and CR
is the chassisredirect port representing the instance of the logical router distributed
gateway port on the redirect-chassis.
• For each NAT rule in the OVN Northbound database that can be handled in a distributed
manner, a priority-100 logical flow with match ip4.src == B && outport == GW, where GW is
the logical router distributed gateway port, with actions next;.
• A priority-50 logical flow with match outport == GW has actions outport = CR; next;, where
GW is the logical router distributed gateway port and CR is the chassisredirect port
representing the instance of the logical router distributed gateway port on the
redirect-chassis.
• A priority-0 logical flow with match 1 has actions next;.
Ingress Table 10: ARP Request
In the common case where the Ethernet destination has been resolved, this table outputs the packet.
Otherwise, it composes and sends an ARP or IPv6 Neighbor Solicitation request. It holds the following
flows:
• Unknown MAC address. A priority-100 flow for IPv4 packets with match eth.dst ==
00:00:00:00:00:00 has the following actions:
arp {
eth.dst = ff:ff:ff:ff:ff:ff;
arp.spa = reg1;
arp.tpa = reg0;
arp.op = 1; /* ARP request. */
output;
};
Unknown MAC address. A priority-100 flow for IPv6 packets with match eth.dst ==
00:00:00:00:00:00 has the following actions:
nd_ns {
nd.target = xxreg0;
output;
};
(Ingress table IP Routing initialized reg1 with the IP address owned by outport and
(xx)reg0 with the next-hop IP address)
The IP packet that triggers the ARP/IPv6 NS request is dropped.
• Known MAC address. A priority-0 flow with match 1 has actions output;.
Egress Table 0: UNDNAT
This is for already established connections’ reverse traffic. i.e., DNAT has already been done in ingress
pipeline and now the packet has entered the egress pipeline as part of a reply. For NAT on a distributed
router, it is unDNATted here. For Gateway routers, the unDNAT processing is carried out in the ingress
DNAT table.
• For all the configured load balancing rules for a router with gateway port in
OVN_Northbound database that includes an IPv4 address VIP, for every backend IPv4 address B
defined for the VIP a priority-120 flow is programmed on redirect-chassis that matches ip
&& ip4.src == B && outport == GW, where GW is the logical router gateway port with an
action ct_dnat;. If the backend IPv4 address B is also configured with L4 port PORT of
protocol P, then the match also includes P.src == PORT. These flows are not added for load
balancers with IPv6 VIPs.
If the router is configured to force SNAT any load-balanced packets, above action will be
replaced by flags.force_snat_for_lb = 1; ct_dnat;.
• For each configuration in the OVN Northbound database that asks to change the destination
IP address of a packet from an IP address of A to B, a priority-100 flow matches ip &&
ip4.src == B && outport == GW, where GW is the logical router gateway port, with an action
ct_dnat;.
If the NAT rule cannot be handled in a distributed manner, then the priority-100 flow above
is only programmed on the redirect-chassis.
If the NAT rule can be handled in a distributed manner, then there is an additional action
eth.src = EA;, where EA is the ethernet address associated with the IP address A in the NAT
rule. This allows upstream MAC learning to point to the correct chassis.
• A priority-0 logical flow with match 1 has actions next;.
Egress Table 1: SNAT
Packets that are configured to be SNATed get their source IP address changed based on the configuration
in the OVN Northbound database.
Egress Table 1: SNAT on Gateway Routers
• If the Gateway router in the OVN Northbound database has been configured to force SNAT a
packet (that has been previously DNATted) to B, a priority-100 flow matches
flags.force_snat_for_dnat == 1 && ip with an action ct_snat(B);.
If the Gateway router in the OVN Northbound database has been configured to force SNAT a
packet (that has been previously load-balanced) to B, a priority-100 flow matches
flags.force_snat_for_lb == 1 && ip with an action ct_snat(B);.
For each configuration in the OVN Northbound database, that asks to change the source IP
address of a packet from an IP address of A or to change the source IP address of a packet
that belongs to network A to B, a flow matches ip && ip4.src == A with an action
ct_snat(B);. The priority of the flow is calculated based on the mask of A, with matches
having larger masks getting higher priorities.
A priority-0 logical flow with match 1 has actions next;.
Egress Table 1: SNAT on Distributed Routers
• For each configuration in the OVN Northbound database, that asks to change the source IP
address of a packet from an IP address of A or to change the source IP address of a packet
that belongs to network A to B, a flow matches ip && ip4.src == A && outport == GW, where
GW is the logical router gateway port, with an action ct_snat(B);. The priority of the flow
is calculated based on the mask of A, with matches having larger masks getting higher
priorities.
If the NAT rule cannot be handled in a distributed manner, then the flow above is only
programmed on the redirect-chassis.
If the NAT rule can be handled in a distributed manner, then there is an additional action
eth.src = EA;, where EA is the ethernet address associated with the IP address A in the NAT
rule. This allows upstream MAC learning to point to the correct chassis.
• A priority-0 logical flow with match 1 has actions next;.
Egress Table 2: Egress Loopback
For distributed logical routers where one of the logical router ports specifies a redirect-chassis.
Earlier in the ingress pipeline, some east-west traffic was redirected to the chassisredirect port, based
on flows in the UNSNAT and DNAT ingress tables setting the REGBIT_NAT_REDIRECT flag, which then triggered
a match to a flow in the Gateway Redirect ingress table. The intention was not to actually send traffic
out the distributed gateway port instance on the redirect-chassis. This traffic was sent to the
distributed gateway port instance in order for DNAT and/or SNAT processing to be applied.
While UNDNAT and SNAT processing have already occurred by this point, this traffic needs to be forced
through egress loopback on this distributed gateway port instance, in order for UNSNAT and DNAT
processing to be applied, and also for IP routing and ARP resolution after all of the NAT processing, so
that the packet can be forwarded to the destination.
This table has the following flows:
• For each NAT rule in the OVN Northbound database on a distributed router, a priority-100
logical flow with match ip4.dst == E && outport == GW, where E is the external IP address
specified in the NAT rule, and GW is the logical router distributed gateway port, with the
following actions:
clone {
ct_clear;
inport = outport;
outport = "";
flags = 0;
flags.loopback = 1;
reg0 = 0;
reg1 = 0;
...
reg9 = 0;
REGBIT_EGRESS_LOOPBACK = 1;
next(pipeline=ingress, table=0);
};
flags.loopback is set since in_port is unchanged and the packet may return back to that
port after NAT processing. REGBIT_EGRESS_LOOPBACK is set to indicate that egress loopback
has occurred, in order to skip the source IP address check against the router address.
• A priority-0 logical flow with match 1 has actions next;.
Egress Table 3: Delivery
Packets that reach this table are ready for delivery. It contains priority-100 logical flows that match
packets on each enabled logical router port, with action output;.
Open vSwitch 2.9.8 ovn-northd ovn-northd(8)