Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.25-rc1 251 lines 6.5 kB view raw
1/* 2 * xt_MARK - Netfilter module to modify the NFMARK field of an skb 3 * 4 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 5 * Copyright © CC Computer Consultants GmbH, 2007 - 2008 6 * Jan Engelhardt <jengelh@computergmbh.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13#include <linux/module.h> 14#include <linux/skbuff.h> 15#include <linux/ip.h> 16#include <net/checksum.h> 17 18#include <linux/netfilter/x_tables.h> 19#include <linux/netfilter/xt_MARK.h> 20 21MODULE_LICENSE("GPL"); 22MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 23MODULE_DESCRIPTION("Xtables: packet mark modification"); 24MODULE_ALIAS("ipt_MARK"); 25MODULE_ALIAS("ip6t_MARK"); 26 27static unsigned int 28mark_tg_v0(struct sk_buff *skb, const struct net_device *in, 29 const struct net_device *out, unsigned int hooknum, 30 const struct xt_target *target, const void *targinfo) 31{ 32 const struct xt_mark_target_info *markinfo = targinfo; 33 34 skb->mark = markinfo->mark; 35 return XT_CONTINUE; 36} 37 38static unsigned int 39mark_tg_v1(struct sk_buff *skb, const struct net_device *in, 40 const struct net_device *out, unsigned int hooknum, 41 const struct xt_target *target, const void *targinfo) 42{ 43 const struct xt_mark_target_info_v1 *markinfo = targinfo; 44 int mark = 0; 45 46 switch (markinfo->mode) { 47 case XT_MARK_SET: 48 mark = markinfo->mark; 49 break; 50 51 case XT_MARK_AND: 52 mark = skb->mark & markinfo->mark; 53 break; 54 55 case XT_MARK_OR: 56 mark = skb->mark | markinfo->mark; 57 break; 58 } 59 60 skb->mark = mark; 61 return XT_CONTINUE; 62} 63 64static unsigned int 65mark_tg(struct sk_buff *skb, const struct net_device *in, 66 const struct net_device *out, unsigned int hooknum, 67 const struct xt_target *target, const void *targinfo) 68{ 69 const struct xt_mark_tginfo2 *info = targinfo; 70 71 skb->mark = (skb->mark & ~info->mask) ^ info->mark; 72 return XT_CONTINUE; 73} 74 75static bool 76mark_tg_check_v0(const char *tablename, const void *entry, 77 const struct xt_target *target, void *targinfo, 78 unsigned int hook_mask) 79{ 80 const struct xt_mark_target_info *markinfo = targinfo; 81 82 if (markinfo->mark > 0xffffffff) { 83 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 84 return false; 85 } 86 return true; 87} 88 89static bool 90mark_tg_check_v1(const char *tablename, const void *entry, 91 const struct xt_target *target, void *targinfo, 92 unsigned int hook_mask) 93{ 94 const struct xt_mark_target_info_v1 *markinfo = targinfo; 95 96 if (markinfo->mode != XT_MARK_SET 97 && markinfo->mode != XT_MARK_AND 98 && markinfo->mode != XT_MARK_OR) { 99 printk(KERN_WARNING "MARK: unknown mode %u\n", 100 markinfo->mode); 101 return false; 102 } 103 if (markinfo->mark > 0xffffffff) { 104 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 105 return false; 106 } 107 return true; 108} 109 110#ifdef CONFIG_COMPAT 111struct compat_xt_mark_target_info { 112 compat_ulong_t mark; 113}; 114 115static void mark_tg_compat_from_user_v0(void *dst, void *src) 116{ 117 const struct compat_xt_mark_target_info *cm = src; 118 struct xt_mark_target_info m = { 119 .mark = cm->mark, 120 }; 121 memcpy(dst, &m, sizeof(m)); 122} 123 124static int mark_tg_compat_to_user_v0(void __user *dst, void *src) 125{ 126 const struct xt_mark_target_info *m = src; 127 struct compat_xt_mark_target_info cm = { 128 .mark = m->mark, 129 }; 130 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 131} 132 133struct compat_xt_mark_target_info_v1 { 134 compat_ulong_t mark; 135 u_int8_t mode; 136 u_int8_t __pad1; 137 u_int16_t __pad2; 138}; 139 140static void mark_tg_compat_from_user_v1(void *dst, void *src) 141{ 142 const struct compat_xt_mark_target_info_v1 *cm = src; 143 struct xt_mark_target_info_v1 m = { 144 .mark = cm->mark, 145 .mode = cm->mode, 146 }; 147 memcpy(dst, &m, sizeof(m)); 148} 149 150static int mark_tg_compat_to_user_v1(void __user *dst, void *src) 151{ 152 const struct xt_mark_target_info_v1 *m = src; 153 struct compat_xt_mark_target_info_v1 cm = { 154 .mark = m->mark, 155 .mode = m->mode, 156 }; 157 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 158} 159#endif /* CONFIG_COMPAT */ 160 161static struct xt_target mark_tg_reg[] __read_mostly = { 162 { 163 .name = "MARK", 164 .family = AF_INET, 165 .revision = 0, 166 .checkentry = mark_tg_check_v0, 167 .target = mark_tg_v0, 168 .targetsize = sizeof(struct xt_mark_target_info), 169#ifdef CONFIG_COMPAT 170 .compatsize = sizeof(struct compat_xt_mark_target_info), 171 .compat_from_user = mark_tg_compat_from_user_v0, 172 .compat_to_user = mark_tg_compat_to_user_v0, 173#endif 174 .table = "mangle", 175 .me = THIS_MODULE, 176 }, 177 { 178 .name = "MARK", 179 .family = AF_INET, 180 .revision = 1, 181 .checkentry = mark_tg_check_v1, 182 .target = mark_tg_v1, 183 .targetsize = sizeof(struct xt_mark_target_info_v1), 184#ifdef CONFIG_COMPAT 185 .compatsize = sizeof(struct compat_xt_mark_target_info_v1), 186 .compat_from_user = mark_tg_compat_from_user_v1, 187 .compat_to_user = mark_tg_compat_to_user_v1, 188#endif 189 .table = "mangle", 190 .me = THIS_MODULE, 191 }, 192 { 193 .name = "MARK", 194 .family = AF_INET6, 195 .revision = 0, 196 .checkentry = mark_tg_check_v0, 197 .target = mark_tg_v0, 198 .targetsize = sizeof(struct xt_mark_target_info), 199#ifdef CONFIG_COMPAT 200 .compatsize = sizeof(struct compat_xt_mark_target_info), 201 .compat_from_user = mark_tg_compat_from_user_v0, 202 .compat_to_user = mark_tg_compat_to_user_v0, 203#endif 204 .table = "mangle", 205 .me = THIS_MODULE, 206 }, 207 { 208 .name = "MARK", 209 .family = AF_INET6, 210 .revision = 1, 211 .checkentry = mark_tg_check_v1, 212 .target = mark_tg_v1, 213 .targetsize = sizeof(struct xt_mark_target_info_v1), 214#ifdef CONFIG_COMPAT 215 .compatsize = sizeof(struct compat_xt_mark_target_info_v1), 216 .compat_from_user = mark_tg_compat_from_user_v1, 217 .compat_to_user = mark_tg_compat_to_user_v1, 218#endif 219 .table = "mangle", 220 .me = THIS_MODULE, 221 }, 222 { 223 .name = "MARK", 224 .revision = 2, 225 .family = AF_INET, 226 .target = mark_tg, 227 .targetsize = sizeof(struct xt_mark_tginfo2), 228 .me = THIS_MODULE, 229 }, 230 { 231 .name = "MARK", 232 .revision = 2, 233 .family = AF_INET6, 234 .target = mark_tg, 235 .targetsize = sizeof(struct xt_mark_tginfo2), 236 .me = THIS_MODULE, 237 }, 238}; 239 240static int __init mark_tg_init(void) 241{ 242 return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 243} 244 245static void __exit mark_tg_exit(void) 246{ 247 xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 248} 249 250module_init(mark_tg_init); 251module_exit(mark_tg_exit);