Blame view
net/netfilter/xt_CONNSECMARK.c
3.46 KB
d2912cb15
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
100468e9c
|
2 3 4 5 6 7 8 |
/* * This module is used to copy security markings from packets * to connections, and restore security markings from connections * back to packets. This would normally be performed in conjunction * with the SECMARK target and state match. * * Based somewhat on CONNMARK: |
50935339c
|
9 |
* Copyright (C) 2002,2004 MARA Systems AB <https://www.marasystems.com> |
100468e9c
|
10 11 |
* by Henrik Nordstrom <hno@marasystems.com> * |
560ee653b
|
12 |
* (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com> |
100468e9c
|
13 |
*/ |
8bee4bad0
|
14 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
100468e9c
|
15 16 17 18 |
#include <linux/module.h> #include <linux/skbuff.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_CONNSECMARK.h> |
587aa6416
|
19 |
#include <net/netfilter/nf_conntrack.h> |
37fccd857
|
20 |
#include <net/netfilter/nf_conntrack_ecache.h> |
100468e9c
|
21 |
|
100468e9c
|
22 23 |
MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris <jmorris@redhat.com>"); |
2ae15b64e
|
24 |
MODULE_DESCRIPTION("Xtables: target for copying between connection and security mark"); |
100468e9c
|
25 26 27 28 29 30 31 |
MODULE_ALIAS("ipt_CONNSECMARK"); MODULE_ALIAS("ip6t_CONNSECMARK"); /* * If the packet has a security mark and the connection does not, copy * the security mark from the packet to the connection. */ |
a47362a22
|
32 |
static void secmark_save(const struct sk_buff *skb) |
100468e9c
|
33 34 |
{ if (skb->secmark) { |
587aa6416
|
35 |
struct nf_conn *ct; |
100468e9c
|
36 |
enum ip_conntrack_info ctinfo; |
587aa6416
|
37 |
ct = nf_ct_get(skb, &ctinfo); |
37fccd857
|
38 |
if (ct && !ct->secmark) { |
587aa6416
|
39 |
ct->secmark = skb->secmark; |
a71996fcc
|
40 |
nf_conntrack_event_cache(IPCT_SECMARK, ct); |
37fccd857
|
41 |
} |
100468e9c
|
42 43 44 45 46 47 48 49 50 51 |
} } /* * If packet has no security mark, and the connection does, restore the * security mark from the connection to the packet. */ static void secmark_restore(struct sk_buff *skb) { if (!skb->secmark) { |
3cf93c96a
|
52 |
const struct nf_conn *ct; |
100468e9c
|
53 |
enum ip_conntrack_info ctinfo; |
587aa6416
|
54 55 56 |
ct = nf_ct_get(skb, &ctinfo); if (ct && ct->secmark) skb->secmark = ct->secmark; |
100468e9c
|
57 58 |
} } |
d3c5ee6d5
|
59 |
static unsigned int |
4b560b447
|
60 |
connsecmark_tg(struct sk_buff *skb, const struct xt_action_param *par) |
100468e9c
|
61 |
{ |
7eb355865
|
62 |
const struct xt_connsecmark_target_info *info = par->targinfo; |
100468e9c
|
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
switch (info->mode) { case CONNSECMARK_SAVE: secmark_save(skb); break; case CONNSECMARK_RESTORE: secmark_restore(skb); break; default: BUG(); } return XT_CONTINUE; } |
135367b8f
|
79 |
static int connsecmark_tg_check(const struct xt_tgchk_param *par) |
100468e9c
|
80 |
{ |
af5d6dc20
|
81 |
const struct xt_connsecmark_target_info *info = par->targinfo; |
4a5a5c73b
|
82 |
int ret; |
100468e9c
|
83 |
|
af5d6dc20
|
84 85 |
if (strcmp(par->table, "mangle") != 0 && strcmp(par->table, "security") != 0) { |
cc48baefd
|
86 87 88 |
pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\' ", par->table); |
d6b00a534
|
89 |
return -EINVAL; |
560ee653b
|
90 |
} |
100468e9c
|
91 92 93 94 95 96 |
switch (info->mode) { case CONNSECMARK_SAVE: case CONNSECMARK_RESTORE: break; default: |
b26066447
|
97 98 |
pr_info_ratelimited("invalid mode: %hu ", info->mode); |
4a5a5c73b
|
99 |
return -EINVAL; |
100468e9c
|
100 |
} |
ecb2421b5
|
101 |
ret = nf_ct_netns_get(par->net, par->family); |
f95c74e33
|
102 |
if (ret < 0) |
b26066447
|
103 104 105 |
pr_info_ratelimited("cannot load conntrack support for proto=%u ", par->family); |
f95c74e33
|
106 |
return ret; |
100468e9c
|
107 |
} |
a2df1648b
|
108 |
static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par) |
11078c371
|
109 |
{ |
ecb2421b5
|
110 |
nf_ct_netns_put(par->net, par->family); |
11078c371
|
111 |
} |
92f3b2b1b
|
112 113 114 115 116 117 118 119 120 |
static struct xt_target connsecmark_tg_reg __read_mostly = { .name = "CONNSECMARK", .revision = 0, .family = NFPROTO_UNSPEC, .checkentry = connsecmark_tg_check, .destroy = connsecmark_tg_destroy, .target = connsecmark_tg, .targetsize = sizeof(struct xt_connsecmark_target_info), .me = THIS_MODULE, |
100468e9c
|
121 |
}; |
d3c5ee6d5
|
122 |
static int __init connsecmark_tg_init(void) |
100468e9c
|
123 |
{ |
92f3b2b1b
|
124 |
return xt_register_target(&connsecmark_tg_reg); |
100468e9c
|
125 |
} |
d3c5ee6d5
|
126 |
static void __exit connsecmark_tg_exit(void) |
100468e9c
|
127 |
{ |
92f3b2b1b
|
128 |
xt_unregister_target(&connsecmark_tg_reg); |
100468e9c
|
129 |
} |
d3c5ee6d5
|
130 131 |
module_init(connsecmark_tg_init); module_exit(connsecmark_tg_exit); |