#include <net/dn_route.h>
 
 static int dn_neigh_construct(struct neighbour *);
-static void dn_long_error_report(struct neighbour *, struct sk_buff *);
-static void dn_short_error_report(struct neighbour *, struct sk_buff *);
-static int dn_long_output(struct neighbour *, struct sk_buff *);
-static int dn_short_output(struct neighbour *, struct sk_buff *);
-static int dn_phase3_output(struct neighbour *, struct sk_buff *);
-
-
-/*
- * For talking to broadcast devices: Ethernet & PPP
- */
-static const struct neigh_ops dn_long_ops = {
-       .family =               AF_DECnet,
-       .error_report =         dn_long_error_report,
-       .output =               dn_long_output,
-       .connected_output =     dn_long_output,
-};
+static void dn_neigh_error_report(struct neighbour *, struct sk_buff *);
+static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb);
 
 /*
- * For talking to pointopoint and multidrop devices: DDCMP and X.25
+ * Operations for adding the link layer header.
  */
-static const struct neigh_ops dn_short_ops = {
+static const struct neigh_ops dn_neigh_ops = {
        .family =               AF_DECnet,
-       .error_report =         dn_short_error_report,
-       .output =               dn_short_output,
-       .connected_output =     dn_short_output,
-};
-
-/*
- * For talking to DECnet phase III nodes
- */
-static const struct neigh_ops dn_phase3_ops = {
-       .family =               AF_DECnet,
-       .error_report =         dn_short_error_report, /* Can use short version here */
-       .output =               dn_phase3_output,
-       .connected_output =     dn_phase3_output,
+       .error_report =         dn_neigh_error_report,
+       .output =               dn_neigh_output,
+       .connected_output =     dn_neigh_output,
 };
 
 static u32 dn_neigh_hash(const void *pkey,
 
        __neigh_parms_put(neigh->parms);
        neigh->parms = neigh_parms_clone(parms);
-
-       if (dn_db->use_long)
-               neigh->ops = &dn_long_ops;
-       else
-               neigh->ops = &dn_short_ops;
        rcu_read_unlock();
 
-       if (dn->flags & DN_NDFLAG_P3)
-               neigh->ops = &dn_phase3_ops;
-
+       neigh->ops = &dn_neigh_ops;
        neigh->nud_state = NUD_NOARP;
        neigh->output = neigh->ops->connected_output;
 
        return 0;
 }
 
-static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb)
-{
-       printk(KERN_DEBUG "dn_long_error_report: called\n");
-       kfree_skb(skb);
-}
-
-
-static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb)
+static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb)
 {
-       printk(KERN_DEBUG "dn_short_error_report: called\n");
+       printk(KERN_DEBUG "dn_neigh_error_report: called\n");
        kfree_skb(skb);
 }
 
-static int dn_neigh_output_packet(struct sk_buff *skb)
+static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
        struct dn_route *rt = (struct dn_route *)dst;
-       struct neighbour *neigh = rt->n;
        struct net_device *dev = neigh->dev;
        char mac_addr[ETH_ALEN];
        unsigned int seq;
        return err;
 }
 
+static int dn_neigh_output_packet(struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+       struct dn_route *rt = (struct dn_route *)dst;
+       struct neighbour *neigh = rt->n;
+
+       return neigh->output(neigh, skb);
+}
+
+/*
+ * For talking to broadcast devices: Ethernet & PPP
+ */
 static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb)
 {
        struct net_device *dev = neigh->dev;
                       neigh->dev, dn_neigh_output_packet);
 }
 
+/*
+ * For talking to pointopoint and multidrop devices: DDCMP and X.25
+ */
 static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb)
 {
        struct net_device *dev = neigh->dev;
 }
 
 /*
- * Phase 3 output is the same is short output, execpt that
+ * For talking to DECnet phase III nodes
+ * Phase 3 output is the same as short output, execpt that
  * it clears the area bits before transmission.
  */
 static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb)
                       neigh->dev, dn_neigh_output_packet);
 }
 
+int dn_to_neigh_output(struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+       struct dn_route *rt = (struct dn_route *) dst;
+       struct neighbour *neigh = rt->n;
+       struct dn_neigh *dn = (struct dn_neigh *)neigh;
+       struct dn_dev *dn_db;
+       bool use_long;
+
+       rcu_read_lock();
+       dn_db = rcu_dereference(neigh->dev->dn_ptr);
+       if (dn_db == NULL) {
+               rcu_read_unlock();
+               return -EINVAL;
+       }
+       use_long = dn_db->use_long;
+       rcu_read_unlock();
+
+       if (dn->flags & DN_NDFLAG_P3)
+               return dn_phase3_output(neigh, skb);
+       if (use_long)
+               return dn_long_output(neigh, skb);
+       else
+               return dn_short_output(neigh, skb);
+}
+
 /*
  * Unfortunately, the neighbour code uses the device in its hash
  * function, so we don't get any advantage from it. This function