Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.14-rc7 631 lines 16 kB view raw
1/* 2 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * (C) 2012 by Vyatta Inc. <http://www.vyatta.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/rculist.h> 13#include <linux/rculist_nulls.h> 14#include <linux/types.h> 15#include <linux/timer.h> 16#include <linux/security.h> 17#include <linux/skbuff.h> 18#include <linux/errno.h> 19#include <linux/netlink.h> 20#include <linux/spinlock.h> 21#include <linux/interrupt.h> 22#include <linux/slab.h> 23 24#include <linux/netfilter.h> 25#include <net/netlink.h> 26#include <net/sock.h> 27#include <net/netfilter/nf_conntrack.h> 28#include <net/netfilter/nf_conntrack_core.h> 29#include <net/netfilter/nf_conntrack_l3proto.h> 30#include <net/netfilter/nf_conntrack_l4proto.h> 31#include <net/netfilter/nf_conntrack_tuple.h> 32#include <net/netfilter/nf_conntrack_timeout.h> 33 34#include <linux/netfilter/nfnetlink.h> 35#include <linux/netfilter/nfnetlink_cttimeout.h> 36 37MODULE_LICENSE("GPL"); 38MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); 39MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning"); 40 41static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { 42 [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING, 43 .len = CTNL_TIMEOUT_NAME_MAX - 1}, 44 [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, 45 [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, 46 [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, 47}; 48 49static int 50ctnl_timeout_parse_policy(void *timeouts, 51 const struct nf_conntrack_l4proto *l4proto, 52 struct net *net, const struct nlattr *attr) 53{ 54 int ret = 0; 55 56 if (likely(l4proto->ctnl_timeout.nlattr_to_obj)) { 57 struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1]; 58 59 ret = nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max, 60 attr, l4proto->ctnl_timeout.nla_policy, 61 NULL); 62 if (ret < 0) 63 return ret; 64 65 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts); 66 } 67 return ret; 68} 69 70static int cttimeout_new_timeout(struct net *net, struct sock *ctnl, 71 struct sk_buff *skb, 72 const struct nlmsghdr *nlh, 73 const struct nlattr * const cda[], 74 struct netlink_ext_ack *extack) 75{ 76 __u16 l3num; 77 __u8 l4num; 78 const struct nf_conntrack_l4proto *l4proto; 79 struct ctnl_timeout *timeout, *matching = NULL; 80 char *name; 81 int ret; 82 83 if (!cda[CTA_TIMEOUT_NAME] || 84 !cda[CTA_TIMEOUT_L3PROTO] || 85 !cda[CTA_TIMEOUT_L4PROTO] || 86 !cda[CTA_TIMEOUT_DATA]) 87 return -EINVAL; 88 89 name = nla_data(cda[CTA_TIMEOUT_NAME]); 90 l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO])); 91 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]); 92 93 list_for_each_entry(timeout, &net->nfct_timeout_list, head) { 94 if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) 95 continue; 96 97 if (nlh->nlmsg_flags & NLM_F_EXCL) 98 return -EEXIST; 99 100 matching = timeout; 101 break; 102 } 103 104 if (matching) { 105 if (nlh->nlmsg_flags & NLM_F_REPLACE) { 106 /* You cannot replace one timeout policy by another of 107 * different kind, sorry. 108 */ 109 if (matching->l3num != l3num || 110 matching->l4proto->l4proto != l4num) 111 return -EINVAL; 112 113 return ctnl_timeout_parse_policy(&matching->data, 114 matching->l4proto, net, 115 cda[CTA_TIMEOUT_DATA]); 116 } 117 118 return -EBUSY; 119 } 120 121 l4proto = nf_ct_l4proto_find_get(l3num, l4num); 122 123 /* This protocol is not supportted, skip. */ 124 if (l4proto->l4proto != l4num) { 125 ret = -EOPNOTSUPP; 126 goto err_proto_put; 127 } 128 129 timeout = kzalloc(sizeof(struct ctnl_timeout) + 130 l4proto->ctnl_timeout.obj_size, GFP_KERNEL); 131 if (timeout == NULL) { 132 ret = -ENOMEM; 133 goto err_proto_put; 134 } 135 136 ret = ctnl_timeout_parse_policy(&timeout->data, l4proto, net, 137 cda[CTA_TIMEOUT_DATA]); 138 if (ret < 0) 139 goto err; 140 141 strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME])); 142 timeout->l3num = l3num; 143 timeout->l4proto = l4proto; 144 refcount_set(&timeout->refcnt, 1); 145 list_add_tail_rcu(&timeout->head, &net->nfct_timeout_list); 146 147 return 0; 148err: 149 kfree(timeout); 150err_proto_put: 151 nf_ct_l4proto_put(l4proto); 152 return ret; 153} 154 155static int 156ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, 157 int event, struct ctnl_timeout *timeout) 158{ 159 struct nlmsghdr *nlh; 160 struct nfgenmsg *nfmsg; 161 unsigned int flags = portid ? NLM_F_MULTI : 0; 162 const struct nf_conntrack_l4proto *l4proto = timeout->l4proto; 163 164 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event); 165 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); 166 if (nlh == NULL) 167 goto nlmsg_failure; 168 169 nfmsg = nlmsg_data(nlh); 170 nfmsg->nfgen_family = AF_UNSPEC; 171 nfmsg->version = NFNETLINK_V0; 172 nfmsg->res_id = 0; 173 174 if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) || 175 nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num)) || 176 nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) || 177 nla_put_be32(skb, CTA_TIMEOUT_USE, 178 htonl(refcount_read(&timeout->refcnt)))) 179 goto nla_put_failure; 180 181 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) { 182 struct nlattr *nest_parms; 183 int ret; 184 185 nest_parms = nla_nest_start(skb, 186 CTA_TIMEOUT_DATA | NLA_F_NESTED); 187 if (!nest_parms) 188 goto nla_put_failure; 189 190 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data); 191 if (ret < 0) 192 goto nla_put_failure; 193 194 nla_nest_end(skb, nest_parms); 195 } 196 197 nlmsg_end(skb, nlh); 198 return skb->len; 199 200nlmsg_failure: 201nla_put_failure: 202 nlmsg_cancel(skb, nlh); 203 return -1; 204} 205 206static int 207ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb) 208{ 209 struct net *net = sock_net(skb->sk); 210 struct ctnl_timeout *cur, *last; 211 212 if (cb->args[2]) 213 return 0; 214 215 last = (struct ctnl_timeout *)cb->args[1]; 216 if (cb->args[1]) 217 cb->args[1] = 0; 218 219 rcu_read_lock(); 220 list_for_each_entry_rcu(cur, &net->nfct_timeout_list, head) { 221 if (last) { 222 if (cur != last) 223 continue; 224 225 last = NULL; 226 } 227 if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid, 228 cb->nlh->nlmsg_seq, 229 NFNL_MSG_TYPE(cb->nlh->nlmsg_type), 230 IPCTNL_MSG_TIMEOUT_NEW, cur) < 0) { 231 cb->args[1] = (unsigned long)cur; 232 break; 233 } 234 } 235 if (!cb->args[1]) 236 cb->args[2] = 1; 237 rcu_read_unlock(); 238 return skb->len; 239} 240 241static int cttimeout_get_timeout(struct net *net, struct sock *ctnl, 242 struct sk_buff *skb, 243 const struct nlmsghdr *nlh, 244 const struct nlattr * const cda[], 245 struct netlink_ext_ack *extack) 246{ 247 int ret = -ENOENT; 248 char *name; 249 struct ctnl_timeout *cur; 250 251 if (nlh->nlmsg_flags & NLM_F_DUMP) { 252 struct netlink_dump_control c = { 253 .dump = ctnl_timeout_dump, 254 }; 255 return netlink_dump_start(ctnl, skb, nlh, &c); 256 } 257 258 if (!cda[CTA_TIMEOUT_NAME]) 259 return -EINVAL; 260 name = nla_data(cda[CTA_TIMEOUT_NAME]); 261 262 list_for_each_entry(cur, &net->nfct_timeout_list, head) { 263 struct sk_buff *skb2; 264 265 if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) 266 continue; 267 268 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 269 if (skb2 == NULL) { 270 ret = -ENOMEM; 271 break; 272 } 273 274 ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).portid, 275 nlh->nlmsg_seq, 276 NFNL_MSG_TYPE(nlh->nlmsg_type), 277 IPCTNL_MSG_TIMEOUT_NEW, cur); 278 if (ret <= 0) { 279 kfree_skb(skb2); 280 break; 281 } 282 ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, 283 MSG_DONTWAIT); 284 if (ret > 0) 285 ret = 0; 286 287 /* this avoids a loop in nfnetlink. */ 288 return ret == -EAGAIN ? -ENOBUFS : ret; 289 } 290 return ret; 291} 292 293static int untimeout(struct nf_conn *ct, void *timeout) 294{ 295 struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct); 296 297 if (timeout_ext && (!timeout || timeout_ext->timeout == timeout)) 298 RCU_INIT_POINTER(timeout_ext->timeout, NULL); 299 300 /* We are not intended to delete this conntrack. */ 301 return 0; 302} 303 304static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout) 305{ 306 nf_ct_iterate_cleanup_net(net, untimeout, timeout, 0, 0); 307} 308 309/* try to delete object, fail if it is still in use. */ 310static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout) 311{ 312 int ret = 0; 313 314 /* We want to avoid races with ctnl_timeout_put. So only when the 315 * current refcnt is 1, we decrease it to 0. 316 */ 317 if (refcount_dec_if_one(&timeout->refcnt)) { 318 /* We are protected by nfnl mutex. */ 319 list_del_rcu(&timeout->head); 320 nf_ct_l4proto_put(timeout->l4proto); 321 ctnl_untimeout(net, timeout); 322 kfree_rcu(timeout, rcu_head); 323 } else { 324 ret = -EBUSY; 325 } 326 return ret; 327} 328 329static int cttimeout_del_timeout(struct net *net, struct sock *ctnl, 330 struct sk_buff *skb, 331 const struct nlmsghdr *nlh, 332 const struct nlattr * const cda[], 333 struct netlink_ext_ack *extack) 334{ 335 struct ctnl_timeout *cur, *tmp; 336 int ret = -ENOENT; 337 char *name; 338 339 if (!cda[CTA_TIMEOUT_NAME]) { 340 list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, 341 head) 342 ctnl_timeout_try_del(net, cur); 343 344 return 0; 345 } 346 name = nla_data(cda[CTA_TIMEOUT_NAME]); 347 348 list_for_each_entry(cur, &net->nfct_timeout_list, head) { 349 if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) 350 continue; 351 352 ret = ctnl_timeout_try_del(net, cur); 353 if (ret < 0) 354 return ret; 355 356 break; 357 } 358 return ret; 359} 360 361static int cttimeout_default_set(struct net *net, struct sock *ctnl, 362 struct sk_buff *skb, 363 const struct nlmsghdr *nlh, 364 const struct nlattr * const cda[], 365 struct netlink_ext_ack *extack) 366{ 367 const struct nf_conntrack_l4proto *l4proto; 368 unsigned int *timeouts; 369 __u16 l3num; 370 __u8 l4num; 371 int ret; 372 373 if (!cda[CTA_TIMEOUT_L3PROTO] || 374 !cda[CTA_TIMEOUT_L4PROTO] || 375 !cda[CTA_TIMEOUT_DATA]) 376 return -EINVAL; 377 378 l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO])); 379 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]); 380 l4proto = nf_ct_l4proto_find_get(l3num, l4num); 381 382 /* This protocol is not supported, skip. */ 383 if (l4proto->l4proto != l4num) { 384 ret = -EOPNOTSUPP; 385 goto err; 386 } 387 388 timeouts = l4proto->get_timeouts(net); 389 390 ret = ctnl_timeout_parse_policy(timeouts, l4proto, net, 391 cda[CTA_TIMEOUT_DATA]); 392 if (ret < 0) 393 goto err; 394 395 nf_ct_l4proto_put(l4proto); 396 return 0; 397err: 398 nf_ct_l4proto_put(l4proto); 399 return ret; 400} 401 402static int 403cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid, 404 u32 seq, u32 type, int event, 405 const struct nf_conntrack_l4proto *l4proto) 406{ 407 struct nlmsghdr *nlh; 408 struct nfgenmsg *nfmsg; 409 unsigned int flags = portid ? NLM_F_MULTI : 0; 410 411 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event); 412 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); 413 if (nlh == NULL) 414 goto nlmsg_failure; 415 416 nfmsg = nlmsg_data(nlh); 417 nfmsg->nfgen_family = AF_UNSPEC; 418 nfmsg->version = NFNETLINK_V0; 419 nfmsg->res_id = 0; 420 421 if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l4proto->l3proto)) || 422 nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto)) 423 goto nla_put_failure; 424 425 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) { 426 struct nlattr *nest_parms; 427 unsigned int *timeouts = l4proto->get_timeouts(net); 428 int ret; 429 430 nest_parms = nla_nest_start(skb, 431 CTA_TIMEOUT_DATA | NLA_F_NESTED); 432 if (!nest_parms) 433 goto nla_put_failure; 434 435 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts); 436 if (ret < 0) 437 goto nla_put_failure; 438 439 nla_nest_end(skb, nest_parms); 440 } 441 442 nlmsg_end(skb, nlh); 443 return skb->len; 444 445nlmsg_failure: 446nla_put_failure: 447 nlmsg_cancel(skb, nlh); 448 return -1; 449} 450 451static int cttimeout_default_get(struct net *net, struct sock *ctnl, 452 struct sk_buff *skb, 453 const struct nlmsghdr *nlh, 454 const struct nlattr * const cda[], 455 struct netlink_ext_ack *extack) 456{ 457 const struct nf_conntrack_l4proto *l4proto; 458 struct sk_buff *skb2; 459 int ret, err; 460 __u16 l3num; 461 __u8 l4num; 462 463 if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO]) 464 return -EINVAL; 465 466 l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO])); 467 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]); 468 l4proto = nf_ct_l4proto_find_get(l3num, l4num); 469 470 /* This protocol is not supported, skip. */ 471 if (l4proto->l4proto != l4num) { 472 err = -EOPNOTSUPP; 473 goto err; 474 } 475 476 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 477 if (skb2 == NULL) { 478 err = -ENOMEM; 479 goto err; 480 } 481 482 ret = cttimeout_default_fill_info(net, skb2, NETLINK_CB(skb).portid, 483 nlh->nlmsg_seq, 484 NFNL_MSG_TYPE(nlh->nlmsg_type), 485 IPCTNL_MSG_TIMEOUT_DEFAULT_SET, 486 l4proto); 487 if (ret <= 0) { 488 kfree_skb(skb2); 489 err = -ENOMEM; 490 goto err; 491 } 492 ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT); 493 if (ret > 0) 494 ret = 0; 495 496 /* this avoids a loop in nfnetlink. */ 497 return ret == -EAGAIN ? -ENOBUFS : ret; 498err: 499 nf_ct_l4proto_put(l4proto); 500 return err; 501} 502 503#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 504static struct ctnl_timeout * 505ctnl_timeout_find_get(struct net *net, const char *name) 506{ 507 struct ctnl_timeout *timeout, *matching = NULL; 508 509 list_for_each_entry_rcu(timeout, &net->nfct_timeout_list, head) { 510 if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) 511 continue; 512 513 if (!try_module_get(THIS_MODULE)) 514 goto err; 515 516 if (!refcount_inc_not_zero(&timeout->refcnt)) { 517 module_put(THIS_MODULE); 518 goto err; 519 } 520 matching = timeout; 521 break; 522 } 523err: 524 return matching; 525} 526 527static void ctnl_timeout_put(struct ctnl_timeout *timeout) 528{ 529 if (refcount_dec_and_test(&timeout->refcnt)) 530 kfree_rcu(timeout, rcu_head); 531 532 module_put(THIS_MODULE); 533} 534#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 535 536static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = { 537 [IPCTNL_MSG_TIMEOUT_NEW] = { .call = cttimeout_new_timeout, 538 .attr_count = CTA_TIMEOUT_MAX, 539 .policy = cttimeout_nla_policy }, 540 [IPCTNL_MSG_TIMEOUT_GET] = { .call = cttimeout_get_timeout, 541 .attr_count = CTA_TIMEOUT_MAX, 542 .policy = cttimeout_nla_policy }, 543 [IPCTNL_MSG_TIMEOUT_DELETE] = { .call = cttimeout_del_timeout, 544 .attr_count = CTA_TIMEOUT_MAX, 545 .policy = cttimeout_nla_policy }, 546 [IPCTNL_MSG_TIMEOUT_DEFAULT_SET]= { .call = cttimeout_default_set, 547 .attr_count = CTA_TIMEOUT_MAX, 548 .policy = cttimeout_nla_policy }, 549 [IPCTNL_MSG_TIMEOUT_DEFAULT_GET]= { .call = cttimeout_default_get, 550 .attr_count = CTA_TIMEOUT_MAX, 551 .policy = cttimeout_nla_policy }, 552}; 553 554static const struct nfnetlink_subsystem cttimeout_subsys = { 555 .name = "conntrack_timeout", 556 .subsys_id = NFNL_SUBSYS_CTNETLINK_TIMEOUT, 557 .cb_count = IPCTNL_MSG_TIMEOUT_MAX, 558 .cb = cttimeout_cb, 559}; 560 561MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_TIMEOUT); 562 563static int __net_init cttimeout_net_init(struct net *net) 564{ 565 INIT_LIST_HEAD(&net->nfct_timeout_list); 566 567 return 0; 568} 569 570static void __net_exit cttimeout_net_exit(struct net *net) 571{ 572 struct ctnl_timeout *cur, *tmp; 573 574 nf_ct_unconfirmed_destroy(net); 575 ctnl_untimeout(net, NULL); 576 577 list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) { 578 list_del_rcu(&cur->head); 579 nf_ct_l4proto_put(cur->l4proto); 580 581 if (refcount_dec_and_test(&cur->refcnt)) 582 kfree_rcu(cur, rcu_head); 583 } 584} 585 586static struct pernet_operations cttimeout_ops = { 587 .init = cttimeout_net_init, 588 .exit = cttimeout_net_exit, 589}; 590 591static int __init cttimeout_init(void) 592{ 593 int ret; 594 595 ret = register_pernet_subsys(&cttimeout_ops); 596 if (ret < 0) 597 return ret; 598 599 ret = nfnetlink_subsys_register(&cttimeout_subsys); 600 if (ret < 0) { 601 pr_err("cttimeout_init: cannot register cttimeout with " 602 "nfnetlink.\n"); 603 goto err_out; 604 } 605#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 606 RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, ctnl_timeout_find_get); 607 RCU_INIT_POINTER(nf_ct_timeout_put_hook, ctnl_timeout_put); 608#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 609 return 0; 610 611err_out: 612 unregister_pernet_subsys(&cttimeout_ops); 613 return ret; 614} 615 616static void __exit cttimeout_exit(void) 617{ 618 pr_info("cttimeout: unregistering from nfnetlink.\n"); 619 620 nfnetlink_subsys_unregister(&cttimeout_subsys); 621 622 unregister_pernet_subsys(&cttimeout_ops); 623#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 624 RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL); 625 RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL); 626 synchronize_rcu(); 627#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 628} 629 630module_init(cttimeout_init); 631module_exit(cttimeout_exit);