diff --git a/northd/northd.c b/northd/northd.c
index 62f511613..bb92bbc6f 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -514,74 +514,6 @@ port_has_qos_params(const struct smap *opts)
 }
 
 
-/*
- * Multicast snooping and querier per datapath configuration.
- */
-struct mcast_switch_info {
-
-    bool enabled;               /* True if snooping enabled. */
-    bool querier;               /* True if querier enabled. */
-    bool flood_unregistered;    /* True if unregistered multicast should be
-                                 * flooded.
-                                 */
-    bool flood_relay;           /* True if the switch is connected to a
-                                 * multicast router and unregistered multicast
-                                 * should be flooded to the mrouter. Only
-                                 * applicable if flood_unregistered == false.
-                                 */
-    bool flood_reports;         /* True if the switch has at least one port
-                                 * configured to flood reports.
-                                 */
-    bool flood_static;          /* True if the switch has at least one port
-                                 * configured to flood traffic.
-                                 */
-    int64_t table_size;         /* Max number of IP multicast groups. */
-    int64_t idle_timeout;       /* Timeout after which an idle group is
-                                 * flushed.
-                                 */
-    int64_t query_interval;     /* Interval between multicast queries. */
-    char *eth_src;              /* ETH src address of the queries. */
-    char *ipv4_src;             /* IPv4 src address of the queries. */
-    char *ipv6_src;             /* IPv6 src address of the queries. */
-
-    int64_t query_max_response; /* Expected time after which reports should
-                                 * be received for queries that were sent out.
-                                 */
-
-    atomic_uint64_t active_v4_flows;   /* Current number of active IPv4 multicast
-                                 * flows.
-                                 */
-    atomic_uint64_t active_v6_flows;   /* Current number of active IPv6 multicast
-                                 * flows.
-                                 */
-};
-
-struct mcast_router_info {
-    bool relay;        /* True if the router should relay IP multicast. */
-    bool flood_static; /* True if the router has at least one port configured
-                        * to flood traffic.
-                        */
-};
-
-struct mcast_info {
-
-    struct hmap group_tnlids;  /* Group tunnel IDs in use on this DP. */
-    uint32_t group_tnlid_hint; /* Hint for allocating next group tunnel ID. */
-    struct ovs_list groups;    /* List of groups learnt on this DP. */
-
-    union {
-        struct mcast_switch_info sw;  /* Switch specific multicast info. */
-        struct mcast_router_info rtr; /* Router specific multicast info. */
-    };
-};
-
-struct mcast_port_info {
-    bool flood;         /* True if the port should flood IP multicast traffic
-                         * regardless if it's registered or not. */
-    bool flood_reports; /* True if the port should flood IP multicast reports
-                         * (e.g., IGMP join/leave). */
-};
-
 static void
 init_mcast_port_info(struct mcast_port_info *mcast_info,
                      const struct nbrec_logical_switch_port *nbsp,
@@ -611,85 +543,6 @@ ovn_mcast_group_allocate_key(struct mcast_info *mcast_info)
                               &mcast_info->group_tnlid_hint);
 }
 
-/* The 'key' comes from nbs->header_.uuid or nbr->header_.uuid or
- * sb->external_ids:logical-switch. */
-struct ovn_datapath {
-    struct hmap_node key_node;  /* Index on 'key'. */
-    struct uuid key;            /* (nbs/nbr)->header_.uuid. */
-
-    const struct nbrec_logical_switch *nbs;  /* May be NULL. */
-    const struct nbrec_logical_router *nbr;  /* May be NULL. */
-    const struct sbrec_datapath_binding *sb; /* May be NULL. */
-
-    struct ovs_list list;       /* In list of similar records. */
-
-    uint32_t tunnel_key;
-
-    /* Logical switch data. */
-    struct ovn_port **router_ports;
-    size_t n_router_ports;
-    size_t n_allocated_router_ports;
-
-    struct hmap port_tnlids;
-    uint32_t port_key_hint;
-
-    bool has_stateful_acl;
-    bool has_lb_vip;
-    bool has_unknown;
-    bool has_acls;
-
-    /* IPAM data. */
-    struct ipam_info ipam_info;
-
-    /* Multicast data. */
-    struct mcast_info mcast_info;
-
-    /* Applies to only logical router datapath.
-     * True if logical router is a gateway router. i.e options:chassis is set.
-     * If this is true, then 'l3dgw_ports' will be ignored. */
-    bool is_gw_router;
-
-    /* OVN northd only needs to know about logical router gateway ports for
-     * NAT/LB on a distributed router.  The "distributed gateway ports" are
-     * populated only when there is a gateway chassis or ha chassis group
-     * specified for some of the ports on the logical router. Otherwise this
-     * will be NULL. */
-    struct ovn_port **l3dgw_ports;
-    size_t n_l3dgw_ports;
-
-    /* NAT entries configured on the router. */
-    struct ovn_nat *nat_entries;
-    size_t n_nat_entries;
-
-    bool has_distributed_nat;
-
-    /* Set of nat external ips on the router. */
-    struct sset external_ips;
-
-    /* SNAT IPs owned by the router (shash of 'struct ovn_snat_ip'). */
-    struct shash snat_ips;
-
-    struct lport_addresses dnat_force_snat_addrs;
-    struct lport_addresses lb_force_snat_addrs;
-    bool lb_force_snat_router_ip;
-
-    /* Load Balancer vIPs relevant for this datapath. */
-    struct ovn_lb_ip_set *lb_ips;
-
-    struct ovn_port **localnet_ports;
-    size_t n_localnet_ports;
-
-    struct ovs_list lr_list; /* In list of logical router datapaths. */
-    /* The logical router group to which this datapath belongs.
-     * Valid only if it is logical router datapath. NULL otherwise. */
-    struct lrouter_group *lr_group;
-
-    /* Port groups related to the datapath, used only when nbs is NOT NULL. */
-    struct hmap nb_pgs;
-
-    struct ovs_list port_list;
-};
-
 /* Contains a NAT entry with the external addresses pre-parsed. */
 struct ovn_nat {
     const struct nbrec_nat *nb;
diff --git a/northd/northd.h b/northd/northd.h
index 4de809a3d..68c55bff4 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -16,6 +16,10 @@
 
 #include "ovsdb-idl.h"
 
+#include "lib/ovn-util.h"
+#include "lib/ovs-atomic.h"
+#include "lib/sset.h"
+#include "northd/ipam.h"
 #include "openvswitch/hmap.h"
 
 struct northd_input {
@@ -101,6 +105,153 @@ struct lflow_input {
     bool ovn_internal_version_changed;
 };
 
+/*
+ * Multicast snooping and querier per datapath configuration.
+ */
+struct mcast_switch_info {
+
+    bool enabled;               /* True if snooping enabled. */
+    bool querier;               /* True if querier enabled. */
+    bool flood_unregistered;    /* True if unregistered multicast should be
+                                 * flooded.
+                                 */
+    bool flood_relay;           /* True if the switch is connected to a
+                                 * multicast router and unregistered multicast
+                                 * should be flooded to the mrouter. Only
+                                 * applicable if flood_unregistered == false.
+                                 */
+    bool flood_reports;         /* True if the switch has at least one port
+                                 * configured to flood reports.
+                                 */
+    bool flood_static;          /* True if the switch has at least one port
+                                 * configured to flood traffic.
+                                 */
+    int64_t table_size;         /* Max number of IP multicast groups. */
+    int64_t idle_timeout;       /* Timeout after which an idle group is
+                                 * flushed.
+                                 */
+    int64_t query_interval;     /* Interval between multicast queries. */
+    char *eth_src;              /* ETH src address of the queries. */
+    char *ipv4_src;             /* IPv4 src address of the queries. */
+    char *ipv6_src;             /* IPv6 src address of the queries. */
+
+    int64_t query_max_response; /* Expected time after which reports should
+                                 * be received for queries that were sent out.
+                                 */
+
+    atomic_uint64_t active_v4_flows;   /* Current number of active IPv4
+                                        * multicast flows.
+                                        */
+    atomic_uint64_t active_v6_flows;   /* Current number of active IPv6
+                                        * multicast flows.
+                                        */
+};
+
+struct mcast_router_info {
+    bool relay;        /* True if the router should relay IP multicast. */
+    bool flood_static; /* True if the router has at least one port configured
+                        * to flood traffic.
+                        */
+};
+
+struct mcast_info {
+
+    struct hmap group_tnlids;  /* Group tunnel IDs in use on this DP. */
+    uint32_t group_tnlid_hint; /* Hint for allocating next group tunnel ID. */
+    struct ovs_list groups;    /* List of groups learnt on this DP. */
+
+    union {
+        struct mcast_switch_info sw;  /* Switch specific multicast info. */
+        struct mcast_router_info rtr; /* Router specific multicast info. */
+    };
+};
+
+struct mcast_port_info {
+    bool flood;         /* True if the port should flood IP multicast traffic
+                         * regardless if it's registered or not. */
+    bool flood_reports; /* True if the port should flood IP multicast reports
+                         * (e.g., IGMP join/leave). */
+};
+
+/* The 'key' comes from nbs->header_.uuid or nbr->header_.uuid or
+ * sb->external_ids:logical-switch. */
+struct ovn_datapath {
+    struct hmap_node key_node;  /* Index on 'key'. */
+    struct uuid key;            /* (nbs/nbr)->header_.uuid. */
+
+    const struct nbrec_logical_switch *nbs;  /* May be NULL. */
+    const struct nbrec_logical_router *nbr;  /* May be NULL. */
+    const struct sbrec_datapath_binding *sb; /* May be NULL. */
+
+    struct ovs_list list;       /* In list of similar records. */
+
+    uint32_t tunnel_key;
+
+    /* Logical switch data. */
+    struct ovn_port **router_ports;
+    size_t n_router_ports;
+    size_t n_allocated_router_ports;
+
+    struct hmap port_tnlids;
+    uint32_t port_key_hint;
+
+    bool has_stateful_acl;
+    bool has_lb_vip;
+    bool has_unknown;
+    bool has_acls;
+
+    /* IPAM data. */
+    struct ipam_info ipam_info;
+
+    /* Multicast data. */
+    struct mcast_info mcast_info;
+
+    /* Applies to only logical router datapath.
+     * True if logical router is a gateway router. i.e options:chassis is set.
+     * If this is true, then 'l3dgw_ports' will be ignored. */
+    bool is_gw_router;
+
+    /* OVN northd only needs to know about logical router gateway ports for
+     * NAT/LB on a distributed router.  The "distributed gateway ports" are
+     * populated only when there is a gateway chassis or ha chassis group
+     * specified for some of the ports on the logical router. Otherwise this
+     * will be NULL. */
+    struct ovn_port **l3dgw_ports;
+    size_t n_l3dgw_ports;
+
+    /* NAT entries configured on the router. */
+    struct ovn_nat *nat_entries;
+    size_t n_nat_entries;
+
+    bool has_distributed_nat;
+
+    /* Set of nat external ips on the router. */
+    struct sset external_ips;
+
+    /* SNAT IPs owned by the router (shash of 'struct ovn_snat_ip'). */
+    struct shash snat_ips;
+
+    struct lport_addresses dnat_force_snat_addrs;
+    struct lport_addresses lb_force_snat_addrs;
+    bool lb_force_snat_router_ip;
+
+    /* Load Balancer vIPs relevant for this datapath. */
+    struct ovn_lb_ip_set *lb_ips;
+
+    struct ovn_port **localnet_ports;
+    size_t n_localnet_ports;
+
+    struct ovs_list lr_list; /* In list of logical router datapaths. */
+    /* The logical router group to which this datapath belongs.
+     * Valid only if it is logical router datapath. NULL otherwise. */
+    struct lrouter_group *lr_group;
+
+    /* Port groups related to the datapath, used only when nbs is NOT NULL. */
+    struct hmap nb_pgs;
+
+    struct ovs_list port_list;
+};
+
 void northd_run(struct northd_input *input_data,
                 struct northd_data *data,
                 struct ovsdb_idl_txn *ovnnb_txn,
