143105Sdfr// SPDX-License-Identifier: GPL-2.0-only 243105Sdfr/* 343105Sdfr * ebt_mark 443105Sdfr * 543105Sdfr * Authors: 643105Sdfr * Bart De Schuymer <bdschuym@pandora.be> 743105Sdfr * 843105Sdfr * July, 2002 943105Sdfr * 1043105Sdfr */ 1143105Sdfr 1243105Sdfr/* The mark target can be used in any chain, 1343105Sdfr * I believe adding a mangle table just for marking is total overkill. 1443105Sdfr * Marking a frame doesn't really change anything in the frame anyway. 1543105Sdfr */ 1643105Sdfr 1743105Sdfr#include <linux/module.h> 1843105Sdfr#include <linux/netfilter/x_tables.h> 1943105Sdfr#include <linux/netfilter_bridge/ebtables.h> 2043105Sdfr#include <linux/netfilter_bridge/ebt_mark_t.h> 2143105Sdfr 2243105Sdfrstatic unsigned int 2343105Sdfrebt_mark_tg(struct sk_buff *skb, const struct xt_action_param *par) 2443105Sdfr{ 2543105Sdfr const struct ebt_mark_t_info *info = par->targinfo; 2643105Sdfr int action = info->target & -16; 27116181Sobrien 28116181Sobrien if (action == MARK_SET_VALUE) 29116181Sobrien skb->mark = info->mark; 3043105Sdfr else if (action == MARK_OR_VALUE) 3143105Sdfr skb->mark |= info->mark; 3243105Sdfr else if (action == MARK_AND_VALUE) 3343105Sdfr skb->mark &= info->mark; 3443105Sdfr else 35129880Sphk skb->mark ^= info->mark; 3643105Sdfr 3743105Sdfr return info->target | ~EBT_VERDICT_BITS; 3847400Sdfr} 3947400Sdfr 40159541Simpstatic int ebt_mark_tg_check(const struct xt_tgchk_param *par) 4143105Sdfr{ 42147271Smarius const struct ebt_mark_t_info *info = par->targinfo; 43147271Smarius int tmp; 4443105Sdfr 4543105Sdfr tmp = info->target | ~EBT_VERDICT_BITS; 4643105Sdfr if (BASE_CHAIN && tmp == EBT_RETURN) 4743105Sdfr return -EINVAL; 48147271Smarius if (ebt_invalid_target(tmp)) 49147271Smarius return -EINVAL; 50212413Savg tmp = info->target & ~EBT_VERDICT_BITS; 51188160Simp if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && 52216492Sjhb tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) 53216492Sjhb return -EINVAL; 54216492Sjhb return 0; 55216492Sjhb} 56216492Sjhb#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 5743105Sdfrstruct compat_ebt_mark_t_info { 58147271Smarius compat_ulong_t mark; 59147271Smarius compat_uint_t target; 60147271Smarius}; 6147296Syokota 6247296Syokotastatic void mark_tg_compat_from_user(void *dst, const void *src) 6343105Sdfr{ 64147271Smarius const struct compat_ebt_mark_t_info *user = src; 6543105Sdfr struct ebt_mark_t_info *kern = dst; 6643105Sdfr 6743105Sdfr kern->mark = user->mark; 6883147Syokota kern->target = user->target; 69216492Sjhb} 70216492Sjhb 7143105Sdfrstatic int mark_tg_compat_to_user(void __user *dst, const void *src) 7243105Sdfr{ 7383147Syokota struct compat_ebt_mark_t_info __user *user = dst; 7483147Syokota const struct ebt_mark_t_info *kern = src; 7583147Syokota 7643105Sdfr if (put_user(kern->mark, &user->mark) || 7743105Sdfr put_user(kern->target, &user->target)) 7843105Sdfr return -EFAULT; 7943105Sdfr return 0; 8043105Sdfr} 8143105Sdfr#endif 82147271Smarius 8343105Sdfrstatic struct xt_target ebt_mark_tg_reg __read_mostly = { 84147271Smarius .name = "mark", 8543105Sdfr .revision = 0, 8643105Sdfr .family = NFPROTO_BRIDGE, 8743105Sdfr .target = ebt_mark_tg, 8858271Syokota .checkentry = ebt_mark_tg_check, 8958271Syokota .targetsize = sizeof(struct ebt_mark_t_info), 9058271Syokota#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 9158271Syokota .compatsize = sizeof(struct compat_ebt_mark_t_info), 9258271Syokota .compat_from_user = mark_tg_compat_from_user, 9343105Sdfr .compat_to_user = mark_tg_compat_to_user, 94147271Smarius#endif 9543105Sdfr .me = THIS_MODULE, 9658271Syokota}; 9758271Syokota 9883147Syokotastatic int __init ebt_mark_init(void) 9983147Syokota{ 10058271Syokota return xt_register_target(&ebt_mark_tg_reg); 10158271Syokota} 102207354Ssobomax 103158041Ssobomaxstatic void __exit ebt_mark_fini(void) 104158041Ssobomax{ 105158041Ssobomax xt_unregister_target(&ebt_mark_tg_reg); 106158041Ssobomax} 107158041Ssobomax 10843105Sdfrmodule_init(ebt_mark_init); 10958271Syokotamodule_exit(ebt_mark_fini); 11058271SyokotaMODULE_DESCRIPTION("Ebtables: Packet mark modification"); 11158271SyokotaMODULE_LICENSE("GPL"); 11247618Sdfr