diff --git a/0001-northd-Provide-the-Gateway-router-option-lb_force_sn.patch b/0001-northd-Provide-the-Gateway-router-option-lb_force_sn.patch
new file mode 100644
index 0000000..05d29ac
--- /dev/null
+++ b/0001-northd-Provide-the-Gateway-router-option-lb_force_sn.patch
@@ -0,0 +1,403 @@
+From e6a52543078d2d618b72151608b9c61326debe05 Mon Sep 17 00:00:00 2001
+From: Numan Siddique flags.force_snat_for_dnat == 1 && ip
with an
+ action ct_snat(B);
.
+
++ If the Gateway router in the OVN Northbound database has been
++ configured to force SNAT a packet (that has been previously
++ load-balanced) using router IP (i.e :lb_force_snat_ip=router_ip), then for
++ each logical router port P attached to the Gateway
++ router, a priority-110 flow matches
++ flags.force_snat_for_lb == 1 && outport == P
++
with an action ct_snat(R);
++ where R is the IP configured on the router port.
++ If R
is an IPv4 address then the match will also
++ include ip4
and if it is an IPv6 address, then the
++ match will also include ip6
.
++
++ If the logical router port P is configured with multiple ++ IPv4 and multiple IPv6 addresses, only the first IPv4 and first IPv6 ++ address is considered. ++
++
+ If the Gateway router in the OVN Northbound database has been
+ configured to force SNAT a packet (that has been previously
+@@ -3660,6 +3686,9 @@ nd_ns {
+ flags.force_snat_for_lb == 1 && ip
with an
+ action ct_snat(B);
.
+
+ For each configuration in the OVN Northbound database, that asks
+ to change the source IP address of a packet from an IP address of
+@@ -3673,14 +3702,18 @@ nd_ns {
+ options, then the action would be ip4/6.src=
+ (B)
.
+
+ If the NAT rule has allowed_ext_ips
configured, then
+ there is an additional match ip4.dst == allowed_ext_ips
+
. Similarly, for IPV6, match would be ip6.dst ==
+ allowed_ext_ips
.
+
+ If the NAT rule has exempted_ext_ips
set, then
+ there is an additional flow configured at the priority + 1 of
+@@ -3689,7 +3722,9 @@ nd_ns {
+ . This flow is used to bypass the ct_snat action for a packet
+ which is destinted to exempted_ext_ips
.
+
+ A priority-0 logical flow with match
+- If set, indicates a set of IP addresses to use to force SNAT a packet
+- that has already been load-balanced in the gateway router. When
+- multiple gateway routers are configured, a packet can potentially
+- enter any of the gateway routers, get DNATted as part of the load-
+- balancing and eventually reach the logical switch port.
+- For the return traffic to go back to the same gateway router (for
+- unDNATing), the packet needs a SNAT in the first place. This can be
+- achieved by setting the above option with a gateway specific set of
+- IP addresses. This option may have exactly one IPv4 and/or one IPv6
+- address on it, separated by a space character.
++ If set, this option can take two possible type of values. Either
++ a set of IP addresses or the string value -
++ If a set of IP addresses are configured, it indicates to use to
++ force SNAT a packet that has already been load-balanced in the
++ gateway router. When multiple gateway routers are configured, a
++ packet can potentially enter any of the gateway routers, get
++ DNATted as part of the load-balancing and eventually reach the
++ logical switch port. For the return traffic to go back to the
++ same gateway router (for unDNATing), the packet needs a SNAT in the
++ first place. This can be achieved by setting the above option with
++ a gateway specific set of IP addresses. This option may have exactly
++ one IPv4 and/or one IPv6 address on it, separated by a space
++ character.
++
++ If it is configured with the value 1
has actions
+ next;
.
+diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
+index 92e1f5b1f..3d81187d8 100644
+--- a/northd/ovn-northd.c
++++ b/northd/ovn-northd.c
+@@ -637,6 +637,7 @@ struct ovn_datapath {
+
+ struct lport_addresses dnat_force_snat_addrs;
+ struct lport_addresses lb_force_snat_addrs;
++ bool lb_force_snat_router_ip;
+
+ struct ovn_port **localnet_ports;
+ size_t n_localnet_ports;
+@@ -730,14 +731,28 @@ init_nat_entries(struct ovn_datapath *od)
+ }
+ }
+
+- if (get_force_snat_ip(od, "lb", &od->lb_force_snat_addrs)) {
+- if (od->lb_force_snat_addrs.n_ipv4_addrs) {
+- snat_ip_add(od, od->lb_force_snat_addrs.ipv4_addrs[0].addr_s,
+- NULL);
+- }
+- if (od->lb_force_snat_addrs.n_ipv6_addrs) {
+- snat_ip_add(od, od->lb_force_snat_addrs.ipv6_addrs[0].addr_s,
+- NULL);
++ /* Check if 'lb_force_snat_ip' is configured with 'router_ip'. */
++ const char *lb_force_snat =
++ smap_get(&od->nbr->options, "lb_force_snat_ip");
++ if (lb_force_snat && !strcmp(lb_force_snat, "router_ip")
++ && smap_get(&od->nbr->options, "chassis")) {
++ /* Set it to true only if its gateway router and
++ * options:lb_force_snat_ip=router_ip. */
++ od->lb_force_snat_router_ip = true;
++ } else {
++ od->lb_force_snat_router_ip = false;
++
++ /* Check if 'lb_force_snat_ip' is configured with a set of
++ * IP address(es). */
++ if (get_force_snat_ip(od, "lb", &od->lb_force_snat_addrs)) {
++ if (od->lb_force_snat_addrs.n_ipv4_addrs) {
++ snat_ip_add(od, od->lb_force_snat_addrs.ipv4_addrs[0].addr_s,
++ NULL);
++ }
++ if (od->lb_force_snat_addrs.n_ipv6_addrs) {
++ snat_ip_add(od, od->lb_force_snat_addrs.ipv6_addrs[0].addr_s,
++ NULL);
++ }
+ }
+ }
+
+@@ -9183,6 +9198,64 @@ build_lrouter_force_snat_flows(struct hmap *lflows, struct ovn_datapath *od,
+ ds_destroy(&actions);
+ }
+
++static void
++build_lrouter_force_snat_flows_op(struct ovn_port *op,
++ struct hmap *lflows,
++ struct ds *match, struct ds *actions)
++{
++ if (!op->nbrp || !op->peer || !op->od->lb_force_snat_router_ip) {
++ return;
++ }
++
++ if (op->lrp_networks.n_ipv4_addrs) {
++ ds_clear(match);
++ ds_clear(actions);
++
++ /* Higher priority rules to force SNAT with the router port ip.
++ * This only takes effect when the packet has already been
++ * load balanced once. */
++ ds_put_format(match, "flags.force_snat_for_lb == 1 && ip4 && "
++ "outport == %s", op->json_key);
++ ds_put_format(actions, "ct_snat(%s);",
++ op->lrp_networks.ipv4_addrs[0].addr_s);
++ ovn_lflow_add(lflows, op->od, S_ROUTER_OUT_SNAT, 110,
++ ds_cstr(match), ds_cstr(actions));
++ if (op->lrp_networks.n_ipv4_addrs > 2) {
++ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
++ VLOG_WARN_RL(&rl, "Logical router port %s is configured with "
++ "multiple IPv4 addresses. Only the first "
++ "IP [%s] is considered as SNAT for load "
++ "balancer", op->json_key,
++ op->lrp_networks.ipv4_addrs[0].addr_s);
++ }
++ }
++
++ /* op->lrp_networks.ipv6_addrs will always have LLA and that will be
++ * last in the list. So add the flows only if n_ipv6_addrs > 1. */
++ if (op->lrp_networks.n_ipv6_addrs > 1) {
++ ds_clear(match);
++ ds_clear(actions);
++
++ /* Higher priority rules to force SNAT with the router port ip.
++ * This only takes effect when the packet has already been
++ * load balanced once. */
++ ds_put_format(match, "flags.force_snat_for_lb == 1 && ip6 && "
++ "outport == %s", op->json_key);
++ ds_put_format(actions, "ct_snat(%s);",
++ op->lrp_networks.ipv6_addrs[0].addr_s);
++ ovn_lflow_add(lflows, op->od, S_ROUTER_OUT_SNAT, 110,
++ ds_cstr(match), ds_cstr(actions));
++ if (op->lrp_networks.n_ipv6_addrs > 2) {
++ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
++ VLOG_WARN_RL(&rl, "Logical router port %s is configured with "
++ "multiple IPv6 addresses. Only the first "
++ "IP [%s] is considered as SNAT for load "
++ "balancer", op->json_key,
++ op->lrp_networks.ipv6_addrs[0].addr_s);
++ }
++ }
++}
++
+ static void
+ build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op)
+ {
+@@ -11706,6 +11779,8 @@ build_lswitch_and_lrouter_iterate_by_op(struct ovn_port *op,
+ &lsi->match, &lsi->actions);
+ build_lrouter_ipv4_ip_input(op, lsi->lflows,
+ &lsi->match, &lsi->actions);
++ build_lrouter_force_snat_flows_op(op, lsi->lflows, &lsi->match,
++ &lsi->actions);
+ }
+
+ static void
+diff --git a/ovn-nb.xml b/ovn-nb.xml
+index 86aa438bd..09b755f1a 100644
+--- a/ovn-nb.xml
++++ b/ovn-nb.xml
+@@ -1935,16 +1935,29 @@
+
+ router_ip
.
++ router_ip
, then
++ the load balanced packet is SNATed with the IP of router port
++ (attached to the gateway router) selected as the destination after
++ taking the routing decision.
+