This is a one-sided operation, so we shouldn't be touching the
remote's Peers.
Also fix the associated test... When both 1 and 2 have lost their
connection to 3, they no longer have a route to 3 and hence gc it.
And because they no longer have a route, gossip from them won't get
through to 3.
We were creating peers with NewPeerFrom, which copies the Version (but
not connections). That's not what happens for a real connection, where
remote peers are always created with an initial version of 0.
The mistake results in brokenness: when we subsequently receive a
topology update for that peer with the same version then we ignore it,
even though the update contains connection information which is new to
us.
Related, it is conceptually wrong to call FetchWithDefault on the
remote router. That is not what happens for a real connection - the
FetchWithDefault occurs in the symmetric counterpart.
The kernel processes vport deletion asynchronously, meaning that we can
sometimes fail to recreate vxlan vports on startup with an EADDRINUSE
error. We compensate by retrying a small number of times with a short
sleep on encountering this error, failing as before on a different error
or exhaustion of retries.
Prior to optional encryption support, enabling encryption disabled the
fast datapath overlay (because it doesn't support encryption) but left
the OVS datapath netdev in place for bridging (so that users could
switch encryption on and off without resetting the bridge). In this
situation the ODP miss handler is guaranteed to be invoked for every
packet, so as an optimisation the weave script configured the router to
use pcap to capture packets from the bridge as that is slightly more
efficient. The introduction of optional encryption means the guarantee
no longer holds, and so the optimisation must be removed.
If overlay encryption is required between peers, the fast datapath
forwarder returns an error rather than aborting the process, allowing
the overlay switch to fall back gracefully to an encrypted sleeve
overlay connection.
Add a 'Trusted' feature to the protocol exchange which indicates whether
the remote considers us to be reachable via a secure network; overlay
encryption will be disabled in the event that both peers agree. For
backwards compatibility purposes a default value of untrusted is assumed
if the feature is missing.
Instead of calculating all routes in one go, we calculate them when
needed.
Except for unicast routes, and broadcast routes from ourself. We still
calculate those eagerly because they are needed to route locally
captured/fdp-missed packets, and performing route calculcations in
that critical path increases the chances of dropping packets due to
not keeping up.
Well, technically only the established & symmetric routes are needed
for the data plane, but we might as well calculate the equivalent
routes for the control plane - it keeps the code simple and uniform.
Calculating all routes is O(n_peers^2), so this change represents a
huge saving in situations where not all of them are needed, which is
quite common, especially when the topology is evolving rapidly.
One downside of this new approach is that we can no longer suppress
OnChange callbacks when the data plane routes remain unchanged. This
means we will be purging the FDP flows more frequently than before,
e.g. when only the control plane topology changed, e.g. new
connections appeared that haven't been marked as 'established'
yet. It's a small price to pay, fixable if we really care, and in any
case making FDP flow invalidation more fine-grained would be a better
approach.
Fixes#1761.