diff --git a/test/e2e/upg_e2e.go b/test/e2e/upg_e2e.go
index 9fe3a51..38e05b9 100644
--- a/test/e2e/upg_e2e.go
+++ b/test/e2e/upg_e2e.go
@@ -2405,6 +2405,7 @@ func describeNAT(f *framework.Framework) {
 	ginkgo.Describe("NAT translations", func() {
 		ginkgo.BeforeEach(func() {
 			setupNAT(f)
+			f.VPP.Ctl("upf nat config upf-nwi-sgi")
 			f.VPP.Ctl("clear trace")
 			out, _ := f.VPP.Ctl("trace add virtio-input 10")
 			fmt.Println("QQQQQQ ", out)
@@ -2412,11 +2413,13 @@ func describeNAT(f *framework.Framework) {
 		})
 		ginkgo.AfterEach(func() {
 			f.VPP.Ctl("show trace")
-			f.VPP.Ctl("sh ip fib table 100")
-			f.VPP.Ctl("sh ip fib table 200")
+			f.VPP.Ctl("sh ip fib")
+			// f.VPP.Ctl("sh ip fib table 200")
 			f.VPP.Ctl("sh fib paths")
 			// fmt.Println("QQQQQQ ", out)
 
+			f.VPP.Ctl("sh interface")
+
 		})
 
 		verify := func(sessionCfg framework.SessionConfig) {
diff --git a/upf/upf.c b/upf/upf.c
index cc0f6d7..a7e8b5c 100644
--- a/upf/upf.c
+++ b/upf/upf.c
@@ -653,6 +653,11 @@ upf_init (vlib_main_t *vm)
   if (!error)
     upf_pfcp_policer_config_init (sm);
 
+  clib_bihash_init_16_8 (&sm->flow_hash, "nat-flow-hash", 1024,
+                         0); // TODO: real number of buckets
+
+  sm->nat_output_sw_if_index = ~0;
+
   return error;
 }
 
@@ -961,3 +966,13 @@ upf_nat_get_src_port (vlib_buffer_t *b, u16 port)
     return;
   flow->nat_sport = clib_net_to_host_u16 (port);
 }
+
+int
+upf_nat_config (u32 output_sw_interface)
+{
+  upf_main_t *um = &upf_main;
+
+  um->nat_output_sw_if_index = output_sw_interface;
+
+  return 0;
+}
diff --git a/upf/upf.h b/upf/upf.h
index 1d38d9e..51aa689 100644
--- a/upf/upf.h
+++ b/upf/upf.h
@@ -24,6 +24,7 @@
 #include <vppinfra/hash.h>
 #include <vppinfra/bihash_8_8.h>
 #include <vppinfra/bihash_24_8.h>
+#include <vppinfra/bihash_16_8.h>
 
 #include <vnet/vnet.h>
 #include <vnet/ip/ip.h>
@@ -1029,6 +1030,12 @@ typedef struct
   policer_t *pfcp_policers;
 
   vlib_log_class_t log_class;
+
+  /* CG-NAT */
+  u32 nat_output_sw_if_index;
+
+  /* Endpoint dependent lookup table */
+  clib_bihash_16_8_t flow_hash;
 } upf_main_t;
 
 extern const fib_node_vft_t upf_vft;
diff --git a/upf/upf_cli.c b/upf/upf_cli.c
index 6ad3bbe..098aafc 100644
--- a/upf/upf_cli.c
+++ b/upf/upf_cli.c
@@ -36,6 +36,7 @@
 #include <upf/upf_app_db.h>
 #include <vnet/fib/fib_path_list.h>
 #include <vnet/fib/fib_walk.h>
+#include <vppinfra/error.h>
 
 #define DEFAULT_MAX_SHOW_UPF_SESSIONS 100
 #define HARD_MAX_SHOW_UPF_SESSIONS    10000
@@ -1756,3 +1757,44 @@ VLIB_CLI_COMMAND (upf_show_pfcp_heartbeat_config_command, static) =
   .function = upf_show_pfcp_heartbeat_config_command_fn,
 };
 /* clang-format on */
+
+static clib_error_t *
+upf_nat_config_command_fn (vlib_main_t *vm, unformat_input_t *main_input,
+                           vlib_cli_command_t *cmd)
+{
+  unformat_input_t _line_input, *line_input = &_line_input;
+  upf_main_t *gtm = &upf_main;
+  vnet_main_t *vnm = vnet_get_main ();
+  clib_error_t *error = NULL;
+
+  u32 sw_if_index = ~0;
+  int rv = 0;
+
+  if (!unformat_user (main_input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm,
+                    &sw_if_index))
+        ;
+      else
+        return (clib_error_return (0, "unknown input '%U'",
+                                   format_unformat_error, line_input));
+    }
+
+  clib_warning ("sw_if_index: %u", sw_if_index);
+  rv = upf_nat_config (sw_if_index);
+
+  if (rv)
+    error = (clib_error_return (0, "invalid parameters"));
+  return error;
+}
+
+/* clang-format off */
+VLIB_CLI_COMMAND (upf_nat_config_command, static) = {
+    .path = "upf nat config",
+    .short_help = "upf nat config <interface>",
+    .function = upf_nat_config_command_fn,
+};
+/* clang-format on */
diff --git a/upf/upf_nat.c b/upf/upf_nat.c
index e01a5ba..c95ed62 100644
--- a/upf/upf_nat.c
+++ b/upf/upf_nat.c
@@ -171,8 +171,14 @@ VLIB_NODE_FN (upf_nat_o2i)
           sx0 = pool_elt_at_index (gtm->sessions,
                                    upf_buffer_opaque (b)->gtpu.session_index);
 
-          bool is_incoming =
-            sx0->nat_addr->ext_addr.as_u32 == ip4->dst_address.as_u32;
+          // clib_warning ("WWWWWWWWWWW2: session_index 0x%08x, sw index %d ->
+          // "
+          //               "%d, condition %d",
+          // vnet_buffer (b)->ip.adj_index[VLIB_TX],
+          // vnet_buffer (b)->sw_if_index[VLIB_RX],
+          // vnet_buffer (b)->sw_if_index[VLIB_TX],
+          // vnet_buffer (b)->sw_if_index[VLIB_TX] == ~0);
+          bool is_incoming = vnet_buffer (b)->sw_if_index[VLIB_TX] == ~0;
 
           if (is_incoming)
             {
@@ -255,6 +261,13 @@ VLIB_NODE_FN (upf_nat_i2o)
           upf_session_t *sx0;
           sx0 = pool_elt_at_index (gtm->sessions,
                                    upf_buffer_opaque (b)->gtpu.session_index);
+          // clib_warning ("WWWWWWWWWWW: session_index 0x%08x, sw index %d -> "
+          //               "%d, condition %d",
+          // vnet_buffer (b)->ip.adj_index[VLIB_TX],
+          // vnet_buffer (b)->sw_if_index[VLIB_RX],
+          // vnet_buffer (b)->sw_if_index[VLIB_TX],
+          // gtm->nat_output_sw_if_index ==
+          //   vnet_buffer (b)->sw_if_index[VLIB_RX]);
 
           nat_6t_t lookup;
           clib_bihash_kv_16_8_t kv0 = { 0 }, value0;
@@ -270,7 +283,11 @@ VLIB_NODE_FN (upf_nat_i2o)
               // goto trace0;
             }
 
-          bool is_outgoing = sx0->user_addr.as_u32 == ip4->src_address.as_u32;
+          // bool is_outgoing = sx0->user_addr.as_u32 ==
+          // ip4->src_address.as_u32;
+
+          bool is_outgoing = gtm->nat_output_sw_if_index ==
+                             vnet_buffer (b)->sw_if_index[VLIB_RX];
 
           if (is_outgoing)
             {
diff --git a/upf/upf_pfcp.c b/upf/upf_pfcp.c
index 8799fdc..cda1486 100644
--- a/upf/upf_pfcp.c
+++ b/upf/upf_pfcp.c
@@ -1541,6 +1541,11 @@ pfcp_add_del_ue_ip (const void *ip, void *si, int is_add)
 
       upf_session_dpo_add_or_lock (fib_proto_to_dpo (pfx.fp_proto), sx, &sxd);
 
+      clib_warning ("XXXXX: fib_index=%d, sw_if_index=%d, dpo_index=%d",
+                    ue_ip->fib_index, ue_ip->sw_if_index, sxd.dpoi_index);
+
+      // sxd.dpoi_index = ~0;
+
       /* add reverse route for client ip through special DPO */
       fib_table_entry_special_dpo_add (
         ue_ip->fib_index, &pfx, FIB_SOURCE_SPECIAL,