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(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_NETFILTER_XTABLES_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_NETFILTER_XTABLES_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(target: &ebt_mark_tg_reg); |
101 | } |
102 | |
103 | static void __exit ebt_mark_fini(void) |
104 | { |
105 | xt_unregister_target(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 | |