1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef _LINUX_SKBUFF_H
15#define _LINUX_SKBUFF_H
16
17#include <linux/config.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/time.h>
21#include <linux/cache.h>
22
23#include <asm/atomic.h>
24#include <asm/types.h>
25#include <linux/spinlock.h>
26#include <linux/mm.h>
27#include <linux/highmem.h>
28
29#define HAVE_ALLOC_SKB
30#define HAVE_ALIGNABLE_SKB
31#define SLAB_SKB
32
33#define CHECKSUM_NONE 0
34#define CHECKSUM_HW 1
35#define CHECKSUM_UNNECESSARY 2
36
37#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES-1)) & ~(SMP_CACHE_BYTES-1))
38#define SKB_MAX_ORDER(X,ORDER) (((PAGE_SIZE<<(ORDER)) - (X) - sizeof(struct skb_shared_info))&~(SMP_CACHE_BYTES-1))
39#define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X),0))
40#define SKB_MAX_ALLOC (SKB_MAX_ORDER(0,2))
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#ifdef __i386__
81#define NET_CALLER(arg) (*(((void**)&arg)-1))
82#else
83#define NET_CALLER(arg) __builtin_return_address(0)
84#endif
85
86#ifdef CONFIG_NETFILTER
87struct nf_conntrack {
88 atomic_t use;
89 void (*destroy)(struct nf_conntrack *);
90};
91
92struct nf_ct_info {
93 struct nf_conntrack *master;
94};
95#endif
96
97struct sk_buff_head {
98
99 struct sk_buff * next;
100 struct sk_buff * prev;
101
102 __u32 qlen;
103 spinlock_t lock;
104};
105
106struct sk_buff;
107
108#define MAX_SKB_FRAGS 6
109
110typedef struct skb_frag_struct skb_frag_t;
111
112struct skb_frag_struct
113{
114 struct page *page;
115 __u16 page_offset;
116 __u16 size;
117};
118
119
120
121
122struct skb_shared_info {
123 atomic_t dataref;
124 unsigned int nr_frags;
125 struct sk_buff *frag_list;
126 skb_frag_t frags[MAX_SKB_FRAGS];
127};
128
129struct sk_buff {
130
131 struct sk_buff * next;
132 struct sk_buff * prev;
133
134 struct sk_buff_head * list;
135 struct sock *sk;
136 struct timeval stamp;
137 struct net_device *dev;
138 struct net_device *real_dev;
139
140
141
142
143
144 union
145 {
146 struct tcphdr *th;
147 struct udphdr *uh;
148 struct icmphdr *icmph;
149 struct igmphdr *igmph;
150 struct iphdr *ipiph;
151 struct spxhdr *spxh;
152 unsigned char *raw;
153 } h;
154
155
156 union
157 {
158 struct iphdr *iph;
159 struct ipv6hdr *ipv6h;
160 struct arphdr *arph;
161 struct ipxhdr *ipxh;
162 unsigned char *raw;
163 } nh;
164
165
166 union
167 {
168 struct ethhdr *ethernet;
169 unsigned char *raw;
170 } mac;
171
172 struct dst_entry *dst;
173
174
175
176
177
178
179
180 char cb[48];
181
182 unsigned int len;
183 unsigned int data_len;
184 unsigned int csum;
185 unsigned char __unused,
186 cloned,
187 pkt_type,
188 ip_summed;
189 __u32 priority;
190 atomic_t users;
191 unsigned short protocol;
192 unsigned short security;
193 unsigned int truesize;
194
195 unsigned char *head;
196 unsigned char *data;
197 unsigned char *tail;
198 unsigned char *end;
199
200 void (*destructor)(struct sk_buff *);
201#ifdef CONFIG_NETFILTER
202
203 unsigned long nfmark;
204
205 __u32 nfcache;
206
207 struct nf_ct_info *nfct;
208#ifdef CONFIG_NETFILTER_DEBUG
209 unsigned int nf_debug;
210#endif
211#endif
212
213#if defined(CONFIG_HIPPI)
214 union{
215 __u32 ifield;
216 } private;
217#endif
218
219#ifdef CONFIG_NET_SCHED
220 __u32 tc_index;
221#endif
222};
223
224#ifdef __KERNEL__
225
226
227
228#include <linux/slab.h>
229
230#include <asm/system.h>
231
232extern void __kfree_skb(struct sk_buff *skb);
233extern struct sk_buff * alloc_skb(unsigned int size, int priority);
234extern void kfree_skbmem(struct sk_buff *skb);
235extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority);
236extern struct sk_buff * skb_copy(const struct sk_buff *skb, int priority);
237extern struct sk_buff * pskb_copy(struct sk_buff *skb, int gfp_mask);
238extern int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask);
239extern struct sk_buff * skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom);
240extern struct sk_buff * skb_copy_expand(const struct sk_buff *skb,
241 int newheadroom,
242 int newtailroom,
243 int priority);
244extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad);
245#define dev_kfree_skb(a) kfree_skb(a)
246extern void skb_over_panic(struct sk_buff *skb, int len, void *here);
247extern void skb_under_panic(struct sk_buff *skb, int len, void *here);
248
249
250#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))
251
252
253
254
255
256
257
258
259static inline int skb_queue_empty(struct sk_buff_head *list)
260{
261 return (list->next == (struct sk_buff *) list);
262}
263
264
265
266
267
268
269
270
271
272static inline struct sk_buff *skb_get(struct sk_buff *skb)
273{
274 atomic_inc(&skb->users);
275 return skb;
276}
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291static inline void kfree_skb(struct sk_buff *skb)
292{
293 if (likely(atomic_read(&skb->users) == 1))
294 smp_rmb();
295 else if (likely(!atomic_dec_and_test(&skb->users)))
296 return;
297 __kfree_skb(skb);
298}
299
300
301
302
303
304
305
306
307
308
309static inline int skb_cloned(struct sk_buff *skb)
310{
311 return skb->cloned && atomic_read(&skb_shinfo(skb)->dataref) != 1;
312}
313
314
315
316
317
318
319
320
321
322static inline int skb_shared(struct sk_buff *skb)
323{
324 return (atomic_read(&skb->users) != 1);
325}
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri)
342{
343 if (skb_shared(skb)) {
344 struct sk_buff *nskb;
345 nskb = skb_clone(skb, pri);
346 kfree_skb(skb);
347 return nskb;
348 }
349 return skb;
350}
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri)
375{
376 struct sk_buff *nskb;
377 if(!skb_cloned(skb))
378 return skb;
379 nskb=skb_copy(skb, pri);
380 kfree_skb(skb);
381 return nskb;
382}
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
399{
400 struct sk_buff *list = ((struct sk_buff *)list_)->next;
401 if (list == (struct sk_buff *)list_)
402 list = NULL;
403 return list;
404}
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
421{
422 struct sk_buff *list = ((struct sk_buff *)list_)->prev;
423 if (list == (struct sk_buff *)list_)
424 list = NULL;
425 return list;
426}
427
428
429
430
431
432
433
434
435static inline __u32 skb_queue_len(struct sk_buff_head *list_)
436{
437 return(list_->qlen);
438}
439
440static inline void skb_queue_head_init(struct sk_buff_head *list)
441{
442 spin_lock_init(&list->lock);
443 list->prev = (struct sk_buff *)list;
444 list->next = (struct sk_buff *)list;
445 list->qlen = 0;
446}
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466static inline void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
467{
468 struct sk_buff *prev, *next;
469
470 newsk->list = list;
471 list->qlen++;
472 prev = (struct sk_buff *)list;
473 next = prev->next;
474 newsk->next = next;
475 newsk->prev = prev;
476 next->prev = newsk;
477 prev->next = newsk;
478}
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493static inline void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
494{
495 unsigned long flags;
496
497 spin_lock_irqsave(&list->lock, flags);
498 __skb_queue_head(list, newsk);
499 spin_unlock_irqrestore(&list->lock, flags);
500}
501
502
503
504
505
506
507
508
509
510
511
512
513
514static inline void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
515{
516 struct sk_buff *prev, *next;
517
518 newsk->list = list;
519 list->qlen++;
520 next = (struct sk_buff *)list;
521 prev = next->prev;
522 newsk->next = next;
523 newsk->prev = prev;
524 next->prev = newsk;
525 prev->next = newsk;
526}
527
528
529
530
531
532
533
534
535
536
537
538
539
540static inline void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
541{
542 unsigned long flags;
543
544 spin_lock_irqsave(&list->lock, flags);
545 __skb_queue_tail(list, newsk);
546 spin_unlock_irqrestore(&list->lock, flags);
547}
548
549
550
551
552
553
554
555
556
557
558static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
559{
560 struct sk_buff *next, *prev, *result;
561
562 prev = (struct sk_buff *) list;
563 next = prev->next;
564 result = NULL;
565 if (next != prev) {
566 result = next;
567 next = next->next;
568 list->qlen--;
569 next->prev = prev;
570 prev->next = next;
571 result->next = NULL;
572 result->prev = NULL;
573 result->list = NULL;
574 }
575 return result;
576}
577
578
579
580
581
582
583
584
585
586
587static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list)
588{
589 unsigned long flags;
590 struct sk_buff *result;
591
592 spin_lock_irqsave(&list->lock, flags);
593 result = __skb_dequeue(list);
594 spin_unlock_irqrestore(&list->lock, flags);
595 return result;
596}
597
598
599
600
601
602static inline void __skb_insert(struct sk_buff *newsk,
603 struct sk_buff * prev, struct sk_buff *next,
604 struct sk_buff_head * list)
605{
606 newsk->next = next;
607 newsk->prev = prev;
608 next->prev = newsk;
609 prev->next = newsk;
610 newsk->list = list;
611 list->qlen++;
612}
613
614
615
616
617
618
619
620
621
622
623
624static inline void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
625{
626 unsigned long flags;
627
628 spin_lock_irqsave(&old->list->lock, flags);
629 __skb_insert(newsk, old->prev, old, old->list);
630 spin_unlock_irqrestore(&old->list->lock, flags);
631}
632
633
634
635
636
637static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
638{
639 __skb_insert(newsk, old, old->next, old->list);
640}
641
642
643
644
645
646
647
648
649
650
651
652
653static inline void skb_append(struct sk_buff *old, struct sk_buff *newsk)
654{
655 unsigned long flags;
656
657 spin_lock_irqsave(&old->list->lock, flags);
658 __skb_append(old, newsk);
659 spin_unlock_irqrestore(&old->list->lock, flags);
660}
661
662
663
664
665
666
667static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
668{
669 struct sk_buff * next, * prev;
670
671 list->qlen--;
672 next = skb->next;
673 prev = skb->prev;
674 skb->next = NULL;
675 skb->prev = NULL;
676 skb->list = NULL;
677 next->prev = prev;
678 prev->next = next;
679}
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694static inline void skb_unlink(struct sk_buff *skb)
695{
696 struct sk_buff_head *list = skb->list;
697
698 if(list) {
699 unsigned long flags;
700
701 spin_lock_irqsave(&list->lock, flags);
702 if(skb->list == list)
703 __skb_unlink(skb, skb->list);
704 spin_unlock_irqrestore(&list->lock, flags);
705 }
706}
707
708
709
710
711
712
713
714
715
716
717
718
719static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list)
720{
721 struct sk_buff *skb = skb_peek_tail(list);
722 if (skb)
723 __skb_unlink(skb, list);
724 return skb;
725}
726
727
728
729
730
731
732
733
734
735
736static inline struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
737{
738 unsigned long flags;
739 struct sk_buff *result;
740
741 spin_lock_irqsave(&list->lock, flags);
742 result = __skb_dequeue_tail(list);
743 spin_unlock_irqrestore(&list->lock, flags);
744 return result;
745}
746
747static inline int skb_is_nonlinear(const struct sk_buff *skb)
748{
749 return skb->data_len;
750}
751
752static inline unsigned int skb_headlen(const struct sk_buff *skb)
753{
754 return skb->len - skb->data_len;
755}
756
757#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) out_of_line_bug(); } while (0)
758#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) out_of_line_bug(); } while (0)
759#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) out_of_line_bug(); } while (0)
760
761
762
763
764
765static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len)
766{
767 unsigned char *tmp=skb->tail;
768 SKB_LINEAR_ASSERT(skb);
769 skb->tail+=len;
770 skb->len+=len;
771 return tmp;
772}
773
774
775
776
777
778
779
780
781
782
783
784static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
785{
786 unsigned char *tmp=skb->tail;
787 SKB_LINEAR_ASSERT(skb);
788 skb->tail+=len;
789 skb->len+=len;
790 if(skb->tail>skb->end) {
791 skb_over_panic(skb, len, current_text_addr());
792 }
793 return tmp;
794}
795
796static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len)
797{
798 skb->data-=len;
799 skb->len+=len;
800 return skb->data;
801}
802
803
804
805
806
807
808
809
810
811
812
813static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
814{
815 skb->data-=len;
816 skb->len+=len;
817 if(skb->data<skb->head) {
818 skb_under_panic(skb, len, current_text_addr());
819 }
820 return skb->data;
821}
822
823static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
824{
825 skb->len-=len;
826 if (skb->len < skb->data_len)
827 out_of_line_bug();
828 return skb->data+=len;
829}
830
831
832
833
834
835
836
837
838
839
840
841
842static inline unsigned char * skb_pull(struct sk_buff *skb, unsigned int len)
843{
844 if (len > skb->len)
845 return NULL;
846 return __skb_pull(skb,len);
847}
848
849extern unsigned char * __pskb_pull_tail(struct sk_buff *skb, int delta);
850
851static inline char *__pskb_pull(struct sk_buff *skb, unsigned int len)
852{
853 if (len > skb_headlen(skb) &&
854 __pskb_pull_tail(skb, len-skb_headlen(skb)) == NULL)
855 return NULL;
856 skb->len -= len;
857 return skb->data += len;
858}
859
860static inline unsigned char * pskb_pull(struct sk_buff *skb, unsigned int len)
861{
862 if (len > skb->len)
863 return NULL;
864 return __pskb_pull(skb,len);
865}
866
867static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
868{
869 if (len <= skb_headlen(skb))
870 return 1;
871 if (len > skb->len)
872 return 0;
873 return (__pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL);
874}
875
876
877
878
879
880
881
882
883static inline int skb_headroom(const struct sk_buff *skb)
884{
885 return skb->data-skb->head;
886}
887
888
889
890
891
892
893
894
895static inline int skb_tailroom(const struct sk_buff *skb)
896{
897 return skb_is_nonlinear(skb) ? 0 : skb->end-skb->tail;
898}
899
900
901
902
903
904
905
906
907
908
909static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
910{
911 skb->data+=len;
912 skb->tail+=len;
913}
914
915extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
916
917static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
918{
919 if (!skb->data_len) {
920 skb->len = len;
921 skb->tail = skb->data+len;
922 } else {
923 ___pskb_trim(skb, len, 0);
924 }
925}
926
927
928
929
930
931
932
933
934
935
936static inline void skb_trim(struct sk_buff *skb, unsigned int len)
937{
938 if (skb->len > len) {
939 __skb_trim(skb, len);
940 }
941}
942
943
944static inline int __pskb_trim(struct sk_buff *skb, unsigned int len)
945{
946 if (!skb->data_len) {
947 skb->len = len;
948 skb->tail = skb->data+len;
949 return 0;
950 } else {
951 return ___pskb_trim(skb, len, 1);
952 }
953}
954
955static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
956{
957 if (len < skb->len)
958 return __pskb_trim(skb, len);
959 return 0;
960}
961
962
963
964
965
966
967
968
969
970
971
972static inline void skb_orphan(struct sk_buff *skb)
973{
974 if (skb->destructor)
975 skb->destructor(skb);
976 skb->destructor = NULL;
977 skb->sk = NULL;
978}
979
980
981
982
983
984
985
986
987
988
989
990static inline void skb_queue_purge(struct sk_buff_head *list)
991{
992 struct sk_buff *skb;
993 while ((skb=skb_dequeue(list))!=NULL)
994 kfree_skb(skb);
995}
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007static inline void __skb_queue_purge(struct sk_buff_head *list)
1008{
1009 struct sk_buff *skb;
1010 while ((skb=__skb_dequeue(list))!=NULL)
1011 kfree_skb(skb);
1012}
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
1028 int gfp_mask)
1029{
1030 struct sk_buff *skb;
1031
1032 skb = alloc_skb(length+16, gfp_mask);
1033 if (skb)
1034 skb_reserve(skb,16);
1035 return skb;
1036}
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051static inline struct sk_buff *dev_alloc_skb(unsigned int length)
1052{
1053 return __dev_alloc_skb(length, GFP_ATOMIC);
1054}
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069static inline int
1070skb_cow(struct sk_buff *skb, unsigned int headroom)
1071{
1072 int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb);
1073
1074 if (delta < 0)
1075 delta = 0;
1076
1077 if (delta || skb_cloned(skb))
1078 return pskb_expand_head(skb, (delta+15)&~15, 0, GFP_ATOMIC);
1079 return 0;
1080}
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len)
1095{
1096 unsigned int size = skb->len;
1097 if(likely(size >= len))
1098 return skb;
1099 return skb_pad(skb, len-size);
1100}
1101
1102
1103
1104
1105
1106
1107
1108
1109int skb_linearize(struct sk_buff *skb, int gfp);
1110
1111static inline void *kmap_skb_frag(const skb_frag_t *frag)
1112{
1113#ifdef CONFIG_HIGHMEM
1114 if (in_irq())
1115 out_of_line_bug();
1116
1117 local_bh_disable();
1118#endif
1119 return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ);
1120}
1121
1122static inline void kunmap_skb_frag(void *vaddr)
1123{
1124 kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
1125#ifdef CONFIG_HIGHMEM
1126 local_bh_enable();
1127#endif
1128}
1129
1130#define skb_queue_walk(queue, skb) \
1131 for (skb = (queue)->next; \
1132 (skb != (struct sk_buff *)(queue)); \
1133 skb=skb->next)
1134
1135
1136extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err);
1137extern unsigned int datagram_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait);
1138extern int skb_copy_datagram(const struct sk_buff *from, int offset, char *to,int size);
1139extern int skb_copy_datagram_iovec(const struct sk_buff *from, int offset, struct iovec *to,int size);
1140extern int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int *csump);
1141extern int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb, int hlen, struct iovec *iov);
1142extern void skb_free_datagram(struct sock * sk, struct sk_buff *skb);
1143
1144extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, int len, unsigned int csum);
1145extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len);
1146extern unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int csum);
1147extern void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
1148
1149extern void skb_init(void);
1150extern void skb_add_mtu(int mtu);
1151
1152#ifdef CONFIG_NETFILTER
1153static inline void
1154nf_conntrack_put(struct nf_ct_info *nfct)
1155{
1156 if (nfct && atomic_dec_and_test(&nfct->master->use))
1157 nfct->master->destroy(nfct->master);
1158}
1159static inline void
1160nf_conntrack_get(struct nf_ct_info *nfct)
1161{
1162 if (nfct)
1163 atomic_inc(&nfct->master->use);
1164}
1165static inline void
1166nf_reset(struct sk_buff *skb)
1167{
1168 nf_conntrack_put(skb->nfct);
1169 skb->nfct = NULL;
1170#ifdef CONFIG_NETFILTER_DEBUG
1171 skb->nf_debug = 0;
1172#endif
1173}
1174#else
1175static inline void nf_reset(struct sk_buff *skb) {}
1176#endif
1177
1178#endif
1179#endif
1180