From 1d5da757da860a6916adbf68b09e868062b4b3b8 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 3 Mar 2015 09:41:47 -0600 Subject: 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" Signed-off-by: David S. Miller --- net/ax25/ax25_ip.c | 60 ++++++------------------------------------------------ 1 file changed, 6 insertions(+), 54 deletions(-) (limited to 'net/ax25') 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); -- cgit v1.2.3