Blame view
net/netfilter/nft_log.c
5.22 KB
96518518c netfilter: add nf... |
1 |
/* |
ef1f7df91 netfilter: nf_tab... |
2 |
* Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> |
09d27b88f netfilter: nft_lo... |
3 |
* Copyright (c) 2012-2014 Pablo Neira Ayuso <pablo@netfilter.org> |
96518518c netfilter: add nf... |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Development of this code funded by Astaro AG (http://www.astaro.com/) */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/netlink.h> #include <linux/netfilter.h> #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_log.h> #include <linux/netdevice.h> static const char *nft_log_null_prefix = ""; struct nft_log { struct nf_loginfo loginfo; char *prefix; |
96518518c netfilter: add nf... |
27 28 29 |
}; static void nft_log_eval(const struct nft_expr *expr, |
a55e22e92 netfilter: nf_tab... |
30 |
struct nft_regs *regs, |
96518518c netfilter: add nf... |
31 32 33 |
const struct nft_pktinfo *pkt) { const struct nft_log *priv = nft_expr_priv(expr); |
96518518c netfilter: add nf... |
34 |
|
88182a0e0 netfilter: nf_tab... |
35 |
nf_log_packet(pkt->net, pkt->pf, pkt->hook, pkt->skb, pkt->in, |
96518518c netfilter: add nf... |
36 37 38 39 40 41 42 43 |
pkt->out, &priv->loginfo, "%s", priv->prefix); } static const struct nla_policy nft_log_policy[NFTA_LOG_MAX + 1] = { [NFTA_LOG_GROUP] = { .type = NLA_U16 }, [NFTA_LOG_PREFIX] = { .type = NLA_STRING }, [NFTA_LOG_SNAPLEN] = { .type = NLA_U32 }, [NFTA_LOG_QTHRESHOLD] = { .type = NLA_U16 }, |
09d27b88f netfilter: nft_lo... |
44 45 |
[NFTA_LOG_LEVEL] = { .type = NLA_U32 }, [NFTA_LOG_FLAGS] = { .type = NLA_U32 }, |
96518518c netfilter: add nf... |
46 47 48 49 50 51 52 53 54 |
}; static int nft_log_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_log *priv = nft_expr_priv(expr); struct nf_loginfo *li = &priv->loginfo; const struct nlattr *nla; |
85d30e241 netfilter: nft_lo... |
55 |
int ret; |
96518518c netfilter: add nf... |
56 |
|
96518518c netfilter: add nf... |
57 58 59 60 61 62 |
nla = tb[NFTA_LOG_PREFIX]; if (nla != NULL) { priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL); if (priv->prefix == NULL) return -ENOMEM; nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1); |
09d27b88f netfilter: nft_lo... |
63 |
} else { |
96518518c netfilter: add nf... |
64 |
priv->prefix = (char *)nft_log_null_prefix; |
09d27b88f netfilter: nft_lo... |
65 |
} |
96518518c netfilter: add nf... |
66 |
|
09d27b88f netfilter: nft_lo... |
67 68 69 70 |
li->type = NF_LOG_TYPE_LOG; if (tb[NFTA_LOG_LEVEL] != NULL && tb[NFTA_LOG_GROUP] != NULL) return -EINVAL; |
96518518c netfilter: add nf... |
71 |
if (tb[NFTA_LOG_GROUP] != NULL) |
09d27b88f netfilter: nft_lo... |
72 73 74 75 76 77 |
li->type = NF_LOG_TYPE_ULOG; switch (li->type) { case NF_LOG_TYPE_LOG: if (tb[NFTA_LOG_LEVEL] != NULL) { li->u.log.level = |
5cbfda204 netfilter: nft_lo... |
78 |
ntohl(nla_get_be32(tb[NFTA_LOG_LEVEL])); |
09d27b88f netfilter: nft_lo... |
79 |
} else { |
a81b2ce85 netfilter: Use LO... |
80 |
li->u.log.level = LOGLEVEL_WARNING; |
09d27b88f netfilter: nft_lo... |
81 82 83 84 85 86 87 |
} if (tb[NFTA_LOG_FLAGS] != NULL) { li->u.log.logflags = ntohl(nla_get_be32(tb[NFTA_LOG_FLAGS])); } break; case NF_LOG_TYPE_ULOG: |
96518518c netfilter: add nf... |
88 |
li->u.ulog.group = ntohs(nla_get_be16(tb[NFTA_LOG_GROUP])); |
09d27b88f netfilter: nft_lo... |
89 90 91 92 93 94 95 96 97 |
if (tb[NFTA_LOG_SNAPLEN] != NULL) { li->u.ulog.copy_len = ntohl(nla_get_be32(tb[NFTA_LOG_SNAPLEN])); } if (tb[NFTA_LOG_QTHRESHOLD] != NULL) { li->u.ulog.qthreshold = ntohs(nla_get_be16(tb[NFTA_LOG_QTHRESHOLD])); } break; |
96518518c netfilter: add nf... |
98 |
} |
85d30e241 netfilter: nft_lo... |
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
if (ctx->afi->family == NFPROTO_INET) { ret = nf_logger_find_get(NFPROTO_IPV4, li->type); if (ret < 0) return ret; ret = nf_logger_find_get(NFPROTO_IPV6, li->type); if (ret < 0) { nf_logger_put(NFPROTO_IPV4, li->type); return ret; } return 0; } return nf_logger_find_get(ctx->afi->family, li->type); |
96518518c netfilter: add nf... |
113 |
} |
62472bcef netfilter: nf_tab... |
114 115 |
static void nft_log_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) |
96518518c netfilter: add nf... |
116 117 |
{ struct nft_log *priv = nft_expr_priv(expr); |
85d30e241 netfilter: nft_lo... |
118 |
struct nf_loginfo *li = &priv->loginfo; |
96518518c netfilter: add nf... |
119 120 121 |
if (priv->prefix != nft_log_null_prefix) kfree(priv->prefix); |
85d30e241 netfilter: nft_lo... |
122 123 124 125 126 127 128 |
if (ctx->afi->family == NFPROTO_INET) { nf_logger_put(NFPROTO_IPV4, li->type); nf_logger_put(NFPROTO_IPV6, li->type); } else { nf_logger_put(ctx->afi->family, li->type); } |
96518518c netfilter: add nf... |
129 130 131 132 133 134 135 136 137 138 |
} static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr) { const struct nft_log *priv = nft_expr_priv(expr); const struct nf_loginfo *li = &priv->loginfo; if (priv->prefix != nft_log_null_prefix) if (nla_put_string(skb, NFTA_LOG_PREFIX, priv->prefix)) goto nla_put_failure; |
09d27b88f netfilter: nft_lo... |
139 140 141 |
switch (li->type) { case NF_LOG_TYPE_LOG: if (nla_put_be32(skb, NFTA_LOG_LEVEL, htonl(li->u.log.level))) |
96518518c netfilter: add nf... |
142 |
goto nla_put_failure; |
09d27b88f netfilter: nft_lo... |
143 144 145 146 147 148 149 150 151 |
if (li->u.log.logflags) { if (nla_put_be32(skb, NFTA_LOG_FLAGS, htonl(li->u.log.logflags))) goto nla_put_failure; } break; case NF_LOG_TYPE_ULOG: if (nla_put_be16(skb, NFTA_LOG_GROUP, htons(li->u.ulog.group))) |
96518518c netfilter: add nf... |
152 |
goto nla_put_failure; |
09d27b88f netfilter: nft_lo... |
153 154 155 156 157 158 159 160 161 162 163 164 165 |
if (li->u.ulog.copy_len) { if (nla_put_be32(skb, NFTA_LOG_SNAPLEN, htonl(li->u.ulog.copy_len))) goto nla_put_failure; } if (li->u.ulog.qthreshold) { if (nla_put_be16(skb, NFTA_LOG_QTHRESHOLD, htons(li->u.ulog.qthreshold))) goto nla_put_failure; } break; } |
96518518c netfilter: add nf... |
166 167 168 169 170 |
return 0; nla_put_failure: return -1; } |
ef1f7df91 netfilter: nf_tab... |
171 172 173 |
static struct nft_expr_type nft_log_type; static const struct nft_expr_ops nft_log_ops = { .type = &nft_log_type, |
96518518c netfilter: add nf... |
174 |
.size = NFT_EXPR_SIZE(sizeof(struct nft_log)), |
96518518c netfilter: add nf... |
175 176 177 178 |
.eval = nft_log_eval, .init = nft_log_init, .destroy = nft_log_destroy, .dump = nft_log_dump, |
ef1f7df91 netfilter: nf_tab... |
179 180 181 182 183 |
}; static struct nft_expr_type nft_log_type __read_mostly = { .name = "log", .ops = &nft_log_ops, |
96518518c netfilter: add nf... |
184 185 |
.policy = nft_log_policy, .maxattr = NFTA_LOG_MAX, |
ef1f7df91 netfilter: nf_tab... |
186 |
.owner = THIS_MODULE, |
96518518c netfilter: add nf... |
187 188 189 190 |
}; static int __init nft_log_module_init(void) { |
ef1f7df91 netfilter: nf_tab... |
191 |
return nft_register_expr(&nft_log_type); |
96518518c netfilter: add nf... |
192 193 194 195 |
} static void __exit nft_log_module_exit(void) { |
ef1f7df91 netfilter: nf_tab... |
196 |
nft_unregister_expr(&nft_log_type); |
96518518c netfilter: add nf... |
197 198 199 200 201 202 203 204 |
} module_init(nft_log_module_init); module_exit(nft_log_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); MODULE_ALIAS_NFT_EXPR("log"); |