From ff7ec8b98f7fc388724207ad63c73ad229e5e36c Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Dec 06 2021 21:07:15 +0000 Subject: Import openvswitch2.15-2.15.0-54 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.15.0.patch b/SOURCES/openvswitch-2.15.0.patch index 6c82777..69cd21d 100644 --- a/SOURCES/openvswitch-2.15.0.patch +++ b/SOURCES/openvswitch-2.15.0.patch @@ -97,7 +97,7 @@ index ea3475f356..2a590b3a79 100644 else install-man-rst: diff --git a/Documentation/faq/releases.rst b/Documentation/faq/releases.rst -index 6a5e4141f1..3bc34c892f 100644 +index 6a5e4141f1..0fd1c2c398 100644 --- a/Documentation/faq/releases.rst +++ b/Documentation/faq/releases.rst @@ -204,9 +204,9 @@ Q: What DPDK version does each Open vSwitch release work with? @@ -107,14 +107,14 @@ index 6a5e4141f1..3bc34c892f 100644 - 2.13.x 19.11.2 - 2.14.x 19.11.2 - 2.15.x 20.11.0 -+ 2.13.x 19.11.8 -+ 2.14.x 19.11.8 ++ 2.13.x 19.11.10 ++ 2.14.x 19.11.10 + 2.15.x 20.11.1 ============ ======== Q: Are all the DPDK releases that OVS versions work with maintained? diff --git a/Documentation/intro/install/dpdk.rst b/Documentation/intro/install/dpdk.rst -index 3a24e54f97..612f2fdbc3 100644 +index 3a24e54f97..20c148f5eb 100644 --- a/Documentation/intro/install/dpdk.rst +++ b/Documentation/intro/install/dpdk.rst @@ -42,7 +42,7 @@ Build requirements @@ -139,6 +139,15 @@ index 3a24e54f97..612f2fdbc3 100644 $ cd $DPDK_DIR #. Configure and install DPDK using Meson +@@ -219,7 +219,7 @@ To verify hugepage configuration:: + + Mount the hugepages, if not already mounted by default:: + +- $ mount -t hugetlbfs none /dev/hugepages`` ++ $ mount -t hugetlbfs none /dev/hugepages + + .. note:: + diff --git a/Documentation/topics/dpdk/pmd.rst b/Documentation/topics/dpdk/pmd.rst index caa7d97bef..e481e79414 100644 --- a/Documentation/topics/dpdk/pmd.rst @@ -19515,6 +19524,37 @@ index 6f7b610a99..fd0127ed17 100644 dst->length = source->length; dst->allocated = dst->length; dst->string = xmalloc(dst->allocated + 1); +diff --git a/lib/flow.c b/lib/flow.c +index 729d59b1b3..910e52ad96 100644 +--- a/lib/flow.c ++++ b/lib/flow.c +@@ -970,14 +970,18 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) + if (OVS_LIKELY(nw_proto == IPPROTO_TCP)) { + if (OVS_LIKELY(size >= TCP_HEADER_LEN)) { + const struct tcp_header *tcp = data; +- +- miniflow_push_be32(mf, arp_tha.ea[2], 0); +- miniflow_push_be32(mf, tcp_flags, +- TCP_FLAGS_BE32(tcp->tcp_ctl)); +- miniflow_push_be16(mf, tp_src, tcp->tcp_src); +- miniflow_push_be16(mf, tp_dst, tcp->tcp_dst); +- miniflow_push_be16(mf, ct_tp_src, ct_tp_src); +- miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst); ++ size_t tcp_hdr_len = TCP_OFFSET(tcp->tcp_ctl) * 4; ++ ++ if (OVS_LIKELY(tcp_hdr_len >= TCP_HEADER_LEN) ++ && OVS_LIKELY(size >= tcp_hdr_len)) { ++ miniflow_push_be32(mf, arp_tha.ea[2], 0); ++ miniflow_push_be32(mf, tcp_flags, ++ TCP_FLAGS_BE32(tcp->tcp_ctl)); ++ miniflow_push_be16(mf, tp_src, tcp->tcp_src); ++ miniflow_push_be16(mf, tp_dst, tcp->tcp_dst); ++ miniflow_push_be16(mf, ct_tp_src, ct_tp_src); ++ miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst); ++ } + } + } else if (OVS_LIKELY(nw_proto == IPPROTO_UDP)) { + if (OVS_LIKELY(size >= UDP_HEADER_LEN)) { diff --git a/lib/ipf.c b/lib/ipf.c index c20bcc0b33..009f5d1e9b 100644 --- a/lib/ipf.c @@ -21365,11 +21405,59 @@ index b41c3d82ad..191cfcb0df 100644 /* Stores the various features which the corresponding backer supports. */ +diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h +index 9ad2b71d23..3cb1a3bbb6 100644 +--- a/ofproto/ofproto-provider.h ++++ b/ofproto/ofproto-provider.h +@@ -66,6 +66,7 @@ struct bfd_cfg; + struct meter; + struct ofoperation; + struct ofproto_packet_out; ++struct rule_collection; + struct smap; + + extern struct ovs_mutex ofproto_mutex; +@@ -115,6 +116,9 @@ struct ofproto { + /* List of expirable flows, in all flow tables. */ + struct ovs_list expirable OVS_GUARDED_BY(ofproto_mutex); + ++ /* List of flows to remove from flow tables. */ ++ struct rule_collection *to_remove OVS_GUARDED_BY(ofproto_mutex); ++ + /* Meter table. */ + struct ofputil_meter_features meter_features; + struct hmap meters; /* uint32_t indexed 'struct meter *'. */ +@@ -1962,6 +1966,7 @@ struct ofproto_flow_mod { + bool modify_may_add_flow; + bool modify_keep_counts; + enum nx_flow_update_event event; ++ uint8_t table_id; + + /* These are only used during commit execution. + * ofproto_flow_mod_uninit() does NOT clean these up. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c -index b91517cd25..80ec2d9ac9 100644 +index b91517cd25..947d5967c8 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c -@@ -968,7 +968,7 @@ ofproto_get_datapath_cap(const char *datapath_type, struct smap *dp_cap) +@@ -213,6 +213,8 @@ static void ofproto_rule_insert__(struct ofproto *, struct rule *) + OVS_REQUIRES(ofproto_mutex); + static void ofproto_rule_remove__(struct ofproto *, struct rule *) + OVS_REQUIRES(ofproto_mutex); ++static void remove_rules_postponed(struct rule_collection *) ++ OVS_REQUIRES(ofproto_mutex); + + /* The source of an OpenFlow request. + * +@@ -530,6 +532,8 @@ ofproto_create(const char *datapath_name, const char *datapath_type, + hindex_init(&ofproto->cookies); + hmap_init(&ofproto->learned_cookies); + ovs_list_init(&ofproto->expirable); ++ ofproto->to_remove = xzalloc(sizeof *ofproto->to_remove); ++ rule_collection_init(ofproto->to_remove); + ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name); + ofproto->min_mtu = INT_MAX; + cmap_init(&ofproto->groups); +@@ -968,7 +972,7 @@ ofproto_get_datapath_cap(const char *datapath_type, struct smap *dp_cap) datapath_type = ofproto_normalize_type(datapath_type); const struct ofproto_class *class = ofproto_class_find__(datapath_type); @@ -21378,7 +21466,7 @@ index b91517cd25..80ec2d9ac9 100644 class->get_datapath_cap(datapath_type, dp_cap); } } -@@ -981,7 +981,7 @@ ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, +@@ -981,7 +985,7 @@ ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, datapath_type = ofproto_normalize_type(datapath_type); const struct ofproto_class *class = ofproto_class_find__(datapath_type); @@ -21387,7 +21475,7 @@ index b91517cd25..80ec2d9ac9 100644 class->ct_set_zone_timeout_policy(datapath_type, zone_id, timeout_policy); } -@@ -993,7 +993,7 @@ ofproto_ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) +@@ -993,7 +997,7 @@ ofproto_ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) datapath_type = ofproto_normalize_type(datapath_type); const struct ofproto_class *class = ofproto_class_find__(datapath_type); @@ -21396,6 +21484,172 @@ index b91517cd25..80ec2d9ac9 100644 class->ct_del_zone_timeout_policy(datapath_type, zone_id); } +@@ -1643,6 +1647,7 @@ ofproto_flush__(struct ofproto *ofproto, bool del) + } + ofproto_group_delete_all__(ofproto); + meter_delete_all(ofproto); ++ remove_rules_postponed(ofproto->to_remove); + /* XXX: Concurrent handler threads may insert new learned flows based on + * learn actions of the now deleted flows right after we release + * 'ofproto_mutex'. */ +@@ -1694,6 +1699,11 @@ ofproto_destroy__(struct ofproto *ofproto) + ovs_assert(hmap_is_empty(&ofproto->learned_cookies)); + hmap_destroy(&ofproto->learned_cookies); + ++ ovs_mutex_lock(&ofproto_mutex); ++ rule_collection_destroy(ofproto->to_remove); ++ free(ofproto->to_remove); ++ ovs_mutex_unlock(&ofproto_mutex); ++ + ofproto->ofproto_class->dealloc(ofproto); + } + +@@ -1890,6 +1900,9 @@ ofproto_run(struct ofproto *p) + + connmgr_run(p->connmgr, handle_openflow); + ++ ovs_mutex_lock(&ofproto_mutex); ++ remove_rules_postponed(p->to_remove); ++ ovs_mutex_unlock(&ofproto_mutex); + return error; + } + +@@ -4449,6 +4462,20 @@ rule_criteria_destroy(struct rule_criteria *criteria) + criteria->version = OVS_VERSION_NOT_REMOVED; /* Mark as destroyed. */ + } + ++/* Adds rules to the 'to_remove' collection, so they can be destroyed ++ * later all together. Destroys 'rules'. */ ++static void ++rules_mark_for_removal(struct ofproto *ofproto, struct rule_collection *rules) ++ OVS_REQUIRES(ofproto_mutex) ++{ ++ struct rule *rule; ++ ++ RULE_COLLECTION_FOR_EACH (rule, rules) { ++ rule_collection_add(ofproto->to_remove, rule); ++ } ++ rule_collection_destroy(rules); ++} ++ + /* Schedules postponed removal of rules, destroys 'rules'. */ + static void + remove_rules_postponed(struct rule_collection *rules) +@@ -5845,7 +5872,7 @@ modify_flows_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm, + } + } + learned_cookies_flush(ofproto, &dead_cookies); +- remove_rules_postponed(old_rules); ++ rules_mark_for_removal(ofproto, old_rules); + } + + return error; +@@ -5953,7 +5980,7 @@ delete_flows_finish__(struct ofproto *ofproto, + learned_cookies_dec(ofproto, rule_get_actions(rule), + &dead_cookies); + } +- remove_rules_postponed(rules); ++ rules_mark_for_removal(ofproto, rules); + + learned_cookies_flush(ofproto, &dead_cookies); + } +@@ -7979,6 +8006,7 @@ ofproto_flow_mod_init(struct ofproto *ofproto, struct ofproto_flow_mod *ofm, + ofm->criteria.version = OVS_VERSION_NOT_REMOVED; + ofm->conjs = NULL; + ofm->n_conjs = 0; ++ ofm->table_id = fm->table_id; + + bool check_buffer_id = false; + +@@ -8116,6 +8144,33 @@ ofproto_flow_mod_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm, + return error; + } + ++static void ++ofproto_table_classifier_defer(struct ofproto *ofproto, ++ const struct ofproto_flow_mod *ofm) ++{ ++ if (check_table_id(ofproto, ofm->table_id)) { ++ if (ofm->table_id == OFPTT_ALL) { ++ struct oftable *table; ++ ++ OFPROTO_FOR_EACH_TABLE (table, ofproto) { ++ classifier_defer(&table->cls); ++ } ++ } else { ++ classifier_defer(&ofproto->tables[ofm->table_id].cls); ++ } ++ } ++} ++ ++static void ++ofproto_publish_classifiers(struct ofproto *ofproto) ++{ ++ struct oftable *table; ++ ++ OFPROTO_FOR_EACH_TABLE (table, ofproto) { ++ classifier_publish(&table->cls); ++ } ++} ++ + /* Commit phases (all while locking ofproto_mutex): + * + * 1. Begin: Gather resources and make changes visible in the next version. +@@ -8177,6 +8232,10 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + /* Store the version in which the changes should take + * effect. */ + be->ofm.version = version; ++ /* Publishing of the classifier update for every flow ++ * modification in a bundle separately is expensive in ++ * CPU time and memory. Deferring. */ ++ ofproto_table_classifier_defer(ofproto, &be->ofm); + error = ofproto_flow_mod_start(ofproto, &be->ofm); + } else if (be->type == OFPTYPE_GROUP_MOD) { + /* Store the version in which the changes should take +@@ -8185,6 +8244,9 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + error = ofproto_group_mod_start(ofproto, &be->ogm); + } else if (be->type == OFPTYPE_PACKET_OUT) { + be->opo.version = version; ++ /* Need to use current version of flows for packet-out, ++ * so publishing all classifiers now. */ ++ ofproto_publish_classifiers(ofproto); + error = ofproto_packet_out_start(ofproto, &be->opo); + } else { + OVS_NOT_REACHED(); +@@ -8195,6 +8257,9 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + } + } + ++ /* Publishing all changes made to classifiers. */ ++ ofproto_publish_classifiers(ofproto); ++ + if (error) { + /* Send error referring to the original message. */ + ofconn_send_error(ofconn, be->msg, error); +@@ -8203,14 +8268,23 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + /* 2. Revert. Undo all the changes made above. */ + LIST_FOR_EACH_REVERSE_CONTINUE(be, node, &bundle->msg_list) { + if (be->type == OFPTYPE_FLOW_MOD) { ++ /* Publishing of the classifier update for every flow ++ * modification in a bundle separately is expensive in ++ * CPU time and memory. Deferring. */ ++ ofproto_table_classifier_defer(ofproto, &be->ofm); + ofproto_flow_mod_revert(ofproto, &be->ofm); + } else if (be->type == OFPTYPE_GROUP_MOD) { + ofproto_group_mod_revert(ofproto, &be->ogm); + } else if (be->type == OFPTYPE_PACKET_OUT) { ++ /* Need to use current version of flows for packet-out, ++ * so publishing all classifiers now. */ ++ ofproto_publish_classifiers(ofproto); + ofproto_packet_out_revert(ofproto, &be->opo); + } + /* Nothing needs to be reverted for a port mod. */ + } ++ /* Publishing all changes made to classifiers. */ ++ ofproto_publish_classifiers(ofproto); + } else { + /* 4. Finish. */ + LIST_FOR_EACH (be, node, &bundle->msg_list) { diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 72756eb1f2..ba28e36d78 100644 --- a/ovsdb/ovsdb-client.c @@ -22257,6 +22511,38 @@ index 2862a3c9b9..16402ebae2 100644 +OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d +/failed to put/d"]) +AT_CLEANUP +diff --git a/tests/flowgen.py b/tests/flowgen.py +index 7ef32d13cb..cb0e9df388 100755 +--- a/tests/flowgen.py ++++ b/tests/flowgen.py +@@ -135,7 +135,7 @@ def output(attrs): + 12893) # urgent pointer + if attrs['TP_PROTO'] == 'TCP+options': + tcp = (tcp[:12] +- + struct.pack('H', (6 << 12) | 0x02 | 0x10) ++ + struct.pack('>H', (6 << 12) | 0x02 | 0x10) + + tcp[14:]) + tcp += struct.pack('>BBH', 2, 4, 1975) # MSS option + tcp += b'payload' +@@ -166,15 +166,15 @@ def output(attrs): + ip = ip[:2] + struct.pack('>H', len(ip)) + ip[4:] + packet += ip + if attrs['DL_HEADER'].startswith('802.2'): +- packet_len = len(packet) ++ packet_len = len(packet) - 14 + if flow['DL_VLAN'] != 0xffff: + packet_len -= 4 + packet = (packet[:len_ofs] + + struct.pack('>H', packet_len) + + packet[len_ofs + 2:]) + +- print(' '.join(['%s=%s' for k, v in attrs.items()])) +- print(' '.join(['%s=%s' for k, v in flow.items()])) ++ print(' '.join(['%s=%s' % (k, v) for k, v in attrs.items()])) ++ print(' '.join(['%s=%s' % (k, v) for k, v in flow.items()])) + print() + + flows.write(struct.pack('>LH', diff --git a/tests/fuzz-regression-list.at b/tests/fuzz-regression-list.at index e3173fb88f..2347c690ef 100644 --- a/tests/fuzz-regression-list.at @@ -22296,7 +22582,7 @@ index 199db8ed0f..59093c03c9 100644 bad_action 'fin_timeout(foo=bar)' "invalid key 'foo' in 'fin_timeout' argument" diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index 31064ed95e..19c85d43a3 100644 +index 31064ed95e..4d710da222 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -342,6 +342,22 @@ AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3]) @@ -22431,7 +22717,62 @@ index 31064ed95e..19c85d43a3 100644 # Makes sure recirculation does not change the way packet is handled. AT_SETUP([ofproto-dpif - balance-tcp bonding, different recirc flow ]) OVS_VSWITCHD_START( -@@ -9520,6 +9596,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): +@@ -4786,6 +4862,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr + OVS_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([ofproto-dpif - handling of malformed TCP packets]) ++OVS_VSWITCHD_START ++add_of_ports br0 1 90 ++ ++dnl drop packet has tcp port 0-f but allow other tcp packets ++AT_DATA([flows.txt], [dnl ++priority=75 tcp tp_dst=0/0xfff0 actions=drop ++priority=50 tcp actions=output:1 ++]) ++AT_CHECK([ovs-ofctl replace-flows br0 flows.txt]) ++ ++dnl good tcp pkt, tcp(sport=100,dpor=16) ++pkt1="be95df40fb57fa163e5ee3570800450000280001000040063e940a0a0a0a141414140064001000000000000000005002200053330000" ++ ++dnl malformed tcp pkt(tcp_hdr < 20 byte), tcp(sport=100,dport=16,dataofs=1) ++pkt2="be95df40fb57fa163e5ee3570800450000280001000040063e940a0a0a0a141414140064001000000000000000001002200093330000" ++ ++dnl malformed tcp pkt(tcp_hdr > pkt_len), tcp(sport=100,dport=16,dataofs=15) ++pkt3="be95df40fb57fa163e5ee3570800450000280001000040063e940a0a0a0a14141414006400100000000000000000f002200093330000" ++ ++AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ++ ++AT_CHECK([ovs-appctl netdev-dummy/receive p90 "$pkt1"], [0], [stdout]) ++dnl for good tcp pkt, ovs can extract the tp_dst=16 ++AT_CHECK([ovs-appctl dpctl/dump-flows filter=in_port\(90\),tcp], [0], [dnl ++flow-dump from the main thread: ++recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,frag=no),tcp(dst=16/0xfff0), packets:0, bytes:0, used:never, actions:1 ++]) ++ ++AT_CHECK([ovs-appctl revalidator/purge], [0], [stdout]) ++AT_CHECK([ovs-appctl netdev-dummy/receive p90 "$pkt2"], [0], [stdout]) ++dnl for malformed tcp pkt(tcp_hdr < 20 byte), ovs uses default value tp_dst=0 ++AT_CHECK([ovs-appctl dpctl/dump-flows filter=in_port\(90\),tcp], [0], [dnl ++flow-dump from the main thread: ++recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,frag=no),tcp(dst=0/0xfff0), packets:0, bytes:0, used:never, actions:drop ++]) ++ ++AT_CHECK([ovs-appctl revalidator/purge], [0], [stdout]) ++AT_CHECK([ovs-appctl netdev-dummy/receive p90 "$pkt3"], [0], [stdout]) ++dnl for malformed tcp pkt(tcp_hdr > pkt_len), ovs uses default value tp_dst=0 ++AT_CHECK([ovs-appctl dpctl/dump-flows filter=in_port\(90\),tcp], [0], [dnl ++flow-dump from the main thread: ++recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,frag=no),tcp(dst=0/0xfff0), packets:0, bytes:0, used:never, actions:drop ++]) ++ ++OVS_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_SETUP([ofproto-dpif - exit]) + OVS_VSWITCHD_START + add_of_ports br0 1 2 3 10 11 12 13 14 +@@ -9520,6 +9644,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): OVS_VSWITCHD_STOP AT_CLEANUP @@ -22458,7 +22799,7 @@ index 31064ed95e..19c85d43a3 100644 AT_SETUP([ofproto-dpif - ICMPv6]) OVS_VSWITCHD_START add_of_ports br0 1 -@@ -10842,6 +10938,31 @@ dnl +@@ -10842,6 +10986,31 @@ dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=2 (via action) data_len=106 (unbuffered) udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1 udp_csum:553 ]) @@ -22490,7 +22831,7 @@ index 31064ed95e..19c85d43a3 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -11204,6 +11325,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no +@@ -11204,6 +11373,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no Datapath actions: 4 ]) @@ -25102,6 +25443,29 @@ index 92d32acb3f..1ece06457c 100644 finally: if local_server is not None: local_server.terminate() +diff --git a/utilities/ovs-lib.in b/utilities/ovs-lib.in +index ab38ece458..799d228671 100644 +--- a/utilities/ovs-lib.in ++++ b/utilities/ovs-lib.in +@@ -513,13 +513,13 @@ join_cluster() { + LOCAL_ADDR="$3" + REMOTE_ADDR="$4" + +- if test ! -e "$DB_FILE"; then +- ovsdb_tool join-cluster "$DB_FILE" "$SCHEMA_NAME" "$LOCAL_ADDR" "$REMOTE_ADDR" +- elif ovsdb_tool db-is-standalone "$DB_FILE"; then +- # Backup standalone database and join cluster. ++ if test -e "$DB_FILE" && ovsdb_tool db-is-standalone "$DB_FILE"; then + backup_db || return 1 ++ rm $DB_FILE ++ fi ++ if test ! -e "$DB_FILE"; then + action "Joining $DB_FILE to cluster" \ +- ovsdb_tool join-cluster "$DB_FILE" "$SCHEMA_NAME" "$LOCAL_ADDR" ++ ovsdb_tool join-cluster "$DB_FILE" "$SCHEMA_NAME" "$LOCAL_ADDR" "$REMOTE_ADDR" + fi + } + diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 3601890f40..ede7f1e61a 100644 --- a/utilities/ovs-ofctl.c @@ -25203,6 +25567,22 @@ index dddbee4dfb..6b5f63399e 100755 sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) sys.exit(1) +diff --git a/utilities/ovs-save b/utilities/ovs-save +index 7d810cb40e..a02395be17 100755 +--- a/utilities/ovs-save ++++ b/utilities/ovs-save +@@ -149,7 +149,10 @@ save_flows () { + ovs-ofctl -O $ofp_version dump-flows --no-names --no-stats "$bridge" | \ + sed -e '/NXST_FLOW/d' \ + -e '/OFPST_FLOW/d' \ +- -e 's/\(idle\|hard\)_age=[^,]*,//g' > \ ++ -e 's/\(idle\|hard\)_age=[^,]*,//g' \ ++ -e 's/igmp_type/tp_src/g' \ ++ -e 's/igmp_code/tp_dst/g' \ ++ -e 's/igmp/ip,nw_proto=2/g' > \ + "$workdir/$bridge.flows.dump" + done + echo "rm -rf \"$workdir\"" diff --git a/utilities/ovs-vlan-test.in b/utilities/ovs-vlan-test.in index 154573a9b5..de3ae16862 100755 --- a/utilities/ovs-vlan-test.in diff --git a/SPECS/openvswitch2.15.spec b/SPECS/openvswitch2.15.spec index 697810e..908ca16 100644 --- a/SPECS/openvswitch2.15.spec +++ b/SPECS/openvswitch2.15.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.15.0 -Release: 53%{?dist} +Release: 54%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -699,6 +699,20 @@ exit 0 %endif %changelog +* Mon Dec 06 2021 Open vSwitch CI - 2.15.0-54 +- Merging upstream branch-2.15 [RH git: d4f13fd840] + Commit list: + 0590e88387 flow: Consider dataofs when parsing TCP packets. + 7266042d84 tests/flowgen: Fix packet data endianness. + d2e0632dbe ofproto: Fix resource usage explosion due to removal of large number of flows. + 0a7e66e37f ofproto: Fix resource usage explosion while processing bundled FLOW_MOD. + 68466efed9 tests/flowgen: Fix length field of 802.2 data link header. + 2a2185f9e6 ovs-lib: Backup and remove existing DB when joining cluster. + fcbc29c6f0 docs/dpdk: Fix install doc. + a5d97d4202 ovs-save: Save igmp flows in ofp_parse syntax. + 1cbd1f0f56 faq: Update OVS/DPDK version table for OVS 2.13/2.14. + + * Thu Nov 18 2021 Open vSwitch CI - 2.15.0-53 - Merging upstream branch-2.15 [RH git: 9221a2233d] Commit list: