diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index 9a3f7e0..7527867 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -81653,7 +81653,7 @@ index 45bb96b543..353d5cd3ed 100644 } diff --git a/lib/ipf.c b/lib/ipf.c -index 446e89d13c..9c83f1913a 100644 +index 446e89d13c..24325a638d 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -93,7 +93,6 @@ struct ipf_frag { @@ -81715,16 +81715,103 @@ index 446e89d13c..9c83f1913a 100644 dp_packet_batch_refill(pb, pkt, pb_idx); } ovs_mutex_unlock(&ipf->ipf_lock); -@@ -1153,7 +1148,7 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, +@@ -1153,59 +1148,64 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, /* Inner batch loop is constant time since batch size is <= * NETDEV_MAX_BURST. */ DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) { - if (pkt == rp->list->reass_execute_ctx) { + if (rp && pkt == rp->list->reass_execute_ctx) { ++ const struct ipf_frag *frag_0 = &rp->list->frag_list[0]; ++ void *l4_frag = dp_packet_l4(frag_0->pkt); ++ void *l4_reass = dp_packet_l4(pkt); ++ memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt)); ++ for (int i = 0; i <= rp->list->last_inuse_idx; i++) { - rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label; - rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark; -@@ -1206,6 +1201,7 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, +- rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label; +- rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark; +- rp->list->frag_list[i].pkt->md.ct_state = pkt->md.ct_state; +- rp->list->frag_list[i].pkt->md.ct_zone = pkt->md.ct_zone; +- rp->list->frag_list[i].pkt->md.ct_orig_tuple_ipv6 = ++ const struct ipf_frag *frag_i = &rp->list->frag_list[i]; ++ ++ frag_i->pkt->md.ct_label = pkt->md.ct_label; ++ frag_i->pkt->md.ct_mark = pkt->md.ct_mark; ++ frag_i->pkt->md.ct_state = pkt->md.ct_state; ++ frag_i->pkt->md.ct_zone = pkt->md.ct_zone; ++ frag_i->pkt->md.ct_orig_tuple_ipv6 = + pkt->md.ct_orig_tuple_ipv6; + if (pkt->md.ct_orig_tuple_ipv6) { +- rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv6 = ++ frag_i->pkt->md.ct_orig_tuple.ipv6 = + pkt->md.ct_orig_tuple.ipv6; + } else { +- rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv4 = ++ frag_i->pkt->md.ct_orig_tuple.ipv4 = + pkt->md.ct_orig_tuple.ipv4; + } +- } +- +- const struct ipf_frag *frag_0 = &rp->list->frag_list[0]; +- void *l4_frag = dp_packet_l4(frag_0->pkt); +- void *l4_reass = dp_packet_l4(pkt); +- memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt)); +- +- if (v6) { +- struct ovs_16aligned_ip6_hdr *l3_frag +- = dp_packet_l3(frag_0->pkt); +- struct ovs_16aligned_ip6_hdr *l3_reass = dp_packet_l3(pkt); +- l3_frag->ip6_src = l3_reass->ip6_src; +- l3_frag->ip6_dst = l3_reass->ip6_dst; +- } else { +- struct ip_header *l3_frag = dp_packet_l3(frag_0->pkt); +- struct ip_header *l3_reass = dp_packet_l3(pkt); +- if (!dp_packet_hwol_is_ipv4(frag_0->pkt)) { +- ovs_be32 reass_ip = +- get_16aligned_be32(&l3_reass->ip_src); +- ovs_be32 frag_ip = +- get_16aligned_be32(&l3_frag->ip_src); +- +- l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, +- frag_ip, reass_ip); +- reass_ip = get_16aligned_be32(&l3_reass->ip_dst); +- frag_ip = get_16aligned_be32(&l3_frag->ip_dst); +- l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, +- frag_ip, reass_ip); ++ if (v6) { ++ struct ovs_16aligned_ip6_hdr *l3_frag ++ = dp_packet_l3(frag_i->pkt); ++ struct ovs_16aligned_ip6_hdr *l3_reass ++ = dp_packet_l3(pkt); ++ l3_frag->ip6_src = l3_reass->ip6_src; ++ l3_frag->ip6_dst = l3_reass->ip6_dst; ++ } else { ++ struct ip_header *l3_frag = dp_packet_l3(frag_i->pkt); ++ struct ip_header *l3_reass = dp_packet_l3(pkt); ++ if (!dp_packet_hwol_is_ipv4(frag_i->pkt)) { ++ ovs_be32 reass_ip = ++ get_16aligned_be32(&l3_reass->ip_src); ++ ovs_be32 frag_ip = ++ get_16aligned_be32(&l3_frag->ip_src); ++ ++ l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, ++ frag_ip, ++ reass_ip); ++ reass_ip = get_16aligned_be32(&l3_reass->ip_dst); ++ frag_ip = get_16aligned_be32(&l3_frag->ip_dst); ++ l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, ++ frag_ip, ++ reass_ip); ++ } ++ ++ l3_frag->ip_src = l3_reass->ip_src; ++ l3_frag->ip_dst = l3_reass->ip_dst; + } +- +- l3_frag->ip_src = l3_reass->ip_src; +- l3_frag->ip_dst = l3_reass->ip_dst; + } + + ipf_completed_list_add(&ipf->frag_complete_list, rp->list); ipf_reassembled_list_remove(rp); dp_packet_delete(rp->pkt); free(rp); @@ -81732,7 +81819,7 @@ index 446e89d13c..9c83f1913a 100644 } else { dp_packet_batch_refill(pb, pkt, pb_idx); } -@@ -1337,9 +1333,7 @@ ipf_destroy(struct ipf *ipf) +@@ -1337,9 +1337,7 @@ ipf_destroy(struct ipf *ipf) while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) { struct dp_packet *pkt = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt; @@ -82360,7 +82447,7 @@ index 6187129c00..f080dec61f 100644 err = rte_vhost_driver_start(dev->vhost_id); diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c -index c6f3d27409..557c3f5e94 100644 +index c6f3d27409..216ea208a7 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -231,6 +231,14 @@ struct rtnl_link_stats64 { @@ -82378,6 +82465,22 @@ index c6f3d27409..557c3f5e94 100644 enum { VALID_IFINDEX = 1 << 0, VALID_ETHERADDR = 1 << 1, +@@ -621,6 +629,7 @@ netdev_linux_notify_sock(void) + if (!error) { + size_t i; + ++ nl_sock_listen_all_nsid(sock, true); + for (i = 0; i < ARRAY_SIZE(mcgroups); i++) { + error = nl_sock_join_mcgroup(sock, mcgroups[i]); + if (error) { +@@ -630,7 +639,6 @@ netdev_linux_notify_sock(void) + } + } + } +- nl_sock_listen_all_nsid(sock, true); + ovsthread_once_done(&once); + } + @@ -659,10 +667,6 @@ netdev_linux_update_lag(struct rtnetlink_change *change) { struct linux_lag_slave *lag; @@ -83128,7 +83231,7 @@ index 42d3335f0f..97320a4dba 100644 } else { a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]; diff --git a/lib/odp-util.c b/lib/odp-util.c -index 746d1e97d4..9701f1a763 100644 +index 746d1e97d4..57943df9ed 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -390,7 +390,8 @@ format_odp_push_nsh_action(struct ds *ds, @@ -83168,6 +83271,15 @@ index 746d1e97d4..9701f1a763 100644 goto out; } } +@@ -2891,7 +2898,7 @@ odp_nsh_key_from_attr__(const struct nlattr *attr, bool is_mask, + const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a); + has_md1 = true; + memcpy(nsh->context, md1->context, sizeof md1->context); +- if (len == 2 * sizeof(*md1)) { ++ if (nsh_mask && (len == 2 * sizeof *md1)) { + const struct ovs_nsh_key_md1 *md1_mask = md1 + 1; + memcpy(nsh_mask->context, md1_mask->context, + sizeof(*md1_mask)); @@ -3136,17 +3143,17 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key, if ((!tnl_type || !strcmp(tnl_type, "erspan") || !strcmp(tnl_type, "ip6erspan")) && @@ -83194,6 +83306,15 @@ index 746d1e97d4..9701f1a763 100644 } nl_msg_end_nested(a, tun_key_ofs); +@@ -4531,7 +4538,7 @@ odp_flow_format(const struct nlattr *key, size_t key_len, + } + ds_put_char(ds, ')'); + } +- if (!has_ethtype_key) { ++ if (!has_ethtype_key && mask) { + const struct nlattr *ma = nl_attr_find__(mask, mask_len, + OVS_KEY_ATTR_ETHERTYPE); + if (ma) { @@ -5428,13 +5435,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) do { \ len = 0; @@ -84556,6 +84677,18 @@ index 9f12ce3206..6ad6d3a54e 100644 const struct ovsdb_idl_row *ovsdb_idl_track_get_first( const struct ovsdb_idl *, const struct ovsdb_idl_table_class *); const struct ovsdb_idl_row *ovsdb_idl_track_get_next(const struct ovsdb_idl_row *); +diff --git a/lib/pcap-file.c b/lib/pcap-file.c +index f0cac8e0fa..7f5561f827 100644 +--- a/lib/pcap-file.c ++++ b/lib/pcap-file.c +@@ -89,6 +89,7 @@ ovs_pcap_open(const char *file_name, const char *mode) + : mode[0] == 'w' ? "writing" + : "appending"), + ovs_strerror(errno)); ++ free(p_file); + return NULL; + } + diff --git a/lib/pvector.c b/lib/pvector.c index aaeee92147..cc527fdc41 100644 --- a/lib/pvector.c @@ -89554,7 +89687,7 @@ index 0000000000..1714273e35 +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/system-traffic.at b/tests/system-traffic.at -index 4a39c929c2..2bd7ef71fe 100644 +index 4a39c929c2..620cd2512f 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -574,6 +574,60 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PI @@ -89671,7 +89804,54 @@ index 4a39c929c2..2bd7ef71fe 100644 AT_SETUP([conntrack - ICMP related]) AT_SKIP_IF([test $HAVE_NC = no]) CHECK_CONNTRACK() -@@ -4379,6 +4472,52 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src= +@@ -3220,6 +3313,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([conntrack - IPv4 Fragmentation + NAT]) ++AT_SKIP_IF([test $HAVE_TCPDUMP = no]) ++CHECK_CONNTRACK() ++ ++OVS_TRAFFIC_VSWITCHD_START( ++ [set-fail-mode br0 secure -- ]) ++ ++ADD_NAMESPACES(at_ns0, at_ns1) ++ ++ADD_VETH(p0, at_ns0, br0, "10.2.1.1/24") ++ADD_VETH(p1, at_ns1, br0, "10.2.1.2/24") ++ ++dnl Create a dummy route for NAT ++NS_CHECK_EXEC([at_ns1], [ip addr add 10.1.1.2/32 dev lo]) ++NS_CHECK_EXEC([at_ns0], [ip route add 10.1.1.0/24 via 10.2.1.2]) ++NS_CHECK_EXEC([at_ns1], [ip route add 10.1.1.0/24 via 10.2.1.1]) ++ ++dnl Solely for debugging when things go wrong ++NS_EXEC([at_ns0], [tcpdump -l -n -xx -U -i p0 -w p0.pcap >tcpdump.out 2>/dev/null &]) ++NS_EXEC([at_ns1], [tcpdump -l -n -xx -U -i p1 -w p1.pcap >tcpdump.out 2>/dev/null &]) ++ ++AT_DATA([flows.txt], [dnl ++table=0,arp,actions=normal ++table=0,ct_state=-trk,ip,in_port=ovs-p0, actions=ct(table=1, nat) ++table=0,ct_state=-trk,ip,in_port=ovs-p1, actions=ct(table=1, nat) ++table=1,ct_state=+trk+new,ip,in_port=ovs-p0, actions=ct(commit, nat(src=10.1.1.1)),ovs-p1 ++table=1,ct_state=+trk+est,ip,in_port=ovs-p0, actions=ovs-p1 ++table=1,ct_state=+trk+est,ip,in_port=ovs-p1, actions=ovs-p0 ++]) ++ ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++ ++dnl Check connectivity ++NS_CHECK_EXEC([at_ns0], [ping -c 1 10.1.1.2 -M dont -s 4500 | FORMAT_PING], [0], [dnl ++1 packets transmitted, 1 received, 0% packet loss, time 0ms ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_SETUP([conntrack - resubmit to ct multiple times]) + CHECK_CONNTRACK() + +@@ -4379,6 +4512,52 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src= OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP @@ -89724,7 +89904,7 @@ index 4a39c929c2..2bd7ef71fe 100644 AT_SETUP([conntrack - simple DNAT]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() -@@ -4434,6 +4573,41 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src= +@@ -4434,6 +4613,41 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src= OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP @@ -89766,7 +89946,7 @@ index 4a39c929c2..2bd7ef71fe 100644 AT_SETUP([conntrack - more complex DNAT]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() -@@ -5873,6 +6047,50 @@ ovs-appctl dpif/dump-flows br0 +@@ -5873,6 +6087,50 @@ ovs-appctl dpif/dump-flows br0 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index 0d38998..5e1c8b9 100644 --- a/SPECS/openvswitch2.13.spec +++ b/SPECS/openvswitch2.13.spec @@ -59,7 +59,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.13.0 -Release: 124%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 125%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -710,6 +710,16 @@ exit 0 %endif %changelog +* Thu Sep 16 2021 Open vSwitch CI - 2.13.0-125 +- Merging upstream branch-2.13 [RH git: 215f08bbd8] + Commit list: + a56a8008eb netdev-linux: Fix a null pointer dereference in netdev_linux_notify_sock(). + 186ff2a5b2 pcap-file: Fix memory leak in ovs_pcap_open(). + b9b144b8d8 odp-util: Fix a null pointer dereference in odp_flow_format(). + fea883d3bd odp-util: Fix a null pointer dereference in odp_nsh_key_from_attr__(). + ef6d151b04 ipf: Fix only nat the first fragment in the reass process. + + * Wed Sep 08 2021 Open vSwitch CI - 2.13.0-124 - Merging upstream branch-2.13 [RH git: b3c7c50935] Commit list: