Skip to content

Commit

Permalink
Merge branch 'neigh_cleanups'
Browse files Browse the repository at this point in the history
Eric W. Biederman says:

====================
Neighbour table and ax25 cleanups

While looking at the neighbour table to what it would take to allow
using next hops in a different address family than the current packets
I found a partial resolution for my issues and I stumbled upon some
work that makes the neighbour table code easier to understand and
maintain.

Long ago in a much younger kernel ax25 found a hack to use
dev_rebuild_header to transmit it's packets instead of going through
what today is ndo_start_xmit.

When the neighbour table was rewritten into it's current form the ax25
code was such a challenge that arp_broken_ops appeard in arp.c and
neigh_compat_output appeared in neighbour.c to keep the ax25 hack alive.

With a little bit of work I was able to remove some of the hack that
is the ax25 transmit path for ip packets and to isolate what remains
into a slightly more readable piece of code in ax25_ip.c.  Removing the
need for the generic code to worry about ax25 special cases.

After cleaning up the old ax25 hacks I also performed a little bit of
work on neigh_resolve_output to remove the need for a dst entry and to
ensure cached headers get a deterministic protocol value in their cached
header.   This guarantees that a cached header will not be different
depending on which protocol of packet is transmitted, and it allows
packets to be transmitted that don't have a dst entry.  There remains
a small amount of code that takes advantage of when packets have a dst
entry but that is something different.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 2, 2015
2 parents 61e021f + 435e8eb commit b898441
Show file tree
Hide file tree
Showing 32 changed files with 105 additions and 544 deletions.
13 changes: 0 additions & 13 deletions drivers/firewire/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,6 @@ static int fwnet_header_create(struct sk_buff *skb, struct net_device *net,
return -net->hard_header_len;
}

static int fwnet_header_rebuild(struct sk_buff *skb)
{
struct fwnet_header *h = (struct fwnet_header *)skb->data;

if (get_unaligned_be16(&h->h_proto) == ETH_P_IP)
return arp_find((unsigned char *)&h->h_dest, skb);

dev_notice(&skb->dev->dev, "unable to resolve type %04x addresses\n",
be16_to_cpu(h->h_proto));
return 0;
}

static int fwnet_header_cache(const struct neighbour *neigh,
struct hh_cache *hh, __be16 type)
{
Expand Down Expand Up @@ -282,7 +270,6 @@ static int fwnet_header_parse(const struct sk_buff *skb, unsigned char *haddr)

static const struct header_ops fwnet_header_ops = {
.create = fwnet_header_create,
.rebuild = fwnet_header_rebuild,
.cache = fwnet_header_cache,
.cache_update = fwnet_header_cache_update,
.parse = fwnet_header_parse,
Expand Down
33 changes: 0 additions & 33 deletions drivers/isdn/i4l/isdn_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1951,38 +1951,6 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
return len;
}

/* We don't need to send arp, because we have point-to-point connections. */
static int
isdn_net_rebuild_header(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
isdn_net_local *lp = netdev_priv(dev);
int ret = 0;

if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
struct ethhdr *eth = (struct ethhdr *) skb->data;

/*
* Only ARP/IP is currently supported
*/

if (eth->h_proto != htons(ETH_P_IP)) {
printk(KERN_WARNING
"isdn_net: %s don't know how to resolve type %d addresses?\n",
dev->name, (int) eth->h_proto);
memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
return 0;
}
/*
* Try to get ARP to resolve the header.
*/
#ifdef CONFIG_INET
ret = arp_find(eth->h_dest, skb);
#endif
}
return ret;
}

static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
__be16 type)
{
Expand All @@ -2005,7 +1973,6 @@ static void isdn_header_cache_update(struct hh_cache *hh,

static const struct header_ops isdn_header_ops = {
.create = isdn_net_header,
.rebuild = isdn_net_rebuild_header,
.cache = isdn_header_cache,
.cache_update = isdn_header_cache_update,
};
Expand Down
1 change: 0 additions & 1 deletion drivers/media/dvb-core/dvb_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,6 @@ static int dvb_net_stop(struct net_device *dev)
static const struct header_ops dvb_header_ops = {
.create = eth_header,
.parse = eth_header_parse,
.rebuild = eth_rebuild_header,
};


Expand Down
55 changes: 0 additions & 55 deletions drivers/net/arcnet/arcnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ EXPORT_SYMBOL(arcnet_timeout);
static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len);
static int arcnet_rebuild_header(struct sk_buff *skb);
static int go_tx(struct net_device *dev);

static int debug = ARCNET_DEBUG;
Expand Down Expand Up @@ -312,7 +311,6 @@ static int choose_mtu(void)

static const struct header_ops arcnet_header_ops = {
.create = arcnet_header,
.rebuild = arcnet_rebuild_header,
};

static const struct net_device_ops arcnet_netdev_ops = {
Expand Down Expand Up @@ -538,59 +536,6 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
return proto->build_header(skb, dev, type, _daddr);
}


/*
* Rebuild the ARCnet hard header. This is called after an ARP (or in the
* future other address resolution) has completed on this sk_buff. We now
* let ARP fill in the destination field.
*/
static int arcnet_rebuild_header(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct arcnet_local *lp = netdev_priv(dev);
int status = 0; /* default is failure */
unsigned short type;
uint8_t daddr=0;
struct ArcProto *proto;
/*
* XXX: Why not use skb->mac_len?
*/
if (skb->network_header - skb->mac_header != 2) {
BUGMSG(D_NORMAL,
"rebuild_header: shouldn't be here! (hdrsize=%d)\n",
(int)(skb->network_header - skb->mac_header));
return 0;
}
type = *(uint16_t *) skb_pull(skb, 2);
BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type);

if (type == ETH_P_IP) {
#ifdef CONFIG_INET
BUGMSG(D_DURING, "rebuild header for ethernet protocol %Xh\n", type);
status = arp_find(&daddr, skb) ? 1 : 0;
BUGMSG(D_DURING, " rebuilt: dest is %d; protocol %Xh\n",
daddr, type);
#endif
} else {
BUGMSG(D_NORMAL,
"I don't understand ethernet protocol %Xh addresses!\n", type);
dev->stats.tx_errors++;
dev->stats.tx_aborted_errors++;
}

/* if we couldn't resolve the address... give up. */
if (!status)
return 0;

/* add the _real_ header this time! */
proto = arc_proto_map[lp->default_proto[daddr]];
proto->build_header(skb, dev, type, daddr);

return 1; /* success */
}



/* Called by the kernel in order to transmit a packet. */
netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
struct net_device *dev)
Expand Down
30 changes: 3 additions & 27 deletions drivers/net/hamradio/6pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,6 @@ static int sp_close(struct net_device *dev)
return 0;
}

/* Return the frame type ID */
static int sp_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len)
{
#ifdef CONFIG_INET
if (type != ETH_P_AX25)
return ax25_hard_header(skb, dev, type, daddr, saddr, len);
#endif
return 0;
}

static int sp_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr_ax25 *sa = addr;
Expand All @@ -309,25 +297,12 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
return 0;
}

static int sp_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
return ax25_rebuild_header(skb);
#else
return 0;
#endif
}

static const struct header_ops sp_header_ops = {
.create = sp_header,
.rebuild = sp_rebuild_header,
};

static const struct net_device_ops sp_netdev_ops = {
.ndo_open = sp_open_dev,
.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)
Expand All @@ -337,10 +312,11 @@ static void sp_setup(struct net_device *dev)
dev->destructor = free_netdev;
dev->mtu = SIXP_MTU;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->header_ops = &sp_header_ops;
dev->header_ops = &ax25_header_ops;

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 */
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/baycom_epp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/*
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/bpqether.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/dmascc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/hdlcdrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/*
Expand Down Expand Up @@ -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 */
Expand Down
35 changes: 3 additions & 32 deletions drivers/net/hamradio/mkiss.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,32 +573,6 @@ static int ax_open_dev(struct net_device *dev)
return 0;
}

#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)

/* Return the frame type ID */
static int ax_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len)
{
#ifdef CONFIG_INET
if (type != ETH_P_AX25)
return ax25_hard_header(skb, dev, type, daddr, saddr, len);
#endif
return 0;
}


static int ax_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
return ax25_rebuild_header(skb);
#else
return 0;
#endif
}

#endif /* CONFIG_{AX25,AX25_MODULE} */

/* Open the low-level part of the AX25 channel. Easy! */
static int ax_open(struct net_device *dev)
{
Expand Down Expand Up @@ -662,16 +636,12 @@ static int ax_close(struct net_device *dev)
return 0;
}

static const struct header_ops ax_header_ops = {
.create = ax_header,
.rebuild = ax_rebuild_header,
};

static const struct net_device_ops ax_netdev_ops = {
.ndo_open = ax_open_dev,
.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)
Expand All @@ -681,8 +651,9 @@ 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 = &ax_header_ops;
dev->header_ops = &ax25_header_ops;
dev->netdev_ops = &ax_netdev_ops;


Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/scc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <----- */
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/hamradio/yam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ipvlan/ipvlan_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev,

static const struct header_ops ipvlan_header_ops = {
.create = ipvlan_hard_header,
.rebuild = eth_rebuild_header,
.parse = eth_header_parse,
.cache = eth_header_cache,
.cache_update = eth_header_cache_update,
Expand Down
1 change: 0 additions & 1 deletion drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,6 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,

static const struct header_ops macvlan_hard_header_ops = {
.create = macvlan_hard_header,
.rebuild = eth_rebuild_header,
.parse = eth_header_parse,
.cache = eth_header_cache,
.cache_update = eth_header_cache_update,
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/hostap/hostap_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,6 @@ static void prism2_tx_timeout(struct net_device *dev)

const struct header_ops hostap_80211_ops = {
.create = eth_header,
.rebuild = eth_rebuild_header,
.cache = eth_header_cache,
.cache_update = eth_header_cache_update,
.parse = hostap_80211_header_parse,
Expand Down
Loading

0 comments on commit b898441

Please sign in to comment.