1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ebt_mark 4 * 5 * Authors: 6 * Bart De Schuymer <bdschuym@pandora.be> 7 * 8 * July, 2002 9 * 10 */ 11 12 /* The mark target can be used in any chain, 13 * I believe adding a mangle table just for marking is total overkill. 14 * Marking a frame doesn't really change anything in the frame anyway. 15 */ 16 17 #include <linux/module.h> 18 #include <linux/netfilter/x_tables.h> 19 #include <linux/netfilter_bridge/ebtables.h> 20 #include <linux/netfilter_bridge/ebt_mark_t.h> 21 22 static unsigned int 23 ebt_mark_tg(struct sk_buff *skb, const struct xt_action_param *par) 24 { 25 const struct ebt_mark_t_info *info = par->targinfo; 26 int action = info->target & -16; 27 28 if (action == MARK_SET_VALUE) 29 skb->mark = info->mark; 30 else if (action == MARK_OR_VALUE) 31 skb->mark |= info->mark; 32 else if (action == MARK_AND_VALUE) 33 skb->mark &= info->mark; 34 else 35 skb->mark ^= info->mark; 36 37 return info->target | ~EBT_VERDICT_BITS; 38 } 39 40 static int ebt_mark_tg_check(const struct xt_tgchk_param *par) 41 { 42 const struct ebt_mark_t_info *info = par->targinfo; 43 int tmp; 44 45 tmp = info->target | ~EBT_VERDICT_BITS; 46 if (BASE_CHAIN && tmp == EBT_RETURN) 47 return -EINVAL; 48 if (ebt_invalid_target(tmp)) 49 return -EINVAL; 50 tmp = info->target & ~EBT_VERDICT_BITS; 51 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && 52 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) 53 return -EINVAL; 54 return 0; 55 } 56 #ifdef CONFIG_COMPAT 57 struct compat_ebt_mark_t_info { 58 compat_ulong_t mark; 59 compat_uint_t target; 60 }; 61 62 static void mark_tg_compat_from_user(void *dst, const void *src) 63 { 64 const struct compat_ebt_mark_t_info *user = src; 65 struct ebt_mark_t_info *kern = dst; 66 67 kern->mark = user->mark; 68 kern->target = user->target; 69 } 70 71 static int mark_tg_compat_to_user(void __user *dst, const void *src) 72 { 73 struct compat_ebt_mark_t_info __user *user = dst; 74 const struct ebt_mark_t_info *kern = src; 75 76 if (put_user(kern->mark, &user->mark) || 77 put_user(kern->target, &user->target)) 78 return -EFAULT; 79 return 0; 80 } 81 #endif 82 83 static struct xt_target ebt_mark_tg_reg __read_mostly = { 84 .name = "mark", 85 .revision = 0, 86 .family = NFPROTO_BRIDGE, 87 .target = ebt_mark_tg, 88 .checkentry = ebt_mark_tg_check, 89 .targetsize = sizeof(struct ebt_mark_t_info), 90 #ifdef CONFIG_COMPAT 91 .compatsize = sizeof(struct compat_ebt_mark_t_info), 92 .compat_from_user = mark_tg_compat_from_user, 93 .compat_to_user = mark_tg_compat_to_user, 94 #endif 95 .me = THIS_MODULE, 96 }; 97 98 static int __init ebt_mark_init(void) 99 { 100 return xt_register_target(&ebt_mark_tg_reg); 101 } 102 103 static void __exit ebt_mark_fini(void) 104 { 105 xt_unregister_target(&ebt_mark_tg_reg); 106 } 107 108 module_init(ebt_mark_init); 109 module_exit(ebt_mark_fini); 110 MODULE_DESCRIPTION("Ebtables: Packet mark modification"); 111 MODULE_LICENSE("GPL"); 112