This reverts commit 1b4058b9162c27edc6bd42c3dedbef622e2fd0a7.

Commit caused issues with handling ARP requests to vif ports inside
switch that has connectivity to the external network through a localnet port,
as well as many other problems, so it was suggested to revert the commit.

Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2026-May/431983.html
Signed-off-by: Alexandra Rukomoinikova <[email protected]>
---
 Documentation/ref/ovn-logical-flows.7.rst |  10 -
 northd/automake.mk                        |   2 -
 northd/en-lflow.c                         |  29 --
 northd/en-lflow.h                         |   2 -
 northd/en-ls-arp.c                        | 354 ----------------------
 northd/en-ls-arp.h                        |  86 ------
 northd/inc-proc-northd.c                  |   6 -
 northd/northd.c                           | 171 +----------
 northd/northd.h                           |   9 -
 tests/ovn-inc-proc-graph-dump.at          |   4 -
 tests/ovn-northd.at                       | 113 +------
 tests/ovn.at                              | 154 ----------
 12 files changed, 12 insertions(+), 928 deletions(-)
 delete mode 100644 northd/en-ls-arp.c
 delete mode 100644 northd/en-ls-arp.h

diff --git a/Documentation/ref/ovn-logical-flows.7.rst 
b/Documentation/ref/ovn-logical-flows.7.rst
index 3f54c1cab..de04d242e 100644
--- a/Documentation/ref/ovn-logical-flows.7.rst
+++ b/Documentation/ref/ovn-logical-flows.7.rst
@@ -43,12 +43,6 @@ Ingress table 0 contains these logical flows:
   want to prevent duplicate replies and advertisements. This is achieved by a
   rule with priority 80 that sets ``REGBIT_PORT_SEC_DROP" = 1; next;"``.
 
-- For each logical switch that has connected physical ports (localnet or
-  l2gateway) and is also connected to a distributed router, filtering rules are
-  added for ARP requests coming from localnet or l2gateway ports, allowed for
-  processing on gateway chassis. The ``REGBIT_EXT_ARP`` register is set for all
-  ARP requests originating from physical ports with priority 75 flow.
-
 - For each (enabled) vtep logical port, a priority 70 flow is added which
   matches on all packets and applies the action ``next(pipeline=ingress,
   table=S_SWITCH_IN_L3_LKUP) = 1;`` to skip most stages of ingress pipeline and
@@ -104,10 +98,6 @@ Ingress table 1 contains these logical flows:
 - One priority-0 fallback flow that matches all packets and advances to the 
next
   table.
 
-- Priority 75: Allows ``REGBIT_EXT_ARP`` packets only on gateway chassis and
-  chassis with distributed NAT entries. Priority 70: Drops ``REGBIT_EXT_ARP``
-  packets on non-gateway chassis (complements the priority 75 flow).
-
 .. _ls-in-2:
 
 Ingress Table 2: Mirror
diff --git a/northd/automake.mk b/northd/automake.mk
index 8cd4fb3a1..45ca0337f 100644
--- a/northd/automake.mk
+++ b/northd/automake.mk
@@ -44,8 +44,6 @@ northd_ovn_northd_SOURCES = \
        northd/en-lr-stateful.h \
        northd/en-ls-stateful.c \
        northd/en-ls-stateful.h \
-       northd/en-ls-arp.c \
-       northd/en-ls-arp.h \
        northd/en-sampling-app.c \
        northd/en-sampling-app.h \
        northd/en-acl-ids.c \
diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index d4351edb9..8cb987777 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -23,7 +23,6 @@
 #include "en-lr-nat.h"
 #include "en-lr-stateful.h"
 #include "en-ls-stateful.h"
-#include "en-ls-arp.h"
 #include "en-multicast.h"
 #include "en-northd.h"
 #include "en-meters.h"
@@ -62,8 +61,6 @@ lflow_get_input_data(struct engine_node *node,
         engine_get_input_data("lr_stateful", node);
     struct ed_type_ls_stateful *ls_stateful_data =
         engine_get_input_data("ls_stateful", node);
-    struct ed_type_ls_arp *ls_arp_data =
-        engine_get_input_data("ls_arp", node);
     struct multicast_igmp_data *multicat_igmp_data =
         engine_get_input_data("multicast_igmp", node);
     struct ic_learned_svc_monitors_data *ic_learned_svc_monitors_data =
@@ -90,7 +87,6 @@ lflow_get_input_data(struct engine_node *node,
     lflow_input->ls_port_groups = &pg_data->ls_port_groups;
     lflow_input->lr_stateful_table = &lr_stateful_data->table;
     lflow_input->ls_stateful_table = &ls_stateful_data->table;
-    lflow_input->ls_arp_table = &ls_arp_data->table;
     lflow_input->meter_groups = &sync_meters_data->meter_groups;
     lflow_input->lb_datapaths_map = &northd_data->lb_datapaths_map;
     lflow_input->local_svc_monitors_map =
@@ -233,31 +229,6 @@ lflow_ls_stateful_handler(struct engine_node *node, void 
*data)
     return EN_HANDLED_UPDATED;
 }
 
-enum engine_input_handler_result
-lflow_ls_arp_handler(struct engine_node *node, void *data)
-{
-    struct ed_type_ls_arp *ls_arp_data =
-        engine_get_input_data("ls_arp", node);
-
-    if (!ls_arp_has_tracked_data(&ls_arp_data->trk_data)) {
-        return EN_UNHANDLED;
-    }
-
-    const struct engine_context *eng_ctx = engine_get_context();
-    struct lflow_data *lflow_data = data;
-    struct lflow_input lflow_input;
-
-    lflow_get_input_data(node, &lflow_input);
-    if (!lflow_handle_ls_arp_changes(eng_ctx->ovnsb_idl_txn,
-                                     &ls_arp_data->trk_data,
-                                     &lflow_input,
-                                     lflow_data->lflow_table)) {
-        return EN_UNHANDLED;
-    }
-
-    return EN_HANDLED_UPDATED;
-}
-
 enum engine_input_handler_result
 lflow_multicast_igmp_handler(struct engine_node *node, void *data)
 {
diff --git a/northd/en-lflow.h b/northd/en-lflow.h
index d2a92e49f..99bcfda15 100644
--- a/northd/en-lflow.h
+++ b/northd/en-lflow.h
@@ -25,8 +25,6 @@ lflow_lr_stateful_handler(struct engine_node *, void *data);
 enum engine_input_handler_result
 lflow_ls_stateful_handler(struct engine_node *node, void *data);
 enum engine_input_handler_result
-lflow_ls_arp_handler(struct engine_node *, void *);
-enum engine_input_handler_result
 lflow_multicast_igmp_handler(struct engine_node *node, void *data);
 enum engine_input_handler_result
 lflow_group_ecmp_route_change_handler(struct engine_node *node, void *data);
diff --git a/northd/en-ls-arp.c b/northd/en-ls-arp.c
deleted file mode 100644
index c48732b8c..000000000
--- a/northd/en-ls-arp.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <config.h>
-
-/* OVS includes */
-#include "include/openvswitch/hmap.h"
-#include "openvswitch/util.h"
-#include "openvswitch/vlog.h"
-
-/* OVN includes */
-#include "en-lr-nat.h"
-#include "en-ls-arp.h"
-#include "lib/inc-proc-eng.h"
-#include "lib/ovn-nb-idl.h"
-#include "lib/ovn-sb-idl.h"
-#include "lib/ovn-util.h"
-#include "lflow-mgr.h"
-#include "northd.h"
-
-VLOG_DEFINE_THIS_MODULE(en_ls_arp);
-
-/* Static functions. */
-struct ls_arp_input {
-    const struct ovn_datapaths *ls_datapaths;
-    const struct lr_nat_table *lr_nats;
-};
-
-static struct ls_arp_input
-ls_arp_get_input_data(struct engine_node *node)
-{
-    const struct northd_data *northd_data =
-        engine_get_input_data("northd", node);
-    struct ed_type_lr_nat_data *lr_nat_data =
-        engine_get_input_data("lr_nat", node);
-
-    return (struct ls_arp_input) {
-        .ls_datapaths = &northd_data->ls_datapaths,
-        .lr_nats = &lr_nat_data->lr_nats,
-    };
-}
-
-static void
-ls_arp_record_clear(struct ls_arp_record *ls_arp_record)
-{
-    lflow_ref_destroy(ls_arp_record->lflow_ref);
-    hmapx_destroy(&ls_arp_record->nat_records);
-    free(ls_arp_record);
-}
-
-static void
-ls_arp_table_clear(struct ls_arp_table *table)
-{
-    struct ls_arp_record *ls_arp_record;
-    HMAP_FOR_EACH_POP (ls_arp_record, key_node, &table->entries) {
-        ls_arp_record_clear(ls_arp_record);
-    }
-}
-
-static inline bool
-is_centralized_nat_record(const struct ovn_nat *nat_entry)
-{
-    return nat_entry->is_valid
-           && nat_entry->l3dgw_port
-           && nat_entry->l3dgw_port->peer
-           && nat_entry->l3dgw_port->peer->od
-           && !nat_entry->is_distributed;
-}
-
-static void
-nat_record_data_create(struct ls_arp_record *ls_arp_record,
-                       const struct ovn_datapath *od,
-                       const struct lr_nat_table *lr_nats)
-{
-    struct ovn_port *op;
-    VECTOR_FOR_EACH (&od->router_ports, op) {
-        const struct ovn_datapath *lr_od = op->peer->od;
-        const struct lr_nat_record *lrnat_rec =
-            lr_nat_table_find_by_uuid(lr_nats, lr_od->key);
-
-        if (!lrnat_rec) {
-            continue;
-        }
-
-        for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) {
-            const struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i];
-
-            if (is_centralized_nat_record(nat_entry)) {
-                hmapx_add(&ls_arp_record->nat_records,
-                          (struct lrnat_rec *) lrnat_rec);
-            }
-        }
-    }
-}
-
-static struct ls_arp_record *
-ls_arp_record_lookup_by_od_(const struct ls_arp_table *table,
-                            const struct ovn_datapath *od)
-{
-    struct ls_arp_record *ls_arp_record;
-    HMAP_FOR_EACH_WITH_HASH (ls_arp_record, key_node,
-                             uuid_hash(&od->nbs->header_.uuid),
-                             &table->entries) {
-        if (uuid_equals(&ls_arp_record->nbs_uuid,
-                        &od->nbs->header_.uuid)) {
-            return ls_arp_record;
-        }
-    }
-
-    return NULL;
-}
-
-static struct ls_arp_record *
-ls_arp_record_create(struct ls_arp_table *table,
-                     const struct ovn_datapath *od,
-                     const struct lr_nat_table *lr_nats)
-{
-    struct ls_arp_record *ls_arp_record = xzalloc(sizeof *ls_arp_record);
-
-    ls_arp_record->ls_index = od->sdp->index;
-    ls_arp_record->nbs_uuid = od->nbs->header_.uuid;
-
-    hmapx_init(&ls_arp_record->nat_records);
-    nat_record_data_create(ls_arp_record, od, lr_nats);
-
-    ls_arp_record->lflow_ref = lflow_ref_create();
-
-    hmap_insert(&table->entries, &ls_arp_record->key_node,
-                uuid_hash(&od->nbs->header_.uuid));
-
-    return ls_arp_record;
-}
-
-/* Public functions. */
-void*
-en_ls_arp_init(struct engine_node *node OVS_UNUSED,
-               struct engine_arg *arg OVS_UNUSED)
-{
-    struct ed_type_ls_arp *data = xzalloc(sizeof *data);
-
-    hmap_init(&data->table.entries);
-    hmapx_init(&data->trk_data.crupdated);
-    hmapx_init(&data->trk_data.deleted);
-
-    return data;
-}
-
-void
-en_ls_arp_clear_tracked_data(void *data_)
-{
-    struct ed_type_ls_arp *data = data_;
-    hmapx_clear(&data->trk_data.crupdated);
-
-    struct hmapx_node *n;
-    HMAPX_FOR_EACH_SAFE (n, &data->trk_data.deleted) {
-        ls_arp_record_clear(n->data);
-        hmapx_delete(&data->trk_data.deleted, n);
-    }
-    hmapx_clear(&data->trk_data.deleted);
-}
-
-void
-en_ls_arp_cleanup(void *data_)
-{
-    struct ed_type_ls_arp *data = data_;
-
-    ls_arp_table_clear(&data->table);
-    hmap_destroy(&data->table.entries);
-    hmapx_destroy(&data->trk_data.crupdated);
-
-    struct hmapx_node *n;
-    HMAPX_FOR_EACH_SAFE (n, &data->trk_data.deleted) {
-        ls_arp_record_clear(n->data);
-        hmapx_delete(&data->trk_data.deleted, n);
-    }
-    hmapx_destroy(&data->trk_data.deleted);
-}
-
-enum engine_node_state
-en_ls_arp_run(struct engine_node *node, void *data_)
-{
-    struct ls_arp_input input_data = ls_arp_get_input_data(node);
-    struct ed_type_ls_arp *data = data_;
-
-    ls_arp_table_clear(&data->table);
-
-    const struct ovn_datapath *od;
-    HMAP_FOR_EACH (od, key_node, &input_data.ls_datapaths->datapaths) {
-        /* Filtering ARP entries at logical switch works
-         * when there are physical ports on the switch. */
-        if (hmapx_is_empty(&od->phys_ports)) {
-            continue;
-        }
-
-        ls_arp_record_create(&data->table, od, input_data.lr_nats);
-    }
-
-    return EN_UPDATED;
-}
-
-/* Handler functions. */
-enum engine_input_handler_result
-ls_arp_northd_handler(struct engine_node *node, void *data_)
-{
-    struct northd_data *northd_data = engine_get_input_data("northd", node);
-    if (!northd_has_tracked_data(&northd_data->trk_data)) {
-        return EN_UNHANDLED;
-    }
-
-    if (!northd_has_lswitches_in_tracked_data(&northd_data->trk_data)) {
-        return EN_HANDLED_UNCHANGED;
-    }
-
-    struct northd_tracked_data *nd_changes = &northd_data->trk_data;
-    struct ls_arp_input input_data = ls_arp_get_input_data(node);
-    struct ed_type_ls_arp *data = data_;
-    struct hmapx_node *hmapx_node;
-    struct ls_arp_record *ls_arp_record;
-
-    HMAPX_FOR_EACH (hmapx_node, &nd_changes->trk_switches.crupdated) {
-        const struct ovn_datapath *od = hmapx_node->data;
-
-        ls_arp_record = ls_arp_record_lookup_by_od_(&data->table, od);
-
-        if (!ls_arp_record) {
-            /* Filtering ARP entries at logical switch works
-             * when there are physical ports on the switch. */
-            if (hmapx_is_empty(&od->phys_ports)) {
-                /* NOTE: If the switch used to have physical ports but those
-                 * were removed the lr_nat node has recomputed and triggers
-                 * the ls_arp_lr_nat_handler() which cannot incrementally
-                 * process changes.  This implicitly triggers correct
-                 * handling of the removal.*/
-                continue;
-            }
-            ls_arp_record = ls_arp_record_create(&data->table,
-                                                 od, input_data.lr_nats);
-        } else {
-            nat_record_data_create(ls_arp_record, od, input_data.lr_nats);
-        }
-
-        hmapx_add(&data->trk_data.crupdated, ls_arp_record);
-    }
-
-    HMAPX_FOR_EACH (hmapx_node, &nd_changes->trk_switches.deleted) {
-        const struct ovn_datapath *od = hmapx_node->data;
-
-        ls_arp_record = ls_arp_record_lookup_by_od_(&data->table, od);
-        if (ls_arp_record) {
-            hmap_remove(&data->table.entries, &ls_arp_record->key_node);
-            hmapx_add(&data->trk_data.deleted, ls_arp_record);
-        }
-    }
-
-    if (ls_arp_has_tracked_data(&data->trk_data)) {
-        return EN_HANDLED_UPDATED;
-    }
-
-    return EN_HANDLED_UNCHANGED;
-}
-
-static void
-nat_odmap_create(struct lr_nat_record *lrnat_rec,
-                 struct hmapx *odmap)
-{
-    for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) {
-        const struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i];
-
-        if (is_centralized_nat_record(nat_entry)) {
-            hmapx_add(odmap, nat_entry->l3dgw_port->peer->od);
-        }
-    }
-}
-
-enum engine_input_handler_result
-ls_arp_lr_nat_handler(struct engine_node *node, void *data_)
-{
-    struct ed_type_lr_nat_data *lr_nat_data =
-        engine_get_input_data("lr_nat", node);
-    struct ls_arp_input input_data = ls_arp_get_input_data(node);
-
-    if (!lr_nat_has_tracked_data(&lr_nat_data->trk_data)) {
-        return EN_UNHANDLED;
-    }
-
-    struct ed_type_ls_arp *data = data_;
-
-    struct hmapx_node *hmapx_node;
-    struct ls_arp_record *ls_arp_record;
-    HMAPX_FOR_EACH (hmapx_node, &lr_nat_data->trk_data.crupdated) {
-        struct lr_nat_record *nat_record_p = hmapx_node->data;
-
-        struct hmapx ls_links_map = HMAPX_INITIALIZER(&ls_links_map);
-        nat_odmap_create(nat_record_p, &ls_links_map);
-
-        LS_ARP_TABLE_FOR_EACH (ls_arp_record, &data->table) {
-            struct hmapx_node *nr_node =
-                hmapx_find(&ls_arp_record->nat_records, nat_record_p);
-
-            if (nr_node) {
-                hmapx_add(&data->trk_data.crupdated, ls_arp_record);
-                hmapx_delete(&ls_arp_record->nat_records, nr_node);
-            }
-        }
-
-        struct hmapx_node *crupdated_ls_hmapx;
-        HMAPX_FOR_EACH (crupdated_ls_hmapx, &ls_links_map) {
-            struct ovn_datapath *crupdated_ls = crupdated_ls_hmapx->data;
-            ls_arp_record =
-                ls_arp_record_lookup_by_od_(&data->table, crupdated_ls);
-
-            if (!ls_arp_record) {
-                ls_arp_record = ls_arp_record_create(&data->table,
-                                                     crupdated_ls,
-                                                     input_data.lr_nats);
-            }
-
-            hmapx_add(&data->trk_data.crupdated, ls_arp_record);
-            hmapx_add(&ls_arp_record->nat_records, nat_record_p);
-        }
-        hmapx_destroy(&ls_links_map);
-    }
-
-    HMAPX_FOR_EACH (hmapx_node, &lr_nat_data->trk_data.deleted) {
-        struct lr_nat_record *nr_cur = hmapx_node->data;
-
-        struct ls_arp_record *ar;
-        LS_ARP_TABLE_FOR_EACH (ar, &data->table) {
-            struct hmapx_node *nr_node = hmapx_find(&ar->nat_records, nr_cur);
-
-            if (nr_node) {
-                hmapx_add(&data->trk_data.crupdated, ar);
-                hmapx_delete(&ar->nat_records, nr_node);
-            }
-        }
-    }
-
-    if (ls_arp_has_tracked_data(&data->trk_data)) {
-        return EN_HANDLED_UPDATED;
-    }
-
-    return EN_HANDLED_UNCHANGED;
-}
diff --git a/northd/en-ls-arp.h b/northd/en-ls-arp.h
deleted file mode 100644
index 5eaf913bb..000000000
--- a/northd/en-ls-arp.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef EN_LS_ARP_H
-#define EN_LS_ARP_H 1
-
-/* OVS includes. */
-#include "lib/hmapx.h"
-#include "openvswitch/hmap.h"
-
-/* OVN includes. */
-#include "lib/inc-proc-eng.h"
-#include "lib/ovn-nb-idl.h"
-#include "lib/ovn-sb-idl.h"
-#include "lib/ovn-util.h"
-#include "lib/stopwatch-names.h"
-
-struct lflow_ref;
-
-struct ls_arp_record {
-    struct hmap_node key_node;
-
-    /* UUID of the NB Logical switch. */
-    struct uuid nbs_uuid;
-
-    /* Index of logical switch item in northd. */
-    size_t ls_index;
-
-    /* 'lflow_ref' is used to reference logical flows generated for
-     * this ls_arp record. */
-    struct lflow_ref *lflow_ref;
-
-    /* lr_nat_record ptrs that trigger this od to rebuild lflow. */
-    struct hmapx nat_records;
-};
-
-struct ls_arp_table {
-    struct hmap entries;
-};
-
-#define LS_ARP_TABLE_FOR_EACH(LS_ARP_REC, TABLE) \
-    HMAP_FOR_EACH (LS_ARP_REC, key_node, \
-                   &(TABLE)->entries)
-
-#define LS_ARP_TABLE_FOR_EACH_IN_P(LS_ARP_REC, JOBID, TABLE) \
-    HMAP_FOR_EACH_IN_PARALLEL (LS_ARP_REC, key_node, JOBID, \
-                               &(TABLE)->entries)
-
-struct ls_arp_tracked_data {
-    struct hmapx crupdated;
-    struct hmapx deleted;
-};
-
-struct ed_type_ls_arp {
-    struct ls_arp_table table;
-    struct ls_arp_tracked_data trk_data;
-};
-
-void *en_ls_arp_init(struct engine_node *, struct engine_arg *);
-void en_ls_arp_cleanup(void *);
-void en_ls_arp_clear_tracked_data(void *);
-enum engine_node_state en_ls_arp_run(struct engine_node *, void *);
-
-enum engine_input_handler_result
-ls_arp_lr_nat_handler(struct engine_node *, void *);
-enum engine_input_handler_result
-ls_arp_northd_handler(struct engine_node *, void *);
-
-static inline bool
-ls_arp_has_tracked_data(struct ls_arp_tracked_data *trk_data) {
-    return !hmapx_is_empty(&trk_data->crupdated) ||
-           !hmapx_is_empty(&trk_data->deleted);
-}
-
-#endif /* EN_LS_ARP_H */
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index ece388ce7..a2b464411 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -34,7 +34,6 @@
 #include "en-lr-stateful.h"
 #include "en-lr-nat.h"
 #include "en-ls-stateful.h"
-#include "en-ls-arp.h"
 #include "en-multicast.h"
 #include "en-northd.h"
 #include "en-lflow.h"
@@ -177,7 +176,6 @@ static ENGINE_NODE(lb_data, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(lr_nat, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(lr_stateful, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(ls_stateful, CLEAR_TRACKED_DATA);
-static ENGINE_NODE(ls_arp, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(route_policies);
 static ENGINE_NODE(routes);
 static ENGINE_NODE(bfd);
@@ -316,9 +314,6 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
                      ls_stateful_port_group_handler);
     engine_add_input(&en_ls_stateful, &en_nb_acl, ls_stateful_acl_handler);
 
-    engine_add_input(&en_ls_arp, &en_lr_nat, ls_arp_lr_nat_handler);
-    engine_add_input(&en_ls_arp, &en_northd, ls_arp_northd_handler);
-
     engine_add_input(&en_mac_binding_aging, &en_sb_mac_binding, NULL);
     engine_add_input(&en_mac_binding_aging, &en_northd, NULL);
     engine_add_input(&en_mac_binding_aging, &en_mac_binding_aging_waker, NULL);
@@ -422,7 +417,6 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_lflow, &en_port_group, engine_noop_handler);
     engine_add_input(&en_lflow, &en_lr_stateful, lflow_lr_stateful_handler);
     engine_add_input(&en_lflow, &en_ls_stateful, lflow_ls_stateful_handler);
-    engine_add_input(&en_lflow, &en_ls_arp, lflow_ls_arp_handler);
     engine_add_input(&en_lflow, &en_multicast_igmp,
                      lflow_multicast_igmp_handler);
     engine_add_input(&en_lflow, &en_sb_acl_id, NULL);
diff --git a/northd/northd.c b/northd/northd.c
index 088033a43..59351f47f 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -50,7 +50,6 @@
 #include "en-lr-nat.h"
 #include "en-lr-stateful.h"
 #include "en-ls-stateful.h"
-#include "en-ls-arp.h"
 #include "en-multicast.h"
 #include "en-sampling-app.h"
 #include "en-datapath-logical-switch.h"
@@ -143,7 +142,6 @@ static bool vxlan_mode;
 #define REGBIT_IP_FRAG            "reg0[19]"
 #define REGBIT_ACL_PERSIST_ID     "reg0[20]"
 #define REGBIT_ACL_HINT_ALLOW_PERSISTED "reg0[21]"
-#define REGBIT_EXT_ARP            "reg0[22]"
 
 /* Register definitions for switches and routers. */
 
@@ -571,7 +569,6 @@ ovn_datapath_create(struct hmap *datapaths, const struct 
uuid *key,
     hmap_insert(datapaths, &od->key_node, uuid_hash(&od->key));
     od->lr_group = NULL;
     hmap_init(&od->ports);
-    hmapx_init(&od->phys_ports);
     sset_init(&od->router_ips);
     od->ls_peers = VECTOR_EMPTY_INITIALIZER(struct ovn_datapath *);
     od->router_ports = VECTOR_EMPTY_INITIALIZER(struct ovn_port *);
@@ -612,7 +609,6 @@ ovn_datapath_destroy(struct ovn_datapath *od)
         vector_destroy(&od->l3dgw_ports);
         destroy_mcast_info_for_datapath(od);
         destroy_ports_for_datapath(od);
-        hmapx_destroy(&od->phys_ports);
         sset_destroy(&od->router_ips);
         lflow_ref_destroy(od->datapath_lflows);
         free(od);
@@ -1250,12 +1246,6 @@ lsp_is_vtep(const struct nbrec_logical_switch_port *nbsp)
     return !strcmp(nbsp->type, "vtep");
 }
 
-static bool
-lsp_is_l2gw(const struct nbrec_logical_switch_port *nbsp)
-{
-    return !strcmp(nbsp->type, "l2gateway");
-}
-
 static bool
 localnet_can_learn_mac(const struct nbrec_logical_switch_port *nbsp)
 {
@@ -1641,10 +1631,6 @@ join_logical_ports_lsp(struct hmap *ports,
         od->has_vtep_lports = true;
     }
 
-    if (lsp_is_localnet(nbsp) || lsp_is_l2gw(nbsp)) {
-        hmapx_add(&od->phys_ports, op);
-    }
-
     parse_lsp_addrs(op);
 
     op->od = od;
@@ -10172,92 +10158,6 @@ 
build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op,
     ds_destroy(&match);
 }
 
-/*
- * Create ARP filtering flow for od, assumed logical switch,
- * for the following condition:
- * Given lswitch has either localnet or l2gateway ports and
- * router connection ports that requires chassis residence.
- * ARP requests coming from localnet/l2gateway ports
- * allowed for processing on resident chassis only.
- */
-static void
-build_lswitch_arp_chassis_resident(const struct ovn_datapath *od,
-                                   struct lflow_table *lflows,
-                                   const struct ls_arp_record *ar)
-{
-    struct sset distributed_nat_ports =
-        SSET_INITIALIZER(&distributed_nat_ports);
-    struct hmapx resident_ports = HMAPX_INITIALIZER(&resident_ports);
-    struct ds match = DS_EMPTY_INITIALIZER;
-
-    struct ovn_port *op;
-    VECTOR_FOR_EACH (&od->router_ports, op) {
-        struct ovn_port *op_r = op->peer;
-
-        if (lrp_is_l3dgw(op_r)) {
-            hmapx_add(&resident_ports, op_r);
-        }
-    }
-
-    struct hmapx_node *hmapx_node;
-    HMAPX_FOR_EACH (hmapx_node, &ar->nat_records) {
-        struct lr_nat_record *nr = hmapx_node->data;
-
-        for (size_t i = 0; i < nr->n_nat_entries; i++) {
-            struct ovn_nat *ent = &nr->nat_entries[i];
-            if (ent->is_valid && ent->is_distributed) {
-                sset_add(&distributed_nat_ports, ent->nb->logical_port);
-            }
-        }
-    }
-
-    if (!hmapx_is_empty(&od->phys_ports) && !hmapx_is_empty(&resident_ports)) {
-        struct hmapx_node *node;
-        const char *port_name;
-
-        HMAPX_FOR_EACH (node, &od->phys_ports) {
-            op = node->data;
-
-            ds_clear(&match);
-            ds_put_format(&match, "(arp.op == 1 || arp.op == 2) "
-                                  "&& inport == %s",
-                          op->json_key);
-            ovn_lflow_add(lflows, od, S_SWITCH_IN_CHECK_PORT_SEC, 75,
-                          ds_cstr(&match), REGBIT_EXT_ARP " = 1; next;",
-                          ar->lflow_ref);
-        }
-
-        HMAPX_FOR_EACH (node, &resident_ports) {
-            op = node->data;
-
-            ds_clear(&match);
-            ds_put_format(&match, REGBIT_EXT_ARP" == 1");
-            if (od_is_centralized(op->od)) {
-                ds_put_format(&match, " && is_chassis_resident(%s)",
-                              op->cr_port->json_key);
-            }
-            ovn_lflow_add(lflows, od, S_SWITCH_IN_APPLY_PORT_SEC, 75,
-                          ds_cstr(&match), "next;", ar->lflow_ref);
-        }
-
-        SSET_FOR_EACH (port_name, &distributed_nat_ports) {
-            ds_clear(&match);
-            ds_put_format(&match, REGBIT_EXT_ARP " == 1 "
-                                  "&& is_chassis_resident(\"%s\")",
-                          port_name);
-            ovn_lflow_add(lflows, od, S_SWITCH_IN_APPLY_PORT_SEC, 75,
-                          ds_cstr(&match), "next;", ar->lflow_ref);
-        }
-
-        ovn_lflow_add(lflows, od, S_SWITCH_IN_APPLY_PORT_SEC, 70,
-                      REGBIT_EXT_ARP" == 1", "drop;", ar->lflow_ref);
-    }
-
-    sset_destroy(&distributed_nat_ports);
-    hmapx_destroy(&resident_ports);
-    ds_destroy(&match);
-}
-
 static bool
 is_vlan_transparent(const struct ovn_datapath *od)
 {
@@ -14882,6 +14782,10 @@ build_neigh_learning_flows_for_lrouter_port(
                           op->lrp_networks.ipv4_addrs[i].network_s,
                           op->lrp_networks.ipv4_addrs[i].plen,
                           op->lrp_networks.ipv4_addrs[i].addr_s);
+            if (lrp_is_l3dgw(op)) {
+                ds_put_format(match, " && is_chassis_resident(%s)",
+                              op->cr_port->json_key);
+            }
             const char *actions_s = REGBIT_LOOKUP_NEIGHBOR_RESULT
                               " = lookup_arp(inport, arp.spa, arp.sha); "
                               REGBIT_LOOKUP_NEIGHBOR_IP_RESULT" = 1;"
@@ -14896,6 +14800,10 @@ build_neigh_learning_flows_for_lrouter_port(
                       op->json_key,
                       op->lrp_networks.ipv4_addrs[i].network_s,
                       op->lrp_networks.ipv4_addrs[i].plen);
+        if (lrp_is_l3dgw(op)) {
+            ds_put_format(match, " && is_chassis_resident(%s)",
+                          op->cr_port->json_key);
+        }
         ds_clear(actions);
         ds_put_format(actions, REGBIT_LOOKUP_NEIGHBOR_RESULT
                       " = lookup_arp(inport, arp.spa, arp.sha); %snext;",
@@ -19459,7 +19367,6 @@ struct lswitch_flow_build_info {
     const struct ls_port_group_table *ls_port_groups;
     const struct lr_stateful_table *lr_stateful_table;
     const struct ls_stateful_table *ls_stateful_table;
-    const struct ls_arp_table *ls_arp_table;
     struct lflow_table *lflows;
     const struct shash *meter_groups;
     const struct hmap *lb_dps_map;
@@ -19661,7 +19568,6 @@ build_lflows_thread(void *arg)
     struct worker_control *control = (struct worker_control *) arg;
     const struct lr_stateful_record *lr_stateful_rec;
     const struct ls_stateful_record *ls_stateful_rec;
-    const struct ls_arp_record *ls_arp_rec;
     struct lswitch_flow_build_info *lsi;
     struct ovn_lb_datapaths *lb_dps;
     struct ovn_datapath *od;
@@ -19815,20 +19721,6 @@ build_lflows_thread(void *arg)
                                             lsi->sbrec_acl_id_table);
                 }
             }
-
-            for (bnum = control->id;
-                    bnum <= lsi->ls_arp_table->entries.mask;
-                    bnum += control->pool->size)
-            {
-                LS_ARP_TABLE_FOR_EACH_IN_P (ls_arp_rec, bnum,
-                                            lsi->ls_arp_table) {
-                    od = ovn_datapaths_find_by_index(
-                        lsi->ls_datapaths, ls_arp_rec->ls_index);
-                    build_lswitch_arp_chassis_resident(od, lsi->lflows,
-                                                       ls_arp_rec);
-                }
-            }
-
             lsi->thread_lflow_counter = thread_lflow_counter;
         }
         post_completed_work(control);
@@ -19877,7 +19769,6 @@ build_lswitch_and_lrouter_flows(
     const struct ls_port_group_table *ls_pgs,
     const struct lr_stateful_table *lr_stateful_table,
     const struct ls_stateful_table *ls_stateful_table,
-    const struct ls_arp_table *ls_arp_table,
     struct lflow_table *lflows,
     const struct shash *meter_groups,
     const struct hmap *lb_dps_map,
@@ -19914,7 +19805,6 @@ build_lswitch_and_lrouter_flows(
             lsiv[index].ls_port_groups = ls_pgs;
             lsiv[index].lr_stateful_table = lr_stateful_table;
             lsiv[index].ls_stateful_table = ls_stateful_table;
-            lsiv[index].ls_arp_table = ls_arp_table;
             lsiv[index].meter_groups = meter_groups;
             lsiv[index].lb_dps_map = lb_dps_map;
             lsiv[index].local_svc_monitor_map =
@@ -19951,7 +19841,6 @@ build_lswitch_and_lrouter_flows(
     } else {
         const struct lr_stateful_record *lr_stateful_rec;
         const struct ls_stateful_record *ls_stateful_rec;
-        const struct ls_arp_record *ls_arp_rec;
         struct ovn_lb_datapaths *lb_dps;
         struct ovn_datapath *od;
         struct ovn_port *op;
@@ -19964,7 +19853,6 @@ build_lswitch_and_lrouter_flows(
             .ls_port_groups = ls_pgs,
             .lr_stateful_table = lr_stateful_table,
             .ls_stateful_table = ls_stateful_table,
-            .ls_arp_table = ls_arp_table,
             .lflows = lflows,
             .meter_groups = meter_groups,
             .lb_dps_map = lb_dps_map,
@@ -20061,12 +19949,6 @@ build_lswitch_and_lrouter_flows(
                                     lsi.sbrec_acl_id_table);
         }
 
-        LS_ARP_TABLE_FOR_EACH (ls_arp_rec, ls_arp_table) {
-            od = ovn_datapaths_find_by_index(lsi.ls_datapaths,
-                                             ls_arp_rec->ls_index);
-            build_lswitch_arp_chassis_resident(od, lsi.lflows, ls_arp_rec);
-        }
-
         ds_destroy(&lsi.match);
         ds_destroy(&lsi.actions);
     }
@@ -20150,7 +20032,6 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn,
                                     input_data->ls_port_groups,
                                     input_data->lr_stateful_table,
                                     input_data->ls_stateful_table,
-                                    input_data->ls_arp_table,
                                     lflows,
                                     input_data->meter_groups,
                                     input_data->lb_datapaths_map,
@@ -20663,42 +20544,6 @@ lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
     return true;
 }
 
-bool
-lflow_handle_ls_arp_changes(struct ovsdb_idl_txn *ovnsb_txn,
-                            struct ls_arp_tracked_data *trk_data,
-                            struct lflow_input *lflow_input,
-                            struct lflow_table *lflows)
-{
-    struct hmapx_node *hmapx_node;
-
-    HMAPX_FOR_EACH (hmapx_node, &trk_data->crupdated) {
-        const struct ls_arp_record *ls_arp_record = hmapx_node->data;
-        const struct ovn_datapath *od =
-            ovn_datapaths_find_by_index(lflow_input->ls_datapaths,
-                                        ls_arp_record->ls_index);
-        lflow_ref_unlink_lflows(ls_arp_record->lflow_ref);
-
-        build_lswitch_arp_chassis_resident(od, lflows, ls_arp_record);
-
-        bool handled = lflow_ref_sync_lflows(
-            ls_arp_record->lflow_ref, lflows, ovnsb_txn,
-            lflow_input->dps,
-            lflow_input->ovn_internal_version_changed,
-            lflow_input->sbrec_logical_flow_table,
-            lflow_input->sbrec_logical_dp_group_table);
-        if (!handled) {
-            return false;
-        }
-    }
-
-    HMAPX_FOR_EACH (hmapx_node, &trk_data->deleted) {
-        struct ls_arp_record *ls_arp_record = hmapx_node->data;
-        lflow_ref_unlink_lflows(ls_arp_record->lflow_ref);
-    }
-
-    return true;
-}
-
 static bool
 mirror_needs_update(const struct nbrec_mirror *nb_mirror,
                     const struct sbrec_mirror *sb_mirror)
diff --git a/northd/northd.h b/northd/northd.h
index 80f8e7687..ac07a58de 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -29,7 +29,6 @@
 #include "simap.h"
 #include "ovs-thread.h"
 #include "en-lr-stateful.h"
-#include "en-ls-arp.h"
 #include "vec.h"
 #include "datapath-sync.h"
 #include "sparse-array.h"
@@ -267,7 +266,6 @@ struct lflow_input {
     const struct ls_port_group_table *ls_port_groups;
     const struct lr_stateful_table *lr_stateful_table;
     const struct ls_stateful_table *ls_stateful_table;
-    const struct ls_arp_table *ls_arp_table;
     const struct shash *meter_groups;
     const struct hmap *lb_datapaths_map;
     const struct sset *bfd_ports;
@@ -473,9 +471,6 @@ struct ovn_datapath {
      * Valid only if it is logical router datapath. NULL otherwise. */
     struct lrouter_group *lr_group;
 
-    /* Set of localnet or l2gw ports. */
-    struct hmapx phys_ports;
-
     /* Map of ovn_port objects belonging to this datapath.
      * This map doesn't include derived ports. */
     struct hmap ports;
@@ -978,10 +973,6 @@ bool lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn 
*,
                                       struct ls_stateful_tracked_data *,
                                       struct lflow_input *,
                                       struct lflow_table *lflows);
-bool lflow_handle_ls_arp_changes(struct ovsdb_idl_txn *,
-                                 struct ls_arp_tracked_data *,
-                                 struct lflow_input *,
-                                 struct lflow_table *lflows);
 bool northd_handle_sb_port_binding_changes(
     const struct sbrec_port_binding_table *, struct hmap *ls_ports,
     struct hmap *lr_ports);
diff --git a/tests/ovn-inc-proc-graph-dump.at b/tests/ovn-inc-proc-graph-dump.at
index bb84d03a3..3750339d0 100644
--- a/tests/ovn-inc-proc-graph-dump.at
+++ b/tests/ovn-inc-proc-graph-dump.at
@@ -174,9 +174,6 @@ digraph "Incremental-Processing-Engine" {
        northd -> ls_stateful [[label="ls_stateful_northd_handler"]];
        port_group -> ls_stateful [[label="ls_stateful_port_group_handler"]];
        NB_acl -> ls_stateful [[label="ls_stateful_acl_handler"]];
-       ls_arp [[style=filled, shape=box, fillcolor=white, label="ls_arp"]];
-       lr_nat -> ls_arp [[label="ls_arp_lr_nat_handler"]];
-       northd -> ls_arp [[label="ls_arp_northd_handler"]];
        SB_igmp_group [[style=filled, shape=box, fillcolor=white, 
label="SB_igmp_group"]];
        multicast_igmp [[style=filled, shape=box, fillcolor=white, 
label="multicast_igmp"]];
        northd -> multicast_igmp [[label="multicast_igmp_northd_handler"]];
@@ -198,7 +195,6 @@ digraph "Incremental-Processing-Engine" {
        port_group -> lflow [[label="engine_noop_handler"]];
        lr_stateful -> lflow [[label="lflow_lr_stateful_handler"]];
        ls_stateful -> lflow [[label="lflow_ls_stateful_handler"]];
-       ls_arp -> lflow [[label="lflow_ls_arp_handler"]];
        multicast_igmp -> lflow [[label="lflow_multicast_igmp_handler"]];
        SB_acl_id -> lflow [[label=""]];
        ic_learned_svc_monitors -> lflow 
[[label="lflow_ic_learned_svc_mons_handler"]];
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index a57c3bad8..2808e67fe 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -7578,6 +7578,9 @@ AT_CHECK([grep lr_in_admission lrflows | grep cr-DR | 
ovn_strip_lflows], [0], [d
 ])
 # Check the flows in lr_in_lookup_neighbor stage
 AT_CHECK([grep lr_in_lookup_neighbor lrflows | grep cr-DR | ovn_strip_lflows], 
[0], [dnl
+  table=??(lr_in_lookup_neighbor), priority=100  , match=(inport == "DR-S1" && 
arp.spa == 172.16.1.0/24 && arp.op == 1 && is_chassis_resident("cr-DR-S1")), 
action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;)
+  table=??(lr_in_lookup_neighbor), priority=100  , match=(inport == "DR-S2" && 
arp.spa == 172.16.2.0/24 && arp.op == 1 && is_chassis_resident("cr-DR-S2")), 
action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;)
+  table=??(lr_in_lookup_neighbor), priority=100  , match=(inport == "DR-S3" && 
arp.spa == 172.16.3.0/24 && arp.op == 1 && is_chassis_resident("cr-DR-S3")), 
action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;)
   table=??(lr_in_lookup_neighbor), priority=120  , match=(inport == "DR-S1" && 
(nd_na || nd_ns) && eth.mcast && !is_chassis_resident("cr-DR-S1")), 
action=(reg9[[2]] = 1; next;)
   table=??(lr_in_lookup_neighbor), priority=120  , match=(inport == "DR-S2" && 
(nd_na || nd_ns) && eth.mcast && !is_chassis_resident("cr-DR-S2")), 
action=(reg9[[2]] = 1; next;)
   table=??(lr_in_lookup_neighbor), priority=120  , match=(inport == "DR-S3" && 
(nd_na || nd_ns) && eth.mcast && !is_chassis_resident("cr-DR-S3")), 
action=(reg9[[2]] = 1; next;)
@@ -14537,7 +14540,7 @@ AT_CHECK([grep -Fe "172.168.0.110" -e "172.168.0.120" 
-e "10.0.0.3" -e "20.0.0.3
   table=??(lr_out_undnat      ), priority=100  , match=(ip && ip4.src == 
20.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), 
action=(ct_dnat;)
 ])
 
-AT_CHECK([grep -Fe "172.168.0.110" -e "172.168.0.120" -e "10.0.0.3" -e 
"20.0.0.3" -e "30:54:00:00:00:03"  -e "sw0-port1" publicflows | 
ovn_strip_lflows | grep -v "reg0.*22"], [0], [dnl
+AT_CHECK([grep -Fe "172.168.0.110" -e "172.168.0.120" -e "10.0.0.3" -e 
"20.0.0.3" -e "30:54:00:00:00:03"  -e "sw0-port1" publicflows | 
ovn_strip_lflows], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
30:54:00:00:00:03 && is_chassis_resident("sw0-port1")), action=(outport = 
"public-lr0"; output;)
   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == 
{00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && 
(arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = "_MC_flood_l2"; 
output;)
   table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && 
arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = 
"public-lr0"; output; }; outport = "_MC_unknown"; output;)
@@ -19947,98 +19950,6 @@ OVN_CLEANUP_NORTHD
 AT_CLEANUP
 ])
 
-OVN_FOR_EACH_NORTHD_NO_HV([
-AT_SETUP([Logical Switch ARP filtering])
-ovn_start
-
-check ovn-nbctl lr-add lr1
-check ovn-nbctl lrp-add lr1 down_link f0:00:00:00:00:f1 192.168.1.1/24
-
-check ovn-nbctl ls-add ls1
-check ovn-nbctl lsp-add ls1 up_link
-check ovn-nbctl lsp-add ls1 down_vif1
-check ovn-nbctl lsp-add ls1 down_vif2
-check ovn-nbctl lsp-add ls1 down_ext
-
-check ovn-nbctl set Logical_Switch_Port up_link \
-    type=router \
-    options:router-port=down_link \
-    addresses=router
-
-check ovn-nbctl lsp-set-addresses down_vif1 'f0:00:00:00:00:01 192.168.1.101'
-check ovn-nbctl lsp-set-addresses down_vif2 'f0:00:00:00:00:02 192.168.1.102'
-check ovn-nbctl lrp-set-gateway-chassis down_link hv1
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-])
-
-# Check localnet port addings trigger ls-arp flow
-check ovn-nbctl --wait=sb lsp-set-type down_ext localnet
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=70   , match=(reg0[[22]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-down_link")), action=(next;)
-])
-
-# Check nat adding to dgr attached to logical switch trigger ls-arp flow.
-check ovn-nbctl lr-nat-add lr1 dnat_and_snat 192.168.0.4 10.0.0.4
-check ovn-nbctl lr-nat-add lr1 dnat_and_snat 192.168.0.3 10.0.0.3 down_vif1 
f0:00:00:00:00:03
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=70   , match=(reg0[[22]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-down_link")), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("down_vif1")), action=(next;)
-])
-
-check ovn-nbctl --wait=sb lr-nat-del lr1 dnat_and_snat 192.168.0.3
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=70   , match=(reg0[[22]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-down_link")), action=(next;)
-])
-
-# Check changing logical port type to l2gateway.
-check ovn-nbctl --wait=sb lsp-set-type down_ext l2gateway
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=70   , match=(reg0[[22]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-down_link")), action=(next;)
-])
-
-# Check changing logical port type to vif.
-check ovn-nbctl --wait=sb lsp-set-type down_ext ''
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-])
-
-# Check changing logical port type back to localnet.
-check ovn-nbctl --wait=sb lsp-set-type down_ext localnet
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=70   , match=(reg0[[22]] == 1), 
action=(drop;)
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-down_link")), action=(next;)
-])
-
-# Check changing removing logical port.
-check ovn-nbctl --wait=sb lsp-del down_ext
-AT_CHECK([ovn-sbctl lflow-list ls1 | grep ls_in_apply_port_sec | 
ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
-])
-
-OVN_CLEANUP_NORTHD
-AT_CLEANUP
-])
-
 OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([IGMP northd crash])
 ovn_start
@@ -20259,14 +20170,6 @@ AT_CHECK([cat lr1_lflows_before | grep lr_in_dnat | 
grep priority=120 | ovn_stri
   table=??(lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && 
ip6 && ip6.dst == 2000::1 && reg1[[16..23]] == 6 && reg1[[0..15]] == 80 && 
is_chassis_resident("cr-lr1-up")), 
action=(ct_lb_mark(backends=[[2001:db8:abcd:1::2]]:10882);)
 ])
 
-AT_CHECK([cat outside_lflows_before | grep ls_in_check_port_sec | grep 
priority=75 | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_check_port_sec), priority=75   , match=(arp.op == 1 && inport 
== "outside"), action=(reg0[[22]] = 1; next;)
-])
-
-AT_CHECK([cat outside_lflows_before | grep ls_in_apply_port_sec | grep 
priority=75 | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1 && 
is_chassis_resident("cr-lr1-up")), action=(next;)
-])
-
 check ovn-nbctl clear logical_router_port $lr1_up_uuid ha_chassis_group
 check ovn-nbctl ha-chassis-group-del gateway
 check ovn-nbctl ha-chassis-group-add gateway2
@@ -20318,14 +20221,6 @@ AT_CHECK([cat lr1_lflows_after | grep lr_in_dnat | 
grep priority=120 | ovn_strip
   table=??(lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && 
ip6 && ip6.dst == 2000::1 && reg1[[16..23]] == 6 && reg1[[0..15]] == 80 && 
is_chassis_resident("cr-lr1-up")), 
action=(ct_lb_mark(backends=[[2001:db8:abcd:1::2]]:10882);)
 ])
 
-AT_CHECK([cat outside_lflows_after | grep ls_in_check_port_sec | grep 
priority=75 | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_check_port_sec), priority=75   , match=(arp.op == 1 && inport 
== "outside"), action=(reg0[[22]] = 1; next;)
-])
-
-AT_CHECK([cat outside_lflows_after | grep ls_in_apply_port_sec | grep 
priority=75 | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_apply_port_sec), priority=75   , match=(reg0[[22]] == 1), 
action=(next;)
-])
-
 check ovn-nbctl --wait=sb set load_balancer lb1_ipv6 options:distributed=true
 
 ovn-sbctl lflow-list outside > outside_lflows_after
diff --git a/tests/ovn.at b/tests/ovn.at
index 7a7121c4f..509c33494 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -44837,160 +44837,6 @@ OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
 
-OVN_FOR_EACH_NORTHD([
-AT_SETUP([GARP delivery: gw and external ports])
-AT_SKIP_IF([test $HAVE_SCAPY = no])
-ovn_start
-
-# Configure initial environment
-# LR1: down_link <-> LS1: up_link
-# set lr_down: gateway port (chassis redirect) bound to hv1
-# LS1: down_vif1 - vif port bound to hv1
-#      down_vif2 - vif port bound to hv2
-#      down_ext - outer (port will be iterated as localnet, l2gateway)
-#
-# Test: send GARP request from virtual ports (down_vif1, down_vif2)
-#       ensure mac_binding is always updated.
-#       (Fixing the issue: mac_binding is only updated for packets came from
-#        down_link's resident chassis)
-#       send GARP request from from localnet.
-#       ensure mac_binding is updated only if localnet bound to same hv as 
l3dgw
-
-check ovn-nbctl lr-add lr1
-check ovn-nbctl lrp-add lr1 down_link f0:00:00:00:00:f1 192.168.1.1/24
-
-check ovn-nbctl ls-add ls1
-check ovn-nbctl lsp-add ls1 up_link
-check ovn-nbctl lsp-add ls1 down_vif1
-check ovn-nbctl lsp-add ls1 down_vif2
-check ovn-nbctl lsp-add ls1 down_ext
-
-check ovn-nbctl set Logical_Switch_Port up_link \
-    type=router \
-    options:router-port=down_link \
-    addresses=router
-
-check ovn-nbctl lsp-set-addresses down_vif1 'f0:00:00:00:00:01 192.168.1.101'
-check ovn-nbctl lsp-set-addresses down_vif2 'f0:00:00:00:00:02 192.168.1.102'
-
-check ovn-nbctl lsp-set-type down_ext localnet
-check ovn-nbctl lsp-set-options down_ext network_name=physnet1
-check ovn-nbctl lrp-set-gateway-chassis down_link hv1
-
-net_add n1
-
-# Create hypervisor hv1 connected to n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl add-port br-int vif1 -- \
-    set Interface vif1 external-ids:iface-id=down_vif1 \
-    options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap
-
-# Create hypervisor hv2 connected to n1, add localnet here
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovs-vsctl add-br br-eth0
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl add-port br-int vif2 -- \
-    set Interface vif2 external-ids:iface-id=down_vif2 \
-    options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap
-
-ovs-vsctl set Open_vSwitch . 
external_ids:ovn-bridge-mappings="physnet1:br-eth0"
-
-ovs-vsctl add-port br-eth0 vif_ext -- \
-    set Interface vif_ext options:tx_pcap=hv2/vif_ext-tx.pcap \
-    options:rxq_pcap=hv2/vif_ext-rx.pcap
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-wait_for_ports_up
-check ovn-nbctl --wait=hv sync
-
-# Annonce 192.168.1.222 from localnet in hv2
-# result: drop, hv2 is not gateway chassis for down_link
-sha=02:00:00:00:00:ee
-tha=00:00:00:00:00:00
-spa=192.168.1.222
-tpa=$spa
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv2 ovs-appctl netdev-dummy/receive vif_ext $garp
-
-# Make hv2 gateway chassis
-# Annonce 192.168.1.223 from localnet in hv2
-# result: ok, hv2 is gateway chassis for down_link
-#
-check ovn-nbctl lrp-set-gateway-chassis down_link hv2
-
-wait_row_count Port_Binding 1 logical_port=cr-down_link 'chassis!=[[]]'
-check ovn-nbctl --wait=hv sync
-
-sha=02:00:00:00:00:ee
-tha=00:00:00:00:00:00
-spa=192.168.1.223
-tpa=$spa
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv2 ovs-appctl netdev-dummy/receive vif_ext $garp
-
-# Annonce 192.168.1.111, 112 from vif1, vif2 in hv1, hv2
-# result: ok, vif1, vif2 are virtual ports, restrictions are not applied.
-sha=f0:00:00:00:00:01
-tha=00:00:00:00:00:00
-spa=192.168.1.111
-tpa=0.0.0.0
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv1 ovs-appctl netdev-dummy/receive vif1 $garp
-
-sha=f0:00:00:00:00:02
-tha=00:00:00:00:00:00
-spa=192.168.1.112
-tpa=0.0.0.0
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv2 ovs-appctl netdev-dummy/receive vif2 $garp
-
-# Set down_ext type to l2gateway
-# Annonce 192.168.1.113, 114 from vif1, vif2 in hv1, hv2
-# result: ok, vif1, vif2 are virtual ports, restrictions are not applied.
-check ovn-nbctl --wait=hv lsp-set-type down_ext l2gateway
-
-sha=f0:00:00:00:00:01
-tha=00:00:00:00:00:00
-spa=192.168.1.113
-tpa=0.0.0.0
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv1 ovs-appctl netdev-dummy/receive vif1 $garp
-
-sha=f0:00:00:00:00:02
-tha=00:00:00:00:00:00
-spa=192.168.1.114
-tpa=0.0.0.0
-garp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \
-                ARP(hwsrc='${sha}', hwdst='${tha}', psrc='${spa}', 
pdst='${tpa}')")
-as hv2 ovs-appctl netdev-dummy/receive vif2 $garp
-
-wait_row_count MAC_Binding 1 ip="192.168.1.111" mac='"f0:00:00:00:00:01"' 
logical_port='"down_link"'
-wait_row_count MAC_Binding 1 ip="192.168.1.112" mac='"f0:00:00:00:00:02"' 
logical_port='"down_link"'
-wait_row_count MAC_Binding 1 ip="192.168.1.113" mac='"f0:00:00:00:00:01"' 
logical_port='"down_link"'
-wait_row_count MAC_Binding 1 ip="192.168.1.114" mac='"f0:00:00:00:00:02"' 
logical_port='"down_link"'
-wait_row_count MAC_Binding 1 ip="192.168.1.223" mac='"02:00:00:00:00:ee"' 
logical_port='"down_link"'
-wait_row_count MAC_Binding 0 ip="192.168.1.222" mac='"02:00:00:00:00:ee"' 
logical_port='"down_link"'
-
-check ovn-nbctl --wait=hv lsp-set-type down_ext localnet
-
-OVN_CLEANUP([hv1],[hv2])
-AT_CLEANUP
-])
-
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([Port security - VRRPv3 ARP/ND])
 AT_SKIP_IF([test $HAVE_SCAPY = no])
-- 
2.48.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to