ax25: Refactor to use private neighbour operations.
authorEric W. Biederman <ebiederm@xmission.com>
Mon, 2 Mar 2015 06:05:28 +0000 (00:05 -0600)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Mar 2015 21:43:40 +0000 (16:43 -0500)
AX25 already has it's own private arp cache operations to isolate
it's abuse of dev_rebuild_header to transmit packets.  Add a function
ax25_neigh_construct that will allow all of the ax25 devices to
force using these operations, so that the generic arp code does
not need to.

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-hams@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/hamradio/6pack.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hamradio/scc.c
drivers/net/hamradio/yam.c
include/net/ax25.h
net/ax25/ax25_ip.c

index 2533933c79dc3bcb7782d6ca8f1a4206ad50eabe..0b8393ca8c80134b444e5d3bf69d3ed58552b644 100644 (file)
@@ -302,6 +302,7 @@ static const struct net_device_ops sp_netdev_ops = {
        .ndo_stop               = sp_close,
        .ndo_start_xmit         = sp_xmit,
        .ndo_set_mac_address    = sp_set_mac_address,
+       .ndo_neigh_construct    = ax25_neigh_construct,
 };
 
 static void sp_setup(struct net_device *dev)
@@ -315,6 +316,7 @@ static void sp_setup(struct net_device *dev)
 
        dev->addr_len           = AX25_ADDR_LEN;
        dev->type               = ARPHRD_AX25;
+       dev->neigh_priv_len     = sizeof(struct ax25_neigh_priv);
        dev->tx_queue_len       = 10;
 
        /* Only activated in AX.25 mode */
index a98c153f371e761f2c396c7fbcc1bdf787f407f3..3539ab392f7dc9af3713a6dfd4ec1e978537f470 100644 (file)
@@ -1109,6 +1109,7 @@ static const struct net_device_ops baycom_netdev_ops = {
        .ndo_do_ioctl        = baycom_ioctl,
        .ndo_start_xmit      = baycom_send_packet,
        .ndo_set_mac_address = baycom_set_mac_address,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 /*
@@ -1146,6 +1147,7 @@ static void baycom_probe(struct net_device *dev)
        dev->header_ops = &ax25_header_ops;
        
        dev->type = ARPHRD_AX25;           /* AF_AX25 device */
+       dev->neigh_priv_len = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
        dev->mtu = AX25_DEF_PACLEN;        /* eth_mtu is the default */
        dev->addr_len = AX25_ADDR_LEN;     /* sizeof an ax.25 address */
index c2894e43840e604e75eac9f40bcfb1470e4c47aa..bce105b16ed0771460e1a03205c1bb64b213f2bb 100644 (file)
@@ -469,6 +469,7 @@ static const struct net_device_ops bpq_netdev_ops = {
        .ndo_start_xmit      = bpq_xmit,
        .ndo_set_mac_address = bpq_set_mac_address,
        .ndo_do_ioctl        = bpq_ioctl,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 static void bpq_setup(struct net_device *dev)
@@ -486,6 +487,7 @@ static void bpq_setup(struct net_device *dev)
 #endif
 
        dev->type            = ARPHRD_AX25;
+       dev->neigh_priv_len  = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
        dev->mtu             = AX25_DEF_PACLEN;
        dev->addr_len        = AX25_ADDR_LEN;
index 0fad408f24aa137694156290ae35a1da99343b80..abab7be77406387fd8442908bfcbe6989d76d083 100644 (file)
@@ -433,6 +433,7 @@ module_exit(dmascc_exit);
 static void __init dev_setup(struct net_device *dev)
 {
        dev->type = ARPHRD_AX25;
+       dev->neigh_priv_len = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN;
        dev->mtu = 1500;
        dev->addr_len = AX25_ADDR_LEN;
@@ -447,6 +448,7 @@ static const struct net_device_ops scc_netdev_ops = {
        .ndo_start_xmit = scc_send_packet,
        .ndo_do_ioctl = scc_ioctl,
        .ndo_set_mac_address = scc_set_mac_address,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 static int __init setup_adapter(int card_base, int type, int n)
index c67a27245072746c3275a3b27a4fd899ebb6f3a4..435868a7b69cdcdde15d05988adb1f66f737fa11 100644 (file)
@@ -626,6 +626,7 @@ static const struct net_device_ops hdlcdrv_netdev = {
        .ndo_start_xmit = hdlcdrv_send_packet,
        .ndo_do_ioctl   = hdlcdrv_ioctl,
        .ndo_set_mac_address = hdlcdrv_set_mac_address,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 /*
@@ -676,6 +677,7 @@ static void hdlcdrv_setup(struct net_device *dev)
        dev->header_ops = &ax25_header_ops;
        
        dev->type = ARPHRD_AX25;           /* AF_AX25 device */
+       dev->neigh_priv_len = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
        dev->mtu = AX25_DEF_PACLEN;        /* eth_mtu is the default */
        dev->addr_len = AX25_ADDR_LEN;     /* sizeof an ax.25 address */
index e37c8d515ce8280c87a7aad0c940a8480e6ba7c4..c12ec2c2b594a79e941ea7a9256c3bc5f8cc8c32 100644 (file)
@@ -641,6 +641,7 @@ static const struct net_device_ops ax_netdev_ops = {
        .ndo_stop            = ax_close,
        .ndo_start_xmit      = ax_xmit,
        .ndo_set_mac_address = ax_set_mac_address,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 static void ax_setup(struct net_device *dev)
@@ -650,6 +651,7 @@ static void ax_setup(struct net_device *dev)
        dev->hard_header_len = 0;
        dev->addr_len        = 0;
        dev->type            = ARPHRD_AX25;
+       dev->neigh_priv_len  = sizeof(struct ax25_neigh_priv);
        dev->tx_queue_len    = 10;
        dev->header_ops      = &ax25_header_ops;
        dev->netdev_ops      = &ax_netdev_ops;
index 57be9e0e98a68608fcbafade768bcf397b248e42..b305f51eb42015316b7943f382165ad36c847408 100644 (file)
@@ -1550,6 +1550,7 @@ static const struct net_device_ops scc_netdev_ops = {
        .ndo_set_mac_address = scc_net_set_mac_address,
        .ndo_get_stats       = scc_net_get_stats,
        .ndo_do_ioctl        = scc_net_ioctl,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 /* ----> Initialize device <----- */
@@ -1567,6 +1568,7 @@ static void scc_net_setup(struct net_device *dev)
        dev->flags      = 0;
 
        dev->type = ARPHRD_AX25;
+       dev->neigh_priv_len = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
        dev->mtu = AX25_DEF_PACLEN;
        dev->addr_len = AX25_ADDR_LEN;
index 717433cfb81d2c4248539a56516daf6eb09c45ae..89d9da7a0c51eebf7fa4b338d21f8a85119ac3eb 100644 (file)
@@ -1100,6 +1100,7 @@ static const struct net_device_ops yam_netdev_ops = {
        .ndo_start_xmit      = yam_send_packet,
        .ndo_do_ioctl        = yam_ioctl,
        .ndo_set_mac_address = yam_set_mac_address,
+       .ndo_neigh_construct = ax25_neigh_construct,
 };
 
 static void yam_setup(struct net_device *dev)
@@ -1128,6 +1129,7 @@ static void yam_setup(struct net_device *dev)
        dev->header_ops = &ax25_header_ops;
 
        dev->type = ARPHRD_AX25;
+       dev->neigh_priv_len = sizeof(struct ax25_neigh_priv);
        dev->hard_header_len = AX25_MAX_HEADER_LEN;
        dev->mtu = AX25_MTU;
        dev->addr_len = AX25_ADDR_LEN;
index 7385a64b61b81bc7f248ad155fa91be93f1a63e3..45feeba7a3250be44e78a1a70b4a7da529a47edf 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
+#include <net/neighbour.h>
 
 #define        AX25_T1CLAMPLO                  1
 #define        AX25_T1CLAMPHI                  (30 * HZ)
@@ -366,7 +367,11 @@ int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *,
                  struct net_device *);
 
 /* ax25_ip.c */
+int ax25_neigh_construct(struct neighbour *neigh);
 extern const struct header_ops ax25_header_ops;
+struct ax25_neigh_priv {
+       struct neigh_ops ops;
+};
 
 /* ax25_out.c */
 ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *,
index d93103ba8ceca1bedecfbfb2c72c67c931c7cb1c..bff12e0c9090ea7f10e65eaadcf3e20985c2e513 100644 (file)
@@ -216,6 +216,22 @@ put:
        return 1;
 }
 
+int ax25_neigh_construct(struct neighbour *neigh)
+{
+       /* This trouble could be saved if ax25 would right a proper
+        * dev_queue_xmit function.
+        */
+       struct ax25_neigh_priv *priv = neighbour_priv(neigh);
+
+       if (neigh->tbl->family != AF_INET)
+               return -EINVAL;
+
+       priv->ops = *neigh->ops;
+       priv->ops.output = neigh_compat_output;
+       priv->ops.connected_output = neigh_compat_output;
+       return 0;
+}
+
 #else  /* INET */
 
 static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
@@ -230,6 +246,10 @@ static int ax25_rebuild_header(struct sk_buff *skb)
        return 1;
 }
 
+int ax25_neigh_construct(struct neighbour *neigh)
+{
+       return 0;
+}
 #endif
 
 const struct header_ops ax25_header_ops = {
@@ -238,4 +258,5 @@ const struct header_ops ax25_header_ops = {
 };
 
 EXPORT_SYMBOL(ax25_header_ops);
+EXPORT_SYMBOL(ax25_neigh_construct);