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.30-rc5 201 lines 4.9 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 xt_target_param *par) 29{ 30 const struct xt_mark_target_info *markinfo = par->targinfo; 31 32 skb->mark = markinfo->mark; 33 return XT_CONTINUE; 34} 35 36static unsigned int 37mark_tg_v1(struct sk_buff *skb, const struct xt_target_param *par) 38{ 39 const struct xt_mark_target_info_v1 *markinfo = par->targinfo; 40 int mark = 0; 41 42 switch (markinfo->mode) { 43 case XT_MARK_SET: 44 mark = markinfo->mark; 45 break; 46 47 case XT_MARK_AND: 48 mark = skb->mark & markinfo->mark; 49 break; 50 51 case XT_MARK_OR: 52 mark = skb->mark | markinfo->mark; 53 break; 54 } 55 56 skb->mark = mark; 57 return XT_CONTINUE; 58} 59 60static unsigned int 61mark_tg(struct sk_buff *skb, const struct xt_target_param *par) 62{ 63 const struct xt_mark_tginfo2 *info = par->targinfo; 64 65 skb->mark = (skb->mark & ~info->mask) ^ info->mark; 66 return XT_CONTINUE; 67} 68 69static bool mark_tg_check_v0(const struct xt_tgchk_param *par) 70{ 71 const struct xt_mark_target_info *markinfo = par->targinfo; 72 73 if (markinfo->mark > 0xffffffff) { 74 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 75 return false; 76 } 77 return true; 78} 79 80static bool mark_tg_check_v1(const struct xt_tgchk_param *par) 81{ 82 const struct xt_mark_target_info_v1 *markinfo = par->targinfo; 83 84 if (markinfo->mode != XT_MARK_SET 85 && markinfo->mode != XT_MARK_AND 86 && markinfo->mode != XT_MARK_OR) { 87 printk(KERN_WARNING "MARK: unknown mode %u\n", 88 markinfo->mode); 89 return false; 90 } 91 if (markinfo->mark > 0xffffffff) { 92 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 93 return false; 94 } 95 return true; 96} 97 98#ifdef CONFIG_COMPAT 99struct compat_xt_mark_target_info { 100 compat_ulong_t mark; 101}; 102 103static void mark_tg_compat_from_user_v0(void *dst, void *src) 104{ 105 const struct compat_xt_mark_target_info *cm = src; 106 struct xt_mark_target_info m = { 107 .mark = cm->mark, 108 }; 109 memcpy(dst, &m, sizeof(m)); 110} 111 112static int mark_tg_compat_to_user_v0(void __user *dst, void *src) 113{ 114 const struct xt_mark_target_info *m = src; 115 struct compat_xt_mark_target_info cm = { 116 .mark = m->mark, 117 }; 118 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 119} 120 121struct compat_xt_mark_target_info_v1 { 122 compat_ulong_t mark; 123 u_int8_t mode; 124 u_int8_t __pad1; 125 u_int16_t __pad2; 126}; 127 128static void mark_tg_compat_from_user_v1(void *dst, void *src) 129{ 130 const struct compat_xt_mark_target_info_v1 *cm = src; 131 struct xt_mark_target_info_v1 m = { 132 .mark = cm->mark, 133 .mode = cm->mode, 134 }; 135 memcpy(dst, &m, sizeof(m)); 136} 137 138static int mark_tg_compat_to_user_v1(void __user *dst, void *src) 139{ 140 const struct xt_mark_target_info_v1 *m = src; 141 struct compat_xt_mark_target_info_v1 cm = { 142 .mark = m->mark, 143 .mode = m->mode, 144 }; 145 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 146} 147#endif /* CONFIG_COMPAT */ 148 149static struct xt_target mark_tg_reg[] __read_mostly = { 150 { 151 .name = "MARK", 152 .family = NFPROTO_UNSPEC, 153 .revision = 0, 154 .checkentry = mark_tg_check_v0, 155 .target = mark_tg_v0, 156 .targetsize = sizeof(struct xt_mark_target_info), 157#ifdef CONFIG_COMPAT 158 .compatsize = sizeof(struct compat_xt_mark_target_info), 159 .compat_from_user = mark_tg_compat_from_user_v0, 160 .compat_to_user = mark_tg_compat_to_user_v0, 161#endif 162 .table = "mangle", 163 .me = THIS_MODULE, 164 }, 165 { 166 .name = "MARK", 167 .family = NFPROTO_UNSPEC, 168 .revision = 1, 169 .checkentry = mark_tg_check_v1, 170 .target = mark_tg_v1, 171 .targetsize = sizeof(struct xt_mark_target_info_v1), 172#ifdef CONFIG_COMPAT 173 .compatsize = sizeof(struct compat_xt_mark_target_info_v1), 174 .compat_from_user = mark_tg_compat_from_user_v1, 175 .compat_to_user = mark_tg_compat_to_user_v1, 176#endif 177 .table = "mangle", 178 .me = THIS_MODULE, 179 }, 180 { 181 .name = "MARK", 182 .revision = 2, 183 .family = NFPROTO_UNSPEC, 184 .target = mark_tg, 185 .targetsize = sizeof(struct xt_mark_tginfo2), 186 .me = THIS_MODULE, 187 }, 188}; 189 190static int __init mark_tg_init(void) 191{ 192 return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 193} 194 195static void __exit mark_tg_exit(void) 196{ 197 xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 198} 199 200module_init(mark_tg_init); 201module_exit(mark_tg_exit);