diff --git a/SOURCES/openvswitch-3.1.0.patch b/SOURCES/openvswitch-3.1.0.patch index 081bd36..11ea003 100644 --- a/SOURCES/openvswitch-3.1.0.patch +++ b/SOURCES/openvswitch-3.1.0.patch @@ -748,6 +748,300 @@ index c576ae620..474344194 100644 + wc->masks.nw_proto = 0xff; + } +} +diff --git a/lib/meta-flow.xml b/lib/meta-flow.xml +index a1a20366d..bdd12f6a7 100644 +--- a/lib/meta-flow.xml ++++ b/lib/meta-flow.xml +@@ -4312,9 +4312,9 @@ r r c c c. + + + +- ++ + +- ++ + + + +diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c +index b89dfdd52..6c9094638 100644 +--- a/lib/netdev-native-tnl.c ++++ b/lib/netdev-native-tnl.c +@@ -320,7 +320,7 @@ netdev_tnl_ip_build_header(struct ovs_action_push_tnl *data, + } + + static void * +-udp_build_header(struct netdev_tunnel_config *tnl_cfg, ++udp_build_header(const struct netdev_tunnel_config *tnl_cfg, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +@@ -452,7 +452,6 @@ netdev_gre_push_header(const struct netdev *netdev, + const struct ovs_action_push_tnl *data) + { + struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; + struct gre_base_hdr *greh; + int ip_tot_size; + +@@ -468,8 +467,7 @@ netdev_gre_push_header(const struct netdev *netdev, + int seq_ofs = gre_header_len(greh->flags) - 4; + ovs_16aligned_be32 *seq_opt = + ALIGNED_CAST(ovs_16aligned_be32 *, (char *)greh + seq_ofs); +- tnl_cfg = &dev->tnl_cfg; +- put_16aligned_be32(seq_opt, htonl(tnl_cfg->seqno++)); ++ put_16aligned_be32(seq_opt, htonl(atomic_count_inc(&dev->gre_seqno))); + } + } + +@@ -478,16 +476,11 @@ netdev_gre_build_header(const struct netdev *netdev, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; ++ const struct netdev_tunnel_config *tnl_cfg; + struct gre_base_hdr *greh; + ovs_16aligned_be32 *options; + unsigned int hlen; + +- /* XXX: RCUfy tnl_cfg. */ +- ovs_mutex_lock(&dev->mutex); +- tnl_cfg = &dev->tnl_cfg; +- + greh = netdev_tnl_ip_build_header(data, params, IPPROTO_GRE); + + if (params->flow->packet_type == htonl(PT_ETH)) { +@@ -495,8 +488,7 @@ netdev_gre_build_header(const struct netdev *netdev, + } else if (pt_ns(params->flow->packet_type) == OFPHTN_ETHERTYPE) { + greh->protocol = pt_ns_type_be(params->flow->packet_type); + } else { +- ovs_mutex_unlock(&dev->mutex); +- return 1; ++ return EINVAL; + } + greh->flags = 0; + +@@ -507,6 +499,8 @@ netdev_gre_build_header(const struct netdev *netdev, + options++; + } + ++ tnl_cfg = netdev_get_tunnel_config(netdev); ++ + if (tnl_cfg->out_key_present) { + greh->flags |= htons(GRE_KEY); + put_16aligned_be32(options, be64_to_be32(params->flow->tunnel.tun_id)); +@@ -519,8 +513,6 @@ netdev_gre_build_header(const struct netdev *netdev, + options++; + } + +- ovs_mutex_unlock(&dev->mutex); +- + hlen = (uint8_t *) options - (uint8_t *) greh; + + data->header_len += hlen; +@@ -605,7 +597,6 @@ netdev_erspan_push_header(const struct netdev *netdev, + const struct ovs_action_push_tnl *data) + { + struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; + struct erspan_base_hdr *ersh; + struct gre_base_hdr *greh; + struct erspan_md2 *md2; +@@ -615,9 +606,8 @@ netdev_erspan_push_header(const struct netdev *netdev, + data->header_len, &ip_tot_size); + + /* update GRE seqno */ +- tnl_cfg = &dev->tnl_cfg; + ovs_16aligned_be32 *seqno = (ovs_16aligned_be32 *) (greh + 1); +- put_16aligned_be32(seqno, htonl(tnl_cfg->seqno++)); ++ put_16aligned_be32(seqno, htonl(atomic_count_inc(&dev->gre_seqno))); + + /* update v2 timestamp */ + if (greh->protocol == htons(ETH_TYPE_ERSPAN2)) { +@@ -632,8 +622,7 @@ netdev_erspan_build_header(const struct netdev *netdev, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; ++ const struct netdev_tunnel_config *tnl_cfg; + struct gre_base_hdr *greh; + struct erspan_base_hdr *ersh; + unsigned int hlen; +@@ -641,21 +630,19 @@ netdev_erspan_build_header(const struct netdev *netdev, + int erspan_ver; + uint16_t sid; + +- /* XXX: RCUfy tnl_cfg. */ +- ovs_mutex_lock(&dev->mutex); +- tnl_cfg = &dev->tnl_cfg; + greh = netdev_tnl_ip_build_header(data, params, IPPROTO_GRE); + ersh = ERSPAN_HDR(greh); + + tun_id = ntohl(be64_to_be32(params->flow->tunnel.tun_id)); + /* ERSPAN only has 10-bit session ID */ + if (tun_id & ~ERSPAN_SID_MASK) { +- ovs_mutex_unlock(&dev->mutex); +- return 1; ++ return EINVAL; + } else { + sid = (uint16_t) tun_id; + } + ++ tnl_cfg = netdev_get_tunnel_config(netdev); ++ + if (tnl_cfg->erspan_ver_flow) { + erspan_ver = params->flow->tunnel.erspan_ver; + } else { +@@ -702,12 +689,9 @@ netdev_erspan_build_header(const struct netdev *netdev, + hlen = ERSPAN_GREHDR_LEN + sizeof *ersh + ERSPAN_V2_MDSIZE; + } else { + VLOG_WARN_RL(&err_rl, "ERSPAN version error %d", tnl_cfg->erspan_ver); +- ovs_mutex_unlock(&dev->mutex); +- return 1; ++ return EINVAL; + } + +- ovs_mutex_unlock(&dev->mutex); +- + data->header_len += hlen; + + if (params->is_ipv6) { +@@ -786,7 +770,6 @@ netdev_gtpu_push_header(const struct netdev *netdev, + const struct ovs_action_push_tnl *data) + { + struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; + struct udp_header *udp; + struct gtpuhdr *gtpuh; + int ip_tot_size; +@@ -801,10 +784,9 @@ netdev_gtpu_push_header(const struct netdev *netdev, + + gtpuh = ALIGNED_CAST(struct gtpuhdr *, udp + 1); + +- tnl_cfg = &dev->tnl_cfg; +- if (tnl_cfg->set_seq) { ++ if (gtpuh->md.flags & GTPU_S_MASK) { + ovs_be16 *seqno = ALIGNED_CAST(ovs_be16 *, gtpuh + 1); +- *seqno = htons(tnl_cfg->seqno++); ++ *seqno = htons(atomic_count_inc(&dev->gre_seqno)); + payload_len += sizeof(struct gtpuhdr_opt); + } + gtpuh->len = htons(payload_len); +@@ -815,13 +797,12 @@ netdev_gtpu_build_header(const struct netdev *netdev, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; ++ const struct netdev_tunnel_config *tnl_cfg; + struct gtpuhdr *gtph; + unsigned int gtpu_hlen; + +- ovs_mutex_lock(&dev->mutex); +- tnl_cfg = &dev->tnl_cfg; ++ tnl_cfg = netdev_get_tunnel_config(netdev); ++ + gtph = udp_build_header(tnl_cfg, data, params); + + /* Set to default if not set in flow. */ +@@ -837,7 +818,6 @@ netdev_gtpu_build_header(const struct netdev *netdev, + gtph->md.flags |= GTPU_S_MASK; + gtpu_hlen += sizeof(struct gtpuhdr_opt); + } +- ovs_mutex_unlock(&dev->mutex); + + data->header_len += gtpu_hlen; + data->tnl_type = OVS_VPORT_TYPE_GTPU; +@@ -920,13 +900,10 @@ netdev_vxlan_build_header(const struct netdev *netdev, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; ++ const struct netdev_tunnel_config *tnl_cfg; + struct vxlanhdr *vxh; + +- /* XXX: RCUfy tnl_cfg. */ +- ovs_mutex_lock(&dev->mutex); +- tnl_cfg = &dev->tnl_cfg; ++ tnl_cfg = netdev_get_tunnel_config(netdev); + + vxh = udp_build_header(tnl_cfg, data, params); + +@@ -951,10 +928,10 @@ netdev_vxlan_build_header(const struct netdev *netdev, + vxh->vx_gpe.next_protocol = VXLAN_GPE_NP_ETHERNET; + break; + default: +- goto drop; ++ return EINVAL; + } + } else { +- goto drop; ++ return EINVAL; + } + } else { + put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS)); +@@ -962,14 +939,9 @@ netdev_vxlan_build_header(const struct netdev *netdev, + htonl(ntohll(params->flow->tunnel.tun_id) << 8)); + } + +- ovs_mutex_unlock(&dev->mutex); + data->header_len += sizeof *vxh; + data->tnl_type = OVS_VPORT_TYPE_VXLAN; + return 0; +- +-drop: +- ovs_mutex_unlock(&dev->mutex); +- return 1; + } + + struct dp_packet * +@@ -1033,22 +1005,14 @@ netdev_geneve_build_header(const struct netdev *netdev, + struct ovs_action_push_tnl *data, + const struct netdev_tnl_build_header_params *params) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); +- struct netdev_tunnel_config *tnl_cfg; + struct genevehdr *gnh; + int opt_len; + bool crit_opt; + +- /* XXX: RCUfy tnl_cfg. */ +- ovs_mutex_lock(&dev->mutex); +- tnl_cfg = &dev->tnl_cfg; +- +- gnh = udp_build_header(tnl_cfg, data, params); ++ gnh = udp_build_header(netdev_get_tunnel_config(netdev), data, params); + + put_16aligned_be32(&gnh->vni, htonl(ntohll(params->flow->tunnel.tun_id) << 8)); + +- ovs_mutex_unlock(&dev->mutex); +- + opt_len = tun_metadata_to_geneve_header(¶ms->flow->tunnel, + gnh->options, &crit_opt); + +diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c +index b3421c099..2d7858f51 100644 +--- a/lib/netdev-offload-dpdk.c ++++ b/lib/netdev-offload-dpdk.c +@@ -2345,13 +2345,13 @@ netdev_offload_dpdk_flow_destroy(struct ufid_to_rte_flow_data *rte_flow_data) + ovsrcu_get(void *, &netdev->hw_info.offload_data); + data->rte_flow_counters[tid]--; + +- ufid_to_rte_flow_disassociate(rte_flow_data); + VLOG_DBG_RL(&rl, "%s/%s: rte_flow 0x%"PRIxPTR + " flow destroy %d ufid " UUID_FMT, + netdev_get_name(netdev), netdev_get_name(physdev), + (intptr_t) rte_flow, + netdev_dpdk_get_port_id(physdev), + UUID_ARGS((struct uuid *) ufid)); ++ ufid_to_rte_flow_disassociate(rte_flow_data); + } else { + VLOG_ERR("Failed flow: %s/%s: flow destroy %d ufid " UUID_FMT, + netdev_get_name(netdev), netdev_get_name(physdev), diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 4c78c4816..09f6393f8 100644 --- a/lib/netdev-offload-tc.c @@ -1165,6 +1459,460 @@ index 4592262bd..a5fa62487 100644 } void +diff --git a/lib/netdev-vport-private.h b/lib/netdev-vport-private.h +index d89a28c66..586231057 100644 +--- a/lib/netdev-vport-private.h ++++ b/lib/netdev-vport-private.h +@@ -22,11 +22,17 @@ + #include "compiler.h" + #include "netdev.h" + #include "netdev-provider.h" ++#include "ovs-atomic.h" + #include "ovs-thread.h" + + struct netdev_vport { + struct netdev up; + ++ OVSRCU_TYPE(const struct netdev_tunnel_config *) tnl_cfg; ++ ++ /* Sequence number for outgoing GRE packets. */ ++ atomic_count gre_seqno; ++ + /* Protects all members below. */ + struct ovs_mutex mutex; + +@@ -34,7 +40,6 @@ struct netdev_vport { + struct netdev_stats stats; + + /* Tunnels. */ +- struct netdev_tunnel_config tnl_cfg; + char egress_iface[IFNAMSIZ]; + bool carrier_status; + +diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c +index 3b3927865..4cfe15d5a 100644 +--- a/lib/netdev-vport.c ++++ b/lib/netdev-vport.c +@@ -37,6 +37,7 @@ + #include "netdev-provider.h" + #include "netdev-vport-private.h" + #include "openvswitch/dynamic-string.h" ++#include "ovs-atomic.h" + #include "ovs-router.h" + #include "packets.h" + #include "openvswitch/poll-loop.h" +@@ -68,8 +69,8 @@ static int get_patch_config(const struct netdev *netdev, struct smap *args); + static int get_tunnel_config(const struct netdev *, struct smap *args); + static bool tunnel_check_status_change__(struct netdev_vport *); + static void update_vxlan_global_cfg(struct netdev *, +- struct netdev_tunnel_config *, +- struct netdev_tunnel_config *); ++ const struct netdev_tunnel_config *, ++ const struct netdev_tunnel_config *); + + struct vport_class { + const char *dpif_port; +@@ -90,10 +91,16 @@ vport_class_cast(const struct netdev_class *class) + return CONTAINER_OF(class, struct vport_class, netdev_class); + } + ++static const struct netdev_tunnel_config * ++vport_tunnel_config(struct netdev_vport *netdev) ++{ ++ return ovsrcu_get(const struct netdev_tunnel_config *, &netdev->tnl_cfg); ++} ++ + static const struct netdev_tunnel_config * + get_netdev_tunnel_config(const struct netdev *netdev) + { +- return &netdev_vport_cast(netdev)->tnl_cfg; ++ return vport_tunnel_config(netdev_vport_cast(netdev)); + } + + bool +@@ -134,8 +141,6 @@ netdev_vport_get_dpif_port(const struct netdev *netdev, + } + + if (netdev_vport_needs_dst_port(netdev)) { +- const struct netdev_vport *vport = netdev_vport_cast(netdev); +- + /* + * Note: IFNAMSIZ is 16 bytes long. Implementations should choose + * a dpif port name that is short enough to fit including any +@@ -144,7 +149,7 @@ netdev_vport_get_dpif_port(const struct netdev *netdev, + BUILD_ASSERT(NETDEV_VPORT_NAME_BUFSIZE >= IFNAMSIZ); + ovs_assert(strlen(dpif_port) + 6 < IFNAMSIZ); + snprintf(namebuf, bufsize, "%s_%d", dpif_port, +- ntohs(vport->tnl_cfg.dst_port)); ++ ntohs(netdev_get_tunnel_config(netdev)->dst_port)); + return namebuf; + } else { + return dpif_port; +@@ -162,12 +167,14 @@ netdev_vport_route_changed(void) + + vports = netdev_get_vports(&n_vports); + for (i = 0; i < n_vports; i++) { ++ const struct netdev_tunnel_config *tnl_cfg; + struct netdev *netdev_ = vports[i]; + struct netdev_vport *netdev = netdev_vport_cast(netdev_); + + ovs_mutex_lock(&netdev->mutex); + /* Finds all tunnel vports. */ +- if (ipv6_addr_is_set(&netdev->tnl_cfg.ipv6_dst)) { ++ tnl_cfg = netdev_get_tunnel_config(netdev_); ++ if (tnl_cfg && ipv6_addr_is_set(&tnl_cfg->ipv6_dst)) { + if (tunnel_check_status_change__(netdev)) { + netdev_change_seq_changed(netdev_); + } +@@ -198,6 +205,7 @@ netdev_vport_construct(struct netdev *netdev_) + uint16_t port = 0; + + ovs_mutex_init(&dev->mutex); ++ atomic_count_init(&dev->gre_seqno, 0); + eth_addr_random(&dev->etheraddr); + + if (name && dpif_port && (strlen(name) > strlen(dpif_port) + 1) && +@@ -206,26 +214,31 @@ netdev_vport_construct(struct netdev *netdev_) + port = atoi(p); + } + ++ struct netdev_tunnel_config *tnl_cfg = xzalloc(sizeof *tnl_cfg); ++ + /* If a destination port for tunnel ports is specified in the netdev + * name, use it instead of the default one. Otherwise, use the default + * destination port */ + if (!strcmp(type, "geneve")) { +- dev->tnl_cfg.dst_port = port ? htons(port) : htons(GENEVE_DST_PORT); ++ tnl_cfg->dst_port = port ? htons(port) : htons(GENEVE_DST_PORT); + } else if (!strcmp(type, "vxlan")) { +- dev->tnl_cfg.dst_port = port ? htons(port) : htons(VXLAN_DST_PORT); +- update_vxlan_global_cfg(netdev_, NULL, &dev->tnl_cfg); ++ tnl_cfg->dst_port = port ? htons(port) : htons(VXLAN_DST_PORT); ++ update_vxlan_global_cfg(netdev_, NULL, tnl_cfg); + } else if (!strcmp(type, "lisp")) { +- dev->tnl_cfg.dst_port = port ? htons(port) : htons(LISP_DST_PORT); ++ tnl_cfg->dst_port = port ? htons(port) : htons(LISP_DST_PORT); + } else if (!strcmp(type, "stt")) { +- dev->tnl_cfg.dst_port = port ? htons(port) : htons(STT_DST_PORT); ++ tnl_cfg->dst_port = port ? htons(port) : htons(STT_DST_PORT); + } else if (!strcmp(type, "gtpu")) { +- dev->tnl_cfg.dst_port = port ? htons(port) : htons(GTPU_DST_PORT); ++ tnl_cfg->dst_port = port ? htons(port) : htons(GTPU_DST_PORT); + } else if (!strcmp(type, "bareudp")) { +- dev->tnl_cfg.dst_port = htons(port); ++ tnl_cfg->dst_port = htons(port); + } + +- dev->tnl_cfg.dont_fragment = true; +- dev->tnl_cfg.ttl = DEFAULT_TTL; ++ tnl_cfg->dont_fragment = true; ++ tnl_cfg->ttl = DEFAULT_TTL; ++ ++ ovsrcu_set(&dev->tnl_cfg, tnl_cfg); ++ + return 0; + } + +@@ -233,12 +246,15 @@ static void + netdev_vport_destruct(struct netdev *netdev_) + { + struct netdev_vport *netdev = netdev_vport_cast(netdev_); ++ const struct netdev_tunnel_config *tnl_cfg = vport_tunnel_config(netdev); + const char *type = netdev_get_type(netdev_); + + if (!strcmp(type, "vxlan")) { +- update_vxlan_global_cfg(netdev_, &netdev->tnl_cfg, NULL); ++ update_vxlan_global_cfg(netdev_, tnl_cfg, NULL); + } + ++ ovsrcu_set(&netdev->tnl_cfg, NULL); ++ ovsrcu_postpone(free, CONST_CAST(struct netdev_tunnel_config *, tnl_cfg)); + free(netdev->peer); + ovs_mutex_destroy(&netdev->mutex); + } +@@ -281,15 +297,16 @@ static bool + tunnel_check_status_change__(struct netdev_vport *netdev) + OVS_REQUIRES(netdev->mutex) + { ++ const struct netdev_tunnel_config *tnl_cfg = vport_tunnel_config(netdev); ++ const struct in6_addr *route; + char iface[IFNAMSIZ]; + bool status = false; +- struct in6_addr *route; + struct in6_addr gw; + uint32_t mark; + + iface[0] = '\0'; +- route = &netdev->tnl_cfg.ipv6_dst; +- mark = netdev->tnl_cfg.egress_pkt_mark; ++ route = &tnl_cfg->ipv6_dst; ++ mark = tnl_cfg->egress_pkt_mark; + if (ovs_router_lookup(mark, route, iface, NULL, &gw)) { + struct netdev *egress_netdev; + +@@ -465,8 +482,8 @@ vxlan_get_port_ext_gbp_str(uint16_t port, bool gbp, + + static void + update_vxlan_global_cfg(struct netdev *netdev, +- struct netdev_tunnel_config *old_cfg, +- struct netdev_tunnel_config *new_cfg) ++ const struct netdev_tunnel_config *old_cfg, ++ const struct netdev_tunnel_config *new_cfg) + { + unsigned int count; + char namebuf[20]; +@@ -510,19 +527,20 @@ static bool + is_concomitant_vxlan_tunnel_present(struct netdev_vport *dev, + const struct netdev_tunnel_config *tnl_cfg) + { +- char namebuf[20]; +- const char *type = netdev_get_type(&dev->up); ++ const struct netdev_tunnel_config *dev_tnl_cfg = vport_tunnel_config(dev); + struct vport_class *vclass = vport_class_cast(netdev_get_class(&dev->up)); ++ const char *type = netdev_get_type(&dev->up); ++ char namebuf[20]; + + if (strcmp(type, "vxlan")) { + return false; + } + +- if (dev->tnl_cfg.dst_port == tnl_cfg->dst_port && +- (dev->tnl_cfg.exts & (1 << OVS_VXLAN_EXT_GBP)) == ++ if (dev_tnl_cfg->dst_port == tnl_cfg->dst_port && ++ (dev_tnl_cfg->exts & (1 << OVS_VXLAN_EXT_GBP)) == + (tnl_cfg->exts & (1 << OVS_VXLAN_EXT_GBP))) { + +- if (ntohs(dev->tnl_cfg.dst_port) == VXLAN_DST_PORT) { ++ if (ntohs(dev_tnl_cfg->dst_port) == VXLAN_DST_PORT) { + /* Special case where we kept the default port/gbp, only ok if + the opposite of the default does not exits */ + vxlan_get_port_ext_gbp_str(ntohs(tnl_cfg->dst_port), +@@ -538,9 +556,9 @@ is_concomitant_vxlan_tunnel_present(struct netdev_vport *dev, + } + + /* Same port: ok if no one is left with the previous configuration */ +- if (dev->tnl_cfg.dst_port == tnl_cfg->dst_port) { +- vxlan_get_port_ext_gbp_str(ntohs(dev->tnl_cfg.dst_port), +- dev->tnl_cfg.exts & ++ if (dev_tnl_cfg->dst_port == tnl_cfg->dst_port) { ++ vxlan_get_port_ext_gbp_str(ntohs(dev_tnl_cfg->dst_port), ++ dev_tnl_cfg->exts & + (1 << OVS_VXLAN_EXT_GBP), + namebuf, sizeof(namebuf)); + +@@ -568,6 +586,7 @@ static int + set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp) + { + struct netdev_vport *dev = netdev_vport_cast(dev_); ++ const struct netdev_tunnel_config *curr_tnl_cfg; + const char *name = netdev_get_name(dev_); + const char *type = netdev_get_type(dev_); + struct ds errors = DS_EMPTY_INITIALIZER; +@@ -858,11 +877,16 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp) + err = EEXIST; + goto out; + } +- update_vxlan_global_cfg(dev_, &dev->tnl_cfg, &tnl_cfg); + + ovs_mutex_lock(&dev->mutex); +- if (memcmp(&dev->tnl_cfg, &tnl_cfg, sizeof tnl_cfg)) { +- dev->tnl_cfg = tnl_cfg; ++ ++ curr_tnl_cfg = vport_tunnel_config(dev); ++ update_vxlan_global_cfg(dev_, curr_tnl_cfg, &tnl_cfg); ++ ++ if (memcmp(curr_tnl_cfg, &tnl_cfg, sizeof tnl_cfg)) { ++ ovsrcu_set(&dev->tnl_cfg, xmemdup(&tnl_cfg, sizeof tnl_cfg)); ++ ovsrcu_postpone(free, CONST_CAST(struct netdev_tunnel_config *, ++ curr_tnl_cfg)); + tunnel_check_status_change__(dev); + netdev_change_seq_changed(dev_); + } +@@ -887,61 +911,60 @@ out: + static int + get_tunnel_config(const struct netdev *dev, struct smap *args) + { +- struct netdev_vport *netdev = netdev_vport_cast(dev); ++ const struct netdev_tunnel_config *tnl_cfg = netdev_get_tunnel_config(dev); + const char *type = netdev_get_type(dev); +- struct netdev_tunnel_config tnl_cfg; + +- ovs_mutex_lock(&netdev->mutex); +- tnl_cfg = netdev->tnl_cfg; +- ovs_mutex_unlock(&netdev->mutex); ++ if (!tnl_cfg) { ++ return 0; ++ } + +- if (ipv6_addr_is_set(&tnl_cfg.ipv6_dst)) { +- smap_add_ipv6(args, "remote_ip", &tnl_cfg.ipv6_dst); +- } else if (tnl_cfg.ip_dst_flow) { ++ if (ipv6_addr_is_set(&tnl_cfg->ipv6_dst)) { ++ smap_add_ipv6(args, "remote_ip", &tnl_cfg->ipv6_dst); ++ } else if (tnl_cfg->ip_dst_flow) { + smap_add(args, "remote_ip", "flow"); + } + +- if (ipv6_addr_is_set(&tnl_cfg.ipv6_src)) { +- smap_add_ipv6(args, "local_ip", &tnl_cfg.ipv6_src); +- } else if (tnl_cfg.ip_src_flow) { ++ if (ipv6_addr_is_set(&tnl_cfg->ipv6_src)) { ++ smap_add_ipv6(args, "local_ip", &tnl_cfg->ipv6_src); ++ } else if (tnl_cfg->ip_src_flow) { + smap_add(args, "local_ip", "flow"); + } + +- if (tnl_cfg.in_key_flow && tnl_cfg.out_key_flow) { ++ if (tnl_cfg->in_key_flow && tnl_cfg->out_key_flow) { + smap_add(args, "key", "flow"); +- } else if (tnl_cfg.in_key_present && tnl_cfg.out_key_present +- && tnl_cfg.in_key == tnl_cfg.out_key) { +- smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg.in_key)); ++ } else if (tnl_cfg->in_key_present && tnl_cfg->out_key_present ++ && tnl_cfg->in_key == tnl_cfg->out_key) { ++ smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg->in_key)); + } else { +- if (tnl_cfg.in_key_flow) { ++ if (tnl_cfg->in_key_flow) { + smap_add(args, "in_key", "flow"); +- } else if (tnl_cfg.in_key_present) { ++ } else if (tnl_cfg->in_key_present) { + smap_add_format(args, "in_key", "%"PRIu64, +- ntohll(tnl_cfg.in_key)); ++ ntohll(tnl_cfg->in_key)); + } + +- if (tnl_cfg.out_key_flow) { ++ if (tnl_cfg->out_key_flow) { + smap_add(args, "out_key", "flow"); +- } else if (tnl_cfg.out_key_present) { ++ } else if (tnl_cfg->out_key_present) { + smap_add_format(args, "out_key", "%"PRIu64, +- ntohll(tnl_cfg.out_key)); ++ ntohll(tnl_cfg->out_key)); + } + } + +- if (tnl_cfg.ttl_inherit) { ++ if (tnl_cfg->ttl_inherit) { + smap_add(args, "ttl", "inherit"); +- } else if (tnl_cfg.ttl != DEFAULT_TTL) { +- smap_add_format(args, "ttl", "%"PRIu8, tnl_cfg.ttl); ++ } else if (tnl_cfg->ttl != DEFAULT_TTL) { ++ smap_add_format(args, "ttl", "%"PRIu8, tnl_cfg->ttl); + } + +- if (tnl_cfg.tos_inherit) { ++ if (tnl_cfg->tos_inherit) { + smap_add(args, "tos", "inherit"); +- } else if (tnl_cfg.tos) { +- smap_add_format(args, "tos", "0x%x", tnl_cfg.tos); ++ } else if (tnl_cfg->tos) { ++ smap_add_format(args, "tos", "0x%x", tnl_cfg->tos); + } + +- if (tnl_cfg.dst_port) { +- uint16_t dst_port = ntohs(tnl_cfg.dst_port); ++ if (tnl_cfg->dst_port) { ++ uint16_t dst_port = ntohs(tnl_cfg->dst_port); + + if ((!strcmp("geneve", type) && dst_port != GENEVE_DST_PORT) || + (!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) || +@@ -953,33 +976,33 @@ get_tunnel_config(const struct netdev *dev, struct smap *args) + } + } + +- if (tnl_cfg.csum) { ++ if (tnl_cfg->csum) { + smap_add(args, "csum", "true"); + } + +- if (tnl_cfg.set_seq) { ++ if (tnl_cfg->set_seq) { + smap_add(args, "seq", "true"); + } + +- enum tunnel_layers layers = tunnel_supported_layers(type, &tnl_cfg); +- if (tnl_cfg.pt_mode != default_pt_mode(layers)) { ++ enum tunnel_layers layers = tunnel_supported_layers(type, tnl_cfg); ++ if (tnl_cfg->pt_mode != default_pt_mode(layers)) { + smap_add(args, "packet_type", +- tnl_cfg.pt_mode == NETDEV_PT_LEGACY_L2 ? "legacy_l2" +- : tnl_cfg.pt_mode == NETDEV_PT_LEGACY_L3 ? "legacy_l3" ++ tnl_cfg->pt_mode == NETDEV_PT_LEGACY_L2 ? "legacy_l2" ++ : tnl_cfg->pt_mode == NETDEV_PT_LEGACY_L3 ? "legacy_l3" + : "ptap"); + } + +- if (!tnl_cfg.dont_fragment) { ++ if (!tnl_cfg->dont_fragment) { + smap_add(args, "df_default", "false"); + } + +- if (tnl_cfg.set_egress_pkt_mark) { ++ if (tnl_cfg->set_egress_pkt_mark) { + smap_add_format(args, "egress_pkt_mark", +- "%"PRIu32, tnl_cfg.egress_pkt_mark); ++ "%"PRIu32, tnl_cfg->egress_pkt_mark); + } + + if (!strcmp("erspan", type) || !strcmp("ip6erspan", type)) { +- if (tnl_cfg.erspan_ver_flow) { ++ if (tnl_cfg->erspan_ver_flow) { + /* since version number is not determined, + * assume print all other as flow + */ +@@ -988,27 +1011,27 @@ get_tunnel_config(const struct netdev *dev, struct smap *args) + smap_add(args, "erspan_dir", "flow"); + smap_add(args, "erspan_hwid", "flow"); + } else { +- smap_add_format(args, "erspan_ver", "%d", tnl_cfg.erspan_ver); ++ smap_add_format(args, "erspan_ver", "%d", tnl_cfg->erspan_ver); + +- if (tnl_cfg.erspan_ver == 1) { +- if (tnl_cfg.erspan_idx_flow) { ++ if (tnl_cfg->erspan_ver == 1) { ++ if (tnl_cfg->erspan_idx_flow) { + smap_add(args, "erspan_idx", "flow"); + } else { + smap_add_format(args, "erspan_idx", "0x%x", +- tnl_cfg.erspan_idx); ++ tnl_cfg->erspan_idx); + } +- } else if (tnl_cfg.erspan_ver == 2) { +- if (tnl_cfg.erspan_dir_flow) { ++ } else if (tnl_cfg->erspan_ver == 2) { ++ if (tnl_cfg->erspan_dir_flow) { + smap_add(args, "erspan_dir", "flow"); + } else { + smap_add_format(args, "erspan_dir", "%d", +- tnl_cfg.erspan_dir); ++ tnl_cfg->erspan_dir); + } +- if (tnl_cfg.erspan_hwid_flow) { ++ if (tnl_cfg->erspan_hwid_flow) { + smap_add(args, "erspan_hwid", "flow"); + } else { + smap_add_format(args, "erspan_hwid", "0x%x", +- tnl_cfg.erspan_hwid); ++ tnl_cfg->erspan_hwid); + } + } + } +@@ -1138,9 +1161,11 @@ netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats) + static enum netdev_pt_mode + netdev_vport_get_pt_mode(const struct netdev *netdev) + { +- struct netdev_vport *dev = netdev_vport_cast(netdev); ++ const struct netdev_tunnel_config *tnl_cfg; ++ ++ tnl_cfg = netdev_get_tunnel_config(netdev); + +- return dev->tnl_cfg.pt_mode; ++ return tnl_cfg ? tnl_cfg->pt_mode : NETDEV_PT_UNKNOWN; + } + + diff --git a/lib/netdev-windows.c b/lib/netdev-windows.c index 4ad45ffa1..3fad501e3 100644 --- a/lib/netdev-windows.c @@ -1194,6 +1942,28 @@ index 4ad45ffa1..3fad501e3 100644 netdev->change_seq = 1; netdev->dev_type = info.ovs_type; netdev->port_no = info.port_no; +diff --git a/lib/netdev.h b/lib/netdev.h +index acf174927..47c15bde7 100644 +--- a/lib/netdev.h ++++ b/lib/netdev.h +@@ -72,6 +72,9 @@ struct sset; + struct ovs_action_push_tnl; + + enum netdev_pt_mode { ++ /* Unknown mode. The netdev is not configured yet. */ ++ NETDEV_PT_UNKNOWN = 0, ++ + /* The netdev is packet type aware. It can potentially carry any kind of + * packet. This "modern" mode is appropriate for both netdevs that handle + * only a single kind of packet (such as a virtual or physical Ethernet +@@ -130,7 +133,6 @@ struct netdev_tunnel_config { + enum netdev_pt_mode pt_mode; + + bool set_seq; +- uint32_t seqno; + uint32_t erspan_idx; + uint8_t erspan_ver; + uint8_t erspan_dir; diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index a90b926ef..102b183a8 100644 --- a/lib/ofp-parse.c @@ -1230,6 +2000,51 @@ index 2d382f1e8..ac5d2c3d0 100644 last_updated = now; cpu_cores = count_cpu_cores__(); } +diff --git a/lib/smap.c b/lib/smap.c +index c1633e2a1..47fb34502 100644 +--- a/lib/smap.c ++++ b/lib/smap.c +@@ -100,7 +100,7 @@ smap_add_format(struct smap *smap, const char *key, const char *format, ...) + /* Adds 'key' paired with a string representation of 'addr'. It is the + * caller's responsibility to avoid duplicate keys if desirable. */ + void +-smap_add_ipv6(struct smap *smap, const char *key, struct in6_addr *addr) ++smap_add_ipv6(struct smap *smap, const char *key, const struct in6_addr *addr) + { + char buf[INET6_ADDRSTRLEN]; + ipv6_string_mapped(buf, addr); +diff --git a/lib/smap.h b/lib/smap.h +index 2fe6c540a..d1d2ae6f2 100644 +--- a/lib/smap.h ++++ b/lib/smap.h +@@ -100,7 +100,7 @@ struct smap_node *smap_add_nocopy(struct smap *, char *, char *); + bool smap_add_once(struct smap *, const char *, const char *); + void smap_add_format(struct smap *, const char *key, const char *, ...) + OVS_PRINTF_FORMAT(3, 4); +-void smap_add_ipv6(struct smap *, const char *, struct in6_addr *); ++void smap_add_ipv6(struct smap *, const char *, const struct in6_addr *); + void smap_replace(struct smap *, const char *, const char *); + void smap_replace_nocopy(struct smap *, const char *, char *); + +diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c +index 62da9febb..86747e58b 100644 +--- a/lib/stream-ssl.c ++++ b/lib/stream-ssl.c +@@ -1075,7 +1075,13 @@ do_ssl_init(void) + VLOG_ERR("SSL_CTX_new: %s", ERR_error_string(ERR_get_error(), NULL)); + return ENOPROTOOPT; + } +- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); ++ ++ long options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; ++#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF ++ options |= SSL_OP_IGNORE_UNEXPECTED_EOF; ++#endif ++ SSL_CTX_set_options(ctx, options); ++ + #if OPENSSL_VERSION_NUMBER < 0x3000000fL + SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_callback); + #else diff --git a/lib/tc.c b/lib/tc.c index 4c07e2216..5c32c6f97 100644 --- a/lib/tc.c @@ -2969,6 +3784,194 @@ index 3b5c66fe5..d63528e69 100644 ]) ovs-appctl time/warp 1000 +diff --git a/tests/system-dpdk-macros.at b/tests/system-dpdk-macros.at +index 53fbc1320..3920f08a5 100644 +--- a/tests/system-dpdk-macros.at ++++ b/tests/system-dpdk-macros.at +@@ -42,7 +42,7 @@ m4_define([OVS_DPDK_START], + OVS_DPDK_START_OVSDB() + dnl Enable DPDK functionality + AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true]) +- OVS_DPDK_START_VSWITCHD() ++ OVS_DPDK_START_VSWITCHD($1) + ]) + + # OVS_DPDK_START_OVSDB() +@@ -72,7 +72,7 @@ m4_define([OVS_DPDK_START_OVSDB], + # + m4_define([OVS_DPDK_START_VSWITCHD], + [dnl Change DPDK drivers log levels so that tests only catch errors +- AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-extra=--log-level=pmd.*:error]) ++ AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-extra="--log-level=pmd.*:error $1"]) + + dnl Start ovs-vswitchd. + AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --log-file -vvconn -vofproto_dpif -vunixctl], [0], [stdout], [stderr]) +diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at +index cb6c6d590..0f58e8574 100644 +--- a/tests/system-dpdk.at ++++ b/tests/system-dpdk.at +@@ -32,7 +32,7 @@ dnl Check if EAL init is successful + AT_SETUP([OVS-DPDK - EAL init]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + AT_CHECK([grep "DPDK Enabled - initializing..." ovs-vswitchd.log], [], [stdout]) + AT_CHECK([grep "EAL" ovs-vswitchd.log], [], [stdout]) + AT_CHECK([grep "DPDK Enabled - initialized" ovs-vswitchd.log], [], [stdout]) +@@ -69,7 +69,7 @@ dnl Add vhost-user-client port + AT_SETUP([OVS-DPDK - add vhost-user-client port]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -98,7 +98,7 @@ AT_SETUP([OVS-DPDK - ping vhost-user ports]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -174,7 +174,7 @@ AT_SETUP([OVS-DPDK - ping vhost-user-client ports]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -309,7 +309,7 @@ AT_SETUP([OVS-DPDK - Ingress policing create delete vport port]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add ingress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -352,7 +352,7 @@ AT_SETUP([OVS-DPDK - Ingress policing no policing rate]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add ingress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -393,7 +393,7 @@ AT_SETUP([OVS-DPDK - Ingress policing no policing burst]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add ingress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -465,7 +465,7 @@ AT_SETUP([OVS-DPDK - QoS create delete vport port]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add egress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -506,7 +506,7 @@ AT_SETUP([OVS-DPDK - QoS no cir]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add egress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -541,7 +541,7 @@ AT_SETUP([OVS-DPDK - QoS no cbs]) + AT_KEYWORDS([dpdk]) + + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Add userspace bridge and attach it to OVS and add egress policer + AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev]) +@@ -661,7 +661,7 @@ AT_KEYWORDS([dpdk]) + + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -717,7 +717,7 @@ AT_KEYWORDS([dpdk]) + + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -856,7 +856,7 @@ AT_KEYWORDS([dpdk]) + + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -908,7 +908,7 @@ AT_KEYWORDS([dpdk]) + + AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + + dnl Find number of sockets + AT_CHECK([lscpu], [], [stdout]) +@@ -963,7 +963,7 @@ dnl MFEX Autovalidator + AT_SETUP([OVS-DPDK - MFEX Autovalidator]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + AT_CHECK([ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev]) + AT_SKIP_IF([! ovs-appctl dpif-netdev/miniflow-parser-get | sed 1,4d | grep "True"], [], [dnl + ]) +@@ -996,7 +996,7 @@ dnl MFEX Autovalidator Fuzzy + AT_SETUP([OVS-DPDK - MFEX Autovalidator Fuzzy]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + AT_CHECK([ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev]) + AT_SKIP_IF([! ovs-appctl dpif-netdev/miniflow-parser-get | sed 1,4d | grep "True"], [], [dnl + ]) +@@ -1032,7 +1032,7 @@ AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() + AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], []) + AT_CHECK([$PYTHON3 $srcdir/mfex_fuzzy.py test_traffic.pcap 1], [], [stdout]) +-OVS_DPDK_START() ++OVS_DPDK_START([--no-pci]) + AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0x1]) + dnl Add userspace bridge and attach it to OVS + AT_CHECK([ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev]) +@@ -1153,7 +1153,7 @@ AT_SETUP([OVS-DPDK - user configured mempool]) + AT_KEYWORDS([dpdk]) + OVS_DPDK_PRE_CHECK() + OVS_DPDK_START_OVSDB() +-OVS_DPDK_START_VSWITCHD() ++OVS_DPDK_START_VSWITCHD([--no-pci]) + + AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:shared-mempool-config=8000,6000,1500]) + AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true]) diff --git a/tests/system-interface.at b/tests/system-interface.at index 784bada12..3bf339582 100644 --- a/tests/system-interface.at @@ -3036,6 +4039,46 @@ index 784bada12..3bf339582 100644 + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP +diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at +index 11920e60b..1f9950f83 100644 +--- a/tests/system-kmod-macros.at ++++ b/tests/system-kmod-macros.at +@@ -224,3 +224,13 @@ m4_define([VSCTL_ADD_DATAPATH_TABLE], + # or necessary for the userspace datapath as it is checking for a kernel + # specific regression. + m4_define([CHECK_L3L4_CONNTRACK_REASM]) ++ ++# OVS_CHECK_BAREUDP() ++# ++# The feature needs to be enabled in the kernel configuration (CONFIG_BAREUDP) ++# to work. ++m4_define([OVS_CHECK_BAREUDP], ++[ ++ AT_SKIP_IF([! ip link add dev ovs_bareudp0 type bareudp dstport 6635 ethertype mpls_uc 2>&1 >/dev/null]) ++ AT_CHECK([ip link del dev ovs_bareudp0]) ++]) +diff --git a/tests/system-layer3-tunnels.at b/tests/system-layer3-tunnels.at +index c37852b21..81123f730 100644 +--- a/tests/system-layer3-tunnels.at ++++ b/tests/system-layer3-tunnels.at +@@ -154,7 +154,7 @@ OVS_VSWITCHD_STOP + AT_CLEANUP + + AT_SETUP([layer3 - ping over MPLS Bareudp]) +-OVS_CHECK_MIN_KERNEL(5, 7) ++OVS_CHECK_BAREUDP() + OVS_TRAFFIC_VSWITCHD_START([_ADD_BR([br1])]) + ADD_NAMESPACES(at_ns0, at_ns1) + +@@ -202,7 +202,7 @@ OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + + AT_SETUP([layer3 - ping over Bareudp]) +-OVS_CHECK_MIN_KERNEL(5, 7) ++OVS_CHECK_BAREUDP() + OVS_TRAFFIC_VSWITCHD_START([_ADD_BR([br1])]) + ADD_NAMESPACES(at_ns0, at_ns1) + diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at index d36da0580..8dd3bdf88 100644 --- a/tests/system-offloads-traffic.at @@ -3241,6 +4284,22 @@ index 221d96aef..6678911b4 100644 OVS_WAIT_UNTIL([grep "listening" tcpdump1_err]) dnl Send UDP client->server +diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at +index b34a84775..40210f7fa 100644 +--- a/tests/system-userspace-macros.at ++++ b/tests/system-userspace-macros.at +@@ -325,3 +325,11 @@ m4_define([CHECK_L3L4_CONNTRACK_REASM], + [ + AT_SKIP_IF([:]) + ]) ++ ++# OVS_CHECK_BAREUDP() ++# ++# The userspace datapath does not support bareudp tunnels. ++m4_define([OVS_CHECK_BAREUDP], ++[ ++ AT_SKIP_IF([:]) ++]) diff --git a/tests/testsuite.at b/tests/testsuite.at index cf4e3eadf..9d77a9f51 100644 --- a/tests/testsuite.at @@ -3250,6 +4309,24 @@ index cf4e3eadf..9d77a9f51 100644 m4_include([tests/drop-stats.at]) m4_include([tests/pytest.at]) +m4_include([tests/learning-switch.at]) +diff --git a/utilities/ovs-appctl-bashcomp.bash b/utilities/ovs-appctl-bashcomp.bash +index 4384be8ae..0a9af1a18 100644 +--- a/utilities/ovs-appctl-bashcomp.bash ++++ b/utilities/ovs-appctl-bashcomp.bash +@@ -223,6 +223,13 @@ printf_stderr() { + # The code below is taken from Peter Amidon. His change makes it more + # robust. + extract_bash_prompt() { ++ # On Bash 4.4+ just use the @P expansion ++ if ((BASH_VERSINFO[0] > 4 || ++ (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4))); then ++ _BASH_PROMPT="${PS1@P}" ++ return ++ fi ++ + local myPS1 v + + myPS1="$(sed 's/Begin prompt/\\Begin prompt/; s/End prompt/\\End prompt/' <<< "$PS1")" diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index eabec18a3..3ce4e82ec 100644 --- a/utilities/ovs-ofctl.c @@ -3287,6 +4364,24 @@ index a49ec9f94..420c11eb8 100755 if pipes.poll() is None: pipes.terminate() +diff --git a/utilities/ovs-vsctl-bashcomp.bash b/utilities/ovs-vsctl-bashcomp.bash +index fc8245bfb..c5ad24fb7 100644 +--- a/utilities/ovs-vsctl-bashcomp.bash ++++ b/utilities/ovs-vsctl-bashcomp.bash +@@ -413,6 +413,13 @@ _ovs_vsctl_get_PS1 () { + return; + fi + ++ # On Bash 4.4+ just use the @P expansion ++ if ((BASH_VERSINFO[0] > 4 || ++ (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4))); then ++ printf '%s\n' "${PS1@P}" ++ return ++ fi ++ + # Original inspiration from + # http://stackoverflow.com/questions/10060500/bash-how-to-evaluate-ps1-ps2, + # but changed quite a lot to make it more robust. diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index bfb2adef1..0deca14b9 100644 --- a/vswitchd/bridge.c diff --git a/SOURCES/openvswitch-hugetlbfs.sysusers b/SOURCES/openvswitch-hugetlbfs.sysusers new file mode 100644 index 0000000..08b2fb1 --- /dev/null +++ b/SOURCES/openvswitch-hugetlbfs.sysusers @@ -0,0 +1,2 @@ +#Type Name ID GECOS Home directory Shell +m openvswitch hugetlbfs diff --git a/SOURCES/openvswitch.sysusers b/SOURCES/openvswitch.sysusers new file mode 100644 index 0000000..a8d06aa --- /dev/null +++ b/SOURCES/openvswitch.sysusers @@ -0,0 +1,2 @@ +#Type Name ID GECOS Home directory Shell +u openvswitch - "Open vSwitch Daemons" / /sbin/nologin diff --git a/SPECS/openvswitch3.1.spec b/SPECS/openvswitch3.1.spec index 8e28423..09b15f2 100644 --- a/SPECS/openvswitch3.1.spec +++ b/SPECS/openvswitch3.1.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 3.1.0 -Release: 24%{?dist} +Release: 27%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -80,6 +80,8 @@ Source: https://github.com/openvswitch/ovs/archive/%{commit}.tar.gz#/openvswitch %else Source: https://github.com/openvswitch/ovs/archive/v%{version}.tar.gz#/openvswitch-%{version}.tar.gz %endif +Source2: openvswitch.sysusers +Source3: openvswitch-hugetlbfs.sysusers Source10: https://fast.dpdk.org/rel/dpdk-%{dpdkver}.tar.xz %define docutilsver 0.12 @@ -133,7 +135,7 @@ BuildRequires: python-nose BuildRequires: gcc gcc-c++ make BuildRequires: autoconf automake libtool -BuildRequires: systemd-units openssl openssl-devel +BuildRequires: systemd-units systemd-rpm-macros openssl openssl-devel BuildRequires: python3-devel python3-setuptools BuildRequires: desktop-file-utils BuildRequires: groff-base graphviz @@ -171,10 +173,8 @@ Requires: openssl iproute module-init-tools #Requires: kernel >= 3.15.0-0 Requires: openvswitch-selinux-extra-policy -Requires(pre): shadow-utils +%{?sysusers_requires_compat} Requires(post): /bin/sed -Requires(post): /usr/sbin/usermod -Requires(post): /usr/sbin/groupadd Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -446,6 +446,11 @@ install -d -m 0755 $RPM_BUILD_ROOT%{_rundir}/openvswitch install -d -m 0750 $RPM_BUILD_ROOT%{_localstatedir}/log/openvswitch install -d -m 0755 $RPM_BUILD_ROOT%{_sysconfdir}/openvswitch +install -p -D -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysusersdir}/openvswitch.conf +%ifarch %{dpdkarches} +install -p -D -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysusersdir}/openvswitch-hugetlbfs.conf +%endif + install -p -D -m 0644 rhel/usr_lib_udev_rules.d_91-vfio.rules \ $RPM_BUILD_ROOT%{_udevrulesdir}/91-vfio.rules @@ -578,16 +583,10 @@ rm -rf $RPM_BUILD_ROOT %endif %pre -getent group openvswitch >/dev/null || groupadd -r openvswitch -getent passwd openvswitch >/dev/null || \ - useradd -r -g openvswitch -d / -s /sbin/nologin \ - -c "Open vSwitch Daemons" openvswitch - +%sysusers_create_compat %{SOURCE2} %ifarch %{dpdkarches} - getent group hugetlbfs >/dev/null || groupadd hugetlbfs - usermod -a -G hugetlbfs openvswitch +%sysusers_create_compat %{SOURCE3} %endif -exit 0 %post if [ $1 -eq 1 ]; then @@ -743,6 +742,10 @@ exit 0 %{_sysconfdir}/sysconfig/network-scripts/ifup-ovs %{_sysconfdir}/sysconfig/network-scripts/ifdown-ovs %endif +%{_sysusersdir}/openvswitch.conf +%ifarch %{dpdkarches} +%{_sysusersdir}/openvswitch-hugetlbfs.conf +%endif %if %{with ipsec} %files ipsec @@ -751,6 +754,31 @@ exit 0 %endif %changelog +* Wed May 31 2023 Timothy Redaelli - 3.1.0-27 +- Be sure SYSUSERSFILES are copied to dist-git [RH git: 59999cf89f] + + +* Tue May 30 2023 Open vSwitch CI - 3.1.0-26 +- Merging upstream branch-3.1 [RH git: 65b407d97b] + Commit list: + faddfa21df utilities/bashcomp: Fix PS1 generation on new bash. (#2170344) + 33db42a34b netdev-offload-dpdk: Fix crash in debug log. + 55535451bb stream-ssl: Disable alerts on unexpected EOF. + e3b84fd4ab tests: layer3-tunnels: Skip bareudp tests if not supported by kernel. + e913394054 ovs-fields: Modify the width of tpa and spa. + 23d77ba105 netdev-vport: RCU-fy tunnel config. + 0f303e4a7f smap: Make argument of smap_add_ipv6 constant. + 467b891f73 netdev-vport: Fix unsafe handling of GRE sequence number. + ea20146882 tests: dpdk: Pass `--no-pci` to tests that do not use physical ports. + + +* Fri May 26 2023 Timothy Redaelli - 3.1.0-25 +- redhat: Use sysusers instead of useradd/groupadd directly [RH git: 4772a9b0e3] (#2193168) + Reported-at: https://bugzilla.redhat.com/2193168 + Reported-by: Dan Williams + Signed-off-by: Timothy Redaelli + + * Tue May 16 2023 Open vSwitch CI - 3.1.0-24 - Merging upstream branch-3.1 [RH git: 63d9d4a1d7] Commit list: