diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-03-03 10:41:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-03 14:44:41 -0500 |
commit | 1d5da757da860a6916adbf68b09e868062b4b3b8 (patch) | |
tree | deee80ad76638718a7babc524235ff13f35b2f98 | |
parent | bcc90e3fb132f009e647c9032eab4fedb6399339 (diff) |
ax25: Stop using magic neighbour cache operations.
Before the ax25 stack calls dev_queue_xmit it always calls
ax25_type_trans which sets skb->protocol to ETH_P_AX25.
Which means that by looking at the protocol type it is possible to
detect IP packets that have not been munged by the ax25 stack in
ndo_start_xmit and call a function to munge them.
Rename ax25_neigh_xmit to ax25_ip_xmit and tweak the return type and
value to be appropriate for an ndo_start_xmit function.
Update all of the ax25 devices to test the protocol type for ETH_P_IP
and return ax25_ip_xmit as the first thing they do. This preserves
the existing semantics of IP packet processing, but the timing will be
a little different as the IP packets now pass through the qdisc layer
before reaching the ax25 ip packet processing.
Remove the now unnecessary ax25 neighbour table operations.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/hamradio/6pack.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_epp.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/bpqether.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/dmascc.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/hdlcdrv.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/mkiss.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/scc.c | 5 | ||||
-rw-r--r-- | drivers/net/hamradio/yam.c | 5 | ||||
-rw-r--r-- | include/net/ax25.h | 5 | ||||
-rw-r--r-- | net/ax25/ax25_ip.c | 60 |
10 files changed, 31 insertions, 74 deletions
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 0b8393ca8c80..7c4a4151ef0f 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -247,6 +247,9 @@ static netdev_tx_t sp_xmit(struct sk_buff *skb, struct net_device *dev) | |||
247 | { | 247 | { |
248 | struct sixpack *sp = netdev_priv(dev); | 248 | struct sixpack *sp = netdev_priv(dev); |
249 | 249 | ||
250 | if (skb->protocol == htons(ETH_P_IP)) | ||
251 | return ax25_ip_xmit(skb); | ||
252 | |||
250 | spin_lock_bh(&sp->lock); | 253 | spin_lock_bh(&sp->lock); |
251 | /* We were not busy, so we are now... :-) */ | 254 | /* We were not busy, so we are now... :-) */ |
252 | netif_stop_queue(dev); | 255 | netif_stop_queue(dev); |
@@ -302,7 +305,6 @@ static const struct net_device_ops sp_netdev_ops = { | |||
302 | .ndo_stop = sp_close, | 305 | .ndo_stop = sp_close, |
303 | .ndo_start_xmit = sp_xmit, | 306 | .ndo_start_xmit = sp_xmit, |
304 | .ndo_set_mac_address = sp_set_mac_address, | 307 | .ndo_set_mac_address = sp_set_mac_address, |
305 | .ndo_neigh_construct = ax25_neigh_construct, | ||
306 | }; | 308 | }; |
307 | 309 | ||
308 | static void sp_setup(struct net_device *dev) | 310 | static void sp_setup(struct net_device *dev) |
@@ -316,7 +318,6 @@ static void sp_setup(struct net_device *dev) | |||
316 | 318 | ||
317 | dev->addr_len = AX25_ADDR_LEN; | 319 | dev->addr_len = AX25_ADDR_LEN; |
318 | dev->type = ARPHRD_AX25; | 320 | dev->type = ARPHRD_AX25; |
319 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
320 | dev->tx_queue_len = 10; | 321 | dev->tx_queue_len = 10; |
321 | 322 | ||
322 | /* Only activated in AX.25 mode */ | 323 | /* Only activated in AX.25 mode */ |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 3539ab392f7d..83c7cce0d172 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -772,6 +772,9 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
772 | { | 772 | { |
773 | struct baycom_state *bc = netdev_priv(dev); | 773 | struct baycom_state *bc = netdev_priv(dev); |
774 | 774 | ||
775 | if (skb->protocol == htons(ETH_P_IP)) | ||
776 | return ax25_ip_xmit(skb); | ||
777 | |||
775 | if (skb->data[0] != 0) { | 778 | if (skb->data[0] != 0) { |
776 | do_kiss_params(bc, skb->data, skb->len); | 779 | do_kiss_params(bc, skb->data, skb->len); |
777 | dev_kfree_skb(skb); | 780 | dev_kfree_skb(skb); |
@@ -1109,7 +1112,6 @@ static const struct net_device_ops baycom_netdev_ops = { | |||
1109 | .ndo_do_ioctl = baycom_ioctl, | 1112 | .ndo_do_ioctl = baycom_ioctl, |
1110 | .ndo_start_xmit = baycom_send_packet, | 1113 | .ndo_start_xmit = baycom_send_packet, |
1111 | .ndo_set_mac_address = baycom_set_mac_address, | 1114 | .ndo_set_mac_address = baycom_set_mac_address, |
1112 | .ndo_neigh_construct = ax25_neigh_construct, | ||
1113 | }; | 1115 | }; |
1114 | 1116 | ||
1115 | /* | 1117 | /* |
@@ -1147,7 +1149,6 @@ static void baycom_probe(struct net_device *dev) | |||
1147 | dev->header_ops = &ax25_header_ops; | 1149 | dev->header_ops = &ax25_header_ops; |
1148 | 1150 | ||
1149 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ | 1151 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ |
1150 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1151 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 1152 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
1152 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ | 1153 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ |
1153 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ | 1154 | 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 bce105b16ed0..63ff08a26da8 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -251,6 +251,9 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) | |||
251 | struct net_device *orig_dev; | 251 | struct net_device *orig_dev; |
252 | int size; | 252 | int size; |
253 | 253 | ||
254 | if (skb->protocol == htons(ETH_P_IP)) | ||
255 | return ax25_ip_xmit(skb); | ||
256 | |||
254 | /* | 257 | /* |
255 | * Just to be *really* sure not to send anything if the interface | 258 | * Just to be *really* sure not to send anything if the interface |
256 | * is down, the ethernet device may have gone. | 259 | * is down, the ethernet device may have gone. |
@@ -469,7 +472,6 @@ static const struct net_device_ops bpq_netdev_ops = { | |||
469 | .ndo_start_xmit = bpq_xmit, | 472 | .ndo_start_xmit = bpq_xmit, |
470 | .ndo_set_mac_address = bpq_set_mac_address, | 473 | .ndo_set_mac_address = bpq_set_mac_address, |
471 | .ndo_do_ioctl = bpq_ioctl, | 474 | .ndo_do_ioctl = bpq_ioctl, |
472 | .ndo_neigh_construct = ax25_neigh_construct, | ||
473 | }; | 475 | }; |
474 | 476 | ||
475 | static void bpq_setup(struct net_device *dev) | 477 | static void bpq_setup(struct net_device *dev) |
@@ -487,7 +489,6 @@ static void bpq_setup(struct net_device *dev) | |||
487 | #endif | 489 | #endif |
488 | 490 | ||
489 | dev->type = ARPHRD_AX25; | 491 | dev->type = ARPHRD_AX25; |
490 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
491 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 492 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
492 | dev->mtu = AX25_DEF_PACLEN; | 493 | dev->mtu = AX25_DEF_PACLEN; |
493 | dev->addr_len = AX25_ADDR_LEN; | 494 | dev->addr_len = AX25_ADDR_LEN; |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index abab7be77406..c3d377770616 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -433,7 +433,6 @@ 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); | ||
437 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 436 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
438 | dev->mtu = 1500; | 437 | dev->mtu = 1500; |
439 | dev->addr_len = AX25_ADDR_LEN; | 438 | dev->addr_len = AX25_ADDR_LEN; |
@@ -448,7 +447,6 @@ static const struct net_device_ops scc_netdev_ops = { | |||
448 | .ndo_start_xmit = scc_send_packet, | 447 | .ndo_start_xmit = scc_send_packet, |
449 | .ndo_do_ioctl = scc_ioctl, | 448 | .ndo_do_ioctl = scc_ioctl, |
450 | .ndo_set_mac_address = scc_set_mac_address, | 449 | .ndo_set_mac_address = scc_set_mac_address, |
451 | .ndo_neigh_construct = ax25_neigh_construct, | ||
452 | }; | 450 | }; |
453 | 451 | ||
454 | static int __init setup_adapter(int card_base, int type, int n) | 452 | static int __init setup_adapter(int card_base, int type, int n) |
@@ -922,6 +920,9 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
922 | unsigned long flags; | 920 | unsigned long flags; |
923 | int i; | 921 | int i; |
924 | 922 | ||
923 | if (skb->protocol == htons(ETH_P_IP)) | ||
924 | return ax25_ip_xmit(skb); | ||
925 | |||
925 | /* Temporarily stop the scheduler feeding us packets */ | 926 | /* Temporarily stop the scheduler feeding us packets */ |
926 | netif_stop_queue(dev); | 927 | netif_stop_queue(dev); |
927 | 928 | ||
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 435868a7b69c..49fe59b180a8 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c | |||
@@ -404,6 +404,9 @@ static netdev_tx_t hdlcdrv_send_packet(struct sk_buff *skb, | |||
404 | { | 404 | { |
405 | struct hdlcdrv_state *sm = netdev_priv(dev); | 405 | struct hdlcdrv_state *sm = netdev_priv(dev); |
406 | 406 | ||
407 | if (skb->protocol == htons(ETH_P_IP)) | ||
408 | return ax25_ip_xmit(skb); | ||
409 | |||
407 | if (skb->data[0] != 0) { | 410 | if (skb->data[0] != 0) { |
408 | do_kiss_params(sm, skb->data, skb->len); | 411 | do_kiss_params(sm, skb->data, skb->len); |
409 | dev_kfree_skb(skb); | 412 | dev_kfree_skb(skb); |
@@ -626,7 +629,6 @@ static const struct net_device_ops hdlcdrv_netdev = { | |||
626 | .ndo_start_xmit = hdlcdrv_send_packet, | 629 | .ndo_start_xmit = hdlcdrv_send_packet, |
627 | .ndo_do_ioctl = hdlcdrv_ioctl, | 630 | .ndo_do_ioctl = hdlcdrv_ioctl, |
628 | .ndo_set_mac_address = hdlcdrv_set_mac_address, | 631 | .ndo_set_mac_address = hdlcdrv_set_mac_address, |
629 | .ndo_neigh_construct = ax25_neigh_construct, | ||
630 | }; | 632 | }; |
631 | 633 | ||
632 | /* | 634 | /* |
@@ -677,7 +679,6 @@ static void hdlcdrv_setup(struct net_device *dev) | |||
677 | dev->header_ops = &ax25_header_ops; | 679 | dev->header_ops = &ax25_header_ops; |
678 | 680 | ||
679 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ | 681 | dev->type = ARPHRD_AX25; /* AF_AX25 device */ |
680 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
681 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 682 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
682 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ | 683 | dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ |
683 | dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ | 684 | 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 c12ec2c2b594..17058c490b79 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -529,6 +529,9 @@ static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev) | |||
529 | { | 529 | { |
530 | struct mkiss *ax = netdev_priv(dev); | 530 | struct mkiss *ax = netdev_priv(dev); |
531 | 531 | ||
532 | if (skb->protocol == htons(ETH_P_IP)) | ||
533 | return ax25_ip_xmit(skb); | ||
534 | |||
532 | if (!netif_running(dev)) { | 535 | if (!netif_running(dev)) { |
533 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); | 536 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); |
534 | return NETDEV_TX_BUSY; | 537 | return NETDEV_TX_BUSY; |
@@ -641,7 +644,6 @@ static const struct net_device_ops ax_netdev_ops = { | |||
641 | .ndo_stop = ax_close, | 644 | .ndo_stop = ax_close, |
642 | .ndo_start_xmit = ax_xmit, | 645 | .ndo_start_xmit = ax_xmit, |
643 | .ndo_set_mac_address = ax_set_mac_address, | 646 | .ndo_set_mac_address = ax_set_mac_address, |
644 | .ndo_neigh_construct = ax25_neigh_construct, | ||
645 | }; | 647 | }; |
646 | 648 | ||
647 | static void ax_setup(struct net_device *dev) | 649 | static void ax_setup(struct net_device *dev) |
@@ -651,7 +653,6 @@ static void ax_setup(struct net_device *dev) | |||
651 | dev->hard_header_len = 0; | 653 | dev->hard_header_len = 0; |
652 | dev->addr_len = 0; | 654 | dev->addr_len = 0; |
653 | dev->type = ARPHRD_AX25; | 655 | dev->type = ARPHRD_AX25; |
654 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
655 | dev->tx_queue_len = 10; | 656 | dev->tx_queue_len = 10; |
656 | dev->header_ops = &ax25_header_ops; | 657 | dev->header_ops = &ax25_header_ops; |
657 | dev->netdev_ops = &ax_netdev_ops; | 658 | dev->netdev_ops = &ax_netdev_ops; |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index b305f51eb420..ce88df33fe17 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1550,7 +1550,6 @@ 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, | ||
1554 | }; | 1553 | }; |
1555 | 1554 | ||
1556 | /* ----> Initialize device <----- */ | 1555 | /* ----> Initialize device <----- */ |
@@ -1568,7 +1567,6 @@ static void scc_net_setup(struct net_device *dev) | |||
1568 | dev->flags = 0; | 1567 | dev->flags = 0; |
1569 | 1568 | ||
1570 | dev->type = ARPHRD_AX25; | 1569 | dev->type = ARPHRD_AX25; |
1571 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1572 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; | 1570 | dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; |
1573 | dev->mtu = AX25_DEF_PACLEN; | 1571 | dev->mtu = AX25_DEF_PACLEN; |
1574 | dev->addr_len = AX25_ADDR_LEN; | 1572 | dev->addr_len = AX25_ADDR_LEN; |
@@ -1641,6 +1639,9 @@ static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev) | |||
1641 | unsigned long flags; | 1639 | unsigned long flags; |
1642 | char kisscmd; | 1640 | char kisscmd; |
1643 | 1641 | ||
1642 | if (skb->protocol == htons(ETH_P_IP)) | ||
1643 | return ax25_ip_xmit(skb); | ||
1644 | |||
1644 | if (skb->len > scc->stat.bufsize || skb->len < 2) { | 1645 | if (skb->len > scc->stat.bufsize || skb->len < 2) { |
1645 | scc->dev_stat.tx_dropped++; /* bogus frame */ | 1646 | scc->dev_stat.tx_dropped++; /* bogus frame */ |
1646 | dev_kfree_skb(skb); | 1647 | dev_kfree_skb(skb); |
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 89d9da7a0c51..1a4729c36aa4 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c | |||
@@ -597,6 +597,9 @@ static netdev_tx_t yam_send_packet(struct sk_buff *skb, | |||
597 | { | 597 | { |
598 | struct yam_port *yp = netdev_priv(dev); | 598 | struct yam_port *yp = netdev_priv(dev); |
599 | 599 | ||
600 | if (skb->protocol == htons(ETH_P_IP)) | ||
601 | return ax25_ip_xmit(skb); | ||
602 | |||
600 | skb_queue_tail(&yp->send_queue, skb); | 603 | skb_queue_tail(&yp->send_queue, skb); |
601 | dev->trans_start = jiffies; | 604 | dev->trans_start = jiffies; |
602 | return NETDEV_TX_OK; | 605 | return NETDEV_TX_OK; |
@@ -1100,7 +1103,6 @@ static const struct net_device_ops yam_netdev_ops = { | |||
1100 | .ndo_start_xmit = yam_send_packet, | 1103 | .ndo_start_xmit = yam_send_packet, |
1101 | .ndo_do_ioctl = yam_ioctl, | 1104 | .ndo_do_ioctl = yam_ioctl, |
1102 | .ndo_set_mac_address = yam_set_mac_address, | 1105 | .ndo_set_mac_address = yam_set_mac_address, |
1103 | .ndo_neigh_construct = ax25_neigh_construct, | ||
1104 | }; | 1106 | }; |
1105 | 1107 | ||
1106 | static void yam_setup(struct net_device *dev) | 1108 | static void yam_setup(struct net_device *dev) |
@@ -1129,7 +1131,6 @@ static void yam_setup(struct net_device *dev) | |||
1129 | dev->header_ops = &ax25_header_ops; | 1131 | dev->header_ops = &ax25_header_ops; |
1130 | 1132 | ||
1131 | dev->type = ARPHRD_AX25; | 1133 | dev->type = ARPHRD_AX25; |
1132 | dev->neigh_priv_len = sizeof(struct ax25_neigh_priv); | ||
1133 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 1134 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
1134 | dev->mtu = AX25_MTU; | 1135 | dev->mtu = AX25_MTU; |
1135 | dev->addr_len = AX25_ADDR_LEN; | 1136 | dev->addr_len = AX25_ADDR_LEN; |
diff --git a/include/net/ax25.h b/include/net/ax25.h index 45feeba7a325..16a923a3a43a 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -367,11 +367,8 @@ int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, | |||
367 | struct net_device *); | 367 | struct net_device *); |
368 | 368 | ||
369 | /* ax25_ip.c */ | 369 | /* ax25_ip.c */ |
370 | int ax25_neigh_construct(struct neighbour *neigh); | 370 | netdev_tx_t ax25_ip_xmit(struct sk_buff *skb); |
371 | 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 | }; | ||
375 | 372 | ||
376 | /* ax25_out.c */ | 373 | /* ax25_out.c */ |
377 | ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, | 374 | ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, |
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index e030c64ebfb7..8b35af4ef93e 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c | |||
@@ -100,7 +100,7 @@ static 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 | static int ax25_neigh_xmit(struct sk_buff *skb) | 103 | netdev_tx_t ax25_ip_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; |
@@ -210,56 +210,7 @@ put: | |||
210 | if (route) | 210 | if (route) |
211 | ax25_put_route(route); | 211 | ax25_put_route(route); |
212 | 212 | ||
213 | return 1; | 213 | return NETDEV_TX_OK; |
214 | } | ||
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 | } | 214 | } |
264 | 215 | ||
265 | #else /* INET */ | 216 | #else /* INET */ |
@@ -271,9 +222,10 @@ static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
271 | return -AX25_HEADER_LEN; | 222 | return -AX25_HEADER_LEN; |
272 | } | 223 | } |
273 | 224 | ||
274 | int ax25_neigh_construct(struct neighbour *neigh) | 225 | netdev_tx_t ax25_ip_xmit(sturct sk_buff *skb) |
275 | { | 226 | { |
276 | return 0; | 227 | kfree_skb(skb); |
228 | return NETDEV_TX_OK; | ||
277 | } | 229 | } |
278 | #endif | 230 | #endif |
279 | 231 | ||
@@ -282,5 +234,5 @@ const struct header_ops ax25_header_ops = { | |||
282 | }; | 234 | }; |
283 | 235 | ||
284 | EXPORT_SYMBOL(ax25_header_ops); | 236 | EXPORT_SYMBOL(ax25_header_ops); |
285 | EXPORT_SYMBOL(ax25_neigh_construct); | 237 | EXPORT_SYMBOL(ax25_ip_xmit); |
286 | 238 | ||