diff --git a/northd/northd.c b/northd/northd.c
index 0cabda7ea0..c0f477358a 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -9568,126 +9568,79 @@ build_lswitch_ip_unicast_lookup(struct ovn_port *op,
         return;
     }
 
-    /* For ports connected to logical routers add flows to bypass the
-     * broadcast flooding of ARP/ND requests in table 19. We direct the
-     * requests only to the router port that owns the IP address.
-     */
-    if (lsp_is_router(op->nbsp)) {
-        build_lswitch_rport_arp_req_flows(op->peer, op->od, op, lflows,
-                                          &op->nbsp->header_);
-    }
-
     bool lsp_clone_to_unknown = lsp_is_clone_to_unknown(op->nbsp);
+    bool lsp_enabled = lsp_is_enabled(op->nbsp);
+    const char *action = lsp_enabled
+                         ? ((lsp_clone_to_unknown && op->od->has_unknown)
+                         ? "clone {outport = %s; output; };"
+                           "outport = \""MC_UNKNOWN "\"; output;"
+                         : "outport = %s; output;")
+                         : debug_drop_action();
+    ds_clear(actions);
+    ds_put_format(actions, action, op->json_key);
 
-    for (size_t i = 0; i < op->nbsp->n_addresses; i++) {
-        /* Addresses are owned by the logical port.
-         * Ethernet address followed by zero or more IPv4
-         * or IPv6 addresses (or both). */
-        struct eth_addr mac;
-        bool lsp_enabled = lsp_is_enabled(op->nbsp);
-        const char *action = lsp_enabled
-                             ? ((lsp_clone_to_unknown && op->od->has_unknown)
-                                ? "clone {outport = %s; output; };"
-                                  "outport = \""MC_UNKNOWN "\"; output;"
-                                : "outport = %s; output;")
-                             : debug_drop_action();
-
-        if (ovs_scan(op->nbsp->addresses[i],
-                    ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
-            ds_clear(match);
-            ds_put_format(match, "eth.dst == "ETH_ADDR_FMT,
-                          ETH_ADDR_ARGS(mac));
+    if (lsp_is_router(op->nbsp) && op->peer && op->peer->nbrp) {
+        /* For ports connected to logical routers add flows to bypass the
+         * broadcast flooding of ARP/ND requests in table 19. We direct the
+         * requests only to the router port that owns the IP address.
+         */
+        build_lswitch_rport_arp_req_flows(op->peer, op->od, op, lflows,
+                                          &op->nbsp->header_);
 
-            ds_clear(actions);
-            ds_put_format(actions, action, op->json_key);
-            ovn_lflow_add_with_hint(lflows, op->od,
-                                    S_SWITCH_IN_L2_LKUP,
-                                    50, ds_cstr(match),
-                                    ds_cstr(actions),
-                                    &op->nbsp->header_,
-                                    op->lflow_ref);
-        } else if (!strcmp(op->nbsp->addresses[i], "unknown")) {
-            continue;
-        } else if (is_dynamic_lsp_address(op->nbsp->addresses[i])) {
-            if (!op->nbsp->dynamic_addresses
-                || !ovs_scan(op->nbsp->dynamic_addresses,
-                        ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
-                continue;
-            }
-            ds_clear(match);
-            ds_put_format(match, "eth.dst == "ETH_ADDR_FMT,
-                          ETH_ADDR_ARGS(mac));
+        ds_clear(match);
+        if (!eth_addr_is_zero(op->proxy_arp_addrs.ea)) {
+            ds_put_format(match, "eth.dst == { %s, %s }",
+                          op->proxy_arp_addrs.ea_s,
+                          op->peer->lrp_networks.ea_s);
+        } else {
+            ds_put_format(match, "eth.dst == %s", op->peer->lrp_networks.ea_s);
+        }
 
-            ds_clear(actions);
-            ds_put_format(actions, action, op->json_key);
-            ovn_lflow_add_with_hint(lflows, op->od,
-                                    S_SWITCH_IN_L2_LKUP,
-                                    50, ds_cstr(match),
-                                    ds_cstr(actions),
-                                    &op->nbsp->header_,
-                                    op->lflow_ref);
-        } else if (!strcmp(op->nbsp->addresses[i], "router")) {
-            if (!op->peer || !op->peer->nbrp
-                || !ovs_scan(op->peer->nbrp->mac,
-                        ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
-                continue;
-            }
-            ds_clear(match);
-            ds_put_cstr(match, "eth.dst == ");
-            if (!eth_addr_is_zero(op->proxy_arp_addrs.ea)) {
-                ds_put_format(match,
-                              "{ %s, "ETH_ADDR_FMT" }",
-                              op->proxy_arp_addrs.ea_s,
-                              ETH_ADDR_ARGS(mac));
+        if (op->peer->od->n_l3dgw_ports && op->od->n_localnet_ports) {
+            bool add_chassis_resident_check = false;
+            const char *json_key;
+            if (is_l3dgw_port(op->peer)) {
+                /* The peer of this port represents a distributed
+                    * gateway port. The destination lookup flow for the
+                    * router's distributed gateway port MAC address should
+                    * only be programmed on the gateway chassis. */
+                add_chassis_resident_check = true;
+                json_key = op->peer->cr_port->json_key;
             } else {
-                ds_put_format(match, ETH_ADDR_FMT, ETH_ADDR_ARGS(mac));
+                /* Check if the option 'reside-on-redirect-chassis'
+                 * is set to true on the peer port. If set to true
+                 * and if the logical switch has a localnet port, it
+                 * means the router pipeline for the packets from
+                 * this logical switch should be run on the chassis
+                 * hosting the gateway port.
+                 */
+                add_chassis_resident_check = smap_get_bool(
+                    &op->peer->nbrp->options,
+                    "reside-on-redirect-chassis", false) &&
+                    op->peer->od->n_l3dgw_ports == 1;
+                json_key = op->peer->od->l3dgw_ports[0]->cr_port->json_key;
             }
-            if (op->peer->od->n_l3dgw_ports
-                && op->od->n_localnet_ports) {
-                bool add_chassis_resident_check = false;
-                const char *json_key;
-                if (is_l3dgw_port(op->peer)) {
-                    /* The peer of this port represents a distributed
-                     * gateway port. The destination lookup flow for the
-                     * router's distributed gateway port MAC address should
-                     * only be programmed on the gateway chassis. */
-                    add_chassis_resident_check = true;
-                    json_key = op->peer->cr_port->json_key;
-                } else {
-                    /* Check if the option 'reside-on-redirect-chassis'
-                     * is set to true on the peer port. If set to true
-                     * and if the logical switch has a localnet port, it
-                     * means the router pipeline for the packets from
-                     * this logical switch should be run on the chassis
-                     * hosting the gateway port.
-                     */
-                    add_chassis_resident_check = smap_get_bool(
-                        &op->peer->nbrp->options,
-                        "reside-on-redirect-chassis", false) &&
-                        op->peer->od->n_l3dgw_ports == 1;
-                    json_key =
-                        op->peer->od->l3dgw_ports[0]->cr_port->json_key;
-                }
 
-                if (add_chassis_resident_check) {
-                    ds_put_format(match, " && is_chassis_resident(%s)",
-                                  json_key);
-                }
+            if (add_chassis_resident_check) {
+                ds_put_format(match, " && is_chassis_resident(%s)", json_key);
             }
+        }
+
+        ovn_lflow_add_with_hint(lflows, op->od,
+                                S_SWITCH_IN_L2_LKUP, 50,
+                                ds_cstr(match), ds_cstr(actions),
+                                &op->nbsp->header_,
+                                op->lflow_ref);
+    } else {
+        for (size_t i = 0; i < op->n_lsp_addrs; i++) {
+            ds_clear(match);
+            ds_put_format(match, "eth.dst == %s", op->lsp_addrs[i].ea_s);
 
-            ds_clear(actions);
-            ds_put_format(actions, action, op->json_key);
             ovn_lflow_add_with_hint(lflows, op->od,
                                     S_SWITCH_IN_L2_LKUP, 50,
                                     ds_cstr(match), ds_cstr(actions),
                                     &op->nbsp->header_,
                                     op->lflow_ref);
-        } else {
-            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
-
-            VLOG_INFO_RL(&rl,
-                         "%s: invalid syntax '%s' in addresses column",
-                         op->nbsp->name, op->nbsp->addresses[i]);
         }
     }
 }
