diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-03-03 09:41:47 -0600 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-03 14:44:41 -0500 |
commit | 1d5da757da860a6916adbf68b09e868062b4b3b8 (patch) | |
tree | deee80ad76638718a7babc524235ff13f35b2f98 /net/ax25 | |
parent | bcc90e3fb132f009e647c9032eab4fedb6399339 (diff) | |
download | linux-stable-1d5da757da860a6916adbf68b09e868062b4b3b8.tar.gz linux-stable-1d5da757da860a6916adbf68b09e868062b4b3b8.tar.bz2 linux-stable-1d5da757da860a6916adbf68b09e868062b4b3b8.zip |
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>
Diffstat (limited to 'net/ax25')
-rw-r--r-- | net/ax25/ax25_ip.c | 60 |
1 files changed, 6 insertions, 54 deletions
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, return -AX25_HEADER_LEN; /* Unfinished header */ } -static int ax25_neigh_xmit(struct sk_buff *skb) +netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) { struct sk_buff *ourskb; unsigned char *bp = skb->data; @@ -210,56 +210,7 @@ put: if (route) ax25_put_route(route); - return 1; -} - -static int ax25_neigh_output(struct neighbour *neigh, struct sk_buff *skb) -{ - /* Except for calling ax25_neigh_xmit instead of - * dev_queue_xmit this is neigh_resolve_output. - */ - int rc = 0; - - if (!neigh_event_send(neigh, skb)) { - int err; - struct net_device *dev = neigh->dev; - unsigned int seq; - - do { - __skb_pull(skb, skb_network_offset(skb)); - seq = read_seqbegin(&neigh->ha_lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - } while (read_seqretry(&neigh->ha_lock, seq)); - - if (err >= 0) { - ax25_neigh_xmit(skb); - } else - goto out_kfree_skb; - } -out: - return rc; - -out_kfree_skb: - rc = -EINVAL; - kfree_skb(skb); - goto out; -} - -int ax25_neigh_construct(struct neighbour *neigh) -{ - /* This trouble could be saved if ax25 would right a proper - * dev_queue_xmit function. - */ - struct ax25_neigh_priv *priv = neighbour_priv(neigh); - - if (neigh->tbl->family != AF_INET) - return -EINVAL; - - priv->ops = *neigh->ops; - priv->ops.output = ax25_neigh_output; - priv->ops.connected_output = ax25_neigh_output; - return 0; + return NETDEV_TX_OK; } #else /* INET */ @@ -271,9 +222,10 @@ static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, return -AX25_HEADER_LEN; } -int ax25_neigh_construct(struct neighbour *neigh) +netdev_tx_t ax25_ip_xmit(sturct sk_buff *skb) { - return 0; + kfree_skb(skb); + return NETDEV_TX_OK; } #endif @@ -282,5 +234,5 @@ const struct header_ops ax25_header_ops = { }; EXPORT_SYMBOL(ax25_header_ops); -EXPORT_SYMBOL(ax25_neigh_construct); +EXPORT_SYMBOL(ax25_ip_xmit); |