OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [net/] [ipv4/] [ip_output.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
3
 *              operating system.  INET is implemented using the  BSD Socket
4
 *              interface as the means of communication with the user level.
5
 *
6
 *              The Internet Protocol (IP) output module.
7
 *
8
 * Version:     @(#)ip.c        1.0.16b 9/1/93
9
 *
10
 * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
11
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12
 *              Donald Becker, <becker@super.org>
13
 *              Alan Cox, <Alan.Cox@linux.org>
14
 *              Richard Underwood
15
 *              Stefan Becker, <stefanb@yello.ping.de>
16
 *              Jorge Cwik, <jorge@laser.satlink.net>
17
 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
18
 *
19
 *      See ip_input.c for original log
20
 *
21
 *      Fixes:
22
 *              Alan Cox        :       Missing nonblock feature in ip_build_xmit.
23
 *              Mike Kilburn    :       htons() missing in ip_build_xmit.
24
 *              Bradford Johnson:       Fix faulty handling of some frames when
25
 *                                      no route is found.
26
 *              Alexander Demenshin:    Missing sk/skb free in ip_queue_xmit
27
 *                                      (in case if packet not accepted by
28
 *                                      output firewall rules)
29
 *              Elliot Poger    :       Added support for SO_BINDTODEVICE.
30
 *              Juan Jose Ciarlante:    sk/skb source address rewriting
31
 *      Elena Apolinario Fdez de Sousa,:ipmr_forward never received multicast
32
 *      Juan-Mariano de Goyeneche       traffic generated locally.
33
 */
34
 
35
#include <asm/segment.h>
36
#include <asm/system.h>
37
#include <linux/types.h>
38
#include <linux/kernel.h>
39
#include <linux/sched.h>
40
#include <linux/mm.h>
41
#include <linux/string.h>
42
#include <linux/errno.h>
43
#include <linux/config.h>
44
 
45
#include <linux/socket.h>
46
#include <linux/sockios.h>
47
#include <linux/in.h>
48
#include <linux/inet.h>
49
#include <linux/netdevice.h>
50
#include <linux/etherdevice.h>
51
#include <linux/proc_fs.h>
52
#include <linux/stat.h>
53
 
54
#include <net/snmp.h>
55
#include <net/ip.h>
56
#include <net/protocol.h>
57
#include <net/route.h>
58
#include <net/tcp.h>
59
#include <net/udp.h>
60
#include <linux/skbuff.h>
61
#include <net/sock.h>
62
#include <net/arp.h>
63
#include <net/icmp.h>
64
#include <net/raw.h>
65
#include <net/checksum.h>
66
#include <linux/igmp.h>
67
#include <linux/ip_fw.h>
68
#include <linux/firewall.h>
69
#include <linux/mroute.h>
70
#include <net/netlink.h>
71
 
72
/*
73
 *      Allows dynamic re-writing of packet's addresses.
74
 *      value & 3    do rewrite
75
 *      value & 2    be verbose
76
 *      value & 4    rewrite connected sockets too
77
 *      Currently implemented:
78
 *              tcp_output.c   if sk->state!=TCP_SYN_SENT
79
 *              ip_masq.c      if no packet has been received by tunnel
80
 */
81
int sysctl_ip_dynaddr = 0;
82
 
83
/*
84
 *      Very Promisc source address re-assignation.
85
 *      ONLY acceptable if socket is NOT connected yet.
86
 *      Caller already checked sysctl_ip_dynaddr & 3 and EITHER
87
 *      sysctl_ip_dynaddr & 4 OR consistent sk->state
88
 *       (TCP_SYN_SENT for tcp, udp-connect sockets are set TCP_ESTABLISHED)
89
 */
90
 
91
int ip_rewrite_addrs (struct sock *sk, struct sk_buff *skb, struct device *dev)
92
{
93
        u32 new_saddr = dev->pa_addr;
94
        struct iphdr *iph;
95
 
96
        /*
97
         *      Be carefull: new_saddr must be !0
98
         */
99
        if (!new_saddr) {
100
                printk(KERN_WARNING "ip_rewrite_addrs(): NULL device \"%s\" addr\n",
101
                       dev->name);
102
                return 0;
103
        }
104
 
105
        /*
106
         *      Ouch!, this should not happen.
107
         */
108
        if (!sk->saddr || !sk->rcv_saddr) {
109
                printk(KERN_WARNING "ip_rewrite_addrs(): not valid sock addrs: saddr=%08lX rcv_saddr=%08lX",
110
                       ntohl(sk->saddr), ntohl(sk->rcv_saddr));
111
                return 0;
112
        }
113
 
114
        /*
115
         *      Be verbose if sysctl value & 2
116
         */
117
        if (sysctl_ip_dynaddr & 2) {
118
                printk(KERN_INFO "ip_rewrite_addrs(): shifting saddr from %s",
119
                       in_ntoa(skb->saddr));
120
                printk(" to %s (state %d)\n", in_ntoa(new_saddr), sk->state);
121
        }
122
 
123
        iph = skb->ip_hdr;
124
 
125
        if (new_saddr != iph->saddr) {
126
                iph->saddr = new_saddr;
127
                skb->saddr = new_saddr;
128
                ip_send_check(iph);
129
        } else if (sysctl_ip_dynaddr & 2) {
130
                printk(KERN_WARNING "ip_rewrite_addrs(): skb already changed (???).\n");
131
                return 0;
132
        }
133
 
134
        /*
135
         *      Maybe whe are in a skb chain loop and socket address has
136
         *      yet been 'damaged'.
137
         */
138
        if (new_saddr != sk->saddr) {
139
                sk->saddr = new_saddr;
140
                sk->rcv_saddr = new_saddr;
141
                sk->prot->rehash(sk);
142
        } else if (sysctl_ip_dynaddr & 2)
143
                printk(KERN_NOTICE "ip_rewrite_addrs(): no change needed for sock\n");
144
        return 1;
145
}
146
 
147
/*
148
 *      Loop a packet back to the sender.
149
 */
150
 
151
static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
152
{
153
        struct device *dev=&loopback_dev;
154
        int len=ntohs(skb->ip_hdr->tot_len);
155
        struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len+15);
156
 
157
        if(newskb==NULL)
158
                return;
159
 
160
        newskb->link3=NULL;
161
        newskb->sk=NULL;
162
        newskb->dev=dev;
163
        newskb->saddr=skb->saddr;
164
        newskb->daddr=skb->daddr;
165
        newskb->raddr=skb->raddr;
166
        newskb->free=1;
167
        newskb->lock=0;
168
        newskb->users=0;
169
        newskb->pkt_type=skb->pkt_type;
170
 
171
        /*
172
         *      Put a MAC header on the packet
173
         */
174
        ip_send(NULL,newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr);
175
        /*
176
         *      Add the rest of the data space.
177
         */
178
        newskb->ip_hdr=(struct iphdr *)skb_put(newskb, len);
179
        memcpy(newskb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
180
 
181
        /*
182
         *      Copy the data
183
         */
184
        memcpy(newskb->ip_hdr,skb->ip_hdr,len);
185
 
186
        /* Recurse. The device check against IFF_LOOPBACK will stop infinite recursion */
187
 
188
        /*printk("Loopback output queued [%lX to %lX].\n", newskb->ip_hdr->saddr,newskb->ip_hdr->daddr);*/
189
        ip_queue_xmit(NULL, dev, newskb, 2);
190
}
191
 
192
 
193
 
194
/*
195
 *      Take an skb, and fill in the MAC header.
196
 */
197
 
198
int ip_send(struct rtable * rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
199
{
200
        int mac = 0;
201
 
202
        skb->dev = dev;
203
        skb->arp = 1;
204
        skb->protocol = htons(ETH_P_IP);
205
        skb_reserve(skb,(dev->hard_header_len+15)&~15); /* 16 byte aligned IP headers are always good */
206
        if (dev->hard_header)
207
        {
208
                /*
209
                 *      Build a hardware header. Source address is our mac, destination unknown
210
                 *      (rebuild header will sort this out)
211
                 */
212
                if (rt && dev == rt->rt_dev && rt->rt_hh)
213
                {
214
                        memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len);
215
                        if (rt->rt_hh->hh_uptodate)
216
                                return dev->hard_header_len;
217
#if RT_CACHE_DEBUG >= 2
218
                        printk("ip_send: hh miss %08x via %08x\n", daddr, rt->rt_gateway);
219
#endif
220
                        skb->arp = 0;
221
                        skb->raddr = daddr;
222
                        return dev->hard_header_len;
223
                }
224
                mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
225
                if (mac < 0)
226
                {
227
                        mac = -mac;
228
                        skb->arp = 0;
229
                        skb->raddr = daddr;     /* next routing address */
230
                }
231
        }
232
        return mac;
233
}
234
 
235
static int ip_send_room(struct rtable * rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
236
{
237
        int mac = 0;
238
 
239
        skb->dev = dev;
240
        skb->arp = 1;
241
        skb->protocol = htons(ETH_P_IP);
242
        skb_reserve(skb,MAX_HEADER);
243
        if (dev->hard_header)
244
        {
245
                if (rt && dev == rt->rt_dev && rt->rt_hh)
246
                {
247
                        memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len);
248
                        if (rt->rt_hh->hh_uptodate)
249
                                return dev->hard_header_len;
250
#if RT_CACHE_DEBUG >= 2
251
                        printk("ip_send_room: hh miss %08x via %08x\n", daddr, rt->rt_gateway);
252
#endif
253
                        skb->arp = 0;
254
                        skb->raddr = daddr;
255
                        return dev->hard_header_len;
256
                }
257
                mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
258
                if (mac < 0)
259
                {
260
                        mac = -mac;
261
                        skb->arp = 0;
262
                        skb->raddr = daddr;     /* next routing address */
263
                }
264
        }
265
        return mac;
266
}
267
 
268
int ip_id_count = 0;
269
 
270
/*
271
 * This routine builds the appropriate hardware/IP headers for
272
 * the routine.  It assumes that if *dev != NULL then the
273
 * protocol knows what it's doing, otherwise it uses the
274
 * routing/ARP tables to select a device struct.
275
 */
276
int ip_build_header(struct sk_buff *skb, __u32 saddr, __u32 daddr,
277
                struct device **dev, int type, struct options *opt,
278
                int len, int tos, int ttl, struct rtable ** rp)
279
{
280
        struct rtable *rt;
281
        __u32 raddr;
282
        int tmp;
283
        struct iphdr *iph;
284
        __u32 final_daddr = daddr;
285
 
286
 
287
        if (opt && opt->srr)
288
                daddr = opt->faddr;
289
 
290
        /*
291
         *      See if we need to look up the device.
292
         */
293
 
294
#ifdef CONFIG_IP_MULTICAST      
295
        if(MULTICAST(daddr) && *dev==NULL && skb->sk && *skb->sk->ip_mc_name)
296
                *dev=dev_get(skb->sk->ip_mc_name);
297
#endif
298
        if (rp)
299
        {
300
                rt = ip_check_route(rp, daddr, skb->localroute, *dev);
301
                /*
302
                 * If rp != NULL rt_put following below should not
303
                 * release route, so that...
304
                 */
305
                if (rt)
306
                        atomic_inc(&rt->rt_refcnt);
307
        }
308
        else
309
                rt = ip_rt_route(daddr, skb->localroute, *dev);
310
 
311
 
312
        if (*dev == NULL)
313
        {
314
                if (rt == NULL)
315
                {
316
                        ip_statistics.IpOutNoRoutes++;
317
                        return(-ENETUNREACH);
318
                }
319
 
320
                *dev = rt->rt_dev;
321
        }
322
 
323
        if ((LOOPBACK(saddr) && !LOOPBACK(daddr)) || !saddr)
324
                saddr = rt ? rt->rt_src : (*dev)->pa_addr;
325
 
326
        raddr = rt ? rt->rt_gateway : daddr;
327
 
328
        if (opt && opt->is_strictroute && rt && (rt->rt_flags & RTF_GATEWAY))
329
        {
330
                ip_rt_put(rt);
331
                ip_statistics.IpOutNoRoutes++;
332
                return -ENETUNREACH;
333
        }
334
 
335
        /*
336
         *      Now build the MAC header.
337
         */
338
 
339
        if (type==IPPROTO_TCP)
340
                tmp = ip_send_room(rt, skb, raddr, len, *dev, saddr);
341
        else
342
                tmp = ip_send(rt, skb, raddr, len, *dev, saddr);
343
 
344
        ip_rt_put(rt);
345
 
346
        /*
347
         *      Book keeping
348
         */
349
 
350
        skb->dev = *dev;
351
        skb->saddr = saddr;
352
 
353
        /*
354
         *      Now build the IP header.
355
         */
356
 
357
        /*
358
         *      If we are using IPPROTO_RAW, then we don't need an IP header, since
359
         *      one is being supplied to us by the user
360
         */
361
 
362
        if(type == IPPROTO_RAW)
363
                return (tmp);
364
 
365
        /*
366
         *      Build the IP addresses
367
         */
368
 
369
        if (opt)
370
                iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr) + opt->optlen);
371
        else
372
                iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr));
373
 
374
        iph->version  = 4;
375
        iph->ihl      = 5;
376
        iph->tos      = tos;
377
        iph->frag_off = 0;
378
        iph->ttl      = ttl;
379
        iph->daddr    = daddr;
380
        iph->saddr    = saddr;
381
        iph->protocol = type;
382
        skb->ip_hdr   = iph;
383
 
384
        if (!opt || !opt->optlen)
385
                return sizeof(struct iphdr) + tmp;
386
        iph->ihl += opt->optlen>>2;
387
        ip_options_build(skb, opt, final_daddr, (*dev)->pa_addr, 0);
388
        return iph->ihl*4 + tmp;
389
}
390
 
391
 
392
/*
393
 *      Generate a checksum for an outgoing IP datagram.
394
 */
395
 
396
void ip_send_check(struct iphdr *iph)
397
{
398
        iph->check = 0;
399
        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
400
}
401
 
402
 
403
/*
404
 *      If a sender wishes the packet to remain unfreed
405
 *      we add it to his send queue. This arguably belongs
406
 *      in the TCP level since nobody else uses it. BUT
407
 *      remember IPng might change all the rules.
408
 */
409
static inline void add_to_send_queue(struct sock * sk, struct sk_buff * skb)
410
{
411
        unsigned long flags;
412
 
413
        /* The socket now has more outstanding blocks */
414
        sk->packets_out++;
415
 
416
        /* Protect the list for a moment */
417
        save_flags(flags);
418
        cli();
419
 
420
        if (skb->link3 != NULL)
421
        {
422
                NETDEBUG(printk("ip.c: link3 != NULL\n"));
423
                skb->link3 = NULL;
424
        }
425
        if (sk->send_head == NULL)
426
        {
427
                sk->send_tail = skb;
428
                sk->send_head = skb;
429
                sk->send_next = skb;
430
        }
431
        else
432
        {
433
                sk->send_tail->link3 = skb;
434
                sk->send_tail = skb;
435
        }
436
        restore_flags(flags);
437
}
438
 
439
 
440
/*
441
 * Queues a packet to be sent, and starts the transmitter
442
 * if necessary.  if free = 1 then we free the block after
443
 * transmit, otherwise we don't. If free==2 we not only
444
 * free the block but also don't assign a new ip seq number.
445
 * This routine also needs to put in the total length,
446
 * and compute the checksum
447
 */
448
 
449
void ip_queue_xmit(struct sock *sk, struct device *dev,
450
              struct sk_buff *skb, int free)
451
{
452
        unsigned int tot_len;
453
        struct iphdr *iph;
454
 
455
        IS_SKB(skb);
456
 
457
        /*
458
         *      Do some book-keeping in the packet for later
459
         */
460
 
461
        skb->sk = sk;
462
        skb->dev = dev;
463
        skb->when = jiffies;
464
 
465
        /*
466
         *      Find the IP header and set the length. This is bad
467
         *      but once we get the skb data handling code in the
468
         *      hardware will push its header sensibly and we will
469
         *      set skb->ip_hdr to avoid this mess and the fixed
470
         *      header length problem
471
         */
472
 
473
        iph = skb->ip_hdr;
474
        tot_len = skb->len - (((unsigned char *)iph) - skb->data);
475
        iph->tot_len = htons(tot_len);
476
 
477
        switch (free) {
478
                /* No reassigning numbers to fragments... */
479
                default:
480
                        free = 1;
481
                        break;
482
                case 0:
483
                        add_to_send_queue(sk, skb);
484
                        /* fall through */
485
                case 1:
486
                        iph->id = htons(ip_id_count++);
487
        }
488
 
489
        skb->free = free;
490
 
491
        /* Sanity check */
492
        if (dev == NULL)
493
                goto no_device;
494
 
495
#ifdef CONFIG_FIREWALL
496
        if (call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT)
497
                goto out;
498
#endif  
499
 
500
        /*
501
         *      Do we need to fragment. Again this is inefficient.
502
         *      We need to somehow lock the original buffer and use
503
         *      bits of it.
504
         */
505
 
506
        if (tot_len > dev->mtu)
507
                goto fragment;
508
 
509
        /*
510
         *      Add an IP checksum
511
         */
512
 
513
        ip_send_check(iph);
514
 
515
        /*
516
         *      More debugging. You cannot queue a packet already on a list
517
         *      Spot this and moan loudly.
518
         */
519
        if (skb->next != NULL)
520
        {
521
                NETDEBUG(printk("ip_queue_xmit: next != NULL\n"));
522
                skb_unlink(skb);
523
        }
524
 
525
        /*
526
         *      If the indicated interface is up and running, send the packet.
527
         */
528
 
529
        ip_statistics.IpOutRequests++;
530
#ifdef CONFIG_IP_ACCT
531
        ip_fw_chk(iph,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
532
#endif  
533
 
534
#ifdef CONFIG_IP_MULTICAST      
535
 
536
        /*
537
         *      Multicasts are looped back for other local users
538
         */
539
 
540
        if (MULTICAST(iph->daddr) && !(dev->flags&IFF_LOOPBACK))
541
        {
542
                if(sk==NULL || sk->ip_mc_loop)
543
                {
544
                        if(iph->daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
545
                        {
546
                                ip_loopback(dev,skb);
547
                        }
548
                        else
549
                        {
550
                                struct ip_mc_list *imc=dev->ip_mc_list;
551
                                while(imc!=NULL)
552
                                {
553
                                        if(imc->multiaddr==iph->daddr)
554
                                        {
555
                                                ip_loopback(dev,skb);
556
                                                break;
557
                                        }
558
                                        imc=imc->next;
559
                                }
560
                        }
561
                }
562
                /* Multicasts with ttl 0 must not go beyond the host */
563
 
564
                if (iph->ttl==0)
565
                        goto out;
566
        }
567
#endif
568
        if ((dev->flags & IFF_BROADCAST) && !(dev->flags & IFF_LOOPBACK)
569
            && (iph->daddr==dev->pa_brdaddr || iph->daddr==0xFFFFFFFF))
570
                ip_loopback(dev,skb);
571
 
572
        if (dev->flags & IFF_UP)
573
        {
574
                /*
575
                 *      If we have an owner use its priority setting,
576
                 *      otherwise use NORMAL
577
                 */
578
                int priority = SOPRI_NORMAL;
579
                if (sk)
580
                        priority = sk->priority;
581
 
582
                dev_queue_xmit(skb, dev, priority);
583
                return;
584
        }
585
        if(sk)
586
                sk->err = ENETDOWN;
587
        ip_statistics.IpOutDiscards++;
588
out:
589
        if (free)
590
                kfree_skb(skb, FREE_WRITE);
591
        return;
592
 
593
no_device:
594
        NETDEBUG(printk("IP: ip_queue_xmit dev = NULL\n"));
595
        goto out;
596
 
597
fragment:
598
        ip_fragment(sk,skb,dev,0);
599
        goto out;
600
}
601
 
602
 
603
/*
604
 *      Build and send a packet, with as little as one copy
605
 *
606
 *      Doesn't care much about ip options... option length can be
607
 *      different for fragment at 0 and other fragments.
608
 *
609
 *      Note that the fragment at the highest offset is sent first,
610
 *      so the getfrag routine can fill in the TCP/UDP checksum header
611
 *      field in the last fragment it sends... actually it also helps
612
 *      the reassemblers, they can put most packets in at the head of
613
 *      the fragment queue, and they know the total size in advance. This
614
 *      last feature will measurable improve the Linux fragment handler.
615
 *
616
 *      The callback has five args, an arbitrary pointer (copy of frag),
617
 *      the source IP address (may depend on the routing table), the
618
 *      destination address (char *), the offset to copy from, and the
619
 *      length to be copied.
620
 *
621
 */
622
 
623
int ip_build_xmit(struct sock *sk,
624
                   void getfrag (const void *,
625
                                 __u32,
626
                                 char *,
627
                                 unsigned int,
628
                                 unsigned int),
629
                   const void *frag,
630
                   unsigned short int length,
631
                   __u32 daddr,
632
                   __u32 user_saddr,
633
                   struct options * opt,
634
                   int flags,
635
                   int type,
636
                   int noblock)
637
{
638
        struct rtable *rt;
639
        unsigned int fraglen, maxfraglen, fragheaderlen;
640
        int offset, mf;
641
        __u32 saddr;
642
        unsigned short id;
643
        struct iphdr *iph;
644
        __u32 raddr;
645
        struct device *dev = NULL;
646
        struct hh_cache * hh=NULL;
647
        int nfrags=0;
648
        __u32 true_daddr = daddr;
649
 
650
        if (opt && opt->srr && !sk->ip_hdrincl)
651
          daddr = opt->faddr;
652
 
653
        ip_statistics.IpOutRequests++;
654
 
655
#ifdef CONFIG_IP_MULTICAST      
656
        if(MULTICAST(daddr) && *sk->ip_mc_name)
657
        {
658
                dev=dev_get(sk->ip_mc_name);
659
                if(!dev)
660
                        return -ENODEV;
661
                rt=NULL;
662
                if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
663
                        saddr = sk->saddr;
664
                else
665
                        saddr = dev->pa_addr;
666
        }
667
        else
668
        {
669
#endif  
670
                rt = ip_check_route(&sk->ip_route_cache, daddr,
671
                                    sk->localroute || (flags&MSG_DONTROUTE) ||
672
                                    (opt && opt->is_strictroute), sk->bound_device);
673
                if (rt == NULL)
674
                {
675
                        ip_statistics.IpOutNoRoutes++;
676
                        return(-ENETUNREACH);
677
                }
678
                saddr = rt->rt_src;
679
 
680
                hh = rt->rt_hh;
681
 
682
                if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
683
                        saddr = sk->saddr;
684
 
685
                dev=rt->rt_dev;
686
#ifdef CONFIG_IP_MULTICAST
687
        }
688
        if (rt && !dev)
689
                dev = rt->rt_dev;
690
#endif          
691
        if (user_saddr)
692
                saddr = user_saddr;
693
 
694
        raddr = rt ? rt->rt_gateway : daddr;
695
        /*
696
         *      Now compute the buffer space we require
697
         */
698
 
699
        /*
700
         *      Try the simple case first. This leaves broadcast, multicast, fragmented frames, and by
701
         *      choice RAW frames within 20 bytes of maximum size(rare) to the long path
702
         */
703
 
704
        if (!sk->ip_hdrincl) {
705
                length += sizeof(struct iphdr);
706
                if(opt) length += opt->optlen;
707
        }
708
 
709
        if(length <= dev->mtu && !MULTICAST(daddr) && daddr!=0xFFFFFFFF && daddr!=dev->pa_brdaddr)
710
        {
711
                int error;
712
                struct sk_buff *skb=sock_alloc_send_skb(sk, length+15+dev->hard_header_len,0, noblock, &error);
713
                if(skb==NULL)
714
                {
715
                        ip_statistics.IpOutDiscards++;
716
                        return error;
717
                }
718
                skb->dev=dev;
719
                skb->protocol = htons(ETH_P_IP);
720
                skb->free=1;
721
                skb->when=jiffies;
722
                skb->sk=sk;
723
                skb->arp=0;
724
                skb->saddr=saddr;
725
                skb->raddr = raddr;
726
                skb_reserve(skb,(dev->hard_header_len+15)&~15);
727
                if (hh)
728
                {
729
                        skb->arp=1;
730
                        memcpy(skb_push(skb,dev->hard_header_len),hh->hh_data,dev->hard_header_len);
731
                        if (!hh->hh_uptodate)
732
                        {
733
                                skb->arp = 0;
734
#if RT_CACHE_DEBUG >= 2
735
                                printk("ip_build_xmit: hh miss %08x via %08x\n", rt->rt_dst, rt->rt_gateway);
736
#endif                          
737
                        }
738
                }
739
                else if(dev->hard_header)
740
                {
741
                        if(dev->hard_header(skb,dev,ETH_P_IP,NULL,NULL,0)>0)
742
                                skb->arp=1;
743
                }
744
                else
745
                        skb->arp=1;
746
                skb->ip_hdr=iph=(struct iphdr *)skb_put(skb,length);
747
                dev_lock_list();
748
                if(!sk->ip_hdrincl)
749
                {
750
                        iph->version=4;
751
                        iph->ihl=5;
752
                        iph->tos=sk->ip_tos;
753
                        iph->tot_len = htons(length);
754
                        iph->id=htons(ip_id_count++);
755
                        iph->frag_off = 0;
756
                        iph->ttl=sk->ip_ttl;
757
                        iph->protocol=type;
758
                        iph->saddr=saddr;
759
                        iph->daddr=daddr;
760
                        if (opt)
761
                        {
762
                                iph->ihl += opt->optlen>>2;
763
                                ip_options_build(skb, opt,
764
                                                 true_daddr, dev->pa_addr, 0);
765
                        }
766
                        iph->check=0;
767
                        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
768
                        getfrag(frag,saddr,((char *)iph)+iph->ihl*4,0, length-iph->ihl*4);
769
                }
770
                else
771
                        getfrag(frag,saddr,(void *)iph,0,length);
772
                dev_unlock_list();
773
#ifdef CONFIG_FIREWALL
774
                if(call_out_firewall(PF_INET, skb->dev, iph, NULL)< FW_ACCEPT)
775
                {
776
                        kfree_skb(skb, FREE_WRITE);
777
                        return -EPERM;
778
                }
779
#endif
780
#ifdef CONFIG_IP_ACCT
781
                ip_fw_chk(iph,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
782
#endif          
783
                if(dev->flags&IFF_UP)
784
                        dev_queue_xmit(skb,dev,sk->priority);
785
                else
786
                {
787
                        ip_statistics.IpOutDiscards++;
788
                        kfree_skb(skb, FREE_WRITE);
789
                }
790
                return 0;
791
        }
792
        if (!sk->ip_hdrincl)
793
                length -= sizeof(struct iphdr);
794
 
795
        if(opt)
796
        {
797
                length -= opt->optlen;
798
                fragheaderlen = dev->hard_header_len + sizeof(struct iphdr) + opt->optlen;
799
                maxfraglen = ((dev->mtu-sizeof(struct iphdr)-opt->optlen) & ~7) + fragheaderlen;
800
        }
801
        else
802
        {
803
                fragheaderlen = dev->hard_header_len;
804
                if(!sk->ip_hdrincl)
805
                        fragheaderlen += 20;
806
 
807
                /*
808
                 *      Fragheaderlen is the size of 'overhead' on each buffer. Now work
809
                 *      out the size of the frames to send.
810
                 */
811
 
812
                maxfraglen = ((dev->mtu-20) & ~7) + fragheaderlen;
813
        }
814
 
815
        /*
816
         *      Start at the end of the frame by handling the remainder.
817
         */
818
 
819
        offset = length - (length % (maxfraglen - fragheaderlen));
820
 
821
        /*
822
         *      Amount of memory to allocate for final fragment.
823
         */
824
 
825
        fraglen = length - offset + fragheaderlen;
826
 
827
        if(length-offset==0)
828
        {
829
                fraglen = maxfraglen;
830
                offset -= maxfraglen-fragheaderlen;
831
        }
832
 
833
 
834
        /*
835
         *      The last fragment will not have MF (more fragments) set.
836
         */
837
 
838
        mf = 0;
839
 
840
        /*
841
         *      Can't fragment raw packets
842
         */
843
 
844
        if (sk->ip_hdrincl && offset > 0)
845
                return(-EMSGSIZE);
846
 
847
        /*
848
         *      Lock the device lists.
849
         */
850
 
851
        dev_lock_list();
852
 
853
        /*
854
         *      Get an identifier
855
         */
856
 
857
        id = htons(ip_id_count++);
858
 
859
        /*
860
         *      Being outputting the bytes.
861
         */
862
 
863
        do
864
        {
865
                struct sk_buff * skb;
866
                int error;
867
                char *data;
868
 
869
                /*
870
                 *      Get the memory we require with some space left for alignment.
871
                 */
872
 
873
                skb = sock_alloc_send_skb(sk, fraglen+15, 0, noblock, &error);
874
                if (skb == NULL)
875
                {
876
                        ip_statistics.IpOutDiscards++;
877
                        if(nfrags>1)
878
                                ip_statistics.IpFragCreates++;
879
                        dev_unlock_list();
880
                        return(error);
881
                }
882
 
883
                /*
884
                 *      Fill in the control structures
885
                 */
886
 
887
                skb->dev = dev;
888
                skb->protocol = htons(ETH_P_IP);
889
                skb->when = jiffies;
890
                skb->free = 1; /* dubious, this one */
891
                skb->sk = sk;
892
                skb->arp = 0;
893
                skb->saddr = saddr;
894
                skb->daddr = daddr;
895
                skb->raddr = raddr;
896
                skb_reserve(skb,(dev->hard_header_len+15)&~15);
897
                data = skb_put(skb, fraglen-dev->hard_header_len);
898
 
899
                /*
900
                 *      Save us ARP and stuff. In the optimal case we do no route lookup (route cache ok)
901
                 *      no ARP lookup (arp cache ok) and output. The cache checks are still too slow but
902
                 *      this can be fixed later. For gateway routes we ought to have a rt->.. header cache
903
                 *      pointer to speed header cache builds for identical targets.
904
                 */
905
 
906
                if (hh)
907
                {
908
                        skb->arp=1;
909
                        memcpy(skb_push(skb,dev->hard_header_len),hh->hh_data,dev->hard_header_len);
910
                        if (!hh->hh_uptodate)
911
                        {
912
                                skb->arp = 0;
913
#if RT_CACHE_DEBUG >= 2
914
                                printk("ip_build_xmit: hh miss %08x via %08x\n", rt->rt_dst, rt->rt_gateway);
915
#endif                          
916
                        }
917
                }
918
                else if (dev->hard_header)
919
                {
920
                        if(dev->hard_header(skb, dev, ETH_P_IP,
921
                                                NULL, NULL, 0)>0)
922
                                skb->arp=1;
923
                }
924
                else
925
                        skb->arp = 1;
926
 
927
                /*
928
                 *      Find where to start putting bytes.
929
                 */
930
 
931
                skb->ip_hdr = iph = (struct iphdr *)data;
932
 
933
                /*
934
                 *      Only write IP header onto non-raw packets
935
                 */
936
 
937
                if(!sk->ip_hdrincl)
938
                {
939
 
940
                        iph->version = 4;
941
                        iph->ihl = 5; /* ugh */
942
                        if (opt) {
943
                                iph->ihl += opt->optlen>>2;
944
                                ip_options_build(skb, opt,
945
                                                 true_daddr, dev->pa_addr, offset);
946
                        }
947
                        iph->tos = sk->ip_tos;
948
                        iph->tot_len = htons(fraglen - fragheaderlen + iph->ihl*4);
949
                        iph->id = id;
950
                        iph->frag_off = htons(offset>>3);
951
                        iph->frag_off |= mf;
952
#ifdef CONFIG_IP_MULTICAST
953
                        if (MULTICAST(daddr))
954
                                iph->ttl = sk->ip_mc_ttl;
955
                        else
956
#endif
957
                                iph->ttl = sk->ip_ttl;
958
                        iph->protocol = type;
959
                        iph->check = 0;
960
                        iph->saddr = saddr;
961
                        iph->daddr = daddr;
962
                        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
963
                        data += iph->ihl*4;
964
 
965
                        /*
966
                         *      Any further fragments will have MF set.
967
                         */
968
 
969
                        mf = htons(IP_MF);
970
                }
971
 
972
                /*
973
                 *      User data callback
974
                 */
975
 
976
                getfrag(frag, saddr, data, offset, fraglen-fragheaderlen);
977
 
978
                /*
979
                 *      Account for the fragment.
980
                 */
981
 
982
#ifdef CONFIG_FIREWALL
983
                if(!offset && call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT)
984
                {
985
                        kfree_skb(skb, FREE_WRITE);
986
                        dev_unlock_list();
987
                        return -EPERM;
988
                }
989
#endif          
990
#ifdef CONFIG_IP_ACCT
991
                ip_fw_chk(iph, dev, NULL, ip_acct_chain, 0, IP_FW_MODE_ACCT_OUT);
992
#endif  
993
                offset -= (maxfraglen-fragheaderlen);
994
                fraglen = maxfraglen;
995
 
996
#ifdef CONFIG_IP_MULTICAST
997
 
998
                /*
999
                 *      Multicasts are looped back for other local users
1000
                 */
1001
 
1002
                if (MULTICAST(daddr) && !(dev->flags&IFF_LOOPBACK))
1003
                {
1004
#ifdef CONFIG_IP_MROUTE
1005
                /* We need this so that mrouted "hears" packets sent from the
1006
                   same host it is running on... (jmel) */
1007
                if (mroute_socket&&(iph->protocol!=IPPROTO_IGMP))
1008
                {
1009
                        if((skb->ip_hdr->daddr&htonl(0xFFFFFF00))!=htonl(0xE0000000))
1010
                        {
1011
                                struct sk_buff* skb2=skb_clone(skb, GFP_ATOMIC);
1012
                                if(skb2)
1013
                                {
1014
                                        skb2->free=1;
1015
                                        ipmr_forward(skb2, 0);
1016
                                }
1017
                        }
1018
                }
1019
#endif
1020
                        /*
1021
                         *      Loop back any frames. The check for IGMP_ALL_HOSTS is because
1022
                         *      you are always magically a member of this group.
1023
                         *
1024
                         *      Always loop back all host messages when running as a multicast router.
1025
                         */
1026
 
1027
                        if(sk==NULL || sk->ip_mc_loop)
1028
                        {
1029
                                if(daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
1030
                                        ip_loopback(dev,skb);
1031
                                else
1032
                                {
1033
                                        struct ip_mc_list *imc=dev->ip_mc_list;
1034
                                        while(imc!=NULL)
1035
                                        {
1036
                                                if(imc->multiaddr==daddr)
1037
                                                {
1038
                                                        ip_loopback(dev,skb);
1039
                                                        break;
1040
                                                }
1041
                                                imc=imc->next;
1042
                                        }
1043
                                }
1044
                        }
1045
 
1046
                        /*
1047
                         *      Multicasts with ttl 0 must not go beyond the host. Fixme: avoid the
1048
                         *      extra clone.
1049
                         */
1050
 
1051
                        if(skb->ip_hdr->ttl==0)
1052
                        {
1053
                                kfree_skb(skb, FREE_WRITE);
1054
                                nfrags++;
1055
                                continue;
1056
                        }
1057
                }
1058
#endif
1059
 
1060
                nfrags++;
1061
 
1062
                /*
1063
                 *      BSD loops broadcasts
1064
                 */
1065
 
1066
                if((dev->flags&IFF_BROADCAST) && (daddr==0xFFFFFFFF || daddr==dev->pa_brdaddr) && !(dev->flags&IFF_LOOPBACK))
1067
                        ip_loopback(dev,skb);
1068
 
1069
                /*
1070
                 *      Now queue the bytes into the device.
1071
                 */
1072
 
1073
                if (dev->flags & IFF_UP)
1074
                {
1075
                        dev_queue_xmit(skb, dev, sk->priority);
1076
                }
1077
                else
1078
                {
1079
                        /*
1080
                         *      Whoops...
1081
                         */
1082
 
1083
                        ip_statistics.IpOutDiscards++;
1084
                        if(nfrags>1)
1085
                                ip_statistics.IpFragCreates+=nfrags;
1086
                        kfree_skb(skb, FREE_WRITE);
1087
                        dev_unlock_list();
1088
                        /*
1089
                         *      BSD behaviour.
1090
                         */
1091
                        if(sk!=NULL)
1092
                                sk->err=ENETDOWN;
1093
                        return(0); /* lose rest of fragments */
1094
                }
1095
        }
1096
        while (offset >= 0);
1097
        if(nfrags>1)
1098
                ip_statistics.IpFragCreates+=nfrags;
1099
        dev_unlock_list();
1100
        return(0);
1101
}
1102
 
1103
 
1104
/*
1105
 *      IP protocol layer initialiser
1106
 */
1107
 
1108
static struct packet_type ip_packet_type =
1109
{
1110
        0,       /* MUTTER ntohs(ETH_P_IP),*/
1111
        NULL,   /* All devices */
1112
        ip_rcv,
1113
        NULL,
1114
        NULL,
1115
};
1116
 
1117
#ifdef CONFIG_RTNETLINK
1118
 
1119
/*
1120
 *      Netlink hooks for IP
1121
 */
1122
 
1123
void ip_netlink_msg(unsigned long msg, __u32 daddr, __u32 gw, __u32 mask, short flags, short metric, char *name)
1124
{
1125
        struct sk_buff *skb=alloc_skb(sizeof(struct netlink_rtinfo), GFP_ATOMIC);
1126
        struct netlink_rtinfo *nrt;
1127
        struct sockaddr_in *s;
1128
        if(skb==NULL)
1129
                return;
1130
        skb->free=1;
1131
        nrt=(struct netlink_rtinfo *)skb_put(skb, sizeof(struct netlink_rtinfo));
1132
        nrt->rtmsg_type=msg;
1133
        s=(struct sockaddr_in *)&nrt->rtmsg_dst;
1134
        s->sin_family=AF_INET;
1135
        s->sin_addr.s_addr=daddr;
1136
        s=(struct sockaddr_in *)&nrt->rtmsg_gateway;
1137
        s->sin_family=AF_INET;
1138
        s->sin_addr.s_addr=gw;
1139
        s=(struct sockaddr_in *)&nrt->rtmsg_genmask;
1140
        s->sin_family=AF_INET;
1141
        s->sin_addr.s_addr=mask;
1142
        nrt->rtmsg_flags=flags;
1143
        nrt->rtmsg_metric=metric;
1144
        strcpy(nrt->rtmsg_device,name);
1145
        if (netlink_post(NETLINK_ROUTE, skb))
1146
                kfree_skb(skb, FREE_WRITE);
1147
}
1148
 
1149
#endif
1150
 
1151
/*
1152
 *      Device notifier
1153
 */
1154
 
1155
static int ip_rt_event(struct notifier_block *this, unsigned long event, void *ptr)
1156
{
1157
        struct device *dev=ptr;
1158
        if(event==NETDEV_DOWN)
1159
        {
1160
                ip_netlink_msg(RTMSG_DELDEVICE, 0,0,0,0,0,dev->name);
1161
                ip_rt_flush(dev);
1162
        }
1163
/*
1164
 *      Join the initial group if multicast.
1165
 */
1166
        if(event==NETDEV_UP)
1167
        {
1168
#ifdef CONFIG_IP_MULTICAST      
1169
                ip_mc_allhost(dev);
1170
#endif          
1171
                ip_netlink_msg(RTMSG_NEWDEVICE, 0,0,0,0,0,dev->name);
1172
                ip_rt_update(NETDEV_UP, dev);
1173
        }
1174
        return NOTIFY_DONE;
1175
}
1176
 
1177
struct notifier_block ip_rt_notifier={
1178
        ip_rt_event,
1179
        NULL,
1180
 
1181
};
1182
 
1183
/*
1184
 *      IP registers the packet type and then calls the subprotocol initialisers
1185
 */
1186
 
1187
#ifdef CONFIG_IP_MULTICAST
1188
#ifdef CONFIG_PROC_FS
1189
static struct proc_dir_entry pde1 = {
1190
                PROC_NET_IGMP, 4, "igmp",
1191
                S_IFREG | S_IRUGO, 1, 0, 0,
1192
                0, &proc_net_inode_operations,
1193
                ip_mc_procinfo
1194
        };
1195
#endif  
1196
#endif
1197
 
1198
void ip_init(void)
1199
{
1200
        ip_packet_type.type=htons(ETH_P_IP);
1201
        dev_add_pack(&ip_packet_type);
1202
 
1203
        /* So we flush routes when a device is downed */
1204
        register_netdevice_notifier(&ip_rt_notifier);
1205
 
1206
/*      ip_raw_init();
1207
        ip_packet_init();
1208
        ip_tcp_init();
1209
        ip_udp_init();*/
1210
 
1211
#ifdef CONFIG_IP_MULTICAST
1212
#ifdef CONFIG_PROC_FS
1213
        proc_net_register(&pde1);
1214
#endif  
1215
#endif
1216
}
1217
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.