diff --git a/SOURCES/openvswitch-2.16.0.patch b/SOURCES/openvswitch-2.16.0.patch
index 17514ec..a39d807 100644
--- a/SOURCES/openvswitch-2.16.0.patch
+++ b/SOURCES/openvswitch-2.16.0.patch
@@ -2425,10 +2425,66 @@ index e4b42b0594..877bca3127 100644
                       struct eth_addr *mac);
  void tnl_neigh_cache_init(void);
 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
-index a426fcfeb6..bb22d29034 100644
+index a426fcfeb6..adae3129b4 100644
 --- a/ofproto/ofproto-dpif-xlate.c
 +++ b/ofproto/ofproto-dpif-xlate.c
-@@ -4097,7 +4097,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow,
+@@ -460,7 +460,7 @@ static void xlate_commit_actions(struct xlate_ctx *ctx);
+ 
+ static void
+ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev,
+-                  struct xport *out_dev);
++                  struct xport *out_dev, bool is_last_action);
+ 
+ static void
+ ctx_trigger_freeze(struct xlate_ctx *ctx)
+@@ -3598,7 +3598,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac,
+ static int
+ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
+                      const struct flow *flow, odp_port_t tunnel_odp_port,
+-                     bool truncate)
++                     bool truncate, bool is_last_action)
+ {
+     struct netdev_tnl_build_header_params tnl_params;
+     struct ovs_action_push_tnl tnl_push_data;
+@@ -3728,7 +3728,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
+         entry->tunnel_hdr.hdr_size = tnl_push_data.header_len;
+         entry->tunnel_hdr.operation = ADD;
+ 
+-        patch_port_output(ctx, xport, out_dev);
++        patch_port_output(ctx, xport, out_dev, is_last_action);
+ 
+         /* Similar to the stats update in revalidation, the x_cache entries
+          * are populated by the previous translation are used to update the
+@@ -3822,7 +3822,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co
+  */
+ static void
+ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev,
+-                  struct xport *out_dev)
++                  struct xport *out_dev, bool is_last_action)
+ {
+     struct flow *flow = &ctx->xin->flow;
+     struct flow old_flow = ctx->xin->flow;
+@@ -3864,8 +3864,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev,
+     if (!process_special(ctx, out_dev) && may_receive(out_dev, ctx)) {
+         if (xport_stp_forward_state(out_dev) &&
+             xport_rstp_forward_state(out_dev)) {
++
+             xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true,
+-                               false, true, clone_xlate_actions);
++                               false, is_last_action, clone_xlate_actions);
+             if (!ctx->freezing) {
+                 xlate_action_set(ctx);
+             }
+@@ -3880,7 +3881,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev,
+             mirror_mask_t old_mirrors2 = ctx->mirrors;
+ 
+             xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true,
+-                               false, true, clone_xlate_actions);
++                               false, is_last_action, clone_xlate_actions);
+             ctx->mirrors = old_mirrors2;
+             ctx->base_flow = old_base_flow;
+             ctx->odp_actions->size = old_size;
+@@ -4097,7 +4098,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow,
              (flow->dl_type == htons(ETH_TYPE_ARP) ||
               flow->nw_proto == IPPROTO_ICMPV6) &&
               is_neighbor_reply_correct(ctx, flow)) {
@@ -2451,7 +2507,35 @@ index a426fcfeb6..bb22d29034 100644
          }
      }
  
-@@ -6177,11 +6191,32 @@ static void
+@@ -4107,7 +4122,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow,
+ static void
+ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+                         const struct xlate_bond_recirc *xr, bool check_stp,
+-                        bool is_last_action OVS_UNUSED, bool truncate)
++                        bool is_last_action, bool truncate)
+ {
+     const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port);
+     struct flow_wildcards *wc = ctx->wc;
+@@ -4144,7 +4159,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+        if (truncate) {
+            xlate_report_error(ctx, "Cannot truncate output to patch port");
+        }
+-       patch_port_output(ctx, xport, xport->peer);
++       patch_port_output(ctx, xport, xport->peer, is_last_action);
+        return;
+     }
+ 
+@@ -4239,7 +4254,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+                            xr->recirc_id);
+         } else if (is_native_tunnel) {
+             /* Output to native tunnel port. */
+-            native_tunnel_output(ctx, xport, flow, odp_port, truncate);
++            native_tunnel_output(ctx, xport, flow, odp_port, truncate,
++                                 is_last_action);
+             flow->tunnel = flow_tnl; /* Restore tunnel metadata */
+ 
+         } else if (terminate_native_tunnel(ctx, flow, wc,
+@@ -6177,11 +6193,32 @@ static void
  compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
                           bool is_last_action)
  {
@@ -2462,7 +2546,7 @@ index a426fcfeb6..bb22d29034 100644
 +    if (ofc->zone_src.field) {
 +        union mf_subvalue value;
 +        memset(&value, 0xff, sizeof(value));
- 
++
 +        zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow);
 +        if (ctx->xin->frozen_state) {
 +            /* If the upcall is a resume of a recirculation, we only need to
@@ -2480,14 +2564,14 @@ index a426fcfeb6..bb22d29034 100644
 +    } else {
 +        zone = ofc->zone_imm;
 +    }
-+
+ 
 +    size_t ct_offset;
 +    ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label;
 +    uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark;
      /* Ensure that any prior actions are applied before composing the new
       * conntrack action. */
      xlate_commit_actions(ctx);
-@@ -6193,11 +6228,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
+@@ -6193,11 +6230,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
      do_xlate_actions(ofc->actions, ofpact_ct_get_action_len(ofc), ctx,
                       is_last_action, false);
  
@@ -2499,7 +2583,7 @@ index a426fcfeb6..bb22d29034 100644
  
      ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT);
      if (ofc->flags & NX_CT_F_COMMIT) {
-@@ -6333,6 +6363,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
+@@ -6333,6 +6365,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
       * then ctx->exit would be true. Reset to false so that we can
       * do flow translation for 'IF_LESS_EQUAL' case. finish_freezing()
       * would have taken care of Undoing the changes done for freeze. */
@@ -2507,7 +2591,7 @@ index a426fcfeb6..bb22d29034 100644
      ctx->exit = false;
  
      offset_attr = nl_msg_start_nested(
-@@ -6357,7 +6388,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
+@@ -6357,7 +6390,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
      ctx->was_mpls = old_was_mpls;
      ctx->conntracked = old_conntracked;
      ctx->xin->flow = old_flow;
@@ -2516,7 +2600,7 @@ index a426fcfeb6..bb22d29034 100644
  }
  
  static void
-@@ -6738,6 +6769,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+@@ -6738,13 +6771,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
          return;
      }
  
@@ -2524,7 +2608,15 @@ index a426fcfeb6..bb22d29034 100644
      OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
          struct ofpact_controller *controller;
          const struct ofpact_metadata *metadata;
-@@ -6752,7 +6784,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+         const struct ofpact_set_field *set_field;
+         const struct mf_field *mf;
+         bool last = is_last_action && ofpact_last(a, ofpacts, ofpacts_len)
+-                    && ctx->action_set.size;
++                    && !ctx->action_set.size;
+ 
+         if (ctx->error) {
+             break;
+@@ -6752,7 +6786,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
  
          recirc_for_mpls(a, ctx);
  
@@ -2533,7 +2625,18 @@ index a426fcfeb6..bb22d29034 100644
              /* Check if need to store the remaining actions for later
               * execution. */
              if (ctx->freezing) {
-@@ -7160,6 +7192,12 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+@@ -7149,17 +7183,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+             break;
+ 
+         case OFPACT_CHECK_PKT_LARGER: {
+-            if (last) {
+-                /* If this is last action, then there is no need to
+-                 * translate the action. */
+-                break;
+-            }
+             const struct ofpact *remaining_acts = ofpact_next(a);
+             size_t remaining_acts_len = ofpact_remaining_len(remaining_acts,
+                                                              ofpacts,
                                                               ofpacts_len);
              xlate_check_pkt_larger(ctx, ofpact_get_CHECK_PKT_LARGER(a),
                                     remaining_acts, remaining_acts_len);
@@ -4955,7 +5058,7 @@ index 7ef32d13cb..cb0e9df388 100755
  
      flows.write(struct.pack('>LH',
 diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
-index 956a69e1fa..035321e892 100644
+index 956a69e1fa..aadfbc8cc5 100644
 --- a/tests/ofproto-dpif.at
 +++ b/tests/ofproto-dpif.at
 @@ -4862,6 +4862,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr
@@ -5013,7 +5116,42 @@ index 956a69e1fa..035321e892 100644
  AT_SETUP([ofproto-dpif - exit])
  OVS_VSWITCHD_START
  add_of_ports br0 1 2 3 10 11 12 13 14
-@@ -9695,6 +9743,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2):
+@@ -8591,6 +8639,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout],
+ OVS_VSWITCHD_STOP
+ AT_CLEANUP
+ 
++
++AT_SETUP([ofproto-dpif - patch ports - meter (clone)])
++
++OVS_VSWITCHD_START(
++  [add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 -- \
++   add-port br0 p1 -- set Interface p1 type=patch \
++                                       options:peer=p2 ofport_request=2 -- \
++   add-br br1 -- \
++   set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
++   set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
++                  fail-mode=secure -- \
++   add-port br1 p2 -- set Interface p2 type=patch \
++                                       options:peer=p1 -- \
++   add-port br1 p3 -- set Interface p3 type=dummy ofport_request=3])
++
++AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br1 'meter=1 pktps stats bands=type=drop rate=2'])
++AT_CHECK([ovs-ofctl del-flows br0])
++AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 in_port=local,ip,actions=2,1])
++AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br1 in_port=1,ip,actions=meter:1,3])
++
++AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(100),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=10.1.1.22,dst=10.0.0.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=53295,dst=8080)'], [0], [stdout])
++AT_CHECK([tail -1 stdout], [0],
++  [Datapath actions: clone(meter(0),3),1
++])
++
++OVS_VSWITCHD_STOP
++AT_CLEANUP
++
+ dnl ----------------------------------------------------------------------
+ AT_BANNER([ofproto-dpif -- megaflows])
+ 
+@@ -9695,6 +9771,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2):
  OVS_VSWITCHD_STOP
  AT_CLEANUP
  
@@ -5040,7 +5178,7 @@ index 956a69e1fa..035321e892 100644
  AT_SETUP([ofproto-dpif - ICMPv6])
  OVS_VSWITCHD_START
  add_of_ports br0 1
-@@ -11404,6 +11472,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no
+@@ -11404,6 +11500,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no
  Datapath actions: 4
  ])
  
diff --git a/SPECS/openvswitch2.16.spec b/SPECS/openvswitch2.16.spec
index 1205bb5..ead87aa 100644
--- a/SPECS/openvswitch2.16.spec
+++ b/SPECS/openvswitch2.16.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 2.16.0
-Release: 40%{?dist}
+Release: 41%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -699,6 +699,12 @@ exit 0
 %endif
 
 %changelog
+* Wed Jan 26 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.16.0-41
+- Merging upstream branch-2.16 [RH git: f1ca7b8ac3]
+    Commit list:
+    2571b1a464 ofproto-dpif: Fix issue with non-reversible actions on a patch ports.
+
+
 * Fri Jan 21 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.16.0-40
 - Merging upstream branch-2.16 [RH git: 60b19f443c]
     Commit list: