diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch index 96ffd87..0cd0470 100644 --- a/SOURCES/openvswitch-2.17.0.patch +++ b/SOURCES/openvswitch-2.17.0.patch @@ -40,15 +40,17 @@ index 6cd38ff3ef..2e1bf25881 100755 fi diff --git a/.ci/linux-prepare.sh b/.ci/linux-prepare.sh -index 1fe890846e..321b9bf86e 100755 +index 1fe890846e..e5f69b496b 100755 --- a/.ci/linux-prepare.sh +++ b/.ci/linux-prepare.sh -@@ -27,7 +27,7 @@ cd .. +@@ -26,8 +26,8 @@ cd .. + # https://github.com/pypa/pip/issues/10655 pip3 install --disable-pip-version-check --user wheel pip3 install --disable-pip-version-check --user \ - flake8 'hacking>=3.0' sphinx setuptools pyelftools +- flake8 'hacking>=3.0' sphinx setuptools pyelftools -pip3 install --user 'meson==0.49.2' -+pip3 install --user 'meson==0.53.2' ++ flake8 sphinx setuptools pyelftools ++pip3 install --user 'meson>=1.4,<1.5' if [ "$M32" ]; then # Installing 32-bit libraries. @@ -66,7 +68,7 @@ index f8facebeb0..36c4d9e4e4 100755 if [ "$CC" = "clang" ]; then make CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument" diff --git a/.cirrus.yml b/.cirrus.yml -index a7ae793bc4..e910576a7a 100644 +index a7ae793bc4..76b8a1c712 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,8 +2,8 @@ freebsd_build_task: @@ -75,16 +77,23 @@ index a7ae793bc4..e910576a7a 100644 matrix: - image_family: freebsd-12-2-snap - image_family: freebsd-11-4-snap -+ image_family: freebsd-13-2-snap ++ image_family: freebsd-13-3-snap + image_family: freebsd-14-0-snap cpu: 4 memory: 4G diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml -index eac3504e48..29c20153a3 100644 +index eac3504e48..12bc2d3bff 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml -@@ -6,7 +6,7 @@ jobs: +@@ -2,11 +2,14 @@ name: Build and Test + + on: [push, pull_request] + ++env: ++ python_default: 3.12 ++ + jobs: build-linux: env: dependencies: | @@ -93,7 +102,7 @@ index eac3504e48..29c20153a3 100644 libssl-dev llvm-dev libelf-dev libnuma-dev libpcap-dev \ ninja-build selinux-policy-dev deb_dependencies: | -@@ -22,10 +22,11 @@ jobs: +@@ -22,10 +25,11 @@ jobs: LIBS: ${{ matrix.libs }} M32: ${{ matrix.m32 }} OPTS: ${{ matrix.opts }} @@ -106,7 +115,7 @@ index eac3504e48..29c20153a3 100644 timeout-minutes: 30 strategy: -@@ -37,12 +38,17 @@ jobs: +@@ -37,12 +41,17 @@ jobs: - compiler: clang opts: --disable-ssl @@ -126,7 +135,7 @@ index eac3504e48..29c20153a3 100644 asan: asan - compiler: gcc -@@ -72,16 +78,16 @@ jobs: +@@ -72,16 +81,16 @@ jobs: kernel_list: 5.8 5.5 5.4 4.19 - compiler: gcc @@ -147,7 +156,7 @@ index eac3504e48..29c20153a3 100644 - compiler: gcc dpdk: dpdk -@@ -111,7 +117,7 @@ jobs: +@@ -111,7 +120,7 @@ jobs: steps: - name: checkout @@ -156,16 +165,19 @@ index eac3504e48..29c20153a3 100644 - name: update PATH run: | -@@ -119,7 +125,7 @@ jobs: +@@ -119,9 +128,9 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: set up python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: '3.9' +- python-version: '3.9' ++ python-version: ${{ env.python_default }} -@@ -135,7 +141,7 @@ jobs: + - name: create ci signature file for the dpdk cache key + if: matrix.dpdk != '' || matrix.dpdk_shared != '' +@@ -135,7 +144,7 @@ jobs: - name: cache if: matrix.dpdk != '' || matrix.dpdk_shared != '' @@ -174,7 +186,22 @@ index eac3504e48..29c20153a3 100644 env: matrix_key: ${{ matrix.dpdk }}${{ matrix.dpdk_shared }} ci_key: ${{ hashFiles('dpdk-ci-signature') }} -@@ -163,7 +169,7 @@ jobs: +@@ -155,6 +164,14 @@ jobs: + if: matrix.m32 == '' + run: sudo apt install -y libunbound-dev libunwind-dev + ++ - name: Reduce ASLR entropy ++ if: matrix.asan != '' ++ # Asan in llvm 14 provided in ubuntu-22.04 is incompatible with ++ # high-entropy ASLR configured in much newer kernels that GitHub ++ # runners are using leading to random crashes: ++ # https://github.com/actions/runner-images/issues/9491 ++ run: sudo sysctl -w vm.mmap_rnd_bits=28 ++ + - name: prepare + run: ./.ci/linux-prepare.sh + +@@ -163,7 +180,7 @@ jobs: - name: upload deb packages if: matrix.deb_package != '' @@ -183,7 +210,7 @@ index eac3504e48..29c20153a3 100644 with: name: deb-packages path: '/home/runner/work/ovs/*.deb' -@@ -171,9 +177,9 @@ jobs: +@@ -171,9 +188,9 @@ jobs: - name: copy logs on failure if: failure() || cancelled() run: | @@ -195,7 +222,7 @@ index eac3504e48..29c20153a3 100644 # So, we're just archiving everything here to avoid any issues. mkdir logs cp config.log ./logs/ -@@ -182,7 +188,7 @@ jobs: +@@ -182,7 +199,7 @@ jobs: - name: upload logs on failure if: failure() || cancelled() @@ -204,7 +231,7 @@ index eac3504e48..29c20153a3 100644 with: name: logs-linux-${{ join(matrix.*, '-') }} path: logs.tgz -@@ -201,13 +207,13 @@ jobs: +@@ -201,15 +218,15 @@ jobs: steps: - name: checkout @@ -218,9 +245,12 @@ index eac3504e48..29c20153a3 100644 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: '3.9' +- python-version: '3.9' ++ python-version: ${{ env.python_default }} - name: install dependencies -@@ -218,7 +224,7 @@ jobs: + run: brew install automake libtool + - name: prepare +@@ -218,7 +235,7 @@ jobs: run: ./.ci/osx-build.sh - name: upload logs on failure if: failure() @@ -311,10 +341,10 @@ index d9f44055db..fff49007e9 100644 #. Configure and install DPDK using Meson diff --git a/Documentation/intro/install/general.rst b/Documentation/intro/install/general.rst -index c4300cd53e..a297aadac8 100644 +index c4300cd53e..4867ebb7bb 100644 --- a/Documentation/intro/install/general.rst +++ b/Documentation/intro/install/general.rst -@@ -169,7 +169,7 @@ other than plain text, only if you have the following: +@@ -169,17 +169,14 @@ other than plain text, only if you have the following: If you are going to extensively modify Open vSwitch, consider installing the following to obtain better warnings: @@ -323,6 +353,17 @@ index c4300cd53e..a297aadac8 100644 (https://git.kernel.org/pub/scm/devel/sparse/sparse.git/). - GNU make. + + - clang, version 3.4 or later + +-- flake8 along with the hacking flake8 plugin (for Python code). The automatic +- flake8 check that runs against Python code has some warnings enabled that +- come from the "hacking" flake8 plugin. If it's not installed, the warnings +- just won't occur until it's run on a system with "hacking" installed. ++- flake8 (for Python code) + + You may find the ovs-dev script found in ``utilities/ovs-dev.py`` useful. + diff --git a/Documentation/ref/ovs-actions.7.rst b/Documentation/ref/ovs-actions.7.rst index b59b7634fa..36adcc5db2 100644 --- a/Documentation/ref/ovs-actions.7.rst @@ -449,7 +490,7 @@ index 27be4aa412..1dc406170f 100644 +.. |emeritus-status| replace:: `Emeritus Status for OVS Committers + `__ diff --git a/Makefile.am b/Makefile.am -index cb8076433e..22227c4957 100644 +index cb8076433e..70c9c62b13 100644 --- a/Makefile.am +++ b/Makefile.am @@ -368,7 +368,7 @@ ALL_LOCAL += manpage-check @@ -461,7 +502,23 @@ index cb8076433e..22227c4957 100644 if grep warning: $@.tmp; then error=:; fi; \ rm -f $@.tmp; \ done; \ -@@ -414,7 +414,7 @@ endif +@@ -398,23 +398,17 @@ ALL_LOCAL += flake8-check + # F811 redefinition of unused from line (only from flake8 v2.0) + # D*** -- warnings from flake8-docstrings plugin + # H*** -- warnings from flake8 hacking plugin (custom style checks beyond PEP8) +-# H231 Python 3.x incompatible 'except x,y:' construct +-# H232 Python 3.x incompatible octal 077 should be written as 0o77 +-# H233 Python 3.x incompatible use of print operator +-# H238 old style class declaration, use new style (inherit from `object`) +-FLAKE8_SELECT = H231,H232,H233,H238 + FLAKE8_IGNORE = E121,E123,E125,E126,E127,E128,E129,E131,E722,W503,W504,F811,D,H,I + flake8-check: $(FLAKE8_PYFILES) + $(FLAKE8_WERROR)$(AM_V_GEN) \ + src='$^' && \ +- flake8 $$src --select=$(FLAKE8_SELECT) $(FLAKE8_FLAGS) && \ + flake8 $$src --ignore=$(FLAKE8_IGNORE) $(FLAKE8_FLAGS) && \ + touch $@ + endif CLEANFILES += flake8-check -include manpages.mk @@ -95493,7 +95550,7 @@ index 5cd3f013ea..ec88500242 100644 /* Declare the same functions as the real rte_memcpy.h, without defining them. * This gives sparse the information it needs without provoking sparse's diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in -index a8b0705d9f..631a8fca80 100755 +index a8b0705d9f..1ffce61544 100755 --- a/ipsec/ovs-monitor-ipsec.in +++ b/ipsec/ovs-monitor-ipsec.in @@ -337,7 +337,14 @@ conn prevent_unencrypted_vxlan @@ -95512,7 +95569,40 @@ index a8b0705d9f..631a8fca80 100755 subprocess.call([self.IPSEC, "rereadsecrets"]) # "ipsec update" command does not remove those tunnels that were # updated or that disappeared from the ipsec.conf file. So, we have -@@ -708,6 +715,11 @@ conn prevent_unencrypted_vxlan +@@ -446,14 +453,30 @@ conn prevent_unencrypted_vxlan + CERTKEY_PREFIX = "ovs_certkey_" + + def __init__(self, libreswan_root_prefix, args): ++ # Collect version infromation ++ self.IPSEC = libreswan_root_prefix + "/usr/sbin/ipsec" ++ proc = subprocess.Popen([self.IPSEC, "--version"], ++ stdout=subprocess.PIPE, ++ encoding="latin1") ++ pout, perr = proc.communicate() ++ ++ v = re.match("^Libreswan (.*)$", pout) ++ try: ++ version = int(v.group(1).split(".")[0]) ++ except: ++ version = 0 ++ ++ if version >= 4: ++ ipsec_d = args.ipsec_d if args.ipsec_d else "/var/lib/ipsec/nss" ++ else: ++ ipsec_d = args.ipsec_d if args.ipsec_d else "/etc/ipsec.d" ++ + ipsec_conf = args.ipsec_conf if args.ipsec_conf else "/etc/ipsec.conf" +- ipsec_d = args.ipsec_d if args.ipsec_d else "/etc/ipsec.d" + ipsec_secrets = (args.ipsec_secrets if args.ipsec_secrets + else "/etc/ipsec.secrets") + ipsec_ctl = (args.ipsec_ctl if args.ipsec_ctl + else "/run/pluto/pluto.ctl") + +- self.IPSEC = libreswan_root_prefix + "/usr/sbin/ipsec" + self.IPSEC_CONF = libreswan_root_prefix + ipsec_conf + self.IPSEC_SECRETS = libreswan_root_prefix + ipsec_secrets + self.IPSEC_D = "sql:" + libreswan_root_prefix + ipsec_d +@@ -708,6 +731,11 @@ conn prevent_unencrypted_vxlan not re.match(r".*need --listen.*", pout): break @@ -95600,7 +95690,7 @@ index 5708bf9c68..1a5b879944 100644 * To use it, insert the following code to where backtrace is * desired: diff --git a/lib/bfd.c b/lib/bfd.c -index 9698576d07..9af258917b 100644 +index 9698576d07..b8149e7897 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -586,7 +586,6 @@ bfd_put_packet(struct bfd *bfd, struct dp_packet *p, @@ -95654,6 +95744,21 @@ index 9698576d07..9af258917b 100644 msg->vers_diag = (BFD_VERSION << 5) | bfd->diag; msg->flags = (bfd->state & STATE_MASK) | bfd->flags; +@@ -1131,10 +1130,11 @@ bfd_set_state(struct bfd *bfd, enum state state, enum diag diag) + if (!VLOG_DROP_INFO(&rl)) { + struct ds ds = DS_EMPTY_INITIALIZER; + +- ds_put_format(&ds, "%s: BFD state change: %s->%s" +- " \"%s\"->\"%s\".\n", ++ ds_put_format(&ds, "%s: BFD state change: (bfd.SessionState: %s," ++ " bfd.LocalDiag: \"%s\") -> (bfd.SessionState: %s," ++ " bfd.LocalDiag: \"%s\")\n", + bfd->name, bfd_state_str(bfd->state), +- bfd_state_str(state), bfd_diag_str(bfd->diag), ++ bfd_diag_str(bfd->diag), bfd_state_str(state), + bfd_diag_str(diag)); + bfd_put_details(&ds, bfd); + VLOG_INFO("%s", ds_cstr(&ds)); diff --git a/lib/cfm.c b/lib/cfm.c index cc43e70e31..c3742f3de2 100644 --- a/lib/cfm.c @@ -95934,7 +96039,7 @@ index 4d411d19fd..7ece2eae2f 100644 int timeout_policy_update(struct conntrack *ct, struct timeout_policy *tp); int timeout_policy_delete(struct conntrack *ct, uint32_t tp_id); diff --git a/lib/conntrack.c b/lib/conntrack.c -index 33a1a92953..a85e9ba886 100644 +index 33a1a92953..a5d90dabaa 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -94,14 +94,13 @@ static bool valid_new(struct dp_packet *pkt, struct conn_key *); @@ -96965,7 +97070,18 @@ index 33a1a92953..a85e9ba886 100644 } /* Convert a conntrack address 'a' into an IP address 'b' based on 'dl_type'. -@@ -2623,11 +2490,14 @@ static void +@@ -2610,7 +2477,9 @@ tuple_to_conn_key(const struct ct_dpif_tuple *tuple, uint16_t zone, + key->src.icmp_type = tuple->icmp_type; + key->src.icmp_code = tuple->icmp_code; + key->dst.icmp_id = tuple->icmp_id; +- key->dst.icmp_type = reverse_icmp_type(tuple->icmp_type); ++ key->dst.icmp_type = (tuple->ip_proto == IPPROTO_ICMP) ++ ? reverse_icmp_type(tuple->icmp_type) ++ : reverse_icmp6_type(tuple->icmp_type); + key->dst.icmp_code = tuple->icmp_code; + } else { + key->src.port = tuple->src_port; +@@ -2623,11 +2492,14 @@ static void conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry, long long now) { @@ -96983,7 +97099,7 @@ index 33a1a92953..a85e9ba886 100644 ovs_mutex_lock(&conn->lock); entry->mark = conn->mark; -@@ -2635,7 +2505,7 @@ conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry, +@@ -2635,7 +2507,7 @@ conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry, long long expiration = conn->expiration - now; @@ -96992,18 +97108,29 @@ index 33a1a92953..a85e9ba886 100644 if (class->conn_get_protoinfo) { class->conn_get_protoinfo(conn, &entry->protoinfo); } -@@ -2683,10 +2553,21 @@ conntrack_dump_next(struct conntrack_dump *dump, struct ct_dpif_entry *entry) - if (!cm_node) { - break; - } -+ struct conn_key_node *keyn; - struct conn *conn; -- INIT_CONTAINER(conn, cm_node, cm_node); -- if ((!dump->filter_zone || conn->key.zone == dump->zone) && -- (conn->conn_type != CT_CONN_TYPE_UN_NAT)) { -+ -+ INIT_CONTAINER(keyn, cm_node, cm_node); +@@ -2668,25 +2540,29 @@ conntrack_dump_start(struct conntrack *ct, struct conntrack_dump *dump, + + dump->ct = ct; + *ptot_bkts = 1; /* Need to clean up the callers. */ ++ dump->cursor = cmap_cursor_start(&ct->conns); + return 0; + } + + int + conntrack_dump_next(struct conntrack_dump *dump, struct ct_dpif_entry *entry) + { +- struct conntrack *ct = dump->ct; + long long now = time_msec(); + +- for (;;) { +- struct cmap_node *cm_node = cmap_next_position(&ct->conns, +- &dump->cm_pos); +- if (!cm_node) { +- break; ++ struct conn_key_node *keyn; ++ struct conn *conn; + ++ CMAP_CURSOR_FOR_EACH_CONTINUE (keyn, cm_node, &dump->cursor) { + if (keyn->dir != CT_DIR_FWD) { + continue; + } @@ -97011,13 +97138,17 @@ index 33a1a92953..a85e9ba886 100644 + conn = CONTAINER_OF(keyn, struct conn, key_node[CT_DIR_FWD]); + if (conn_expired(conn, now)) { + continue; -+ } + } +- struct conn *conn; +- INIT_CONTAINER(conn, cm_node, cm_node); +- if ((!dump->filter_zone || conn->key.zone == dump->zone) && +- (conn->conn_type != CT_CONN_TYPE_UN_NAT)) { + + if ((!dump->filter_zone || keyn->key.zone == dump->zone)) { conn_to_ct_dpif_entry(conn, entry, now); return 0; } -@@ -2704,12 +2585,18 @@ conntrack_dump_done(struct conntrack_dump *dump OVS_UNUSED) +@@ -2704,12 +2580,18 @@ conntrack_dump_done(struct conntrack_dump *dump OVS_UNUSED) int conntrack_flush(struct conntrack *ct, const uint16_t *zone) { @@ -97039,7 +97170,7 @@ index 33a1a92953..a85e9ba886 100644 } } ovs_mutex_unlock(&ct->ct_lock); -@@ -2721,19 +2608,19 @@ int +@@ -2721,19 +2603,19 @@ int conntrack_flush_tuple(struct conntrack *ct, const struct ct_dpif_tuple *tuple, uint16_t zone) { @@ -97062,7 +97193,7 @@ index 33a1a92953..a85e9ba886 100644 error = ENOENT; } -@@ -2857,8 +2744,8 @@ expectation_clean(struct conntrack *ct, const struct conn_key *parent_key) +@@ -2857,8 +2739,8 @@ expectation_clean(struct conntrack *ct, const struct conn_key *parent_key) { ovs_rwlock_wrlock(&ct->resources_lock); @@ -97073,7 +97204,7 @@ index 33a1a92953..a85e9ba886 100644 conn_key_hash(parent_key, ct->hash_basis), &ct->alg_expectation_refs) { if (!conn_key_cmp(&node->parent_key, parent_key)) { -@@ -2877,50 +2764,54 @@ expectation_create(struct conntrack *ct, ovs_be16 dst_port, +@@ -2877,50 +2759,54 @@ expectation_create(struct conntrack *ct, ovs_be16 dst_port, const struct conn *parent_conn, bool reply, bool src_ip_wc, bool skip_nat) { @@ -97140,7 +97271,7 @@ index 33a1a92953..a85e9ba886 100644 sizeof alg_exp_node->parent_key); /* Take the write lock here because it is almost 100% * likely that the lookup will fail and -@@ -3172,12 +3063,16 @@ process_ftp_ctl_v4(struct conntrack *ct, +@@ -3172,12 +3058,16 @@ process_ftp_ctl_v4(struct conntrack *ct, switch (mode) { case CT_FTP_MODE_ACTIVE: @@ -97161,7 +97292,7 @@ index 33a1a92953..a85e9ba886 100644 break; case CT_TFTP_MODE: default: -@@ -3209,7 +3104,7 @@ skip_ipv6_digits(char *str) +@@ -3209,7 +3099,7 @@ skip_ipv6_digits(char *str) static enum ftp_ctl_pkt process_ftp_ctl_v6(struct conntrack *ct, struct dp_packet *pkt, @@ -97170,7 +97301,7 @@ index 33a1a92953..a85e9ba886 100644 union ct_addr *v6_addr_rep, char **ftp_data_start, size_t *addr_offset_from_ftp_data_start, size_t *addr_size, enum ct_alg_mode *mode) -@@ -3277,24 +3172,25 @@ process_ftp_ctl_v6(struct conntrack *ct, +@@ -3277,24 +3167,25 @@ process_ftp_ctl_v6(struct conntrack *ct, switch (*mode) { case CT_FTP_MODE_ACTIVE: @@ -97200,7 +97331,7 @@ index 33a1a92953..a85e9ba886 100644 !!(pkt->md.ct_state & CS_REPLY_DIR), false, false); return CT_FTP_CTL_INTEREST; } -@@ -3448,7 +3344,8 @@ handle_tftp_ctl(struct conntrack *ct, +@@ -3448,7 +3339,8 @@ handle_tftp_ctl(struct conntrack *ct, long long now OVS_UNUSED, enum ftp_ctl_pkt ftp_ctl OVS_UNUSED, bool nat OVS_UNUSED) { @@ -97210,6 +97341,19 @@ index 33a1a92953..a85e9ba886 100644 conn_for_expectation, !!(pkt->md.ct_state & CS_REPLY_DIR), false, false); } +diff --git a/lib/conntrack.h b/lib/conntrack.h +index 9553b188a4..7876e8d438 100644 +--- a/lib/conntrack.h ++++ b/lib/conntrack.h +@@ -100,7 +100,7 @@ void conntrack_clear(struct dp_packet *packet); + struct conntrack_dump { + struct conntrack *ct; + unsigned bucket; +- struct cmap_position cm_pos; ++ struct cmap_cursor cursor; + bool filter_zone; + uint16_t zone; + }; diff --git a/lib/cpu.c b/lib/cpu.c index 2df003c51b..e7cbfcfe6e 100644 --- a/lib/cpu.c @@ -102746,6 +102890,54 @@ index acf174927d..47c15bde7e 100644 uint32_t erspan_idx; uint8_t erspan_ver; uint8_t erspan_dir; +diff --git a/lib/netlink-protocol.h b/lib/netlink-protocol.h +index 6eaa7035a4..e4bb28ac9f 100644 +--- a/lib/netlink-protocol.h ++++ b/lib/netlink-protocol.h +@@ -155,6 +155,11 @@ enum { + #define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) + #endif + ++/* Introduced in v4.4. */ ++#ifndef NLM_F_DUMP_FILTERED ++#define NLM_F_DUMP_FILTERED 0x20 ++#endif ++ + /* These were introduced all together in 2.6.14. (We want our programs to + * support the newer kernel features even if compiled with older headers.) */ + #ifndef NETLINK_ADD_MEMBERSHIP +@@ -168,6 +173,11 @@ enum { + #define NETLINK_LISTEN_ALL_NSID 8 + #endif + ++/* Strict checking of netlink arguments introduced in Linux kernel v4.20. */ ++#ifndef NETLINK_GET_STRICT_CHK ++#define NETLINK_GET_STRICT_CHK 12 ++#endif ++ + /* These were introduced all together in 2.6.23. (We want our programs to + * support the newer kernel features even if compiled with older headers.) */ + #ifndef CTRL_ATTR_MCAST_GRP_MAX +diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c +index 93c1fa561c..b570d6142e 100644 +--- a/lib/netlink-socket.c ++++ b/lib/netlink-socket.c +@@ -205,6 +205,15 @@ nl_sock_create(int protocol, struct nl_sock **sockp) + } + } + ++ /* Strict checking only supported for NETLINK_ROUTE. */ ++ if (protocol == NETLINK_ROUTE ++ && setsockopt(sock->fd, SOL_NETLINK, NETLINK_GET_STRICT_CHK, ++ &one, sizeof one) < 0) { ++ VLOG_RL(&rl, errno == ENOPROTOOPT ? VLL_DBG : VLL_WARN, ++ "netlink: could not enable strict checking (%s)", ++ ovs_strerror(errno)); ++ } ++ + retval = get_socket_rcvbuf(sock->fd); + if (retval < 0) { + retval = -retval; diff --git a/lib/netlink.c b/lib/netlink.c index 8204025a56..6215282d6f 100644 --- a/lib/netlink.c @@ -103214,9 +103406,24 @@ index a956754f2d..f9bd3b7f9c 100644 i++; } diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c -index 271105bdea..879275a7a3 100644 +index 271105bdea..821265c12b 100644 --- a/lib/ofpbuf.c +++ b/lib/ofpbuf.c +@@ -179,12 +179,12 @@ ofpbuf_clone_with_headroom(const struct ofpbuf *b, size_t headroom) + struct ofpbuf *new_buffer; + + new_buffer = ofpbuf_clone_data_with_headroom(b->data, b->size, headroom); +- if (b->header) { ++ if (new_buffer->data && b->header) { + ptrdiff_t header_offset = (char *) b->header - (char *) b->data; + + new_buffer->header = (char *) new_buffer->data + header_offset; + } +- if (b->msg) { ++ if (new_buffer->data && b->msg) { + ptrdiff_t msg_offset = (char *) b->msg - (char *) b->data; + + new_buffer->msg = (char *) new_buffer->data + msg_offset; @@ -426,6 +426,10 @@ void ofpbuf_reserve(struct ofpbuf *b, size_t size) { @@ -104300,6 +104507,172 @@ index a929ddfd2d..89a0bcaf95 100644 if (deadline != LLONG_MAX) { long long int remaining = deadline - now; return MAX(0, MIN(INT_MAX, remaining)); +diff --git a/lib/route-table.c b/lib/route-table.c +index ac82cf262f..6df7237e10 100644 +--- a/lib/route-table.c ++++ b/lib/route-table.c +@@ -26,6 +26,7 @@ + #include + #include + ++#include "coverage.h" + #include "hash.h" + #include "netdev.h" + #include "netlink.h" +@@ -44,6 +45,8 @@ + + VLOG_DEFINE_THIS_MODULE(route_table); + ++COVERAGE_DEFINE(route_table_dump); ++ + struct route_data { + /* Copied from struct rtmsg. */ + unsigned char rtm_dst_len; +@@ -79,7 +82,7 @@ static struct nln_notifier *name_notifier = NULL; + + static bool route_table_valid = false; + +-static int route_table_reset(void); ++static void route_table_reset(void); + static void route_table_handle_msg(const struct route_table_msg *); + static int route_table_parse(struct ofpbuf *, struct route_table_msg *); + static void route_table_change(const struct route_table_msg *, void *); +@@ -152,26 +155,22 @@ route_table_wait(void) + ovs_mutex_unlock(&route_table_mutex); + } + +-static int +-route_table_reset(void) ++static bool ++route_table_dump_one_table(unsigned char id) + { +- struct nl_dump dump; +- struct rtgenmsg *rtgenmsg; + uint64_t reply_stub[NL_DUMP_BUFSIZE / 8]; + struct ofpbuf request, reply, buf; +- +- route_map_clear(); +- netdev_get_addrs_list_flush(); +- route_table_valid = true; +- rt_change_seq++; ++ struct rtmsg *rq_msg; ++ bool filtered = true; ++ struct nl_dump dump; + + ofpbuf_init(&request, 0); + +- nl_msg_put_nlmsghdr(&request, sizeof *rtgenmsg, RTM_GETROUTE, +- NLM_F_REQUEST); ++ nl_msg_put_nlmsghdr(&request, sizeof *rq_msg, RTM_GETROUTE, NLM_F_REQUEST); + +- rtgenmsg = ofpbuf_put_zeros(&request, sizeof *rtgenmsg); +- rtgenmsg->rtgen_family = AF_UNSPEC; ++ rq_msg = ofpbuf_put_zeros(&request, sizeof *rq_msg); ++ rq_msg->rtm_family = AF_UNSPEC; ++ rq_msg->rtm_table = id; + + nl_dump_start(&dump, NETLINK_ROUTE, &request); + ofpbuf_uninit(&request); +@@ -181,12 +180,43 @@ route_table_reset(void) + struct route_table_msg msg; + + if (route_table_parse(&reply, &msg)) { ++ struct nlmsghdr *nlmsghdr = nl_msg_nlmsghdr(&reply); ++ ++ /* Older kernels do not support filtering. */ ++ if (!(nlmsghdr->nlmsg_flags & NLM_F_DUMP_FILTERED)) { ++ filtered = false; ++ } + route_table_handle_msg(&msg); + } + } + ofpbuf_uninit(&buf); ++ nl_dump_done(&dump); ++ ++ return filtered; ++} ++ ++static void ++route_table_reset(void) ++{ ++ unsigned char tables[] = { ++ RT_TABLE_DEFAULT, ++ RT_TABLE_MAIN, ++ RT_TABLE_LOCAL, ++ }; + +- return nl_dump_done(&dump); ++ route_map_clear(); ++ netdev_get_addrs_list_flush(); ++ route_table_valid = true; ++ rt_change_seq++; ++ ++ COVERAGE_INC(route_table_dump); ++ ++ for (size_t i = 0; i < ARRAY_SIZE(tables); i++) { ++ if (!route_table_dump_one_table(tables[i])) { ++ /* Got unfiltered reply, no need to dump further. */ ++ break; ++ } ++ } + } + + /* Return RTNLGRP_IPV4_ROUTE or RTNLGRP_IPV6_ROUTE on success, 0 on parse +@@ -201,6 +231,7 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) + [RTA_OIF] = { .type = NL_A_U32, .optional = true }, + [RTA_GATEWAY] = { .type = NL_A_U32, .optional = true }, + [RTA_MARK] = { .type = NL_A_U32, .optional = true }, ++ [RTA_TABLE] = { .type = NL_A_U32, .optional = true }, + }; + + static const struct nl_policy policy6[] = { +@@ -208,6 +239,7 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) + [RTA_OIF] = { .type = NL_A_U32, .optional = true }, + [RTA_MARK] = { .type = NL_A_U32, .optional = true }, + [RTA_GATEWAY] = { .type = NL_A_IPV6, .optional = true }, ++ [RTA_TABLE] = { .type = NL_A_U32, .optional = true }, + }; + + struct nlattr *attrs[ARRAY_SIZE(policy)]; +@@ -229,6 +261,7 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) + + if (parsed) { + const struct nlmsghdr *nlmsg; ++ uint32_t table_id; + int rta_oif; /* Output interface index. */ + + nlmsg = buf->data; +@@ -244,6 +277,19 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) + rtm->rtm_type != RTN_LOCAL) { + change->relevant = false; + } ++ ++ table_id = rtm->rtm_table; ++ if (attrs[RTA_TABLE]) { ++ table_id = nl_attr_get_u32(attrs[RTA_TABLE]); ++ } ++ /* Do not consider changes in non-standard routing tables. */ ++ if (table_id ++ && table_id != RT_TABLE_DEFAULT ++ && table_id != RT_TABLE_MAIN ++ && table_id != RT_TABLE_LOCAL) { ++ change->relevant = false; ++ } ++ + change->nlmsg_type = nlmsg->nlmsg_type; + change->rd.rtm_dst_len = rtm->rtm_dst_len + (ipv4 ? 96 : 0); + change->rd.local = rtm->rtm_type == RTN_LOCAL; +@@ -299,7 +345,9 @@ static void + route_table_change(const struct route_table_msg *change OVS_UNUSED, + void *aux OVS_UNUSED) + { +- route_table_valid = false; ++ if (!change || change->relevant) { ++ route_table_valid = false; ++ } + } + + static void diff --git a/lib/rstp.c b/lib/rstp.c index 7e351bf32f..f8c46e7f92 100644 --- a/lib/rstp.c @@ -107000,10 +107373,10 @@ index 78a54c715d..b2e778707f 100644 void diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 57f94df544..4629406b3f 100644 +index 57f94df544..047f684e1b 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c -@@ -47,17 +47,20 @@ +@@ -47,17 +47,21 @@ #define UPCALL_MAX_BATCH 64 #define REVALIDATE_MAX_BATCH 50 @@ -107019,6 +107392,7 @@ index 57f94df544..4629406b3f 100644 COVERAGE_DEFINE(revalidate_missed_dp_flow); +COVERAGE_DEFINE(ukey_dp_change); +COVERAGE_DEFINE(ukey_invalid_stat_reset); ++COVERAGE_DEFINE(ukey_replace_contention); COVERAGE_DEFINE(upcall_flow_limit_hit); COVERAGE_DEFINE(upcall_flow_limit_kill); +COVERAGE_DEFINE(upcall_ukey_contention); @@ -107026,7 +107400,7 @@ index 57f94df544..4629406b3f 100644 /* A thread that reads upcalls from dpif, forwards each upcall's packet, * and possibly sets up a kernel flow as a cache. */ -@@ -287,6 +290,7 @@ struct udpif_key { +@@ -287,6 +291,7 @@ struct udpif_key { struct ovs_mutex mutex; /* Guards the following. */ struct dpif_flow_stats stats OVS_GUARDED; /* Last known stats.*/ @@ -107034,7 +107408,7 @@ index 57f94df544..4629406b3f 100644 long long int created OVS_GUARDED; /* Estimate of creation time. */ uint64_t dump_seq OVS_GUARDED; /* Tracks udpif->dump_seq. */ uint64_t reval_seq OVS_GUARDED; /* Tracks udpif->reval_seq. */ -@@ -362,6 +366,10 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, +@@ -362,6 +367,10 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, const char *argv[], void *aux); static void upcall_unixctl_purge(struct unixctl_conn *conn, int argc, const char *argv[], void *aux); @@ -107045,7 +107419,7 @@ index 57f94df544..4629406b3f 100644 static struct udpif_key *ukey_create_from_upcall(struct upcall *, struct flow_wildcards *); -@@ -434,6 +442,10 @@ udpif_init(void) +@@ -434,6 +443,10 @@ udpif_init(void) upcall_unixctl_dump_wait, NULL); unixctl_command_register("revalidator/purge", "", 0, 0, upcall_unixctl_purge, NULL); @@ -107056,7 +107430,7 @@ index 57f94df544..4629406b3f 100644 ovsthread_once_done(&once); } } -@@ -771,6 +783,17 @@ udpif_get_n_flows(struct udpif *udpif) +@@ -771,6 +784,17 @@ udpif_get_n_flows(struct udpif *udpif) atomic_store_relaxed(&udpif->n_flows_timestamp, now); dpif_get_dp_stats(udpif->dpif, &stats); flow_count = stats.n_flows; @@ -107074,7 +107448,7 @@ index 57f94df544..4629406b3f 100644 atomic_store_relaxed(&udpif->n_flows, flow_count); ovs_mutex_unlock(&udpif->n_flows_mutex); } else { -@@ -959,7 +982,7 @@ udpif_revalidator(void *arg) +@@ -959,7 +983,7 @@ udpif_revalidator(void *arg) udpif->reval_exit = latch_is_set(&udpif->exit_latch); start_time = time_msec(); @@ -107083,7 +107457,7 @@ index 57f94df544..4629406b3f 100644 bool terse_dump; terse_dump = udpif_use_ufid(udpif); -@@ -968,10 +991,15 @@ udpif_revalidator(void *arg) +@@ -968,10 +992,15 @@ udpif_revalidator(void *arg) } } @@ -107100,7 +107474,16 @@ index 57f94df544..4629406b3f 100644 } if (udpif->reval_exit) { -@@ -1746,6 +1774,7 @@ ukey_create__(const struct nlattr *key, size_t key_len, +@@ -1375,8 +1404,6 @@ upcall_cb(const struct dp_packet *packet, const struct flow *flow, ovs_u128 *ufi + } + + if (upcall.ukey && !ukey_install(udpif, upcall.ukey)) { +- static struct vlog_rate_limit rll = VLOG_RATE_LIMIT_INIT(1, 1); +- VLOG_WARN_RL(&rll, "upcall_cb failure: ukey installation fails"); + error = ENOSPC; + } + out: +@@ -1746,6 +1773,7 @@ ukey_create__(const struct nlattr *key, size_t key_len, ukey->created = ukey->flow_time = time_msec(); memset(&ukey->stats, 0, sizeof ukey->stats); ukey->stats.used = used; @@ -107108,7 +107491,7 @@ index 57f94df544..4629406b3f 100644 ukey->xcache = NULL; ukey->offloaded = false; -@@ -1868,6 +1897,7 @@ try_ukey_replace(struct umap *umap, struct udpif_key *old_ukey, +@@ -1868,19 +1896,20 @@ try_ukey_replace(struct umap *umap, struct udpif_key *old_ukey, ovs_mutex_lock(&new_ukey->mutex); cmap_replace(&umap->cmap, &old_ukey->cmap_node, &new_ukey->cmap_node, new_ukey->hash); @@ -107116,7 +107499,25 @@ index 57f94df544..4629406b3f 100644 ovsrcu_postpone(ukey_delete__, old_ukey); transition_ukey(old_ukey, UKEY_DELETED); transition_ukey(new_ukey, UKEY_VISIBLE); -@@ -2074,10 +2104,12 @@ ukey_delete(struct umap *umap, struct udpif_key *ukey) + replaced = true; ++ COVERAGE_INC(upcall_ukey_replace); ++ } else { ++ COVERAGE_INC(handler_duplicate_upcall); + } + ovs_mutex_unlock(&old_ukey->mutex); +- } +- +- if (replaced) { +- COVERAGE_INC(upcall_ukey_replace); + } else { +- COVERAGE_INC(handler_duplicate_upcall); ++ COVERAGE_INC(ukey_replace_contention); + } ++ + return replaced; + } + +@@ -2074,10 +2103,12 @@ ukey_delete(struct umap *umap, struct udpif_key *ukey) } static bool @@ -107131,7 +107532,7 @@ index 57f94df544..4629406b3f 100644 if (!used) { /* Always revalidate the first time a flow is dumped. */ -@@ -2104,8 +2136,12 @@ should_revalidate(const struct udpif *udpif, uint64_t packets, +@@ -2104,8 +2135,12 @@ should_revalidate(const struct udpif *udpif, uint64_t packets, duration = now - used; metric = duration / packets; @@ -107146,7 +107547,7 @@ index 57f94df544..4629406b3f 100644 return true; } return false; -@@ -2303,7 +2339,7 @@ static enum reval_result +@@ -2303,7 +2338,7 @@ static enum reval_result revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, const struct dpif_flow_stats *stats, struct ofpbuf *odp_actions, uint64_t reval_seq, @@ -107155,7 +107556,7 @@ index 57f94df544..4629406b3f 100644 OVS_REQUIRES(ukey->mutex) { bool need_revalidate = ukey->reval_seq != reval_seq; -@@ -2321,8 +2357,15 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, +@@ -2321,8 +2356,15 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, ? stats->n_bytes - ukey->stats.n_bytes : 0); @@ -107172,7 +107573,7 @@ index 57f94df544..4629406b3f 100644 if (!ukey->xcache) { ukey->xcache = xlate_cache_new(); } else { -@@ -2338,7 +2381,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, +@@ -2338,7 +2380,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, /* Stats for deleted flows will be attributed upon flow deletion. Skip. */ if (result != UKEY_DELETE) { @@ -107181,7 +107582,7 @@ index 57f94df544..4629406b3f 100644 ukey->stats = *stats; ukey->reval_seq = reval_seq; } -@@ -2434,6 +2477,15 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops) +@@ -2434,6 +2476,15 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops) push->tcp_flags = stats->tcp_flags | op->ukey->stats.tcp_flags; push->n_packets = stats->n_packets - op->ukey->stats.n_packets; push->n_bytes = stats->n_bytes - op->ukey->stats.n_bytes; @@ -107197,7 +107598,7 @@ index 57f94df544..4629406b3f 100644 ovs_mutex_unlock(&op->ukey->mutex); } else { push = stats; -@@ -2738,6 +2790,22 @@ revalidate(struct revalidator *revalidator) +@@ -2738,6 +2789,22 @@ revalidate(struct revalidator *revalidator) continue; } @@ -107220,7 +107621,7 @@ index 57f94df544..4629406b3f 100644 already_dumped = ukey->dump_seq == dump_seq; if (already_dumped) { /* The flow has already been handled during this flow dump -@@ -2769,8 +2837,7 @@ revalidate(struct revalidator *revalidator) +@@ -2769,8 +2836,7 @@ revalidate(struct revalidator *revalidator) result = UKEY_DELETE; } else { result = revalidate_ukey(udpif, ukey, &stats, &odp_actions, @@ -107230,6 +107631,14 @@ index 57f94df544..4629406b3f 100644 } ukey->dump_seq = dump_seq; +@@ -2836,6 +2902,7 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge) + /* Handler threads could be holding a ukey lock while it installs a + * new flow, so don't hang around waiting for access to it. */ + if (ovs_mutex_trylock(&ukey->mutex)) { ++ COVERAGE_INC(upcall_ukey_contention); + continue; + } + ukey_state = ukey->state; @@ -2853,9 +2920,9 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge) } else { struct dpif_flow_stats stats; @@ -107259,10 +107668,10 @@ index 57f94df544..4629406b3f 100644 + if (wake_up) { + udpif_resume_revalidators(udpif); + } -+ } -+ unixctl_command_reply(conn, ""); -+} -+ + } + unixctl_command_reply(conn, ""); + } + +static void +upcall_unixctl_pause(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) @@ -107271,10 +107680,10 @@ index 57f94df544..4629406b3f 100644 + + LIST_FOR_EACH (udpif, list_node, &all_udpifs) { + udpif_pause_revalidators(udpif); - } - unixctl_command_reply(conn, ""); - } - ++ } ++ unixctl_command_reply(conn, ""); ++} ++ +static void +upcall_unixctl_resume(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) @@ -107337,7 +107746,7 @@ index 114aff8ea3..0fc6d2ea60 100644 enum xc_type type; union { diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c -index 578cbfe581..d5e7a36c6f 100644 +index 578cbfe581..e46a686661 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -66,6 +66,7 @@ @@ -107938,7 +108347,112 @@ index 578cbfe581..d5e7a36c6f 100644 return b; } } -@@ -5120,6 +5277,7 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct ofpact_cnt_ids *ids) +@@ -4852,10 +5009,37 @@ put_controller_user_action(struct xlate_ctx *ctx, + bool dont_send, bool continuation, + uint32_t recirc_id, int len, + enum ofp_packet_in_reason reason, ++ uint32_t provider_meter_id, + uint16_t controller_id) + { + struct user_action_cookie cookie; + ++ /* If the controller action didn't request a meter (indicated by a ++ * 'meter_id' argument other than NX_CTLR_NO_METER), see if one was ++ * configured through the "controller" virtual meter. ++ * ++ * Internally, ovs-vswitchd uses UINT32_MAX to indicate no meter is ++ * configured. */ ++ uint32_t meter_id; ++ if (provider_meter_id == UINT32_MAX) { ++ meter_id = ctx->xbridge->ofproto->up.controller_meter_id; ++ } else { ++ meter_id = provider_meter_id; ++ } ++ ++ size_t offset; ++ size_t ac_offset; ++ if (meter_id != UINT32_MAX) { ++ /* If controller meter is configured, generate ++ * clone(meter,userspace) action. */ ++ offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_SAMPLE); ++ nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PROBABILITY, ++ UINT32_MAX); ++ ac_offset = nl_msg_start_nested(ctx->odp_actions, ++ OVS_SAMPLE_ATTR_ACTIONS); ++ nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_METER, meter_id); ++ } ++ + memset(&cookie, 0, sizeof cookie); + cookie.type = USER_ACTION_COOKIE_CONTROLLER; + cookie.ofp_in_port = OFPP_NONE, +@@ -4873,6 +5057,11 @@ put_controller_user_action(struct xlate_ctx *ctx, + uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); + odp_put_userspace_action(pid, &cookie, sizeof cookie, ODPP_NONE, + false, ctx->odp_actions, NULL); ++ ++ if (meter_id != UINT32_MAX) { ++ nl_msg_end_nested(ctx->odp_actions, ac_offset); ++ nl_msg_end_nested(ctx->odp_actions, offset); ++ } + } + + static void +@@ -4917,32 +5106,6 @@ xlate_controller_action(struct xlate_ctx *ctx, int len, + } + recirc_refs_add(&ctx->xout->recircs, recirc_id); + +- /* If the controller action didn't request a meter (indicated by a +- * 'meter_id' argument other than NX_CTLR_NO_METER), see if one was +- * configured through the "controller" virtual meter. +- * +- * Internally, ovs-vswitchd uses UINT32_MAX to indicate no meter is +- * configured. */ +- uint32_t meter_id; +- if (provider_meter_id == UINT32_MAX) { +- meter_id = ctx->xbridge->ofproto->up.controller_meter_id; +- } else { +- meter_id = provider_meter_id; +- } +- +- size_t offset; +- size_t ac_offset; +- if (meter_id != UINT32_MAX) { +- /* If controller meter is configured, generate clone(meter, userspace) +- * action. */ +- offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_SAMPLE); +- nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PROBABILITY, +- UINT32_MAX); +- ac_offset = nl_msg_start_nested(ctx->odp_actions, +- OVS_SAMPLE_ATTR_ACTIONS); +- nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_METER, meter_id); +- } +- + /* Generate the datapath flows even if we don't send the packet-in + * so that debugging more closely represents normal state. */ + bool dont_send = false; +@@ -4950,12 +5113,7 @@ xlate_controller_action(struct xlate_ctx *ctx, int len, + dont_send = true; + } + put_controller_user_action(ctx, dont_send, false, recirc_id, len, +- reason, controller_id); +- +- if (meter_id != UINT32_MAX) { +- nl_msg_end_nested(ctx->odp_actions, ac_offset); +- nl_msg_end_nested(ctx->odp_actions, offset); +- } ++ reason, provider_meter_id, controller_id); + } + + /* Creates a frozen state, and allocates a unique recirc id for the given +@@ -5007,6 +5165,7 @@ finish_freezing__(struct xlate_ctx *ctx, uint8_t table) + put_controller_user_action(ctx, false, true, recirc_id, + ctx->pause->max_len, + ctx->pause->reason, ++ ctx->pause->provider_meter_id, + ctx->pause->controller_id); + } else { + if (ctx->recirc_update_dp_hash) { +@@ -5120,6 +5279,7 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct ofpact_cnt_ids *ids) } ctx->wc->masks.nw_ttl = 0xff; @@ -107946,15 +108460,15 @@ index 578cbfe581..d5e7a36c6f 100644 if (flow->nw_ttl > 1) { flow->nw_ttl--; return false; -@@ -5308,15 +5466,15 @@ xlate_output_reg_action(struct xlate_ctx *ctx, +@@ -5308,15 +5468,15 @@ xlate_output_reg_action(struct xlate_ctx *ctx, { uint64_t port = mf_get_subfield(&or->src, &ctx->xin->flow); if (port <= UINT16_MAX) { - xlate_report(ctx, OFT_DETAIL, "output port is %"PRIu64, port); -- -- union mf_subvalue value; + union mf_subvalue *value = xmalloc(sizeof *value); +- union mf_subvalue value; +- - memset(&value, 0xff, sizeof value); - mf_write_subfield_flow(&or->src, &value, &ctx->wc->masks); + xlate_report(ctx, OFT_DETAIL, "output port is %"PRIu64, port); @@ -107967,7 +108481,7 @@ index 578cbfe581..d5e7a36c6f 100644 } else { xlate_report(ctx, OFT_WARN, "output port %"PRIu64" is out of range", port); -@@ -5525,8 +5683,16 @@ xlate_learn_action(struct xlate_ctx *ctx, const struct ofpact_learn *learn) +@@ -5525,8 +5685,16 @@ xlate_learn_action(struct xlate_ctx *ctx, const struct ofpact_learn *learn) if (!error) { bool success = true; if (ctx->xin->allow_side_effects) { @@ -107985,7 +108499,7 @@ index 578cbfe581..d5e7a36c6f 100644 } else if (learn->limit) { if (!ofm->temp_rule || ofm->temp_rule->state != RULE_INSERTED) { -@@ -5622,7 +5788,8 @@ xlate_sample_action(struct xlate_ctx *ctx, +@@ -5622,7 +5790,8 @@ xlate_sample_action(struct xlate_ctx *ctx, /* Scale the probability from 16-bit to 32-bit while representing * the same percentage. */ @@ -107995,7 +108509,7 @@ index 578cbfe581..d5e7a36c6f 100644 /* If ofp_port in flow sample action is equel to ofp_port, * this sample action is a input port action. */ -@@ -5656,13 +5823,15 @@ xlate_sample_action(struct xlate_ctx *ctx, +@@ -5656,13 +5825,15 @@ xlate_sample_action(struct xlate_ctx *ctx, struct flow *flow = &ctx->xin->flow; tnl_port_send(xport->ofport, flow, ctx->wc); if (!ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) { @@ -108013,7 +108527,7 @@ index 578cbfe581..d5e7a36c6f 100644 } } else { xlate_report_error(ctx, -@@ -5772,21 +5941,12 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, +@@ -5772,21 +5943,12 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, struct xlate_ctx *ctx, bool is_last_action, bool group_bucket_action OVS_UNUSED) { @@ -108038,7 +108552,7 @@ index 578cbfe581..d5e7a36c6f 100644 do_xlate_actions(actions, actions_len, ctx, is_last_action, false); if (!ctx->freezing) { xlate_action_set(ctx); -@@ -5801,7 +5961,8 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, +@@ -5801,7 +5963,8 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, * avoid emitting those actions twice. Once inside * the clone, another time for the action after clone. */ xlate_commit_actions(ctx); @@ -108048,7 +108562,7 @@ index 578cbfe581..d5e7a36c6f 100644 bool old_was_mpls = ctx->was_mpls; bool old_conntracked = ctx->conntracked; -@@ -5858,14 +6019,10 @@ dp_clone_done: +@@ -5858,14 +6021,10 @@ dp_clone_done: ctx->was_mpls = old_was_mpls; /* Restore the 'base_flow' for the next action. */ @@ -108065,7 +108579,7 @@ index 578cbfe581..d5e7a36c6f 100644 } static void -@@ -6241,8 +6398,8 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, +@@ -6241,8 +6400,8 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, { uint16_t zone; if (ofc->zone_src.field) { @@ -108076,7 +108590,7 @@ index 578cbfe581..d5e7a36c6f 100644 zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow); if (ctx->xin->frozen_state) { -@@ -6252,12 +6409,13 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, +@@ -6252,12 +6411,13 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, * which will invalidate the megaflow with old the recirc_id. */ if (!mf_is_frozen_metadata(ofc->zone_src.field)) { @@ -108092,7 +108606,7 @@ index 578cbfe581..d5e7a36c6f 100644 } else { zone = ofc->zone_imm; } -@@ -6347,16 +6505,16 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6347,16 +6507,16 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, const struct ofpact *remaining_acts, size_t remaining_acts_len) { @@ -108113,7 +108627,7 @@ index 578cbfe581..d5e7a36c6f 100644 &ctx->xin->flow); /* If datapath doesn't support check_pkt_len action, then set the * SLOW_ACTION flag. If we don't set SLOW_ACTION, we -@@ -6366,22 +6524,17 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6366,22 +6526,17 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, * the packet length. This results in wrong actions being applied. */ ctx->xout->slow |= SLOW_ACTION; @@ -108141,7 +108655,7 @@ index 578cbfe581..d5e7a36c6f 100644 bool old_was_mpls = ctx->was_mpls; bool old_conntracked = ctx->conntracked; -@@ -6391,8 +6544,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6391,8 +6546,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, check_pkt_larger->pkt_len); size_t offset_attr = nl_msg_start_nested( ctx->odp_actions, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER); @@ -108152,7 +108666,7 @@ index 578cbfe581..d5e7a36c6f 100644 do_xlate_actions(remaining_acts, remaining_acts_len, ctx, true, false); if (!ctx->freezing) { xlate_action_set(ctx); -@@ -6402,10 +6555,10 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6402,10 +6557,10 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, } nl_msg_end_nested(ctx->odp_actions, offset_attr); @@ -108165,7 +108679,7 @@ index 578cbfe581..d5e7a36c6f 100644 /* If the flow translation for the IF_GREATER case requires freezing, * then ctx->exit would be true. Reset to false so that we can -@@ -6416,8 +6569,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6416,8 +6571,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, offset_attr = nl_msg_start_nested( ctx->odp_actions, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL); @@ -108176,7 +108690,7 @@ index 578cbfe581..d5e7a36c6f 100644 do_xlate_actions(remaining_acts, remaining_acts_len, ctx, true, false); if (!ctx->freezing) { xlate_action_set(ctx); -@@ -6428,15 +6581,12 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6428,15 +6583,12 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, nl_msg_end_nested(ctx->odp_actions, offset_attr); nl_msg_end_nested(ctx->odp_actions, offset); @@ -108195,7 +108709,7 @@ index 578cbfe581..d5e7a36c6f 100644 } static void -@@ -6887,6 +7037,107 @@ xlate_ofpact_unroll_xlate(struct xlate_ctx *ctx, +@@ -6887,6 +7039,107 @@ xlate_ofpact_unroll_xlate(struct xlate_ctx *ctx, "cookie=%#"PRIx64, a->rule_table_id, a->rule_cookie); } @@ -108303,7 +108817,7 @@ index 578cbfe581..d5e7a36c6f 100644 static void do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, struct xlate_ctx *ctx, bool is_last_action, -@@ -6928,6 +7179,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6928,6 +7181,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; } @@ -108312,7 +108826,7 @@ index 578cbfe581..d5e7a36c6f 100644 if (OVS_UNLIKELY(ctx->xin->trace)) { struct ds s = DS_EMPTY_INITIALIZER; struct ofpact_format_params fp = { .s = &s }; -@@ -7027,6 +7280,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7027,6 +7282,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IPV4_SRC: if (flow->dl_type == htons(ETH_TYPE_IP)) { memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); @@ -108320,7 +108834,7 @@ index 578cbfe581..d5e7a36c6f 100644 flow->nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4; } break; -@@ -7034,12 +7288,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7034,12 +7290,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IPV4_DST: if (flow->dl_type == htons(ETH_TYPE_IP)) { memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); @@ -108335,7 +108849,7 @@ index 578cbfe581..d5e7a36c6f 100644 wc->masks.nw_tos |= IP_DSCP_MASK; flow->nw_tos &= ~IP_DSCP_MASK; flow->nw_tos |= ofpact_get_SET_IP_DSCP(a)->dscp; -@@ -7048,6 +7304,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7048,6 +7306,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IP_ECN: if (is_ip_any(flow)) { @@ -108343,7 +108857,7 @@ index 578cbfe581..d5e7a36c6f 100644 wc->masks.nw_tos |= IP_ECN_MASK; flow->nw_tos &= ~IP_ECN_MASK; flow->nw_tos |= ofpact_get_SET_IP_ECN(a)->ecn; -@@ -7056,6 +7313,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7056,6 +7315,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IP_TTL: if (is_ip_any(flow)) { @@ -108351,7 +108865,7 @@ index 578cbfe581..d5e7a36c6f 100644 wc->masks.nw_ttl = 0xff; flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl; } -@@ -7123,6 +7381,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7123,6 +7383,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, /* Set the field only if the packet actually has it. */ if (mf_are_prereqs_ok(mf, flow, wc)) { @@ -108359,7 +108873,7 @@ index 578cbfe581..d5e7a36c6f 100644 mf_mask_field_masked(mf, ofpact_set_field_mask(set_field), wc); mf_set_flow_value_masked(mf, set_field->value, ofpact_set_field_mask(set_field), -@@ -7179,6 +7438,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7179,6 +7440,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_DEC_TTL: wc->masks.nw_ttl = 0xff; @@ -108367,7 +108881,7 @@ index 578cbfe581..d5e7a36c6f 100644 if (compose_dec_ttl(ctx, ofpact_get_DEC_TTL(a))) { return; } -@@ -7609,6 +7869,43 @@ xlate_wc_finish(struct xlate_ctx *ctx) +@@ -7609,6 +7871,43 @@ xlate_wc_finish(struct xlate_ctx *ctx) ctx->wc->masks.vlans[i].tci = 0; } } @@ -108411,7 +108925,7 @@ index 578cbfe581..d5e7a36c6f 100644 } /* Translates the flow, actions, or rule in 'xin' into datapath actions in -@@ -7784,6 +8081,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7784,6 +8083,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -108424,7 +108938,7 @@ index 578cbfe581..d5e7a36c6f 100644 /* Tunnel metadata in udpif format must be normalized before translation. */ if (flow->tunnel.flags & FLOW_TNL_F_UDPIF) { const struct tun_table *tun_tab = ofproto_get_tun_tab( -@@ -8030,6 +8333,10 @@ exit: +@@ -8030,6 +8335,10 @@ exit: if (xin->odp_actions) { ofpbuf_clear(xin->odp_actions); } @@ -108448,7 +108962,7 @@ index 851088d794..2ba90e999c 100644 void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *, const char *name, enum port_vlan_mode, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c -index 8143dd965f..06f6d00b39 100644 +index 8143dd965f..f20ed9a3f1 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -215,10 +215,6 @@ struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers); @@ -108729,7 +109243,35 @@ index 8143dd965f..06f6d00b39 100644 for (i = 0; i < s->n_members; i++) { if (s->members[i] == port->up.ofp_port) { goto found; -@@ -3963,6 +3956,10 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev) +@@ -3909,15 +3902,21 @@ port_query_by_name(const struct ofproto *ofproto_, const char *devname, + int error; + + if (sset_contains(&ofproto->ghost_ports, devname)) { +- const char *type = netdev_get_type_from_name(devname); +- + /* We may be called before ofproto->up.port_by_name is populated with + * the appropriate ofport. For this reason, we must get the name and +- * type from the netdev layer directly. */ +- if (type) { +- const struct ofport *ofport; ++ * type from the netdev layer directly. ++ * However, when a port deleted, the corresponding netdev is also ++ * removed from netdev_shash. netdev_get_type_from_name returns NULL ++ * in such case and we should try to get type from ofport->netdev. */ ++ const char *type = netdev_get_type_from_name(devname); ++ const struct ofport *ofport = ++ shash_find_data(&ofproto->up.port_by_name, devname); ++ ++ if (!type && ofport && ofport->netdev) { ++ type = netdev_get_type(ofport->netdev); ++ } + +- ofport = shash_find_data(&ofproto->up.port_by_name, devname); ++ if (type) { + ofproto_port->ofp_port = ofport ? ofport->ofp_port : OFPP_NONE; + ofproto_port->name = xstrdup(devname); + ofproto_port->type = xstrdup(type); +@@ -3963,6 +3962,10 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev) simap_put(&ofproto->backer->tnl_backers, dp_port_name, odp_to_u32(port_no)); } @@ -108740,7 +109282,7 @@ index 8143dd965f..06f6d00b39 100644 } if (netdev_get_tunnel_config(netdev)) { -@@ -4471,12 +4468,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, +@@ -4471,12 +4474,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, atomic_add_relaxed(&tbl->n_matched, stats->n_packets, &orig); } if (xcache) { @@ -108760,7 +109302,7 @@ index 8143dd965f..06f6d00b39 100644 } return rule; } -@@ -4507,12 +4506,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, +@@ -4507,12 +4512,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, stats->n_packets, &orig); } if (xcache) { @@ -108780,7 +109322,7 @@ index 8143dd965f..06f6d00b39 100644 } if (rule) { goto out; /* Match. */ -@@ -4879,7 +4880,7 @@ packet_xlate(struct ofproto *ofproto_, struct ofproto_packet_out *opo) +@@ -4879,7 +4886,7 @@ packet_xlate(struct ofproto *ofproto_, struct ofproto_packet_out *opo) if (entry->type == XC_LEARN) { struct ofproto_flow_mod *ofm = entry->learn.ofm; @@ -108789,7 +109331,7 @@ index 8143dd965f..06f6d00b39 100644 if (error) { goto error_out; } -@@ -5550,9 +5551,9 @@ ct_zone_timeout_policy_sweep(struct dpif_backer *backer) +@@ -5550,9 +5557,9 @@ ct_zone_timeout_policy_sweep(struct dpif_backer *backer) { if (!ovs_list_is_empty(&backer->ct_tp_kill_list) && time_msec() >= timeout_policy_cleanup_timer) { @@ -108801,7 +109343,7 @@ index 8143dd965f..06f6d00b39 100644 if (!ct_dpif_del_timeout_policy(backer->dpif, ct_tp->tp_id)) { ovs_list_remove(&ct_tp->list_node); ct_timeout_policy_destroy(ct_tp, backer->tp_ids); -@@ -5594,6 +5595,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, +@@ -5594,6 +5601,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, ct_timeout_policy_unref(backer, ct_zone->ct_tp); ct_zone->ct_tp = ct_tp; ct_tp->ref_count++; @@ -108809,7 +109351,7 @@ index 8143dd965f..06f6d00b39 100644 } } else { struct ct_zone *new_ct_zone = ct_zone_alloc(zone_id); -@@ -5601,6 +5603,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, +@@ -5601,6 +5609,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, cmap_insert(&backer->ct_zones, &new_ct_zone->node, hash_int(zone_id, 0)); ct_tp->ref_count++; @@ -108817,7 +109359,7 @@ index 8143dd965f..06f6d00b39 100644 } } -@@ -5617,6 +5620,7 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) +@@ -5617,6 +5626,7 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) if (ct_zone) { ct_timeout_policy_unref(backer, ct_zone->ct_tp); ct_zone_remove_and_destroy(backer, ct_zone); @@ -108825,7 +109367,7 @@ index 8143dd965f..06f6d00b39 100644 } } -@@ -5818,15 +5822,7 @@ ofproto_dpif_lookup_by_name(const char *name) +@@ -5818,15 +5828,7 @@ ofproto_dpif_lookup_by_name(const char *name) struct ofproto_dpif * ofproto_dpif_lookup_by_uuid(const struct uuid *uuid) { @@ -109283,10 +109825,24 @@ index fbcefafc6e..a4f9d38f11 100644 /ovsdb-client.1 /ovsdb-doc diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk -index 62cc02686f..eba713bb6d 100644 +index 62cc02686f..d484fe9deb 100644 --- a/ovsdb/automake.mk +++ b/ovsdb/automake.mk -@@ -148,4 +148,25 @@ ovsdb/ovsdb-server.5: \ +@@ -114,11 +114,13 @@ $(OVSIDL_BUILT): ovsdb/ovsdb-idlc.in python/ovs/dirs.py + + # ovsdb-doc + EXTRA_DIST += ovsdb/ovsdb-doc ++FLAKE8_PYFILES += ovsdb/ovsdb-doc + OVSDB_DOC = $(run_python) $(srcdir)/ovsdb/ovsdb-doc + ovsdb/ovsdb-doc: python/ovs/dirs.py + + # ovsdb-dot + EXTRA_DIST += ovsdb/ovsdb-dot.in ovsdb/dot2pic ++FLAKE8_PYFILES += ovsdb/ovsdb-dot.in ovsdb/dot2pic + noinst_SCRIPTS += ovsdb/ovsdb-dot + CLEANFILES += ovsdb/ovsdb-dot + OVSDB_DOT = $(run_python) $(srcdir)/ovsdb/ovsdb-dot.in +@@ -148,4 +150,25 @@ ovsdb/ovsdb-server.5: \ $(srcdir)/ovsdb/_server.xml > $@.tmp && \ mv $@.tmp $@ @@ -109334,6 +109890,34 @@ index 388dd54a16..9aa3788dbb 100644 hmap_remove(&o_column->o_clauses, &c->hmap_node); free(c); } +diff --git a/ovsdb/dot2pic b/ovsdb/dot2pic +index 2f858e19d5..3db6444de6 100755 +--- a/ovsdb/dot2pic ++++ b/ovsdb/dot2pic +@@ -17,6 +17,7 @@ + import getopt + import sys + ++ + def dot2pic(src, dst): + scale = 1.0 + while True: +@@ -49,8 +50,8 @@ def dot2pic(src, dst): + dst.write("box at %f,%f wid %f height %f\n" + % (x, y, width, height)) + elif command == 'edge': +- tail = words[1] +- head = words[2] ++ # tail = words[1] ++ # head = words[2] + n = int(words[3]) + + # Extract x,y coordinates. +@@ -114,4 +115,3 @@ else: + if font_scale: + print(".ps %+d" % font_scale) + print(".PE") +- diff --git a/ovsdb/execution.c b/ovsdb/execution.c index f9b8067d02..5587ef96fe 100644 --- a/ovsdb/execution.c @@ -110089,18 +110673,274 @@ index 0f222cc992..952fa902e4 100644 } } diff --git a/ovsdb/ovsdb-doc b/ovsdb/ovsdb-doc -index 10d0c0c134..099770d253 100755 +index 10d0c0c134..2edf487a28 100755 --- a/ovsdb/ovsdb-doc +++ b/ovsdb/ovsdb-doc -@@ -24,7 +24,7 @@ import ovs.json +@@ -14,9 +14,7 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-from datetime import date + import getopt +-import os + import sys + import xml.dom.minidom + +@@ -24,10 +22,13 @@ import ovs.json from ovs.db import error import ovs.db.schema -from build.nroff import * -+from ovs_build_helpers.nroff import * ++from ovs_build_helpers.nroff import block_xml_to_nroff ++from ovs_build_helpers.nroff import escape_nroff_literal ++from ovs_build_helpers.nroff import text_to_nroff argv0 = sys.argv[0] ++ + def typeAndConstraintsToNroff(column): + type = column.type.toEnglish(escape_nroff_literal) + constraints = column.type.constraintsToEnglish(escape_nroff_literal, +@@ -38,6 +39,7 @@ def typeAndConstraintsToNroff(column): + type += " (must be unique within table)" + return type + ++ + def columnGroupToNroff(table, groupXml, documented_columns): + introNodes = [] + columnNodes = [] +@@ -49,7 +51,10 @@ def columnGroupToNroff(table, groupXml, documented_columns): + if (columnNodes + and not (node.nodeType == node.TEXT_NODE + and node.data.isspace())): +- raise error.Error("text follows or inside : %s" % node) ++ raise error.Error( ++ "text follows or inside : %s" ++ % node ++ ) + introNodes += [node] + + summary = [] +@@ -65,15 +70,9 @@ def columnGroupToNroff(table, groupXml, documented_columns): + if node.hasAttribute('type'): + type_string = node.attributes['type'].nodeValue + type_json = ovs.json.from_string(str(type_string)) +- # py2 -> py3 means str -> bytes and unicode -> str +- try: +- if type(type_json) in (str, unicode): +- raise error.Error("%s %s:%s has invalid 'type': %s" +- % (table.name, name, key, type_json)) +- except: +- if type(type_json) in (bytes, str): +- raise error.Error("%s %s:%s has invalid 'type': %s" +- % (table.name, name, key, type_json)) ++ if type(type_json) in (bytes, str): ++ raise error.Error("%s %s:%s has invalid 'type': %s" ++ % (table.name, name, key, type_json)) + type_ = ovs.db.types.BaseType.from_json(type_json) + else: + type_ = column.type.value +@@ -91,10 +90,11 @@ def columnGroupToNroff(table, groupXml, documented_columns): + else: + if type_.type != column.type.value.type: + type_english = type_.toEnglish() ++ typeNroff += ", containing " + if type_english[0] in 'aeiou': +- typeNroff += ", containing an %s" % type_english ++ typeNroff += "an %s" % type_english + else: +- typeNroff += ", containing a %s" % type_english ++ typeNroff += "a %s" % type_english + constraints = ( + type_.constraintsToEnglish(escape_nroff_literal, + text_to_nroff)) +@@ -121,6 +121,7 @@ def columnGroupToNroff(table, groupXml, documented_columns): + raise error.Error("unknown element %s in " % node.tagName) + return summary, intro, body + ++ + def tableSummaryToNroff(summary, level=0): + s = "" + for type, name, arg in summary: +@@ -132,6 +133,7 @@ def tableSummaryToNroff(summary, level=0): + s += ".RE\n" + return s + ++ + def tableToNroff(schema, tableXml): + tableName = tableXml.attributes['name'].nodeValue + table = schema.tables[tableName] +@@ -156,20 +158,17 @@ def tableToNroff(schema, tableXml): + + return s + ++ + def docsToNroff(schemaFile, xmlFile, erFile, version=None): + schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schemaFile)) + doc = xml.dom.minidom.parse(xmlFile).documentElement + +- schemaDate = os.stat(schemaFile).st_mtime +- xmlDate = os.stat(xmlFile).st_mtime +- d = date.fromtimestamp(max(schemaDate, xmlDate)) +- + if doc.hasAttribute('name'): + manpage = doc.attributes['name'].nodeValue + else: + manpage = schema.name + +- if version == None: ++ if version is None: + version = "UNKNOWN" + + # Putting '\" p as the first line tells "man" that the manpage +@@ -194,7 +193,6 @@ def docsToNroff(schemaFile, xmlFile, erFile, version=None): + .PP + ''' % (manpage, schema.version, version, text_to_nroff(manpage), schema.name) + +- tables = "" + introNodes = [] + tableNodes = [] + summary = [] +@@ -237,8 +235,8 @@ Purpose + """ % (name, text_to_nroff(title)) + + if erFile: +- s += """ +-.\\" check if in troff mode (TTY) ++ s += r""" ++.\" check if in troff mode (TTY) + .if t \{ + .bp + .SH "TABLE RELATIONSHIPS" +@@ -248,8 +246,8 @@ database. Each node represents a table. Tables that are part of the + ``root set'' are shown with double borders. Each edge leads from the + table that contains it and points to the table that its value + represents. Edges are labeled with their column names, followed by a +-constraint on the number of allowed values: \\fB?\\fR for zero or one, +-\\fB*\\fR for zero or more, \\fB+\\fR for one or more. Thick lines ++constraint on the number of allowed values: \fB?\fR for zero or one, ++\fB*\fR for zero or more, \fB+\fR for one or more. Thick lines + represent strong references; thin lines represent weak references. + .RS -1in + """ +@@ -263,6 +261,7 @@ represent strong references; thin lines represent weak references. + s += tableToNroff(schema, node) + "\n" + return s + ++ + def usage(): + print("""\ + %(argv0)s: ovsdb schema documentation generator +@@ -278,6 +277,7 @@ The following options are also available: + """ % {'argv0': argv0}) + sys.exit(0) + ++ + if __name__ == "__main__": + try: + try: +diff --git a/ovsdb/ovsdb-dot.in b/ovsdb/ovsdb-dot.in +index 41b986c0ac..f1eefd49cb 100755 +--- a/ovsdb/ovsdb-dot.in ++++ b/ovsdb/ovsdb-dot.in +@@ -1,15 +1,13 @@ + #! @PYTHON3@ + +-from datetime import date + import ovs.db.error + import ovs.db.schema + import getopt +-import os +-import re + import sys + + argv0 = sys.argv[0] + ++ + def printEdge(tableName, type, baseType, label): + if baseType.ref_table_name: + if type.n_min == 0: +@@ -31,38 +29,42 @@ def printEdge(tableName, type, baseType, label): + options['label'] = '"%s%s"' % (label, arity) + if baseType.ref_type == 'weak': + options['style'] = 'dotted' +- print ("\t%s -> %s [%s];" % ( ++ print("\t%s -> %s [%s];" % ( + tableName, + baseType.ref_table_name, +- ', '.join(['%s=%s' % (k,v) for k,v in options.items()]))) ++ ', '.join(['%s=%s' % (k, v) for k, v in options.items()]))) ++ + + def schemaToDot(schemaFile, arrows): + schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schemaFile)) + +- print ("digraph %s {" % schema.name) +- print ('\trankdir=LR;') +- print ('\tsize="6.5,4";') +- print ('\tmargin="0";') +- print ("\tnode [shape=box];") ++ print("digraph %s {" % schema.name) ++ print('\trankdir=LR;') ++ print('\tsize="6.5,4";') ++ print('\tmargin="0";') ++ print("\tnode [shape=box];") + if not arrows: +- print ("\tedge [dir=none, arrowhead=none, arrowtail=none];") ++ print("\tedge [dir=none, arrowhead=none, arrowtail=none];") + for tableName, table in schema.tables.items(): + options = {} + if table.is_root: + options['style'] = 'bold' +- print ("\t%s [%s];" % ( ++ print("\t%s [%s];" % ( + tableName, +- ', '.join(['%s=%s' % (k,v) for k,v in options.items()]))) ++ ', '.join(['%s=%s' % (k, v) for k, v in options.items()]))) + for columnName, column in table.columns.items(): + if column.type.value: +- printEdge(tableName, column.type, column.type.key, "%s key" % columnName) +- printEdge(tableName, column.type, column.type.value, "%s value" % columnName) ++ printEdge(tableName, column.type, column.type.key, ++ "%s key" % columnName) ++ printEdge(tableName, column.type, column.type.value, ++ "%s value" % columnName) + else: + printEdge(tableName, column.type, column.type.key, columnName) +- print ("}"); ++ print("}") ++ + + def usage(): +- print ("""\ ++ print("""\ + %(argv0)s: compiles ovsdb schemas to graphviz format + Prints a .dot file that "dot" can render to an entity-relationship diagram + usage: %(argv0)s [OPTIONS] SCHEMA +@@ -75,12 +77,13 @@ The following options are also available: + """ % {'argv0': argv0}) + sys.exit(0) + ++ + if __name__ == "__main__": + try: + try: + options, args = getopt.gnu_getopt(sys.argv[1:], 'hV', + ['no-arrows', +- 'help', 'version',]) ++ 'help', 'version']) + except getopt.GetoptError as geo: + sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) + sys.exit(1) +@@ -92,7 +95,7 @@ if __name__ == "__main__": + elif key in ['-h', '--help']: + usage() + elif key in ['-V', '--version']: +- print ("ovsdb-dot (Open vSwitch) @VERSION@") ++ print("ovsdb-dot (Open vSwitch) @VERSION@") + else: + sys.exit(0) + diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index 10a70ae26f..13c5359395 100755 --- a/ovsdb/ovsdb-idlc.in @@ -110509,10 +111349,10 @@ index 30760233ee..e685c8103b 100644 raft_server_destroy(s); } diff --git a/ovsdb/raft.c b/ovsdb/raft.c -index 1a3447a8dd..cf9edf35c6 100644 +index 1a3447a8dd..1ad74bf124 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c -@@ -74,9 +74,12 @@ enum raft_failure_test { +@@ -74,9 +74,13 @@ enum raft_failure_test { FT_CRASH_BEFORE_SEND_EXEC_REQ, FT_CRASH_AFTER_SEND_EXEC_REQ, FT_CRASH_AFTER_RECV_APPEND_REQ_UPDATE, @@ -110522,10 +111362,16 @@ index 1a3447a8dd..cf9edf35c6 100644 FT_STOP_RAFT_RPC, + FT_TRANSFER_LEADERSHIP, + FT_TRANSFER_LEADERSHIP_AFTER_SEND_APPEND_REQ, ++ FT_TRANSFER_LEADERSHIP_AFTER_STARTING_TO_ADD, }; static enum raft_failure_test failure_test; -@@ -379,12 +382,19 @@ static bool raft_handle_write_error(struct raft *, struct ovsdb_error *); +@@ -375,16 +379,24 @@ static void raft_get_servers_from_log(struct raft *, enum vlog_level); + static void raft_get_election_timer_from_log(struct raft *); + + static bool raft_handle_write_error(struct raft *, struct ovsdb_error *); ++static bool raft_has_uncommitted_configuration(const struct raft *); + static void raft_run_reconfigure(struct raft *); static void raft_set_leader(struct raft *, const struct uuid *sid); @@ -110545,7 +111391,7 @@ index 1a3447a8dd..cf9edf35c6 100644 static char * raft_make_address_passive(const char *address_) { -@@ -692,8 +702,8 @@ static void +@@ -692,8 +704,8 @@ static void raft_set_servers(struct raft *raft, const struct hmap *new_servers, enum vlog_level level) { @@ -110556,7 +111402,7 @@ index 1a3447a8dd..cf9edf35c6 100644 if (!raft_server_find(new_servers, &s->sid)) { ovs_assert(s != raft->remove_server); -@@ -703,7 +713,7 @@ raft_set_servers(struct raft *raft, const struct hmap *new_servers, +@@ -703,7 +715,7 @@ raft_set_servers(struct raft *raft, const struct hmap *new_servers, } } @@ -110565,7 +111411,77 @@ index 1a3447a8dd..cf9edf35c6 100644 if (!raft_find_server(raft, &s->sid)) { VLOG(level, "server %s added to configuration", s->nickname); -@@ -1376,8 +1386,8 @@ raft_close__(struct raft *raft) +@@ -1240,10 +1252,30 @@ raft_transfer_leadership(struct raft *raft, const char *reason) + return; + } + +- struct raft_server *s; ++ struct raft_server **servers, *s; ++ uint64_t threshold = 0; ++ size_t n = 0, start, i; ++ ++ servers = xmalloc(hmap_count(&raft->servers) * sizeof *servers); ++ + HMAP_FOR_EACH (s, hmap_node, &raft->servers) { +- if (!uuid_equals(&raft->sid, &s->sid) +- && s->phase == RAFT_PHASE_STABLE) { ++ if (uuid_equals(&raft->sid, &s->sid) ++ || s->phase != RAFT_PHASE_STABLE) { ++ continue; ++ } ++ if (s->match_index > threshold) { ++ threshold = s->match_index; ++ } ++ servers[n++] = s; ++ } ++ ++ start = n ? random_range(n) : 0; ++ ++retry: ++ for (i = 0; i < n; i++) { ++ s = servers[(start + i) % n]; ++ ++ if (s->match_index >= threshold) { + struct raft_conn *conn = raft_find_conn_by_sid(raft, &s->sid); + if (!conn) { + continue; +@@ -1259,7 +1291,10 @@ raft_transfer_leadership(struct raft *raft, const char *reason) + .term = raft->term, + } + }; +- raft_send_to_conn(raft, &rpc, conn); ++ ++ if (!raft_send_to_conn(raft, &rpc, conn)) { ++ continue; ++ } + + raft_record_note(raft, "transfer leadership", + "transferring leadership to %s because %s", +@@ -1267,6 +1302,23 @@ raft_transfer_leadership(struct raft *raft, const char *reason) + break; + } + } ++ ++ if (n && i == n && threshold) { ++ if (threshold > raft->commit_index) { ++ /* Failed to transfer to servers with the highest 'match_index'. ++ * Try other servers that are not behind the majority. */ ++ threshold = raft->commit_index; ++ } else { ++ /* Try any other server. It is safe, because they either have all ++ * the append requests queued up for them before the leadership ++ * transfer message or their connection is broken and we will not ++ * transfer anyway. */ ++ threshold = 0; ++ } ++ goto retry; ++ } ++ ++ free(servers); + } + + /* Send a RemoveServerRequest to the rest of the servers in the cluster. +@@ -1376,8 +1428,8 @@ raft_close__(struct raft *raft) raft->remove_server = NULL; } @@ -110576,7 +111492,7 @@ index 1a3447a8dd..cf9edf35c6 100644 raft_conn_close(conn); } } -@@ -1713,8 +1723,8 @@ raft_waiters_run(struct raft *raft) +@@ -1713,8 +1765,8 @@ raft_waiters_run(struct raft *raft) } uint64_t cur = ovsdb_log_commit_progress(raft->log); @@ -110587,7 +111503,7 @@ index 1a3447a8dd..cf9edf35c6 100644 if (cur < w->commit_ticket) { break; } -@@ -1736,8 +1746,8 @@ raft_waiters_wait(struct raft *raft) +@@ -1736,8 +1788,8 @@ raft_waiters_wait(struct raft *raft) static void raft_waiters_destroy(struct raft *raft) { @@ -110598,7 +111514,7 @@ index 1a3447a8dd..cf9edf35c6 100644 raft_waiter_destroy(w); } } -@@ -1867,6 +1877,8 @@ raft_open_conn(struct raft *raft, const char *address, const struct uuid *sid) +@@ -1867,6 +1919,8 @@ raft_open_conn(struct raft *raft, const char *address, const struct uuid *sid) static void raft_conn_close(struct raft_conn *conn) { @@ -110607,7 +111523,7 @@ index 1a3447a8dd..cf9edf35c6 100644 jsonrpc_session_close(conn->js); ovs_list_remove(&conn->list_node); free(conn->nickname); -@@ -1921,6 +1933,13 @@ raft_run(struct raft *raft) +@@ -1921,6 +1975,13 @@ raft_run(struct raft *raft) return; } @@ -110621,7 +111537,7 @@ index 1a3447a8dd..cf9edf35c6 100644 raft_waiters_run(raft); if (!raft->listener && time_msec() >= raft->listen_backoff) { -@@ -1957,16 +1976,29 @@ raft_run(struct raft *raft) +@@ -1957,16 +2018,29 @@ raft_run(struct raft *raft) } /* Close unneeded sessions. */ @@ -110654,7 +111570,7 @@ index 1a3447a8dd..cf9edf35c6 100644 HMAP_FOR_EACH (server, hmap_node, &raft->servers) { raft_open_conn(raft, server->address, &server->sid); } -@@ -2039,11 +2071,18 @@ raft_run(struct raft *raft) +@@ -2039,11 +2113,18 @@ raft_run(struct raft *raft) * commands becomes new leader: the pending commands can still complete * if the crashed leader has replicated the transactions to majority of * followers before it crashed. */ @@ -110676,7 +111592,7 @@ index 1a3447a8dd..cf9edf35c6 100644 } } raft_reset_ping_timer(raft); -@@ -2235,6 +2274,9 @@ raft_command_initiate(struct raft *raft, +@@ -2235,6 +2316,9 @@ raft_command_initiate(struct raft *raft, if (failure_test == FT_CRASH_AFTER_SEND_APPEND_REQ) { ovs_fatal(0, "Raft test: crash after sending append_request."); } @@ -110686,7 +111602,7 @@ index 1a3447a8dd..cf9edf35c6 100644 raft_reset_ping_timer(raft); return cmd; -@@ -2243,8 +2285,12 @@ raft_command_initiate(struct raft *raft, +@@ -2243,8 +2327,12 @@ raft_command_initiate(struct raft *raft, static void log_all_commands(struct raft *raft) { @@ -110701,7 +111617,7 @@ index 1a3447a8dd..cf9edf35c6 100644 VLOG_DBG("raft command eid: "UUID_FMT, UUID_ARGS(&cmd->eid)); } } -@@ -2398,8 +2444,8 @@ raft_command_complete(struct raft *raft, +@@ -2398,8 +2486,8 @@ raft_command_complete(struct raft *raft, static void raft_complete_all_commands(struct raft *raft, enum raft_command_status status) { @@ -110712,22 +111628,34 @@ index 1a3447a8dd..cf9edf35c6 100644 raft_command_complete(raft, cmd, status); } } -@@ -2601,7 +2647,13 @@ raft_become_follower(struct raft *raft) +@@ -2601,11 +2689,24 @@ raft_become_follower(struct raft *raft) * configuration is already part of the log. Possibly the configuration * log entry will not be committed, but until we know that we must use the * new configuration. Our AppendEntries processing will properly update - * the server configuration later, if necessary. */ + * the server configuration later, if necessary. + * ++ * However, since we're sending replies about a failure to add, those new ++ * servers has to be cleaned up. Otherwise, they will stuck in a 'CATCHUP' ++ * phase in case this server regains leadership before they join through ++ * the current new leader. They are not yet in 'raft->servers', so not ++ * part of the shared configuration. ++ * + * Also we do not complete commands here, as they can still be completed + * if their log entries have already been replicated to other servers. + * If the entries were actually committed according to the new leader, our + * AppendEntries processing will complete the corresponding commands. + */ struct raft_server *s; - HMAP_FOR_EACH (s, hmap_node, &raft->add_servers) { +- HMAP_FOR_EACH (s, hmap_node, &raft->add_servers) { ++ HMAP_FOR_EACH_POP (s, hmap_node, &raft->add_servers) { raft_send_add_server_reply__(raft, &s->sid, s->address, false, -@@ -2615,8 +2667,6 @@ raft_become_follower(struct raft *raft) + RAFT_SERVER_LOST_LEADERSHIP); ++ raft_server_destroy(s); + } + if (raft->remove_server) { + raft_send_remove_server_reply__(raft, &raft->remove_server->sid, +@@ -2615,8 +2716,6 @@ raft_become_follower(struct raft *raft) raft_server_destroy(raft->remove_server); raft->remove_server = NULL; } @@ -110736,7 +111664,26 @@ index 1a3447a8dd..cf9edf35c6 100644 } static void -@@ -2865,61 +2915,56 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) +@@ -2708,6 +2807,18 @@ raft_become_leader(struct raft *raft) + raft_reset_election_timer(raft); + raft_reset_ping_timer(raft); + ++ if (raft->joining) { ++ /* It is possible that the server committing this one to the list of ++ * servers lost leadership before the entry is committed but after ++ * it was already replicated to majority of servers. In this case ++ * other servers will recognize this one as a valid cluster member ++ * and may transfer leadership to it and vote for it. This way ++ * we're becoming a cluster leader without receiving reply for a ++ * join request and will commit addition of this server ourselves. */ ++ VLOG_INFO_RL(&rl, "elected as leader while joining"); ++ raft->joining = false; ++ } ++ + struct raft_server *s; + HMAP_FOR_EACH (s, hmap_node, &raft->servers) { + raft_server_init_leader(raft, s); +@@ -2865,61 +2976,85 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) return false; } @@ -110756,12 +111703,12 @@ index 1a3447a8dd..cf9edf35c6 100644 - } - raft_command_complete(raft, cmd, RAFT_CMD_SUCCESS); + while (raft->commit_index < new_commit_index) { ++ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); + uint64_t index = ++raft->commit_index; + const struct raft_entry *e = raft_get_entry(raft, index); + + if (raft_entry_has_data(e)) { + struct raft_command *cmd = raft_find_command_by_eid(raft, &e->eid); -+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); + + if (cmd) { + if (!cmd->index && raft->role == RAFT_LEADER) { @@ -110841,10 +111788,39 @@ index 1a3447a8dd..cf9edf35c6 100644 + * reallocate raft->entries, which would invalidate 'e', so + * this case must be last, after the one for 'e->data'. */ + raft_run_reconfigure(raft); ++ } else if (e->servers && !raft_has_uncommitted_configuration(raft)) { ++ struct ovsdb_error *error; ++ struct raft_server *s; ++ struct hmap servers; ++ ++ error = raft_servers_from_json(e->servers, &servers); ++ ovs_assert(!error); ++ HMAP_FOR_EACH (s, hmap_node, &servers) { ++ struct raft_server *server = raft_find_server(raft, &s->sid); ++ ++ if (server && server->phase == RAFT_PHASE_COMMITTING) { ++ /* This server lost leadership while committing ++ * server 's', but it was committed later by a ++ * new leader. */ ++ server->phase = RAFT_PHASE_STABLE; ++ } ++ ++ if (raft->joining && uuid_equals(&s->sid, &raft->sid)) { ++ /* Leadership change happened before previous leader ++ * could commit the change of a servers list, but it ++ * was replicated and a new leader committed it. */ ++ VLOG_INFO_RL(&rl, ++ "added to configuration without reply " ++ "(eid: "UUID_FMT", commit index: %"PRIu64")", ++ UUID_ARGS(&e->eid), index); ++ raft->joining = false; ++ } ++ } ++ raft_servers_destroy(&servers); } } -@@ -3354,12 +3399,6 @@ raft_find_peer(struct raft *raft, const struct uuid *uuid) +@@ -3354,12 +3489,6 @@ raft_find_peer(struct raft *raft, const struct uuid *uuid) return s && !uuid_equals(&raft->sid, &s->sid) ? s : NULL; } @@ -110857,7 +111833,18 @@ index 1a3447a8dd..cf9edf35c6 100644 /* Figure 3.1: "If there exists an N such that N > commitIndex, a * majority of matchIndex[i] >= N, and log[N].term == currentTerm, set * commitIndex = N (sections 3.5 and 3.6)." */ -@@ -4000,7 +4039,7 @@ raft_write_snapshot(struct raft *raft, struct ovsdb_log *log, +@@ -3838,6 +3967,10 @@ raft_handle_add_server_request(struct raft *raft, + "to cluster "CID_FMT, s->nickname, SID_ARGS(&s->sid), + rq->address, CID_ARGS(&raft->cid)); + raft_send_append_request(raft, s, 0, "initialize new server"); ++ ++ if (failure_test == FT_TRANSFER_LEADERSHIP_AFTER_STARTING_TO_ADD) { ++ failure_test = FT_TRANSFER_LEADERSHIP; ++ } + } + + static void +@@ -4000,7 +4133,7 @@ raft_write_snapshot(struct raft *raft, struct ovsdb_log *log, if (error) { return error; } @@ -110866,7 +111853,7 @@ index 1a3447a8dd..cf9edf35c6 100644 /* Write log records. */ for (uint64_t index = new_log_start; index < raft->log_end; index++) { -@@ -4142,6 +4181,10 @@ static void +@@ -4142,6 +4275,10 @@ static void raft_handle_install_snapshot_request( struct raft *raft, const struct raft_install_snapshot_request *rq) { @@ -110877,7 +111864,7 @@ index 1a3447a8dd..cf9edf35c6 100644 if (raft_handle_install_snapshot_request__(raft, rq)) { union raft_rpc rpy = { .install_snapshot_reply = { -@@ -4940,6 +4983,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, +@@ -4940,6 +5077,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, failure_test = FT_CRASH_AFTER_SEND_EXEC_REQ; } else if (!strcmp(test, "crash-after-receiving-append-request-update")) { failure_test = FT_CRASH_AFTER_RECV_APPEND_REQ_UPDATE; @@ -110886,13 +111873,15 @@ index 1a3447a8dd..cf9edf35c6 100644 } else if (!strcmp(test, "delay-election")) { failure_test = FT_DELAY_ELECTION; struct raft *raft; -@@ -4952,6 +4997,11 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, +@@ -4952,6 +5091,13 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, failure_test = FT_DONT_SEND_VOTE_REQUEST; } else if (!strcmp(test, "stop-raft-rpc")) { failure_test = FT_STOP_RAFT_RPC; + } else if (!strcmp(test, + "transfer-leadership-after-sending-append-request")) { + failure_test = FT_TRANSFER_LEADERSHIP_AFTER_SEND_APPEND_REQ; ++ } else if (!strcmp(test, "transfer-leadership-after-starting-to-add")) { ++ failure_test = FT_TRANSFER_LEADERSHIP_AFTER_STARTING_TO_ADD; + } else if (!strcmp(test, "transfer-leadership")) { + failure_test = FT_TRANSFER_LEADERSHIP; } else if (!strcmp(test, "clear")) { @@ -113980,7 +114969,7 @@ index 2c7e163bd6..7be6628c34 100644 AT_CLEANUP diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index 7c2edeb9d4..23f29ac8c3 100644 +index 7c2edeb9d4..89adfaaf84 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -29,6 +29,58 @@ AT_CHECK([ovs-appctl revalidator/wait]) @@ -115377,7 +116366,65 @@ index 7c2edeb9d4..23f29ac8c3 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -6202,6 +6400,20 @@ AT_CHECK([tail -2 stderr], [0], [dnl +@@ -5868,6 +6066,57 @@ AT_CHECK([test 1 = `$PYTHON3 "$top_srcdir/utilities/ovs-pcap.in" p2-tx.pcap | wc + OVS_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([ofproto-dpif - continuation with meters]) ++AT_KEYWORDS([continuations pause meters]) ++OVS_VSWITCHD_START ++add_of_ports br0 1 2 ++ ++dnl Add meter with id=1. ++AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1']) ++ ++AT_DATA([flows.txt], [dnl ++table=0 dl_dst=50:54:00:00:00:0a actions=goto_table(1) ++table=1 dl_dst=50:54:00:00:00:0a actions=controller(pause,meter_id=1) ++]) ++AT_CHECK([ovs-ofctl -O OpenFlow13 add-flows br0 flows.txt]) ++ ++on_exit 'kill $(cat ovs-ofctl.pid)' ++AT_CAPTURE_FILE([ofctl_monitor.log]) ++AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in \ ++ --detach --no-chdir --pidfile 2> ofctl_monitor.log]) ++ ++AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ ++ 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x1234)']) ++ ++OVS_WAIT_UNTIL([test $(wc -l < ofctl_monitor.log) -ge 2]) ++OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) ++AT_CHECK([cat ofctl_monitor.log], [0], [dnl ++NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via action) data_len=14 (unbuffered) ++vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,dl_type=0x1234 ++]) ++ ++AT_CHECK([ovs-appctl revalidator/purge], [0]) ++AT_CHECK([ovs-ofctl -O OpenFlow13 dump-flows br0 | ofctl_strip | sort], [0], [dnl ++ n_packets=1, n_bytes=14, dl_dst=50:54:00:00:00:0a actions=goto_table:1 ++ table=1, n_packets=1, n_bytes=14, dl_dst=50:54:00:00:00:0a actions=controller(pause,meter_id=1) ++OFPST_FLOW reply (OF1.3): ++]) ++ ++AT_CHECK([ovs-ofctl -O OpenFlow13 dump-meters br0 | ofctl_strip | sort], [0], [dnl ++OFPST_METER_CONFIG reply (OF1.3): ++meter=1 pktps bands= ++type=drop rate=1 ++]) ++ ++AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | strip_timers], [0], [dnl ++OFPST_METER reply (OF1.3) (xid=0x2): ++meter:1 flow_count:0 packet_in_count:1 byte_in_count:14 duration:0.0s bands: ++0: packet_count:0 byte_count:0 ++]) ++ ++OVS_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_SETUP([ofproto-dpif - continuation with patch port]) + AT_KEYWORDS([continuations pause resume]) + OVS_VSWITCHD_START( +@@ -6202,6 +6451,20 @@ AT_CHECK([tail -2 stderr], [0], [dnl ovs-appctl: ovs-vswitchd: server returned an error ]) @@ -115398,7 +116445,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -7004,6 +7216,29 @@ AT_CHECK([ovs-appctl coverage/read-counter mac_learning_static_none_move], [0], +@@ -7004,6 +7267,29 @@ AT_CHECK([ovs-appctl coverage/read-counter mac_learning_static_none_move], [0], OVS_VSWITCHD_STOP AT_CLEANUP @@ -115428,7 +116475,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 AT_SETUP([ofproto-dpif - basic truncate action]) OVS_VSWITCHD_START add_of_ports br0 1 2 3 4 5 -@@ -7031,7 +7266,7 @@ dnl An 170 byte packet +@@ -7031,7 +7317,7 @@ dnl An 170 byte packet AT_CHECK([ovs-appctl netdev-dummy/receive p1 '000c29c8a0a4005056c0000808004500009cb4a6000040019003c0a8da01c0a8da640800cb5fa762000556f431ad0009388e08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f']) AT_CHECK([ovs-ofctl parse-pcap p1.pcap], [0], [dnl @@ -115437,7 +116484,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) AT_CHECK([ovs-appctl revalidator/purge], [0]) -@@ -7294,12 +7529,14 @@ dummy@ovs-dummy: hit:0 missed:0 +@@ -7294,12 +7580,14 @@ dummy@ovs-dummy: hit:0 missed:0 vm1 5/3: (dummy: ifindex=2011) ]) @@ -115455,7 +116502,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 dnl Prime ARP Cache for 1.1.2.92 AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) -@@ -7310,10 +7547,13 @@ ovs-vsctl \ +@@ -7310,10 +7598,13 @@ ovs-vsctl \ --id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" agent=127.0.0.1 \ header=128 sampling=1 polling=0 @@ -115471,7 +116518,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) dnl add rule for int-br to force packet onto tunnel. There is no ifindex -@@ -7600,13 +7840,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the +@@ -7600,13 +7891,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the dnl datapath level. AT_SETUP([ofproto-dpif - Bridge IPFIX sanity check]) OVS_VSWITCHD_START @@ -115501,7 +116548,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 dnl Send some packets that should be sampled. for i in `seq 1 3`; do AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800)']) -@@ -8666,7 +8921,7 @@ recirc_id(0),in_port(100),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.1 +@@ -8666,7 +8972,7 @@ recirc_id(0),in_port(100),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.1 ]) AT_CHECK([grep -e '|ofproto_dpif_xlate|WARN|' ovs-vswitchd.log | sed "s/^.*|WARN|//"], [0], [dnl @@ -115510,7 +116557,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP(["/stack underflow/d"]) -@@ -8717,6 +8972,40 @@ AT_CHECK([tail -1 stdout], [0], +@@ -8717,6 +9023,40 @@ AT_CHECK([tail -1 stdout], [0], OVS_VSWITCHD_STOP AT_CLEANUP @@ -115551,7 +116598,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 dnl ---------------------------------------------------------------------- AT_BANNER([ofproto-dpif -- megaflows]) -@@ -9855,7 +10144,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -9855,7 +10195,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via no_match) data_len=86 (unbuffered) @@ -115560,7 +116607,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -9906,7 +10195,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -9906,7 +10246,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via action) data_len=86 (unbuffered) @@ -115569,7 +116616,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10166,10 +10455,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10166,10 +10506,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered) @@ -115582,7 +116629,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log]) -@@ -10187,10 +10476,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10187,10 +10527,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We should see both packets AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered) @@ -115595,7 +116642,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10239,10 +10528,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10239,10 +10579,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115608,7 +116655,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log]) -@@ -10261,10 +10550,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10261,10 +10601,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115621,7 +116668,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) dnl -@@ -10320,9 +10609,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10320,9 +10660,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=126 in_port=1 (via action) data_len=126 (unbuffered) @@ -115633,7 +116680,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10433,7 +10722,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10433,7 +10773,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. Only one reply must be there AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -115642,7 +116689,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 dnl OFPT_ECHO_REQUEST (xid=0x0): 0 bytes of payload ]) -@@ -10467,7 +10756,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10467,7 +10807,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 ct_state=inv|trk,ipv6,in_port=2 (via action) data_len=86 (unbuffered) @@ -115651,7 +116698,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10523,16 +10812,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10523,16 +10863,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets (for each zone), not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115672,7 +116719,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10579,10 +10868,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10579,10 +10919,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115685,7 +116732,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10629,10 +10918,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10629,10 +10969,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the first and the last packet AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=47 ct_state=new|trk,ct_nw_src=172.16.0.1,ct_nw_dst=172.16.0.2,ct_nw_proto=17,ct_tp_src=41614,ct_tp_dst=5555,ip,in_port=1 (via action) data_len=47 (unbuffered) @@ -115698,7 +116745,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10681,19 +10970,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10681,19 +11021,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115723,7 +116770,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -10738,10 +11027,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10738,10 +11078,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_label=0x1,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -115736,7 +116783,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -11152,16 +11441,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -11152,16 +11492,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -115757,7 +116804,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) dnl The next test verifies that ct_clear at the datapath only gets executed -@@ -11235,13 +11524,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -11235,13 +11575,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.2.100,ct_nw_dst=10.1.2.200,ct_nw_proto=17,ct_tp_src=6,ct_tp_dst=6,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -115774,7 +116821,7 @@ index 7c2edeb9d4..23f29ac8c3 100644 ]) OVS_VSWITCHD_STOP -@@ -11504,7 +11793,7 @@ ovs-ofctl dump-flows br0 +@@ -11504,7 +11844,7 @@ ovs-ofctl dump-flows br0 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) AT_CHECK([tail -3 stdout], [0], [dnl @@ -116251,7 +117298,7 @@ index 06b671df8c..c618cf4839 100644 AT_CLEANUP diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at -index fc6253cfe9..9fbf5dc897 100644 +index fc6253cfe9..987e05103d 100644 --- a/tests/ovsdb-cluster.at +++ b/tests/ovsdb-cluster.at @@ -1,12 +1,25 @@ @@ -116359,7 +117406,7 @@ index fc6253cfe9..9fbf5dc897 100644 for i in $cleanup; do OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid]) -@@ -400,6 +428,61 @@ done +@@ -400,6 +428,167 @@ done AT_CLEANUP @@ -116418,10 +117465,116 @@ index fc6253cfe9..9fbf5dc897 100644 + +AT_CLEANUP + ++AT_SETUP([OVSDB cluster - leadership change after replication while joining]) ++AT_KEYWORDS([ovsdb server negative unix cluster join]) ++ ++n=5 ++AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db dnl ++ $abs_srcdir/idltest.ovsschema unix:s1.raft], [0], [], [stderr]) ++cid=$(ovsdb-tool db-cid s1.db) ++schema_name=$(ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema) ++for i in $(seq 2 $n); do ++ AT_CHECK([ovsdb-tool join-cluster s$i.db $schema_name unix:s$i.raft unix:s1.raft]) ++done ++ ++on_exit 'kill $(cat *.pid)' ++on_exit " ++ for i in \$(ls $(pwd)/s[[0-$n]]); do ++ ovs-appctl --timeout 1 -t \$i cluster/status $schema_name; ++ done ++" ++ ++dnl Starting servers one by one asking all exisitng servers to transfer ++dnl leadership after append reply forcing the joining server to try another ++dnl one that will also transfer leadership. Since transfer is happening ++dnl after the servers update is replicated to other servers, one of the ++dnl other servers will actually commit it. It may be a new leader from ++dnl one of the old members or the new joining server itself. ++for i in $(seq $n); do ++ dnl Make sure that all already started servers joined the cluster. ++ for j in $(seq $((i - 1)) ); do ++ AT_CHECK([ovsdb_client_wait unix:s$j.ovsdb $schema_name connected]) ++ done ++ for j in $(seq $((i - 1)) ); do ++ OVS_WAIT_UNTIL([ovs-appctl -t "$(pwd)"/s$j \ ++ cluster/failure-test \ ++ transfer-leadership-after-sending-append-request \ ++ | grep -q "engaged"]) ++ done ++ ++ AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off \ ++ --detach --no-chdir --log-file=s$i.log \ ++ --pidfile=s$i.pid --unixctl=s$i \ ++ --remote=punix:s$i.ovsdb s$i.db]) ++done ++ ++dnl Make sure that all servers joined the cluster. ++for i in $(seq $n); do ++ AT_CHECK([ovsdb_client_wait unix:s$i.ovsdb $schema_name connected]) ++done ++ ++for i in $(seq $n); do ++ OVS_APP_EXIT_AND_WAIT_BY_TARGET([$(pwd)/s$i], [s$i.pid]) ++done ++ ++AT_CLEANUP ++ ++AT_SETUP([OVSDB cluster - leadership change before replication while joining]) ++AT_KEYWORDS([ovsdb server negative unix cluster join]) ++ ++n=5 ++AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db dnl ++ $abs_srcdir/idltest.ovsschema unix:s1.raft], [0], [], [stderr]) ++cid=$(ovsdb-tool db-cid s1.db) ++schema_name=$(ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema) ++for i in $(seq 2 $n); do ++ AT_CHECK([ovsdb-tool join-cluster s$i.db $schema_name unix:s$i.raft unix:s1.raft]) ++done ++ ++on_exit 'kill $(cat *.pid)' ++on_exit " ++ for i in \$(ls $(pwd)/s[[0-$n]]); do ++ ovs-appctl --timeout 1 -t \$i cluster/status $schema_name; ++ done ++" ++ ++dnl Starting servers one by one asking all exisitng servers to transfer ++dnl leadership right after starting to add a server. Joining server will ++dnl need to find a new leader that will also transfer leadership. ++dnl This will continue until the same server will not become a leader ++dnl for the second time and will be able to add a new server. ++for i in $(seq $n); do ++ dnl Make sure that all already started servers joined the cluster. ++ for j in $(seq $((i - 1)) ); do ++ AT_CHECK([ovsdb_client_wait unix:s$j.ovsdb $schema_name connected]) ++ done ++ for j in $(seq $((i - 1)) ); do ++ OVS_WAIT_UNTIL([ovs-appctl -t "$(pwd)"/s$j \ ++ cluster/failure-test \ ++ transfer-leadership-after-starting-to-add \ ++ | grep -q "engaged"]) ++ done ++ ++ AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off \ ++ --detach --no-chdir --log-file=s$i.log \ ++ --pidfile=s$i.pid --unixctl=s$i \ ++ --remote=punix:s$i.ovsdb s$i.db]) ++done ++ ++dnl Make sure that all servers joined the cluster. ++for i in $(seq $n); do ++ AT_CHECK([ovsdb_client_wait unix:s$i.ovsdb $schema_name connected]) ++done ++ ++for i in $(seq $n); do ++ OVS_APP_EXIT_AND_WAIT_BY_TARGET([$(pwd)/s$i], [s$i.pid]) ++done ++ ++AT_CLEANUP OVS_START_SHELL_HELPERS -@@ -410,15 +493,15 @@ ovsdb_cluster_failure_test () { +@@ -410,15 +599,15 @@ ovsdb_cluster_failure_test () { remote_2=$2 crash_node=$3 crash_command=$4 @@ -116441,7 +117594,7 @@ index fc6253cfe9..9fbf5dc897 100644 n=3 join_cluster() { -@@ -434,7 +517,7 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral +@@ -434,7 +623,7 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral start_server() { local i=$1 printf "\ns$i: starting\n" @@ -116450,7 +117603,7 @@ index fc6253cfe9..9fbf5dc897 100644 } connect_server() { local i=$1 -@@ -453,21 +536,30 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral +@@ -453,21 +642,30 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral # To ensure $new_leader node the new leader, we delay election timer for # the other follower. if test -n "$new_leader"; then @@ -116487,7 +117640,7 @@ index fc6253cfe9..9fbf5dc897 100644 fi AT_CHECK([ovs-vsctl --db="$db" --no-leader-only --no-wait --columns=type --bare list QoS], [0], [x ]) -@@ -563,6 +655,11 @@ AT_KEYWORDS([ovsdb server negative unix cluster pending-txn]) +@@ -563,6 +761,11 @@ AT_KEYWORDS([ovsdb server negative unix cluster pending-txn]) ovsdb_cluster_failure_test 2 2 3 crash-after-receiving-append-request-update AT_CLEANUP @@ -116499,7 +117652,7 @@ index fc6253cfe9..9fbf5dc897 100644 AT_SETUP([OVSDB cluster - competing candidates]) AT_KEYWORDS([ovsdb server negative unix cluster competing-candidates]) -@@ -629,9 +726,8 @@ ovsdb_torture_test () { +@@ -629,9 +832,8 @@ ovsdb_torture_test () { local variant=$3 # 'kill' and restart or 'remove' and add cp $top_srcdir/vswitchd/vswitch.ovsschema schema schema=`ovsdb-tool schema-name schema` @@ -117397,7 +118550,7 @@ index 62e2b63832..22d4481efb 100644 +OVSDB_CHECK_IDL_CHANGE_AWARE([standalone]) +OVSDB_CHECK_IDL_CHANGE_AWARE([clustered]) diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at -index 876cb836cd..ad9219da3c 100644 +index 876cb836cd..fa3e40e462 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -4,7 +4,7 @@ m4_define([OVSDB_SERVER_SHUTDOWN], @@ -117493,7 +118646,19 @@ index 876cb836cd..ad9219da3c 100644 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=db:mydb,Root,managers --remote=db:mydb,Root,manager_options --log-file db], [0], [ignore], [ignore]) ovs-appctl -t ovsdb-server time/warp 6000 1000 AT_CHECK( -@@ -686,6 +697,7 @@ ovsdb_check_online_compaction() { +@@ -656,8 +667,10 @@ AT_CHECK_UNQUOTED( + [ignore]) + # The error message for being unable to negotiate a shared ciphersuite + # is 'sslv3 alert handshake failure'. This is not the clearest message. ++# In openssl 3.2.0 all the error messages were updated to replace 'sslv3' ++# with 'ssl/tls'. + AT_CHECK_UNQUOTED( +- [grep "sslv3 alert handshake failure" output], [0], ++ [grep -E "(sslv3|ssl/tls) alert handshake failure" output], [0], + [stdout], + [ignore]) + OVSDB_SERVER_SHUTDOWN +@@ -686,6 +699,7 @@ ovsdb_check_online_compaction() { ovsdb-tool create-cluster db schema unix:s1.raft fi]) dnl Start ovsdb-server. @@ -117501,7 +118666,7 @@ index 876cb836cd..ad9219da3c 100644 AT_CHECK([ovsdb-server -vvlog:off -vconsole:off --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0]) AT_CHECK([ovsdb_client_wait unix:socket ordinals connected]) AT_CAPTURE_FILE([ovsdb-server.log]) -@@ -832,7 +844,7 @@ _uuid name number +@@ -832,7 +846,7 @@ _uuid name number <0> five 5 <1> four 4 <2> three 3 @@ -117510,7 +118675,7 @@ index 876cb836cd..ad9219da3c 100644 OVSDB_SERVER_SHUTDOWN } OVS_END_SHELL_HELPERS -@@ -1255,7 +1267,7 @@ dnl a case where there is only one transaction in a history. +@@ -1255,7 +1269,7 @@ dnl a case where there is only one transaction in a history. get_memory_value () { n=$(ovs-appctl -t ovsdb-server memory/show dnl | tr ' ' '\n' | grep "^$1:" | cut -d ':' -f 2) @@ -117519,7 +118684,7 @@ index 876cb836cd..ad9219da3c 100644 n=0 fi echo $n -@@ -1293,6 +1305,24 @@ dnl After removing all the bridges, the number of atoms in the database +@@ -1293,6 +1307,24 @@ dnl After removing all the bridges, the number of atoms in the database dnl should return to its initial value. AT_CHECK([test $(get_memory_value atoms) -eq $initial_db_atoms]) @@ -117544,7 +118709,7 @@ index 876cb836cd..ad9219da3c 100644 OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP -@@ -1319,15 +1349,14 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1319,15 +1351,14 @@ m4_define([OVSDB_CHECK_EXECUTION], $2 > schema PKIDIR=$abs_top_builddir/tests AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore]) @@ -117563,7 +118728,7 @@ index 876cb836cd..ad9219da3c 100644 OVSDB_SERVER_SHUTDOWN AT_CLEANUP]) -@@ -1356,16 +1385,15 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1356,16 +1387,15 @@ m4_define([OVSDB_CHECK_EXECUTION], AT_SKIP_IF([test $HAVE_IPV6 = no]) $2 > schema PKIDIR=$abs_top_builddir/tests @@ -117583,7 +118748,7 @@ index 876cb836cd..ad9219da3c 100644 OVSDB_SERVER_SHUTDOWN AT_CLEANUP]) -@@ -1392,16 +1420,15 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1392,16 +1422,15 @@ m4_define([OVSDB_CHECK_EXECUTION], AT_KEYWORDS([ovsdb server positive tcp $5]) $2 > schema PKIDIR=$abs_top_builddir/tests @@ -117603,7 +118768,7 @@ index 876cb836cd..ad9219da3c 100644 OVSDB_SERVER_SHUTDOWN AT_CLEANUP]) -@@ -1429,16 +1456,15 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1429,16 +1458,15 @@ m4_define([OVSDB_CHECK_EXECUTION], AT_SKIP_IF([test $HAVE_IPV6 = no]) $2 > schema PKIDIR=$abs_top_builddir/tests @@ -117623,7 +118788,7 @@ index 876cb836cd..ad9219da3c 100644 OVSDB_SERVER_SHUTDOWN AT_CLEANUP]) -@@ -1518,9 +1544,9 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1518,9 +1546,9 @@ m4_define([OVSDB_CHECK_EXECUTION], target=4 $2 > schema schema_name=`ovsdb-tool schema-name schema` @@ -117634,7 +118799,7 @@ index 876cb836cd..ad9219da3c 100644 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log dnl --pidfile --remote=punix:db1.sock db1 ], [0], [ignore], [ignore]) -@@ -1576,12 +1602,11 @@ m4_define([OVSDB_CHECK_EXECUTION], +@@ -1576,12 +1604,11 @@ m4_define([OVSDB_CHECK_EXECUTION], AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore]) @@ -117649,7 +118814,7 @@ index 876cb836cd..ad9219da3c 100644 m4_foreach([txn], [$3], [AT_CHECK([ovsdb-client transact 'txn'], [0], [stdout], [ignore]) -@@ -1622,11 +1647,10 @@ m4_define([OVSDB_CHECK_REPLICATION], +@@ -1622,11 +1649,10 @@ m4_define([OVSDB_CHECK_REPLICATION], AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore]) @@ -117663,7 +118828,7 @@ index 876cb836cd..ad9219da3c 100644 m4_foreach([txn], [$3], [AT_CHECK([ ovsdb-client transact 'txn' ], [0], [stdout], [ignore]) -@@ -1694,6 +1718,7 @@ AT_CLEANUP +@@ -1694,6 +1720,7 @@ AT_CLEANUP #ovsdb-server/set-sync-exclude-tables command AT_SETUP([ovsdb-server/set-sync-exclude-tables]) @@ -117671,7 +118836,7 @@ index 876cb836cd..ad9219da3c 100644 AT_KEYWORDS([ovsdb server replication set-exclude-tables]) AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no]) -@@ -1702,12 +1727,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) +@@ -1702,12 +1729,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore]) @@ -117686,7 +118851,7 @@ index 876cb836cd..ad9219da3c 100644 AT_CHECK([ovsdb-client transact unix:db.sock \ '[["mydb", -@@ -1716,11 +1739,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \ +@@ -1716,11 +1741,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \ "row": {"number": 0, "name": "zero"}}, {"op": "insert", "table": "b", @@ -117700,7 +118865,7 @@ index 876cb836cd..ad9219da3c 100644 cat stdout > dump1 OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep zero ]) AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore]) -@@ -1744,16 +1765,20 @@ AT_CLEANUP +@@ -1744,16 +1767,20 @@ AT_CLEANUP #ovsdb-server/connect-active-ovsdb-server AT_SETUP([ovsdb-server/connect-active-server]) @@ -117725,7 +118890,7 @@ index 876cb836cd..ad9219da3c 100644 dnl Try to connect without specifying the active server. AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server], [0], -@@ -1783,6 +1808,7 @@ AT_CLEANUP +@@ -1783,6 +1810,7 @@ AT_CLEANUP #ovsdb-server/disconnect-active-server command AT_SETUP([ovsdb-server/disconnect-active-server]) @@ -117733,7 +118898,7 @@ index 876cb836cd..ad9219da3c 100644 AT_KEYWORDS([ovsdb server replication disconnect-active-server]) AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no]) -@@ -1791,10 +1817,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) +@@ -1791,10 +1819,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore]) @@ -117745,7 +118910,7 @@ index 876cb836cd..ad9219da3c 100644 AT_CHECK([ovsdb-client transact unix:db.sock \ '[["mydb", -@@ -1840,7 +1864,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8 +@@ -1840,7 +1866,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8 --- > _uuid name number > ----- ---- ------ @@ -117754,7 +118919,7 @@ index 876cb836cd..ad9219da3c 100644 dnl The backup server now become active, and can accept write transactions. AT_CHECK([ovsdb-client transact unix:db2.sock \ -@@ -1891,13 +1915,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each +@@ -1891,13 +1917,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each dnl other. This is not an supported operation state, but to simulate a start dnl up condition where an HA manger can select which one to be an active dnl server soon after. @@ -117771,7 +118936,7 @@ index 876cb836cd..ad9219da3c 100644 dnl dnl make sure both servers reached the replication state -@@ -1965,8 +1988,8 @@ AT_CHECK([ovsdb-tool transact db \ +@@ -1965,8 +1990,8 @@ AT_CHECK([ovsdb-tool transact db \ "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore]) dnl Start 'db', then try to be a back up server of itself. @@ -117782,7 +118947,7 @@ index 876cb836cd..ad9219da3c 100644 dnl Save the current content AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout]) -@@ -1984,6 +2007,7 @@ AT_CHECK([diff dump1 dump2]) +@@ -1984,6 +2009,7 @@ AT_CHECK([diff dump1 dump2]) AT_CLEANUP AT_SETUP([ovsdb-server/read-only db:ptcp connection]) @@ -117790,7 +118955,7 @@ index 876cb836cd..ad9219da3c 100644 AT_KEYWORDS([ovsdb server read-only]) AT_DATA([schema], [[{"name": "mydb", -@@ -2072,12 +2096,17 @@ AT_CHECK([ovsdb-tool transact db2 \ +@@ -2072,12 +2098,17 @@ AT_CHECK([ovsdb-tool transact db2 \ "row": {"number": 10, "name": "ten"}}]]'], [0], [ignore], [ignore]) dnl Start both 'db1' and 'db2'. @@ -117813,7 +118978,7 @@ index 876cb836cd..ad9219da3c 100644 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep active]) OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep active]) -@@ -2177,7 +2206,7 @@ dnl Starting a dummy server only to reserve some tcp port. +@@ -2177,7 +2208,7 @@ dnl Starting a dummy server only to reserve some tcp port. AT_CHECK([cp db db.tmp]) AT_CHECK([ovsdb-server -vfile -vvlog:off --log-file=listener.log dnl --detach --no-chdir dnl @@ -117822,7 +118987,7 @@ index 876cb836cd..ad9219da3c 100644 --remote=ptcp:0:127.0.0.1 dnl db.tmp], [0], [stdout], [stderr]) PARSE_LISTENING_PORT([listener.log], [BAD_TCP_PORT]) -@@ -2304,6 +2333,6 @@ CLEAN_LOG_FILE([2.log], [2.log.clear]) +@@ -2304,6 +2335,6 @@ CLEAN_LOG_FILE([2.log], [2.log.clear]) dnl Checking that databases and logs are equal. AT_CHECK([diff db.clear ./replay_dir/db.copy.clear]) @@ -119333,7 +120498,7 @@ index 80bc1dd5c3..9d47461cc2 100644 +/Unable to parse geneve options/d"]) +AT_CLEANUP diff --git a/tests/system-route.at b/tests/system-route.at -index 1714273e35..270956d13f 100644 +index 1714273e35..3ea5f6e9ba 100644 --- a/tests/system-route.at +++ b/tests/system-route.at @@ -14,10 +14,9 @@ dnl Add ip address. @@ -119350,6 +120515,74 @@ index 1714273e35..270956d13f 100644 dnl Delete ip address. AT_CHECK([ip addr del 10.0.0.17/24 dev p1-route], [0], [stdout]) +@@ -26,3 +25,67 @@ OVS_WAIT_UNTIL([test `ovs-appctl ovs/route/show | grep -c 'p1-route'` -eq 0 ]) + + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP ++ ++dnl Checks that OVS doesn't use routes from non-standard tables. ++AT_SETUP([ovs-route - route tables]) ++AT_KEYWORDS([route]) ++OVS_TRAFFIC_VSWITCHD_START() ++ ++dnl Create tap port. ++on_exit 'ip link del p1-route' ++AT_CHECK([ip tuntap add name p1-route mode tap]) ++AT_CHECK([ip link set p1-route up]) ++ ++dnl Add ip address. ++AT_CHECK([ip addr add 10.0.0.17/24 dev p1-route], [0], [stdout]) ++ ++dnl Check that OVS catches route updates. ++OVS_WAIT_UNTIL_EQUAL([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [dnl ++Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 ++Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local]) ++ ++dnl Add a route to the main routing table and check that OVS caches ++dnl this new route. ++AT_CHECK([ip route add 10.0.0.18/32 dev p1-route]) ++OVS_WAIT_UNTIL_EQUAL([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [dnl ++Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 ++Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local ++Cached: 10.0.0.18/32 dev p1-route SRC 10.0.0.17]) ++ ++dnl Add a route to a custom routing table and check that OVS doesn't cache it. ++AT_CHECK([ip route add 10.0.0.19/32 dev p1-route table 42]) ++AT_CHECK([ip route show table 42 | grep 'p1-route' | grep -q '10.0.0.19']) ++dnl Give the main thread a chance to act. ++AT_CHECK([ovs-appctl revalidator/wait]) ++dnl Check that OVS didn't learn this route. ++AT_CHECK([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [0], [dnl ++Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 ++Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local ++Cached: 10.0.0.18/32 dev p1-route SRC 10.0.0.17 ++]) ++ ++dnl Delete a route from the main table and check that OVS removes the route ++dnl from the cache. ++AT_CHECK([ip route del 10.0.0.18/32 dev p1-route]) ++OVS_WAIT_UNTIL_EQUAL([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [dnl ++Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 ++Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local]) ++ ++dnl Delete a route from a custom routing table and check that the cache ++dnl dosn't change. ++AT_CHECK([ip route del 10.0.0.19/32 dev p1-route table 42]) ++dnl Give the main thread a chance to act. ++AT_CHECK([ovs-appctl revalidator/wait]) ++dnl Check that the cache is still the same. ++AT_CHECK([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [0], [dnl ++Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 ++Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local ++]) ++ ++dnl Delete ip address. ++AT_CHECK([ip addr del 10.0.0.17/24 dev p1-route], [0], [stdout]) ++dnl Check that routes were removed from OVS. ++OVS_WAIT_UNTIL([test $(ovs-appctl ovs/route/show | grep -c 'p1-route') -eq 0 ]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP diff --git a/tests/system-tap.at b/tests/system-tap.at index 871a3bda4f..3d84a53182 100644 --- a/tests/system-tap.at @@ -119364,7 +120597,7 @@ index 871a3bda4f..3d84a53182 100644 ]) diff --git a/tests/system-traffic.at b/tests/system-traffic.at -index f22d86e466..099e972812 100644 +index f22d86e466..8a3caeb0af 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -10,13 +10,13 @@ ADD_NAMESPACES(at_ns0, at_ns1) @@ -119555,11 +120788,13 @@ index f22d86e466..099e972812 100644 dnl Okay, now check the overlay with different packet sizes -NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +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 -+]) + 3 packets transmitted, 3 received, 0% packet loss, time 0ms + ]) +-NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +NS_CHECK_EXEC([at_ns0], [ping -s 1600 -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 -+]) + 3 packets transmitted, 3 received, 0% packet loss, time 0ms + ]) +-NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +NS_CHECK_EXEC([at_ns0], [ping -s 3200 -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 +]) @@ -119598,14 +120833,12 @@ index f22d86e466..099e972812 100644 + +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 - ]) --NS_CHECK_EXEC([at_ns0], [ping -s 1600 -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 ++]) +dnl Okay, now check the overlay with different packet sizes +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 - ]) --NS_CHECK_EXEC([at_ns0], [ping -s 3200 -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 ++]) +NS_CHECK_EXEC([at_ns0], [ping -s 1600 -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 +]) @@ -119879,11 +121112,13 @@ index f22d86e466..099e972812 100644 dnl Okay, now check the overlay with different packet sizes -NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +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 -+]) + 3 packets transmitted, 3 received, 0% packet loss, time 0ms + ]) +-NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +NS_CHECK_EXEC([at_ns0], [ping -s 1600 -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 -+]) + 3 packets transmitted, 3 received, 0% packet loss, time 0ms + ]) +-NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl +NS_CHECK_EXEC([at_ns0], [ping -s 3200 -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 +]) @@ -119999,18 +121234,16 @@ index f22d86e466..099e972812 100644 +3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) +NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -W 2 172.31.2.100 | FORMAT_PING], [0], [dnl - 3 packets transmitted, 3 received, 0% packet loss, time 0ms - ]) --NS_CHECK_EXEC([at_ns0], [ping -s 1600 -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 ++]) + +dnl Now, check the overlay with different packet sizes. +NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.1.1.2 | FORMAT_PING], [0], [dnl +3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) +NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -W 2 10.1.1.2 | FORMAT_PING], [0], [dnl - 3 packets transmitted, 3 received, 0% packet loss, time 0ms - ]) --NS_CHECK_EXEC([at_ns0], [ping -s 3200 -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 ++]) +NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -W 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) @@ -120519,7 +121752,7 @@ index f22d86e466..099e972812 100644 sleep 1 dnl The hex dump is an mpls packet encapsulating ethernet packet. pkt=eth/mpls/eth/ip/icmp -@@ -1933,14 +2276,50 @@ dnl p1(at_ns1) interface +@@ -1933,15 +2276,51 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected decapsulated on the egress interface @@ -120537,8 +121770,8 @@ index f22d86e466..099e972812 100644 +OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *1617 *1819 *1a1b *1c1d *1e1f *2021 *2223 *2425" 2>&1 1>/dev/null]) +OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *2627 *2829 *2a2b *2c2d *2e2f *3031 *3233 *3435" 2>&1 1>/dev/null]) +OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0060: *3637" 2>&1 1>/dev/null]) -+ -+ + + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP + @@ -120565,7 +121798,7 @@ index f22d86e466..099e972812 100644 + other_config:min-rate=2000000 other_config:max-rate=3000000 dnl + other_config:burst=3000000], + [ignore], [ignore]) - ++ +dnl Wait for qdiscs to be applied. +OVS_WAIT_UNTIL([tc qdisc show dev ovs-p0 | grep -q htb]) +OVS_WAIT_UNTIL([tc qdisc show dev ovs-p1 | grep -q htb]) @@ -120574,9 +121807,10 @@ index f22d86e466..099e972812 100644 +m4_define([HTB_CONF], [rate 2Mbit ceil 3Mbit burst 375000b cburst 375000b]) +AT_CHECK([tc class show dev ovs-p0 | grep -q 'class htb .* HTB_CONF']) +AT_CHECK([tc class show dev ovs-p1 | grep -q 'class htb .* HTB_CONF']) - ++ OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP + @@ -1985,9 +2364,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl @@ -120619,7 +121853,19 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -2182,7 +2561,7 @@ priority=100,in_port=2,icmp,ct_state=+trk+est,action=1 +@@ -2149,7 +2528,10 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl + icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0) + ]) + +-AT_CHECK([ovs-appctl dpctl/flush-conntrack]) ++AT_CHECK([ovs-appctl dpctl/flush-conntrack 'ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2']) ++ ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl ++]) + + dnl Pings from ns1->ns0 should fail. + NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -w 2 10.1.1.1 | FORMAT_PING], [0], [dnl +@@ -2182,7 +2564,7 @@ priority=100,in_port=2,icmp,ct_state=+trk+est,action=1 AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Pings from ns0->ns1 should work fine. @@ -120628,7 +121874,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -2282,7 +2661,7 @@ NS_CHECK_EXEC([at_ns1], [ping6 -q -c 3 -i 0.3 -w 2 fc00::1 | FORMAT_PING], [0], +@@ -2282,7 +2664,7 @@ NS_CHECK_EXEC([at_ns1], [ping6 -q -c 3 -i 0.3 -w 2 fc00::1 | FORMAT_PING], [0], ]) dnl Pings from ns0->ns1 should work fine. @@ -120637,7 +121883,19 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -2980,6 +3359,15 @@ NXST_FLOW reply: +@@ -2290,6 +2672,11 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl + icmpv6,orig=(src=fc00::1,dst=fc00::2,id=,type=128,code=0),reply=(src=fc00::2,dst=fc00::1,id=,type=129,code=0) + ]) + ++AT_CHECK([ovs-appctl dpctl/flush-conntrack 'ct_ipv6_src=fc00::1,ct_ipv6_dst=fc00::2']) ++ ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl ++]) ++ + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + +@@ -2980,6 +3367,15 @@ NXST_FLOW reply: table=1, priority=100,ct_state=+est+trk,in_port=1 actions=output:2 ]) @@ -120653,7 +121911,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -3140,11 +3528,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -3140,11 +3536,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log | grep -v ff02 | grep -v fe80 | grep -v no_match], [0], [dnl NXT_PACKET_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=75 ct_state=inv|trk,ip,in_port=2 (via action) data_len=75 (unbuffered) @@ -120668,7 +121926,7 @@ index f22d86e466..099e972812 100644 ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.1)], [0], [dnl -@@ -3181,12 +3569,12 @@ dnl Modify userspace conntrack fragmentation handling. +@@ -3181,12 +3577,12 @@ dnl Modify userspace conntrack fragmentation handling. DPCTL_MODIFY_FRAGMENTATION() dnl Ipv4 fragmentation connectivity check. @@ -120683,7 +121941,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3258,12 +3646,12 @@ dnl Modify userspace conntrack fragmentation handling. +@@ -3258,12 +3654,12 @@ dnl Modify userspace conntrack fragmentation handling. DPCTL_MODIFY_FRAGMENTATION() dnl Ipv4 fragmentation connectivity check. @@ -120698,7 +121956,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3303,22 +3691,22 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) +@@ -3303,22 +3699,22 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) dnl Ipv4 fragmentation connectivity check. @@ -120725,7 +121983,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3345,6 +3733,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt]) +@@ -3345,6 +3741,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl ]) @@ -120737,7 +121995,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -3472,12 +3865,12 @@ dnl "connect: Cannot assign requested address" +@@ -3472,12 +3873,12 @@ dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) dnl Ipv6 fragmentation connectivity check. @@ -120752,7 +122010,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3554,12 +3947,12 @@ dnl "connect: Cannot assign requested address" +@@ -3554,12 +3955,12 @@ dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) dnl Ipv4 fragmentation connectivity check. @@ -120767,7 +122025,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3597,22 +3990,22 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) +@@ -3597,22 +3998,22 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::4]) dnl Ipv6 fragmentation connectivity check. @@ -120794,7 +122052,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3823,18 +4216,18 @@ ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.1.1.1/24], +@@ -3823,18 +4224,18 @@ ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.1.1.1/24], [id 0 dstport 4789]) dnl First, check the underlay @@ -120817,7 +122075,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3883,18 +4276,18 @@ dnl "connect: Cannot assign requested address" +@@ -3883,18 +4284,18 @@ dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) dnl First, check the underlay @@ -120840,7 +122098,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -3919,8 +4312,8 @@ NS_CHECK_EXEC([at_ns0], [ip route add 10.1.1.0/24 via 10.2.1.2]) +@@ -3919,8 +4320,8 @@ NS_CHECK_EXEC([at_ns0], [ip route add 10.1.1.0/24 via 10.2.1.2]) NS_CHECK_EXEC([at_ns1], [ip route add 10.1.1.0/24 via 10.2.1.1]) dnl Solely for debugging when things go wrong @@ -120851,7 +122109,7 @@ index f22d86e466..099e972812 100644 AT_DATA([flows.txt], [dnl table=0,arp,actions=normal -@@ -4007,7 +4400,7 @@ dnl The default udp_single and icmp_first timeouts are 30 seconds in +@@ -4007,7 +4408,7 @@ dnl The default udp_single and icmp_first timeouts are 30 seconds in dnl kernel DP, and 60 seconds in userspace DP. dnl Send ICMP and UDP traffic @@ -120860,7 +122118,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) -@@ -4033,7 +4426,7 @@ done +@@ -4033,7 +4434,7 @@ done AT_CHECK([ovs-vsctl --may-exist add-zone-tp $DP_TYPE zone=5 udp_first=1 udp_single=1 icmp_first=1 icmp_reply=1]) dnl Send ICMP and UDP traffic @@ -120869,7 +122127,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) -@@ -4051,7 +4444,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl +@@ -4051,7 +4452,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl ]) dnl Re-send ICMP and UDP traffic to test conntrack cache @@ -120878,7 +122136,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) -@@ -4072,7 +4465,7 @@ dnl Set the timeout policy to default again. +@@ -4072,7 +4473,7 @@ dnl Set the timeout policy to default again. AT_CHECK([ovs-vsctl del-zone-tp $DP_TYPE zone=5]) dnl Send ICMP and UDP traffic @@ -120887,7 +122145,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) -@@ -4100,15 +4493,15 @@ action=normal +@@ -4100,15 +4501,15 @@ action=normal AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) @@ -120906,7 +122164,7 @@ index f22d86e466..099e972812 100644 "1616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610a, actions=ct(table=1)"]) AT_CHECK([ovs-appctl dpctl/dump-flows | head -2 | tail -1 | grep -q -e ["]udp[(]src=5001["]]) -@@ -4265,7 +4658,7 @@ table=2,in_port=1,ip,ct_state=+trk+est,ct_zone=2,action=LOCAL +@@ -4265,7 +4666,7 @@ table=2,in_port=1,ip,ct_state=+trk+est,ct_zone=2,action=LOCAL AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) @@ -120915,7 +122173,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -4336,7 +4729,7 @@ table=4,priority=100,ip,action=output:NXM_NX_REG0[[]] +@@ -4336,7 +4737,7 @@ table=4,priority=100,ip,action=output:NXM_NX_REG0[[]] AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) @@ -120924,7 +122182,55 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -5360,7 +5753,7 @@ table=10 priority=0 action=drop +@@ -5031,11 +5432,11 @@ ADD_NAMESPACES(at_ns0, at_ns1) + ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") + NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address 80:88:88:88:88:88]) + ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ++NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address 80:89:89:89:89:89]) + + dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. + AT_DATA([flows.txt], [dnl +-in_port=1,tcp,action=ct(commit,zone=1,nat(src=10.1.1.240:34568,random)),2 +-in_port=2,ct_state=-trk,tcp,tp_dst=34567,action=ct(table=0,zone=1,nat) ++in_port=1,tcp,action=ct(commit,zone=1,nat(src=10.1.1.240:34568)),2 + in_port=2,ct_state=-trk,tcp,tp_dst=34568,action=ct(table=0,zone=1,nat) + in_port=2,ct_state=+trk,ct_zone=1,tcp,action=1 + dnl +@@ -5059,17 +5460,29 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) + + dnl HTTP requests from p0->p1 should work fine. + OVS_START_L7([at_ns1], [http]) +-NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 1 -T 1 --retry-connrefused -v -o wget0.log]) ++ ++dnl Send a valid SYN to make conntrack pick it up. ++dnl The source port used is 123 to prevent unwanted reuse in the next HTTP request. ++eth=8089898989898088888888880800 ++ip4=4500002800000000400664cc0a0101010a010102 ++tcp=007b005000000000000000005002000099130000 ++syn_pkt=${eth}${ip4}${tcp} ++AT_CHECK([ovs-ofctl packet-out br0 "packet=${syn_pkt} actions=ct(commit,zone=1,nat(src=10.1.1.240:34568))"]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | uniq], [0], [dnl ++tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),zone=1,protoinfo=(state=) ++]) + + NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 1 -T 1 --retry-connrefused -v -o wget0.log], [4]) + +-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst=10.1.1.2[[45]][[0-9]]/dst=10.1.1.2XX/' | uniq], [0], [dnl +-tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),zone=1,protoinfo=(state=) ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | uniq], [0], [dnl ++tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),zone=1,protoinfo=(state=) + ]) + + OVS_TRAFFIC_VSWITCHD_STOP(["dnl + /Unable to NAT due to tuple space exhaustion - if DoS attack, use firewalling and\/or zone partitioning./d +-/Dropped .* log messages in last .* seconds \(most recently, .* seconds ago\) due to excessive rate/d"]) ++/Dropped .* log messages in last .* seconds \(most recently, .* seconds ago\) due to excessive rate/d ++/|WARN|.* execute ct.* failed/d"]) + AT_CLEANUP + + AT_SETUP([conntrack - more complex SNAT]) +@@ -5360,7 +5773,7 @@ table=10 priority=0 action=drop AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) rm p0.pcap @@ -120933,7 +122239,7 @@ index f22d86e466..099e972812 100644 sleep 1 dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response. -@@ -5384,7 +5777,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst= +@@ -5384,7 +5797,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst= udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),mark=1 ]) @@ -120942,7 +122248,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -6074,7 +6467,7 @@ dnl waiting, we get occasional failures due to the following error: +@@ -6074,7 +6487,7 @@ dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::240]) @@ -120951,7 +122257,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -6128,13 +6521,13 @@ OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) +@@ -6128,13 +6541,13 @@ OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) rm p0.pcap @@ -120967,7 +122273,7 @@ index f22d86e466..099e972812 100644 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl udp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=) -@@ -6454,7 +6847,7 @@ on_exit 'ovs-appctl revalidator/purge' +@@ -6454,7 +6867,7 @@ on_exit 'ovs-appctl revalidator/purge' on_exit 'ovs-appctl dpif/dump-flows br0' dnl Should work with the virtual IP address through NAT @@ -120976,7 +122282,7 @@ index f22d86e466..099e972812 100644 echo Request $i NS_CHECK_EXEC([at_ns1], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget$i.log]) done -@@ -6743,6 +7136,239 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE +@@ -6743,6 +7156,302 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP @@ -121213,10 +122519,73 @@ index f22d86e466..099e972812 100644 +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP + ++AT_SETUP([conntrack - Flush many conntrack entries by port]) ++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") ++ ++AT_DATA([flows.txt], [dnl ++priority=100,in_port=1,udp,action=ct(zone=1,commit),2 ++]) ++ ++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) ++ ++dnl 20 packets from port 1 and 1 packet from port 2. ++flow_l3="\ ++ eth_src=50:54:00:00:00:09,eth_dst=50:54:00:00:00:0a,dl_type=0x0800,\ ++ nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_proto=17,nw_ttl=64,nw_frag=no" ++ ++head="50540000000a50540000000908004500005c000000004011648d0a0101010a010102" ++len=72 ++base_csum=1366 ++tail="000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\ ++ 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" ++ ++dst_port=1 ++for src_port in $(seq 1 20); do ++ csum=$((base_csum - src_port - dst_port)) ++ frame=$(printf "%s%04x%04x%04x%04x%s" $head 1 $src_port $len $csum $tail) ++ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=$frame actions=resubmit(,0)"]) ++done ++ ++src_port=2 ++dst_port=1 ++csum=$((base_csum - src_port - dst_port)) ++frame=$(printf "%s%04x%04x%04x%04x%s" $head $src_port $dst_port $len $csum $tail) ++AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=$frame actions=resubmit(,0)"]) ++ ++: > conntrack ++ ++for i in $(seq 1 20); do ++ echo "udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=${i}),reply=(src=10.1.1.2,dst=10.1.1.1,sport=${i},dport=1),zone=1" >> conntrack ++done ++echo "udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=2,dport=1),reply=(src=10.1.1.2,dst=10.1.1.1,sport=1,dport=2),zone=1" >> conntrack ++ ++sort conntrack > expout ++ ++AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=1 | grep -F "src=10.1.1.1," | sort ], [0], [expout]) ++ ++dnl Check that flushing conntrack by port 1 flush all ct for port 1 but keeps ct for port 2. ++for i in $(seq 1 20); do ++ AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=1 "ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=$i"]) ++done ++AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=1 | grep -F "src=10.1.1.1," | sort ], [0], [dnl ++udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=2,dport=1),reply=(src=10.1.1.2,dst=10.1.1.1,sport=1,dport=2),zone=1 ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ ++AT_BANNER([IGMP]) ++ AT_BANNER([802.1ad]) AT_SETUP([802.1ad - vlan_limit]) -@@ -6768,7 +7394,7 @@ dnl CVLAN traffic should match the flow and drop +@@ -6768,7 +7477,7 @@ dnl CVLAN traffic should match the flow and drop AT_CHECK([ovs-appctl revalidator/purge]) AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:vlan-limit=1]) AT_CHECK([ovs-ofctl add-flow br0 "priority=100 dl_type=0x8100 action=drop"]) @@ -121225,7 +122594,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -6818,11 +7444,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) +@@ -6818,11 +7527,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) @@ -121239,7 +122608,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -6874,11 +7500,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) +@@ -6874,11 +7583,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) @@ -121253,7 +122622,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -6926,24 +7552,24 @@ AT_CHECK([ovs-vsctl set port ovs-p2 vlan_mode=dot1q-tunnel tag=4094 cvlans=100,2 +@@ -6926,24 +7635,24 @@ AT_CHECK([ovs-vsctl set port ovs-p2 vlan_mode=dot1q-tunnel tag=4094 cvlans=100,2 OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.3.2.2]) @@ -121283,7 +122652,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP(["/dropping VLAN \(0\|300\) packet received on dot1q-tunnel port/d"]) AT_CLEANUP -@@ -6972,11 +7598,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) +@@ -6972,11 +7681,11 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) @@ -121297,7 +122666,7 @@ index f22d86e466..099e972812 100644 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -@@ -6998,7 +7624,7 @@ dnl The flow will encap a nsh header to the TCP syn packet +@@ -6998,7 +7707,7 @@ dnl The flow will encap a nsh header to the TCP syn packet dnl eth/ip/tcp --> OVS --> eth/nsh/eth/ip/tcp AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,ip,actions=encap(nsh(md_type=1)),set_field:0x1234->nsh_spi,set_field:0x11223344->nsh_c1,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"]) @@ -121306,7 +122675,7 @@ index f22d86e466..099e972812 100644 sleep 1 dnl The hex dump is a TCP syn packet. pkt=eth/ip/tcp -@@ -7007,12 +7633,12 @@ dnl p1(at_ns1) interface +@@ -7007,12 +7716,12 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected nsh encapsulated packet on the egress interface @@ -121325,7 +122694,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7030,7 +7656,7 @@ dnl The flow will decap a nsh header which in turn carries a TCP syn packet +@@ -7030,7 +7739,7 @@ dnl The flow will decap a nsh header which in turn carries a TCP syn packet dnl eth/nsh/eth/ip/tcp --> OVS --> eth/ip/tcp AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f, actions=decap(),decap(), ovs-p1"]) @@ -121334,7 +122703,7 @@ index f22d86e466..099e972812 100644 sleep 1 dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp -@@ -7039,10 +7665,10 @@ dnl p1(at_ns1) interface +@@ -7039,10 +7748,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected de-capsulated TCP packet on the egress interface @@ -121349,7 +122718,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7062,7 +7688,7 @@ dnl The flow will add another NSH header with nsh_spi=0x101, nsh_si=4, +@@ -7062,7 +7771,7 @@ dnl The flow will add another NSH header with nsh_spi=0x101, nsh_si=4, dnl nsh_ttl=7 and change the md1 context AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x03,actions=decap(),decap(),encap(nsh(md_type=1)),set_field:0x07->nsh_ttl,set_field:0x0101->nsh_spi,set_field:0x04->nsh_si,set_field:0x100f0e0d->nsh_c1,set_field:0x0c0b0a09->nsh_c2,set_field:0x08070605->nsh_c3,set_field:0x04030201->nsh_c4,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"]) @@ -121358,7 +122727,7 @@ index f22d86e466..099e972812 100644 sleep 1 dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp -@@ -7072,12 +7698,12 @@ dnl p1(at_ns1) interface +@@ -7072,12 +7781,12 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected NSH packet with new fields in the header @@ -121377,7 +122746,7 @@ index f22d86e466..099e972812 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7098,31 +7724,31 @@ dnl packet to to at_ns2. +@@ -7098,31 +7807,31 @@ dnl packet to to at_ns2. AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x02,actions=ovs-p1"]) AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x01,actions=ovs-p2"]) @@ -123587,7 +124956,7 @@ index 57589758f4..0771c4453a 100644 +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/tunnel.at b/tests/tunnel.at -index b8ae7caa9b..1be899fff3 100644 +index b8ae7caa9b..b3f8c3417b 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at @@ -126,7 +126,7 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl @@ -123666,6 +125035,34 @@ index b8ae7caa9b..1be899fff3 100644 ]) dnl change the flow table to bump the internal table version +@@ -1205,3 +1250,15 @@ Datapath actions: push_eth(src=00:00:00:00:00:00,dst=00:00:00:00:00:00),1 + + OVS_VSWITCHD_STOP + AT_CLEANUP ++ ++AT_SETUP([tunnel - re-create port with different name]) ++OVS_VSWITCHD_START( ++ [add-port br0 p0 -- set int p0 type=vxlan options:remote_ip=10.10.10.1]) ++ ++AT_CHECK([ovs-vsctl --if-exists del-port p0 -- \ ++ add-port br0 p1 -- \ ++ set int p1 type=vxlan options:remote_ip=10.10.10.1]) ++ ++OVS_APP_EXIT_AND_WAIT([ovs-vswitchd]) ++OVS_APP_EXIT_AND_WAIT([ovsdb-server])] ++AT_CLEANUP +diff --git a/tests/vlog.at b/tests/vlog.at +index 3e92e70a93..595d7e9cee 100644 +--- a/tests/vlog.at ++++ b/tests/vlog.at +@@ -8,6 +8,7 @@ AT_CHECK([$PYTHON3 $srcdir/test-vlog.py --log-file log_file \ + + AT_CHECK([sed -e 's/.*-.*-.*T..:..:..Z |//' \ + -e 's/File ".*", line [[0-9]][[0-9]]*,/File , line ,/' \ ++-e '/\^\+/d' \ + stderr_log], [0], [dnl + 0 | module_0 | EMER | emergency + 1 | module_0 | ERR | error diff --git a/utilities/bugtool/ovs-bugtool.in b/utilities/bugtool/ovs-bugtool.in index fa62cbe949..fee0de8532 100755 --- a/utilities/bugtool/ovs-bugtool.in @@ -124598,3 +125995,16 @@ index 4d21c6364f..ae22f2f5c4 100644 /usr/share/man/man5/ovsdb-server.5.gz /usr/share/man/man5/ovs-vswitchd.conf.db.5.gz /usr/share/man/man5/vtep.5.gz +diff --git a/xenserver/opt_xensource_libexec_interface-reconfigure b/xenserver/opt_xensource_libexec_interface-reconfigure +index 9c20725de2..49d208296e 100755 +--- a/xenserver/opt_xensource_libexec_interface-reconfigure ++++ b/xenserver/opt_xensource_libexec_interface-reconfigure +@@ -95,7 +95,7 @@ def check_allowed(pif): + macline = filter(lambda x: x.startswith("HWaddr:"), f.readlines()) + f.close() + if len(macline) == 1: +- p = re.compile(".*\s%(MAC)s\s.*" % pifrec, re.IGNORECASE) ++ p = re.compile(r".*\s%(MAC)s\s.*" % pifrec, re.IGNORECASE) + if p.match(macline[0]): + log("Skipping PVS device %(device)s (%(MAC)s)" % pifrec) + return False diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec index 4011168..9dbcb4e 100644 --- a/SPECS/openvswitch2.17.spec +++ b/SPECS/openvswitch2.17.spec @@ -63,7 +63,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.17.0 -Release: 154%{?dist} +Release: 163%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -749,6 +749,73 @@ exit 0 %endif %changelog +* Thu Apr 11 2024 Open vSwitch CI - 2.17.0-163 +- Merging upstream branch-2.17 [RH git: 8ddde31ed4] + Commit list: + 1fe98e41f0 github: Update python to 3.12. + ae67980c00 ovsdb-dot: Fix flake8 issues. + 143fdbaeb5 ovsdb-doc: Fix syntax warning with Python 3.12 and flake8 issues. + + +* Wed Apr 10 2024 Open vSwitch CI - 2.17.0-162 +- Merging upstream branch-2.17 [RH git: 2c32df368d] + Commit list: + e4d61152f8 python: Remove hacking dependency and use recent flake8. + 69687ac1b2 cirrus: Update to FreeBSD 13.3. + 10588fed09 xenserver: Fix tests with Python 3.12. + + +* Tue Apr 09 2024 Open vSwitch CI - 2.17.0-161 +- Merging upstream branch-2.17 [RH git: 82677811bd] + Commit list: + fc2b1ad3d4 tests: Fix compatibility issue with Python 3.13 in vlog.at. + + +* Fri Apr 05 2024 Open vSwitch CI - 2.17.0-160 +- Merging upstream branch-2.17 [RH git: dc58c42229] + Commit list: + 74875da782 ofproto-dpif-upcall: Fix ukey installation failure logs and counters. + + +* Wed Apr 03 2024 Open vSwitch CI - 2.17.0-159 +- Merging upstream branch-2.17 [RH git: 36ad511ce1] + Commit list: + 915d3c1ae5 conntrack: Do not use icmp reverse helper for icmpv6. + 13678cfab7 conntrack: Fix SNAT with exhaustion system test. + + +* Wed Mar 27 2024 Open vSwitch CI - 2.17.0-158 +- Merging upstream branch-2.17 [RH git: 8a1e4c7d37] + Commit list: + 1d740ed1b8 ovsdb: raft: Fix inability to join after leadership change round trip. + 7065ac8e10 ovsdb: raft: Fix permanent joining state on a cluster member. + 1aa302fb5e ovsdb: raft: Avoid transferring leadership to unavailable servers. + + +* Wed Mar 27 2024 Open vSwitch CI - 2.17.0-157 +- Merging upstream branch-2.17 [RH git: a58875a08f] + Commit list: + 30ea1ecc3e ofproto-dpif-xlate: Fix continuations with associated metering. + + +* Fri Mar 22 2024 Open vSwitch CI - 2.17.0-156 +- Merging upstream branch-2.17 [RH git: 23f3cdb128] + Commit list: + c0f0426195 ovs-monitor-ipsec: LibreSwan autodetect paths. (#1975039) + f913a4c78b route-table: Avoid routes from non-standard routing tables. + + +* Tue Mar 19 2024 Open vSwitch CI - 2.17.0-155 +- Merging upstream branch-2.17 [RH git: cda1401fbf] + Commit list: + 2c1b9e9cee ofproto-dpif: Fix tunnel with different name del/add failure. + 019e545ba8 ofpbuf: Prevent undefined behavior in ofpbuf_clone. + 1a5f056303 github: Reduce ASLR entropy to be compatible with asan in llvm 14. + adcb870d1a bfd: Improve state change log message. (#2258496) + f9602296a9 tests: Fix "SSL db: Implementation" test with openssl > 3.2.0. + ee8485227f conntrack: Fix flush not flushing all elements. + + * Tue Mar 12 2024 Open vSwitch CI - 2.17.0-154 - Merging dpdk subtree [RH git: e5c83b7dbf] Commit list: