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