diff --git a/SOURCES/openvswitch-2.16.0.patch b/SOURCES/openvswitch-2.16.0.patch
index be9f6c5..7df258c 100644
--- a/SOURCES/openvswitch-2.16.0.patch
+++ b/SOURCES/openvswitch-2.16.0.patch
@@ -2695,7 +2695,7 @@ index 1c9c720f04..57f94df544 100644
              }
              ds_put_format(&ds, "  %u: (keys %d)\n", revalidator->id, elements);
 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
-index a426fcfeb6..adae3129b4 100644
+index a426fcfeb6..aeff3b2679 100644
 --- a/ofproto/ofproto-dpif-xlate.c
 +++ b/ofproto/ofproto-dpif-xlate.c
 @@ -460,7 +460,7 @@ static void xlate_commit_actions(struct xlate_ctx *ctx);
@@ -2707,7 +2707,18 @@ index a426fcfeb6..adae3129b4 100644
  
  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,
+@@ -3272,7 +3272,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port)
+     struct dpif_ipfix *ipfix = ctx->xbridge->ipfix;
+     odp_port_t tunnel_out_port = ODPP_NONE;
+ 
+-    if (!ipfix || ctx->xin->flow.in_port.ofp_port == OFPP_NONE) {
++    if (!ipfix ||
++        (output_odp_port == ODPP_NONE &&
++         ctx->xin->flow.in_port.ofp_port == OFPP_NONE)) {
+         return;
+     }
+ 
+@@ -3598,7 +3600,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,
@@ -2716,7 +2727,7 @@ index a426fcfeb6..adae3129b4 100644
  {
      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,
+@@ -3728,7 +3730,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;
  
@@ -2725,7 +2736,7 @@ index a426fcfeb6..adae3129b4 100644
  
          /* 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
+@@ -3822,7 +3824,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,
@@ -2734,7 +2745,7 @@ index a426fcfeb6..adae3129b4 100644
  {
      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,
+@@ -3864,8 +3866,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)) {
@@ -2745,7 +2756,7 @@ index a426fcfeb6..adae3129b4 100644
              if (!ctx->freezing) {
                  xlate_action_set(ctx);
              }
-@@ -3880,7 +3881,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev,
+@@ -3880,7 +3883,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,
@@ -2754,7 +2765,7 @@ index a426fcfeb6..adae3129b4 100644
              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,
+@@ -4097,7 +4100,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)) {
@@ -2777,7 +2788,7 @@ index a426fcfeb6..adae3129b4 100644
          }
      }
  
-@@ -4107,7 +4122,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow,
+@@ -4107,7 +4124,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,
@@ -2786,7 +2797,7 @@ index a426fcfeb6..adae3129b4 100644
  {
      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,
+@@ -4144,7 +4161,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");
         }
@@ -2795,7 +2806,7 @@ index a426fcfeb6..adae3129b4 100644
         return;
      }
  
-@@ -4239,7 +4254,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+@@ -4239,7 +4256,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. */
@@ -2805,7 +2816,7 @@ index a426fcfeb6..adae3129b4 100644
              flow->tunnel = flow_tnl; /* Restore tunnel metadata */
  
          } else if (terminate_native_tunnel(ctx, flow, wc,
-@@ -6177,11 +6193,32 @@ static void
+@@ -6177,11 +6195,32 @@ static void
  compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
                           bool is_last_action)
  {
@@ -2816,7 +2827,7 @@ index a426fcfeb6..adae3129b4 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
@@ -2834,14 +2845,14 @@ index a426fcfeb6..adae3129b4 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 +6230,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
+@@ -6193,11 +6232,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);
  
@@ -2853,7 +2864,7 @@ index a426fcfeb6..adae3129b4 100644
  
      ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT);
      if (ofc->flags & NX_CT_F_COMMIT) {
-@@ -6333,6 +6365,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
+@@ -6333,6 +6367,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. */
@@ -2861,7 +2872,7 @@ index a426fcfeb6..adae3129b4 100644
      ctx->exit = false;
  
      offset_attr = nl_msg_start_nested(
-@@ -6357,7 +6390,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
+@@ -6357,7 +6392,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx,
      ctx->was_mpls = old_was_mpls;
      ctx->conntracked = old_conntracked;
      ctx->xin->flow = old_flow;
@@ -2870,7 +2881,7 @@ index a426fcfeb6..adae3129b4 100644
  }
  
  static void
-@@ -6738,13 +6771,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+@@ -6738,13 +6773,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
          return;
      }
  
@@ -2886,7 +2897,7 @@ index a426fcfeb6..adae3129b4 100644
  
          if (ctx->error) {
              break;
-@@ -6752,7 +6786,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+@@ -6752,7 +6788,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
  
          recirc_for_mpls(a, ctx);
  
@@ -2895,7 +2906,7 @@ index a426fcfeb6..adae3129b4 100644
              /* Check if need to store the remaining actions for later
               * execution. */
              if (ctx->freezing) {
-@@ -7149,17 +7183,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
+@@ -7149,17 +7185,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
              break;
  
          case OFPACT_CHECK_PKT_LARGER: {
@@ -5390,7 +5401,7 @@ index 7ef32d13cb..cb0e9df388 100755
  
      flows.write(struct.pack('>LH',
 diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
-index 956a69e1fa..aadfbc8cc5 100644
+index 956a69e1fa..df62bb9e8a 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
@@ -5448,7 +5459,45 @@ index 956a69e1fa..aadfbc8cc5 100644
  AT_SETUP([ofproto-dpif - exit])
  OVS_VSWITCHD_START
  add_of_ports br0 1 2 3 10 11 12 13 14
-@@ -8591,6 +8639,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout],
+@@ -7524,7 +7572,7 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the
+ dnl datapath level.
+ AT_SETUP([ofproto-dpif - Bridge IPFIX sanity check])
+ OVS_VSWITCHD_START
+-add_of_ports br0 1 2
++add_of_ports br0 1 2 3
+ 
+ dnl Sample every packet using bridge-based sampling.
+ AT_CHECK([ovs-vsctl -- set bridge br0 ipfix=@fix -- \
+@@ -7540,6 +7588,28 @@ flow-dump from the main thread:
+ packets:2, bytes:68, used:0.001s, actions:userspace(pid=0,ipfix(output_port=4294967295))
+ ])
+ 
++AT_CHECK([ovs-appctl revalidator/purge])
++
++dnl Check sample is performed even if only one of the ports is present.
++AT_DATA([flows.txt], [dnl
++table=0,in_port=3,tcp actions=load:0xffff->NXM_OF_IN_PORT[],ct(zone=1,table=1)
++table=1,tcp, actions=output:2
++])
++AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
++
++for i in `seq 1 3`; do
++    AT_CHECK([ovs-appctl netdev-dummy/receive p3 'in_port(3),eth(src=50:54:00:00:00:08,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no)'])
++done
++
++AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/.*\(packets:\)/\1/' | sed 's/used:[[0-9]].[[0-9]]*s/used:0.001s/'], [0], [dnl
++flow-dump from the main thread:
++packets:2, bytes:236, used:0.001s, actions:userspace(pid=0,ipfix(output_port=2)),2
++packets:2, bytes:236, used:0.001s, actions:userspace(pid=0,ipfix(output_port=4294967295)),ct(zone=1),recirc(0x1)
++])
++
++AT_CHECK([ovs-ofctl del-flows br0 in_port=3])
++AT_CHECK([ovs-ofctl del-flows br0 table=1])
++
+ AT_CHECK([ovs-appctl revalidator/purge])
+ dnl
+ dnl Add a slowpath meter. The userspace action should be metered.
+@@ -8591,6 +8661,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
  
@@ -5483,7 +5532,7 @@ index 956a69e1fa..aadfbc8cc5 100644
  dnl ----------------------------------------------------------------------
  AT_BANNER([ofproto-dpif -- megaflows])
  
-@@ -9695,6 +9771,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2):
+@@ -9695,6 +9793,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2):
  OVS_VSWITCHD_STOP
  AT_CLEANUP
  
@@ -5510,7 +5559,7 @@ index 956a69e1fa..aadfbc8cc5 100644
  AT_SETUP([ofproto-dpif - ICMPv6])
  OVS_VSWITCHD_START
  add_of_ports br0 1
-@@ -11404,6 +11500,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no
+@@ -11404,6 +11522,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 b98efb8..39ef635 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: 50%{?dist}
+Release: 51%{?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 Feb 09 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.16.0-51
+- Merging upstream branch-2.16 [RH git: 7b6570c65f]
+    Commit list:
+    0954c2911d ofproto: Fix ipfix not always sampling on egress. (#2016346)
+
+
 * Wed Feb 09 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.16.0-50
 - Merging upstream branch-2.16 [RH git: c5ad7f71c5]
     Commit list: