aboutsummaryrefslogtreecommitdiffstats
path: root/net/netrom
diff options
context:
space:
mode:
Diffstat (limited to 'net/netrom')
-rw-r--r--net/netrom/af_netrom.c28
-rw-r--r--net/netrom/nr_dev.c54
-rw-r--r--net/netrom/nr_in.c15
-rw-r--r--net/netrom/nr_subr.c7
-rw-r--r--net/netrom/sysctl_net_netrom.c12
5 files changed, 63 insertions, 53 deletions
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index f4578c759ffc..e5d82d711cae 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -56,6 +56,7 @@ int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
56int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE; 56int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE;
57int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING; 57int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING;
58int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS; 58int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS;
59int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET;
59 60
60static unsigned short circuit = 0x101; 61static unsigned short circuit = 0x101;
61 62
@@ -908,17 +909,17 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
908 if (frametype != NR_CONNREQ) { 909 if (frametype != NR_CONNREQ) {
909 /* 910 /*
910 * Here it would be nice to be able to send a reset but 911 * Here it would be nice to be able to send a reset but
911 * NET/ROM doesn't have one. The following hack would 912 * NET/ROM doesn't have one. We've tried to extend the protocol
912 * have been a way to extend the protocol but apparently 913 * by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that
913 * it kills BPQ boxes... :-( 914 * apparently kills BPQ boxes... :-(
915 * So now we try to follow the established behaviour of
916 * G8PZT's Xrouter which is sending packets with command type 7
917 * as an extension of the protocol.
914 */ 918 */
915#if 0 919 if (sysctl_netrom_reset_circuit &&
916 /* 920 (frametype != NR_RESET || flags != 0))
917 * Never reply to a CONNACK/CHOKE. 921 nr_transmit_reset(skb, 1);
918 */ 922
919 if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG)
920 nr_transmit_refusal(skb, 1);
921#endif
922 return 0; 923 return 0;
923 } 924 }
924 925
@@ -1187,9 +1188,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1187 } 1188 }
1188 1189
1189 case SIOCGSTAMP: 1190 case SIOCGSTAMP:
1190 ret = -EINVAL; 1191 ret = sock_get_timestamp(sk, argp);
1191 if (sk != NULL)
1192 ret = sock_get_timestamp(sk, argp);
1193 release_sock(sk); 1192 release_sock(sk);
1194 return ret; 1193 return ret;
1195 1194
@@ -1393,8 +1392,7 @@ static int __init nr_proto_init(void)
1393 struct net_device *dev; 1392 struct net_device *dev;
1394 1393
1395 sprintf(name, "nr%d", i); 1394 sprintf(name, "nr%d", i);
1396 dev = alloc_netdev(sizeof(struct net_device_stats), name, 1395 dev = alloc_netdev(sizeof(struct nr_private), name, nr_setup);
1397 nr_setup);
1398 if (!dev) { 1396 if (!dev) {
1399 printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); 1397 printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
1400 goto fail; 1398 goto fail;
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 263da4c26494..4e66eef9a034 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -47,7 +47,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
47 struct net_device_stats *stats = netdev_priv(dev); 47 struct net_device_stats *stats = netdev_priv(dev);
48 48
49 if (!netif_running(dev)) { 49 if (!netif_running(dev)) {
50 stats->rx_errors++; 50 stats->rx_dropped++;
51 return 0; 51 return 0;
52 } 52 }
53 53
@@ -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
@@ -185,15 +160,27 @@ static int nr_close(struct net_device *dev)
185 160
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 nr_private *nr = netdev_priv(dev);
189 dev_kfree_skb(skb); 164 struct net_device_stats *stats = &nr->stats;
190 stats->tx_errors++; 165 unsigned int len = skb->len;
166
167 if (!nr_route_frame(skb, NULL)) {
168 kfree_skb(skb);
169 stats->tx_errors++;
170 return 0;
171 }
172
173 stats->tx_packets++;
174 stats->tx_bytes += len;
175
191 return 0; 176 return 0;
192} 177}
193 178
194static struct net_device_stats *nr_get_stats(struct net_device *dev) 179static struct net_device_stats *nr_get_stats(struct net_device *dev)
195{ 180{
196 return netdev_priv(dev); 181 struct nr_private *nr = netdev_priv(dev);
182
183 return &nr->stats;
197} 184}
198 185
199void nr_setup(struct net_device *dev) 186void nr_setup(struct net_device *dev)
@@ -208,12 +195,11 @@ void nr_setup(struct net_device *dev)
208 dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; 195 dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
209 dev->addr_len = AX25_ADDR_LEN; 196 dev->addr_len = AX25_ADDR_LEN;
210 dev->type = ARPHRD_NETROM; 197 dev->type = ARPHRD_NETROM;
211 dev->tx_queue_len = 40;
212 dev->rebuild_header = nr_rebuild_header; 198 dev->rebuild_header = nr_rebuild_header;
213 dev->set_mac_address = nr_set_mac_address; 199 dev->set_mac_address = nr_set_mac_address;
214 200
215 /* New-style flags. */ 201 /* New-style flags. */
216 dev->flags = 0; 202 dev->flags = IFF_NOARP;
217 203
218 dev->get_stats = nr_get_stats; 204 dev->get_stats = nr_get_stats;
219} 205}
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 64b81a796907..004e8599b8fe 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -98,6 +98,11 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
98 nr_disconnect(sk, ECONNREFUSED); 98 nr_disconnect(sk, ECONNREFUSED);
99 break; 99 break;
100 100
101 case NR_RESET:
102 if (sysctl_netrom_reset_circuit);
103 nr_disconnect(sk, ECONNRESET);
104 break;
105
101 default: 106 default:
102 break; 107 break;
103 } 108 }
@@ -124,6 +129,11 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
124 nr_disconnect(sk, 0); 129 nr_disconnect(sk, 0);
125 break; 130 break;
126 131
132 case NR_RESET:
133 if (sysctl_netrom_reset_circuit);
134 nr_disconnect(sk, ECONNRESET);
135 break;
136
127 default: 137 default:
128 break; 138 break;
129 } 139 }
@@ -254,6 +264,11 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
254 } 264 }
255 break; 265 break;
256 266
267 case NR_RESET:
268 if (sysctl_netrom_reset_circuit);
269 nr_disconnect(sk, ECONNRESET);
270 break;
271
257 default: 272 default:
258 break; 273 break;
259 } 274 }
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
index 587bed2674bf..bcb9946b4f56 100644
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -210,10 +210,9 @@ void nr_write_internal(struct sock *sk, int frametype)
210} 210}
211 211
212/* 212/*
213 * This routine is called when a Connect Acknowledge with the Choke Flag 213 * This routine is called to send an error reply.
214 * set is needed to refuse a connection.
215 */ 214 */
216void nr_transmit_refusal(struct sk_buff *skb, int mine) 215void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
217{ 216{
218 struct sk_buff *skbn; 217 struct sk_buff *skbn;
219 unsigned char *dptr; 218 unsigned char *dptr;
@@ -254,7 +253,7 @@ void nr_transmit_refusal(struct sk_buff *skb, int mine)
254 *dptr++ = 0; 253 *dptr++ = 0;
255 } 254 }
256 255
257 *dptr++ = NR_CONNACK | NR_CHOKE_FLAG; 256 *dptr++ = cmdflags;
258 *dptr++ = 0; 257 *dptr++ = 0;
259 258
260 if (!nr_route_frame(skbn, NULL)) 259 if (!nr_route_frame(skbn, NULL))
diff --git a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c
index c9ed50382ea7..6bb8dda849dc 100644
--- a/net/netrom/sysctl_net_netrom.c
+++ b/net/netrom/sysctl_net_netrom.c
@@ -30,6 +30,7 @@ static int min_idle[] = {0 * HZ};
30static int max_idle[] = {65535 * HZ}; 30static int max_idle[] = {65535 * HZ};
31static int min_route[] = {0}, max_route[] = {1}; 31static int min_route[] = {0}, max_route[] = {1};
32static int min_fails[] = {1}, max_fails[] = {10}; 32static int min_fails[] = {1}, max_fails[] = {10};
33static int min_reset[] = {0}, max_reset[] = {1};
33 34
34static struct ctl_table_header *nr_table_header; 35static struct ctl_table_header *nr_table_header;
35 36
@@ -155,6 +156,17 @@ static ctl_table nr_table[] = {
155 .extra1 = &min_fails, 156 .extra1 = &min_fails,
156 .extra2 = &max_fails 157 .extra2 = &max_fails
157 }, 158 },
159 {
160 .ctl_name = NET_NETROM_RESET,
161 .procname = "reset",
162 .data = &sysctl_netrom_reset_circuit,
163 .maxlen = sizeof(int),
164 .mode = 0644,
165 .proc_handler = &proc_dointvec_minmax,
166 .strategy = &sysctl_intvec,
167 .extra1 = &min_reset,
168 .extra2 = &max_reset
169 },
158 { .ctl_name = 0 } 170 { .ctl_name = 0 }
159}; 171};
160 172