We figure out local datapaths in binding_run() but update the field
localnet_port for each local datapath that has localnet port in
patch_run(). This patch updates the localnet_port field in binding_run
directly and removes the logic in patch_run(), since the logic is
more about port-binding processing, and patch_run() is focusing on
patch port creation only.
In a future patch binding_run() will be used in a new thread for
pinctrl, but patch_run() will not.
Signed-off-by: Han Zhou <zhouhan@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Until now, ovn-controller has implemented OVN logical patch ports and
l3gateway ports in terms of OVS patch ports. It is a hassle to create and
destroy ports, and it is also wasteful compared to what the patch ports
actually buy us: the ability to "save and restore" a packet around a
recursive trip through the flow table. The "clone" action can do that too,
without the need to create a port. This commit takes advantage of the
clone action for that purpose, getting rid of most of the patch ports
previously created by ovn-controller.
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Mickey Spiegel <mickeys.dev@gmail.com>
On a particular hypervisor, ovn-controller only needs to handle ports
and datapaths that have some relationship with it, that is, the
ports that actually reside on the hypervisor, plus all the other ports on
those ports' datapaths, plus all of the ports and datapaths that are
reachable from those via logical patch ports. Until now, ovn-controller
has done a poor job of limiting what it deals with to this set. This
commit improves the situation.
This commit gets rid of the concept of a "patched_datapath" which until now
was used to represent any datapath that contained a logical patch port.
Previously, the concept of a "local_datapath" meant a datapath with a VIF
that resides on the local hypervisor. This commit extends that concept to
include any other datapath that can be reached from a VIF on the local
hypervisor, which is a simplification that makes the code easier to
understand in a few places.
CC: Gurucharan Shetty <guru@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Mickey Spiegel <mickeys.dev@gmail.com>
When ovn-controller implemented incremental processing, the set of
patched datapaths was revised on each trip through the main loop, so it
was necessary to notice datapaths that shouldn't exist anymore and remove
them.
With incremental processing gone, the set of patched datapaths is
built and torn down on every trip through the main loop, so there will
never be any stale datapaths. This commit retires the concept.
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Russell Bryant <russell@ovn.org>
Nothing freed 'key', which was dynamically allocated. This commit changes
'key' so that it is no longer dynamically allocated.
Reported-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Flavio Fernandes <flavio@flaviof.com>
Acked-by: Russell Bryant <russell@ovn.org>
As [1] indicates, incremental processing hasn't resulted
in an improvement worth the complexity it has added.
This patch backs out all of the code specific to incremental
processing, along with the persisting of OF flows,
logical ports, multicast groups, all_lports, local and patched
datapaths.
Persisted objects in the ovn/controller/physical.c module will
be used by a future patch set to determine if physical changes
have occurred.
Future patch sets in the series will convert
the ovn/controller/encaps.c module back to full processing
and remove the persistance of address sets in the
ovn/controller/lflow.c module.
[1] http://openvswitch.org/pipermail/dev/2016-August/078272.html
Signed-off-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
In cases where a DNAT IP is moved to a new router or the SNAT IP is reused
with a new mac address, the NAT IPs become unreachable because the external
switches/routers have stale ARP entries. This commit
aims to fix the problem by sending GARPs for NAT IPs via locanet. There are
two parts to this patch.
[1] Adding the datapath of the l3 gateway port to local datapaths in
ovn-controller. This will result in creation of patch ports between
br-int and the physical bridge (that provides connectivity to local network
via localnet port) and will enable gateway router to have external
connectivity
[2] A new options key "nat-addresses" is added to the logical switch port of
type router, the logical switch that has this port is the one that provides
connectivity to local network via localnet port. The value for the key
"nat-addresses" is the MAC address of the port followed by a list of
SNAT & DNAT IPs. When ovn-controller sees a new IP in nat-addrress option,
it sends a GARP message for the IP via the localnet port. nat-addresses
option is added to the logical switch port of type router and not to the
logical router port, because the logical switch datapath has the localnet
port. Adding nat-addresses option to the router port will involve more
changes to get to the local net port.
Signed-off-by: Chandra Sekhar Vejendla <csvejend@us.ibm.com>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
If the chassis doesn't configure the 'external-ids:ovn-bridge-mappings' in
the OVSDB, the 'add_bridge_mappings' should return directly to skip some
unnecessary code.
Signed-off-by: nickcooper-zhangtonghao <nickcooper-zhangtonghao@opencloud.tech>
Signed-off-by: Russell Bryant <russell@ovn.org>
When L3 gateway support was added, it introduced a port type called
"gateway" and a corresponding option called "gateway-chassis". Since
that time, we also have an L2 gateway port type called "l2gateway" and a
corresponding option called "l2gateway-chassis". This patch renames the
L3 gateway port type and option to "l3gateway" and "l3gateway-chassis"
to make things a little more clear and consistent.
Signed-off-by: Russell Bryant <russell@ovn.org>
To easily allow both in- and out-of-tree building of the Python
wrapper for the OVS JSON parser (e.g. w/ pip), move json.h to
include/openvswitch. This also requires moving lib/{hmap,shash}.h.
Both hmap.h and shash.h were #include-ing "util.h" even though the
headers themselves did not use anything from there, but rather from
include/openvswitch/util.h. Fixing that required including util.h
in several C files mostly due to OVS_NOT_REACHED and things like
xmalloc.
Signed-off-by: Terry Wilson <twilson@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This code changes to allow incremental processing of the
logical flow and physical binding tables whenver possible.
Note: flows created by physical_run for multicast_groups are
*NOT* handled incrementally due to to be solved issues
with GWs and local routers.
Signed-off-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Commit 263064aeaa (Convert binding_run to incremental processing.)
changed the way patched_datapaths were handled. Previously we would
destroy the datastructure in every run and re-create it fresh. The new
way causes problems with the way conntrack zones are allocated as now
we can have stale port_binding entries causing segmentation faults.
With this commit, we simply don't depend on port_binding records in
conntrack zone allocation and instead store the UUID as a string in
the patch_datapath datastructure.
(The test enhanced with this commit would fail without the changes
in the commit. i.e. ovn-controller would crash. )
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
Patched datapaths that are no longer referenced should be removed from
the patched_datapaths map; otherwise incorrect state references for a
patched datapath may be used and also datapaths that are absent will be
interpreted as present.
Signed-off-by: Darrell Ball <dlu998@gmail.com>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
This patch implements one approach to using ovn-controller to implement
a software l2 gateway between logical and physical networks.
A new logical port type called "l2gateway" is introduced here. It is very
close to how localnet ports work, with the following exception:
- A localnet port makes OVN use the physical network as the
transport between hypervisors instead of tunnels. An l2gateway port still
uses tunnels between all hypervisors, and packets only go to/from the
specified physical network as needed via the chassis the l2gateway port
is bound to.
- An l2gateway port also gets bound to a chassis while a localnet port does
not. This binding is not done by ovn-controller. It is left as an
administrative function. In the case of OpenStack, the Neutron plugin
will do this.
Signed-off-by: Russell Bryant <russell@ovn.org>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
Acked-by: Ben Pfaff <blp@ovn.org>
Acked-by: Justin Pettit <jpettit@ovn.org>
Ensure that the entire port binding table is processed
when chassis are added/removed or when get_local_iface_ids
finds new ports on the local vswitch.
Side effects:
- Persist local_datapaths and patch_datapaths across runs so
that changes to either can be used as a trigger to reset
incremental flow processing.
- Persist all_lports structure
- Revert commit 9baaabfff3
(ovn: Fix localnet ports deletion and recreation sometimes
after restart.) as these changes are not desirable once
local_datatpath is persisted.
Signed-off-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
OVS NAT currently cannot do snat and dnat in the same zone.
So we need two zones per gateway router.
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
Currently OVN has distributed switches and routers. When a packet
exits a container or a VM, the entire lifecycle of the packet
through multiple switches and routers are calculated in source
chassis itself. When the destination endpoint resides on a different
chassis, the packet is sent to the other chassis and it only goes
through the egress pipeline of that chassis once and eventually to
the real destination.
When the packet returns back, the same thing happens. The return
packet leaves the VM/container on the chassis where it resides.
The packet goes through all the switches and routers in the logical
pipleline on that chassis and then sent to the eventual destination
over the tunnel.
The above makes the logical pipeline very flexible and easy. But,
creates a problem for cases where you need to add stateful services
(via conntrack) on switches and routers.
For l3 gateways, we plan to leverage DNAT and SNAT functionality
and we want to apply DNAT and SNAT rules on a router. So we ideally need
the packet to go through that router in both directions in the same
chassis. To achieve this, this commit introduces a new gateway router which is
static and can be connected to your distributed router via a switch.
To make minimal changes in OVN's logical pipeline, this commit
tries to make the switch port connected to a l3 gateway router look like
a container/VM endpoint for every other chassis except the chassis
on which the l3 gateway router resides. On the chassis where the
gateway router resides, the connection looks just like a patch port.
This is achieved by the doing the following:
Introduces a new type of port_binding record called 'gateway'.
On the chassis where the gateway router resides, this port behaves just
like the port of type 'patch'. The ovn-controller on that chassis
populates the "chassis" column for this record as an indication for
other ovn-controllers of its physical location. Other ovn-controllers
treat this port as they would treat a VM/Container port on a different
chassis.
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
The new helpers get_local_datapath() and get_patched_datapath() make code
a little shorter and easier to read. They also avoid a pitfall that was
present in at least a few of the instances: CONTAINER_OF is not safe on a
null pointer, because it does a raw pointer subtraction and will change
NULL to something else. This wasn't actually a problem in these particular
cases because the value it was subtracting was zero (although arguably it
is still undefined behavior because the compiler is allowed to assume that
a pointer on which arithmetic is performed is nonnull).
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Russell Bryant <russell@ovn.org>
This commit applies a minor restructuring of this code to put the
localnet port specific code in its own block. This is mostly to make a
future patch easier to read.
Signed-off-by: Russell Bryant <russell@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
For non-local datapaths, if there are no patch ports attached, it
means the lflows and port bindings would never be needed on the
Chassis. Since lflow_run() and physical_run() are the bottlenecks,
skipping the processing for such lflows and port bindings can save
significant amount of CPU, at the same time largely reduce the
number of rules in local openflow tables. This is specifically
useful when most of the lswitches are created for bridged networks,
where logical router is not used.
Test precondition:
2k hypervisors, 20k lports, 200 lswitches (each with a localnet
port).
Test case:
step1: add 50 hypervisors (simulated on 1 BM with 40 cores), and
wait for flow updates complete on all new hypervisors.
step2: create a lswitch and a localnet port, create and bind 100
lports evenly on these hypervisors. Repeat this 5 times.
Before the change:
Step1 took around 20 minutes.
Step2 took 936 seconds.
After the change:
Step1 took less than 1 minute: 20x faster.
Step2 took 464 seconds: 2x faster.
Signed-off-by: Han Zhou <zhouhan@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This reverts commit 3a83007a76. It's really
nonobvious from the code why the condition added by that commit makes sense.
The new condition should not be necessary now that binding_run() always keeps
track of the local datapaths, since commit 7c040135cf351 (binding: Track local
datapaths even when no transaction is possible).
CC: Ramu Ramamurthy <ramu.ramamurthy@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Russell Bryant <russell@ovn.org>
when ctx->ovnsb_idl_txn is null, binding_run exits early
and does not add any local_datapaths, but patch_run
doesnt check this, and ends up deleting localnet ports,
because there are no local datapaths for them,
They get readded in a subsequent run causing unnecessary
deletion and readdition.
Signed-off-by: Ramu Ramamurthy <ramu.ramamurthy@us.ibm.com>
Signed-off-by: Russell Bryant <russell@ovn.org>
Before this patch, inter-chassis communication between VIFs of same
lswitch will always go through tunnel, which end up of modeling a
single physical network with many lswitches and pairs of lports, and
complexity in CMS like OpenStack neutron to manage the lswitches and
lports.
With this patch, inter-chassis communication can go through physical
networks via localnet port with a 1:1 mapping between lswitches and
physical networks. The pipeline becomes:
Ingress -> Egress (local) -> Ingress (remote) -> Egress
The original tunneling mechanism will still be used if there is no
localnet port configured on the lswitch.
Signed-off-by: Han Zhou <zhouhan@gmail.com>
Acked-by: Russell Bryant <russell@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Multiple logical ports on the same chassis that were connected to the
same physical network via localnet ports were not able to send packets
to each other. This was because ovn-controller created a single patch
port between br-int and the physical network access bridge and used it
for all localnet ports.
The fix implemented here is to create a separate patch port for every
logical port of type=localnet. An optimization is included where these
ports are only created if the localnet port is on a logical switch with
another logical port with an associated local VIF.
A nice side effect of this fix is that the code in physical.c got a lot
simpler, as localnet ports are now handled mostly like local VIFs.
Fixes: c02819293d ("ovn: Add "localnet" logical port type.")
Reported-by: Han Zhou <zhouhan@gmail.com>
Reported-at: http://openvswitch.org/pipermail/dev/2016-January/064413.html
Signed-off-by: Russell Bryant <russell@ovn.org>
Tested-by: Kyle Mestery <mestery@mestery.com
Acked-By: Kyle Mestery <mestery@mestery.com>
Tested-by: Han Zhou <zhouhan@gmail.com>
Tested-by: Michael Arnaldi <michael.arnaldi@mymoneyex.com>
Acked-by: Ben Pfaff <blp@ovn.org>
This implementation is suboptimal for several reasons. First, it
creates an OVS port for every OVN logical patch port, not just for the
ones that are actually useful on this hypervisor. Second, it's
wasteful to create an OVS patch port per OVN logical patch port, when
really there's no benefit to them beyond a way to identify how a
packet ingressed into a logical datapath.
There are two obvious ways to improve the situation here, by modifying
OVS:
1. Add a way to configure in OVS which fields are preserved on a
hop across an OVS patch port. If MFF_LOG_DATAPATH and
MFF_LOG_INPORT were preserved, then only a single pair of OVS
patch ports would be required regardless of the number of OVN
logical patch ports.
2. Add a new OpenFlow extension action modeled on "resubmit" that
also saves and restores the packet data and metadata (the
inability to do this is the only reason that "resubmit" can't
be used already). Or add OpenFlow extension actions to
otherwise save and restore packet data and metadata.
We should probably choose one of those in the medium to long term, but
I don't know which one.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
An upcoming patch will introduce a different use for patch ports, so
ovn-patch-port would become an ambiguous name.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
Calculating the patch port names from the bridge names makes sense when
there's only one pair of patch ports between a pair of bridges, but that
won't be the case for an upcoming use of patch ports.
This changes makes it easy to check for existing patch ports in
create_patch_port(), instead of in its caller, and since that seems like a
more sensible place this change also moves it there.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
Until now, the code here lumped together what was necessary to create and
destroy patch ports, with what was necessary to identify the patch ports
that were needed. An upcoming patch will add new reasons to create patch
ports, so this commit more cleanly separates those two functions.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
The whole point of this module is side effects on the Open vSwitch
database, so the whole thing can be skipped if those are impossible.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
Upcoming patches will introduce new extensive use of patch ports and it
seems reasonable to put it into its own file.
This is mostly code motion. Code changes are limited to those necessary
to make the separated code compile, except for renaming
init_bridge_mappings() to patch_run().
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>