+ The ct
action
+- ct(argument
]...)
++ ct(
[argument
]...)
+ ct(commit
[, argument
]...)
+
+
+@@ -1816,6 +1816,16 @@ for i in [1,n_slaves]:
+ connection, will behave the same as a bare nat
.
+
+
++
++ For SNAT, there is a special case when the src
IP
++ address is configured as all 0's, i.e.,
++ nat(src=0.0.0.0)
. In this case, when a source port
++ collision is detected during the commit, the source port will be
++ translated to an ephemeral port. If there is no collision, no SNAT
++ is performed. Note that this is currently only implemented in the
++ Linux kernel datapath.
++
++
+
+ Open vSwitch 2.6 introduced nat
. Linux 4.6 was the
+ earliest upstream kernel that implemented ct
support for
diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c
index ebc8120f0f..cde1e925ba 100644
--- a/lib/ovs-rcu.c
@@ -84313,6 +84692,19 @@ index d31c0953ed..0dc62bd83f 100644
};
/* assert that if we overflow with a masked write of uint32_t to the last byte
+diff --git a/lib/tun-metadata.c b/lib/tun-metadata.c
+index f8a0e19524..d177333297 100644
+--- a/lib/tun-metadata.c
++++ b/lib/tun-metadata.c
+@@ -811,7 +811,7 @@ tun_metadata_to_geneve_nlattr(const struct flow_tnl *tun,
+ } else {
+ tun_metadata_to_geneve_nlattr_mask(key, tun, flow, b);
+ }
+- } else if (flow->metadata.present.len || is_mask) {
++ } else {
+ nl_msg_put_unspec(b, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
+ tun->metadata.opts.gnv,
+ flow->metadata.present.len);
diff --git a/lib/util.c b/lib/util.c
index 830e14516f..25635b27ff 100644
--- a/lib/util.c
@@ -84432,10 +84824,10 @@ index 51d656cba9..fd926cbb82 100644
struct rconn_packet_counter *counter = ofconn->monitor_counter;
diff --git a/ofproto/ipfix-gen-entities b/ofproto/ipfix-gen-entities
-index 0be719967d..d5abe9c2ed 100755
+index 0be719967d..dcecdab212 100755
--- a/ofproto/ipfix-gen-entities
+++ b/ofproto/ipfix-gen-entities
-@@ -1,6 +1,6 @@
+@@ -1,14 +1,12 @@
-#! /usr/bin/env python
+#!/usr/bin/env python3
#
@@ -84444,6 +84836,14 @@ index 0be719967d..d5abe9c2ed 100755
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
+ # notice and this notice are preserved. This file is offered as-is,
+ # without warranty of any kind.
+
+-from __future__ import print_function
+-
+ import getopt
+ import re
+ import sys
diff --git a/ofproto/ofproto-dpif-rid.h b/ofproto/ofproto-dpif-rid.h
index 147ef9c333..97699cb905 100644
--- a/ofproto/ofproto-dpif-rid.h
@@ -84626,10 +85026,43 @@ index 4407f9c97a..04a75e12d3 100644
&ctx.xbridge->ofproto->up);
}
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
-index d3cb392077..4d1048f70c 100644
+index d3cb392077..12a1d3ca7e 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
-@@ -5375,6 +5375,8 @@ ct_add_timeout_policy_to_dpif(struct dpif *dpif,
+@@ -1381,6 +1381,24 @@ check_ct_timeout_policy(struct dpif_backer *backer)
+ return !error;
+ }
+
++/* Tests whether 'backer''s datapath supports the all-zero SNAT case. */
++static bool
++dpif_supports_ct_zero_snat(struct dpif_backer *backer)
++{
++ enum ct_features features;
++ bool supported = false;
++
++ if (!ct_dpif_get_features(backer->dpif, &features)) {
++ if (features & CONNTRACK_F_ZERO_SNAT) {
++ supported = true;
++ }
++ }
++ VLOG_INFO("%s: Datapath %s ct_zero_snat",
++ dpif_name(backer->dpif), (supported) ? "supports"
++ : "does not support");
++ return supported;
++}
++
+ /* Tests whether 'backer''s datapath supports the
+ * OVS_ACTION_ATTR_CHECK_PKT_LEN action. */
+ static bool
+@@ -1580,6 +1598,7 @@ check_support(struct dpif_backer *backer)
+ backer->rt_support.ct_timeout = check_ct_timeout_policy(backer);
+ backer->rt_support.explicit_drop_action =
+ dpif_supports_explicit_drop_action(backer->dpif);
++ backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer);
+
+ /* Flow fields. */
+ backer->rt_support.odp.ct_state = check_ct_state(backer);
+@@ -5375,6 +5394,8 @@ ct_add_timeout_policy_to_dpif(struct dpif *dpif,
struct ct_dpif_timeout_policy cdtp;
struct simap_node *node;
@@ -84638,10 +85071,61 @@ index d3cb392077..4d1048f70c 100644
cdtp.id = ct_tp->tp_id;
SIMAP_FOR_EACH (node, &ct_tp->tp) {
ct_dpif_set_timeout_policy_attr_by_name(&cdtp, node->name, node->data);
+@@ -5563,6 +5584,7 @@ get_datapath_cap(const char *datapath_type, struct smap *cap)
+ smap_add(cap, "ct_timeout", s.ct_timeout ? "true" : "false");
+ smap_add(cap, "explicit_drop_action",
+ s.explicit_drop_action ? "true" :"false");
++ smap_add(cap, "ct_zero_snat", s.ct_zero_snat ? "true" : "false");
+ }
+
+ /* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and
+diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
+index c9d5df34b0..4d1f126910 100644
+--- a/ofproto/ofproto-dpif.h
++++ b/ofproto/ofproto-dpif.h
+@@ -202,7 +202,10 @@ struct group_dpif *group_dpif_lookup(struct ofproto_dpif *,
+ DPIF_SUPPORT_FIELD(bool, ct_timeout, "Conntrack timeout policy") \
+ \
+ /* True if the datapath supports explicit drop action. */ \
+- DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop action")
++ DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop action") \
++ \
++ /* True if the datapath supports all-zero IP SNAT. */ \
++ DPIF_SUPPORT_FIELD(bool, ct_zero_snat, "Conntrack all-zero IP SNAT")
+
+
+ /* Stores the various features which the corresponding backer supports. */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
-index 08830d8371..8594afad4a 100644
+index 08830d8371..4e9569e4ad 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
+@@ -961,7 +961,7 @@ ofproto_get_datapath_cap(const char *datapath_type, struct smap *dp_cap)
+ datapath_type = ofproto_normalize_type(datapath_type);
+ const struct ofproto_class *class = ofproto_class_find__(datapath_type);
+
+- if (class->get_datapath_cap) {
++ if (class && class->get_datapath_cap) {
+ class->get_datapath_cap(datapath_type, dp_cap);
+ }
+ }
+@@ -974,7 +974,7 @@ ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id,
+ datapath_type = ofproto_normalize_type(datapath_type);
+ const struct ofproto_class *class = ofproto_class_find__(datapath_type);
+
+- if (class->ct_set_zone_timeout_policy) {
++ if (class && class->ct_set_zone_timeout_policy) {
+ class->ct_set_zone_timeout_policy(datapath_type, zone_id,
+ timeout_policy);
+ }
+@@ -986,7 +986,7 @@ ofproto_ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id)
+ datapath_type = ofproto_normalize_type(datapath_type);
+ const struct ofproto_class *class = ofproto_class_find__(datapath_type);
+
+- if (class->ct_del_zone_timeout_policy) {
++ if (class && class->ct_del_zone_timeout_policy) {
+ class->ct_del_zone_timeout_policy(datapath_type, zone_id);
+ }
+
@@ -6077,8 +6077,8 @@ ofproto_rule_send_removed(struct rule *rule)
fr.hard_timeout = rule->hard_timeout;
ovs_mutex_unlock(&rule->mutex);
@@ -84755,10 +85239,17 @@ index 406c293114..10d0c0c134 100755
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in
-index c285ee4b3c..e296bb6d4f 100755
+index c285ee4b3c..9bec653421 100755
--- a/ovsdb/ovsdb-idlc.in
+++ b/ovsdb/ovsdb-idlc.in
-@@ -279,13 +279,21 @@ const struct %(s)s *%(s)s_table_track_get_first(const struct %(s)s_table *);
+@@ -1,6 +1,5 @@
+ #! @PYTHON3@
+
+-from __future__ import print_function
+ import getopt
+ import os
+ import re
+@@ -279,13 +278,21 @@ const struct %(s)s *%(s)s_table_track_get_first(const struct %(s)s_table *);
(ROW) = %(s)s_track_get_next(ROW))
@@ -84783,7 +85274,7 @@ index c285ee4b3c..e296bb6d4f 100755
static inline bool %(s)s_is_deleted(const struct %(s)s *row)
{
return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_DELETE) > 0;
-@@ -333,6 +341,14 @@ struct %(s)s *%(s)s_cursor_data(struct ovsdb_idl_cursor *);
+@@ -333,6 +340,14 @@ struct %(s)s *%(s)s_cursor_data(struct ovsdb_idl_cursor *);
void %(s)s_init(struct %(s)s *);
void %(s)s_delete(const struct %(s)s *);
struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
@@ -84826,7 +85317,7 @@ index 338f3bc299..b8bd1c2d57 100644
.so lib/vlog-unixctl.man
.so lib/memory-unixctl.man
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
-index b6957d7300..54ed7c4283 100644
+index b6957d7300..2bc0a69066 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -76,8 +76,12 @@ static char *ssl_protocols;
@@ -84913,7 +85404,36 @@ index b6957d7300..54ed7c4283 100644
if (error) {
break;
}
-@@ -1481,7 +1495,8 @@ ovsdb_server_compact(struct unixctl_conn *conn, int argc,
+@@ -637,8 +651,6 @@ add_db(struct server_config *config, struct db *db)
+ static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
+ open_db(struct server_config *config, const char *filename)
+ {
+- struct db *db;
+-
+ /* If we know that the file is already open, return a good error message.
+ * Otherwise, if the file is open, we'll fail later on with a harder to
+ * interpret file locking error. */
+@@ -653,9 +665,6 @@ open_db(struct server_config *config, const char *filename)
+ return error;
+ }
+
+- db = xzalloc(sizeof *db);
+- db->filename = xstrdup(filename);
+-
+ struct ovsdb_schema *schema;
+ if (ovsdb_storage_is_clustered(storage)) {
+ schema = NULL;
+@@ -668,6 +677,9 @@ open_db(struct server_config *config, const char *filename)
+ }
+ ovs_assert(schema && !txn_json);
+ }
++
++ struct db *db = xzalloc(sizeof *db);
++ db->filename = xstrdup(filename);
+ db->db = ovsdb_create(schema, storage);
+ ovsdb_jsonrpc_server_add_db(config->jsonrpc, db->db);
+
+@@ -1481,7 +1493,8 @@ ovsdb_server_compact(struct unixctl_conn *conn, int argc,
VLOG_INFO("compacting %s database by user request",
node->name);
@@ -84923,7 +85443,7 @@ index b6957d7300..54ed7c4283 100644
if (error) {
char *s = ovsdb_error_to_string(error);
ds_put_format(&reply, "%s\n", s);
-@@ -1504,6 +1519,35 @@ ovsdb_server_compact(struct unixctl_conn *conn, int argc,
+@@ -1504,6 +1517,35 @@ ovsdb_server_compact(struct unixctl_conn *conn, int argc,
ds_destroy(&reply);
}
@@ -85733,8 +86253,21 @@ index 9852786466..8bbcd824f4 100644
@@ -1 +1,2 @@
version.py
+dirs.py
+diff --git a/python/ovs/compat/sortedcontainers/sortedlist.py b/python/ovs/compat/sortedcontainers/sortedlist.py
+index 8aec6bbac1..ba55566926 100644
+--- a/python/ovs/compat/sortedcontainers/sortedlist.py
++++ b/python/ovs/compat/sortedcontainers/sortedlist.py
+@@ -3,8 +3,6 @@
+ """
+ # pylint: disable=redefined-builtin, ungrouped-imports
+
+-from __future__ import print_function
+-
+ from bisect import bisect_left, bisect_right, insort
+ from collections import Sequence, MutableSequence
+ from functools import wraps
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
-index 020291d486..4226d1cb2f 100644
+index 020291d486..4cf79cf94e 100644
--- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.py
@@ -12,6 +12,7 @@
@@ -85756,7 +86289,60 @@ index 020291d486..4226d1cb2f 100644
class Idl(object):
"""Open vSwitch Database Interface Definition Language (OVSDB IDL).
-@@ -614,6 +619,7 @@ class Idl(object):
+@@ -241,6 +246,7 @@ class Idl(object):
+ i = 0
+ while i < 50:
+ i += 1
++ previous_change_seqno = self.change_seqno
+ if not self._session.is_connected():
+ break
+
+@@ -269,7 +275,7 @@ class Idl(object):
+ if msg.params[0] == str(self.server_monitor_uuid):
+ self.__parse_update(msg.params[1], OVSDB_UPDATE,
+ tables=self.server_tables)
+- self.change_seqno = initial_change_seqno
++ self.change_seqno = previous_change_seqno
+ if not self.__check_server_db():
+ self.force_reconnect()
+ break
+@@ -312,7 +318,7 @@ class Idl(object):
+ self.__error()
+ break
+ else:
+- self.change_seqno = initial_change_seqno
++ self.change_seqno = previous_change_seqno
+ self.__send_monitor_request()
+ elif (msg.type == ovs.jsonrpc.Message.T_REPLY
+ and self._server_monitor_request_id is not None
+@@ -322,7 +328,7 @@ class Idl(object):
+ self._server_monitor_request_id = None
+ self.__parse_update(msg.result, OVSDB_UPDATE,
+ tables=self.server_tables)
+- self.change_seqno = initial_change_seqno
++ self.change_seqno = previous_change_seqno
+ if self.__check_server_db():
+ self.__send_monitor_request()
+ self.__send_db_change_aware()
+@@ -336,7 +342,7 @@ class Idl(object):
+ self.__error()
+ break
+ else:
+- self.change_seqno = initial_change_seqno
++ self.change_seqno = previous_change_seqno
+ self.__send_monitor_request()
+ elif (msg.type == ovs.jsonrpc.Message.T_REPLY
+ and self._db_change_aware_request_id is not None
+@@ -372,7 +378,7 @@ class Idl(object):
+ self.force_reconnect()
+ break
+ else:
+- self.change_seqno = initial_change_seqno
++ self.change_seqno = previous_change_seqno
+ self.__send_monitor_request()
+ elif (msg.type in (ovs.jsonrpc.Message.T_ERROR,
+ ovs.jsonrpc.Message.T_REPLY)
+@@ -614,6 +620,7 @@ class Idl(object):
raise error.Error(" is not an object",
table_updates)
@@ -85764,7 +86350,7 @@ index 020291d486..4226d1cb2f 100644
for table_name, table_update in table_updates.items():
table = tables.get(table_name)
if not table:
-@@ -639,7 +645,9 @@ class Idl(object):
+@@ -639,7 +646,9 @@ class Idl(object):
% (table_name, uuid_string))
if version == OVSDB_UPDATE2:
@@ -85775,7 +86361,7 @@ index 020291d486..4226d1cb2f 100644
self.change_seqno += 1
continue
-@@ -652,17 +660,20 @@ class Idl(object):
+@@ -652,17 +661,20 @@ class Idl(object):
raise error.Error(' missing "old" and '
'"new" members', row_update)
@@ -85800,7 +86386,7 @@ index 020291d486..4226d1cb2f 100644
else:
# XXX rate-limit
vlog.warn("cannot delete missing row %s from table"
-@@ -681,29 +692,27 @@ class Idl(object):
+@@ -681,29 +693,27 @@ class Idl(object):
changed = self.__row_update(table, row, row_update)
table.rows[uuid] = row
if changed:
@@ -85835,7 +86421,7 @@ index 020291d486..4226d1cb2f 100644
else:
# XXX rate-limit
vlog.warn("cannot delete missing row %s from table %s"
-@@ -723,7 +732,7 @@ class Idl(object):
+@@ -723,7 +733,7 @@ class Idl(object):
if op == ROW_CREATE:
table.rows[uuid] = row
if changed:
@@ -85844,7 +86430,7 @@ index 020291d486..4226d1cb2f 100644
else:
op = ROW_UPDATE
if not row:
-@@ -737,8 +746,8 @@ class Idl(object):
+@@ -737,8 +747,8 @@ class Idl(object):
if op == ROW_CREATE:
table.rows[uuid] = row
if changed:
@@ -85855,7 +86441,7 @@ index 020291d486..4226d1cb2f 100644
def __check_server_db(self):
"""Returns True if this is a valid server database, False otherwise."""
-@@ -1567,10 +1576,9 @@ class Transaction(object):
+@@ -1567,10 +1577,9 @@ class Transaction(object):
for col, val in row._mutations['_inserts'].items():
column = row._table.columns[col]
if column.type.is_map():
@@ -85951,11 +86537,137 @@ index e9bb0c8548..f5a520862c 100644
@staticmethod
def needs_probes():
return True
+diff --git a/python/ovstest/rpcserver.py b/python/ovstest/rpcserver.py
+index c4aab70207..05b6b1be20 100644
+--- a/python/ovstest/rpcserver.py
++++ b/python/ovstest/rpcserver.py
+@@ -18,22 +18,14 @@ rpcserver is an XML RPC server that allows RPC client to initiate tests
+
+ import sys
+
+-import exceptions
+-
+ import xmlrpc.client
+
+-import tcp
+-
+ from twisted.internet import reactor
+ from twisted.internet.error import CannotListenError
+ from twisted.web import server
+ from twisted.web import xmlrpc
+
+-import udp
+-
+-import util
+-
+-import vswitch
++from . import tcp, udp, util, vswitch
+
+
+ class TestArena(xmlrpc.XMLRPC):
+@@ -210,7 +202,7 @@ class TestArena(xmlrpc.XMLRPC):
+ (_, port) = self.__get_handle_resources(handle)
+ port.loseConnection()
+ self.__delete_handle(handle)
+- except exceptions.KeyError:
++ except KeyError:
+ return -1
+ return 0
+
+@@ -222,7 +214,7 @@ class TestArena(xmlrpc.XMLRPC):
+ (_, connector) = self.__get_handle_resources(handle)
+ connector.disconnect()
+ self.__delete_handle(handle)
+- except exceptions.KeyError:
++ except KeyError:
+ return -1
+ return 0
+
+diff --git a/python/ovstest/tcp.py b/python/ovstest/tcp.py
+index c495717f2f..098c6cba3e 100644
+--- a/python/ovstest/tcp.py
++++ b/python/ovstest/tcp.py
+@@ -21,7 +21,7 @@ import time
+ from twisted.internet import interfaces
+ from twisted.internet.protocol import ClientFactory, Factory, Protocol
+
+-from zope.interface import implements
++from zope.interface.declarations import implementer
+
+
+ class TcpListenerConnection(Protocol):
+@@ -55,8 +55,8 @@ class TcpListenerFactory(Factory):
+ return str(self.stats)
+
+
++@implementer(interfaces.IPushProducer)
+ class Producer(object):
+- implements(interfaces.IPushProducer)
+ """
+ This producer class generates infinite byte stream for a specified time
+ duration
+diff --git a/python/ovstest/tests.py b/python/ovstest/tests.py
+index 6de3cc3af4..f959f945ef 100644
+--- a/python/ovstest/tests.py
++++ b/python/ovstest/tests.py
+@@ -10,8 +10,6 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-from __future__ import print_function
+-
+ import math
+ import time
+
+diff --git a/python/ovstest/util.py b/python/ovstest/util.py
+index 72457158f2..270d6a0376 100644
+--- a/python/ovstest/util.py
++++ b/python/ovstest/util.py
+@@ -26,8 +26,6 @@ import socket
+ import struct
+ import subprocess
+
+-import exceptions
+-
+ import xmlrpc.client
+
+
+@@ -88,7 +86,7 @@ def start_process(args):
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ return (p.returncode, out, err)
+- except exceptions.OSError:
++ except OSError:
+ return (-1, None, None)
+
+
+diff --git a/python/ovstest/vswitch.py b/python/ovstest/vswitch.py
+index 9d5b5cffd0..45c9587eeb 100644
+--- a/python/ovstest/vswitch.py
++++ b/python/ovstest/vswitch.py
+@@ -15,7 +15,7 @@
+ """
+ vswitch module allows its callers to interact with OVS DB.
+ """
+-import util
++from . import util
+
+
+ def ovs_vsctl_add_bridge(bridge):
diff --git a/python/setup.py b/python/setup.py
-index b7252800c1..d385d83722 100644
+index b7252800c1..cfe01763f3 100644
--- a/python/setup.py
+++ b/python/setup.py
-@@ -30,6 +30,15 @@ except IOError:
+@@ -10,8 +10,6 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-from __future__ import print_function
+-
+ import sys
+
+ from distutils.command.build_ext import build_ext
+@@ -30,6 +28,15 @@ except IOError:
file=sys.stderr)
sys.exit(-1)
@@ -85971,6 +86683,15 @@ index b7252800c1..d385d83722 100644
ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
if sys.platform == 'win32':
ext_errors += (IOError, ValueError)
+@@ -73,8 +80,6 @@ setup_args = dict(
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Topic :: System :: Networking',
+ 'License :: OSI Approved :: Apache Software License',
+- 'Programming Language :: Python :: 2',
+- 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in
index 7bc8c34b80..f6ec347c15 100644
--- a/rhel/openvswitch-fedora.spec.in
@@ -88512,6 +89233,28 @@ index 68c8774d1a..9d5e24a292 100644
# OVS_CHECK_VXLAN()
#
# Do basic check for vxlan functionality, skip the test if it's not there.
+diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at
+index daf66bdec8..26beefcf44 100644
+--- a/tests/system-kmod-macros.at
++++ b/tests/system-kmod-macros.at
+@@ -99,6 +99,17 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP],
+ #
+ m4_define([CHECK_CONNTRACK_NAT])
+
++# CHECK_CONNTRACK_ZEROIP_SNAT()
++#
++# Perform requirements checks for running conntrack all-zero IP SNAT tests.
++# The kernel always supports all-zero IP SNAT, so no check is needed.
++# However, the Windows datapath using the same netlink interface does not.
++#
++m4_define([CHECK_CONNTRACK_ZEROIP_SNAT],
++[
++ AT_SKIP_IF([test "$IS_WIN32" = "yes"])
++])
++
+ # CHECK_CONNTRACK_TIMEOUT()
+ #
+ # Perform requirements checks for running conntrack customized timeout tests.
diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at
index 379a8a5e92..bfad66e051 100644
--- a/tests/system-offloads-traffic.at
@@ -88605,10 +89348,71 @@ index 0000000000..1714273e35
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
-index 4a39c929c2..da61e4cae8 100644
+index 4a39c929c2..2bd7ef71fe 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
-@@ -611,6 +611,16 @@ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 10.1.1.100 | FORMAT_PING], [0], [dnl
+@@ -574,6 +574,60 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PI
+ OVS_TRAFFIC_VSWITCHD_STOP
+ AT_CLEANUP
+
++AT_SETUP([datapath - ping over geneve tunnel, delete flow regression])
++OVS_CHECK_GENEVE()
++
++OVS_TRAFFIC_VSWITCHD_START()
++ADD_BR([br-underlay])
++
++AT_DATA([flows.txt], [dnl
++priority=100,icmp actions=resubmit(,10)
++priority=0 actions=NORMAL
++table=10, priority=100, ip, actions=ct(table=20,zone=65520)
++table=20, priority=200, ip, ct_state=-new+trk, actions=resubmit(,30)
++table=20, priority=100, ip, ct_state=+new, actions=resubmit(,30)
++table=20, priority=50, ip, actions=DROP
++table=30, priority=100, ip, actions=ct(commit,table=40,zone=65520)
++table=40, actions=normal
++])
++
++AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
++AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
++
++ADD_NAMESPACES(at_ns0)
++
++dnl Set up underlay link from host into the namespace using veth pair.
++ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
++AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
++AT_CHECK([ip link set dev br-underlay up])
++
++dnl Set up tunnel endpoints on OVS outside the namespace and with a native
++dnl linux device inside the namespace.
++ADD_OVS_TUNNEL([geneve], [br0], [at_gnv0], [172.31.1.1], [10.1.1.100/24])
++ADD_NATIVE_TUNNEL([geneve], [ns_gnv0], [at_ns0], [172.31.1.100], [10.1.1.1/24],
++ [vni 0])
++
++dnl First, check the underlay
++NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl
++3 packets transmitted, 3 received, 0% packet loss, time 0ms
++])
++
++dnl ping over tunnel should work
++NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl
++3 packets transmitted, 3 received, 0% packet loss, time 0ms
++])
++
++AT_CHECK([ovs-ofctl del-flows br0 "ct_state=+new"])
++
++dnl ping should not go through after removal of the flow
++NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl
++7 packets transmitted, 0 received, 100% packet loss, time 0ms
++])
++
++OVS_TRAFFIC_VSWITCHD_STOP(["/|ERR|/d
++/|WARN|/d"])
++AT_CLEANUP
++
+ AT_SETUP([datapath - flow resume with geneve tun_metadata])
+ OVS_CHECK_GENEVE()
+
+@@ -611,6 +665,16 @@ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 10.1.1.100 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
@@ -88625,7 +89429,7 @@ index 4a39c929c2..da61e4cae8 100644
OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
-@@ -2331,6 +2341,35 @@ NXST_FLOW reply:
+@@ -2331,6 +2395,35 @@ NXST_FLOW reply:
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
@@ -88661,7 +89465,102 @@ index 4a39c929c2..da61e4cae8 100644
AT_SETUP([conntrack - ICMP related])
AT_SKIP_IF([test $HAVE_NC = no])
CHECK_CONNTRACK()
-@@ -5873,6 +5912,50 @@ ovs-appctl dpif/dump-flows br0
+@@ -4379,6 +4472,52 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=
+ OVS_TRAFFIC_VSWITCHD_STOP
+ AT_CLEANUP
+
++
++AT_SETUP([conntrack - all-zero IP SNAT])
++AT_SKIP_IF([test $HAVE_NC = no])
++CHECK_CONNTRACK()
++CHECK_CONNTRACK_ZEROIP_SNAT()
++OVS_TRAFFIC_VSWITCHD_START()
++
++ADD_NAMESPACES(at_ns0, at_ns1)
++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
++NS_CHECK_EXEC([at_ns0], [ip route add 172.1.1.0/24 via 10.1.1.2])
++
++OVS_START_L7([at_ns1], [http])
++
++AT_DATA([flows.txt], [dnl
++table=0,priority=30,ct_state=-trk,ip,action=ct(table=0)
++table=0,priority=20,ct_state=-rpl,ip,nw_dst=10.1.1.0/24,actions=ct(commit,nat(src=0.0.0.0),table=10)
++table=0,priority=20,ct_state=+rpl,ip,nw_dst=10.1.1.0/24,actions=resubmit(,10)
++table=0,priority=20,ip,nw_dst=172.1.1.2,actions=ct(commit,nat(dst=10.1.1.2),table=10)
++table=0,priority=10,arp,action=normal
++table=0,priority=1,action=drop
++table=10,priority=20,ct_state=+rpl,ip,nw_dst=10.1.1.0/24 actions=ct(table=20,nat)
++table=10,priority=10,ip,nw_dst=10.1.1.0/24 actions=resubmit(,20)
++table=20,priority=10,ip,nw_dst=10.1.1.1,action=1
++table=20,priority=10,ip,nw_dst=10.1.1.2,action=2
++])
++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
++
++dnl - Test to make sure src nat is NOT done when not needed
++NS_CHECK_EXEC([at_ns0], [echo "TEST" | nc -p 30000 10.1.1.2 80 > nc-1.log])
++AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [0], [dnl
++tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=30000,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=30000),protoinfo=(state=TIME_WAIT)
++])
++
++dnl - Test to make sure src nat is done when needed
++NS_CHECK_EXEC([at_ns0], [echo "TEST2" | nc -p 30001 172.1.1.2 80 > nc-2.log])
++NS_CHECK_EXEC([at_ns0], [echo "TEST3" | nc -p 30001 10.1.1.2 80 > nc-3.log])
++AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep 30001 | grep "orig=.src=10\.1\.1\.1," | sed -e 's/port=30001/port=/g' -e 's/sport=80,dport=[[0-9]]\+/sport=80,dport=/g' | sort], [0], [dnl
++tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=),protoinfo=(state=TIME_WAIT)
++tcp,orig=(src=10.1.1.1,dst=172.1.1.2,sport=,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=),protoinfo=(state=TIME_WAIT)
++])
++
++OVS_TRAFFIC_VSWITCHD_STOP
++AT_CLEANUP
++
++
+ AT_SETUP([conntrack - simple DNAT])
+ CHECK_CONNTRACK()
+ CHECK_CONNTRACK_NAT()
+@@ -4434,6 +4573,41 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=
+ OVS_TRAFFIC_VSWITCHD_STOP
+ AT_CLEANUP
+
++AT_SETUP([conntrack - DNAT with additional SNAT])
++CHECK_CONNTRACK()
++OVS_TRAFFIC_VSWITCHD_START()
++
++ADD_NAMESPACES(at_ns0, at_ns1)
++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
++NS_CHECK_EXEC([at_ns0], [ip route add 172.1.1.0/24 via 10.1.1.2])
++
++OVS_START_L7([at_ns1], [http])
++
++AT_DATA([flows.txt], [dnl
++table=0,priority=30,in_port=1,ip,nw_dst=172.1.1.2,actions=ct(commit,nat(dst=10.1.1.2:80),table=1)
++table=0,priority=20,in_port=2,ip,actions=ct(nat),1
++table=0,priority=10,arp,actions=NORMAL
++table=0,priority=1,actions=drop
++dnl Be sure all ct() actions but src nat are executed
++table=1,ip,actions=ct(commit,nat(src=10.1.1.240),exec(set_field:0xac->ct_mark,set_field:0xac->ct_label),table=2)
++table=2,in_port=1,ip,ct_mark=0xac,ct_label=0xac,actions=2
++])
++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
++
++NS_CHECK_EXEC([at_ns0], [wget http://172.1.1.2:8080 -t 5 -T 1 --retry-connrefused -v -o wget0.log])
++
++dnl - make sure only dst nat has been performed
++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.240)], [0], [dnl
++])
++
++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl
++tcp,orig=(src=10.1.1.1,dst=172.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),mark=172,labels=0xac,protoinfo=(state=)
++])
++
++OVS_TRAFFIC_VSWITCHD_STOP
++AT_CLEANUP
++
+ AT_SETUP([conntrack - more complex DNAT])
+ CHECK_CONNTRACK()
+ CHECK_CONNTRACK_NAT()
+@@ -5873,6 +6047,50 @@ ovs-appctl dpif/dump-flows br0
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
@@ -88712,6 +89611,27 @@ index 4a39c929c2..da61e4cae8 100644
AT_BANNER([802.1ad])
AT_SETUP([802.1ad - vlan_limit])
+diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at
+index ba7f4102f4..5c96f943df 100644
+--- a/tests/system-userspace-macros.at
++++ b/tests/system-userspace-macros.at
+@@ -96,6 +96,16 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP])
+ #
+ m4_define([CHECK_CONNTRACK_NAT])
+
++# CHECK_CONNTRACK_ZEROIP_SNAT()
++#
++# Perform requirements checks for running conntrack all-zero IP SNAT tests.
++# The userspace datapath does not support all-zero IP SNAT.
++#
++m4_define([CHECK_CONNTRACK_ZEROIP_SNAT],
++[
++ AT_SKIP_IF([:])
++])
++
+ # CHECK_CONNTRACK_TIMEOUT()
+ #
+ # Perform requirements checks for running conntrack customized timeout tests.
diff --git a/tests/system-userspace-packet-type-aware.at b/tests/system-userspace-packet-type-aware.at
index c2246316de..974304758f 100644
--- a/tests/system-userspace-packet-type-aware.at
@@ -88787,6 +89707,19 @@ index f77ee75e38..da1ac63b6c 100644
}
ovs_barrier_block(&barrier);
destroy_packets(pkt_batch);
+diff --git a/tests/test-jsonrpc.py b/tests/test-jsonrpc.py
+index 3eabcd78d5..1df5afa221 100644
+--- a/tests/test-jsonrpc.py
++++ b/tests/test-jsonrpc.py
+@@ -12,8 +12,6 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-from __future__ import print_function
+-
+ import argparse
+ import errno
+ import os
diff --git a/tests/test-l7.py b/tests/test-l7.py
index d7854a1df3..32a77392c6 100755
--- a/tests/test-l7.py
@@ -89689,6 +90622,19 @@ index 5a14e7fe58..bf0463e25c 100644
reconnect_set_name(reconnect, "remote");
reconnect_get_stats(reconnect, now, &prev);
printf("### t=%d ###\n", now);
+diff --git a/tests/test-reconnect.py b/tests/test-reconnect.py
+index 6cd052878e..ef669b0417 100644
+--- a/tests/test-reconnect.py
++++ b/tests/test-reconnect.py
+@@ -12,8 +12,6 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-from __future__ import print_function
+-
+ import errno
+ import sys
+
diff --git a/tests/test-sha1.c b/tests/test-sha1.c
index b7279db6aa..cc80888a7d 100644
--- a/tests/test-sha1.c
@@ -90008,6 +90954,18 @@ index e55bfc2ed5..987d211069 100755
self.mtime = time.time()
+diff --git a/utilities/checkpatch.py b/utilities/checkpatch.py
+index fc9e20bf1b..893244578a 100755
+--- a/utilities/checkpatch.py
++++ b/utilities/checkpatch.py
+@@ -13,7 +13,6 @@
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+-from __future__ import print_function
+
+ import email
+ import getopt
diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in
index 8c5cd70327..4156da20ef 100644
--- a/utilities/ovs-ctl.in
@@ -90217,6 +91175,39 @@ index f2cc3f7f2a..fbe6e4f560 100755
def main():
+diff --git a/utilities/ovs-l3ping.in b/utilities/ovs-l3ping.in
+index 92d32acb3f..1ece06457c 100644
+--- a/utilities/ovs-l3ping.in
++++ b/utilities/ovs-l3ping.in
+@@ -19,7 +19,7 @@ achieved by tunneling the control connection inside the tunnel itself.
+ """
+
+ import socket
+-import xmlrpclib
++import xmlrpc.client
+
+ import ovstest.args as args
+ import ovstest.tests as tests
+@@ -64,13 +64,13 @@ if __name__ == '__main__':
+ ps = get_packet_sizes(me, he, args.client[0])
+ tests.do_direct_tests(me, he, bandwidth, interval, ps)
+ except KeyboardInterrupt:
+- print "Terminating"
+- except xmlrpclib.Fault:
+- print "Couldn't contact peer"
++ print("Terminating")
++ except xmlrpc.client.Fault:
++ print("Couldn't contact peer")
+ except socket.error:
+- print "Couldn't contact peer"
+- except xmlrpclib.ProtocolError:
+- print "XMLRPC control channel was abruptly terminated"
++ print("Couldn't contact peer")
++ except xmlrpc.client.ProtocolError:
++ print("XMLRPC control channel was abruptly terminated")
+ finally:
+ if local_server is not None:
+ local_server.terminate()
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 3601890f40..ede7f1e61a 100644
--- a/utilities/ovs-ofctl.c
@@ -90262,6 +91253,62 @@ index 3601890f40..ede7f1e61a 100644
{ "mod-group", "switch group",
1, 2, ofctl_mod_group, OVS_RW },
{ "del-groups", "switch [group]",
+diff --git a/utilities/ovs-parse-backtrace.in b/utilities/ovs-parse-backtrace.in
+index d5506769a8..f44f05cd1e 100755
+--- a/utilities/ovs-parse-backtrace.in
++++ b/utilities/ovs-parse-backtrace.in
+@@ -70,7 +70,7 @@ result. Expected usage is for ovs-appctl backtrace to be piped in.""")
+ if os.path.exists(debug):
+ binary = debug
+
+- print "Binary: %s\n" % binary
++ print("Binary: %s\n" % binary)
+
+ stdin = sys.stdin.read()
+
+@@ -88,15 +88,15 @@ result. Expected usage is for ovs-appctl backtrace to be piped in.""")
+ for lines, count in traces:
+ longest = max(len(l) for l in lines)
+
+- print "Backtrace Count: %d" % count
++ print("Backtrace Count: %d" % count)
+ for line in lines:
+ match = re.search(r'\[(0x.*)]', line)
+ if match:
+- print "%s %s" % (line.ljust(longest),
+- addr2line(binary, match.group(1)))
++ print("%s %s" % (line.ljust(longest),
++ addr2line(binary, match.group(1))))
+ else:
+- print line
+- print
++ print(line)
++ print()
+
+
+ if __name__ == "__main__":
+diff --git a/utilities/ovs-pcap.in b/utilities/ovs-pcap.in
+index dddbee4dfb..6b5f63399e 100755
+--- a/utilities/ovs-pcap.in
++++ b/utilities/ovs-pcap.in
+@@ -14,8 +14,6 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-from __future__ import print_function
+-
+ import binascii
+ import getopt
+ import struct
+@@ -79,7 +77,7 @@ if __name__ == "__main__":
+ try:
+ options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
+ ['help', 'version'])
+- except getopt.GetoptException as geo:
++ except getopt.GetoptError as geo:
+ sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
+ sys.exit(1)
+
diff --git a/utilities/ovs-pipegen.py b/utilities/ovs-pipegen.py
index ee5797221c..a3b6a661de 100755
--- a/utilities/ovs-pipegen.py
@@ -90274,6 +91321,122 @@ index ee5797221c..a3b6a661de 100755
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+diff --git a/utilities/ovs-vlan-test.in b/utilities/ovs-vlan-test.in
+index 154573a9b5..de3ae16862 100755
+--- a/utilities/ovs-vlan-test.in
++++ b/utilities/ovs-vlan-test.in
+@@ -14,9 +14,9 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-import BaseHTTPServer
+ import getopt
+-import httplib
++import http.client
++import http.server
+ import os
+ import threading
+ import time
+@@ -84,7 +84,7 @@ class UDPReceiver:
+
+ try:
+ sock.bind((self.vlan_ip, self.vlan_port))
+- except socket.error, e:
++ except socket.error as e:
+ print_safe('Failed to bind to %s:%d with error: %s'
+ % (self.vlan_ip, self.vlan_port, e))
+ os._exit(1) #sys.exit only exits the current thread.
+@@ -95,7 +95,7 @@ class UDPReceiver:
+ data, _ = sock.recvfrom(4096)
+ except socket.timeout:
+ continue
+- except socket.error, e:
++ except socket.error as e:
+ print_safe('Failed to receive from %s:%d with error: %s'
+ % (self.vlan_ip, self.vlan_port, e))
+ os._exit(1)
+@@ -180,7 +180,7 @@ class VlanServer:
+ for _ in range(send_time * 2):
+ try:
+ send_packet(test_id, size, ip, port)
+- except socket.error, e:
++ except socket.error as e:
+ self.set_result(test_id, 'Failure: ' + str(e))
+ return
+ time.sleep(.5)
+@@ -194,15 +194,15 @@ class VlanServer:
+ def run(self):
+ self.udp_recv.start()
+ try:
+- BaseHTTPServer.HTTPServer((self.server_ip, self.server_port),
++ http.server.HTTPServer((self.server_ip, self.server_port),
+ VlanServerHandler).serve_forever()
+- except socket.error, e:
++ except socket.error as e:
+ print_safe('Failed to start control server: %s' % e)
+ self.udp_recv.stop()
+
+ return 1
+
+-class VlanServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
++class VlanServerHandler(http.server.BaseHTTPRequestHandler):
+ def do_GET(self):
+
+ #Guarantee three arguments.
+@@ -244,7 +244,7 @@ class VlanClient:
+ self.udp_recv = UDPReceiver(vlan_ip, vlan_port)
+
+ def request(self, resource):
+- conn = httplib.HTTPConnection(self.server_ip_port)
++ conn = http.client.HTTPConnection(self.server_ip_port)
+ conn.request('GET', resource)
+ return conn
+
+@@ -256,7 +256,7 @@ class VlanClient:
+ try:
+ conn = self.request('/start/recv')
+ data = conn.getresponse().read()
+- except (socket.error, httplib.HTTPException), e:
++ except (socket.error, http.client.HTTPException) as e:
+ error_msg(e)
+ return False
+
+@@ -277,7 +277,7 @@ class VlanClient:
+ send_packet(test_id, size, ip, port)
+ resp = self.request('/result/%d' % test_id).getresponse()
+ data = resp.read()
+- except (socket.error, httplib.HTTPException), e:
++ except (socket.error, http.client.HTTPException) as e:
+ error_msg(e)
+ return False
+
+@@ -302,7 +302,7 @@ class VlanClient:
+ try:
+ conn = self.request(resource)
+ test_id = conn.getresponse().read()
+- except (socket.error, httplib.HTTPException), e:
++ except (socket.error, http.client.HTTPException) as e:
+ error_msg(e)
+ return False
+
+@@ -335,7 +335,7 @@ class VlanClient:
+ try:
+ resp = self.request('/ping').getresponse()
+ data = resp.read()
+- except (socket.error, httplib.HTTPException), e:
++ except (socket.error, http.client.HTTPException) as e:
+ error_msg(e)
+ return False
+
+@@ -383,7 +383,7 @@ def main():
+ try:
+ options, args = getopt.gnu_getopt(sys.argv[1:], 'hVs',
+ ['help', 'version', 'server'])
+- except getopt.GetoptError, geo:
++ except getopt.GetoptError as geo:
+ print_safe('%s: %s\n' % (sys.argv[0], geo.msg))
+ return 1
+
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index bd3972636e..37cc72d401 100644
--- a/utilities/ovs-vsctl.c
@@ -90313,7 +91476,7 @@ index e591c26a6c..ce348b9d16 100644
}
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
-index 3ddaaefda8..11880f1d2f 100644
+index 3ddaaefda8..fd13281a7f 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -653,8 +653,9 @@
@@ -90392,6 +91555,22 @@ index 3ddaaefda8..11880f1d2f 100644
The Excess Burst Size (EBS) is measured in bytes and represents a
+@@ -5976,6 +6005,15 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
+ True if the datapath supports OVS_ACTION_ATTR_DROP. If false,
+ explicit drop action will not be sent to the datapath.
+
++
++ True if the datapath supports all-zero SNAT. This is a special case
++ if the src
IP address is configured as all 0's, i.e.,
++ nat(src=0.0.0.0)
. In this case, when a source port
++ collision is detected during the commit, the source port will be
++ translated to an ephemeral port. If there is no collision, no SNAT
++ is performed.
++
+
+
+
diff --git a/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update b/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update
index e7404e3b00..b8db881949 100755
--- a/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update
diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec
index a9c677d..00bd95a 100644
--- a/SPECS/openvswitch2.13.spec
+++ b/SPECS/openvswitch2.13.spec
@@ -59,7 +59,7 @@ Summary: Open vSwitch
Group: System Environment/Daemons daemon/database/utilities
URL: http://www.openvswitch.org/
Version: 2.13.0
-Release: 115%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist}
+Release: 117%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist}
# Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the
# lib/sflow*.[ch] files are SISSL
@@ -710,6 +710,14 @@ exit 0
%endif
%changelog
+* Sat Jul 17 2021 Open vSwitch CI - 2.13.0-117
+- Merging upstream branch-2.13
+ [1dbd295283c1533e979c2d7694168a6737c8d645]
+
+* Wed Jun 30 2021 Timothy Redaelli - 2.13.0-116
+- Merging 15251f0e1d datapath-windows: Specify external include ..
+ [f9d10a495b5d502d948a4c8e3c6301cfb942d6ac]
+
* Thu May 27 2021 Open vSwitch CI - 2.13.0-115
- Merging upstream branch-2.13
[190762bf5ce2ebac4f08d1505bcee11520f7be38]