1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include <linux/errno.h>
41#include <linux/types.h>
42#include <linux/socket.h>
43#include <linux/in.h>
44#include <linux/kernel.h>
45#include <linux/sched.h>
46#include <linux/timer.h>
47#include <linux/string.h>
48#include <linux/sockios.h>
49#include <linux/net.h>
50#include <linux/netdevice.h>
51#include <linux/inet.h>
52#include <linux/route.h>
53#include <net/sock.h>
54#include <asm/segment.h>
55#include <asm/system.h>
56#include <linux/fcntl.h>
57#include <linux/mm.h>
58#include <linux/termios.h>
59#include <linux/interrupt.h>
60#include <linux/proc_fs.h>
61#include <linux/stat.h>
62#include <linux/init.h>
63#include <linux/poll.h>
64#include <linux/if_packet.h>
65#include <net/neighbour.h>
66#include <net/dst.h>
67#include <net/dn_nsp.h>
68#include <net/dn_dev.h>
69#include <net/dn_route.h>
70
71
72static int nsp_backoff[NSP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
73
74
75
76
77
78
79
80
81
82struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
83{
84 struct sk_buff *skb;
85 int hdr = 64;
86
87 if ((skb = alloc_skb(size + hdr, pri)) == NULL)
88 return NULL;
89
90 skb->protocol = __constant_htons(ETH_P_DNA_RT);
91 skb->pkt_type = PACKET_OUTGOING;
92
93 if (sk)
94 skb_set_owner_w(skb, sk);
95
96 skb_reserve(skb, hdr);
97
98 return skb;
99}
100
101
102
103
104
105
106struct sk_buff *dn_alloc_send_skb(struct sock *sk, int *size, int noblock, int *err)
107{
108 int space;
109 int len;
110 struct sk_buff *skb = NULL;
111
112 *err = 0;
113
114 while(skb == NULL) {
115 if (signal_pending(current)) {
116 *err = ERESTARTSYS;
117 break;
118 }
119
120 if (sk->shutdown & SEND_SHUTDOWN) {
121 *err = EINVAL;
122 break;
123 }
124
125 if (sk->err)
126 break;
127
128 len = *size + 11;
129 space = sk->sndbuf - atomic_read(&sk->wmem_alloc);
130
131 if (space < len) {
132 if ((sk->socket->type == SOCK_STREAM) && (space >= (16 + 11)))
133 len = space;
134 }
135
136 if (space < len) {
137 set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
138 if (noblock) {
139 *err = EWOULDBLOCK;
140 break;
141 }
142
143 clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
144 SOCK_SLEEP_PRE(sk)
145
146 if ((sk->sndbuf - atomic_read(&sk->wmem_alloc)) < len)
147 schedule();
148
149 SOCK_SLEEP_POST(sk)
150 continue;
151 }
152
153 if ((skb = dn_alloc_skb(sk, len, sk->allocation)) == NULL)
154 continue;
155
156 *size = len - 11;
157 }
158
159 return skb;
160}
161
162
163
164
165
166
167unsigned long dn_nsp_persist(struct sock *sk)
168{
169 struct dn_scp *scp = DN_SK(sk);
170
171 unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
172
173 t *= nsp_backoff[scp->nsp_rxtshift];
174
175 if (t < HZ) t = HZ;
176 if (t > (600*HZ)) t = (600*HZ);
177
178 if (scp->nsp_rxtshift < NSP_MAXRXTSHIFT)
179 scp->nsp_rxtshift++;
180
181
182
183 return t;
184}
185
186
187
188
189
190static void dn_nsp_rtt(struct sock *sk, long rtt)
191{
192 struct dn_scp *scp = DN_SK(sk);
193 long srtt = (long)scp->nsp_srtt;
194 long rttvar = (long)scp->nsp_rttvar;
195 long delta;
196
197
198
199
200
201
202 if (rtt < 0)
203 rtt = -rtt;
204
205
206
207 delta = ((rtt << 3) - srtt);
208 srtt += (delta >> 3);
209 if (srtt >= 1)
210 scp->nsp_srtt = (unsigned long)srtt;
211 else
212 scp->nsp_srtt = 1;
213
214
215
216
217 delta >>= 1;
218 rttvar += ((((delta>0)?(delta):(-delta)) - rttvar) >> 2);
219 if (rttvar >= 1)
220 scp->nsp_rttvar = (unsigned long)rttvar;
221 else
222 scp->nsp_rttvar = 1;
223
224
225}
226
227
228
229
230
231
232
233
234
235
236static inline unsigned dn_nsp_clone_and_send(struct sk_buff *skb, int gfp)
237{
238 struct dn_skb_cb *cb = DN_SKB_CB(skb);
239 struct sk_buff *skb2;
240 int ret = 0;
241
242 if ((skb2 = skb_clone(skb, gfp)) != NULL) {
243 ret = cb->xmit_count;
244 cb->xmit_count++;
245 cb->stamp = jiffies;
246 skb2->sk = skb->sk;
247 dn_nsp_send(skb2);
248 }
249
250 return ret;
251}
252
253
254
255
256
257
258
259
260
261
262
263void dn_nsp_output(struct sock *sk)
264{
265 struct dn_scp *scp = DN_SK(sk);
266 struct sk_buff *skb;
267 unsigned reduce_win = 0;
268
269
270
271
272 if ((skb = skb_peek(&scp->other_xmit_queue)) != NULL)
273 reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
274
275
276
277
278
279
280 if (reduce_win || (scp->flowrem_sw != DN_SEND))
281 goto recalc_window;
282
283 if ((skb = skb_peek(&scp->data_xmit_queue)) != NULL)
284 reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
285
286
287
288
289
290
291recalc_window:
292 if (reduce_win) {
293 scp->snd_window >>= 1;
294 if (scp->snd_window < NSP_MIN_WINDOW)
295 scp->snd_window = NSP_MIN_WINDOW;
296 }
297}
298
299int dn_nsp_xmit_timeout(struct sock *sk)
300{
301 struct dn_scp *scp = DN_SK(sk);
302
303 dn_nsp_output(sk);
304
305 if (skb_queue_len(&scp->data_xmit_queue) || skb_queue_len(&scp->other_xmit_queue))
306 scp->persist = dn_nsp_persist(sk);
307
308 return 0;
309}
310
311static inline unsigned char *dn_mk_common_header(struct dn_scp *scp, struct sk_buff *skb, unsigned char msgflag, int len)
312{
313 unsigned char *ptr = skb_push(skb, len);
314
315 if (len < 5)
316 BUG();
317
318 *ptr++ = msgflag;
319 *((unsigned short *)ptr) = scp->addrrem;
320 ptr += 2;
321 *((unsigned short *)ptr) = scp->addrloc;
322 ptr += 2;
323 return ptr;
324}
325
326static unsigned short *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, unsigned char msgflag, int hlen, int other)
327{
328 struct dn_scp *scp = DN_SK(sk);
329 unsigned short acknum = scp->numdat_rcv & 0x0FFF;
330 unsigned short ackcrs = scp->numoth_rcv & 0x0FFF;
331 unsigned short *ptr;
332
333 if (hlen < 9)
334 BUG();
335
336 scp->ackxmt_dat = acknum;
337 scp->ackxmt_oth = ackcrs;
338 acknum |= 0x8000;
339 ackcrs |= 0x8000;
340
341
342 if (other) {
343 unsigned short tmp = acknum;
344 acknum = ackcrs;
345 ackcrs = tmp;
346 }
347
348
349 ackcrs |= 0x2000;
350
351 ptr = (unsigned short *)dn_mk_common_header(scp, skb, msgflag, hlen);
352
353 *ptr++ = dn_htons(acknum);
354 *ptr++ = dn_htons(ackcrs);
355
356 return ptr;
357}
358
359void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oth)
360{
361 struct dn_scp *scp = DN_SK(sk);
362 struct dn_skb_cb *cb = DN_SKB_CB(skb);
363 unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
364
365
366
367
368
369 if ((jiffies - scp->stamp) > t)
370 scp->snd_window = NSP_MIN_WINDOW;
371
372
373
374 cb->xmit_count = 0;
375
376 if (oth)
377 skb_queue_tail(&scp->other_xmit_queue, skb);
378 else
379 skb_queue_tail(&scp->data_xmit_queue, skb);
380
381 if (scp->flowrem_sw != DN_SEND)
382 return;
383
384 dn_nsp_clone_and_send(skb, gfp);
385}
386
387
388int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum)
389{
390 struct dn_skb_cb *cb = DN_SKB_CB(skb);
391 struct dn_scp *scp = DN_SK(sk);
392 struct sk_buff *skb2, *list, *ack = NULL;
393 int wakeup = 0;
394 int try_retrans = 0;
395 unsigned long reftime = cb->stamp;
396 unsigned long pkttime;
397 unsigned short xmit_count;
398 unsigned short segnum;
399
400 skb2 = q->next;
401 list = (struct sk_buff *)q;
402 while(list != skb2) {
403 struct dn_skb_cb *cb2 = DN_SKB_CB(skb2);
404
405 if (before_or_equal(cb2->segnum, acknum))
406 ack = skb2;
407
408
409
410 skb2 = skb2->next;
411
412 if (ack == NULL)
413 continue;
414
415
416
417
418 try_retrans = 0;
419
420 wakeup = 1;
421
422 pkttime = cb2->stamp;
423 xmit_count = cb2->xmit_count;
424 segnum = cb2->segnum;
425
426 skb_unlink(ack);
427 kfree_skb(ack);
428 ack = NULL;
429
430
431
432
433
434 if (xmit_count == 0)
435 BUG();
436
437
438
439
440
441 if (xmit_count == 1) {
442 if (equal(segnum, acknum))
443 dn_nsp_rtt(sk, (long)(pkttime - reftime));
444
445 if (scp->snd_window < scp->max_window)
446 scp->snd_window++;
447 }
448
449
450
451
452
453
454
455 if (xmit_count > 1)
456 try_retrans = 1;
457 }
458
459 if (try_retrans)
460 dn_nsp_output(sk);
461
462 return wakeup;
463}
464
465void dn_nsp_send_data_ack(struct sock *sk)
466{
467 struct sk_buff *skb = NULL;
468
469 if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
470 return;
471
472 skb_reserve(skb, 9);
473 dn_mk_ack_header(sk, skb, 0x04, 9, 0);
474 dn_nsp_send(skb);
475}
476
477void dn_nsp_send_oth_ack(struct sock *sk)
478{
479 struct sk_buff *skb = NULL;
480
481 if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
482 return;
483
484 skb_reserve(skb, 9);
485 dn_mk_ack_header(sk, skb, 0x14, 9, 1);
486 dn_nsp_send(skb);
487}
488
489
490void dn_send_conn_ack (struct sock *sk)
491{
492 struct dn_scp *scp = DN_SK(sk);
493 struct sk_buff *skb = NULL;
494 struct nsp_conn_ack_msg *msg;
495
496 if ((skb = dn_alloc_skb(sk, 3, sk->allocation)) == NULL)
497 return;
498
499 msg = (struct nsp_conn_ack_msg *)skb_put(skb, 3);
500 msg->msgflg = 0x24;
501 msg->dstaddr = scp->addrrem;
502
503 dn_nsp_send(skb);
504}
505
506void dn_nsp_delayed_ack(struct sock *sk)
507{
508 struct dn_scp *scp = DN_SK(sk);
509
510 if (scp->ackxmt_oth != scp->numoth_rcv)
511 dn_nsp_send_oth_ack(sk);
512
513 if (scp->ackxmt_dat != scp->numdat_rcv)
514 dn_nsp_send_data_ack(sk);
515}
516
517static int dn_nsp_retrans_conn_conf(struct sock *sk)
518{
519 struct dn_scp *scp = DN_SK(sk);
520
521 if (scp->state == DN_CC)
522 dn_send_conn_conf(sk, GFP_ATOMIC);
523
524 return 0;
525}
526
527void dn_send_conn_conf(struct sock *sk, int gfp)
528{
529 struct dn_scp *scp = DN_SK(sk);
530 struct sk_buff *skb = NULL;
531 struct nsp_conn_init_msg *msg;
532 unsigned char len = scp->conndata_out.opt_optl;
533
534 if ((skb = dn_alloc_skb(sk, 50 + scp->conndata_out.opt_optl, gfp)) == NULL)
535 return;
536
537 msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg));
538 msg->msgflg = 0x28;
539 msg->dstaddr = scp->addrrem;
540 msg->srcaddr = scp->addrloc;
541 msg->services = scp->services_loc;
542 msg->info = scp->info_loc;
543 msg->segsize = dn_htons(scp->segsize_loc);
544
545 *skb_put(skb,1) = len;
546
547 if (len > 0)
548 memcpy(skb_put(skb, len), scp->conndata_out.opt_data, len);
549
550
551 dn_nsp_send(skb);
552
553 scp->persist = dn_nsp_persist(sk);
554 scp->persist_fxn = dn_nsp_retrans_conn_conf;
555}
556
557
558static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
559 unsigned short reason, int gfp, struct dst_entry *dst,
560 int ddl, unsigned char *dd, __u16 rem, __u16 loc)
561{
562 struct sk_buff *skb = NULL;
563 int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0);
564 unsigned char *msg;
565
566 if ((dst == NULL) || (rem == 0)) {
567 if (net_ratelimit())
568 printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", (unsigned)rem, dst);
569 return;
570 }
571
572 if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL)
573 return;
574
575 msg = skb_put(skb, size);
576 *msg++ = msgflg;
577 *(__u16 *)msg = rem;
578 msg += 2;
579 *(__u16 *)msg = loc;
580 msg += 2;
581 *(__u16 *)msg = dn_htons(reason);
582 msg += 2;
583 if (msgflg == NSP_DISCINIT)
584 *msg++ = ddl;
585
586 if (ddl) {
587 memcpy(msg, dd, ddl);
588 }
589
590
591
592
593
594
595 skb->dst = dst_clone(dst);
596 skb->dst->output(skb);
597}
598
599
600void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg,
601 unsigned short reason, int gfp)
602{
603 struct dn_scp *scp = DN_SK(sk);
604 int ddl = 0;
605
606 if (msgflg == NSP_DISCINIT)
607 ddl = scp->discdata_out.opt_optl;
608
609 if (reason == 0)
610 reason = scp->discdata_out.opt_status;
611
612 dn_nsp_do_disc(sk, msgflg, reason, gfp, sk->dst_cache, ddl,
613 scp->discdata_out.opt_data, scp->addrrem, scp->addrloc);
614}
615
616
617void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
618 unsigned short reason)
619{
620 struct dn_skb_cb *cb = DN_SKB_CB(skb);
621 int ddl = 0;
622 int gfp = GFP_ATOMIC;
623
624 dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl,
625 NULL, cb->src_port, cb->dst_port);
626}
627
628
629void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval)
630{
631 struct dn_scp *scp = DN_SK(sk);
632 struct sk_buff *skb;
633 unsigned short *segnum;
634 unsigned char *ptr;
635 int gfp = GFP_ATOMIC;
636
637 if ((skb = dn_alloc_skb(sk, 13, gfp)) == NULL)
638 return;
639
640 skb_reserve(skb, 13);
641 segnum = dn_mk_ack_header(sk, skb, 0x10, 13, 1);
642 *segnum = dn_htons(scp->numoth);
643 DN_SKB_CB(skb)->segnum = scp->numoth;
644 seq_add(&scp->numoth, 1);
645 ptr = (unsigned char *)(segnum + 1);
646 *ptr++ = lsflags;
647 *ptr = fcval;
648
649 dn_nsp_queue_xmit(sk, skb, gfp, 1);
650
651 scp->persist = dn_nsp_persist(sk);
652 scp->persist_fxn = dn_nsp_xmit_timeout;
653}
654
655static int dn_nsp_retrans_conninit(struct sock *sk)
656{
657 struct dn_scp *scp = DN_SK(sk);
658
659 if (scp->state == DN_CI)
660 dn_nsp_send_conninit(sk, NSP_RCI);
661
662 return 0;
663}
664
665void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
666{
667 struct dn_scp *scp = DN_SK(sk);
668 struct sk_buff *skb = NULL;
669 struct nsp_conn_init_msg *msg;
670 unsigned char aux;
671 unsigned char menuver;
672 struct dn_skb_cb *cb;
673 unsigned char type = 1;
674
675 if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL)
676 return;
677
678 cb = DN_SKB_CB(skb);
679 msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg));
680
681 msg->msgflg = msgflg;
682 msg->dstaddr = 0x0000;
683
684 msg->srcaddr = scp->addrloc;
685 msg->services = scp->services_loc;
686 msg->info = scp->info_loc;
687 msg->segsize = dn_htons(scp->segsize_loc);
688
689 if (scp->peer.sdn_objnum)
690 type = 0;
691
692 skb_put(skb, dn_sockaddr2username(&scp->peer, skb->tail, type));
693 skb_put(skb, dn_sockaddr2username(&scp->addr, skb->tail, 2));
694
695 menuver = DN_MENUVER_ACC | DN_MENUVER_USR;
696 if (scp->peer.sdn_flags & SDF_PROXY)
697 menuver |= DN_MENUVER_PRX;
698 if (scp->peer.sdn_flags & SDF_UICPROXY)
699 menuver |= DN_MENUVER_UIC;
700
701 *skb_put(skb, 1) = menuver;
702
703 aux = scp->accessdata.acc_userl;
704 *skb_put(skb, 1) = aux;
705 if (aux > 0)
706 memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);
707
708 aux = scp->accessdata.acc_passl;
709 *skb_put(skb, 1) = aux;
710 if (aux > 0)
711 memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);
712
713 aux = scp->accessdata.acc_accl;
714 *skb_put(skb, 1) = aux;
715 if (aux > 0)
716 memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);
717
718 aux = scp->conndata_out.opt_optl;
719 *skb_put(skb, 1) = aux;
720 if (aux > 0)
721 memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);
722
723 scp->persist = dn_nsp_persist(sk);
724 scp->persist_fxn = dn_nsp_retrans_conninit;
725
726 cb->rt_flags = DN_RT_F_RQR;
727
728 dn_nsp_send(skb);
729}
730
731