Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b898441f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'neigh_cleanups'



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: default avatarDavid S. Miller <davem@davemloft.net>
parents 61e021f3 435e8eb2
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -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)
{
@@ -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,
+0 −33
Original line number Diff line number Diff line
@@ -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)
{
@@ -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,
};
+0 −1
Original line number Diff line number Diff line
@@ -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,
};


+0 −55
Original line number Diff line number Diff line
@@ -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;
@@ -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 = {
@@ -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)
+3 −27
Original line number Diff line number Diff line
@@ -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;
@@ -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)
@@ -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 */
Loading