diff --git a/SOURCES/openvswitch-2.11.3.patch b/SOURCES/openvswitch-2.11.3.patch index 3d9ccbc..9872a3d 100644 --- a/SOURCES/openvswitch-2.11.3.patch +++ b/SOURCES/openvswitch-2.11.3.patch @@ -17362,7 +17362,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..311204fa8a 100644 +index d41c9369f2..0d85186e2d 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -131,6 +131,8 @@ odp_action_len(uint16_t type) @@ -17430,7 +17430,34 @@ index d41c9369f2..311204fa8a 100644 case OVS_ACTION_ATTR_UNSPEC: case __OVS_ACTION_ATTR_MAX: default: -@@ -2397,6 +2441,52 @@ parse_odp_action(const char *s, const struct simap *port_names, +@@ -1380,14 +1424,20 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) + int n1 = -1; + if (ovs_scan(&s[n], ",tunnel_out_port=%"SCNi32")%n", + &tunnel_out_port, &n1)) { +- odp_put_userspace_action(pid, user_data, user_data_size, +- tunnel_out_port, include_actions, actions); +- res = n + n1; ++ res = odp_put_userspace_action(pid, user_data, user_data_size, ++ tunnel_out_port, include_actions, ++ actions, NULL); ++ if (!res) { ++ res = n + n1; ++ } + goto out; + } else if (s[n] == ')') { +- odp_put_userspace_action(pid, user_data, user_data_size, +- ODPP_NONE, include_actions, actions); +- res = n + 1; ++ res = odp_put_userspace_action(pid, user_data, user_data_size, ++ ODPP_NONE, include_actions, ++ actions, NULL); ++ if (!res) { ++ res = n + 1; ++ } + goto out; + } + } +@@ -2397,6 +2447,52 @@ parse_odp_action(const char *s, const struct simap *port_names, } } @@ -17483,7 +17510,7 @@ index d41c9369f2..311204fa8a 100644 { int retval; -@@ -2433,6 +2523,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names, +@@ -2433,6 +2529,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names, size_t old_size; if (!strcasecmp(s, "drop")) { @@ -17491,7 +17518,7 @@ index d41c9369f2..311204fa8a 100644 return 0; } -@@ -5185,13 +5276,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) +@@ -5185,13 +5282,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) do { \ len = 0; @@ -17515,7 +17542,7 @@ index d41c9369f2..311204fa8a 100644 } #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, +@@ -5757,26 +5857,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)) { @@ -17562,7 +17589,7 @@ index d41c9369f2..311204fa8a 100644 } } if (parms->support.recirc) { -@@ -5986,6 +6082,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) +@@ -5986,6 +6088,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); @@ -17573,6 +17600,80 @@ index d41c9369f2..311204fa8a 100644 if (flow_tnl_dst_is_set(&md->tunnel)) { tun_key_to_attr(buf, &md->tunnel, &md->tunnel, NULL, NULL); } +@@ -6957,15 +7063,18 @@ odp_key_fitness_to_string(enum odp_key_fitness fitness) + + /* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies + * Netlink PID 'pid'. If 'userdata' is nonnull, adds a userdata attribute +- * whose contents are the 'userdata_size' bytes at 'userdata' and returns the +- * offset within 'odp_actions' of the start of the cookie. (If 'userdata' is +- * null, then the return value is not meaningful.) */ +-size_t ++ * whose contents are the 'userdata_size' bytes at 'userdata' and sets ++ * 'odp_actions_ofs' if nonnull with the offset within 'odp_actions' of the ++ * start of the cookie. (If 'userdata' is null, then the 'odp_actions_ofs' ++ * value is not meaningful.) ++ * ++ * Returns negative error code on failure. */ ++int + odp_put_userspace_action(uint32_t pid, + const void *userdata, size_t userdata_size, + odp_port_t tunnel_out_port, + bool include_actions, +- struct ofpbuf *odp_actions) ++ struct ofpbuf *odp_actions, size_t *odp_actions_ofs) + { + size_t userdata_ofs; + size_t offset; +@@ -6973,6 +7082,9 @@ odp_put_userspace_action(uint32_t pid, + offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE); + nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid); + if (userdata) { ++ if (nl_attr_oversized(userdata_size)) { ++ return -E2BIG; ++ } + userdata_ofs = odp_actions->size + NLA_HDRLEN; + + /* The OVS kernel module before OVS 1.11 and the upstream Linux kernel +@@ -6998,9 +7110,16 @@ odp_put_userspace_action(uint32_t pid, + if (include_actions) { + nl_msg_put_flag(odp_actions, OVS_USERSPACE_ATTR_ACTIONS); + } ++ if (nl_attr_oversized(odp_actions->size - offset - NLA_HDRLEN)) { ++ return -E2BIG; ++ } + nl_msg_end_nested(odp_actions, offset); + +- return userdata_ofs; ++ if (odp_actions_ofs) { ++ *odp_actions_ofs = userdata_ofs; ++ } ++ ++ return 0; + } + + void +diff --git a/lib/odp-util.h b/lib/odp-util.h +index aa8e6efe37..706fbeb8db 100644 +--- a/lib/odp-util.h ++++ b/lib/odp-util.h +@@ -351,11 +351,12 @@ struct user_action_cookie { + }; + BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 48); + +-size_t odp_put_userspace_action(uint32_t pid, +- const void *userdata, size_t userdata_size, +- odp_port_t tunnel_out_port, +- bool include_actions, +- struct ofpbuf *odp_actions); ++int odp_put_userspace_action(uint32_t pid, ++ const void *userdata, size_t userdata_size, ++ odp_port_t tunnel_out_port, ++ bool include_actions, ++ struct ofpbuf *odp_actions, ++ size_t *odp_actions_ofs); + void odp_put_tunnel_action(const struct flow_tnl *tunnel, + struct ofpbuf *odp_actions, + const char *tnl_type); diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 68132c9455..1259c59141 100644 --- a/lib/ofp-actions.c @@ -18458,9 +18559,18 @@ index 7da31753c7..28b04682ea 100644 default: break; diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 4143bfa29f..ea9efbbae3 100644 +index 4143bfa29f..8c440372fa 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c +@@ -1088,7 +1088,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout, + } + + odp_put_userspace_action(pid, &cookie, sizeof cookie, +- ODPP_NONE, false, buf); ++ ODPP_NONE, false, buf, NULL); + + if (meter_id != UINT32_MAX) { + nl_msg_end_nested(buf, ac_offset); @@ -1526,6 +1526,7 @@ process_upcall(struct udpif *udpif, struct upcall *upcall, : NULL), am->pin.up.action_set_len = state->action_set_len, @@ -18479,7 +18589,7 @@ index 4143bfa29f..ea9efbbae3 100644 flow->mask, flow->mask_len, flow->ufid_present, &flow->ufid, flow->pmd_id, &actions, diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c -index 09ad76538f..3f83acd1a9 100644 +index 09ad76538f..d1981769fd 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -444,6 +444,12 @@ const char *xlate_strerror(enum xlate_error error) @@ -18503,6 +18613,32 @@ index 09ad76538f..3f83acd1a9 100644 } } +@@ -3043,6 +3050,7 @@ xlate_normal(struct xlate_ctx *ctx) + xlate_report(ctx, OFT_DETAIL, "MLD query, flooding"); + xlate_normal_flood(ctx, in_xbundle, &xvlan); + } ++ return; + } else { + if (is_ip_local_multicast(flow, wc)) { + /* RFC4541: section 2.1.2, item 2: Packets with a dst IP +@@ -3158,12 +3166,11 @@ compose_sample_action(struct xlate_ctx *ctx, + odp_port_t odp_port = ofp_port_to_odp_port( + ctx->xbridge, ctx->xin->flow.in_port.ofp_port); + uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); +- size_t cookie_offset = odp_put_userspace_action(pid, cookie, +- sizeof *cookie, +- tunnel_out_port, +- include_actions, +- ctx->odp_actions); +- ++ size_t cookie_offset; ++ int res = odp_put_userspace_action(pid, cookie, sizeof *cookie, ++ tunnel_out_port, include_actions, ++ ctx->odp_actions, &cookie_offset); ++ ovs_assert(res == 0); + if (is_sample) { + nl_msg_end_nested(ctx->odp_actions, actions_offset); + nl_msg_end_nested(ctx->odp_actions, sample_offset); @@ -4296,6 +4303,7 @@ xlate_table_action(struct xlate_ctx *ctx, ofp_port_t in_port, uint8_t table_id, !is_ip_any(&ctx->xin->flow)) { xlate_report_error(ctx, @@ -18511,6 +18647,15 @@ index 09ad76538f..3f83acd1a9 100644 return; } tuple_swap(&ctx->xin->flow, ctx->wc); +@@ -4709,7 +4717,7 @@ put_controller_user_action(struct xlate_ctx *ctx, + ctx->xin->flow.in_port.ofp_port); + uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); + odp_put_userspace_action(pid, &cookie, sizeof cookie, ODPP_NONE, +- false, ctx->odp_actions); ++ false, ctx->odp_actions, NULL); + } + + static void @@ -5569,6 +5577,7 @@ reversible_actions(const struct ofpact *ofpacts, size_t ofpacts_len) case OFPACT_UNROLL_XLATE: case OFPACT_WRITE_ACTIONS: @@ -19467,7 +19612,7 @@ index 65a47a41d3..284ed05519 100644 } diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c -index 438f975902..45e656d3d3 100644 +index 438f975902..49ba05c88a 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -559,7 +559,9 @@ do_db_has_magic(struct ovs_cmdl_context *ctx, const char *magic) @@ -19481,6 +19626,14 @@ index 438f975902..45e656d3d3 100644 exit(2); } } +@@ -715,6 +717,7 @@ print_db_changes(struct shash *tables, struct smap *names, + ds_init(&s); + ovsdb_datum_to_string(&datum, type, &s); + value_string = ds_steal_cstr(&s); ++ ovsdb_datum_destroy(&datum, type); + } else { + ovsdb_error_destroy(error); + } diff --git a/ovsdb/raft.c b/ovsdb/raft.c index 68b527c12a..7ba75f6a3f 100644 --- a/ovsdb/raft.c @@ -20259,7 +20412,7 @@ index a30d362e34..49d90f4303 100644 AT_CLEANUP diff --git a/tests/odp.at b/tests/odp.at -index 86a918e662..a172c49fe1 100644 +index 86a918e662..ac17b8525f 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -377,6 +377,10 @@ clone(1) @@ -20273,6 +20426,50 @@ index 86a918e662..a172c49fe1 100644 ]) AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [`cat actions.txt` +@@ -391,6 +395,43 @@ odp_actions_from_string: error + ]) + AT_CLEANUP + ++AT_SETUP([OVS datapath actions parsing and formatting - userdata overflow]) ++dnl Userdata should fit in a single netlink message, i.e. should be less than ++dnl UINT16_MAX - NLA_HDRLEN = 65535 - 4 = 65531 bytes. OVS should not accept ++dnl larger userdata. OTOH, userdata is part of a nested netlink message, that ++dnl should not be oversized too. 'pid' takes NLA_HDRLEN + 4 = 8 bytes. ++dnl Plus NLA_HDRLEN for the nested header. 'actions' flag takes NLA_HDRLEN = 4 ++dnl and 'tunnel_out_port' takes NLA_HDRLEN + 4 = 8 bytes. ++dnl So, for the variant with 'actions' maximum length of userdata should be: ++dnl UINT16_MAX - NLA_HDRLEN - (NLA_HDRLEN + 4) - NLA_HDRLEN - NLA_HDRLEN ++dnl total max nested header pid actions userdata ++dnl Result: 65515 bytes for the actual userdata. ++dnl For the case with 'tunnel_out_port': 65511 ++dnl Size of userdata will be rounded up to be multiple of 4, so highest ++dnl acceptable sizes are 65512 and 65508. ++ ++dnl String with length 65512 * 2 = 131024 is valid, while 131026 is not. ++data_valid=$( printf '%*s' 131024 | tr ' ' "a") ++data_invalid=$(printf '%*s' 131026 | tr ' ' "a") ++ ++echo "userspace(pid=1234567,userdata(${data_valid}),actions)" > actions.txt ++echo "userspace(pid=1234567,userdata(${data_invalid}),actions)" >> actions.txt ++ ++dnl String with length 65508 * 2 = 131016 is valid, while 131018 is not. ++data_valid=$( printf '%*s' 131016 | tr ' ' "a") ++data_invalid=$(printf '%*s' 131018 | tr ' ' "a") ++ ++echo "userspace(pid=1234567,userdata(${data_valid}),tunnel_out_port=10)" >> actions.txt ++echo "userspace(pid=1234567,userdata(${data_invalid}),tunnel_out_port=10)" >> actions.txt ++ ++AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [dnl ++`cat actions.txt | head -1` ++odp_actions_from_string: error ++`cat actions.txt | head -3 | tail -1` ++odp_actions_from_string: error ++]) ++AT_CLEANUP ++ + AT_SETUP([OVS datapath keys parsing and formatting - 33 nested encap ]) + AT_DATA([odp-in.txt], [dnl + encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap())))))))))))))))))))))))))))))))) diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at index e320a92a8f..348117197c 100644 --- a/tests/ofp-actions.at diff --git a/SPECS/openvswitch2.11.spec b/SPECS/openvswitch2.11.spec index f5fa486..e0b0ffc 100644 --- a/SPECS/openvswitch2.11.spec +++ b/SPECS/openvswitch2.11.spec @@ -66,7 +66,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.11.3 -Release: 75%{?dist} +Release: 76%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -745,6 +745,10 @@ exit 0 %changelog +* Thu Dec 24 2020 Open vSwitch CI - 2.11.3-76 +- Merging upstream branch-2.11 + [aa80d76b094b7eea8cd651a62ce251f77f179c25] + * Wed Dec 02 2020 Open vSwitch CI - 2.11.3-75 - Merging upstream branch-2.11 [838f461d65b104b814f1f6857710c0221f50ca3f]