diff --git a/SOURCES/openvswitch-2.11.3.patch b/SOURCES/openvswitch-2.11.3.patch index a927c4a..d637ff7 100644 --- a/SOURCES/openvswitch-2.11.3.patch +++ b/SOURCES/openvswitch-2.11.3.patch @@ -127,7 +127,7 @@ index 33f20277be..e8b3440943 100644 -__ security@ovs.org +__ security@openvswitch.org diff --git a/Documentation/intro/install/dpdk.rst b/Documentation/intro/install/dpdk.rst -index 6e5f1ea60a..510923dcc8 100644 +index 6e5f1ea60a..f0a7bffce9 100644 --- a/Documentation/intro/install/dpdk.rst +++ b/Documentation/intro/install/dpdk.rst @@ -42,7 +42,7 @@ Build requirements @@ -152,6 +152,22 @@ index 6e5f1ea60a..510923dcc8 100644 $ cd $DPDK_DIR #. (Optional) Configure DPDK as a shared library +@@ -687,6 +687,15 @@ Limitations + around is temporary and is expected to be removed once a method is provided + by DPDK to query the upper bound MTU value for a given device. + ++- Flow Control: When using i40e devices (Intel(R) 700 Series) it is recommended ++ to set Link State Change detection to interrupt mode. Otherwise it has been ++ observed that using the default polling mode, flow control changes may not be ++ applied, and flow control states will not be reflected correctly. ++ The issue is under investigation, this is a temporary work around. ++ ++ For information about setting Link State Change detection, refer to ++ :ref:`lsc-detection`. ++ + Reporting Bugs + -------------- + diff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst index a3ed926ca9..2fae9188a4 100644 --- a/Documentation/topics/dpdk/bridge.rst @@ -169,6 +185,19 @@ index a3ed926ca9..2fae9188a4 100644 EMC Insertion Probability ------------------------- +diff --git a/Documentation/topics/dpdk/phy.rst b/Documentation/topics/dpdk/phy.rst +index 93d74df452..9bf6e3112a 100644 +--- a/Documentation/topics/dpdk/phy.rst ++++ b/Documentation/topics/dpdk/phy.rst +@@ -364,6 +364,8 @@ Jumbo Frames + DPDK physical ports can be configured to use Jumbo Frames. For more + information, refer to :doc:`jumbo-frames`. + ++.. _lsc-detection: ++ + Link State Change (LSC) detection configuration + ----------------------------------------------- + diff --git a/Documentation/topics/dpdk/vhost-user.rst b/Documentation/topics/dpdk/vhost-user.rst index 33361ec359..3bd2dc608a 100644 --- a/Documentation/topics/dpdk/vhost-user.rst @@ -270,12 +299,16 @@ index 33361ec359..3bd2dc608a 100644 ------------------------------------------- diff --git a/NEWS b/NEWS -index f177d7efc1..87f24b52c2 100644 +index f177d7efc1..b0d3022eb6 100644 --- a/NEWS +++ b/NEWS -@@ -1,3 +1,16 @@ +@@ -1,3 +1,20 @@ +v2.11.5 - xx xxx xxxx +--------------------- ++ - OVSDB: ++ * Fixed SHA-1 hash computation for databases larger than 512 MB. ++ - DPDK: ++ * Fixed support of 'net_virtio' devices. + +v2.11.4 - 30 Jul 2020 +--------------------- @@ -291,7 +324,7 @@ index f177d7efc1..87f24b52c2 100644 --------------------- - Fix compilation issue with Ubuntu kernel 4.15.60. diff --git a/acinclude.m4 b/acinclude.m4 -index f15b1ff670..78d3f2779e 100644 +index f15b1ff670..71813077c6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -172,16 +172,30 @@ AC_DEFUN([OVS_CHECK_LINUX], [ @@ -339,7 +372,16 @@ index f15b1ff670..78d3f2779e 100644 OVS_GREP_IFELSE([$KSRC/include/net/rtnetlink.h], [get_link_net]) OVS_GREP_IFELSE([$KSRC/include/net/rtnetlink.h], [name_assign_type]) -@@ -967,6 +985,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ +@@ -834,8 +852,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ + + OVS_GREP_IFELSE([$KSRC/include/net/sock.h], [sk_no_check_tx]) + OVS_GREP_IFELSE([$KSRC/include/linux/udp.h], [no_check6_tx]) +- OVS_GREP_IFELSE([$KSRC/include/linux/utsrelease.h], [el6], +- [OVS_DEFINE([HAVE_RHEL6_PER_CPU])]) + OVS_FIND_PARAM_IFELSE([$KSRC/include/net/protocol.h], + [udp_add_offload], [net], + [OVS_DEFINE([HAVE_UDP_ADD_OFFLOAD_TAKES_NET])]) +@@ -967,6 +983,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ [OVS_DEFINE([HAVE_NF_CONNTRACK_IN_TAKES_NF_HOOK_STATE])]) OVS_GREP_IFELSE([$KSRC/include/net/ipv6_frag.h], [IP6_DEFRAG_CONNTRACK_IN], [OVS_DEFINE([HAVE_IPV6_FRAG_H])]) @@ -625,6 +667,36 @@ index 9b087f1b06..3369c8630d 100644 #endif __OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted * from userspace. */ +diff --git a/datapath/linux/compat/include/linux/percpu.h b/datapath/linux/compat/include/linux/percpu.h +index 7c346aa31a..a039142e22 100644 +--- a/datapath/linux/compat/include/linux/percpu.h ++++ b/datapath/linux/compat/include/linux/percpu.h +@@ -7,12 +7,6 @@ + #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, smp_processor_id()) + #endif + +-#ifdef HAVE_RHEL6_PER_CPU +-#undef this_cpu_read +-#undef this_cpu_inc +-#undef this_cpu_dec +-#endif +- + #if !defined this_cpu_read + #define this_cpu_read(ptr) percpu_read(ptr) + #endif +diff --git a/datapath/linux/compat/include/linux/skbuff.h b/datapath/linux/compat/include/linux/skbuff.h +index 4a6ac2384c..9828f811d9 100644 +--- a/datapath/linux/compat/include/linux/skbuff.h ++++ b/datapath/linux/compat/include/linux/skbuff.h +@@ -278,7 +278,7 @@ static inline void skb_clear_hash(struct sk_buff *skb) + #ifdef HAVE_RXHASH + skb->rxhash = 0; + #endif +-#if defined(HAVE_L4_RXHASH) && !defined(HAVE_RHEL_OVS_HOOK) ++#if defined(HAVE_L4_RXHASH) + skb->l4_rxhash = 0; + #endif + } diff --git a/datapath/linux/compat/ip6_gre.c b/datapath/linux/compat/ip6_gre.c index 2ffdda5e1d..aa6cf3e7fc 100644 --- a/datapath/linux/compat/ip6_gre.c @@ -667,6 +739,25 @@ index d16e60fbfe..f1c8ba7cdc 100644 if (skb->protocol == htons(ETH_P_IP)) { if (!skb_is_gso(skb) && +diff --git a/datapath/linux/compat/nf_conntrack_reasm.c b/datapath/linux/compat/nf_conntrack_reasm.c +index 9d77d98271..715388d838 100644 +--- a/datapath/linux/compat/nf_conntrack_reasm.c ++++ b/datapath/linux/compat/nf_conntrack_reasm.c +@@ -56,10 +56,13 @@ + #include + #include "datapath.h" + +-#ifdef OVS_NF_DEFRAG6_BACKPORT ++#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || !defined(HAVE_INET_FRAGS_RND) + + static const char nf_frags_cache_name[] = "ovs-frag6"; + ++#endif ++ ++#ifdef OVS_NF_DEFRAG6_BACKPORT + struct nf_ct_frag6_skb_cb + { + struct inet6_skb_parm h; diff --git a/debian/changelog b/debian/changelog index d08cfbfd91..851cca9cb6 100644 --- a/debian/changelog @@ -15125,6 +15216,167 @@ index 4c2c1ba84a..c366cf53eb 100644 struct json_parser *parser; /* Output. */ +diff --git a/lib/lldp/lldp.c b/lib/lldp/lldp.c +index 74f747fcdc..e5755307fb 100644 +--- a/lib/lldp/lldp.c ++++ b/lib/lldp/lldp.c +@@ -59,7 +59,7 @@ VLOG_DEFINE_THIS_MODULE(lldp); + } while (0) + #define PEEK_DISCARD_UINT8 PEEK_DISCARD(1) + #define PEEK_DISCARD_UINT16 PEEK_DISCARD(2) +-#define PEEK_DISCARD_UINT32 PEEK_DISCARD(3) ++#define PEEK_DISCARD_UINT32 PEEK_DISCARD(4) + #define PEEK_CMP(value, bytes) \ + (length -= (bytes), \ + pos += (bytes), \ +@@ -341,6 +341,12 @@ lldp_send(struct lldpd *global OVS_UNUSED, + + return dp_packet_size(p); + } ++#define CHECK_TLV_MAX_SIZE(x, name) \ ++ do { if (tlv_size > (x)) { \ ++ VLOG_WARN(name " TLV too large received on %s", \ ++ hardware->h_ifname); \ ++ goto malformed; \ ++ } } while (0) + + int + lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, +@@ -359,7 +365,7 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + int length, af; + bool gotend = false; + bool ttl_received = false; +- int tlv_size, tlv_type, tlv_subtype; ++ int tlv_size, tlv_type, tlv_subtype, tlv_count = 0; + u_int8_t *pos, *tlv; + void *b; + struct lldpd_aa_isid_vlan_maps_tlv *isid_vlan_map = NULL; +@@ -411,6 +417,31 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + hardware->h_ifname); + goto malformed; + } ++ /* Check order for mandatory TLVs */ ++ tlv_count++; ++ switch (tlv_type) { ++ case LLDP_TLV_CHASSIS_ID: ++ if (tlv_count != 1) { ++ VLOG_WARN("first TLV should be a chassis ID on %s, not %d", ++ hardware->h_ifname, tlv_type); ++ goto malformed; ++ } ++ break; ++ case LLDP_TLV_PORT_ID: ++ if (tlv_count != 2) { ++ VLOG_WARN("second TLV should be a port ID on %s, not %d", ++ hardware->h_ifname, tlv_type); ++ goto malformed; ++ } ++ break; ++ case LLDP_TLV_TTL: ++ if (tlv_count != 3) { ++ VLOG_WARN("third TLV should be a TTL on %s, not %d", ++ hardware->h_ifname, tlv_type); ++ goto malformed; ++ } ++ break; ++ } + + switch (tlv_type) { + case LLDP_TLV_END: +@@ -428,7 +459,8 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + + case LLDP_TLV_CHASSIS_ID: + case LLDP_TLV_PORT_ID: +- CHECK_TLV_SIZE(2, "Port Id"); ++ CHECK_TLV_SIZE(2, "Port/Chassis Id"); ++ CHECK_TLV_MAX_SIZE(256, "Port/Chassis Id"); + tlv_subtype = PEEK_UINT8; + if (tlv_subtype == 0 || tlv_subtype > 7) { + VLOG_WARN("unknown subtype for tlv id received on %s", +@@ -438,10 +470,22 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + b = xzalloc(tlv_size - 1); + PEEK_BYTES(b, tlv_size - 1); + if (tlv_type == LLDP_TLV_PORT_ID) { ++ if (port->p_id != NULL) { ++ VLOG_WARN("Port ID TLV received twice on %s", ++ hardware->h_ifname); ++ free(b); ++ goto malformed; ++ } + port->p_id_subtype = tlv_subtype; + port->p_id = b; + port->p_id_len = tlv_size - 1; + } else { ++ if (chassis->c_id != NULL) { ++ VLOG_WARN("Chassis ID TLV received twice on %s", ++ hardware->h_ifname); ++ free(b); ++ goto malformed; ++ } + chassis->c_id_subtype = tlv_subtype; + chassis->c_id = b; + chassis->c_id_len = tlv_size - 1; +@@ -449,6 +493,11 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + break; + + case LLDP_TLV_TTL: ++ if (ttl_received) { ++ VLOG_WARN("TTL TLV received twice on %s", ++ hardware->h_ifname); ++ goto malformed; ++ } + CHECK_TLV_SIZE(2, "TTL"); + chassis->c_ttl = PEEK_UINT16; + ttl_received = true; +@@ -481,6 +530,11 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + case LLDP_TLV_MGMT_ADDR: + CHECK_TLV_SIZE(1, "Management address"); + addr_str_length = PEEK_UINT8; ++ if (addr_str_length > sizeof(addr_str_buffer)) { ++ VLOG_WARN("too large management address on %s", ++ hardware->h_ifname); ++ goto malformed; ++ } + CHECK_TLV_SIZE(1 + addr_str_length, "Management address"); + PEEK_BYTES(addr_str_buffer, addr_str_length); + addr_length = addr_str_length - 1; +@@ -505,7 +559,7 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + break; + + case LLDP_TLV_ORG: +- CHECK_TLV_SIZE(4, "Organisational"); ++ CHECK_TLV_SIZE(1 + sizeof orgid, "Organisational"); + PEEK_BYTES(orgid, sizeof orgid); + tlv_subtype = PEEK_UINT8; + if (memcmp(dot1, orgid, sizeof orgid) == 0) { +@@ -625,6 +679,7 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, + VLOG_WARN("unknown tlv (%d) received on %s", + tlv_type, + hardware->h_ifname); ++ hardware->h_rx_unrecognized_cnt++; + goto malformed; + } + if (pos > tlv + tlv_size) { +diff --git a/lib/lldp/lldpd.c b/lib/lldp/lldpd.c +index 19e9305266..34738535db 100644 +--- a/lib/lldp/lldpd.c ++++ b/lib/lldp/lldpd.c +@@ -244,6 +244,7 @@ lldpd_decode(struct lldpd *cfg, char *frame, int s, + + if (s < sizeof(struct eth_header) + 4) { + /* Too short, just discard it */ ++ hw->h_rx_discarded_cnt++; + return; + } + +@@ -284,6 +285,7 @@ lldpd_decode(struct lldpd *cfg, char *frame, int s, + VLOG_DBG("function for %s protocol did not " + "decode this frame", + cfg->g_protocols[i].name); ++ hw->h_rx_discarded_cnt++; + return; + } + chassis->c_protocol = port->p_protocol = cfg->g_protocols[i].mode; diff --git a/lib/meta-flow.c b/lib/meta-flow.c index bc48d63049..a131adc918 100644 --- a/lib/meta-flow.c @@ -15201,7 +15453,7 @@ index 0b5c1d0087..e1b32d6ab4 100644 diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c -index 20be56bc6c..0021867e92 100644 +index 20be56bc6c..a3283d3698 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -41,11 +41,13 @@ @@ -15263,7 +15515,7 @@ index 20be56bc6c..0021867e92 100644 #define SOCKET0 0 /* Default size of Physical NIC RXQ */ -@@ -157,7 +134,13 @@ BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF / MIN_NB_MBUF)) +@@ -157,12 +134,17 @@ BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF / MIN_NB_MBUF)) typedef uint16_t dpdk_port_t; #define DPDK_PORT_ID_FMT "%"PRIu16 @@ -15278,7 +15530,12 @@ index 20be56bc6c..0021867e92 100644 #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ) static const struct rte_eth_conf port_conf = { -@@ -195,12 +178,28 @@ struct ufid_to_rte_flow_data { + .rxmode = { +- .mq_mode = ETH_MQ_RX_RSS, + .split_hdr_size = 0, + .offloads = 0, + }, +@@ -195,12 +177,28 @@ struct ufid_to_rte_flow_data { static int new_device(int vid); static void destroy_device(int vid); static int vring_state_changed(int vid, uint16_t queue_id, int enable); @@ -15308,7 +15565,7 @@ index 20be56bc6c..0021867e92 100644 }; enum { DPDK_RING_SIZE = 256 }; -@@ -391,6 +390,8 @@ struct netdev_dpdk { +@@ -391,6 +389,8 @@ struct netdev_dpdk { bool attached; /* If true, rte_eth_dev_start() was successfully called */ bool started; @@ -15317,7 +15574,7 @@ index 20be56bc6c..0021867e92 100644 struct eth_addr hwaddr; int mtu; int socket_id; -@@ -413,7 +414,9 @@ struct netdev_dpdk { +@@ -413,7 +413,9 @@ struct netdev_dpdk { /* True if vHost device is 'up' and has been reconfigured at least once */ bool vhost_reconfigured; @@ -15328,7 +15585,7 @@ index 20be56bc6c..0021867e92 100644 ); PADDED_MEMBERS(CACHE_LINE_SIZE, -@@ -437,9 +440,10 @@ struct netdev_dpdk { +@@ -437,9 +439,10 @@ struct netdev_dpdk { PADDED_MEMBERS(CACHE_LINE_SIZE, struct netdev_stats stats; @@ -15340,7 +15597,7 @@ index 20be56bc6c..0021867e92 100644 ); PADDED_MEMBERS(CACHE_LINE_SIZE, -@@ -493,6 +497,8 @@ struct netdev_rxq_dpdk { +@@ -493,6 +496,8 @@ struct netdev_rxq_dpdk { static void netdev_dpdk_destruct(struct netdev *netdev); static void netdev_dpdk_vhost_destruct(struct netdev *netdev); @@ -15349,7 +15606,22 @@ index 20be56bc6c..0021867e92 100644 static void netdev_dpdk_clear_xstats(struct netdev_dpdk *dev); int netdev_dpdk_get_vid(const struct netdev_dpdk *dev); -@@ -1162,6 +1168,8 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, +@@ -915,6 +920,14 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) + + rte_eth_dev_info_get(dev->port_id, &info); + ++ /* As of DPDK 18.11.6, it is not allowed to set a mq_mode for ++ * virtio PMD driver. */ ++ if (!strcmp(info.driver_name, "net_virtio")) { ++ conf.rxmode.mq_mode = ETH_MQ_RX_NONE; ++ } else { ++ conf.rxmode.mq_mode = ETH_MQ_RX_RSS; ++ } ++ + /* As of DPDK 17.11.1 a few PMDs require to explicitly enable + * scatter to support jumbo RX. + * Setting scatter for the device is done after checking for +@@ -1162,6 +1175,8 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, ovsrcu_index_init(&dev->vid, -1); dev->vhost_reconfigured = false; dev->attached = false; @@ -15358,7 +15630,7 @@ index 20be56bc6c..0021867e92 100644 ovsrcu_init(&dev->qos_conf, NULL); -@@ -1194,6 +1202,9 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, +@@ -1194,6 +1209,9 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, dev->rte_xstats_ids = NULL; dev->rte_xstats_ids_size = 0; @@ -15368,7 +15640,7 @@ index 20be56bc6c..0021867e92 100644 return 0; } -@@ -1250,6 +1261,8 @@ vhost_common_construct(struct netdev *netdev) +@@ -1250,6 +1268,8 @@ vhost_common_construct(struct netdev *netdev) return ENOMEM; } @@ -15377,7 +15649,7 @@ index 20be56bc6c..0021867e92 100644 return common_construct(netdev, DPDK_ETH_PORT_ID_INVALID, DPDK_DEV_VHOST, socket_id); } -@@ -1366,6 +1379,7 @@ common_destruct(struct netdev_dpdk *dev) +@@ -1366,6 +1386,7 @@ common_destruct(struct netdev_dpdk *dev) ovs_list_remove(&dev->list_node); free(ovsrcu_get_protected(struct ingress_policer *, &dev->ingress_policer)); @@ -15385,7 +15657,7 @@ index 20be56bc6c..0021867e92 100644 ovs_mutex_destroy(&dev->mutex); } -@@ -1739,6 +1753,34 @@ netdev_dpdk_process_devargs(struct netdev_dpdk *dev, +@@ -1739,6 +1760,34 @@ netdev_dpdk_process_devargs(struct netdev_dpdk *dev, return new_port_id; } @@ -15420,7 +15692,7 @@ index 20be56bc6c..0021867e92 100644 static void dpdk_set_rxq_config(struct netdev_dpdk *dev, const struct smap *args) OVS_REQUIRES(dev->mutex) -@@ -1775,6 +1817,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, +@@ -1775,6 +1824,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); bool rx_fc_en, tx_fc_en, autoneg, lsc_interrupt_mode; @@ -15428,7 +15700,7 @@ index 20be56bc6c..0021867e92 100644 enum rte_eth_fc_mode fc_mode; static const enum rte_eth_fc_mode fc_mode_set[2][2] = { {RTE_FC_NONE, RTE_FC_TX_PAUSE}, -@@ -1797,7 +1840,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, +@@ -1797,7 +1847,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, new_devargs = smap_get(args, "dpdk-devargs"); @@ -15437,7 +15709,7 @@ index 20be56bc6c..0021867e92 100644 /* The user requested a new device. If we return error, the caller * will delete this netdev and try to recreate it. */ err = EAGAIN; -@@ -1862,15 +1905,34 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, +@@ -1862,15 +1912,34 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, autoneg = smap_get_bool(args, "flow-ctrl-autoneg", false); fc_mode = fc_mode_set[tx_fc_en][rx_fc_en]; @@ -15478,7 +15750,7 @@ index 20be56bc6c..0021867e92 100644 dpdk_eth_flow_ctrl_setup(dev); } -@@ -1901,6 +1963,7 @@ netdev_dpdk_vhost_client_set_config(struct netdev *netdev, +@@ -1901,6 +1970,7 @@ netdev_dpdk_vhost_client_set_config(struct netdev *netdev, { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); const char *path; @@ -15486,7 +15758,7 @@ index 20be56bc6c..0021867e92 100644 ovs_mutex_lock(&dev->mutex); if (!(dev->vhost_driver_flags & RTE_VHOST_USER_CLIENT)) { -@@ -1916,6 +1979,19 @@ netdev_dpdk_vhost_client_set_config(struct netdev *netdev, +@@ -1916,6 +1986,19 @@ netdev_dpdk_vhost_client_set_config(struct netdev *netdev, netdev_request_reconfigure(netdev); } } @@ -15506,7 +15778,7 @@ index 20be56bc6c..0021867e92 100644 ovs_mutex_unlock(&dev->mutex); return 0; -@@ -2115,16 +2191,17 @@ netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats, +@@ -2115,16 +2198,17 @@ netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats, } static inline void @@ -15529,7 +15801,7 @@ index 20be56bc6c..0021867e92 100644 for (i = 0; i < count; i++) { packet = packets[i]; packet_size = dp_packet_size(packet); -@@ -2147,6 +2224,10 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, +@@ -2147,6 +2231,10 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, stats->rx_bytes += packet_size; } @@ -15540,7 +15812,7 @@ index 20be56bc6c..0021867e92 100644 } /* -@@ -2159,7 +2240,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, +@@ -2159,7 +2247,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev); struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev); uint16_t nb_rx = 0; @@ -15549,7 +15821,7 @@ index 20be56bc6c..0021867e92 100644 int qid = rxq->queue_id * VIRTIO_QNUM + VIRTIO_TXQ; int vid = netdev_dpdk_get_vid(dev); -@@ -2186,16 +2267,16 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, +@@ -2186,16 +2274,16 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, } if (policer) { @@ -15570,7 +15842,7 @@ index 20be56bc6c..0021867e92 100644 rte_spinlock_unlock(&dev->stats_lock); batch->count = nb_rx; -@@ -2237,6 +2318,7 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, +@@ -2237,6 +2325,7 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, if (OVS_UNLIKELY(dropped)) { rte_spinlock_lock(&dev->stats_lock); dev->stats.rx_dropped += dropped; @@ -15578,7 +15850,7 @@ index 20be56bc6c..0021867e92 100644 rte_spinlock_unlock(&dev->stats_lock); } -@@ -2296,13 +2378,17 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, +@@ -2296,13 +2385,17 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, } static inline void @@ -15599,7 +15871,7 @@ index 20be56bc6c..0021867e92 100644 stats->tx_packets += sent; stats->tx_dropped += dropped; -@@ -2310,6 +2396,15 @@ netdev_dpdk_vhost_update_tx_counters(struct netdev_stats *stats, +@@ -2310,6 +2403,15 @@ netdev_dpdk_vhost_update_tx_counters(struct netdev_stats *stats, for (i = 0; i < sent; i++) { stats->tx_bytes += dp_packet_size(packets[i]); } @@ -15615,7 +15887,7 @@ index 20be56bc6c..0021867e92 100644 } static void -@@ -2318,9 +2413,11 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, +@@ -2318,9 +2420,11 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts; @@ -15629,7 +15901,7 @@ index 20be56bc6c..0021867e92 100644 int vid = netdev_dpdk_get_vid(dev); qid = dev->tx_q[qid % netdev->n_txq].map; -@@ -2333,12 +2430,20 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, +@@ -2333,12 +2437,20 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, goto out; } @@ -15652,7 +15924,7 @@ index 20be56bc6c..0021867e92 100644 do { int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ; -@@ -2350,21 +2455,31 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, +@@ -2350,21 +2462,31 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, cnt -= tx_pkts; /* Prepare for possible retry.*/ cur_pkts = &cur_pkts[tx_pkts]; @@ -15688,7 +15960,7 @@ index 20be56bc6c..0021867e92 100644 dp_packet_delete(pkts[i]); } } -@@ -2383,14 +2498,18 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) +@@ -2383,14 +2505,18 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) #endif struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_mbuf *pkts[PKT_ARRAY_SIZE]; @@ -15708,7 +15980,7 @@ index 20be56bc6c..0021867e92 100644 } uint32_t txcnt = 0; -@@ -2403,13 +2522,13 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) +@@ -2403,13 +2529,13 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) VLOG_WARN_RL(&rl, "Too big size %u max_packet_len %d", size, dev->max_packet_len); @@ -15724,7 +15996,7 @@ index 20be56bc6c..0021867e92 100644 break; } -@@ -2426,13 +2545,17 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) +@@ -2426,13 +2552,17 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) __netdev_dpdk_vhost_send(netdev, qid, (struct dp_packet **) pkts, txcnt); } else { @@ -15743,7 +16015,7 @@ index 20be56bc6c..0021867e92 100644 rte_spinlock_unlock(&dev->stats_lock); } } -@@ -2473,19 +2596,27 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, +@@ -2473,19 +2603,27 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, dpdk_do_tx_copy(netdev, qid, batch); dp_packet_delete_batch(batch, true); } else { @@ -15773,7 +16045,7 @@ index 20be56bc6c..0021867e92 100644 rte_spinlock_unlock(&dev->stats_lock); } } -@@ -2620,51 +2751,41 @@ netdev_dpdk_convert_xstats(struct netdev_stats *stats, +@@ -2620,51 +2758,41 @@ netdev_dpdk_convert_xstats(struct netdev_stats *stats, const struct rte_eth_xstat_name *names, const unsigned int size) { @@ -15857,7 +16129,7 @@ index 20be56bc6c..0021867e92 100644 } static int -@@ -2753,7 +2874,9 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, +@@ -2753,7 +2881,9 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, uint32_t i; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); @@ -15868,7 +16140,7 @@ index 20be56bc6c..0021867e92 100644 ovs_mutex_lock(&dev->mutex); -@@ -2768,23 +2891,22 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, +@@ -2768,23 +2898,22 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, if (rte_xstats_ret > 0 && rte_xstats_ret <= dev->rte_xstats_ids_size) { @@ -15899,7 +16171,7 @@ index 20be56bc6c..0021867e92 100644 /* Let's clear statistics cache, so it will be * reconfigured */ netdev_dpdk_clear_xstats(dev); -@@ -2798,6 +2920,55 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, +@@ -2798,6 +2927,55 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, return 0; } @@ -15955,7 +16227,7 @@ index 20be56bc6c..0021867e92 100644 static int netdev_dpdk_get_features(const struct netdev *netdev, enum netdev_features *current, -@@ -3639,6 +3810,12 @@ vring_state_changed(int vid, uint16_t queue_id, int enable) +@@ -3639,6 +3817,12 @@ vring_state_changed(int vid, uint16_t queue_id, int enable) return 0; } @@ -15968,7 +16240,7 @@ index 20be56bc6c..0021867e92 100644 /* * Retrieve the DPDK virtio device ID (vid) associated with a vhostuser * or vhostuserclient netdev. -@@ -3672,6 +3849,8 @@ netdev_dpdk_class_init(void) +@@ -3672,6 +3856,8 @@ netdev_dpdk_class_init(void) /* This function can be called for different classes. The initialization * needs to be done only once */ if (ovsthread_once_start(&once)) { @@ -15977,7 +16249,7 @@ index 20be56bc6c..0021867e92 100644 ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL); unixctl_command_register("netdev-dpdk/set-admin-state", "[netdev] up|down", 1, 2, -@@ -3685,6 +3864,14 @@ netdev_dpdk_class_init(void) +@@ -3685,6 +3871,14 @@ netdev_dpdk_class_init(void) "[netdev]", 0, 1, netdev_dpdk_get_mempool_info, NULL); @@ -15992,7 +16264,7 @@ index 20be56bc6c..0021867e92 100644 ovsthread_once_done(&once); } -@@ -4046,13 +4233,20 @@ netdev_dpdk_reconfigure(struct netdev *netdev) +@@ -4046,13 +4240,20 @@ netdev_dpdk_reconfigure(struct netdev *netdev) && dev->rxq_size == dev->requested_rxq_size && dev->txq_size == dev->requested_txq_size && dev->socket_id == dev->requested_socket_id @@ -16015,7 +16287,7 @@ index 20be56bc6c..0021867e92 100644 dev->started = false; err = netdev_dpdk_mempool_configure(dev); -@@ -4580,8 +4774,18 @@ netdev_dpdk_add_rte_flow_offload(struct netdev *netdev, +@@ -4580,8 +4781,18 @@ netdev_dpdk_add_rte_flow_offload(struct netdev *netdev, struct rte_flow_item_eth eth_mask; memset(ð_spec, 0, sizeof(eth_spec)); memset(ð_mask, 0, sizeof(eth_mask)); @@ -16036,7 +16308,7 @@ index 20be56bc6c..0021867e92 100644 rte_memcpy(ð_spec.dst, &match->flow.dl_dst, sizeof(eth_spec.dst)); rte_memcpy(ð_spec.src, &match->flow.dl_src, sizeof(eth_spec.src)); eth_spec.type = match->flow.dl_type; -@@ -4594,15 +4798,6 @@ netdev_dpdk_add_rte_flow_offload(struct netdev *netdev, +@@ -4594,15 +4805,6 @@ netdev_dpdk_add_rte_flow_offload(struct netdev *netdev, add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, ð_spec, ð_mask); @@ -16052,7 +16324,7 @@ index 20be56bc6c..0021867e92 100644 } /* VLAN */ -@@ -5020,6 +5215,7 @@ static const struct netdev_class dpdk_vhost_class = { +@@ -5020,6 +5222,7 @@ static const struct netdev_class dpdk_vhost_class = { .send = netdev_dpdk_vhost_send, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, @@ -16060,7 +16332,7 @@ index 20be56bc6c..0021867e92 100644 .get_status = netdev_dpdk_vhost_user_get_status, .reconfigure = netdev_dpdk_vhost_reconfigure, .rxq_recv = netdev_dpdk_vhost_rxq_recv -@@ -5034,6 +5230,7 @@ static const struct netdev_class dpdk_vhost_client_class = { +@@ -5034,6 +5237,7 @@ static const struct netdev_class dpdk_vhost_client_class = { .send = netdev_dpdk_vhost_send, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, @@ -16337,6 +16609,34 @@ index d94817fb62..2d2d6f3a60 100644 }; struct dpif_class; struct netdev_flow_dump; +diff --git a/lib/netlink.c b/lib/netlink.c +index de3ebcd0e7..26ab20bb4b 100644 +--- a/lib/netlink.c ++++ b/lib/netlink.c +@@ -498,6 +498,7 @@ void + nl_msg_end_nested(struct ofpbuf *msg, size_t offset) + { + struct nlattr *attr = ofpbuf_at_assert(msg, offset, sizeof *attr); ++ ovs_assert(!nl_attr_oversized(msg->size - offset - NLA_HDRLEN)); + attr->nla_len = msg->size - offset; + } + +diff --git a/lib/nx-match.c b/lib/nx-match.c +index fd3eac0c0e..b6284b2432 100644 +--- a/lib/nx-match.c ++++ b/lib/nx-match.c +@@ -1110,6 +1110,11 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match, + mpls_lse_to_bos(flow->mpls_lse[0])); + } + ++ if (match->wc.masks.mpls_lse[0] & htonl(MPLS_TTL_MASK)) { ++ nxm_put_8(&ctx, MFF_MPLS_TTL, oxm, ++ mpls_lse_to_ttl(flow->mpls_lse[0])); ++ } ++ + if (match->wc.masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK)) { + nxm_put_32(&ctx, MFF_MPLS_LABEL, oxm, + htonl(mpls_lse_to_label(flow->mpls_lse[0]))); diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 3b6890e952..1d33fcbb8d 100644 --- a/lib/odp-execute.c @@ -16526,7 +16826,7 @@ index 3b6890e952..1d33fcbb8d 100644 case OVS_ACTION_ATTR_TUNNEL_PUSH: case OVS_ACTION_ATTR_TUNNEL_POP: diff --git a/lib/odp-util.c b/lib/odp-util.c -index d41c9369f2..9222960f54 100644 +index d41c9369f2..311204fa8a 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -131,6 +131,8 @@ odp_action_len(uint16_t type) @@ -16655,7 +16955,31 @@ index d41c9369f2..9222960f54 100644 return 0; } -@@ -5757,26 +5848,28 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, +@@ -5185,13 +5276,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) + do { \ + len = 0; + +-#define SCAN_END_NESTED() \ +- SCAN_FINISH(); \ +- nl_msg_end_nested(key, key_offset); \ +- if (mask) { \ +- nl_msg_end_nested(mask, mask_offset); \ +- } \ +- return s - start; \ ++#define SCAN_END_NESTED() \ ++ SCAN_FINISH(); \ ++ if (nl_attr_oversized(key->size - key_offset - NLA_HDRLEN)) { \ ++ return -E2BIG; \ ++ } \ ++ nl_msg_end_nested(key, key_offset); \ ++ if (mask) { \ ++ nl_msg_end_nested(mask, mask_offset); \ ++ } \ ++ return s - start; \ + } + + #define SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, ATTR, FUNC) \ +@@ -5757,26 +5851,28 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, if (flow->ct_nw_proto) { if (parms->support.ct_orig_tuple && flow->dl_type == htons(ETH_TYPE_IP)) { @@ -16702,7 +17026,7 @@ index d41c9369f2..9222960f54 100644 } } if (parms->support.recirc) { -@@ -5986,6 +6079,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) +@@ -5986,6 +6082,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority); @@ -16892,6 +17216,27 @@ index 68132c9455..1259c59141 100644 if (ofpact_type_from_name(key, &type)) { error = ofpact_parse(type, value, pp); inst = ovs_instruction_type_from_ofpact_type(type); +diff --git a/lib/ofp-ed-props.c b/lib/ofp-ed-props.c +index 28382e0123..02a9235d51 100644 +--- a/lib/ofp-ed-props.c ++++ b/lib/ofp-ed-props.c +@@ -49,7 +49,7 @@ decode_ed_prop(const struct ofp_ed_prop_header **ofp_prop, + return OFPERR_NXBAC_BAD_ED_PROP; + } + struct ofpact_ed_prop_nsh_md_type *pnmt = +- ofpbuf_put_uninit(out, sizeof(*pnmt)); ++ ofpbuf_put_zeros(out, sizeof *pnmt); + pnmt->header.prop_class = prop_class; + pnmt->header.type = prop_type; + pnmt->header.len = len; +@@ -108,6 +108,7 @@ encode_ed_prop(const struct ofpact_ed_prop **prop, + opnmt->header.len = + offsetof(struct ofp_ed_prop_nsh_md_type, pad); + opnmt->md_type = pnmt->md_type; ++ memset(opnmt->pad, 0, sizeof opnmt->pad); + prop_len = sizeof(*pnmt); + break; + } diff --git a/lib/ofp-packet.c b/lib/ofp-packet.c index aa3417c9b0..4638d8192c 100644 --- a/lib/ofp-packet.c @@ -17079,7 +17424,7 @@ index bfb2b7071b..09b81c6e5a 100644 } } diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c -index 4c9862b88b..ebb5b50f3c 100644 +index 4c9862b88b..7e66d37e9d 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -577,7 +577,6 @@ ovsdb_idl_db_clear(struct ovsdb_idl_db *db) @@ -17098,6 +17443,80 @@ index 4c9862b88b..ebb5b50f3c 100644 db->cond_seqno = 0; ovsdb_idl_db_track_clear(db); +@@ -1771,6 +1769,11 @@ ovsdb_idl_db_track_clear(struct ovsdb_idl_db *db) + free(row->updated); + row->updated = NULL; + } ++ ++ row->change_seqno[OVSDB_IDL_CHANGE_INSERT] = ++ row->change_seqno[OVSDB_IDL_CHANGE_MODIFY] = ++ row->change_seqno[OVSDB_IDL_CHANGE_DELETE] = 0; ++ + ovs_list_remove(&row->track_node); + ovs_list_init(&row->track_node); + if (ovsdb_idl_row_is_orphan(row)) { +@@ -2351,22 +2354,25 @@ ovsdb_idl_process_update2(struct ovsdb_idl_table *table, + return true; + } + +-/* Recursively add rows to tracked change lists for current row +- * and the rows that reference this row. */ ++/* Recursively add rows to tracked change lists for all rows that reference ++ 'row'. */ + static void + add_tracked_change_for_references(struct ovsdb_idl_row *row) + { +- if (ovs_list_is_empty(&row->track_node) && +- ovsdb_idl_track_is_set(row->table)) { +- ovs_list_push_back(&row->table->track_list, +- &row->track_node); +- row->change_seqno[OVSDB_IDL_CHANGE_MODIFY] +- = row->table->change_seqno[OVSDB_IDL_CHANGE_MODIFY] +- = row->table->db->change_seqno + 1; +- +- const struct ovsdb_idl_arc *arc; +- LIST_FOR_EACH (arc, dst_node, &row->dst_arcs) { +- add_tracked_change_for_references(arc->src); ++ const struct ovsdb_idl_arc *arc; ++ LIST_FOR_EACH (arc, dst_node, &row->dst_arcs) { ++ struct ovsdb_idl_row *ref = arc->src; ++ ++ if (ovs_list_is_empty(&ref->track_node) && ++ ovsdb_idl_track_is_set(ref->table)) { ++ ovs_list_push_back(&ref->table->track_list, ++ &ref->track_node); ++ ++ ref->change_seqno[OVSDB_IDL_CHANGE_MODIFY] ++ = ref->table->change_seqno[OVSDB_IDL_CHANGE_MODIFY] ++ = ref->table->db->change_seqno + 1; ++ ++ add_tracked_change_for_references(ref); + } + } + } +@@ -2434,7 +2440,14 @@ ovsdb_idl_row_change__(struct ovsdb_idl_row *row, const struct json *row_json, + row->change_seqno[change] + = row->table->change_seqno[change] + = row->table->db->change_seqno + 1; ++ + if (table->modes[column_idx] & OVSDB_IDL_TRACK) { ++ if (ovs_list_is_empty(&row->track_node) && ++ ovsdb_idl_track_is_set(row->table)) { ++ ovs_list_push_back(&row->table->track_list, ++ &row->track_node); ++ } ++ + add_tracked_change_for_references(row); + if (!row->updated) { + row->updated = bitmap_allocate(class->n_columns); +@@ -4496,6 +4509,7 @@ ovsdb_idl_txn_insert(struct ovsdb_idl_txn *txn, + hmap_insert(&row->table->rows, &row->hmap_node, uuid_hash(&row->uuid)); + hmap_insert(&txn->txn_rows, &row->txn_node, uuid_hash(&row->uuid)); + ovsdb_idl_add_to_indexes(row); ++ + return row; + } + diff --git a/lib/packets.h b/lib/packets.h index 8ae054a742..5e438db9dd 100644 --- a/lib/packets.h @@ -17189,6 +17608,44 @@ index b175b213d1..3d491ee257 100644 cursor.vector = impl->vector; cursor.entry_idx = -1; +diff --git a/lib/sha1.c b/lib/sha1.c +index 4f48ef2102..87360d9cd0 100644 +--- a/lib/sha1.c ++++ b/lib/sha1.c +@@ -197,7 +197,7 @@ sha1_init(struct sha1_ctx *sha_info) + * inputLen: The length of the input buffer. + */ + void +-sha1_update(struct sha1_ctx *ctx, const void *buffer_, size_t count) ++sha1_update(struct sha1_ctx *ctx, const void *buffer_, uint32_t count) + { + const uint8_t *buffer = buffer_; + unsigned int i; +@@ -274,7 +274,7 @@ sha1_final(struct sha1_ctx *ctx, uint8_t digest[SHA1_DIGEST_SIZE]) + + /* Computes the hash of 'n' bytes in 'data' into 'digest'. */ + void +-sha1_bytes(const void *data, size_t n, uint8_t digest[SHA1_DIGEST_SIZE]) ++sha1_bytes(const void *data, uint32_t n, uint8_t digest[SHA1_DIGEST_SIZE]) + { + struct sha1_ctx ctx; + +diff --git a/lib/sha1.h b/lib/sha1.h +index eda265dfc5..a635ff7689 100644 +--- a/lib/sha1.h ++++ b/lib/sha1.h +@@ -45,9 +45,9 @@ struct sha1_ctx { + }; + + void sha1_init(struct sha1_ctx *); +-void sha1_update(struct sha1_ctx *, const void *, size_t); ++void sha1_update(struct sha1_ctx *, const void *, uint32_t size); + void sha1_final(struct sha1_ctx *, uint8_t digest[SHA1_DIGEST_SIZE]); +-void sha1_bytes(const void *, size_t, uint8_t digest[SHA1_DIGEST_SIZE]); ++void sha1_bytes(const void *, uint32_t size, uint8_t digest[SHA1_DIGEST_SIZE]); + + #define SHA1_FMT \ + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index 63b141d1ca..343dced587 100644 --- a/lib/stream-ssl.c @@ -18249,6 +18706,50 @@ index cd20bdb7cb..56edc5f000 100644 m->type.value.type = OVSDB_TYPE_VOID; error = ovsdb_datum_from_json(&m->arg, &m->type, array->elems[2], symtab); +diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in +index 40fef39edf..96a48d8711 100755 +--- a/ovsdb/ovsdb-idlc.in ++++ b/ovsdb/ovsdb-idlc.in +@@ -279,13 +279,21 @@ const struct %(s)s *%(s)s_table_track_get_first(const struct %(s)s_table *); + (ROW) = %(s)s_track_get_next(ROW)) + + +-/* Returns true if 'row' was inserted since the last change tracking reset. */ ++/* Returns true if 'row' was inserted since the last change tracking reset. ++ * ++ * Note: This can only be used to test rows of tracked changes. This cannot be ++ * used to test if an uncommitted row that has been added locally is new or it ++ * may given unexpected results. */ + static inline bool %(s)s_is_new(const struct %(s)s *row) + { +- return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_MODIFY) == 0; ++ return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_INSERT) > 0; + } + +-/* Returns true if 'row' was deleted since the last change tracking reset. */ ++/* Returns true if 'row' was deleted since the last change tracking reset. ++ * ++ * Note: This can only be used to test rows of tracked changes. This cannot be ++ * used to test if an uncommitted row that has been added locally has been ++ * deleted or it may given unexpected results. */ + static inline bool %(s)s_is_deleted(const struct %(s)s *row) + { + return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_DELETE) > 0; +@@ -333,6 +341,14 @@ struct %(s)s *%(s)s_cursor_data(struct ovsdb_idl_cursor *); + void %(s)s_init(struct %(s)s *); + void %(s)s_delete(const struct %(s)s *); + struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *); ++ ++/* Returns true if the tracked column referenced by 'enum %(s)s_column_id' of ++ * the row referenced by 'struct %(s)s *' was updated since the last change ++ * tracking reset. ++ * ++ * Note: This can only be used to test rows of tracked changes. This cannot be ++ * used to test if an uncommitted row that has been added locally has been ++ * updated or it may given unexpected results. */ + bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id); + ''' % {'s': structName, 'S': structName.upper()}) + diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in index 9f78e87f65..11403b1009 100644 --- a/ovsdb/ovsdb-server.1.in @@ -18445,9 +18946,18 @@ index 438f975902..45e656d3d3 100644 } } diff --git a/ovsdb/raft.c b/ovsdb/raft.c -index 68b527c12a..00bf3687f3 100644 +index 68b527c12a..7ba75f6a3f 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c +@@ -3738,7 +3738,7 @@ raft_handle_install_snapshot_request__( + struct ovsdb_error *error = raft_save_snapshot(raft, new_log_start, + &new_snapshot); + if (error) { +- char *error_s = ovsdb_error_to_string(error); ++ char *error_s = ovsdb_error_to_string_free(error); + VLOG_WARN("could not save snapshot: %s", error_s); + free(error_s); + return false; @@ -3960,9 +3960,7 @@ raft_handle_execute_command_request__( cmd->sid = rq->common.sid; @@ -18787,10 +19297,53 @@ index 1f9c32fa74..c45f33e262 100644 char *set_blacklist_tables(const char *blacklist, bool dryrun) OVS_WARN_UNUSED_RESULT; diff --git a/python/ovs/stream.py b/python/ovs/stream.py -index c15be4b3e5..a98057e42a 100644 +index c15be4b3e5..73aa993da3 100644 --- a/python/ovs/stream.py +++ b/python/ovs/stream.py -@@ -825,6 +825,14 @@ class SSLStream(Stream): +@@ -134,6 +134,10 @@ class Stream(object): + IPTOS_PREC_INTERNETCONTROL = 0xc0 + DSCP_DEFAULT = IPTOS_PREC_INTERNETCONTROL >> 2 + ++ @staticmethod ++ def check_connection_completion(sock): ++ return ovs.socket_util.check_connection_completion(sock) ++ + @staticmethod + def open(name, dscp=DSCP_DEFAULT): + """Attempts to connect a stream to a remote peer. 'name' is a +@@ -191,7 +195,7 @@ class Stream(object): + if error: + return error, None + else: +- err = ovs.socket_util.check_connection_completion(sock) ++ err = cls.check_connection_completion(sock) + if err == errno.EAGAIN or err == errno.EINPROGRESS: + status = errno.EAGAIN + err = 0 +@@ -263,7 +267,7 @@ class Stream(object): + + def __scs_connecting(self): + if self.socket is not None: +- retval = ovs.socket_util.check_connection_completion(self.socket) ++ retval = self.check_connection_completion(self.socket) + assert retval != errno.EINPROGRESS + elif sys.platform == 'win32': + if self.retry_connect: +@@ -763,6 +767,13 @@ Stream.register_method("tcp", TCPStream) + + + class SSLStream(Stream): ++ @staticmethod ++ def check_connection_completion(sock): ++ try: ++ return Stream.check_connection_completion(sock) ++ except SSL.SysCallError as e: ++ return ovs.socket_util.get_exception_errno(e) ++ + @staticmethod + def needs_probes(): + return True +@@ -825,6 +836,14 @@ class SSLStream(Stream): except SSL.SysCallError as e: return -ovs.socket_util.get_exception_errno(e) @@ -19171,7 +19724,7 @@ index 86a918e662..a172c49fe1 100644 AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [`cat actions.txt` diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at -index e320a92a8f..0f559d587d 100644 +index e320a92a8f..348117197c 100644 --- a/tests/ofp-actions.at +++ b/tests/ofp-actions.at @@ -310,6 +310,12 @@ ffff 0018 00002320 0025 0000 0005 5000 1122334455 000000 @@ -19187,6 +19740,24 @@ index e320a92a8f..0f559d587d 100644 ]) sed '/^[[#&]]/d' < test-data > input.txt sed -n 's/^# //p; /^$/p' < test-data > expout +@@ -746,6 +752,17 @@ dnl Check the ONF extension form of "copy_field". + # actions=move:NXM_OF_IN_PORT[]->NXM_OF_VLAN_TCI[] + ffff 0020 4f4e4600 0c80 0000 0010 0000 0000 0000 00000002 00000802 00000000 + ++dnl Check NSH encap (experimenter extension). ++# actions=encap(nsh(md_type=1)) ++ffff 0018 00002320 002e 0000 0001894f 0004 01 05 01 000000 ++ ++dnl NSH encap with non-zero padding. ++# actions=encap(nsh(md_type=1)) ++# 21: 12 -> 00 ++# 22: 34 -> 00 ++# 23: 56 -> 00 ++ffff 0018 00002320 002e 0000 0001894f 0004 01 05 01 123456 ++ + ]) + sed '/^[[#&]]/d' < test-data > input.txt + sed -n 's/^# //p; /^$/p' < test-data > expout diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index ded2ef0132..b7cb3cf5f8 100644 --- a/tests/ofproto-dpif.at @@ -19507,6 +20078,71 @@ index 4b14720f32..291330b3b2 100644 +]) + +AT_CLEANUP +diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at +index 6ae3470425..82c89686f0 100644 +--- a/tests/ovs-ofctl.at ++++ b/tests/ovs-ofctl.at +@@ -101,6 +101,7 @@ for test_case in \ + 'mpls,mpls_label=5 NXM,OXM,OpenFlow11' \ + 'mpls,mpls_tc=1 NXM,OXM,OpenFlow11' \ + 'mpls,mpls_bos=0 NXM,OXM' \ ++ 'mpls,mpls_ttl=5 NXM,OXM' \ + 'ip,ip_src=1.2.3.4 any' \ + 'ip,ip_src=192.168.0.0/24 any' \ + 'ip,ip_src=192.0.168.0/255.0.255.0 NXM,OXM,OpenFlow11' \ +@@ -434,6 +435,7 @@ tcp,actions=fin_timeout(idle_timeout=5,hard_timeout=15) + actions=controller(max_len=123,reason=invalid_ttl,id=555) + actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) + actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,sampling_port=56789) ++mpls,mpls_label=5,mpls_tc=1,mpls_ttl=1,mpls_bos=0,actions=drop + ip,actions=ct(commit,zone=5) + ip,actions=ct(commit,exec(load(1->NXM_NX_CT_MARK[]))) + ip,actions=ct(commit,exec(load(0x1->NXM_NX_CT_LABEL[]))) +@@ -490,6 +492,7 @@ NXT_FLOW_MOD: ADD table:255 tcp actions=fin_timeout(idle_timeout=5,hard_timeout= + NXT_FLOW_MOD: ADD table:255 actions=controller(reason=invalid_ttl,max_len=123,id=555) + NXT_FLOW_MOD: ADD table:255 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) + NXT_FLOW_MOD: ADD table:255 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,sampling_port=56789) ++NXT_FLOW_MOD: ADD table:255 mpls,mpls_label=5,mpls_tc=1,mpls_ttl=1,mpls_bos=0 actions=drop + NXT_FLOW_MOD: ADD table:255 ip actions=ct(commit,zone=5) + NXT_FLOW_MOD: ADD table:255 ip actions=ct(commit,exec(load:0x1->NXM_NX_CT_MARK[])) + NXT_FLOW_MOD: ADD table:255 ip actions=ct(commit,exec(load:0x1->NXM_NX_CT_LABEL[0..63],load:0->NXM_NX_CT_LABEL[64..127])) +diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at +index 8981b5e2f9..3661816f6d 100644 +--- a/tests/ovsdb-idl.at ++++ b/tests/ovsdb-idl.at +@@ -1193,6 +1193,7 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated], + "where": [], + "row": {"b": true}}]']], + [[000: i=1 r=2 b=true s=mystring u=<0> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<1> <2>] uuid=<3> ++000: inserted row: uuid=<3> + 000: updated columns: b ba i ia r ra s sa u ua + 001: {"error":null,"result":[{"count":2}]} + 002: i=0 r=0 b=true s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<5> +@@ -1255,6 +1256,7 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops], + [[000: empty + 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]} + 002: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0> ++002: inserted row: uuid=<0> + 002: updated columns: b ba i ia r ra s sa u ua + 003: {"error":null,"result":[{"count":2}]} + 004: i=0 r=0 b=true s= u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1> +@@ -1266,6 +1268,7 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops], + 006: updated columns: r + 007: {"error":null,"result":[{"uuid":["uuid","<6>"]}]} + 008: i=-1 r=125 b=false s= u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6> ++008: inserted row: uuid=<6> + 008: updated columns: ba i ia r ra + 009: {"error":null,"result":[{"count":2}]} + 010: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6> +@@ -1273,7 +1276,7 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops], + 010: updated columns: s + 010: updated columns: s + 011: {"error":null,"result":[{"count":1}]} +-012: ##deleted## uuid=<1> ++012: deleted row: uuid=<1> + 013: reconnect + 014: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6> + 014: i=1 r=123.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0> diff --git a/tests/ovsdb-replication.at b/tests/ovsdb-replication.at index f81381bdb3..82c4160529 100644 --- a/tests/ovsdb-replication.at @@ -19744,10 +20380,34 @@ index e34f7a4fbd..be702ae597 100644 OVS_CHECK_KERNEL_EXCL(3, 10, 4, 15) OVS_CHECK_GRE() diff --git a/tests/system-userspace-packet-type-aware.at b/tests/system-userspace-packet-type-aware.at -index 24a7698ab4..c2246316de 100644 +index 24a7698ab4..974304758f 100644 --- a/tests/system-userspace-packet-type-aware.at +++ b/tests/system-userspace-packet-type-aware.at -@@ -252,39 +252,39 @@ AT_CHECK([ +@@ -129,6 +129,7 @@ AT_CHECK([ + ip addr add 10.0.0.1/24 dev br-p1 + ip link set br-p1 up + ], [0], [stdout]) ++OVS_WAIT_UNTIL([ovs-appctl ovs/route/show | grep -q br-p1]) + + AT_CHECK([ + ovs-appctl ovs/route/add 10.0.0.0/24 br-p1 +@@ -141,6 +142,7 @@ AT_CHECK([ + ip addr add 20.0.0.2/24 dev br-p2 + ip link set br-p2 up + ], [0], [stdout]) ++OVS_WAIT_UNTIL([ovs-appctl ovs/route/show | grep -q br-p2]) + + AT_CHECK([ + ovs-appctl ovs/route/add 20.0.0.0/24 br-p2 +@@ -153,6 +155,7 @@ AT_CHECK([ + ip addr add 30.0.0.3/24 dev br-p3 + ip link set br-p3 up + ], [0], [stdout]) ++OVS_WAIT_UNTIL([ovs-appctl ovs/route/show | grep -q br-p3]) + + AT_CHECK([ + ovs-appctl ovs/route/add 30.0.0.0/24 br-p3 +@@ -252,39 +255,39 @@ AT_CHECK([ ### Verify datapath configuration AT_CHECK([ @@ -19844,6 +20504,77 @@ index 6d53d016de..2d98fad485 100644 } assert(n_rules <= cls->n_rules); } +diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c +index 187eb28671..c49f084b5f 100644 +--- a/tests/test-ovsdb.c ++++ b/tests/test-ovsdb.c +@@ -2030,7 +2030,7 @@ print_idl(struct ovsdb_idl *idl, int step) + } + + static void +-print_idl_track(struct ovsdb_idl *idl, int step, unsigned int seqno) ++print_idl_track(struct ovsdb_idl *idl, int step) + { + const struct idltest_simple *s; + const struct idltest_link1 *l1; +@@ -2038,26 +2038,42 @@ print_idl_track(struct ovsdb_idl *idl, int step, unsigned int seqno) + int n = 0; + + IDLTEST_SIMPLE_FOR_EACH_TRACKED (s, idl) { +- if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) { +- printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid)); ++ if (idltest_simple_is_deleted(s)) { ++ printf("%03d: deleted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&s->header_.uuid)); + } else { + print_idl_row_simple(s, step); ++ if (idltest_simple_is_new(s)) { ++ printf("%03d: inserted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&s->header_.uuid)); ++ } + } + n++; + } + IDLTEST_LINK1_FOR_EACH_TRACKED (l1, idl) { +- if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) { +- printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid)); ++ if (idltest_link1_is_deleted(l1)) { ++ printf("%03d: deleted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&l1->header_.uuid)); + } else { + print_idl_row_link1(l1, step); ++ if (idltest_link1_is_new(l1)) { ++ printf("%03d: inserted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&l1->header_.uuid)); ++ } + } + n++; + } + IDLTEST_LINK2_FOR_EACH_TRACKED (l2, idl) { +- if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) { +- printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid)); ++ if (idltest_link2_is_deleted(l2)) { ++ printf("%03d: deleted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&l2->header_.uuid)); + } else { + print_idl_row_link2(l2, step); ++ if (idltest_link2_is_new(l2)) { ++ printf("%03d: inserted row: uuid="UUID_FMT"\n", step, ++ UUID_ARGS(&l2->header_.uuid)); ++ } ++ + } + n++; + } +@@ -2464,7 +2480,7 @@ do_idl(struct ovs_cmdl_context *ctx) + + /* Print update. */ + if (track) { +- print_idl_track(idl, step++, ovsdb_idl_get_seqno(idl)); ++ print_idl_track(idl, step++); + ovsdb_idl_track_clear(idl); + } else { + print_idl(idl, step++); diff --git a/tests/testsuite.at b/tests/testsuite.at index b840dbfa70..922ba48fdf 100644 --- a/tests/testsuite.at @@ -19993,10 +20724,10 @@ index f7172433ee..6581c5ea09 100644 AT_SETUP([tunnel_push_pop - packet_out]) diff --git a/tests/tunnel.at b/tests/tunnel.at -index 417343e2c5..4f7c13e7c5 100644 +index 417343e2c5..470cfc9b96 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at -@@ -102,8 +102,9 @@ Datapath actions: set(ipv4(tos=0x3/0x3)),2 +@@ -102,13 +102,43 @@ Datapath actions: set(ipv4(tos=0x3/0x3)),2 dnl Tunnel CE and encapsulated packet Non-ECT AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) @@ -20008,7 +20739,41 @@ index 417343e2c5..4f7c13e7c5 100644 Datapath actions: drop ]) OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is not ECN capable/d"]) -@@ -193,6 +194,17 @@ AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00: + AT_CLEANUP + ++AT_SETUP([tunnel - too long nested attributes]) ++OVS_VSWITCHD_START([add-port br0 p1 \ ++ -- set Interface p1 type=gre options:remote_ip=1.1.1.1 ofport_request=1 \ ++ -- add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2]) ++ ++AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl ++ br0 65534/100: (dummy-internal) ++ p1 1/1: (gre: remote_ip=1.1.1.1) ++ p2 2/2: (dummy) ++]) ++ ++dst_single="dst=1.1.1.1" ++dst_rep=${dst_single} ++dnl Size of one OVS_TUNNEL_KEY_ATTR_IPV4_DST is 4 bytes + NLA_HDRLEN (4 bytes). ++dnl One nested message has room for UINT16_MAX - NLA_HDRLEN (4) bytes, i.e. ++dnl (UINT16_MAX - NLA_HDRLEN) / (4 + NLA_HDRLEN) = 8191.375 of dst addresses. ++for i in `seq 1 8192` ; do ++ dst_rep="${dst_rep},${dst_single}" ++done ++ ++AT_CHECK([ovs-appctl dpctl/add-flow "tunnel(${dst_rep})" "2"], ++ [2], [ignore], [dnl ++ovs-vswitchd: parsing flow key (Argument list too long) ++ovs-appctl: ovs-vswitchd: server returned an error ++]) ++ ++OVS_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_SETUP([tunnel - output]) + OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \ + options:remote_ip=1.1.1.1 options:local_ip=2.2.2.2 \ +@@ -193,6 +223,17 @@ AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00: AT_CHECK([tail -1 stdout], [0], [Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))),set(skb_mark(0x2)),1 ]) diff --git a/SPECS/openvswitch2.11.spec b/SPECS/openvswitch2.11.spec index 4e1bf81..a85e2ff 100644 --- a/SPECS/openvswitch2.11.spec +++ b/SPECS/openvswitch2.11.spec @@ -52,6 +52,7 @@ %endif # On RHEL8 Sphinx is included in buildroot %global external_sphinx 1 +%global __python %{__python3} %else # Use Python2 %global _py python @@ -60,6 +61,7 @@ %global with_python3 0 # Don't use external sphinx (RHV doesn't have optional repositories enabled) %global external_sphinx 0 +%global __python %{__python2} %endif Name: %{pkgname} @@ -67,7 +69,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.11.3 -Release: 68%{?dist} +Release: 74%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -746,6 +748,30 @@ exit 0 %changelog +* Tue Nov 17 2020 Open vSwitch CI - 2.11.3-74 +- Merging upstream branch-2.11 + [757d6ce62c7f7fe77533f6d632f515db847c4145] + +* Mon Nov 02 2020 Timothy Redaelli - 2.11.3-73 +- redhat: Explicitly define __python + [045337a5c881dae4f3b0b4f581eea4dfc32df256] + +* Tue Oct 27 2020 Open vSwitch CI - 2.11.3-72 +- Merging upstream branch-2.11 + [e835b37ab382f04c6b3fa2fec4b7cd0d93cdaec6] + +* Thu Oct 22 2020 Open vSwitch CI - 2.11.3-71 +- Merging upstream branch-2.11 + [a11c3da9f778089b46183f3b21c33cbd48f43cc3] + +* Fri Oct 09 2020 Open vSwitch CI - 2.11.3-70 +- Merging upstream branch-2.11 + [2a26d61978f7ddfd63a957142ae87512db9a6c68] + +* Tue Oct 06 2020 Open vSwitch CI - 2.11.3-69 +- Merging upstream branch-2.11 + [e31b9384beb303ae722faf6fbaaac931a0a491c7] + * Wed Sep 16 2020 Open vSwitch CI - 2.11.3-68 - Merging upstream branch-2.11 [a43432762b2e12773cf207bb659b2e181dc269ed]