diff options
author | David S. Miller <davem@davemloft.net> | 2015-03-02 16:43:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-02 16:43:46 -0500 |
commit | b898441f4ece44933af90b116b467f7864dd1ae7 (patch) | |
tree | 56316bfd883fa759f7a6fc7744088028b64e7b85 | |
parent | 61e021f3b86cbbcc04cbe8ac7b7da2b8c94b5e8e (diff) | |
parent | 435e8eb27edb4da0b47b9b980239bd59057a7362 (diff) |
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: David S. Miller <davem@davemloft.net>
32 files changed, 105 insertions, 544 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 2c68da1ceeee..f4ea80d602f7 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -237,18 +237,6 @@ static int fwnet_header_create(struct sk_buff *skb, struct net_device *net, | |||
237 | return -net->hard_header_len; | 237 | return -net->hard_header_len; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int fwnet_header_rebuild(struct sk_buff *skb) | ||
241 | { | ||
242 | struct fwnet_header *h = (struct fwnet_header *)skb->data; | ||
243 | |||
244 | if (get_unaligned_be16(&h->h_proto) == ETH_P_IP) | ||
245 | return arp_find((unsigned char *)&h->h_dest, skb); | ||
246 | |||
247 | dev_notice(&skb->dev->dev, "unable to resolve type %04x addresses\n", | ||
248 | be16_to_cpu(h->h_proto)); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int fwnet_header_cache(const struct neighbour *neigh, | 240 | static int fwnet_header_cache(const struct neighbour *neigh, |
253 | struct hh_cache *hh, __be16 type) | 241 | struct hh_cache *hh, __be16 type) |
254 | { | 242 | { |
@@ -282,7 +270,6 @@ static int fwnet_header_parse(const struct sk_buff *skb, unsigned char *haddr) | |||
282 | 270 | ||
283 | static const struct header_ops fwnet_header_ops = { | 271 | static const struct header_ops fwnet_header_ops = { |
284 | .create = fwnet_header_create, | 272 | .create = fwnet_header_create, |
285 | .rebuild = fwnet_header_rebuild, | ||
286 | .cache = fwnet_header_cache, | 273 | .cache = fwnet_header_cache, |
287 | .cache_update = fwnet_header_cache_update, | 274 | .cache_update = fwnet_header_cache_update, |
288 | .parse = fwnet_header_parse, | 275 | .parse = fwnet_header_parse, |
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 94affa5e6f28..546b7e81161d 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -1951,38 +1951,6 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev, | |||
1951 | return len; | 1951 | return len; |
1952 | } | 1952 | } |
1953 | 1953 | ||
1954 | /* We don't need to send arp, because we have point-to-point connections. */ | ||
1955 | static int | ||
1956 | isdn_net_rebuild_header(struct sk_buff *skb) | ||
1957 | { | ||
1958 | struct net_device *dev = skb->dev; | ||
1959 | isdn_net_local *lp = netdev_priv(dev); | ||
1960 | int ret = 0; | ||
1961 | |||
1962 | if (lp->p_encap == ISDN_NET_ENCAP_ETHER) { | ||
1963 | struct ethhdr *eth = (struct ethhdr *) skb->data; | ||
1964 | |||
1965 | /* | ||
1966 | * Only ARP/IP is currently supported | ||
1967 | */ | ||
1968 | |||
1969 | if (eth->h_proto != htons(ETH_P_IP)) { | ||
1970 | printk(KERN_WARNING | ||
1971 | "isdn_net: %s don't know how to resolve type %d addresses?\n", | ||
1972 | dev->name, (int) eth->h_proto); | ||
1973 | memcpy(eth->h_source, dev->dev_addr, dev->addr_len); | ||
1974 | return 0; | ||
1975 | } | ||
1976 | /* | ||
1977 | * Try to get ARP to resolve the header. | ||
1978 | */ | ||
1979 | #ifdef CONFIG_INET | ||
1980 | ret = arp_find(eth->h_dest, skb); | ||
1981 | #endif | ||
1982 | } | ||
1983 | return ret; | ||
1984 | } | ||
1985 | |||
1986 | static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh, | 1954 | static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh, |
1987 | __be16 type) | 1955 | __be16 type) |
1988 | { | 1956 | { |
@@ -2005,7 +1973,6 @@ static void isdn_header_cache_update(struct hh_cache *hh, | |||
2005 | 1973 | ||
2006 | static const struct header_ops isdn_header_ops = { | 1974 | static const struct header_ops isdn_header_ops = { |
2007 | .create = isdn_net_header, | 1975 | .create = isdn_net_header, |
2008 | .rebuild = isdn_net_rebuild_header, | ||
2009 | .cache = isdn_header_cache, | 1976 | .cache = isdn_header_cache, |
2010 | .cache_update = isdn_header_cache_update, | 1977 | .cache_update = isdn_header_cache_update, |
2011 | }; | 1978 | }; |
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 686d3277dad1..4a77cb02dffc 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c | |||
@@ -1190,7 +1190,6 @@ static int dvb_net_stop(struct net_device *dev) | |||
1190 | static const struct header_ops dvb_header_ops = { | 1190 | static const struct header_ops dvb_header_ops = { |
1191 | .create = eth_header, | 1191 | .create = eth_header, |
1192 | .parse = eth_header_parse, | 1192 | .parse = eth_header_parse, |
1193 | .rebuild = eth_rebuild_header, | ||
1194 | }; | 1193 | }; |
1195 | 1194 | ||
1196 | 1195 | ||
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 09de683c167e..10f71c732b59 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c | |||
@@ -104,7 +104,6 @@ EXPORT_SYMBOL(arcnet_timeout); | |||
104 | static int arcnet_header(struct sk_buff *skb, struct net_device *dev, | 104 | static int arcnet_header(struct sk_buff *skb, struct net_device *dev, |
105 | unsigned short type, const void *daddr, | 105 | unsigned short type, const void *daddr, |
106 | const void *saddr, unsigned len); | 106 | const void *saddr, unsigned len); |
107 | static int arcnet_rebuild_header(struct sk_buff *skb); | ||
108 | static int go_tx(struct net_device *dev); | 107 | static int go_tx(struct net_device *dev); |
109 | 108 | ||
110 | static int debug = ARCNET_DEBUG; | 109 | static int debug = ARCNET_DEBUG; |
@@ -312,7 +311,6 @@ static int choose_mtu(void) | |||
312 | 311 | ||
313 | static const struct header_ops arcnet_header_ops = { | 312 | static const struct header_ops arcnet_header_ops = { |
314 | .create = arcnet_header, | 313 | .create = arcnet_header, |
315 | .rebuild = arcnet_rebuild_header, | ||
316 | }; | 314 | }; |
317 | 315 | ||
318 | static const struct net_device_ops arcnet_netdev_ops = { | 316 | 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, | |||
538 | return proto->build_header(skb, dev, type, _daddr); | 536 | return proto->build_header(skb, dev, type, _daddr); |
539 | } | 537 | } |
540 | 538 | ||
541 | |||
542 | /* | ||
543 | * Rebuild the ARCnet hard header. This is called after an ARP (or in the | ||
544 | * future other address resolution) has completed on this sk_buff. We now | ||
545 | * let ARP fill in the destination field. | ||
546 | */ | ||
547 | static int arcnet_rebuild_header(struct sk_buff *skb) | ||
548 | { | ||
549 | struct net_device *dev = skb->dev; | ||
550 | struct arcnet_local *lp = netdev_priv(dev); | ||
551 | int status = 0; /* default is failure */ | ||
552 | unsigned short type; | ||
553 | uint8_t daddr=0; | ||
554 | struct ArcProto *proto; | ||
555 | /* | ||
556 | * XXX: Why not use skb->mac_len? | ||
557 | */ | ||
558 | if (skb->network_header - skb->mac_header != 2) { | ||
559 | BUGMSG(D_NORMAL, | ||
560 | "rebuild_header: shouldn't be here! (hdrsize=%d)\n", | ||
561 | (int)(skb->network_header - skb->mac_header)); | ||
562 | return 0; | ||
563 | } | ||
564 | type = *(uint16_t *) skb_pull(skb, 2); | ||
565 | BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type); | ||
566 | |||
567 | if (type == ETH_P_IP) { | ||
568 | #ifdef CONFIG_INET | ||
569 | BUGMSG(D_DURING, "rebuild header for ethernet protocol %Xh\n", type); | ||
570 | status = arp_find(&daddr, skb) ? 1 : 0; | ||
571 | BUGMSG(D_DURING, " rebuilt: dest is %d; protocol %Xh\n", | ||
572 | daddr, type); | ||
573 | #endif | ||
574 | } else { | ||
575 | BUGMSG(D_NORMAL, | ||
576 | "I don't understand ethernet protocol %Xh addresses!\n", type); | ||
577 | dev->stats.tx_errors++; | ||
578 | dev->stats.tx_aborted_errors++; | ||
579 | } | ||
580 | |||
581 | /* if we couldn't resolve the address... give up. */ | ||
582 | if (!status) | ||
583 | return 0; | ||
584 | |||
585 | /* add the _real_ header this time! */ | ||
586 | proto = arc_proto_map[lp->default_proto[daddr]]; | ||
587 | proto->build_header(skb, dev, type, daddr); | ||
588 | |||
589 | return 1; /* success */ | ||
590 | } | ||
591 | |||
592 | |||
593 | |||
594 | /* Called by the kernel in order to transmit a packet. */ | 539 | /* Called by the kernel in order to transmit a packet. */ |
595 | netdev_tx_t arcnet_send_packet(struct sk_buff *skb, | 540 | netdev_tx_t arcnet_send_packet(struct sk_buff *skb, |
596 | struct net_device *dev) | 541 | struct net_device *dev) |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index daca0dee88f3..0b8393ca8c80 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -284,18 +284,6 @@ static int sp_close(struct net_device *dev) | |||
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | /* Return the frame type ID */ | ||
288 | static int sp_header(struct sk_buff *skb, struct net_device *dev, | ||
289 | unsigned short type, const void *daddr, | ||
290 | const void *saddr, unsigned len) | ||
291 | { | ||
292 | #ifdef CONFIG_INET | ||
293 | if (type != ETH_P_AX25) | ||
294 | return ax25_hard_header(skb, dev, type, daddr, saddr, len); | ||
295 | #endif | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int sp_set_mac_address(struct net_device *dev, void *addr) | 287 | static int sp_set_mac_address(struct net_device *dev, void *addr) |
300 | { | 288 | { |
301 | struct sockaddr_ax25 *sa = addr; | 289 | struct sockaddr_ax25 *sa = addr; |
@@ -309,25 +297,12 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) | |||
309 | return 0; | 297 | return 0; |
310 | } | 298 | } |
311 | 299 | ||
312 | static int sp_rebuild_header(struct sk_buff *skb) | ||
313 | { | ||
314 | #ifdef CONFIG_INET | ||
315 | return ax25_rebuild_header(skb); | ||
316 | #else | ||
317 | return 0; | ||
318 | #endif | ||
319 | } | ||
320 | |||
321 | static const struct header_ops sp_header_ops = { | ||
322 | .create = sp_header, | ||
323 | .rebuild = sp_rebuild_header, | ||
324 | }; | ||
325 | |||
326 | static const struct net_device_ops sp_netdev_ops = { | 300 | static const struct net_device_ops sp_netdev_ops = { |
327 | .ndo_open = sp_open_dev, | 301 | .ndo_open = sp_open_dev, |
328 | .ndo_stop = sp_close, | 302 | .ndo_stop = sp_close, |
329 | .ndo_start_xmit = sp_xmit, | 303 | .ndo_start_xmit = sp_xmit, |
330 | .ndo_set_mac_address = sp_set_mac_address, | 304 | .ndo_set_mac_address = sp_set_mac_address, |
305 | .ndo_neigh_construct = ax25_neigh_construct, | ||
331 | }; | 306 | }; |
332 | 307 | ||
333 | static void sp_setup(struct net_device *dev) | 308 | static void sp_setup(struct net_device *dev) |
@@ -337,10 +312,11 @@ static void sp_setup(struct net_device *dev) | |||
337 | dev->destructor = free_netdev; | 312 | dev->destructor = free_netdev; |
338 | dev->mtu = SIXP_MTU; | 313 | dev->mtu = SIXP_MTU; |
339 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 314 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
340 | dev->header_ops = &sp_header_ops; | 315 | dev->header_ops = &ax25_header_ops; |
341 | 316 | ||
342 | dev->addr_len = AX25_ADDR_LEN; | 317 | dev->addr_len = AX25_ADDR_LEN; |
343 | dev->type = ARPHRD_AX25; | 318 | dev->type = ARPHRD_AX25; |
319 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
344 | dev->tx_queue_len = 10; | 320 | dev->tx_queue_len = 10; |
345 | 321 | ||
346 | /* Only activated in AX.25 mode */ | 322 | /* Only activated in AX.25 mode */ |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index a98c153f371e..3539ab392f7d 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -1109,6 +1109,7 @@ static const struct net_device_ops baycom_netdev_ops = { | |||
1109 | .ndo_do_ioctl = baycom_ioctl, | 1109 | .ndo_do_ioctl = baycom_ioctl, |
1110 | .ndo_start_xmit = baycom_send_packet, | 1110 | .ndo_start_xmit = baycom_send_packet, |
1111 | .ndo_set_mac_address = baycom_set_mac_address, | 1111 | .ndo_set_mac_address = baycom_set_mac_address, |
1112 | .ndo_neigh_construct = ax25_neigh_construct, | ||
1112 | }; | 1113 | }; |
1113 | 1114 | ||
1114 | /* | 1115 | /* |
@@ -1146,6 +1147,7 @@ static void baycom_probe(struct net_device *dev) | |||
1146 | dev->header_ops = &ax25_header_ops; | 1147 | dev->header_ops = &ax25_header_ops; |
1147 | 1148 | ||
1148 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ | 1149 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ |
1150 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1149 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 1151 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
1150 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ | 1152 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ |
1151 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ | 1153 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ |
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index c2894e43840e..bce105b16ed0 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -469,6 +469,7 @@ static const struct net_device_ops bpq_netdev_ops = { | |||
469 | .ndo_start_xmit = bpq_xmit, | 469 | .ndo_start_xmit = bpq_xmit, |
470 | .ndo_set_mac_address = bpq_set_mac_address, | 470 | .ndo_set_mac_address = bpq_set_mac_address, |
471 | .ndo_do_ioctl = bpq_ioctl, | 471 | .ndo_do_ioctl = bpq_ioctl, |
472 | .ndo_neigh_construct = ax25_neigh_construct, | ||
472 | }; | 473 | }; |
473 | 474 | ||
474 | static void bpq_setup(struct net_device *dev) | 475 | static void bpq_setup(struct net_device *dev) |
@@ -486,6 +487,7 @@ static void bpq_setup(struct net_device *dev) | |||
486 | #endif | 487 | #endif |
487 | 488 | ||
488 | dev->type = ARPHRD_AX25; | 489 | dev->type = ARPHRD_AX25; |
490 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
489 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 491 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
490 | dev->mtu = AX25_DEF_PACLEN; | 492 | dev->mtu = AX25_DEF_PACLEN; |
491 | dev->addr_len = AX25_ADDR_LEN; | 493 | dev->addr_len = AX25_ADDR_LEN; |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0fad408f24aa..abab7be77406 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -433,6 +433,7 @@ module_exit(dmascc_exit); | |||
433 | static void __init dev_setup(struct net_device *dev) | 433 | static void __init dev_setup(struct net_device *dev) |
434 | { | 434 | { |
435 | dev->type = ARPHRD_AX25; | 435 | dev->type = ARPHRD_AX25; |
436 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
436 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 437 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
437 | dev->mtu = 1500; | 438 | dev->mtu = 1500; |
438 | dev->addr_len = AX25_ADDR_LEN; | 439 | dev->addr_len = AX25_ADDR_LEN; |
@@ -447,6 +448,7 @@ static const struct net_device_ops scc_netdev_ops = { | |||
447 | .ndo_start_xmit = scc_send_packet, | 448 | .ndo_start_xmit = scc_send_packet, |
448 | .ndo_do_ioctl = scc_ioctl, | 449 | .ndo_do_ioctl = scc_ioctl, |
449 | .ndo_set_mac_address = scc_set_mac_address, | 450 | .ndo_set_mac_address = scc_set_mac_address, |
451 | .ndo_neigh_construct = ax25_neigh_construct, | ||
450 | }; | 452 | }; |
451 | 453 | ||
452 | static int __init setup_adapter(int card_base, int type, int n) | 454 | static int __init setup_adapter(int card_base, int type, int n) |
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index c67a27245072..435868a7b69c 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c | |||
@@ -626,6 +626,7 @@ static const struct net_device_ops hdlcdrv_netdev = { | |||
626 | .ndo_start_xmit = hdlcdrv_send_packet, | 626 | .ndo_start_xmit = hdlcdrv_send_packet, |
627 | .ndo_do_ioctl = hdlcdrv_ioctl, | 627 | .ndo_do_ioctl = hdlcdrv_ioctl, |
628 | .ndo_set_mac_address = hdlcdrv_set_mac_address, | 628 | .ndo_set_mac_address = hdlcdrv_set_mac_address, |
629 | .ndo_neigh_construct = ax25_neigh_construct, | ||
629 | }; | 630 | }; |
630 | 631 | ||
631 | /* | 632 | /* |
@@ -676,6 +677,7 @@ static void hdlcdrv_setup(struct net_device *dev) | |||
676 | dev->header_ops = &ax25_header_ops; | 677 | dev->header_ops = &ax25_header_ops; |
677 | 678 | ||
678 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ | 679 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ |
680 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
679 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 681 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
680 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ | 682 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ |
681 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ | 683 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index f990bb1c3e02..c12ec2c2b594 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -573,32 +573,6 @@ static int ax_open_dev(struct net_device *dev) | |||
573 | return 0; | 573 | return 0; |
574 | } | 574 | } |
575 | 575 | ||
576 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | ||
577 | |||
578 | /* Return the frame type ID */ | ||
579 | static int ax_header(struct sk_buff *skb, struct net_device *dev, | ||
580 | unsigned short type, const void *daddr, | ||
581 | const void *saddr, unsigned len) | ||
582 | { | ||
583 | #ifdef CONFIG_INET | ||
584 | if (type != ETH_P_AX25) | ||
585 | return ax25_hard_header(skb, dev, type, daddr, saddr, len); | ||
586 | #endif | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | |||
591 | static int ax_rebuild_header(struct sk_buff *skb) | ||
592 | { | ||
593 | #ifdef CONFIG_INET | ||
594 | return ax25_rebuild_header(skb); | ||
595 | #else | ||
596 | return 0; | ||
597 | #endif | ||
598 | } | ||
599 | |||
600 | #endif /* CONFIG_{AX25,AX25_MODULE} */ | ||
601 | |||
602 | /* Open the low-level part of the AX25 channel. Easy! */ | 576 | /* Open the low-level part of the AX25 channel. Easy! */ |
603 | static int ax_open(struct net_device *dev) | 577 | static int ax_open(struct net_device *dev) |
604 | { | 578 | { |
@@ -662,16 +636,12 @@ static int ax_close(struct net_device *dev) | |||
662 | return 0; | 636 | return 0; |
663 | } | 637 | } |
664 | 638 | ||
665 | static const struct header_ops ax_header_ops = { | ||
666 | .create = ax_header, | ||
667 | .rebuild = ax_rebuild_header, | ||
668 | }; | ||
669 | |||
670 | static const struct net_device_ops ax_netdev_ops = { | 639 | static const struct net_device_ops ax_netdev_ops = { |
671 | .ndo_open = ax_open_dev, | 640 | .ndo_open = ax_open_dev, |
672 | .ndo_stop = ax_close, | 641 | .ndo_stop = ax_close, |
673 | .ndo_start_xmit = ax_xmit, | 642 | .ndo_start_xmit = ax_xmit, |
674 | .ndo_set_mac_address = ax_set_mac_address, | 643 | .ndo_set_mac_address = ax_set_mac_address, |
644 | .ndo_neigh_construct = ax25_neigh_construct, | ||
675 | }; | 645 | }; |
676 | 646 | ||
677 | static void ax_setup(struct net_device *dev) | 647 | static void ax_setup(struct net_device *dev) |
@@ -681,8 +651,9 @@ static void ax_setup(struct net_device *dev) | |||
681 | dev->hard_header_len = 0; | 651 | dev->hard_header_len = 0; |
682 | dev->addr_len = 0; | 652 | dev->addr_len = 0; |
683 | dev->type = ARPHRD_AX25; | 653 | dev->type = ARPHRD_AX25; |
654 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
684 | dev->tx_queue_len = 10; | 655 | dev->tx_queue_len = 10; |
685 | dev->header_ops = &ax_header_ops; | 656 | dev->header_ops = &ax25_header_ops; |
686 | dev->netdev_ops = &ax_netdev_ops; | 657 | dev->netdev_ops = &ax_netdev_ops; |
687 | 658 | ||
688 | 659 | ||
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 57be9e0e98a6..b305f51eb420 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1550,6 +1550,7 @@ static const struct net_device_ops scc_netdev_ops = { | |||
1550 | .ndo_set_mac_address = scc_net_set_mac_address, | 1550 | .ndo_set_mac_address = scc_net_set_mac_address, |
1551 | .ndo_get_stats = scc_net_get_stats, | 1551 | .ndo_get_stats = scc_net_get_stats, |
1552 | .ndo_do_ioctl = scc_net_ioctl, | 1552 | .ndo_do_ioctl = scc_net_ioctl, |
1553 | .ndo_neigh_construct = ax25_neigh_construct, | ||
1553 | }; | 1554 | }; |
1554 | 1555 | ||
1555 | /* ----> Initialize device <----- */ | 1556 | /* ----> Initialize device <----- */ |
@@ -1567,6 +1568,7 @@ static void scc_net_setup(struct net_device *dev) | |||
1567 | dev->flags = 0; | 1568 | dev->flags = 0; |
1568 | 1569 | ||
1569 | dev->type = ARPHRD_AX25; | 1570 | dev->type = ARPHRD_AX25; |
1571 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1570 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 1572 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
1571 | dev->mtu = AX25_DEF_PACLEN; | 1573 | dev->mtu = AX25_DEF_PACLEN; |
1572 | dev->addr_len = AX25_ADDR_LEN; | 1574 | dev->addr_len = AX25_ADDR_LEN; |
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 717433cfb81d..89d9da7a0c51 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c | |||
@@ -1100,6 +1100,7 @@ static const struct net_device_ops yam_netdev_ops = { | |||
1100 | .ndo_start_xmit = yam_send_packet, | 1100 | .ndo_start_xmit = yam_send_packet, |
1101 | .ndo_do_ioctl = yam_ioctl, | 1101 | .ndo_do_ioctl = yam_ioctl, |
1102 | .ndo_set_mac_address = yam_set_mac_address, | 1102 | .ndo_set_mac_address = yam_set_mac_address, |
1103 | .ndo_neigh_construct = ax25_neigh_construct, | ||
1103 | }; | 1104 | }; |
1104 | 1105 | ||
1105 | static void yam_setup(struct net_device *dev) | 1106 | static void yam_setup(struct net_device *dev) |
@@ -1128,6 +1129,7 @@ static void yam_setup(struct net_device *dev) | |||
1128 | dev->header_ops = &ax25_header_ops; | 1129 | dev->header_ops = &ax25_header_ops; |
1129 | 1130 | ||
1130 | dev->type = ARPHRD_AX25; | 1131 | dev->type = ARPHRD_AX25; |
1132 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1131 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 1133 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
1132 | dev->mtu = AX25_MTU; | 1134 | dev->mtu = AX25_MTU; |
1133 | dev->addr_len = AX25_ADDR_LEN; | 1135 | dev->addr_len = AX25_ADDR_LEN; |
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 4f4099d5603d..2950c3780230 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c | |||
@@ -336,7 +336,6 @@ static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
336 | 336 | ||
337 | static const struct header_ops ipvlan_header_ops = { | 337 | static const struct header_ops ipvlan_header_ops = { |
338 | .create = ipvlan_hard_header, | 338 | .create = ipvlan_hard_header, |
339 | .rebuild = eth_rebuild_header, | ||
340 | .parse = eth_header_parse, | 339 | .parse = eth_header_parse, |
341 | .cache = eth_header_cache, | 340 | .cache = eth_header_cache, |
342 | .cache_update = eth_header_cache_update, | 341 | .cache_update = eth_header_cache_update, |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1df38bdae2ee..b5e3320ca506 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -550,7 +550,6 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
550 | 550 | ||
551 | static const struct header_ops macvlan_hard_header_ops = { | 551 | static const struct header_ops macvlan_hard_header_ops = { |
552 | .create = macvlan_hard_header, | 552 | .create = macvlan_hard_header, |
553 | .rebuild = eth_rebuild_header, | ||
554 | .parse = eth_header_parse, | 553 | .parse = eth_header_parse, |
555 | .cache = eth_header_cache, | 554 | .cache = eth_header_cache, |
556 | .cache_update = eth_header_cache_update, | 555 | .cache_update = eth_header_cache_update, |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 52919ad42726..8f9f3e9fbfce 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -798,7 +798,6 @@ static void prism2_tx_timeout(struct net_device *dev) | |||
798 | 798 | ||
799 | const struct header_ops hostap_80211_ops = { | 799 | const struct header_ops hostap_80211_ops = { |
800 | .create = eth_header, | 800 | .create = eth_header, |
801 | .rebuild = eth_rebuild_header, | ||
802 | .cache = eth_header_cache, | 801 | .cache = eth_header_cache, |
803 | .cache_update = eth_header_cache_update, | 802 | .cache_update = eth_header_cache_update, |
804 | .parse = hostap_80211_header_parse, | 803 | .parse = hostap_80211_header_parse, |
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 1d869d185a0d..606563ef8a72 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -35,7 +35,6 @@ extern const struct header_ops eth_header_ops; | |||
35 | 35 | ||
36 | int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, | 36 | int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, |
37 | const void *daddr, const void *saddr, unsigned len); | 37 | const void *daddr, const void *saddr, unsigned len); |
38 | int eth_rebuild_header(struct sk_buff *skb); | ||
39 | int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); | 38 | int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); |
40 | int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, | 39 | int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, |
41 | __be16 type); | 40 | __be16 type); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5897b4ea5a3f..2007f3b44d05 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -261,7 +261,6 @@ struct header_ops { | |||
261 | unsigned short type, const void *daddr, | 261 | unsigned short type, const void *daddr, |
262 | const void *saddr, unsigned int len); | 262 | const void *saddr, unsigned int len); |
263 | int (*parse)(const struct sk_buff *skb, unsigned char *haddr); | 263 | int (*parse)(const struct sk_buff *skb, unsigned char *haddr); |
264 | int (*rebuild)(struct sk_buff *skb); | ||
265 | int (*cache)(const struct neighbour *neigh, struct hh_cache *hh, __be16 type); | 264 | int (*cache)(const struct neighbour *neigh, struct hh_cache *hh, __be16 type); |
266 | void (*cache_update)(struct hh_cache *hh, | 265 | void (*cache_update)(struct hh_cache *hh, |
267 | const struct net_device *dev, | 266 | const struct net_device *dev, |
@@ -1346,7 +1345,7 @@ enum netdev_priv_flags { | |||
1346 | * if one wants to override the ndo_*() functions | 1345 | * if one wants to override the ndo_*() functions |
1347 | * @ethtool_ops: Management operations | 1346 | * @ethtool_ops: Management operations |
1348 | * @fwd_ops: Management operations | 1347 | * @fwd_ops: Management operations |
1349 | * @header_ops: Includes callbacks for creating,parsing,rebuilding,etc | 1348 | * @header_ops: Includes callbacks for creating,parsing,caching,etc |
1350 | * of Layer 2 headers. | 1349 | * of Layer 2 headers. |
1351 | * | 1350 | * |
1352 | * @flags: Interface flags (a la BSD) | 1351 | * @flags: Interface flags (a la BSD) |
@@ -2399,15 +2398,6 @@ static inline int dev_parse_header(const struct sk_buff *skb, | |||
2399 | return dev->header_ops->parse(skb, haddr); | 2398 | return dev->header_ops->parse(skb, haddr); |
2400 | } | 2399 | } |
2401 | 2400 | ||
2402 | static inline int dev_rebuild_header(struct sk_buff *skb) | ||
2403 | { | ||
2404 | const struct net_device *dev = skb->dev; | ||
2405 | |||
2406 | if (!dev->header_ops || !dev->header_ops->rebuild) | ||
2407 | return 0; | ||
2408 | return dev->header_ops->rebuild(skb); | ||
2409 | } | ||
2410 | |||
2411 | typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); | 2401 | typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); |
2412 | int register_gifconf(unsigned int family, gifconf_func_t *gifconf); | 2402 | int register_gifconf(unsigned int family, gifconf_func_t *gifconf); |
2413 | static inline int unregister_gifconf(unsigned int family) | 2403 | static inline int unregister_gifconf(unsigned int family) |
diff --git a/include/net/arp.h b/include/net/arp.h index 73c49864076b..21ee1860abbc 100644 --- a/include/net/arp.h +++ b/include/net/arp.h | |||
@@ -47,7 +47,6 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 | |||
47 | } | 47 | } |
48 | 48 | ||
49 | void arp_init(void); | 49 | void arp_init(void); |
50 | int arp_find(unsigned char *haddr, struct sk_buff *skb); | ||
51 | int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); | 50 | int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); |
52 | void arp_send(int type, int ptype, __be32 dest_ip, | 51 | void arp_send(int type, int ptype, __be32 dest_ip, |
53 | struct net_device *dev, __be32 src_ip, | 52 | struct net_device *dev, __be32 src_ip, |
diff --git a/include/net/ax25.h b/include/net/ax25.h index bf0396e9a5d3..45feeba7a325 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/atomic.h> | 14 | #include <linux/atomic.h> |
15 | #include <net/neighbour.h> | ||
15 | 16 | ||
16 | #define AX25_T1CLAMPLO 1 | 17 | #define AX25_T1CLAMPLO 1 |
17 | #define AX25_T1CLAMPHI (30 * HZ) | 18 | #define AX25_T1CLAMPHI (30 * HZ) |
@@ -366,10 +367,11 @@ int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, | |||
366 | struct net_device *); | 367 | struct net_device *); |
367 | 368 | ||
368 | /* ax25_ip.c */ | 369 | /* ax25_ip.c */ |
369 | int ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, | 370 | int ax25_neigh_construct(struct neighbour *neigh); |
370 | const void *, const void *, unsigned int); | ||
371 | int ax25_rebuild_header(struct sk_buff *); | ||
372 | extern const struct header_ops ax25_header_ops; | 371 | extern const struct header_ops ax25_header_ops; |
372 | struct ax25_neigh_priv { | ||
373 | struct neigh_ops ops; | ||
374 | }; | ||
373 | 375 | ||
374 | /* ax25_out.c */ | 376 | /* ax25_out.c */ |
375 | ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, | 377 | ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 76f708486aae..9f912e4d4232 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -193,6 +193,7 @@ struct neigh_table { | |||
193 | int family; | 193 | int family; |
194 | int entry_size; | 194 | int entry_size; |
195 | int key_len; | 195 | int key_len; |
196 | __be16 protocol; | ||
196 | __u32 (*hash)(const void *pkey, | 197 | __u32 (*hash)(const void *pkey, |
197 | const struct net_device *dev, | 198 | const struct net_device *dev, |
198 | __u32 *hash_rnd); | 199 | __u32 *hash_rnd); |
@@ -268,7 +269,6 @@ void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); | |||
268 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); | 269 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); |
269 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb); | 270 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb); |
270 | int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb); | 271 | int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb); |
271 | int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb); | ||
272 | int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb); | 272 | int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb); |
273 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, | 273 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, |
274 | u8 *lladdr, void *saddr, | 274 | u8 *lladdr, void *saddr, |
diff --git a/net/802/fc.c b/net/802/fc.c index 7c174b6750cd..7b9219022418 100644 --- a/net/802/fc.c +++ b/net/802/fc.c | |||
@@ -75,29 +75,8 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev, | |||
75 | return -hdr_len; | 75 | return -hdr_len; |
76 | } | 76 | } |
77 | 77 | ||
78 | /* | ||
79 | * A neighbour discovery of some species (eg arp) has completed. We | ||
80 | * can now send the packet. | ||
81 | */ | ||
82 | |||
83 | static int fc_rebuild_header(struct sk_buff *skb) | ||
84 | { | ||
85 | #ifdef CONFIG_INET | ||
86 | struct fch_hdr *fch=(struct fch_hdr *)skb->data; | ||
87 | struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr)); | ||
88 | if(fcllc->ethertype != htons(ETH_P_IP)) { | ||
89 | printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype)); | ||
90 | return 0; | ||
91 | } | ||
92 | return arp_find(fch->daddr, skb); | ||
93 | #else | ||
94 | return 0; | ||
95 | #endif | ||
96 | } | ||
97 | |||
98 | static const struct header_ops fc_header_ops = { | 78 | static const struct header_ops fc_header_ops = { |
99 | .create = fc_header, | 79 | .create = fc_header, |
100 | .rebuild = fc_rebuild_header, | ||
101 | }; | 80 | }; |
102 | 81 | ||
103 | static void fc_setup(struct net_device *dev) | 82 | static void fc_setup(struct net_device *dev) |
diff --git a/net/802/fddi.c b/net/802/fddi.c index 59e7346f1193..7d3a0af954e8 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c | |||
@@ -87,31 +87,6 @@ static int fddi_header(struct sk_buff *skb, struct net_device *dev, | |||
87 | return -hl; | 87 | return -hl; |
88 | } | 88 | } |
89 | 89 | ||
90 | |||
91 | /* | ||
92 | * Rebuild the FDDI MAC header. This is called after an ARP | ||
93 | * (or in future other address resolution) has completed on | ||
94 | * this sk_buff. We now let ARP fill in the other fields. | ||
95 | */ | ||
96 | |||
97 | static int fddi_rebuild_header(struct sk_buff *skb) | ||
98 | { | ||
99 | struct fddihdr *fddi = (struct fddihdr *)skb->data; | ||
100 | |||
101 | #ifdef CONFIG_INET | ||
102 | if (fddi->hdr.llc_snap.ethertype == htons(ETH_P_IP)) | ||
103 | /* Try to get ARP to resolve the header and fill destination address */ | ||
104 | return arp_find(fddi->daddr, skb); | ||
105 | else | ||
106 | #endif | ||
107 | { | ||
108 | printk("%s: Don't know how to resolve type %04X addresses.\n", | ||
109 | skb->dev->name, ntohs(fddi->hdr.llc_snap.ethertype)); | ||
110 | return 0; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | |||
115 | /* | 90 | /* |
116 | * Determine the packet's protocol ID and fill in skb fields. | 91 | * Determine the packet's protocol ID and fill in skb fields. |
117 | * This routine is called before an incoming packet is passed | 92 | * This routine is called before an incoming packet is passed |
@@ -177,7 +152,6 @@ EXPORT_SYMBOL(fddi_change_mtu); | |||
177 | 152 | ||
178 | static const struct header_ops fddi_header_ops = { | 153 | static const struct header_ops fddi_header_ops = { |
179 | .create = fddi_header, | 154 | .create = fddi_header, |
180 | .rebuild = fddi_rebuild_header, | ||
181 | }; | 155 | }; |
182 | 156 | ||
183 | 157 | ||
diff --git a/net/802/hippi.c b/net/802/hippi.c index 2e03f8259dd5..ade1a52cdcff 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c | |||
@@ -91,33 +91,6 @@ static int hippi_header(struct sk_buff *skb, struct net_device *dev, | |||
91 | 91 | ||
92 | 92 | ||
93 | /* | 93 | /* |
94 | * Rebuild the HIPPI MAC header. This is called after an ARP has | ||
95 | * completed on this sk_buff. We now let ARP fill in the other fields. | ||
96 | */ | ||
97 | |||
98 | static int hippi_rebuild_header(struct sk_buff *skb) | ||
99 | { | ||
100 | struct hippi_hdr *hip = (struct hippi_hdr *)skb->data; | ||
101 | |||
102 | /* | ||
103 | * Only IP is currently supported | ||
104 | */ | ||
105 | |||
106 | if(hip->snap.ethertype != htons(ETH_P_IP)) | ||
107 | { | ||
108 | printk(KERN_DEBUG "%s: unable to resolve type %X addresses.\n",skb->dev->name,ntohs(hip->snap.ethertype)); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * We don't support dynamic ARP on HIPPI, but we use the ARP | ||
114 | * static ARP tables to hold the I-FIELDs. | ||
115 | */ | ||
116 | return arp_find(hip->le.daddr, skb); | ||
117 | } | ||
118 | |||
119 | |||
120 | /* | ||
121 | * Determine the packet's protocol ID. | 94 | * Determine the packet's protocol ID. |
122 | */ | 95 | */ |
123 | 96 | ||
@@ -186,7 +159,6 @@ EXPORT_SYMBOL(hippi_neigh_setup_dev); | |||
186 | 159 | ||
187 | static const struct header_ops hippi_header_ops = { | 160 | static const struct header_ops hippi_header_ops = { |
188 | .create = hippi_header, | 161 | .create = hippi_header, |
189 | .rebuild = hippi_rebuild_header, | ||
190 | }; | 162 | }; |
191 | 163 | ||
192 | 164 | ||
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 118956448cf6..1dcfec8b49f3 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -37,39 +37,6 @@ | |||
37 | #include <linux/netpoll.h> | 37 | #include <linux/netpoll.h> |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Rebuild the Ethernet MAC header. This is called after an ARP | ||
41 | * (or in future other address resolution) has completed on this | ||
42 | * sk_buff. We now let ARP fill in the other fields. | ||
43 | * | ||
44 | * This routine CANNOT use cached dst->neigh! | ||
45 | * Really, it is used only when dst->neigh is wrong. | ||
46 | * | ||
47 | * TODO: This needs a checkup, I'm ignorant here. --BLG | ||
48 | */ | ||
49 | static int vlan_dev_rebuild_header(struct sk_buff *skb) | ||
50 | { | ||
51 | struct net_device *dev = skb->dev; | ||
52 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | ||
53 | |||
54 | switch (veth->h_vlan_encapsulated_proto) { | ||
55 | #ifdef CONFIG_INET | ||
56 | case htons(ETH_P_IP): | ||
57 | |||
58 | /* TODO: Confirm this will work with VLAN headers... */ | ||
59 | return arp_find(veth->h_dest, skb); | ||
60 | #endif | ||
61 | default: | ||
62 | pr_debug("%s: unable to resolve type %X addresses\n", | ||
63 | dev->name, ntohs(veth->h_vlan_encapsulated_proto)); | ||
64 | |||
65 | ether_addr_copy(veth->h_source, dev->dev_addr); | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Create the VLAN header for an arbitrary protocol layer | 40 | * Create the VLAN header for an arbitrary protocol layer |
74 | * | 41 | * |
75 | * saddr=NULL means use device source address | 42 | * saddr=NULL means use device source address |
@@ -534,7 +501,6 @@ static int vlan_dev_get_lock_subclass(struct net_device *dev) | |||
534 | 501 | ||
535 | static const struct header_ops vlan_header_ops = { | 502 | static const struct header_ops vlan_header_ops = { |
536 | .create = vlan_dev_hard_header, | 503 | .create = vlan_dev_hard_header, |
537 | .rebuild = vlan_dev_rebuild_header, | ||
538 | .parse = eth_header_parse, | 504 | .parse = eth_header_parse, |
539 | }; | 505 | }; |
540 | 506 | ||
@@ -554,7 +520,6 @@ static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev | |||
554 | 520 | ||
555 | static const struct header_ops vlan_passthru_header_ops = { | 521 | static const struct header_ops vlan_passthru_header_ops = { |
556 | .create = vlan_passthru_hard_header, | 522 | .create = vlan_passthru_hard_header, |
557 | .rebuild = dev_rebuild_header, | ||
558 | .parse = eth_header_parse, | 523 | .parse = eth_header_parse, |
559 | }; | 524 | }; |
560 | 525 | ||
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index 67de6b33f2c3..e030c64ebfb7 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c | |||
@@ -46,9 +46,9 @@ | |||
46 | 46 | ||
47 | #ifdef CONFIG_INET | 47 | #ifdef CONFIG_INET |
48 | 48 | ||
49 | int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, | 49 | static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, |
50 | unsigned short type, const void *daddr, | 50 | unsigned short type, const void *daddr, |
51 | const void *saddr, unsigned int len) | 51 | const void *saddr, unsigned int len) |
52 | { | 52 | { |
53 | unsigned char *buff; | 53 | unsigned char *buff; |
54 | 54 | ||
@@ -100,7 +100,7 @@ int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
100 | return -AX25_HEADER_LEN; /* Unfinished header */ | 100 | return -AX25_HEADER_LEN; /* Unfinished header */ |
101 | } | 101 | } |
102 | 102 | ||
103 | int ax25_rebuild_header(struct sk_buff *skb) | 103 | static int ax25_neigh_xmit(struct sk_buff *skb) |
104 | { | 104 | { |
105 | struct sk_buff *ourskb; | 105 | struct sk_buff *ourskb; |
106 | unsigned char *bp = skb->data; | 106 | unsigned char *bp = skb->data; |
@@ -115,9 +115,6 @@ int ax25_rebuild_header(struct sk_buff *skb) | |||
115 | dst = (ax25_address *)(bp + 1); | 115 | dst = (ax25_address *)(bp + 1); |
116 | src = (ax25_address *)(bp + 8); | 116 | src = (ax25_address *)(bp + 8); |
117 | 117 | ||
118 | if (arp_find(bp + 1, skb)) | ||
119 | return 1; | ||
120 | |||
121 | route = ax25_get_route(dst, NULL); | 118 | route = ax25_get_route(dst, NULL); |
122 | if (route) { | 119 | if (route) { |
123 | digipeat = route->digipeat; | 120 | digipeat = route->digipeat; |
@@ -129,6 +126,7 @@ int ax25_rebuild_header(struct sk_buff *skb) | |||
129 | dev = skb->dev; | 126 | dev = skb->dev; |
130 | 127 | ||
131 | if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) { | 128 | if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) { |
129 | kfree_skb(skb); | ||
132 | goto put; | 130 | goto put; |
133 | } | 131 | } |
134 | 132 | ||
@@ -215,28 +213,74 @@ put: | |||
215 | return 1; | 213 | return 1; |
216 | } | 214 | } |
217 | 215 | ||
216 | static int ax25_neigh_output(struct neighbour *neigh, struct sk_buff *skb) | ||
217 | { | ||
218 | /* Except for calling ax25_neigh_xmit instead of | ||
219 | * dev_queue_xmit this is neigh_resolve_output. | ||
220 | */ | ||
221 | int rc = 0; | ||
222 | |||
223 | if (!neigh_event_send(neigh, skb)) { | ||
224 | int err; | ||
225 | struct net_device *dev = neigh->dev; | ||
226 | unsigned int seq; | ||
227 | |||
228 | do { | ||
229 | __skb_pull(skb, skb_network_offset(skb)); | ||
230 | seq = read_seqbegin(&neigh->ha_lock); | ||
231 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), | ||
232 | neigh->ha, NULL, skb->len); | ||
233 | } while (read_seqretry(&neigh->ha_lock, seq)); | ||
234 | |||
235 | if (err >= 0) { | ||
236 | ax25_neigh_xmit(skb); | ||
237 | } else | ||
238 | goto out_kfree_skb; | ||
239 | } | ||
240 | out: | ||
241 | return rc; | ||
242 | |||
243 | out_kfree_skb: | ||
244 | rc = -EINVAL; | ||
245 | kfree_skb(skb); | ||
246 | goto out; | ||
247 | } | ||
248 | |||
249 | int ax25_neigh_construct(struct neighbour *neigh) | ||
250 | { | ||
251 | /* This trouble could be saved if ax25 would right a proper | ||
252 | * dev_queue_xmit function. | ||
253 | */ | ||
254 | struct ax25_neigh_priv *priv = neighbour_priv(neigh); | ||
255 | |||
256 | if (neigh->tbl->family != AF_INET) | ||
257 | return -EINVAL; | ||
258 | |||
259 | priv->ops = *neigh->ops; | ||
260 | priv->ops.output = ax25_neigh_output; | ||
261 | priv->ops.connected_output = ax25_neigh_output; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
218 | #else /* INET */ | 265 | #else /* INET */ |
219 | 266 | ||
220 | int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, | 267 | static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, |
221 | unsigned short type, const void *daddr, | 268 | unsigned short type, const void *daddr, |
222 | const void *saddr, unsigned int len) | 269 | const void *saddr, unsigned int len) |
223 | { | 270 | { |
224 | return -AX25_HEADER_LEN; | 271 | return -AX25_HEADER_LEN; |
225 | } | 272 | } |
226 | 273 | ||
227 | int ax25_rebuild_header(struct sk_buff *skb) | 274 | int ax25_neigh_construct(struct neighbour *neigh) |
228 | { | 275 | { |
229 | return 1; | 276 | return 0; |
230 | } | 277 | } |
231 | |||
232 | #endif | 278 | #endif |
233 | 279 | ||
234 | const struct header_ops ax25_header_ops = { | 280 | const struct header_ops ax25_header_ops = { |
235 | .create = ax25_hard_header, | 281 | .create = ax25_hard_header, |
236 | .rebuild = ax25_rebuild_header, | ||
237 | }; | 282 | }; |
238 | 283 | ||
239 | EXPORT_SYMBOL(ax25_hard_header); | ||
240 | EXPORT_SYMBOL(ax25_rebuild_header); | ||
241 | EXPORT_SYMBOL(ax25_header_ops); | 284 | EXPORT_SYMBOL(ax25_header_ops); |
285 | EXPORT_SYMBOL(ax25_neigh_construct); | ||
242 | 286 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 70fe9e10ac86..0f48ea3affed 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1263,10 +1263,10 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, | |||
1263 | EXPORT_SYMBOL(neigh_event_ns); | 1263 | EXPORT_SYMBOL(neigh_event_ns); |
1264 | 1264 | ||
1265 | /* called with read_lock_bh(&n->lock); */ | 1265 | /* called with read_lock_bh(&n->lock); */ |
1266 | static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst) | 1266 | static void neigh_hh_init(struct neighbour *n) |
1267 | { | 1267 | { |
1268 | struct net_device *dev = dst->dev; | 1268 | struct net_device *dev = n->dev; |
1269 | __be16 prot = dst->ops->protocol; | 1269 | __be16 prot = n->tbl->protocol; |
1270 | struct hh_cache *hh = &n->hh; | 1270 | struct hh_cache *hh = &n->hh; |
1271 | 1271 | ||
1272 | write_lock_bh(&n->lock); | 1272 | write_lock_bh(&n->lock); |
@@ -1280,43 +1280,19 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst) | |||
1280 | write_unlock_bh(&n->lock); | 1280 | write_unlock_bh(&n->lock); |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | /* This function can be used in contexts, where only old dev_queue_xmit | ||
1284 | * worked, f.e. if you want to override normal output path (eql, shaper), | ||
1285 | * but resolution is not made yet. | ||
1286 | */ | ||
1287 | |||
1288 | int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb) | ||
1289 | { | ||
1290 | struct net_device *dev = skb->dev; | ||
1291 | |||
1292 | __skb_pull(skb, skb_network_offset(skb)); | ||
1293 | |||
1294 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, | ||
1295 | skb->len) < 0 && | ||
1296 | dev_rebuild_header(skb)) | ||
1297 | return 0; | ||
1298 | |||
1299 | return dev_queue_xmit(skb); | ||
1300 | } | ||
1301 | EXPORT_SYMBOL(neigh_compat_output); | ||
1302 | |||
1303 | /* Slow and careful. */ | 1283 | /* Slow and careful. */ |
1304 | 1284 | ||
1305 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) | 1285 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) |
1306 | { | 1286 | { |
1307 | struct dst_entry *dst = skb_dst(skb); | ||
1308 | int rc = 0; | 1287 | int rc = 0; |
1309 | 1288 | ||
1310 | if (!dst) | ||
1311 | goto discard; | ||
1312 | |||
1313 | if (!neigh_event_send(neigh, skb)) { | 1289 | if (!neigh_event_send(neigh, skb)) { |
1314 | int err; | 1290 | int err; |
1315 | struct net_device *dev = neigh->dev; | 1291 | struct net_device *dev = neigh->dev; |
1316 | unsigned int seq; | 1292 | unsigned int seq; |
1317 | 1293 | ||
1318 | if (dev->header_ops->cache && !neigh->hh.hh_len) | 1294 | if (dev->header_ops->cache && !neigh->hh.hh_len) |
1319 | neigh_hh_init(neigh, dst); | 1295 | neigh_hh_init(neigh); |
1320 | 1296 | ||
1321 | do { | 1297 | do { |
1322 | __skb_pull(skb, skb_network_offset(skb)); | 1298 | __skb_pull(skb, skb_network_offset(skb)); |
@@ -1332,8 +1308,6 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1332 | } | 1308 | } |
1333 | out: | 1309 | out: |
1334 | return rc; | 1310 | return rc; |
1335 | discard: | ||
1336 | neigh_dbg(1, "%s: dst=%p neigh=%p\n", __func__, dst, neigh); | ||
1337 | out_kfree_skb: | 1311 | out_kfree_skb: |
1338 | rc = -EINVAL; | 1312 | rc = -EINVAL; |
1339 | kfree_skb(skb); | 1313 | kfree_skb(skb); |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 7ca7c3143da3..f123c6c6748c 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -97,6 +97,7 @@ struct neigh_table dn_neigh_table = { | |||
97 | .family = PF_DECnet, | 97 | .family = PF_DECnet, |
98 | .entry_size = NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)), | 98 | .entry_size = NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)), |
99 | .key_len = sizeof(__le16), | 99 | .key_len = sizeof(__le16), |
100 | .protocol = cpu_to_be16(ETH_P_DNA_RT), | ||
100 | .hash = dn_neigh_hash, | 101 | .hash = dn_neigh_hash, |
101 | .constructor = dn_neigh_construct, | 102 | .constructor = dn_neigh_construct, |
102 | .id = "dn_neigh_cache", | 103 | .id = "dn_neigh_cache", |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 238f38d21641..8dbdf6c910b7 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -113,39 +113,6 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, | |||
113 | EXPORT_SYMBOL(eth_header); | 113 | EXPORT_SYMBOL(eth_header); |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * eth_rebuild_header- rebuild the Ethernet MAC header. | ||
117 | * @skb: socket buffer to update | ||
118 | * | ||
119 | * This is called after an ARP or IPV6 ndisc it's resolution on this | ||
120 | * sk_buff. We now let protocol (ARP) fill in the other fields. | ||
121 | * | ||
122 | * This routine CANNOT use cached dst->neigh! | ||
123 | * Really, it is used only when dst->neigh is wrong. | ||
124 | */ | ||
125 | int eth_rebuild_header(struct sk_buff *skb) | ||
126 | { | ||
127 | struct ethhdr *eth = (struct ethhdr *)skb->data; | ||
128 | struct net_device *dev = skb->dev; | ||
129 | |||
130 | switch (eth->h_proto) { | ||
131 | #ifdef CONFIG_INET | ||
132 | case htons(ETH_P_IP): | ||
133 | return arp_find(eth->h_dest, skb); | ||
134 | #endif | ||
135 | default: | ||
136 | netdev_dbg(dev, | ||
137 | "%s: unable to resolve type %X addresses.\n", | ||
138 | dev->name, ntohs(eth->h_proto)); | ||
139 | |||
140 | memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | EXPORT_SYMBOL(eth_rebuild_header); | ||
147 | |||
148 | /** | ||
149 | * eth_get_headlen - determine the the length of header for an ethernet frame | 116 | * eth_get_headlen - determine the the length of header for an ethernet frame |
150 | * @data: pointer to start of frame | 117 | * @data: pointer to start of frame |
151 | * @len: total length of frame | 118 | * @len: total length of frame |
@@ -369,7 +336,6 @@ EXPORT_SYMBOL(eth_validate_addr); | |||
369 | const struct header_ops eth_header_ops ____cacheline_aligned = { | 336 | const struct header_ops eth_header_ops ____cacheline_aligned = { |
370 | .create = eth_header, | 337 | .create = eth_header, |
371 | .parse = eth_header_parse, | 338 | .parse = eth_header_parse, |
372 | .rebuild = eth_rebuild_header, | ||
373 | .cache = eth_header_cache, | 339 | .cache = eth_header_cache, |
374 | .cache_update = eth_header_cache_update, | 340 | .cache_update = eth_header_cache_update, |
375 | }; | 341 | }; |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 205e1472aa78..6b8aad6a0d7d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -149,17 +149,10 @@ static const struct neigh_ops arp_direct_ops = { | |||
149 | .connected_output = neigh_direct_output, | 149 | .connected_output = neigh_direct_output, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | static const struct neigh_ops arp_broken_ops = { | ||
153 | .family = AF_INET, | ||
154 | .solicit = arp_solicit, | ||
155 | .error_report = arp_error_report, | ||
156 | .output = neigh_compat_output, | ||
157 | .connected_output = neigh_compat_output, | ||
158 | }; | ||
159 | |||
160 | struct neigh_table arp_tbl = { | 152 | struct neigh_table arp_tbl = { |
161 | .family = AF_INET, | 153 | .family = AF_INET, |
162 | .key_len = 4, | 154 | .key_len = 4, |
155 | .protocol = cpu_to_be16(ETH_P_IP), | ||
163 | .hash = arp_hash, | 156 | .hash = arp_hash, |
164 | .constructor = arp_constructor, | 157 | .constructor = arp_constructor, |
165 | .proxy_redo = parp_redo, | 158 | .proxy_redo = parp_redo, |
@@ -260,35 +253,6 @@ static int arp_constructor(struct neighbour *neigh) | |||
260 | in old paradigm. | 253 | in old paradigm. |
261 | */ | 254 | */ |
262 | 255 | ||
263 | #if 1 | ||
264 | /* So... these "amateur" devices are hopeless. | ||
265 | The only thing, that I can say now: | ||
266 | It is very sad that we need to keep ugly obsolete | ||
267 | code to make them happy. | ||
268 | |||
269 | They should be moved to more reasonable state, now | ||
270 | they use rebuild_header INSTEAD OF hard_start_xmit!!! | ||
271 | Besides that, they are sort of out of date | ||
272 | (a lot of redundant clones/copies, useless in 2.1), | ||
273 | I wonder why people believe that they work. | ||
274 | */ | ||
275 | switch (dev->type) { | ||
276 | default: | ||
277 | break; | ||
278 | case ARPHRD_ROSE: | ||
279 | #if IS_ENABLED(CONFIG_AX25) | ||
280 | case ARPHRD_AX25: | ||
281 | #if IS_ENABLED(CONFIG_NETROM) | ||
282 | case ARPHRD_NETROM: | ||
283 | #endif | ||
284 | neigh->ops = &arp_broken_ops; | ||
285 | neigh->output = neigh->ops->output; | ||
286 | return 0; | ||
287 | #else | ||
288 | break; | ||
289 | #endif | ||
290 | } | ||
291 | #endif | ||
292 | if (neigh->type == RTN_MULTICAST) { | 256 | if (neigh->type == RTN_MULTICAST) { |
293 | neigh->nud_state = NUD_NOARP; | 257 | neigh->nud_state = NUD_NOARP; |
294 | arp_mc_map(addr, neigh->ha, dev, 1); | 258 | arp_mc_map(addr, neigh->ha, dev, 1); |
@@ -433,71 +397,6 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) | |||
433 | return flag; | 397 | return flag; |
434 | } | 398 | } |
435 | 399 | ||
436 | /* OBSOLETE FUNCTIONS */ | ||
437 | |||
438 | /* | ||
439 | * Find an arp mapping in the cache. If not found, post a request. | ||
440 | * | ||
441 | * It is very UGLY routine: it DOES NOT use skb->dst->neighbour, | ||
442 | * even if it exists. It is supposed that skb->dev was mangled | ||
443 | * by a virtual device (eql, shaper). Nobody but broken devices | ||
444 | * is allowed to use this function, it is scheduled to be removed. --ANK | ||
445 | */ | ||
446 | |||
447 | static int arp_set_predefined(int addr_hint, unsigned char *haddr, | ||
448 | __be32 paddr, struct net_device *dev) | ||
449 | { | ||
450 | switch (addr_hint) { | ||
451 | case RTN_LOCAL: | ||
452 | pr_debug("arp called for own IP address\n"); | ||
453 | memcpy(haddr, dev->dev_addr, dev->addr_len); | ||
454 | return 1; | ||
455 | case RTN_MULTICAST: | ||
456 | arp_mc_map(paddr, haddr, dev, 1); | ||
457 | return 1; | ||
458 | case RTN_BROADCAST: | ||
459 | memcpy(haddr, dev->broadcast, dev->addr_len); | ||
460 | return 1; | ||
461 | } | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | |||
466 | int arp_find(unsigned char *haddr, struct sk_buff *skb) | ||
467 | { | ||
468 | struct net_device *dev = skb->dev; | ||
469 | __be32 paddr; | ||
470 | struct neighbour *n; | ||
471 | |||
472 | if (!skb_dst(skb)) { | ||
473 | pr_debug("arp_find is called with dst==NULL\n"); | ||
474 | kfree_skb(skb); | ||
475 | return 1; | ||
476 | } | ||
477 | |||
478 | paddr = rt_nexthop(skb_rtable(skb), ip_hdr(skb)->daddr); | ||
479 | if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, | ||
480 | paddr, dev)) | ||
481 | return 0; | ||
482 | |||
483 | n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); | ||
484 | |||
485 | if (n) { | ||
486 | n->used = jiffies; | ||
487 | if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) { | ||
488 | neigh_ha_snapshot(haddr, n, dev); | ||
489 | neigh_release(n); | ||
490 | return 0; | ||
491 | } | ||
492 | neigh_release(n); | ||
493 | } else | ||
494 | kfree_skb(skb); | ||
495 | return 1; | ||
496 | } | ||
497 | EXPORT_SYMBOL(arp_find); | ||
498 | |||
499 | /* END OF OBSOLETE FUNCTIONS */ | ||
500 | |||
501 | /* | 400 | /* |
502 | * Check if we can use proxy ARP for this path | 401 | * Check if we can use proxy ARP for this path |
503 | */ | 402 | */ |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 471ed24aabae..e363bbc2420d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -117,6 +117,7 @@ static const struct neigh_ops ndisc_direct_ops = { | |||
117 | struct neigh_table nd_tbl = { | 117 | struct neigh_table nd_tbl = { |
118 | .family = AF_INET6, | 118 | .family = AF_INET6, |
119 | .key_len = sizeof(struct in6_addr), | 119 | .key_len = sizeof(struct in6_addr), |
120 | .protocol = cpu_to_be16(ETH_P_IPV6), | ||
120 | .hash = ndisc_hash, | 121 | .hash = ndisc_hash, |
121 | .constructor = ndisc_constructor, | 122 | .constructor = ndisc_constructor, |
122 | .pconstructor = pndisc_constructor, | 123 | .pconstructor = pndisc_constructor, |
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 6ae063cebf7d..988f542481a8 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c | |||
@@ -65,36 +65,6 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev) | |||
65 | return 1; | 65 | return 1; |
66 | } | 66 | } |
67 | 67 | ||
68 | #ifdef CONFIG_INET | ||
69 | |||
70 | static int nr_rebuild_header(struct sk_buff *skb) | ||
71 | { | ||
72 | unsigned char *bp = skb->data; | ||
73 | |||
74 | if (arp_find(bp + 7, skb)) | ||
75 | return 1; | ||
76 | |||
77 | bp[6] &= ~AX25_CBIT; | ||
78 | bp[6] &= ~AX25_EBIT; | ||
79 | bp[6] |= AX25_SSSID_SPARE; | ||
80 | bp += AX25_ADDR_LEN; | ||
81 | |||
82 | bp[6] &= ~AX25_CBIT; | ||
83 | bp[6] |= AX25_EBIT; | ||
84 | bp[6] |= AX25_SSSID_SPARE; | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | #else | ||
90 | |||
91 | static int nr_rebuild_header(struct sk_buff *skb) | ||
92 | { | ||
93 | return 1; | ||
94 | } | ||
95 | |||
96 | #endif | ||
97 | |||
98 | static int nr_header(struct sk_buff *skb, struct net_device *dev, | 68 | static int nr_header(struct sk_buff *skb, struct net_device *dev, |
99 | unsigned short type, | 69 | unsigned short type, |
100 | const void *daddr, const void *saddr, unsigned int len) | 70 | const void *daddr, const void *saddr, unsigned int len) |
@@ -188,7 +158,6 @@ static netdev_tx_t nr_xmit(struct sk_buff *skb, struct net_device *dev) | |||
188 | 158 | ||
189 | static const struct header_ops nr_header_ops = { | 159 | static const struct header_ops nr_header_ops = { |
190 | .create = nr_header, | 160 | .create = nr_header, |
191 | .rebuild= nr_rebuild_header, | ||
192 | }; | 161 | }; |
193 | 162 | ||
194 | static const struct net_device_ops nr_netdev_ops = { | 163 | static const struct net_device_ops nr_netdev_ops = { |
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index 50005888be57..369ca81a8c5d 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c | |||
@@ -41,6 +41,9 @@ static int rose_header(struct sk_buff *skb, struct net_device *dev, | |||
41 | { | 41 | { |
42 | unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); | 42 | unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); |
43 | 43 | ||
44 | if (daddr) | ||
45 | memcpy(buff + 7, daddr, dev->addr_len); | ||
46 | |||
44 | *buff++ = ROSE_GFI | ROSE_Q_BIT; | 47 | *buff++ = ROSE_GFI | ROSE_Q_BIT; |
45 | *buff++ = 0x00; | 48 | *buff++ = 0x00; |
46 | *buff++ = ROSE_DATA; | 49 | *buff++ = ROSE_DATA; |
@@ -53,43 +56,6 @@ static int rose_header(struct sk_buff *skb, struct net_device *dev, | |||
53 | return -37; | 56 | return -37; |
54 | } | 57 | } |
55 | 58 | ||
56 | static int rose_rebuild_header(struct sk_buff *skb) | ||
57 | { | ||
58 | #ifdef CONFIG_INET | ||
59 | struct net_device *dev = skb->dev; | ||
60 | struct net_device_stats *stats = &dev->stats; | ||
61 | unsigned char *bp = (unsigned char *)skb->data; | ||
62 | struct sk_buff *skbn; | ||
63 | unsigned int len; | ||
64 | |||
65 | if (arp_find(bp + 7, skb)) { | ||
66 | return 1; | ||
67 | } | ||
68 | |||
69 | if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { | ||
70 | kfree_skb(skb); | ||
71 | return 1; | ||
72 | } | ||
73 | |||
74 | if (skb->sk != NULL) | ||
75 | skb_set_owner_w(skbn, skb->sk); | ||
76 | |||
77 | kfree_skb(skb); | ||
78 | |||
79 | len = skbn->len; | ||
80 | |||
81 | if (!rose_route_frame(skbn, NULL)) { | ||
82 | kfree_skb(skbn); | ||
83 | stats->tx_errors++; | ||
84 | return 1; | ||
85 | } | ||
86 | |||
87 | stats->tx_packets++; | ||
88 | stats->tx_bytes += len; | ||
89 | #endif | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static int rose_set_mac_address(struct net_device *dev, void *addr) | 59 | static int rose_set_mac_address(struct net_device *dev, void *addr) |
94 | { | 60 | { |
95 | struct sockaddr *sa = addr; | 61 | struct sockaddr *sa = addr; |
@@ -134,19 +100,26 @@ static int rose_close(struct net_device *dev) | |||
134 | static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev) | 100 | static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev) |
135 | { | 101 | { |
136 | struct net_device_stats *stats = &dev->stats; | 102 | struct net_device_stats *stats = &dev->stats; |
103 | unsigned int len = skb->len; | ||
137 | 104 | ||
138 | if (!netif_running(dev)) { | 105 | if (!netif_running(dev)) { |
139 | printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n"); | 106 | printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n"); |
140 | return NETDEV_TX_BUSY; | 107 | return NETDEV_TX_BUSY; |
141 | } | 108 | } |
142 | dev_kfree_skb(skb); | 109 | |
143 | stats->tx_errors++; | 110 | if (!rose_route_frame(skb, NULL)) { |
111 | dev_kfree_skb(skb); | ||
112 | stats->tx_errors++; | ||
113 | return NETDEV_TX_OK; | ||
114 | } | ||
115 | |||
116 | stats->tx_packets++; | ||
117 | stats->tx_bytes += len; | ||
144 | return NETDEV_TX_OK; | 118 | return NETDEV_TX_OK; |
145 | } | 119 | } |
146 | 120 | ||
147 | static const struct header_ops rose_header_ops = { | 121 | static const struct header_ops rose_header_ops = { |
148 | .create = rose_header, | 122 | .create = rose_header, |
149 | .rebuild = rose_rebuild_header, | ||
150 | }; | 123 | }; |
151 | 124 | ||
152 | static const struct net_device_ops rose_netdev_ops = { | 125 | static const struct net_device_ops rose_netdev_ops = { |