Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* This is a module which is used for setting the NFMARK field of an skb. */
  2 
  3 /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License version 2 as
  7  * published by the Free Software Foundation.
  8  */
  9 
 10 #include <linux/module.h>
 11 #include <linux/skbuff.h>
 12 #include <linux/ip.h>
 13 #include <net/checksum.h>
 14 
 15 #include <linux/netfilter_ipv4/ip_tables.h>
 16 #include <linux/netfilter_ipv4/ipt_MARK.h>
 17 
 18 MODULE_LICENSE("GPL");
 19 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
 20 MODULE_DESCRIPTION("iptables MARK modification module");
 21 
 22 static unsigned int
 23 target_v0(struct sk_buff **pskb,
 24           const struct net_device *in,
 25           const struct net_device *out,
 26           unsigned int hooknum,
 27           const void *targinfo,
 28           void *userinfo)
 29 {
 30         const struct ipt_mark_target_info *markinfo = targinfo;
 31 
 32         if((*pskb)->nfmark != markinfo->mark) {
 33                 (*pskb)->nfmark = markinfo->mark;
 34                 (*pskb)->nfcache |= NFC_ALTERED;
 35         }
 36         return IPT_CONTINUE;
 37 }
 38 
 39 static unsigned int
 40 target_v1(struct sk_buff **pskb,
 41           const struct net_device *in,
 42           const struct net_device *out,
 43           unsigned int hooknum,
 44           const void *targinfo,
 45           void *userinfo)
 46 {
 47         const struct ipt_mark_target_info_v1 *markinfo = targinfo;
 48         int mark = 0;
 49 
 50         switch (markinfo->mode) {
 51         case IPT_MARK_SET:
 52                 mark = markinfo->mark;
 53                 break;
 54                 
 55         case IPT_MARK_AND:
 56                 mark = (*pskb)->nfmark & markinfo->mark;
 57                 break;
 58                 
 59         case IPT_MARK_OR:
 60                 mark = (*pskb)->nfmark | markinfo->mark;
 61                 break;
 62         }
 63 
 64         if((*pskb)->nfmark != mark) {
 65                 (*pskb)->nfmark = mark;
 66                 (*pskb)->nfcache |= NFC_ALTERED;
 67         }
 68         return IPT_CONTINUE;
 69 }
 70 
 71 
 72 static int
 73 checkentry_v0(const char *tablename,
 74               const struct ipt_entry *e,
 75               void *targinfo,
 76               unsigned int targinfosize,
 77               unsigned int hook_mask)
 78 {
 79         if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
 80                 printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
 81                        targinfosize,
 82                        IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
 83                 return 0;
 84         }
 85 
 86         if (strcmp(tablename, "mangle") != 0) {
 87                 printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
 88                 return 0;
 89         }
 90 
 91         return 1;
 92 }
 93 
 94 static int
 95 checkentry_v1(const char *tablename,
 96               const struct ipt_entry *e,
 97               void *targinfo,
 98               unsigned int targinfosize,
 99               unsigned int hook_mask)
100 {
101         struct ipt_mark_target_info_v1 *markinfo = targinfo;
102 
103         if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){
104                 printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
105                        targinfosize,
106                        IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)));
107                 return 0;
108         }
109 
110         if (strcmp(tablename, "mangle") != 0) {
111                 printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
112                 return 0;
113         }
114 
115         if (markinfo->mode != IPT_MARK_SET
116             && markinfo->mode != IPT_MARK_AND
117             && markinfo->mode != IPT_MARK_OR) {
118                 printk(KERN_WARNING "MARK: unknown mode %u\n",
119                        markinfo->mode);
120                 return 0;
121         }
122 
123         return 1;
124 }
125 
126 static struct ipt_target ipt_mark_reg_v0 = {
127         .name           = "MARK",
128         .target         = target_v0,
129         .checkentry     = checkentry_v0,
130         .me             = THIS_MODULE,
131         .revision       = 0,
132 };
133 
134 static struct ipt_target ipt_mark_reg_v1 = {
135         .name           = "MARK",
136         .target         = target_v1,
137         .checkentry     = checkentry_v1,
138         .me             = THIS_MODULE,
139         .revision       = 1,
140 };
141 
142 static int __init init(void)
143 {
144         int err;
145 
146         err = ipt_register_target(&ipt_mark_reg_v0);
147         if (!err) {
148                 err = ipt_register_target(&ipt_mark_reg_v1);
149                 if (err)
150                         ipt_unregister_target(&ipt_mark_reg_v0);
151         }
152         return err;
153 }
154 
155 static void __exit fini(void)
156 {
157         ipt_unregister_target(&ipt_mark_reg_v0);
158         ipt_unregister_target(&ipt_mark_reg_v1);
159 }
160 
161 module_init(init);
162 module_exit(fini);
163 
  This page was automatically generated by the LXR engine.