Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://1984.lsi.us.es/nf-next

+599 -265
+12 -1
include/net/netfilter/nf_conntrack_l4proto.h
··· 97 97 #endif 98 98 int *net_id; 99 99 /* Init l4proto pernet data */ 100 - int (*init_net)(struct net *net); 100 + int (*init_net)(struct net *net, u_int16_t proto); 101 + 102 + /* Return the per-net protocol part. */ 103 + struct nf_proto_net *(*get_net_proto)(struct net *net); 101 104 102 105 /* Protocol name */ 103 106 const char *name; ··· 126 123 struct nf_conntrack_l4proto *proto); 127 124 extern void nf_conntrack_l4proto_unregister(struct net *net, 128 125 struct nf_conntrack_l4proto *proto); 126 + 127 + static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn) 128 + { 129 + #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 130 + kfree(pn->ctl_compat_table); 131 + pn->ctl_compat_table = NULL; 132 + #endif 133 + } 129 134 130 135 /* Generic netlink helpers */ 131 136 extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
+38 -9
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
··· 337 337 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 338 338 #endif /* CONFIG_SYSCTL */ 339 339 340 - static int icmp_init_net(struct net *net) 340 + static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn, 341 + struct nf_icmp_net *in) 341 342 { 342 - struct nf_icmp_net *in = icmp_pernet(net); 343 - struct nf_proto_net *pn = (struct nf_proto_net *)in; 344 - in->timeout = nf_ct_icmp_timeout; 345 - 346 343 #ifdef CONFIG_SYSCTL 347 344 pn->ctl_table = kmemdup(icmp_sysctl_table, 348 345 sizeof(icmp_sysctl_table), 349 346 GFP_KERNEL); 350 347 if (!pn->ctl_table) 351 348 return -ENOMEM; 349 + 352 350 pn->ctl_table[0].data = &in->timeout; 351 + #endif 352 + return 0; 353 + } 354 + 355 + static int icmp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 356 + struct nf_icmp_net *in) 357 + { 358 + #ifdef CONFIG_SYSCTL 353 359 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 354 360 pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table, 355 361 sizeof(icmp_compat_sysctl_table), 356 362 GFP_KERNEL); 357 - if (!pn->ctl_compat_table) { 358 - kfree(pn->ctl_table); 359 - pn->ctl_table = NULL; 363 + if (!pn->ctl_compat_table) 360 364 return -ENOMEM; 361 - } 365 + 362 366 pn->ctl_compat_table[0].data = &in->timeout; 363 367 #endif 364 368 #endif 365 369 return 0; 370 + } 371 + 372 + static int icmp_init_net(struct net *net, u_int16_t proto) 373 + { 374 + int ret; 375 + struct nf_icmp_net *in = icmp_pernet(net); 376 + struct nf_proto_net *pn = &in->pn; 377 + 378 + in->timeout = nf_ct_icmp_timeout; 379 + 380 + ret = icmp_kmemdup_compat_sysctl_table(pn, in); 381 + if (ret < 0) 382 + return ret; 383 + 384 + ret = icmp_kmemdup_sysctl_table(pn, in); 385 + if (ret < 0) 386 + nf_ct_kfree_compat_sysctl_table(pn); 387 + 388 + return ret; 389 + } 390 + 391 + static struct nf_proto_net *icmp_get_net_proto(struct net *net) 392 + { 393 + return &net->ct.nf_ct_proto.icmp.pn; 366 394 } 367 395 368 396 struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = ··· 423 395 }, 424 396 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 425 397 .init_net = icmp_init_net, 398 + .get_net_proto = icmp_get_net_proto, 426 399 };
+19 -4
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
··· 333 333 }; 334 334 #endif /* CONFIG_SYSCTL */ 335 335 336 - static int icmpv6_init_net(struct net *net) 336 + static int icmpv6_kmemdup_sysctl_table(struct nf_proto_net *pn, 337 + struct nf_icmp_net *in) 337 338 { 338 - struct nf_icmp_net *in = icmpv6_pernet(net); 339 - struct nf_proto_net *pn = (struct nf_proto_net *)in; 340 - in->timeout = nf_ct_icmpv6_timeout; 341 339 #ifdef CONFIG_SYSCTL 342 340 pn->ctl_table = kmemdup(icmpv6_sysctl_table, 343 341 sizeof(icmpv6_sysctl_table), 344 342 GFP_KERNEL); 345 343 if (!pn->ctl_table) 346 344 return -ENOMEM; 345 + 347 346 pn->ctl_table[0].data = &in->timeout; 348 347 #endif 349 348 return 0; 349 + } 350 + 351 + static int icmpv6_init_net(struct net *net, u_int16_t proto) 352 + { 353 + struct nf_icmp_net *in = icmpv6_pernet(net); 354 + struct nf_proto_net *pn = &in->pn; 355 + 356 + in->timeout = nf_ct_icmpv6_timeout; 357 + 358 + return icmpv6_kmemdup_sysctl_table(pn, in); 359 + } 360 + 361 + static struct nf_proto_net *icmpv6_get_net_proto(struct net *net) 362 + { 363 + return &net->ct.nf_ct_proto.icmpv6.pn; 350 364 } 351 365 352 366 struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = ··· 391 377 }, 392 378 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 393 379 .init_net = icmpv6_init_net, 380 + .get_net_proto = icmpv6_get_net_proto, 394 381 };
+226 -1
net/netfilter/nf_conntrack_netlink.c
··· 4 4 * (C) 2001 by Jay Schulist <jschlst@samba.org> 5 5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> 6 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net> 7 - * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 7 + * (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org> 8 8 * 9 9 * Initial connection tracking via netlink development funded and 10 10 * generally made possible by Network Robots, Inc. (www.networkrobots.com) ··· 1627 1627 return err; 1628 1628 } 1629 1629 1630 + static int 1631 + ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 pid, u32 seq, 1632 + __u16 cpu, const struct ip_conntrack_stat *st) 1633 + { 1634 + struct nlmsghdr *nlh; 1635 + struct nfgenmsg *nfmsg; 1636 + unsigned int flags = pid ? NLM_F_MULTI : 0, event; 1637 + 1638 + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS_CPU); 1639 + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); 1640 + if (nlh == NULL) 1641 + goto nlmsg_failure; 1642 + 1643 + nfmsg = nlmsg_data(nlh); 1644 + nfmsg->nfgen_family = AF_UNSPEC; 1645 + nfmsg->version = NFNETLINK_V0; 1646 + nfmsg->res_id = htons(cpu); 1647 + 1648 + if (nla_put_be32(skb, CTA_STATS_SEARCHED, htonl(st->searched)) || 1649 + nla_put_be32(skb, CTA_STATS_FOUND, htonl(st->found)) || 1650 + nla_put_be32(skb, CTA_STATS_NEW, htonl(st->new)) || 1651 + nla_put_be32(skb, CTA_STATS_INVALID, htonl(st->invalid)) || 1652 + nla_put_be32(skb, CTA_STATS_IGNORE, htonl(st->ignore)) || 1653 + nla_put_be32(skb, CTA_STATS_DELETE, htonl(st->delete)) || 1654 + nla_put_be32(skb, CTA_STATS_DELETE_LIST, htonl(st->delete_list)) || 1655 + nla_put_be32(skb, CTA_STATS_INSERT, htonl(st->insert)) || 1656 + nla_put_be32(skb, CTA_STATS_INSERT_FAILED, 1657 + htonl(st->insert_failed)) || 1658 + nla_put_be32(skb, CTA_STATS_DROP, htonl(st->drop)) || 1659 + nla_put_be32(skb, CTA_STATS_EARLY_DROP, htonl(st->early_drop)) || 1660 + nla_put_be32(skb, CTA_STATS_ERROR, htonl(st->error)) || 1661 + nla_put_be32(skb, CTA_STATS_SEARCH_RESTART, 1662 + htonl(st->search_restart))) 1663 + goto nla_put_failure; 1664 + 1665 + nlmsg_end(skb, nlh); 1666 + return skb->len; 1667 + 1668 + nla_put_failure: 1669 + nlmsg_failure: 1670 + nlmsg_cancel(skb, nlh); 1671 + return -1; 1672 + } 1673 + 1674 + static int 1675 + ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb) 1676 + { 1677 + int cpu; 1678 + struct net *net = sock_net(skb->sk); 1679 + 1680 + if (cb->args[0] == nr_cpu_ids) 1681 + return 0; 1682 + 1683 + for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) { 1684 + const struct ip_conntrack_stat *st; 1685 + 1686 + if (!cpu_possible(cpu)) 1687 + continue; 1688 + 1689 + st = per_cpu_ptr(net->ct.stat, cpu); 1690 + if (ctnetlink_ct_stat_cpu_fill_info(skb, 1691 + NETLINK_CB(cb->skb).pid, 1692 + cb->nlh->nlmsg_seq, 1693 + cpu, st) < 0) 1694 + break; 1695 + } 1696 + cb->args[0] = cpu; 1697 + 1698 + return skb->len; 1699 + } 1700 + 1701 + static int 1702 + ctnetlink_stat_ct_cpu(struct sock *ctnl, struct sk_buff *skb, 1703 + const struct nlmsghdr *nlh, 1704 + const struct nlattr * const cda[]) 1705 + { 1706 + if (nlh->nlmsg_flags & NLM_F_DUMP) { 1707 + struct netlink_dump_control c = { 1708 + .dump = ctnetlink_ct_stat_cpu_dump, 1709 + }; 1710 + return netlink_dump_start(ctnl, skb, nlh, &c); 1711 + } 1712 + 1713 + return 0; 1714 + } 1715 + 1716 + static int 1717 + ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type, 1718 + struct net *net) 1719 + { 1720 + struct nlmsghdr *nlh; 1721 + struct nfgenmsg *nfmsg; 1722 + unsigned int flags = pid ? NLM_F_MULTI : 0, event; 1723 + unsigned int nr_conntracks = atomic_read(&net->ct.count); 1724 + 1725 + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS); 1726 + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); 1727 + if (nlh == NULL) 1728 + goto nlmsg_failure; 1729 + 1730 + nfmsg = nlmsg_data(nlh); 1731 + nfmsg->nfgen_family = AF_UNSPEC; 1732 + nfmsg->version = NFNETLINK_V0; 1733 + nfmsg->res_id = 0; 1734 + 1735 + if (nla_put_be32(skb, CTA_STATS_GLOBAL_ENTRIES, htonl(nr_conntracks))) 1736 + goto nla_put_failure; 1737 + 1738 + nlmsg_end(skb, nlh); 1739 + return skb->len; 1740 + 1741 + nla_put_failure: 1742 + nlmsg_failure: 1743 + nlmsg_cancel(skb, nlh); 1744 + return -1; 1745 + } 1746 + 1747 + static int 1748 + ctnetlink_stat_ct(struct sock *ctnl, struct sk_buff *skb, 1749 + const struct nlmsghdr *nlh, 1750 + const struct nlattr * const cda[]) 1751 + { 1752 + struct sk_buff *skb2; 1753 + int err; 1754 + 1755 + skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1756 + if (skb2 == NULL) 1757 + return -ENOMEM; 1758 + 1759 + err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).pid, 1760 + nlh->nlmsg_seq, 1761 + NFNL_MSG_TYPE(nlh->nlmsg_type), 1762 + sock_net(skb->sk)); 1763 + if (err <= 0) 1764 + goto free; 1765 + 1766 + err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); 1767 + if (err < 0) 1768 + goto out; 1769 + 1770 + return 0; 1771 + 1772 + free: 1773 + kfree_skb(skb2); 1774 + out: 1775 + /* this avoids a loop in nfnetlink. */ 1776 + return err == -EAGAIN ? -ENOBUFS : err; 1777 + } 1778 + 1630 1779 #ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT 1631 1780 static size_t 1632 1781 ctnetlink_nfqueue_build_size(const struct nf_conn *ct) ··· 2589 2440 return err; 2590 2441 } 2591 2442 2443 + static int 2444 + ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int cpu, 2445 + const struct ip_conntrack_stat *st) 2446 + { 2447 + struct nlmsghdr *nlh; 2448 + struct nfgenmsg *nfmsg; 2449 + unsigned int flags = pid ? NLM_F_MULTI : 0, event; 2450 + 2451 + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_EXP_GET_STATS_CPU); 2452 + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); 2453 + if (nlh == NULL) 2454 + goto nlmsg_failure; 2455 + 2456 + nfmsg = nlmsg_data(nlh); 2457 + nfmsg->nfgen_family = AF_UNSPEC; 2458 + nfmsg->version = NFNETLINK_V0; 2459 + nfmsg->res_id = htons(cpu); 2460 + 2461 + if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) || 2462 + nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) || 2463 + nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete))) 2464 + goto nla_put_failure; 2465 + 2466 + nlmsg_end(skb, nlh); 2467 + return skb->len; 2468 + 2469 + nla_put_failure: 2470 + nlmsg_failure: 2471 + nlmsg_cancel(skb, nlh); 2472 + return -1; 2473 + } 2474 + 2475 + static int 2476 + ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb) 2477 + { 2478 + int cpu; 2479 + struct net *net = sock_net(skb->sk); 2480 + 2481 + if (cb->args[0] == nr_cpu_ids) 2482 + return 0; 2483 + 2484 + for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) { 2485 + const struct ip_conntrack_stat *st; 2486 + 2487 + if (!cpu_possible(cpu)) 2488 + continue; 2489 + 2490 + st = per_cpu_ptr(net->ct.stat, cpu); 2491 + if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).pid, 2492 + cb->nlh->nlmsg_seq, 2493 + cpu, st) < 0) 2494 + break; 2495 + } 2496 + cb->args[0] = cpu; 2497 + 2498 + return skb->len; 2499 + } 2500 + 2501 + static int 2502 + ctnetlink_stat_exp_cpu(struct sock *ctnl, struct sk_buff *skb, 2503 + const struct nlmsghdr *nlh, 2504 + const struct nlattr * const cda[]) 2505 + { 2506 + if (nlh->nlmsg_flags & NLM_F_DUMP) { 2507 + struct netlink_dump_control c = { 2508 + .dump = ctnetlink_exp_stat_cpu_dump, 2509 + }; 2510 + return netlink_dump_start(ctnl, skb, nlh, &c); 2511 + } 2512 + 2513 + return 0; 2514 + } 2515 + 2592 2516 #ifdef CONFIG_NF_CONNTRACK_EVENTS 2593 2517 static struct nf_ct_event_notifier ctnl_notifier = { 2594 2518 .fcn = ctnetlink_conntrack_event, ··· 2685 2463 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, 2686 2464 .attr_count = CTA_MAX, 2687 2465 .policy = ct_nla_policy }, 2466 + [IPCTNL_MSG_CT_GET_STATS_CPU] = { .call = ctnetlink_stat_ct_cpu }, 2467 + [IPCTNL_MSG_CT_GET_STATS] = { .call = ctnetlink_stat_ct }, 2688 2468 }; 2689 2469 2690 2470 static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { ··· 2699 2475 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, 2700 2476 .attr_count = CTA_EXPECT_MAX, 2701 2477 .policy = exp_nla_policy }, 2478 + [IPCTNL_MSG_EXP_GET_STATS_CPU] = { .call = ctnetlink_stat_exp_cpu }, 2702 2479 }; 2703 2480 2704 2481 static const struct nfnetlink_subsystem ctnl_subsys = {
+83 -64
net/netfilter/nf_conntrack_proto.c
··· 39 39 nf_ct_register_sysctl(struct net *net, 40 40 struct ctl_table_header **header, 41 41 const char *path, 42 - struct ctl_table *table, 43 - unsigned int *users) 42 + struct ctl_table *table) 44 43 { 45 44 if (*header == NULL) { 46 45 *header = register_net_sysctl(net, path, table); 47 46 if (*header == NULL) 48 47 return -ENOMEM; 49 48 } 50 - if (users != NULL) 51 - (*users)++; 52 49 53 50 return 0; 54 51 } ··· 53 56 static void 54 57 nf_ct_unregister_sysctl(struct ctl_table_header **header, 55 58 struct ctl_table **table, 56 - unsigned int *users) 59 + unsigned int users) 57 60 { 58 - if (users != NULL && --*users > 0) 61 + if (users > 0) 59 62 return; 60 63 61 64 unregister_net_sysctl_table(*header); ··· 188 191 err = nf_ct_register_sysctl(net, 189 192 &in->ctl_table_header, 190 193 l3proto->ctl_table_path, 191 - in->ctl_table, 192 - NULL); 194 + in->ctl_table); 193 195 if (err < 0) { 194 196 kfree(in->ctl_table); 195 197 in->ctl_table = NULL; ··· 209 213 if (in->ctl_table_header != NULL) 210 214 nf_ct_unregister_sysctl(&in->ctl_table_header, 211 215 &in->ctl_table, 212 - NULL); 216 + 0); 213 217 #endif 214 218 } 215 219 ··· 249 253 { 250 254 int ret = 0; 251 255 252 - if (net == &init_net) 253 - ret = nf_conntrack_l3proto_register_net(proto); 254 - 255 - if (ret < 0) 256 - return ret; 257 - 258 256 if (proto->init_net) { 259 257 ret = proto->init_net(net); 260 258 if (ret < 0) 261 259 return ret; 262 260 } 263 - return nf_ct_l3proto_register_sysctl(net, proto); 261 + 262 + ret = nf_ct_l3proto_register_sysctl(net, proto); 263 + if (ret < 0) 264 + return ret; 265 + 266 + if (net == &init_net) { 267 + ret = nf_conntrack_l3proto_register_net(proto); 268 + if (ret < 0) 269 + nf_ct_l3proto_unregister_sysctl(net, proto); 270 + } 271 + 272 + return ret; 264 273 } 265 274 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); 266 275 ··· 303 302 static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, 304 303 struct nf_conntrack_l4proto *l4proto) 305 304 { 306 - switch (l4proto->l4proto) { 307 - case IPPROTO_TCP: 308 - return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp; 309 - case IPPROTO_UDP: 310 - return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp; 311 - case IPPROTO_ICMP: 312 - return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmp; 313 - case IPPROTO_ICMPV6: 314 - return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmpv6; 315 - case 255: /* l4proto_generic */ 316 - return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; 317 - default: 318 - if (l4proto->net_id) 319 - return net_generic(net, *l4proto->net_id); 320 - else 321 - return NULL; 305 + if (l4proto->get_net_proto) { 306 + /* statically built-in protocols use static per-net */ 307 + return l4proto->get_net_proto(net); 308 + } else if (l4proto->net_id) { 309 + /* ... and loadable protocols use dynamic per-net */ 310 + return net_generic(net, *l4proto->net_id); 322 311 } 323 312 return NULL; 324 313 } 325 314 326 315 static 327 316 int nf_ct_l4proto_register_sysctl(struct net *net, 317 + struct nf_proto_net *pn, 328 318 struct nf_conntrack_l4proto *l4proto) 329 319 { 330 320 int err = 0; 331 - struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); 332 - if (pn == NULL) 333 - return 0; 334 321 335 322 #ifdef CONFIG_SYSCTL 336 323 if (pn->ctl_table != NULL) { 337 324 err = nf_ct_register_sysctl(net, 338 325 &pn->ctl_table_header, 339 326 "net/netfilter", 340 - pn->ctl_table, 341 - &pn->users); 327 + pn->ctl_table); 342 328 if (err < 0) { 343 329 if (!pn->users) { 344 330 kfree(pn->ctl_table); 345 331 pn->ctl_table = NULL; 346 332 } 347 - goto out; 348 333 } 349 334 } 350 335 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 351 336 if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) { 337 + if (err < 0) { 338 + nf_ct_kfree_compat_sysctl_table(pn); 339 + goto out; 340 + } 352 341 err = nf_ct_register_sysctl(net, 353 342 &pn->ctl_compat_header, 354 343 "net/ipv4/netfilter", 355 - pn->ctl_compat_table, 356 - NULL); 344 + pn->ctl_compat_table); 357 345 if (err == 0) 358 346 goto out; 359 347 360 - kfree(pn->ctl_compat_table); 361 - pn->ctl_compat_table = NULL; 348 + nf_ct_kfree_compat_sysctl_table(pn); 362 349 nf_ct_unregister_sysctl(&pn->ctl_table_header, 363 350 &pn->ctl_table, 364 - &pn->users); 351 + pn->users); 365 352 } 366 - #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 367 353 out: 354 + #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 368 355 #endif /* CONFIG_SYSCTL */ 369 356 return err; 370 357 } 371 358 372 359 static 373 360 void nf_ct_l4proto_unregister_sysctl(struct net *net, 361 + struct nf_proto_net *pn, 374 362 struct nf_conntrack_l4proto *l4proto) 375 363 { 376 - struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); 377 - if (pn == NULL) 378 - return; 379 364 #ifdef CONFIG_SYSCTL 380 365 if (pn->ctl_table_header != NULL) 381 366 nf_ct_unregister_sysctl(&pn->ctl_table_header, 382 367 &pn->ctl_table, 383 - &pn->users); 368 + pn->users); 384 369 385 370 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 386 371 if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL) 387 372 nf_ct_unregister_sysctl(&pn->ctl_compat_header, 388 373 &pn->ctl_compat_table, 389 - NULL); 374 + 0); 390 375 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 391 - #else 392 - pn->users--; 393 376 #endif /* CONFIG_SYSCTL */ 394 377 } 395 378 ··· 439 454 struct nf_conntrack_l4proto *l4proto) 440 455 { 441 456 int ret = 0; 442 - if (net == &init_net) 457 + struct nf_proto_net *pn = NULL; 458 + 459 + if (l4proto->init_net) { 460 + ret = l4proto->init_net(net, l4proto->l3proto); 461 + if (ret < 0) 462 + goto out; 463 + } 464 + 465 + pn = nf_ct_l4proto_net(net, l4proto); 466 + if (pn == NULL) 467 + goto out; 468 + 469 + ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto); 470 + if (ret < 0) 471 + goto out; 472 + 473 + if (net == &init_net) { 443 474 ret = nf_conntrack_l4proto_register_net(l4proto); 475 + if (ret < 0) { 476 + nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); 477 + goto out; 478 + } 479 + } 444 480 445 - if (ret < 0) 446 - return ret; 447 - 448 - if (l4proto->init_net) 449 - ret = l4proto->init_net(net); 450 - 451 - if (ret < 0) 452 - return ret; 453 - 454 - return nf_ct_l4proto_register_sysctl(net, l4proto); 481 + pn->users++; 482 + out: 483 + return ret; 455 484 } 456 485 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); 457 486 ··· 489 490 void nf_conntrack_l4proto_unregister(struct net *net, 490 491 struct nf_conntrack_l4proto *l4proto) 491 492 { 493 + struct nf_proto_net *pn = NULL; 494 + 492 495 if (net == &init_net) 493 496 nf_conntrack_l4proto_unregister_net(l4proto); 494 497 495 - nf_ct_l4proto_unregister_sysctl(net, l4proto); 498 + pn = nf_ct_l4proto_net(net, l4proto); 499 + if (pn == NULL) 500 + return; 501 + 502 + pn->users--; 503 + nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); 504 + 496 505 /* Remove all contrack entries for this protocol */ 497 506 rtnl_lock(); 498 507 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); ··· 512 505 { 513 506 unsigned int i; 514 507 int err; 515 - err = nf_conntrack_l4proto_generic.init_net(net); 508 + struct nf_proto_net *pn = nf_ct_l4proto_net(net, 509 + &nf_conntrack_l4proto_generic); 510 + 511 + err = nf_conntrack_l4proto_generic.init_net(net, 512 + nf_conntrack_l4proto_generic.l3proto); 516 513 if (err < 0) 517 514 return err; 518 515 err = nf_ct_l4proto_register_sysctl(net, 516 + pn, 519 517 &nf_conntrack_l4proto_generic); 520 518 if (err < 0) 521 519 return err; ··· 530 518 rcu_assign_pointer(nf_ct_l3protos[i], 531 519 &nf_conntrack_l3proto_generic); 532 520 } 521 + 522 + pn->users++; 533 523 return 0; 534 524 } 535 525 536 526 void nf_conntrack_proto_fini(struct net *net) 537 527 { 538 528 unsigned int i; 529 + struct nf_proto_net *pn = nf_ct_l4proto_net(net, 530 + &nf_conntrack_l4proto_generic); 531 + 532 + pn->users--; 539 533 nf_ct_l4proto_unregister_sysctl(net, 534 + pn, 540 535 &nf_conntrack_l4proto_generic); 541 536 if (net == &init_net) { 542 537 /* free l3proto protocol tables */
+31 -25
net/netfilter/nf_conntrack_proto_dccp.c
··· 387 387 /* this module per-net specifics */ 388 388 static int dccp_net_id __read_mostly; 389 389 struct dccp_net { 390 - struct nf_proto_net np; 390 + struct nf_proto_net pn; 391 391 int dccp_loose; 392 392 unsigned int dccp_timeout[CT_DCCP_MAX + 1]; 393 393 }; ··· 815 815 }; 816 816 #endif /* CONFIG_SYSCTL */ 817 817 818 - static int dccp_init_net(struct net *net) 818 + static int dccp_kmemdup_sysctl_table(struct nf_proto_net *pn, 819 + struct dccp_net *dn) 820 + { 821 + #ifdef CONFIG_SYSCTL 822 + if (pn->ctl_table) 823 + return 0; 824 + 825 + pn->ctl_table = kmemdup(dccp_sysctl_table, 826 + sizeof(dccp_sysctl_table), 827 + GFP_KERNEL); 828 + if (!pn->ctl_table) 829 + return -ENOMEM; 830 + 831 + pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; 832 + pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; 833 + pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; 834 + pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; 835 + pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; 836 + pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; 837 + pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; 838 + pn->ctl_table[7].data = &dn->dccp_loose; 839 + #endif 840 + return 0; 841 + } 842 + 843 + static int dccp_init_net(struct net *net, u_int16_t proto) 819 844 { 820 845 struct dccp_net *dn = dccp_pernet(net); 821 - struct nf_proto_net *pn = (struct nf_proto_net *)dn; 846 + struct nf_proto_net *pn = &dn->pn; 822 847 823 - #ifdef CONFIG_SYSCTL 824 - if (!pn->ctl_table) { 825 - #else 826 - if (!pn->users++) { 827 - #endif 848 + if (!pn->users) { 828 849 /* default values */ 829 850 dn->dccp_loose = 1; 830 851 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL; ··· 855 834 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ; 856 835 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ; 857 836 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL; 858 - #ifdef CONFIG_SYSCTL 859 - pn->ctl_table = kmemdup(dccp_sysctl_table, 860 - sizeof(dccp_sysctl_table), 861 - GFP_KERNEL); 862 - if (!pn->ctl_table) 863 - return -ENOMEM; 864 - 865 - pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; 866 - pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; 867 - pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; 868 - pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; 869 - pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; 870 - pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; 871 - pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; 872 - pn->ctl_table[7].data = &dn->dccp_loose; 873 - #endif 874 837 } 875 - return 0; 838 + 839 + return dccp_kmemdup_sysctl_table(pn, dn); 876 840 } 877 841 878 842 static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
+38 -9
net/netfilter/nf_conntrack_proto_generic.c
··· 135 135 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 136 136 #endif /* CONFIG_SYSCTL */ 137 137 138 - static int generic_init_net(struct net *net) 138 + static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn, 139 + struct nf_generic_net *gn) 139 140 { 140 - struct nf_generic_net *gn = generic_pernet(net); 141 - struct nf_proto_net *pn = (struct nf_proto_net *)gn; 142 - gn->timeout = nf_ct_generic_timeout; 143 141 #ifdef CONFIG_SYSCTL 144 142 pn->ctl_table = kmemdup(generic_sysctl_table, 145 143 sizeof(generic_sysctl_table), 146 144 GFP_KERNEL); 147 145 if (!pn->ctl_table) 148 146 return -ENOMEM; 149 - pn->ctl_table[0].data = &gn->timeout; 150 147 148 + pn->ctl_table[0].data = &gn->timeout; 149 + #endif 150 + return 0; 151 + } 152 + 153 + static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 154 + struct nf_generic_net *gn) 155 + { 156 + #ifdef CONFIG_SYSCTL 151 157 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 152 158 pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table, 153 159 sizeof(generic_compat_sysctl_table), 154 160 GFP_KERNEL); 155 - if (!pn->ctl_compat_table) { 156 - kfree(pn->ctl_table); 157 - pn->ctl_table = NULL; 161 + if (!pn->ctl_compat_table) 158 162 return -ENOMEM; 159 - } 163 + 160 164 pn->ctl_compat_table[0].data = &gn->timeout; 161 165 #endif 162 166 #endif 163 167 return 0; 168 + } 169 + 170 + static int generic_init_net(struct net *net, u_int16_t proto) 171 + { 172 + int ret; 173 + struct nf_generic_net *gn = generic_pernet(net); 174 + struct nf_proto_net *pn = &gn->pn; 175 + 176 + gn->timeout = nf_ct_generic_timeout; 177 + 178 + ret = generic_kmemdup_compat_sysctl_table(pn, gn); 179 + if (ret < 0) 180 + return ret; 181 + 182 + ret = generic_kmemdup_sysctl_table(pn, gn); 183 + if (ret < 0) 184 + nf_ct_kfree_compat_sysctl_table(pn); 185 + 186 + return ret; 187 + } 188 + 189 + static struct nf_proto_net *generic_get_net_proto(struct net *net) 190 + { 191 + return &net->ct.nf_ct_proto.generic.pn; 164 192 } 165 193 166 194 struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = ··· 212 184 }, 213 185 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 214 186 .init_net = generic_init_net, 187 + .get_net_proto = generic_get_net_proto, 215 188 };
+1 -1
net/netfilter/nf_conntrack_proto_gre.c
··· 348 348 }; 349 349 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 350 350 351 - static int gre_init_net(struct net *net) 351 + static int gre_init_net(struct net *net, u_int16_t proto) 352 352 { 353 353 struct netns_proto_gre *net_gre = gre_pernet(net); 354 354 int i;
+24 -45
net/netfilter/nf_conntrack_proto_sctp.c
··· 707 707 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 708 708 #endif 709 709 710 - static void sctp_init_net_data(struct sctp_net *sn) 711 - { 712 - int i; 713 - #ifdef CONFIG_SYSCTL 714 - if (!sn->pn.ctl_table) { 715 - #else 716 - if (!sn->pn.users++) { 717 - #endif 718 - for (i = 0; i < SCTP_CONNTRACK_MAX; i++) 719 - sn->timeouts[i] = sctp_timeouts[i]; 720 - } 721 - } 722 - 723 - static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn) 710 + static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn, 711 + struct sctp_net *sn) 724 712 { 725 713 #ifdef CONFIG_SYSCTL 726 - struct sctp_net *sn = (struct sctp_net *)pn; 727 714 if (pn->ctl_table) 728 715 return 0; 729 716 ··· 731 744 return 0; 732 745 } 733 746 734 - static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) 747 + static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 748 + struct sctp_net *sn) 735 749 { 736 750 #ifdef CONFIG_SYSCTL 737 751 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 738 - struct sctp_net *sn = (struct sctp_net *)pn; 739 752 pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table, 740 753 sizeof(sctp_compat_sysctl_table), 741 754 GFP_KERNEL); ··· 754 767 return 0; 755 768 } 756 769 757 - static int sctpv4_init_net(struct net *net) 770 + static int sctp_init_net(struct net *net, u_int16_t proto) 758 771 { 759 772 int ret; 760 773 struct sctp_net *sn = sctp_pernet(net); 761 - struct nf_proto_net *pn = (struct nf_proto_net *)sn; 774 + struct nf_proto_net *pn = &sn->pn; 762 775 763 - sctp_init_net_data(sn); 776 + if (!pn->users) { 777 + int i; 764 778 765 - ret = sctp_kmemdup_compat_sysctl_table(pn); 766 - if (ret < 0) 767 - return ret; 768 - 769 - ret = sctp_kmemdup_sysctl_table(pn); 770 - 771 - #ifdef CONFIG_SYSCTL 772 - #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 773 - if (ret < 0) { 774 - 775 - kfree(pn->ctl_compat_table); 776 - pn->ctl_compat_table = NULL; 779 + for (i = 0; i < SCTP_CONNTRACK_MAX; i++) 780 + sn->timeouts[i] = sctp_timeouts[i]; 777 781 } 778 - #endif 779 - #endif 782 + 783 + if (proto == AF_INET) { 784 + ret = sctp_kmemdup_compat_sysctl_table(pn, sn); 785 + if (ret < 0) 786 + return ret; 787 + 788 + ret = sctp_kmemdup_sysctl_table(pn, sn); 789 + if (ret < 0) 790 + nf_ct_kfree_compat_sysctl_table(pn); 791 + } else 792 + ret = sctp_kmemdup_sysctl_table(pn, sn); 793 + 780 794 return ret; 781 - } 782 - 783 - static int sctpv6_init_net(struct net *net) 784 - { 785 - struct sctp_net *sn = sctp_pernet(net); 786 - struct nf_proto_net *pn = (struct nf_proto_net *)sn; 787 - 788 - sctp_init_net_data(sn); 789 - return sctp_kmemdup_sysctl_table(pn); 790 795 } 791 796 792 797 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { ··· 812 833 }, 813 834 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 814 835 .net_id = &sctp_net_id, 815 - .init_net = sctpv4_init_net, 836 + .init_net = sctp_init_net, 816 837 }; 817 838 818 839 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { ··· 846 867 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 847 868 #endif 848 869 .net_id = &sctp_net_id, 849 - .init_net = sctpv6_init_net, 870 + .init_net = sctp_init_net, 850 871 }; 851 872 852 873 static int sctp_net_init(struct net *net)
+26 -48
net/netfilter/nf_conntrack_proto_tcp.c
··· 821 821 822 822 static unsigned int *tcp_get_timeouts(struct net *net) 823 823 { 824 - return tcp_timeouts; 824 + return tcp_pernet(net)->timeouts; 825 825 } 826 826 827 827 /* Returns verdict for packet, or -1 for invalid. */ ··· 1533 1533 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 1534 1534 #endif /* CONFIG_SYSCTL */ 1535 1535 1536 - static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn) 1536 + static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn, 1537 + struct nf_tcp_net *tn) 1537 1538 { 1538 1539 #ifdef CONFIG_SYSCTL 1539 - struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; 1540 - 1541 1540 if (pn->ctl_table) 1542 1541 return 0; 1543 1542 ··· 1563 1564 return 0; 1564 1565 } 1565 1566 1566 - static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) 1567 + static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 1568 + struct nf_tcp_net *tn) 1567 1569 { 1568 1570 #ifdef CONFIG_SYSCTL 1569 1571 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 1570 - struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; 1571 1572 pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table, 1572 1573 sizeof(tcp_compat_sysctl_table), 1573 1574 GFP_KERNEL); ··· 1592 1593 return 0; 1593 1594 } 1594 1595 1595 - static int tcpv4_init_net(struct net *net) 1596 + static int tcp_init_net(struct net *net, u_int16_t proto) 1596 1597 { 1597 - int i; 1598 - int ret = 0; 1598 + int ret; 1599 1599 struct nf_tcp_net *tn = tcp_pernet(net); 1600 - struct nf_proto_net *pn = (struct nf_proto_net *)tn; 1600 + struct nf_proto_net *pn = &tn->pn; 1601 1601 1602 - #ifdef CONFIG_SYSCTL 1603 - if (!pn->ctl_table) { 1604 - #else 1605 - if (!pn->users++) { 1606 - #endif 1602 + if (!pn->users) { 1603 + int i; 1604 + 1607 1605 for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) 1608 1606 tn->timeouts[i] = tcp_timeouts[i]; 1609 1607 ··· 1609 1613 tn->tcp_max_retrans = nf_ct_tcp_max_retrans; 1610 1614 } 1611 1615 1612 - ret = tcp_kmemdup_compat_sysctl_table(pn); 1616 + if (proto == AF_INET) { 1617 + ret = tcp_kmemdup_compat_sysctl_table(pn, tn); 1618 + if (ret < 0) 1619 + return ret; 1613 1620 1614 - if (ret < 0) 1615 - return ret; 1621 + ret = tcp_kmemdup_sysctl_table(pn, tn); 1622 + if (ret < 0) 1623 + nf_ct_kfree_compat_sysctl_table(pn); 1624 + } else 1625 + ret = tcp_kmemdup_sysctl_table(pn, tn); 1616 1626 1617 - ret = tcp_kmemdup_sysctl_table(pn); 1618 - 1619 - #ifdef CONFIG_SYSCTL 1620 - #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 1621 - if (ret < 0) { 1622 - kfree(pn->ctl_compat_table); 1623 - pn->ctl_compat_table = NULL; 1624 - } 1625 - #endif 1626 - #endif 1627 1627 return ret; 1628 1628 } 1629 1629 1630 - static int tcpv6_init_net(struct net *net) 1630 + static struct nf_proto_net *tcp_get_net_proto(struct net *net) 1631 1631 { 1632 - int i; 1633 - struct nf_tcp_net *tn = tcp_pernet(net); 1634 - struct nf_proto_net *pn = (struct nf_proto_net *)tn; 1635 - 1636 - #ifdef CONFIG_SYSCTL 1637 - if (!pn->ctl_table) { 1638 - #else 1639 - if (!pn->users++) { 1640 - #endif 1641 - for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) 1642 - tn->timeouts[i] = tcp_timeouts[i]; 1643 - tn->tcp_loose = nf_ct_tcp_loose; 1644 - tn->tcp_be_liberal = nf_ct_tcp_be_liberal; 1645 - tn->tcp_max_retrans = nf_ct_tcp_max_retrans; 1646 - } 1647 - 1648 - return tcp_kmemdup_sysctl_table(pn); 1632 + return &net->ct.nf_ct_proto.tcp.pn; 1649 1633 } 1650 1634 1651 1635 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = ··· 1660 1684 .nla_policy = tcp_timeout_nla_policy, 1661 1685 }, 1662 1686 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 1663 - .init_net = tcpv4_init_net, 1687 + .init_net = tcp_init_net, 1688 + .get_net_proto = tcp_get_net_proto, 1664 1689 }; 1665 1690 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4); 1666 1691 ··· 1697 1720 .nla_policy = tcp_timeout_nla_policy, 1698 1721 }, 1699 1722 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 1700 - .init_net = tcpv6_init_net, 1723 + .init_net = tcp_init_net, 1724 + .get_net_proto = tcp_get_net_proto, 1701 1725 }; 1702 1726 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
+28 -40
net/netfilter/nf_conntrack_proto_udp.c
··· 235 235 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 236 236 #endif /* CONFIG_SYSCTL */ 237 237 238 - static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn) 238 + static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn, 239 + struct nf_udp_net *un) 239 240 { 240 241 #ifdef CONFIG_SYSCTL 241 - struct nf_udp_net *un = (struct nf_udp_net *)pn; 242 242 if (pn->ctl_table) 243 243 return 0; 244 244 pn->ctl_table = kmemdup(udp_sysctl_table, ··· 252 252 return 0; 253 253 } 254 254 255 - static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) 255 + static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 256 + struct nf_udp_net *un) 256 257 { 257 258 #ifdef CONFIG_SYSCTL 258 259 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 259 - struct nf_udp_net *un = (struct nf_udp_net *)pn; 260 260 pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table, 261 261 sizeof(udp_compat_sysctl_table), 262 262 GFP_KERNEL); ··· 270 270 return 0; 271 271 } 272 272 273 - static void udp_init_net_data(struct nf_udp_net *un) 274 - { 275 - int i; 276 - #ifdef CONFIG_SYSCTL 277 - if (!un->pn.ctl_table) { 278 - #else 279 - if (!un->pn.users++) { 280 - #endif 281 - for (i = 0; i < UDP_CT_MAX; i++) 282 - un->timeouts[i] = udp_timeouts[i]; 283 - } 284 - } 285 - 286 - static int udpv4_init_net(struct net *net) 273 + static int udp_init_net(struct net *net, u_int16_t proto) 287 274 { 288 275 int ret; 289 276 struct nf_udp_net *un = udp_pernet(net); 290 - struct nf_proto_net *pn = (struct nf_proto_net *)un; 277 + struct nf_proto_net *pn = &un->pn; 291 278 292 - udp_init_net_data(un); 279 + if (!pn->users) { 280 + int i; 293 281 294 - ret = udp_kmemdup_compat_sysctl_table(pn); 295 - if (ret < 0) 296 - return ret; 297 - 298 - ret = udp_kmemdup_sysctl_table(pn); 299 - #ifdef CONFIG_SYSCTL 300 - #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 301 - if (ret < 0) { 302 - kfree(pn->ctl_compat_table); 303 - pn->ctl_compat_table = NULL; 282 + for (i = 0; i < UDP_CT_MAX; i++) 283 + un->timeouts[i] = udp_timeouts[i]; 304 284 } 305 - #endif 306 - #endif 285 + 286 + if (proto == AF_INET) { 287 + ret = udp_kmemdup_compat_sysctl_table(pn, un); 288 + if (ret < 0) 289 + return ret; 290 + 291 + ret = udp_kmemdup_sysctl_table(pn, un); 292 + if (ret < 0) 293 + nf_ct_kfree_compat_sysctl_table(pn); 294 + } else 295 + ret = udp_kmemdup_sysctl_table(pn, un); 296 + 307 297 return ret; 308 298 } 309 299 310 - static int udpv6_init_net(struct net *net) 300 + static struct nf_proto_net *udp_get_net_proto(struct net *net) 311 301 { 312 - struct nf_udp_net *un = udp_pernet(net); 313 - struct nf_proto_net *pn = (struct nf_proto_net *)un; 314 - 315 - udp_init_net_data(un); 316 - return udp_kmemdup_sysctl_table(pn); 302 + return &net->ct.nf_ct_proto.udp.pn; 317 303 } 318 304 319 305 struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = ··· 329 343 .nla_policy = udp_timeout_nla_policy, 330 344 }, 331 345 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 332 - .init_net = udpv4_init_net, 346 + .init_net = udp_init_net, 347 + .get_net_proto = udp_get_net_proto, 333 348 }; 334 349 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4); 335 350 ··· 361 374 .nla_policy = udp_timeout_nla_policy, 362 375 }, 363 376 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 364 - .init_net = udpv6_init_net, 377 + .init_net = udp_init_net, 378 + .get_net_proto = udp_get_net_proto, 365 379 }; 366 380 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
+26 -17
net/netfilter/nf_conntrack_proto_udplite.c
··· 234 234 }; 235 235 #endif /* CONFIG_SYSCTL */ 236 236 237 - static int udplite_init_net(struct net *net) 237 + static int udplite_kmemdup_sysctl_table(struct nf_proto_net *pn, 238 + struct udplite_net *un) 238 239 { 239 - int i; 240 - struct udplite_net *un = udplite_pernet(net); 241 - struct nf_proto_net *pn = (struct nf_proto_net *)un; 242 240 #ifdef CONFIG_SYSCTL 243 - if (!pn->ctl_table) { 244 - #else 245 - if (!pn->users++) { 241 + if (pn->ctl_table) 242 + return 0; 243 + 244 + pn->ctl_table = kmemdup(udplite_sysctl_table, 245 + sizeof(udplite_sysctl_table), 246 + GFP_KERNEL); 247 + if (!pn->ctl_table) 248 + return -ENOMEM; 249 + 250 + pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED]; 251 + pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED]; 246 252 #endif 253 + return 0; 254 + } 255 + 256 + static int udplite_init_net(struct net *net, u_int16_t proto) 257 + { 258 + struct udplite_net *un = udplite_pernet(net); 259 + struct nf_proto_net *pn = &un->pn; 260 + 261 + if (!pn->users) { 262 + int i; 263 + 247 264 for (i = 0 ; i < UDPLITE_CT_MAX; i++) 248 265 un->timeouts[i] = udplite_timeouts[i]; 249 - #ifdef CONFIG_SYSCTL 250 - pn->ctl_table = kmemdup(udplite_sysctl_table, 251 - sizeof(udplite_sysctl_table), 252 - GFP_KERNEL); 253 - if (!pn->ctl_table) 254 - return -ENOMEM; 255 - pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED]; 256 - pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED]; 257 - #endif 258 266 } 259 - return 0; 267 + 268 + return udplite_kmemdup_sysctl_table(pn, un); 260 269 } 261 270 262 271 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
+3 -1
net/netfilter/nfnetlink.c
··· 195 195 lockdep_is_held(&nfnl_mutex)) != ss || 196 196 nfnetlink_find_client(type, ss) != nc) 197 197 err = -EAGAIN; 198 - else 198 + else if (nc->call) 199 199 err = nc->call(net->nfnl, skb, nlh, 200 200 (const struct nlattr **)cda); 201 + else 202 + err = -EINVAL; 201 203 nfnl_unlock(); 202 204 } 203 205 if (err == -EAGAIN)