diff --git a/northd/helpers.dl b/northd/helpers.dl
index 820e37bb3072..757532e46c0e 100644
--- a/northd/helpers.dl
+++ b/northd/helpers.dl
@@ -23,7 +23,7 @@ output relation Warning[string]
 /* Switch-to-router logical port connections */
 relation SwitchRouterPeer(lsp: uuid, lsp_name: string, lrp: uuid)
 SwitchRouterPeer(lsp, lsp_name, lrp) :-
-    nb::Logical_Switch_Port(._uuid = lsp, .name = lsp_name, .__type = "router", .options = options),
+    &nb::Logical_Switch_Port(._uuid = lsp, .name = lsp_name, .__type = "router", .options = options),
     Some{var router_port} = options.get("router-port"),
     &nb::Logical_Router_Port(.name = router_port, ._uuid = lrp).
 
diff --git a/northd/lrouter.dl b/northd/lrouter.dl
index 81e4a03e8a91..38a19e7ea324 100644
--- a/northd/lrouter.dl
+++ b/northd/lrouter.dl
@@ -92,7 +92,7 @@ FirstHopLogicalRouter(lrouter, lswitch) :-
 relation LogicalSwitchRouterPort(lsp: uuid, lsp_router_port: string, ls: uuid)
 LogicalSwitchRouterPort(lsp, lsp_router_port, ls) :-
   LogicalSwitchPort(lsp, ls),
-  nb::Logical_Switch_Port(._uuid = lsp, .__type = "router", .options = options),
+  &nb::Logical_Switch_Port(._uuid = lsp, .__type = "router", .options = options),
   Some{var lsp_router_port} = options.get("router-port").
 
 /*
diff --git a/northd/lswitch.dl b/northd/lswitch.dl
index 7a49ac17dbab..419117f743b3 100644
--- a/northd/lswitch.dl
+++ b/northd/lswitch.dl
@@ -22,7 +22,7 @@ import helpers
 import ipam
 import vec
 
-function is_enabled(lsp: nb::Logical_Switch_Port): bool { is_enabled(lsp.enabled) }
+function is_enabled(lsp: Intern<nb::Logical_Switch_Port>): bool { is_enabled(lsp.enabled) }
 function is_enabled(sp: SwitchPort): bool { sp.lsp.is_enabled() }
 function is_enabled(sp: Intern<SwitchPort>): bool { sp.lsp.is_enabled() }
 
@@ -33,7 +33,7 @@ SwitchRouterPeerRef(lsp, Some{rport}) :-
     rport in &RouterPort(.lrp = &nb::Logical_Router_Port{._uuid = lrp}).
 
 SwitchRouterPeerRef(lsp, None) :-
-    nb::Logical_Switch_Port(._uuid = lsp),
+    &nb::Logical_Switch_Port(._uuid = lsp),
     not SwitchRouterPeer(lsp, _, _).
 
 /* LogicalSwitchPortCandidate.
@@ -50,7 +50,7 @@ Warning[message] :-
     LogicalSwitchPortCandidate(lsp_uuid, ls_uuid),
     var lss = ls_uuid.group_by(lsp_uuid).to_set(),
     lss.size() > 1,
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     var message = "Bad configuration: logical switch port ${lsp.name} belongs "
     "to more than one logical switch".
 
@@ -66,7 +66,7 @@ LogicalSwitchPort(lsp_uuid, ls_uuid) :-
 relation LogicalSwitchPortWithUnknownAddress(ls: uuid, lsp: uuid)
 LogicalSwitchPortWithUnknownAddress(ls_uuid, lsp_uuid) :-
     LogicalSwitchPort(lsp_uuid, ls_uuid),
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     lsp.is_enabled() and lsp.addresses.contains("unknown").
 
 relation LogicalSwitchHasUnknownPorts(ls: uuid, has_unknown: bool)
@@ -81,7 +81,7 @@ relation PortStaticAddresses(lsport: uuid, ip4addrs: Set<string>, ip6addrs: Set<
 PortStaticAddresses(.lsport     = port_uuid,
                     .ip4addrs   = ip4_addrs.union(),
                     .ip6addrs   = ip6_addrs.union()) :-
-    nb::Logical_Switch_Port(._uuid = port_uuid, .addresses = addresses),
+    &nb::Logical_Switch_Port(._uuid = port_uuid, .addresses = addresses),
     var address = FlatMap(if (addresses.is_empty()) { set_singleton("") } else { addresses }),
     (var ip4addrs, var ip6addrs) = if (not is_dynamic_lsp_address(address)) {
         split_addresses(address)
@@ -133,7 +133,7 @@ relation LogicalSwitchLocalnetPort0(ls_uuid: uuid, lsp: (uuid, string))
 LogicalSwitchLocalnetPort0(ls_uuid, (lsp_uuid, lsp.name)) :-
     ls in nb::Logical_Switch(._uuid = ls_uuid),
     var lsp_uuid = FlatMap(ls.ports),
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     lsp.__type == "localnet".
 
 relation LogicalSwitchLocalnetPorts(ls_uuid: uuid, localnet_ports: Vec<(uuid, string)>)
@@ -173,7 +173,7 @@ relation LogicalSwitchHasNonRouterPort0(ls: uuid)
 LogicalSwitchHasNonRouterPort0(ls_uuid) :-
     ls in nb::Logical_Switch(._uuid = ls_uuid),
     var lsp_uuid = FlatMap(ls.ports),
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     lsp.__type != "router".
 
 relation LogicalSwitchHasNonRouterPort(ls: uuid, has_non_router_port: bool)
@@ -512,9 +512,9 @@ relation &SwitchACL(sw: Intern<Switch>,
 function oVN_FEATURE_PORT_UP_NOTIF(): string { "port-up-notif" }
 relation SwitchPortUp0(lsp: uuid)
 SwitchPortUp0(lsp) :-
-    nb::Logical_Switch_Port(._uuid = lsp, .__type = "router").
+    &nb::Logical_Switch_Port(._uuid = lsp, .__type = "router").
 SwitchPortUp0(lsp) :-
-    nb::Logical_Switch_Port(._uuid = lsp, .name = lsp_name, .__type = __type),
+    &nb::Logical_Switch_Port(._uuid = lsp, .name = lsp_name, .__type = __type),
     sb::Port_Binding(.logical_port = lsp_name, .up = up, .chassis = Some{chassis_uuid}),
     sb::Chassis(._uuid = chassis_uuid, .other_config = other_config),
     if (other_config.get_bool_def(oVN_FEATURE_PORT_UP_NOTIF(), false)) {
@@ -525,11 +525,11 @@ SwitchPortUp0(lsp) :-
 
 relation SwitchPortUp(lsp: uuid, up: bool)
 SwitchPortUp(lsp, true) :- SwitchPortUp0(lsp).
-SwitchPortUp(lsp, false) :- nb::Logical_Switch_Port(._uuid = lsp), not SwitchPortUp0(lsp).
+SwitchPortUp(lsp, false) :- &nb::Logical_Switch_Port(._uuid = lsp), not SwitchPortUp0(lsp).
 
 relation SwitchPortHAChassisGroup0(lsp_uuid: uuid, hac_group_uuid: uuid)
 SwitchPortHAChassisGroup0(lsp_uuid, ha_chassis_group_uuid(ls_uuid)) :-
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     lsp.__type == "external",
     Some{var hac_group_uuid} = lsp.ha_chassis_group,
     ha_chassis_group in nb::HA_Chassis_Group(._uuid = hac_group_uuid),
@@ -542,7 +542,7 @@ relation SwitchPortHAChassisGroup(lsp_uuid: uuid, hac_group_uuid: Option<uuid>)
 SwitchPortHAChassisGroup(lsp_uuid, Some{hac_group_uuid}) :-
     SwitchPortHAChassisGroup0(lsp_uuid, hac_group_uuid).
 SwitchPortHAChassisGroup(lsp_uuid, None) :-
-    lsp in nb::Logical_Switch_Port(._uuid = lsp_uuid),
+    lsp in &nb::Logical_Switch_Port(._uuid = lsp_uuid),
     not SwitchPortHAChassisGroup0(lsp_uuid, _).
 
 /* SwitchPort relation collects all attributes of a logical switch port
@@ -558,7 +558,7 @@ SwitchPortHAChassisGroup(lsp_uuid, None) :-
  * - 'hac_group_uuid'            - uuid of sb::HA_Chassis_Group, only for "external" ports
  */
 typedef SwitchPort = SwitchPort {
-    lsp:                        nb::Logical_Switch_Port,
+    lsp:                        Intern<nb::Logical_Switch_Port>,
     json_name:                  string,
     sw:                         Intern<Switch>,
     peer:                       Option<Intern<RouterPort>>,
@@ -602,7 +602,7 @@ SwitchPort[SwitchPort{
               .mcast_cfg                  = mcast_cfg,
               .hac_group_uuid             = hac_group_uuid
            }.intern()] :-
-    nb::Logical_Switch_Port[lsp],
+    lsp in &nb::Logical_Switch_Port(),
     LogicalSwitchPort(lsp._uuid, lswitch_uuid),
     sw in &Switch(._uuid = lswitch_uuid,
                   .other_config = other_config,
diff --git a/northd/multicast.dl b/northd/multicast.dl
index bd9bc9b46f61..dfd58f4770bd 100644
--- a/northd/multicast.dl
+++ b/northd/multicast.dl
@@ -96,7 +96,7 @@ typedef McastPortCfg = McastPortCfg {
 relation McastPortCfg[Intern<McastPortCfg>]
 
 McastPortCfg[McastPortCfg{lsp_uuid, false, flood, flood_reports}.intern()] :-
-    nb::Logical_Switch_Port(._uuid = lsp_uuid, .options = options),
+    &nb::Logical_Switch_Port(._uuid = lsp_uuid, .options = options),
     var flood = options.get_bool_def("mcast_flood", false),
     var flood_reports = options.get_bool_def("mcast_flood_reports", false).
 
@@ -195,7 +195,7 @@ IgmpSwitchGroupPort(address, switch, lsp_uuid) :-
     var pb_port_uuid = FlatMap(pb_ports),
     sb::Port_Binding(._uuid = pb_port_uuid, .logical_port = lsp_name),
     &SwitchPort(
-        .lsp = nb::Logical_Switch_Port{._uuid = lsp_uuid, .name = lsp_name},
+        .lsp = &nb::Logical_Switch_Port{._uuid = lsp_uuid, .name = lsp_name},
         .sw = switch).
 IgmpSwitchGroupPort(address, switch, localnet_port.0) :-
     IgmpSwitchGroupPort(address, switch, _),
@@ -235,7 +235,7 @@ IgmpRouterGroupPort(address, rtr_port.router, rtr_port.lrp._uuid) :-
         None -> true
     },
     var flood_port = FlatMap(sw_flood_ports),
-    &SwitchPort(.lsp = nb::Logical_Switch_Port{._uuid = flood_port},
+    &SwitchPort(.lsp = &nb::Logical_Switch_Port{._uuid = flood_port},
                 .peer = Some{rtr_port}).
 
 /* Aggregated IGMP group for routers: merges all IgmpRouterGroupPort for
diff --git a/northd/ovn-nb.dlopts b/northd/ovn-nb.dlopts
index c1ceb4f1496a..402a44636ab9 100644
--- a/northd/ovn-nb.dlopts
+++ b/northd/ovn-nb.dlopts
@@ -22,3 +22,4 @@
 --intern-table NAT
 --intern-table Address_Set
 --intern-table Logical_Router_Port
+--intern-table Logical_Switch_Port
diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl
index 045a054105bc..cfa348d90efc 100644
--- a/northd/ovn_northd.dl
+++ b/northd/ovn_northd.dl
@@ -493,7 +493,7 @@ RefChassis(lr_uuid, chassis_uuid) :-
     ReachableLogicalRouter(lr_uuid, lr2_uuid),
     FirstHopLogicalRouter(lr2_uuid, ls_uuid),
     LogicalSwitchPort(lsp_uuid, ls_uuid),
-    nb::Logical_Switch_Port(._uuid = lsp_uuid, .name = lsp_name),
+    &nb::Logical_Switch_Port(._uuid = lsp_uuid, .name = lsp_name),
     sb::Port_Binding(.logical_port = lsp_name, .chassis = chassis_uuids),
     Some{var chassis_uuid} = chassis_uuids.
 relation RefChassisSet0(lr_uuid: uuid, chassis_uuids: Set<uuid>)
@@ -717,7 +717,7 @@ sb::Out_Address_Set(hash128(as_name), as_name, pg_ip4addrs.union()) :-
     // avoid name collisions with user-defined Address_Sets
     not &nb::Address_Set(.name = as_name),
     PortStaticAddresses(.lsport = port_uuid, .ip4addrs = stat),
-    SwitchPortNewDynamicAddress(&SwitchPort{.lsp = nb::Logical_Switch_Port{._uuid = port_uuid}},
+    SwitchPortNewDynamicAddress(&SwitchPort{.lsp = &nb::Logical_Switch_Port{._uuid = port_uuid}},
                                 dyn_addr),
     var dynamic = match (dyn_addr) {
         None -> set_empty(),
@@ -742,7 +742,7 @@ sb::Out_Address_Set(hash128(as_name), as_name, pg_ip6addrs.union()) :-
     // avoid name collisions with user-defined Address_Sets
     not &nb::Address_Set(.name = as_name),
     PortStaticAddresses(.lsport = port_uuid, .ip6addrs = stat),
-    SwitchPortNewDynamicAddress(&SwitchPort{.lsp = nb::Logical_Switch_Port{._uuid = port_uuid}},
+    SwitchPortNewDynamicAddress(&SwitchPort{.lsp = &nb::Logical_Switch_Port{._uuid = port_uuid}},
                                 dyn_addr),
     var dynamic = match (dyn_addr) {
         None -> set_empty(),
@@ -781,8 +781,8 @@ PortGroupPort(pg_uuid, pg_name, port) :-
 
 sb::Out_Port_Group(._uuid = hash128(sb_name), .name = sb_name, .ports = port_names) :-
     PortGroupPort(.pg_uuid = _uuid, .pg_name = nb_name, .port = port_uuid),
-    &SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{._uuid = port_uuid,
-                                                   .name = port_name},
+    &SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{._uuid = port_uuid,
+                                                    .name = port_name},
                 .sw = &Switch{._uuid = ls_uuid}),
     TunKeyAllocation(.datapath = ls_uuid, .tunkey = tunkey),
     var sb_name = "${tunkey}_${nb_name}",
@@ -1839,7 +1839,7 @@ for (&Switch(._uuid =ls_uuid)) {
  * send all IP packets through the conntrack action, which handles
  * defragmentation, in order to match L4 headers. */
 
-for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "router"},
+for (&SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "router"},
                  .json_name = lsp_name,
                  .sw = &Switch{._uuid = ls_uuid, .has_stateful_acl = true})) {
     /* Can't use ct() for router ports. Consider the
@@ -1868,7 +1868,7 @@ for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "router"},
          .external_ids     = stage_hint(lsp._uuid))
 }
 
-for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "localnet"},
+for (&SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "localnet"},
                  .json_name = lsp_name,
                  .sw = &Switch{._uuid = ls_uuid, .has_stateful_acl = true})) {
     Flow(.logical_datapath = ls_uuid,
@@ -2760,7 +2760,7 @@ for (&Switch(._uuid = ls_uuid, .load_balancer = load_balancer, .has_lb_vip = has
          .external_ids     = map_empty());
 
     if (not load_balancer.is_empty()) {
-        for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "router"},
+        for (&SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "router"},
                          .json_name = lsp_name,
                          .sw = &Switch{._uuid = ls_uuid})) {
             Flow(.logical_datapath = ls_uuid,
@@ -3259,7 +3259,7 @@ for (&SwitchPort(.lsp = lsp, .sw = sw, .json_name = json_name)
          .external_ids     = stage_hint(lsp._uuid))
 }
 
-function lsp_is_up(lsp: nb::Logical_Switch_Port): bool = {
+function lsp_is_up(lsp: Intern<nb::Logical_Switch_Port>): bool = {
     lsp.up == Some{true}
 }
 
@@ -3280,12 +3280,12 @@ function lsp_is_up(lsp: nb::Logical_Switch_Port): bool = {
                           "(arp.op == 2 && arp.spa == ${virtual_ip}))",
       .actions          = "bind_vport(${sp.json_name}, inport); next;",
       .external_ids     = stage_hint(lsp._uuid)) :-
-    sp in &SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "virtual"}),
+    sp in &SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "virtual"}),
     Some{var virtual_ip} = lsp.options.get("virtual-ip"),
     Some{var virtual_parents} = lsp.options.get("virtual-parents"),
     Some{var ip} = ip_parse(virtual_ip),
     var vparent = FlatMap(string_split(virtual_parents, ",")),
-    vp in &SwitchPort(.lsp = nb::Logical_Switch_Port{.name = vparent}),
+    vp in &SwitchPort(.lsp = &nb::Logical_Switch_Port{.name = vparent}),
     vp.sw == sp.sw.
 
 /*
@@ -3414,7 +3414,7 @@ Flow(.logical_datapath = sp.sw._uuid,
     var lbvipbackend = FlatMap(lbvip.backends),
     Some{var svc_monitor} = lbvipbackend.svc_monitor,
     sp in &SwitchPort(
-        .lsp = nb::Logical_Switch_Port{.name = svc_monitor.port_name}),
+        .lsp = &nb::Logical_Switch_Port{.name = svc_monitor.port_name}),
     var svc_mon_src_ip = svc_monitor.src_ip,
     SvcMonitorMac(svc_monitor_mac).
 
@@ -3606,7 +3606,7 @@ for (lsp in &SwitchPort
             Some{var dhcpv4_options_uuid} = lsp.lsp.dhcpv4_options in
             {
                 for (dhcpv4_options in &nb::DHCP_Options(._uuid = dhcpv4_options_uuid)) {
-                    for (SwitchPortIPv4Address(.port = &SwitchPort{.lsp = nb::Logical_Switch_Port{._uuid = lsp.lsp._uuid}}, .ea = ea, .addr = addr)) {
+                    for (SwitchPortIPv4Address(.port = &SwitchPort{.lsp = &nb::Logical_Switch_Port{._uuid = lsp.lsp._uuid}}, .ea = ea, .addr = addr)) {
                         Some{(var options_action, var response_action, var ipv4_addr_match)} =
                             build_dhcpv4_action(json_key, dhcpv4_options, addr.addr) in
                         {
@@ -3663,7 +3663,7 @@ for (lsp in &SwitchPort
             Some{var dhcpv6_options_uuid} = lsp.lsp.dhcpv6_options in
             {
                 for (dhcpv6_options in &nb::DHCP_Options(._uuid = dhcpv6_options_uuid)) {
-                    for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = nb::Logical_Switch_Port{._uuid = lsp.lsp._uuid}}, .ea = ea, .addr = addr)) {
+                    for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = &nb::Logical_Switch_Port{._uuid = lsp.lsp._uuid}}, .ea = ea, .addr = addr)) {
                         Some{(var options_action, var response_action)} =
                             build_dhcpv6_action(json_key, dhcpv6_options, addr.addr) in
                         {
@@ -4322,7 +4322,7 @@ Flow(.logical_datapath = ls_uuid,
      .actions = "put_fdb(inport, eth.src); next;",
      .external_ids = stage_hint(lsp_uuid)) :-
     LogicalSwitchPortWithUnknownAddress(ls_uuid, lsp_uuid),
-    sp in &SwitchPort(.lsp = nb::Logical_Switch_Port{._uuid = lsp_uuid, .__type = ""},
+    sp in &SwitchPort(.lsp = &nb::Logical_Switch_Port{._uuid = lsp_uuid, .__type = ""},
                       .ps_addresses = vec_empty()).
 
 Flow(.logical_datapath = ls_uuid,
@@ -6988,7 +6988,7 @@ Flow(.logical_datapath = peer.router._uuid,
                          "${rEG_NEXT_HOP()} == ${virtual_ip}",
      .actions          = "eth.dst = 00:00:00:00:00:00; next;",
      .external_ids     = stage_hint(sp.lsp._uuid)) :-
-    sp in &SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "virtual"}),
+    sp in &SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "virtual"}),
     Some{var virtual_ip_s} = lsp.options.get("virtual-ip"),
     Some{var virtual_parents} = lsp.options.get("virtual-parents"),
     Some{var virtual_ip} = ip_parse(virtual_ip_s),
@@ -7003,14 +7003,14 @@ Flow(.logical_datapath = peer.router._uuid,
                          "${rEG_NEXT_HOP()} == ${virtual_ip}",
      .actions          = "eth.dst = ${address.ea}; next;",
      .external_ids     = stage_hint(sp.lsp._uuid)) :-
-    sp in &SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "virtual"}),
+    sp in &SwitchPort(.lsp = lsp@&nb::Logical_Switch_Port{.__type = "virtual"}),
     Some{var virtual_ip_s} = lsp.options.get("virtual-ip"),
     Some{var virtual_parents} = lsp.options.get("virtual-parents"),
     Some{var virtual_ip} = ip_parse(virtual_ip_s),
     pb in sb::Port_Binding(.logical_port = sp.lsp.name),
     not (is_empty_set_or_string(pb.virtual_parent) or pb.chassis == None),
     Some{var virtual_parent} = pb.virtual_parent,
-    vp in &SwitchPort(.lsp = nb::Logical_Switch_Port{.name = virtual_parent}),
+    vp in &SwitchPort(.lsp = &nb::Logical_Switch_Port{.name = virtual_parent}),
     var address = FlatMap(vp.static_addresses),
     sp2 in &SwitchPort(.sw = sp.sw, .peer = Some{peer}),
     Some{_} = find_lrp_member_ip(peer.networks, IPv4{virtual_ip}).
@@ -7670,7 +7670,7 @@ SwitchPortReservedTags(parent_name, tags) :-
     var tags = tag.group_by(parent_name).to_set().
 
 SwitchPortReservedTags(parent_name, set_empty()) :-
-    nb::Logical_Switch_Port(.name = parent_name),
+    &nb::Logical_Switch_Port(.name = parent_name),
     not SwitchPortReservedTag(.parent_name = parent_name).
 
 /* Allocate tags for ports that require dynamically allocated tags and do not
@@ -7732,7 +7732,7 @@ sb::Out_IP_Multicast(._uuid = cfg.datapath,
 
 
 relation PortExists(name: string)
-PortExists(name) :- nb::Logical_Switch_Port(.name = name).
+PortExists(name) :- &nb::Logical_Switch_Port(.name = name).
 PortExists(name) :- &nb::Logical_Router_Port(.name = name).
 
 sb::Out_Load_Balancer(._uuid = lb._uuid,
