1 /* 2 * (C) 2011 Pablo Neira Ayuso <pablo@netfilter.org> 3 * (C) 2011 Intra2net AG <http://www.intra2net.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation (or any later at your option). 8 */ 9 #include <linux/init.h> 10 #include <linux/module.h> 11 #include <linux/kernel.h> 12 #include <linux/skbuff.h> 13 #include <linux/atomic.h> 14 #include <linux/refcount.h> 15 #include <linux/netlink.h> 16 #include <linux/rculist.h> 17 #include <linux/slab.h> 18 #include <linux/types.h> 19 #include <linux/errno.h> 20 #include <net/netlink.h> 21 #include <net/sock.h> 22 23 #include <linux/netfilter.h> 24 #include <linux/netfilter/nfnetlink.h> 25 #include <linux/netfilter/nfnetlink_acct.h> 26 27 MODULE_LICENSE("GPL"); 28 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); 29 MODULE_DESCRIPTION("nfacct: Extended Netfilter accounting infrastructure"); 30 31 struct nf_acct { 32 atomic64_t pkts; 33 atomic64_t bytes; 34 unsigned long flags; 35 struct list_head head; 36 refcount_t refcnt; 37 char name[NFACCT_NAME_MAX]; 38 struct rcu_head rcu_head; 39 char data[0]; 40 }; 41 42 struct nfacct_filter { 43 u32 value; 44 u32 mask; 45 }; 46 47 #define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES) 48 #define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */ 49 50 static int nfnl_acct_new(struct net *net, struct sock *nfnl, 51 struct sk_buff *skb, const struct nlmsghdr *nlh, 52 const struct nlattr * const tb[], 53 struct netlink_ext_ack *extack) 54 { 55 struct nf_acct *nfacct, *matching = NULL; 56 char *acct_name; 57 unsigned int size = 0; 58 u32 flags = 0; 59 60 if (!tb[NFACCT_NAME]) 61 return -EINVAL; 62 63 acct_name = nla_data(tb[NFACCT_NAME]); 64 if (strlen(acct_name) == 0) 65 return -EINVAL; 66 67 list_for_each_entry(nfacct, &net->nfnl_acct_list, head) { 68 if (strncmp(nfacct->name, acct_name, NFACCT_NAME_MAX) != 0) 69 continue; 70 71 if (nlh->nlmsg_flags & NLM_F_EXCL) 72 return -EEXIST; 73 74 matching = nfacct; 75 break; 76 } 77 78 if (matching) { 79 if (nlh->nlmsg_flags & NLM_F_REPLACE) { 80 /* reset counters if you request a replacement. */ 81 atomic64_set(&matching->pkts, 0); 82 atomic64_set(&matching->bytes, 0); 83 smp_mb__before_atomic(); 84 /* reset overquota flag if quota is enabled. */ 85 if ((matching->flags & NFACCT_F_QUOTA)) 86 clear_bit(NFACCT_OVERQUOTA_BIT, 87 &matching->flags); 88 return 0; 89 } 90 return -EBUSY; 91 } 92 93 if (tb[NFACCT_FLAGS]) { 94 flags = ntohl(nla_get_be32(tb[NFACCT_FLAGS])); 95 if (flags & ~NFACCT_F_QUOTA) 96 return -EOPNOTSUPP; 97 if ((flags & NFACCT_F_QUOTA) == NFACCT_F_QUOTA) 98 return -EINVAL; 99 if (flags & NFACCT_F_OVERQUOTA) 100 return -EINVAL; 101 if ((flags & NFACCT_F_QUOTA) && !tb[NFACCT_QUOTA]) 102 return -EINVAL; 103 104 size += sizeof(u64); 105 } 106 107 nfacct = kzalloc(sizeof(struct nf_acct) + size, GFP_KERNEL); 108 if (nfacct == NULL) 109 return -ENOMEM; 110 111 if (flags & NFACCT_F_QUOTA) { 112 u64 *quota = (u64 *)nfacct->data; 113 114 *quota = be64_to_cpu(nla_get_be64(tb[NFACCT_QUOTA])); 115 nfacct->flags = flags; 116 } 117 118 strncpy(nfacct->name, nla_data(tb[NFACCT_NAME]), NFACCT_NAME_MAX); 119 120 if (tb[NFACCT_BYTES]) { 121 atomic64_set(&nfacct->bytes, 122 be64_to_cpu(nla_get_be64(tb[NFACCT_BYTES]))); 123 } 124 if (tb[NFACCT_PKTS]) { 125 atomic64_set(&nfacct->pkts, 126 be64_to_cpu(nla_get_be64(tb[NFACCT_PKTS]))); 127 } 128 refcount_set(&nfacct->refcnt, 1); 129 list_add_tail_rcu(&nfacct->head, &net->nfnl_acct_list); 130 return 0; 131 } 132 133 static int 134 nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, 135 int event, struct nf_acct *acct) 136 { 137 struct nlmsghdr *nlh; 138 struct nfgenmsg *nfmsg; 139 unsigned int flags = portid ? NLM_F_MULTI : 0; 140 u64 pkts, bytes; 141 u32 old_flags; 142 143 event = nfnl_msg_type(NFNL_SUBSYS_ACCT, event); 144 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); 145 if (nlh == NULL) 146 goto nlmsg_failure; 147 148 nfmsg = nlmsg_data(nlh); 149 nfmsg->nfgen_family = AF_UNSPEC; 150 nfmsg->version = NFNETLINK_V0; 151 nfmsg->res_id = 0; 152 153 if (nla_put_string(skb, NFACCT_NAME, acct->name)) 154 goto nla_put_failure; 155 156 old_flags = acct->flags; 157 if (type == NFNL_MSG_ACCT_GET_CTRZERO) { 158 pkts = atomic64_xchg(&acct->pkts, 0); 159 bytes = atomic64_xchg(&acct->bytes, 0); 160 smp_mb__before_atomic(); 161 if (acct->flags & NFACCT_F_QUOTA) 162 clear_bit(NFACCT_OVERQUOTA_BIT, &acct->flags); 163 } else { 164 pkts = atomic64_read(&acct->pkts); 165 bytes = atomic64_read(&acct->bytes); 166 } 167 if (nla_put_be64(skb, NFACCT_PKTS, cpu_to_be64(pkts), 168 NFACCT_PAD) || 169 nla_put_be64(skb, NFACCT_BYTES, cpu_to_be64(bytes), 170 NFACCT_PAD) || 171 nla_put_be32(skb, NFACCT_USE, htonl(refcount_read(&acct->refcnt)))) 172 goto nla_put_failure; 173 if (acct->flags & NFACCT_F_QUOTA) { 174 u64 *quota = (u64 *)acct->data; 175 176 if (nla_put_be32(skb, NFACCT_FLAGS, htonl(old_flags)) || 177 nla_put_be64(skb, NFACCT_QUOTA, cpu_to_be64(*quota), 178 NFACCT_PAD)) 179 goto nla_put_failure; 180 } 181 nlmsg_end(skb, nlh); 182 return skb->len; 183 184 nlmsg_failure: 185 nla_put_failure: 186 nlmsg_cancel(skb, nlh); 187 return -1; 188 } 189 190 static int 191 nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) 192 { 193 struct net *net = sock_net(skb->sk); 194 struct nf_acct *cur, *last; 195 const struct nfacct_filter *filter = cb->data; 196 197 if (cb->args[2]) 198 return 0; 199 200 last = (struct nf_acct *)cb->args[1]; 201 if (cb->args[1]) 202 cb->args[1] = 0; 203 204 rcu_read_lock(); 205 list_for_each_entry_rcu(cur, &net->nfnl_acct_list, head) { 206 if (last) { 207 if (cur != last) 208 continue; 209 210 last = NULL; 211 } 212 213 if (filter && (cur->flags & filter->mask) != filter->value) 214 continue; 215 216 if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid, 217 cb->nlh->nlmsg_seq, 218 NFNL_MSG_TYPE(cb->nlh->nlmsg_type), 219 NFNL_MSG_ACCT_NEW, cur) < 0) { 220 cb->args[1] = (unsigned long)cur; 221 break; 222 } 223 } 224 if (!cb->args[1]) 225 cb->args[2] = 1; 226 rcu_read_unlock(); 227 return skb->len; 228 } 229 230 static int nfnl_acct_done(struct netlink_callback *cb) 231 { 232 kfree(cb->data); 233 return 0; 234 } 235 236 static const struct nla_policy filter_policy[NFACCT_FILTER_MAX + 1] = { 237 [NFACCT_FILTER_MASK] = { .type = NLA_U32 }, 238 [NFACCT_FILTER_VALUE] = { .type = NLA_U32 }, 239 }; 240 241 static struct nfacct_filter * 242 nfacct_filter_alloc(const struct nlattr * const attr) 243 { 244 struct nfacct_filter *filter; 245 struct nlattr *tb[NFACCT_FILTER_MAX + 1]; 246 int err; 247 248 err = nla_parse_nested(tb, NFACCT_FILTER_MAX, attr, filter_policy, 249 NULL); 250 if (err < 0) 251 return ERR_PTR(err); 252 253 if (!tb[NFACCT_FILTER_MASK] || !tb[NFACCT_FILTER_VALUE]) 254 return ERR_PTR(-EINVAL); 255 256 filter = kzalloc(sizeof(struct nfacct_filter), GFP_KERNEL); 257 if (!filter) 258 return ERR_PTR(-ENOMEM); 259 260 filter->mask = ntohl(nla_get_be32(tb[NFACCT_FILTER_MASK])); 261 filter->value = ntohl(nla_get_be32(tb[NFACCT_FILTER_VALUE])); 262 263 return filter; 264 } 265 266 static int nfnl_acct_get(struct net *net, struct sock *nfnl, 267 struct sk_buff *skb, const struct nlmsghdr *nlh, 268 const struct nlattr * const tb[], 269 struct netlink_ext_ack *extack) 270 { 271 int ret = -ENOENT; 272 struct nf_acct *cur; 273 char *acct_name; 274 275 if (nlh->nlmsg_flags & NLM_F_DUMP) { 276 struct netlink_dump_control c = { 277 .dump = nfnl_acct_dump, 278 .done = nfnl_acct_done, 279 }; 280 281 if (tb[NFACCT_FILTER]) { 282 struct nfacct_filter *filter; 283 284 filter = nfacct_filter_alloc(tb[NFACCT_FILTER]); 285 if (IS_ERR(filter)) 286 return PTR_ERR(filter); 287 288 c.data = filter; 289 } 290 return netlink_dump_start(nfnl, skb, nlh, &c); 291 } 292 293 if (!tb[NFACCT_NAME]) 294 return -EINVAL; 295 acct_name = nla_data(tb[NFACCT_NAME]); 296 297 list_for_each_entry(cur, &net->nfnl_acct_list, head) { 298 struct sk_buff *skb2; 299 300 if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0) 301 continue; 302 303 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 304 if (skb2 == NULL) { 305 ret = -ENOMEM; 306 break; 307 } 308 309 ret = nfnl_acct_fill_info(skb2, NETLINK_CB(skb).portid, 310 nlh->nlmsg_seq, 311 NFNL_MSG_TYPE(nlh->nlmsg_type), 312 NFNL_MSG_ACCT_NEW, cur); 313 if (ret <= 0) { 314 kfree_skb(skb2); 315 break; 316 } 317 ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid, 318 MSG_DONTWAIT); 319 if (ret > 0) 320 ret = 0; 321 322 /* this avoids a loop in nfnetlink. */ 323 return ret == -EAGAIN ? -ENOBUFS : ret; 324 } 325 return ret; 326 } 327 328 /* try to delete object, fail if it is still in use. */ 329 static int nfnl_acct_try_del(struct nf_acct *cur) 330 { 331 int ret = 0; 332 333 /* We want to avoid races with nfnl_acct_put. So only when the current 334 * refcnt is 1, we decrease it to 0. 335 */ 336 if (refcount_dec_if_one(&cur->refcnt)) { 337 /* We are protected by nfnl mutex. */ 338 list_del_rcu(&cur->head); 339 kfree_rcu(cur, rcu_head); 340 } else { 341 ret = -EBUSY; 342 } 343 return ret; 344 } 345 346 static int nfnl_acct_del(struct net *net, struct sock *nfnl, 347 struct sk_buff *skb, const struct nlmsghdr *nlh, 348 const struct nlattr * const tb[], 349 struct netlink_ext_ack *extack) 350 { 351 struct nf_acct *cur, *tmp; 352 int ret = -ENOENT; 353 char *acct_name; 354 355 if (!tb[NFACCT_NAME]) { 356 list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head) 357 nfnl_acct_try_del(cur); 358 359 return 0; 360 } 361 acct_name = nla_data(tb[NFACCT_NAME]); 362 363 list_for_each_entry(cur, &net->nfnl_acct_list, head) { 364 if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX) != 0) 365 continue; 366 367 ret = nfnl_acct_try_del(cur); 368 if (ret < 0) 369 return ret; 370 371 break; 372 } 373 return ret; 374 } 375 376 static const struct nla_policy nfnl_acct_policy[NFACCT_MAX+1] = { 377 [NFACCT_NAME] = { .type = NLA_NUL_STRING, .len = NFACCT_NAME_MAX-1 }, 378 [NFACCT_BYTES] = { .type = NLA_U64 }, 379 [NFACCT_PKTS] = { .type = NLA_U64 }, 380 [NFACCT_FLAGS] = { .type = NLA_U32 }, 381 [NFACCT_QUOTA] = { .type = NLA_U64 }, 382 [NFACCT_FILTER] = {.type = NLA_NESTED }, 383 }; 384 385 static const struct nfnl_callback nfnl_acct_cb[NFNL_MSG_ACCT_MAX] = { 386 [NFNL_MSG_ACCT_NEW] = { .call = nfnl_acct_new, 387 .attr_count = NFACCT_MAX, 388 .policy = nfnl_acct_policy }, 389 [NFNL_MSG_ACCT_GET] = { .call = nfnl_acct_get, 390 .attr_count = NFACCT_MAX, 391 .policy = nfnl_acct_policy }, 392 [NFNL_MSG_ACCT_GET_CTRZERO] = { .call = nfnl_acct_get, 393 .attr_count = NFACCT_MAX, 394 .policy = nfnl_acct_policy }, 395 [NFNL_MSG_ACCT_DEL] = { .call = nfnl_acct_del, 396 .attr_count = NFACCT_MAX, 397 .policy = nfnl_acct_policy }, 398 }; 399 400 static const struct nfnetlink_subsystem nfnl_acct_subsys = { 401 .name = "acct", 402 .subsys_id = NFNL_SUBSYS_ACCT, 403 .cb_count = NFNL_MSG_ACCT_MAX, 404 .cb = nfnl_acct_cb, 405 }; 406 407 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ACCT); 408 409 struct nf_acct *nfnl_acct_find_get(struct net *net, const char *acct_name) 410 { 411 struct nf_acct *cur, *acct = NULL; 412 413 rcu_read_lock(); 414 list_for_each_entry_rcu(cur, &net->nfnl_acct_list, head) { 415 if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0) 416 continue; 417 418 if (!try_module_get(THIS_MODULE)) 419 goto err; 420 421 if (!refcount_inc_not_zero(&cur->refcnt)) { 422 module_put(THIS_MODULE); 423 goto err; 424 } 425 426 acct = cur; 427 break; 428 } 429 err: 430 rcu_read_unlock(); 431 return acct; 432 } 433 EXPORT_SYMBOL_GPL(nfnl_acct_find_get); 434 435 void nfnl_acct_put(struct nf_acct *acct) 436 { 437 if (refcount_dec_and_test(&acct->refcnt)) 438 kfree_rcu(acct, rcu_head); 439 440 module_put(THIS_MODULE); 441 } 442 EXPORT_SYMBOL_GPL(nfnl_acct_put); 443 444 void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct) 445 { 446 atomic64_inc(&nfacct->pkts); 447 atomic64_add(skb->len, &nfacct->bytes); 448 } 449 EXPORT_SYMBOL_GPL(nfnl_acct_update); 450 451 static void nfnl_overquota_report(struct net *net, struct nf_acct *nfacct) 452 { 453 int ret; 454 struct sk_buff *skb; 455 456 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 457 if (skb == NULL) 458 return; 459 460 ret = nfnl_acct_fill_info(skb, 0, 0, NFNL_MSG_ACCT_OVERQUOTA, 0, 461 nfacct); 462 if (ret <= 0) { 463 kfree_skb(skb); 464 return; 465 } 466 netlink_broadcast(net->nfnl, skb, 0, NFNLGRP_ACCT_QUOTA, 467 GFP_ATOMIC); 468 } 469 470 int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb, 471 struct nf_acct *nfacct) 472 { 473 u64 now; 474 u64 *quota; 475 int ret = NFACCT_UNDERQUOTA; 476 477 /* no place here if we don't have a quota */ 478 if (!(nfacct->flags & NFACCT_F_QUOTA)) 479 return NFACCT_NO_QUOTA; 480 481 quota = (u64 *)nfacct->data; 482 now = (nfacct->flags & NFACCT_F_QUOTA_PKTS) ? 483 atomic64_read(&nfacct->pkts) : atomic64_read(&nfacct->bytes); 484 485 ret = now > *quota; 486 487 if (now >= *quota && 488 !test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) { 489 nfnl_overquota_report(net, nfacct); 490 } 491 492 return ret; 493 } 494 EXPORT_SYMBOL_GPL(nfnl_acct_overquota); 495 496 static int __net_init nfnl_acct_net_init(struct net *net) 497 { 498 INIT_LIST_HEAD(&net->nfnl_acct_list); 499 500 return 0; 501 } 502 503 static void __net_exit nfnl_acct_net_exit(struct net *net) 504 { 505 struct nf_acct *cur, *tmp; 506 507 list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head) { 508 list_del_rcu(&cur->head); 509 510 if (refcount_dec_and_test(&cur->refcnt)) 511 kfree_rcu(cur, rcu_head); 512 } 513 } 514 515 static struct pernet_operations nfnl_acct_ops = { 516 .init = nfnl_acct_net_init, 517 .exit = nfnl_acct_net_exit, 518 }; 519 520 static int __init nfnl_acct_init(void) 521 { 522 int ret; 523 524 ret = register_pernet_subsys(&nfnl_acct_ops); 525 if (ret < 0) { 526 pr_err("nfnl_acct_init: failed to register pernet ops\n"); 527 goto err_out; 528 } 529 530 ret = nfnetlink_subsys_register(&nfnl_acct_subsys); 531 if (ret < 0) { 532 pr_err("nfnl_acct_init: cannot register with nfnetlink.\n"); 533 goto cleanup_pernet; 534 } 535 return 0; 536 537 cleanup_pernet: 538 unregister_pernet_subsys(&nfnl_acct_ops); 539 err_out: 540 return ret; 541 } 542 543 static void __exit nfnl_acct_exit(void) 544 { 545 nfnetlink_subsys_unregister(&nfnl_acct_subsys); 546 unregister_pernet_subsys(&nfnl_acct_ops); 547 } 548 549 module_init(nfnl_acct_init); 550 module_exit(nfnl_acct_exit); 551