Blame view
net/netfilter/xt_dscp.c
2.63 KB
d2912cb15
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
9ba162761
|
2 3 |
/* IP tables module for matching the value of the IPv4/IPv6 DSCP field * |
9ba162761
|
4 |
* (C) 2002 by Harald Welte <laforge@netfilter.org> |
9ba162761
|
5 |
*/ |
8bee4bad0
|
6 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
9ba162761
|
7 8 9 10 11 |
#include <linux/module.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <net/dsfield.h> |
9ba162761
|
12 |
#include <linux/netfilter/x_tables.h> |
c3b33e6a2
|
13 |
#include <linux/netfilter/xt_dscp.h> |
9ba162761
|
14 15 |
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
2ae15b64e
|
16 |
MODULE_DESCRIPTION("Xtables: DSCP/TOS field match"); |
9ba162761
|
17 18 19 |
MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_dscp"); MODULE_ALIAS("ip6t_dscp"); |
c3b33e6a2
|
20 |
MODULE_ALIAS("ipt_tos"); |
f1095ab51
|
21 |
MODULE_ALIAS("ip6t_tos"); |
9ba162761
|
22 |
|
d3c5ee6d5
|
23 |
static bool |
62fc80510
|
24 |
dscp_mt(const struct sk_buff *skb, struct xt_action_param *par) |
9ba162761
|
25 |
{ |
f7108a20d
|
26 |
const struct xt_dscp_info *info = par->matchinfo; |
1d93a9cba
|
27 28 29 30 |
u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; return (dscp == info->dscp) ^ !!info->invert; } |
d3c5ee6d5
|
31 |
static bool |
62fc80510
|
32 |
dscp_mt6(const struct sk_buff *skb, struct xt_action_param *par) |
1d93a9cba
|
33 |
{ |
f7108a20d
|
34 |
const struct xt_dscp_info *info = par->matchinfo; |
0660e03f6
|
35 |
u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; |
9ba162761
|
36 37 38 |
return (dscp == info->dscp) ^ !!info->invert; } |
b0f38452f
|
39 |
static int dscp_mt_check(const struct xt_mtchk_param *par) |
9ba162761
|
40 |
{ |
9b4fce7a3
|
41 |
const struct xt_dscp_info *info = par->matchinfo; |
9ba162761
|
42 |
|
0cc9501f9
|
43 |
if (info->dscp > XT_DSCP_MAX) |
4a5a5c73b
|
44 |
return -EDOM; |
9ba162761
|
45 |
|
bd414ee60
|
46 |
return 0; |
9ba162761
|
47 |
} |
62fc80510
|
48 |
static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par) |
f1095ab51
|
49 |
{ |
f7108a20d
|
50 |
const struct xt_tos_match_info *info = par->matchinfo; |
f1095ab51
|
51 |
|
613dbd957
|
52 |
if (xt_family(par) == NFPROTO_IPV4) |
f1095ab51
|
53 54 55 56 57 58 |
return ((ip_hdr(skb)->tos & info->tos_mask) == info->tos_value) ^ !!info->invert; else return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) == info->tos_value) ^ !!info->invert; } |
d3c5ee6d5
|
59 |
static struct xt_match dscp_mt_reg[] __read_mostly = { |
4470bbc74
|
60 61 |
{ .name = "dscp", |
ee999d8b9
|
62 |
.family = NFPROTO_IPV4, |
d3c5ee6d5
|
63 64 |
.checkentry = dscp_mt_check, .match = dscp_mt, |
4470bbc74
|
65 66 67 68 69 |
.matchsize = sizeof(struct xt_dscp_info), .me = THIS_MODULE, }, { .name = "dscp", |
ee999d8b9
|
70 |
.family = NFPROTO_IPV6, |
d3c5ee6d5
|
71 72 |
.checkentry = dscp_mt_check, .match = dscp_mt6, |
4470bbc74
|
73 74 75 |
.matchsize = sizeof(struct xt_dscp_info), .me = THIS_MODULE, }, |
c3b33e6a2
|
76 77 |
{ .name = "tos", |
f1095ab51
|
78 |
.revision = 1, |
ee999d8b9
|
79 |
.family = NFPROTO_IPV4, |
f1095ab51
|
80 81 82 83 84 85 86 |
.match = tos_mt, .matchsize = sizeof(struct xt_tos_match_info), .me = THIS_MODULE, }, { .name = "tos", .revision = 1, |
ee999d8b9
|
87 |
.family = NFPROTO_IPV6, |
f1095ab51
|
88 89 90 91 |
.match = tos_mt, .matchsize = sizeof(struct xt_tos_match_info), .me = THIS_MODULE, }, |
9ba162761
|
92 |
}; |
d3c5ee6d5
|
93 |
static int __init dscp_mt_init(void) |
9ba162761
|
94 |
{ |
d3c5ee6d5
|
95 |
return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); |
9ba162761
|
96 |
} |
d3c5ee6d5
|
97 |
static void __exit dscp_mt_exit(void) |
9ba162761
|
98 |
{ |
d3c5ee6d5
|
99 |
xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); |
9ba162761
|
100 |
} |
d3c5ee6d5
|
101 102 |
module_init(dscp_mt_init); module_exit(dscp_mt_exit); |