aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-09-12 17:21:48 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-12 17:21:48 -0400
commit3f2aadd041a7a3e732d182c3770b3fa95a2300b2 (patch)
treebe2917b8e811c91d95a2413bb31ee44e99dadb88 /net
parent6f74998e5c3b4610e6eba06babf16547369c512a (diff)
[NETROM]: Fix rebuild header mess
For reason that probably nobody recalls NET/ROM does it's actual packet transmission in nr_rebuild_header and even treats invocation of it's hard_start_xmit method nr_xmit as a bug. Fix that by splitting the job done by nr_rebuild_header into two halves. Along with that we now also can get rid of the silly clone of the skb on transmit. Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netrom/nr_dev.c44
1 files changed, 15 insertions, 29 deletions
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 263da4c26494..431a25384421 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -71,15 +71,10 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
71 71
72static int nr_rebuild_header(struct sk_buff *skb) 72static int nr_rebuild_header(struct sk_buff *skb)
73{ 73{
74 struct net_device *dev = skb->dev;
75 struct net_device_stats *stats = netdev_priv(dev);
76 struct sk_buff *skbn;
77 unsigned char *bp = skb->data; 74 unsigned char *bp = skb->data;
78 int len;
79 75
80 if (arp_find(bp + 7, skb)) { 76 if (arp_find(bp + 7, skb))
81 return 1; 77 return 1;
82 }
83 78
84 bp[6] &= ~AX25_CBIT; 79 bp[6] &= ~AX25_CBIT;
85 bp[6] &= ~AX25_EBIT; 80 bp[6] &= ~AX25_EBIT;
@@ -90,27 +85,7 @@ static int nr_rebuild_header(struct sk_buff *skb)
90 bp[6] |= AX25_EBIT; 85 bp[6] |= AX25_EBIT;
91 bp[6] |= AX25_SSSID_SPARE; 86 bp[6] |= AX25_SSSID_SPARE;
92 87
93 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { 88 return 0;
94 kfree_skb(skb);
95 return 1;
96 }
97
98 if (skb->sk != NULL)
99 skb_set_owner_w(skbn, skb->sk);
100
101 kfree_skb(skb);
102
103 len = skbn->len;
104
105 if (!nr_route_frame(skbn, NULL)) {
106 kfree_skb(skbn);
107 stats->tx_errors++;
108 }
109
110 stats->tx_packets++;
111 stats->tx_bytes += len;
112
113 return 1;
114} 89}
115 90
116#else 91#else
@@ -186,8 +161,19 @@ static int nr_close(struct net_device *dev)
186static int nr_xmit(struct sk_buff *skb, struct net_device *dev) 161static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
187{ 162{
188 struct net_device_stats *stats = netdev_priv(dev); 163 struct net_device_stats *stats = netdev_priv(dev);
189 dev_kfree_skb(skb); 164 unsigned int len;
190 stats->tx_errors++; 165
166 len = skb->len;
167
168 if (!nr_route_frame(skb, NULL)) {
169 kfree_skb(skb);
170 stats->tx_errors++;
171 return 0;
172 }
173
174 stats->tx_packets++;
175 stats->tx_bytes += len;
176
191 return 0; 177 return 0;
192} 178}
193 179