diff --git a/SOURCES/openvswitch-2.15.0.patch b/SOURCES/openvswitch-2.15.0.patch index b6e3081..a703100 100644 --- a/SOURCES/openvswitch-2.15.0.patch +++ b/SOURCES/openvswitch-2.15.0.patch @@ -859,7 +859,7 @@ index fd82d7d270..2691412c41 100644 OVS_CHECK_OPENSSL OVS_CHECK_LIBCAPNG diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c -index 4f43369844..218e7db814 100644 +index 4f43369844..e3eb05d659 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -1112,9 +1112,9 @@ OvsPopFieldInPacketBuf(OvsForwardingContext *ovsFwdCtx, @@ -901,7 +901,16 @@ index 4f43369844..218e7db814 100644 } -@@ -1516,6 +1527,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, +@@ -1491,6 +1502,8 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, + UINT16 *checkField = NULL; + BOOLEAN l4Offload = FALSE; + NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; ++ UINT16 preNatPseudoChecksum = 0; ++ BOOLEAN preservePseudoChecksum = FALSE; + + ASSERT(layers->value != 0); + +@@ -1516,6 +1529,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, csumInfo.Value = NET_BUFFER_LIST_INFO(ovsFwdCtx->curNbl, TcpIpChecksumNetBufferListInfo); @@ -909,24 +918,34 @@ index 4f43369844..218e7db814 100644 /* * Adjust the IP header inline as dictated by the action, and also update * the IP and the TCP checksum for the data modified. -@@ -1524,6 +1536,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, +@@ -1524,6 +1538,12 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, * ChecksumUpdate32(). Ignoring this for now, since for the most common * case, we only update the TTL. */ + /*Only tx direction the checksum value will be reset to be PseudoChecksum*/ ++ if (!isTx) { ++ preNatPseudoChecksum = IPPseudoChecksum(&ipHdr->saddr, &ipHdr->daddr, ++ tcpHdr ? IPPROTO_TCP : IPPROTO_UDP, ++ ntohs(ipHdr->tot_len) - ipHdr->ihl * 4); ++ } if (isSource) { addrField = &ipHdr->saddr; -@@ -1540,7 +1553,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, +@@ -1540,7 +1560,12 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, ((BOOLEAN)csumInfo.Receive.UdpChecksumSucceeded || (BOOLEAN)csumInfo.Receive.UdpChecksumFailed); } - if (l4Offload) { -+ if (isTx && l4Offload) { ++ if (!isTx && l4Offload) { ++ if (*checkField == preNatPseudoChecksum) { ++ preservePseudoChecksum = TRUE; ++ } ++ } ++ if (isTx && l4Offload || preservePseudoChecksum) { *checkField = IPPseudoChecksum(&newAddr, &ipHdr->daddr, tcpHdr ? IPPROTO_TCP : IPPROTO_UDP, ntohs(ipHdr->tot_len) - ipHdr->ihl * 4); -@@ -1550,15 +1563,27 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, +@@ -1550,15 +1575,33 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, if (tcpHdr) { portField = &tcpHdr->dest; checkField = &tcpHdr->check; @@ -940,8 +959,13 @@ index 4f43369844..218e7db814 100644 + ((BOOLEAN)csumInfo.Receive.UdpChecksumSucceeded || + (BOOLEAN)csumInfo.Receive.UdpChecksumFailed); + } ++ if (!isTx && l4Offload) { ++ if (*checkField == preNatPseudoChecksum) { ++ preservePseudoChecksum = TRUE; ++ } ++ } + -+ if (isTx && l4Offload) { ++ if (isTx && l4Offload || preservePseudoChecksum) { + *checkField = IPPseudoChecksum(&ipHdr->saddr, &newAddr, + tcpHdr ? IPPROTO_TCP : IPPROTO_UDP, + ntohs(ipHdr->tot_len) - ipHdr->ihl * 4); @@ -951,11 +975,12 @@ index 4f43369844..218e7db814 100644 if (*addrField != newAddr) { UINT32 oldAddr = *addrField; - if (checkField && *checkField != 0 && !l4Offload) { -+ if ((checkField && *checkField != 0) && (!l4Offload || !isTx)) { ++ if ((checkField && *checkField != 0) && ++ (!l4Offload || (!isTx && !preservePseudoChecksum))) { /* Recompute total checksum. */ *checkField = ChecksumUpdate32(*checkField, oldAddr, newAddr); -@@ -1567,11 +1592,12 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, +@@ -1567,11 +1610,13 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, ipHdr->check = ChecksumUpdate32(ipHdr->check, oldAddr, newAddr); } @@ -965,11 +990,12 @@ index 4f43369844..218e7db814 100644 if (portField && *portField != newPort) { - if (checkField && !l4Offload) { -+ if ((checkField) && (!l4Offload || !isTx)) { ++ if ((checkField) && ++ (!l4Offload || (!isTx && !preservePseudoChecksum))) { /* Recompute total checksum. */ *checkField = ChecksumUpdate16(*checkField, *portField, newPort); -@@ -1686,6 +1712,15 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx, +@@ -1686,6 +1731,15 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx, ipHdr->ttl = ipAttr->ipv4_ttl; key->ipKey.nwTtl = ipAttr->ipv4_ttl; } @@ -985,7 +1011,7 @@ index 4f43369844..218e7db814 100644 return NDIS_STATUS_SUCCESS; } -@@ -1780,9 +1815,11 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx, +@@ -1780,9 +1834,11 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx, } if (newNbl) { @@ -999,7 +1025,7 @@ index 4f43369844..218e7db814 100644 } if (deferredAction) { -@@ -1952,7 +1989,7 @@ OvsExecuteSampleAction(OvsForwardingContext *ovsFwdCtx, +@@ -1952,7 +2008,7 @@ OvsExecuteSampleAction(OvsForwardingContext *ovsFwdCtx, return STATUS_SUCCESS; } @@ -1008,7 +1034,7 @@ index 4f43369844..218e7db814 100644 OVS_LOG_INFO( "Deferred actions limit reached, dropping sample action."); OvsCompleteNBL(ovsFwdCtx->switchContext, newNbl, TRUE); -@@ -2088,6 +2125,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext, +@@ -2088,6 +2144,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext, */ status = OvsPopVlanInPktBuf(&ovsFwdCtx); if (status != NDIS_STATUS_SUCCESS) { @@ -1016,7 +1042,7 @@ index 4f43369844..218e7db814 100644 dropReason = L"OVS-pop vlan action failed"; goto dropit; } -@@ -2337,7 +2375,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext, +@@ -2337,7 +2394,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext, if (status == STATUS_SUCCESS) { status = OvsProcessDeferredActions(switchContext, completionList, @@ -100188,6 +100214,80 @@ index d75d66b863..ba096dd0c8 100644 void jsonrpc_session_set_max_backoff(struct jsonrpc_session *, int max_backoff); +diff --git a/lib/learn.c b/lib/learn.c +index a40209ec0b..a62add2fda 100644 +--- a/lib/learn.c ++++ b/lib/learn.c +@@ -241,7 +241,7 @@ static char * OVS_WARN_UNUSED_RESULT + learn_parse_spec(const char *orig, char *name, char *value, + const struct ofputil_port_map *port_map, + struct ofpact_learn_spec *spec, +- struct ofpbuf *ofpacts, struct match *match) ++ struct ofpbuf *ofpacts) + { + /* Parse destination and check prerequisites. */ + struct mf_subfield dst; +@@ -275,14 +275,14 @@ learn_parse_spec(const char *orig, char *name, char *value, + } else { + char *tail; + /* Partial field value. */ +- if (parse_int_string(value, (uint8_t *)&imm, ++ if (parse_int_string(value, imm.b, + dst.field->n_bytes, &tail) + || *tail != 0) { + imm_error = xasprintf("%s: cannot parse integer value", orig); + } + + if (!imm_error && +- !bitwise_is_all_zeros(&imm, dst.field->n_bytes, ++ !bitwise_is_all_zeros(imm.b, dst.field->n_bytes, + dst.n_bits, + dst.field->n_bytes * 8 - dst.n_bits)) { + struct ds ds; +@@ -304,15 +304,13 @@ learn_parse_spec(const char *orig, char *name, char *value, + + spec->src_type = NX_LEARN_SRC_IMMEDIATE; + +- /* Update 'match' to allow for satisfying destination +- * prerequisites. */ +- mf_write_subfield_value(&dst, &imm, match); +- + /* Push value last, as this may reallocate 'spec'! */ + unsigned int imm_bytes = DIV_ROUND_UP(dst.n_bits, 8); + uint8_t *src_imm = ofpbuf_put_zeros(ofpacts, + OFPACT_ALIGN(imm_bytes)); +- memcpy(src_imm, &imm, imm_bytes); ++ ++ memcpy(src_imm, &imm.b[dst.field->n_bytes - imm_bytes], ++ imm_bytes); + + free(error); + return NULL; +@@ -391,7 +389,6 @@ learn_parse__(char *orig, char *arg, const struct ofputil_port_map *port_map, + struct ofpbuf *ofpacts) + { + struct ofpact_learn *learn; +- struct match match; + char *name, *value; + + learn = ofpact_put_LEARN(ofpacts); +@@ -400,7 +397,6 @@ learn_parse__(char *orig, char *arg, const struct ofputil_port_map *port_map, + learn->priority = OFP_DEFAULT_PRIORITY; + learn->table_id = 1; + +- match_init_catchall(&match); + while (ofputil_parse_key_value(&arg, &name, &value)) { + if (!strcmp(name, "table")) { + if (!ofputil_table_from_string(value, table_map, +@@ -448,7 +444,7 @@ learn_parse__(char *orig, char *arg, const struct ofputil_port_map *port_map, + + spec = ofpbuf_put_zeros(ofpacts, sizeof *spec); + error = learn_parse_spec(orig, name, value, port_map, +- spec, ofpacts, &match); ++ spec, ofpacts); + if (error) { + return error; + } diff --git a/lib/libopenvswitch.pc.in b/lib/libopenvswitch.pc.in index 2a3f2ca7bc..44fbb1f9fd 100644 --- a/lib/libopenvswitch.pc.in @@ -102039,7 +102139,7 @@ index f0cac8e0fa..7f5561f827 100644 } diff --git a/lib/rculist.h b/lib/rculist.h -index 1072b87af2..c0d77acf94 100644 +index 1072b87af2..9bb8cbf3eb 100644 --- a/lib/rculist.h +++ b/lib/rculist.h @@ -365,35 +365,57 @@ rculist_is_singleton_protected(const struct rculist *list) @@ -102091,18 +102191,18 @@ index 1072b87af2..c0d77acf94 100644 +#define RCULIST_FOR_EACH_REVERSE_PROTECTED(ITER, MEMBER, RCULIST) \ + for (INIT_MULTIVAR(ITER, MEMBER, (RCULIST)->prev, struct rculist); \ + CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) ++ UPDATE_MULTIVAR(ITER, ITER_VAR(ITER)->prev)) + +#define RCULIST_FOR_EACH_REVERSE_PROTECTED_CONTINUE(ITER, MEMBER, RCULIST) \ + for (INIT_MULTIVAR(ITER, MEMBER, (ITER)->MEMBER.prev, struct rculist); \ + CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) ++ UPDATE_MULTIVAR(ITER, ITER_VAR(ITER)->prev)) + +#define RCULIST_FOR_EACH_PROTECTED(ITER, MEMBER, RCULIST) \ + for (INIT_MULTIVAR(ITER, MEMBER, rculist_next_protected(RCULIST), \ + struct rculist); \ + CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, rculist_next_protected(ITER_VAR(ITER))) \ ++ UPDATE_MULTIVAR(ITER, rculist_next_protected(ITER_VAR(ITER)))) \ + +#define RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED(ITER, MEMBER, RCULIST) \ + for (INIT_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ @@ -102110,18 +102210,18 @@ index 1072b87af2..c0d77acf94 100644 + struct rculist); \ + CONDITION_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ + ITER_VAR(ITER) != (RCULIST), \ -+ ITER_NEXT_VAR(ITER) = rculist_next_protected(ITER_VAR(VAR))); \ -+ UPDATE_MULTIVAR_SHORT(ITER)) ++ ITER_NEXT_VAR(ITER) = rculist_next_protected(ITER_VAR(ITER))); \ ++ UPDATE_MULTIVAR_SAFE_SHORT(ITER)) + +#define RCULIST_FOR_EACH_SAFE_LONG_PROTECTED(ITER, NEXT, MEMBER, RCULIST) \ + for (INIT_MULTIVAR_SAFE_LONG(ITER, NEXT, MEMBER, \ -+ rculist_next_protected(RCULIST) \ ++ rculist_next_protected(RCULIST), \ + struct rculist); \ -+ CONDITION_MULTIVAR_SAFE_LONG(VAR, NEXT, MEMBER \ ++ CONDITION_MULTIVAR_SAFE_LONG(ITER, NEXT, MEMBER, \ + ITER_VAR(ITER) != (RCULIST), \ -+ ITER_VAR(NEXT) = rculist_next_protected(ITER_VAR(VAR)), \ ++ ITER_VAR(NEXT) = rculist_next_protected(ITER_VAR(ITER)), \ + ITER_VAR(NEXT) != (RCULIST)); \ -+ UPDATE_MULTIVAR_LONG(ITER)) ++ UPDATE_MULTIVAR_SAFE_LONG(ITER, NEXT)) + +#define RCULIST_FOR_EACH_SAFE_PROTECTED(...) \ + OVERLOAD_SAFE_MACRO(RCULIST_FOR_EACH_SAFE_LONG_PROTECTED, \ @@ -106478,6 +106578,28 @@ index e3173fb88f..2347c690ef 100644 diff --git a/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 b/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 new file mode 100644 index 0000000000..e69de29bb2 +diff --git a/tests/learn.at b/tests/learn.at +index 5f1d6df9de..d127fed348 100644 +--- a/tests/learn.at ++++ b/tests/learn.at +@@ -6,7 +6,7 @@ actions=learn() + actions=learn(send_flow_rem) + actions=learn(delete_learned) + actions=learn(send_flow_rem,delete_learned) +-actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[], load:10->NXM_NX_REG0[5..10]) ++actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], NXM_NX_REG3[3..19]=0x10011, output:NXM_OF_IN_PORT[], load:10->NXM_NX_REG0[5..10]) + actions=learn(table=1,idle_timeout=10, hard_timeout=20, fin_idle_timeout=5, fin_hard_timeout=10, priority=10, cookie=0xfedcba9876543210, in_port=99,eth_dst=eth_src,load:in_port->reg1[16..31]) + actions=learn(limit=4096) + actions=learn(limit=4096,result_dst=reg0[0]) +@@ -18,7 +18,7 @@ OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1) + OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,send_flow_rem) + OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,delete_learned) + OFPT_FLOW_MOD (xid=0x4): ADD actions=learn(table=1,send_flow_rem,delete_learned) +-OFPT_FLOW_MOD (xid=0x5): ADD actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10]) ++OFPT_FLOW_MOD (xid=0x5): ADD actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],NXM_NX_REG3[3..19]=0x10011,output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10]) + OFPT_FLOW_MOD (xid=0x6): ADD actions=learn(table=1,idle_timeout=10,hard_timeout=20,fin_idle_timeout=5,fin_hard_timeout=10,priority=10,cookie=0xfedcba9876543210,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31]) + OFPT_FLOW_MOD (xid=0x7): ADD actions=learn(table=1,limit=4096) + OFPT_FLOW_MOD (xid=0x8): ADD actions=learn(table=1,limit=4096,result_dst=NXM_NX_REG0[0]) diff --git a/tests/library.at b/tests/library.at index 1702b7556b..e27d9e8bce 100644 --- a/tests/library.at diff --git a/SPECS/openvswitch2.15.spec b/SPECS/openvswitch2.15.spec index 15d99de..abf499c 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: 128%{?dist} +Release: 129%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -702,6 +702,14 @@ exit 0 %endif %changelog +* Thu Nov 24 2022 Open vSwitch CI - 2.15.0-129 +- Merging upstream branch-2.15 [RH git: 31a84993c7] + Commit list: + f4094a3d1d rculist: Fix iteration macros. + 262b62f1d3 learn: Fix parsing immediate value for a field match. + 408aac587c datapath-windows: Check the condition to reset pseudo header checksum on Rx side + + * Sat Nov 05 2022 Open vSwitch CI - 2.15.0-128 - Merging upstream branch-2.15 [RH git: bd14504e2d] Commit list: