Merge branch 'master' of git://1984.lsi.us.es/net-next
This commit is contained in:
Коммит
67da255210
|
@ -414,21 +414,6 @@ Who: Jean Delvare <khali@linux-fr.org>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: xt_connlimit rev 0
|
||||
When: 2012
|
||||
Who: Jan Engelhardt <jengelh@medozas.de>
|
||||
Files: net/netfilter/xt_connlimit.c
|
||||
|
||||
----------------------------
|
||||
|
||||
What: ipt_addrtype match include file
|
||||
When: 2012
|
||||
Why: superseded by xt_addrtype
|
||||
Who: Florian Westphal <fw@strlen.de>
|
||||
Files: include/linux/netfilter_ipv4/ipt_addrtype.h
|
||||
|
||||
----------------------------
|
||||
|
||||
What: i2c_driver.attach_adapter
|
||||
i2c_driver.detach_adapter
|
||||
When: September 2011
|
||||
|
@ -589,6 +574,13 @@ Why: Remount currently allows changing bound subsystems and
|
|||
|
||||
----------------------------
|
||||
|
||||
What: xt_recent rev 0
|
||||
When: 2013
|
||||
Who: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Files: net/netfilter/xt_recent.c
|
||||
|
||||
----------------------------
|
||||
|
||||
What: KVM debugfs statistics
|
||||
When: 2013
|
||||
Why: KVM tracepoints provide mostly equivalent information in a much more
|
||||
|
|
|
@ -94,6 +94,16 @@ static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1,
|
|||
a1->all[3] == a2->all[3];
|
||||
}
|
||||
|
||||
static inline void nf_inet_addr_mask(const union nf_inet_addr *a1,
|
||||
union nf_inet_addr *result,
|
||||
const union nf_inet_addr *mask)
|
||||
{
|
||||
result->all[0] = a1->all[0] & mask->all[0];
|
||||
result->all[1] = a1->all[1] & mask->all[1];
|
||||
result->all[2] = a1->all[2] & mask->all[2];
|
||||
result->all[3] = a1->all[3] & mask->all[3];
|
||||
}
|
||||
|
||||
extern void netfilter_init(void);
|
||||
|
||||
/* Largest hook number + 1 */
|
||||
|
|
|
@ -84,8 +84,13 @@ enum nfqnl_attr_config {
|
|||
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
|
||||
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
|
||||
NFQA_CFG_QUEUE_MAXLEN, /* __u32 */
|
||||
NFQA_CFG_MASK, /* identify which flags to change */
|
||||
NFQA_CFG_FLAGS, /* value of these flags (__u32) */
|
||||
__NFQA_CFG_MAX
|
||||
};
|
||||
#define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
|
||||
|
||||
/* Flags for NFQA_CFG_FLAGS */
|
||||
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
|
||||
|
||||
#endif /* _NFNETLINK_QUEUE_H */
|
||||
|
|
|
@ -22,13 +22,8 @@ struct xt_connlimit_info {
|
|||
#endif
|
||||
};
|
||||
unsigned int limit;
|
||||
union {
|
||||
/* revision 0 */
|
||||
unsigned int inverse;
|
||||
|
||||
/* revision 1 */
|
||||
__u32 flags;
|
||||
};
|
||||
/* revision 1 */
|
||||
__u32 flags;
|
||||
|
||||
/* Used internally by the kernel */
|
||||
struct xt_connlimit_data *data __attribute__((aligned(8)));
|
||||
|
|
|
@ -32,4 +32,14 @@ struct xt_recent_mtinfo {
|
|||
__u8 side;
|
||||
};
|
||||
|
||||
struct xt_recent_mtinfo_v1 {
|
||||
__u32 seconds;
|
||||
__u32 hit_count;
|
||||
__u8 check_set;
|
||||
__u8 invert;
|
||||
char name[XT_RECENT_NAME_LEN];
|
||||
__u8 side;
|
||||
union nf_inet_addr mask;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_RECENT_H */
|
||||
|
|
|
@ -5,7 +5,6 @@ header-y += ipt_LOG.h
|
|||
header-y += ipt_REJECT.h
|
||||
header-y += ipt_TTL.h
|
||||
header-y += ipt_ULOG.h
|
||||
header-y += ipt_addrtype.h
|
||||
header-y += ipt_ah.h
|
||||
header-y += ipt_ecn.h
|
||||
header-y += ipt_ttl.h
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef _IPT_ADDRTYPE_H
|
||||
#define _IPT_ADDRTYPE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum {
|
||||
IPT_ADDRTYPE_INVERT_SOURCE = 0x0001,
|
||||
IPT_ADDRTYPE_INVERT_DEST = 0x0002,
|
||||
IPT_ADDRTYPE_LIMIT_IFACE_IN = 0x0004,
|
||||
IPT_ADDRTYPE_LIMIT_IFACE_OUT = 0x0008,
|
||||
};
|
||||
|
||||
struct ipt_addrtype_info_v1 {
|
||||
__u16 source; /* source-type mask */
|
||||
__u16 dest; /* dest-type mask */
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
/* revision 0 */
|
||||
struct ipt_addrtype_info {
|
||||
__u16 source; /* source-type mask */
|
||||
__u16 dest; /* dest-type mask */
|
||||
__u32 invert_source;
|
||||
__u32 invert_dest;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -28,8 +28,8 @@ extern unsigned int nf_conntrack_in(struct net *net,
|
|||
extern int nf_conntrack_init(struct net *net);
|
||||
extern void nf_conntrack_cleanup(struct net *net);
|
||||
|
||||
extern int nf_conntrack_proto_init(void);
|
||||
extern void nf_conntrack_proto_fini(void);
|
||||
extern int nf_conntrack_proto_init(struct net *net);
|
||||
extern void nf_conntrack_proto_fini(struct net *net);
|
||||
|
||||
extern bool
|
||||
nf_ct_get_tuple(const struct sk_buff *skb,
|
||||
|
|
|
@ -64,11 +64,12 @@ struct nf_conntrack_l3proto {
|
|||
size_t nla_size;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *ctl_table_header;
|
||||
const char *ctl_table_path;
|
||||
struct ctl_table *ctl_table;
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
/* Init l3proto pernet data */
|
||||
int (*init_net)(struct net *net);
|
||||
|
||||
/* Module (if any) which this is connected to. */
|
||||
struct module *me;
|
||||
};
|
||||
|
@ -76,8 +77,10 @@ struct nf_conntrack_l3proto {
|
|||
extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
|
||||
|
||||
/* Protocol registration. */
|
||||
extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
|
||||
extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
|
||||
extern int nf_conntrack_l3proto_register(struct net *net,
|
||||
struct nf_conntrack_l3proto *proto);
|
||||
extern void nf_conntrack_l3proto_unregister(struct net *net,
|
||||
struct nf_conntrack_l3proto *proto);
|
||||
extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
|
||||
extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/netlink.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
struct seq_file;
|
||||
|
||||
|
@ -86,23 +87,18 @@ struct nf_conntrack_l4proto {
|
|||
#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
|
||||
struct {
|
||||
size_t obj_size;
|
||||
int (*nlattr_to_obj)(struct nlattr *tb[], void *data);
|
||||
int (*nlattr_to_obj)(struct nlattr *tb[],
|
||||
struct net *net, void *data);
|
||||
int (*obj_to_nlattr)(struct sk_buff *skb, const void *data);
|
||||
|
||||
unsigned int nlattr_max;
|
||||
const struct nla_policy *nla_policy;
|
||||
} ctnl_timeout;
|
||||
#endif
|
||||
int *net_id;
|
||||
/* Init l4proto pernet data */
|
||||
int (*init_net)(struct net *net);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header **ctl_table_header;
|
||||
struct ctl_table *ctl_table;
|
||||
unsigned int *ctl_table_users;
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct ctl_table_header *ctl_compat_table_header;
|
||||
struct ctl_table *ctl_compat_table;
|
||||
#endif
|
||||
#endif
|
||||
/* Protocol name */
|
||||
const char *name;
|
||||
|
||||
|
@ -123,8 +119,10 @@ nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
|
|||
extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
|
||||
|
||||
/* Protocol registration. */
|
||||
extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
|
||||
extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
|
||||
extern int nf_conntrack_l4proto_register(struct net *net,
|
||||
struct nf_conntrack_l4proto *proto);
|
||||
extern void nf_conntrack_l4proto_unregister(struct net *net,
|
||||
struct nf_conntrack_l4proto *proto);
|
||||
|
||||
/* Generic netlink helpers */
|
||||
extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
|
||||
|
|
|
@ -4,10 +4,64 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/list_nulls.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/netfilter/nf_conntrack_tcp.h>
|
||||
|
||||
struct ctl_table_header;
|
||||
struct nf_conntrack_ecache;
|
||||
|
||||
struct nf_proto_net {
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *ctl_table_header;
|
||||
struct ctl_table *ctl_table;
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct ctl_table_header *ctl_compat_header;
|
||||
struct ctl_table *ctl_compat_table;
|
||||
#endif
|
||||
#endif
|
||||
unsigned int users;
|
||||
};
|
||||
|
||||
struct nf_generic_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeout;
|
||||
};
|
||||
|
||||
struct nf_tcp_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX];
|
||||
unsigned int tcp_loose;
|
||||
unsigned int tcp_be_liberal;
|
||||
unsigned int tcp_max_retrans;
|
||||
};
|
||||
|
||||
enum udp_conntrack {
|
||||
UDP_CT_UNREPLIED,
|
||||
UDP_CT_REPLIED,
|
||||
UDP_CT_MAX
|
||||
};
|
||||
|
||||
struct nf_udp_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeouts[UDP_CT_MAX];
|
||||
};
|
||||
|
||||
struct nf_icmp_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeout;
|
||||
};
|
||||
|
||||
struct nf_ip_net {
|
||||
struct nf_generic_net generic;
|
||||
struct nf_tcp_net tcp;
|
||||
struct nf_udp_net udp;
|
||||
struct nf_icmp_net icmp;
|
||||
struct nf_icmp_net icmpv6;
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
struct ctl_table_header *ctl_table_header;
|
||||
struct ctl_table *ctl_table;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct netns_ct {
|
||||
atomic_t count;
|
||||
unsigned int expect_count;
|
||||
|
@ -28,6 +82,7 @@ struct netns_ct {
|
|||
unsigned int sysctl_log_invalid; /* Log invalid packets */
|
||||
int sysctl_auto_assign_helper;
|
||||
bool auto_assign_helper_warned;
|
||||
struct nf_ip_net nf_ct_proto;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *sysctl_header;
|
||||
struct ctl_table_header *acct_sysctl_header;
|
||||
|
|
|
@ -764,9 +764,9 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
|
|||
return NF_DROP;
|
||||
|
||||
if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb))
|
||||
pf = PF_INET;
|
||||
pf = NFPROTO_IPV4;
|
||||
else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb))
|
||||
pf = PF_INET6;
|
||||
pf = NFPROTO_IPV6;
|
||||
else
|
||||
return NF_ACCEPT;
|
||||
|
||||
|
@ -778,13 +778,13 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
|
|||
nf_bridge->mask |= BRNF_PKT_TYPE;
|
||||
}
|
||||
|
||||
if (pf == PF_INET && br_parse_ip_options(skb))
|
||||
if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb))
|
||||
return NF_DROP;
|
||||
|
||||
/* The physdev module checks on this */
|
||||
nf_bridge->mask |= BRNF_BRIDGED;
|
||||
nf_bridge->physoutdev = skb->dev;
|
||||
if (pf == PF_INET)
|
||||
if (pf == NFPROTO_IPV4)
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
else
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
|
@ -871,9 +871,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
|
|||
return NF_DROP;
|
||||
|
||||
if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb))
|
||||
pf = PF_INET;
|
||||
pf = NFPROTO_IPV4;
|
||||
else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb))
|
||||
pf = PF_INET6;
|
||||
pf = NFPROTO_IPV6;
|
||||
else
|
||||
return NF_ACCEPT;
|
||||
|
||||
|
@ -886,7 +886,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
|
|||
|
||||
nf_bridge_pull_encap_header(skb);
|
||||
nf_bridge_save_header(skb);
|
||||
if (pf == PF_INET)
|
||||
if (pf == NFPROTO_IPV4)
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
else
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
|
@ -919,49 +919,49 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = br_nf_pre_routing,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_BRIDGE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_PRE_ROUTING,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_local_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_BRIDGE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_LOCAL_IN,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_forward_ip,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_BRIDGE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_FORWARD,
|
||||
.priority = NF_BR_PRI_BRNF - 1,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_forward_arp,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_BRIDGE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_FORWARD,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_post_routing,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_BRIDGE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_POST_ROUTING,
|
||||
.priority = NF_BR_PRI_LAST,
|
||||
},
|
||||
{
|
||||
.hook = ip_sabotage_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_FIRST,
|
||||
},
|
||||
{
|
||||
.hook = ip_sabotage_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
},
|
||||
|
|
|
@ -117,7 +117,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
|
|||
|
||||
static struct nf_hook_ops dnrmg_ops __read_mostly = {
|
||||
.hook = dnrmg_hook,
|
||||
.pf = PF_DECnet,
|
||||
.pf = NFPROTO_DECNET,
|
||||
.hooknum = NF_DN_ROUTE,
|
||||
.priority = NF_DN_PRI_DNRTMSG,
|
||||
};
|
||||
|
|
|
@ -207,35 +207,30 @@ static int log_invalid_proto_max = 255;
|
|||
static ctl_table ip_ct_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_max",
|
||||
.data = &nf_conntrack_max,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_count",
|
||||
.data = &init_net.ct.count,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_buckets",
|
||||
.data = &init_net.ct.htable_size,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_checksum",
|
||||
.data = &init_net.ct.sysctl_checksum,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_log_invalid",
|
||||
.data = &init_net.ct.sysctl_log_invalid,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
|
@ -351,6 +346,25 @@ static struct nf_sockopt_ops so_getorigdst = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ipv4_init_net(struct net *net)
|
||||
{
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
struct nf_ip_net *in = &net->ct.nf_ct_proto;
|
||||
in->ctl_table = kmemdup(ip_ct_sysctl_table,
|
||||
sizeof(ip_ct_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!in->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
in->ctl_table[0].data = &nf_conntrack_max;
|
||||
in->ctl_table[1].data = &net->ct.count;
|
||||
in->ctl_table[2].data = &net->ct.htable_size;
|
||||
in->ctl_table[3].data = &net->ct.sysctl_checksum;
|
||||
in->ctl_table[4].data = &net->ct.sysctl_log_invalid;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
|
||||
.l3proto = PF_INET,
|
||||
.name = "ipv4",
|
||||
|
@ -366,8 +380,8 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
|
|||
#endif
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
.ctl_table_path = "net/ipv4/netfilter",
|
||||
.ctl_table = ip_ct_sysctl_table,
|
||||
#endif
|
||||
.init_net = ipv4_init_net,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -378,6 +392,65 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
|
|||
MODULE_ALIAS("ip_conntrack");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int ipv4_net_init(struct net *net)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_tcp4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_tcp4 :protocol register failed\n");
|
||||
goto out_tcp;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_udp4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_udp4 :protocol register failed\n");
|
||||
goto out_udp;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_icmp);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n");
|
||||
goto out_icmp;
|
||||
}
|
||||
ret = nf_conntrack_l3proto_register(net,
|
||||
&nf_conntrack_l3proto_ipv4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l3proto_ipv4 :protocol register failed\n");
|
||||
goto out_ipv4;
|
||||
}
|
||||
return 0;
|
||||
out_ipv4:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_icmp);
|
||||
out_icmp:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_udp4);
|
||||
out_udp:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_tcp4);
|
||||
out_tcp:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ipv4_net_exit(struct net *net)
|
||||
{
|
||||
nf_conntrack_l3proto_unregister(net,
|
||||
&nf_conntrack_l3proto_ipv4);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_icmp);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_udp4);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_tcp4);
|
||||
}
|
||||
|
||||
static struct pernet_operations ipv4_net_ops = {
|
||||
.init = ipv4_net_init,
|
||||
.exit = ipv4_net_exit,
|
||||
};
|
||||
|
||||
static int __init nf_conntrack_l3proto_ipv4_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -391,35 +464,17 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4);
|
||||
ret = register_pernet_subsys(&ipv4_net_ops);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv4: can't register tcp.\n");
|
||||
pr_err("nf_conntrack_ipv4: can't register pernet ops\n");
|
||||
goto cleanup_sockopt;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv4: can't register udp.\n");
|
||||
goto cleanup_tcp;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv4: can't register icmp.\n");
|
||||
goto cleanup_udp;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv4: can't register ipv4\n");
|
||||
goto cleanup_icmp;
|
||||
}
|
||||
|
||||
ret = nf_register_hooks(ipv4_conntrack_ops,
|
||||
ARRAY_SIZE(ipv4_conntrack_ops));
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv4: can't register hooks.\n");
|
||||
goto cleanup_ipv4;
|
||||
goto cleanup_pernet;
|
||||
}
|
||||
#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
ret = nf_conntrack_ipv4_compat_init();
|
||||
|
@ -431,14 +486,8 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
|
|||
cleanup_hooks:
|
||||
nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
|
||||
#endif
|
||||
cleanup_ipv4:
|
||||
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
|
||||
cleanup_icmp:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
|
||||
cleanup_udp:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
|
||||
cleanup_tcp:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
|
||||
cleanup_pernet:
|
||||
unregister_pernet_subsys(&ipv4_net_ops);
|
||||
cleanup_sockopt:
|
||||
nf_unregister_sockopt(&so_getorigdst);
|
||||
return ret;
|
||||
|
@ -451,10 +500,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
|
|||
nf_conntrack_ipv4_compat_fini();
|
||||
#endif
|
||||
nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
|
||||
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
|
||||
unregister_pernet_subsys(&ipv4_net_ops);
|
||||
nf_unregister_sockopt(&so_getorigdst);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
|
||||
static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ;
|
||||
|
||||
static inline struct nf_icmp_net *icmp_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.icmp;
|
||||
}
|
||||
|
||||
static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
|
@ -77,7 +82,7 @@ static int icmp_print_tuple(struct seq_file *s,
|
|||
|
||||
static unsigned int *icmp_get_timeouts(struct net *net)
|
||||
{
|
||||
return &nf_ct_icmp_timeout;
|
||||
return &icmp_pernet(net)->timeout;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -1 for invalid. */
|
||||
|
@ -274,16 +279,18 @@ static int icmp_nlattr_tuple_size(void)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeout = data;
|
||||
struct nf_icmp_net *in = icmp_pernet(net);
|
||||
|
||||
if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) {
|
||||
*timeout =
|
||||
ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) * HZ;
|
||||
} else {
|
||||
/* Set default ICMP timeout. */
|
||||
*timeout = nf_ct_icmp_timeout;
|
||||
*timeout = in->timeout;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -308,11 +315,9 @@ icmp_timeout_nla_policy[CTA_TIMEOUT_ICMP_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table_header *icmp_sysctl_header;
|
||||
static struct ctl_table icmp_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_icmp_timeout",
|
||||
.data = &nf_ct_icmp_timeout,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -323,7 +328,6 @@ static struct ctl_table icmp_sysctl_table[] = {
|
|||
static struct ctl_table icmp_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_icmp_timeout",
|
||||
.data = &nf_ct_icmp_timeout,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -333,6 +337,34 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
|
|||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int icmp_init_net(struct net *net)
|
||||
{
|
||||
struct nf_icmp_net *in = icmp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)in;
|
||||
in->timeout = nf_ct_icmp_timeout;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
pn->ctl_table = kmemdup(icmp_sysctl_table,
|
||||
sizeof(icmp_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
pn->ctl_table[0].data = &in->timeout;
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table,
|
||||
sizeof(icmp_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table) {
|
||||
kfree(pn->ctl_table);
|
||||
pn->ctl_table = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
pn->ctl_compat_table[0].data = &in->timeout;
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
|
||||
{
|
||||
.l3proto = PF_INET,
|
||||
|
@ -362,11 +394,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
|
|||
.nla_policy = icmp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_header = &icmp_sysctl_header,
|
||||
.ctl_table = icmp_sysctl_table,
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
.ctl_compat_table = icmp_compat_sysctl_table,
|
||||
#endif
|
||||
#endif
|
||||
.init_net = icmp_init_net,
|
||||
};
|
||||
|
|
|
@ -94,14 +94,14 @@ static struct nf_hook_ops ipv4_defrag_ops[] = {
|
|||
{
|
||||
.hook = ipv4_conntrack_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_conntrack_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
|
|
|
@ -333,6 +333,65 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
|
||||
|
||||
static int ipv6_net_init(struct net *net)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_tcp6);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_udp6);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n");
|
||||
goto cleanup_tcp6;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_icmpv6);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
|
||||
goto cleanup_udp6;
|
||||
}
|
||||
ret = nf_conntrack_l3proto_register(net,
|
||||
&nf_conntrack_l3proto_ipv6);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n");
|
||||
goto cleanup_icmpv6;
|
||||
}
|
||||
return 0;
|
||||
cleanup_icmpv6:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_icmpv6);
|
||||
cleanup_udp6:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_udp6);
|
||||
cleanup_tcp6:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_tcp6);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ipv6_net_exit(struct net *net)
|
||||
{
|
||||
nf_conntrack_l3proto_unregister(net,
|
||||
&nf_conntrack_l3proto_ipv6);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_icmpv6);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_udp6);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_tcp6);
|
||||
}
|
||||
|
||||
static struct pernet_operations ipv6_net_ops = {
|
||||
.init = ipv6_net_init,
|
||||
.exit = ipv6_net_exit,
|
||||
};
|
||||
|
||||
static int __init nf_conntrack_l3proto_ipv6_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -340,30 +399,9 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
|
|||
need_conntrack();
|
||||
nf_defrag_ipv6_enable();
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv6: can't register tcp.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv6: can't register udp.\n");
|
||||
goto cleanup_tcp;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv6: can't register icmpv6.\n");
|
||||
goto cleanup_udp;
|
||||
}
|
||||
|
||||
ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_ipv6: can't register ipv6\n");
|
||||
goto cleanup_icmpv6;
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&ipv6_net_ops);
|
||||
if (ret < 0)
|
||||
goto cleanup_pernet;
|
||||
ret = nf_register_hooks(ipv6_conntrack_ops,
|
||||
ARRAY_SIZE(ipv6_conntrack_ops));
|
||||
if (ret < 0) {
|
||||
|
@ -374,13 +412,8 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
|
|||
return ret;
|
||||
|
||||
cleanup_ipv6:
|
||||
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
|
||||
cleanup_icmpv6:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
|
||||
cleanup_udp:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
|
||||
cleanup_tcp:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
|
||||
unregister_pernet_subsys(&ipv6_net_ops);
|
||||
cleanup_pernet:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -388,10 +421,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
|
|||
{
|
||||
synchronize_net();
|
||||
nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
|
||||
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
|
||||
unregister_pernet_subsys(&ipv6_net_ops);
|
||||
}
|
||||
|
||||
module_init(nf_conntrack_l3proto_ipv6_init);
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
|
||||
static unsigned int nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
|
||||
|
||||
static inline struct nf_icmp_net *icmpv6_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.icmpv6;
|
||||
}
|
||||
|
||||
static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
|
@ -90,7 +95,7 @@ static int icmpv6_print_tuple(struct seq_file *s,
|
|||
|
||||
static unsigned int *icmpv6_get_timeouts(struct net *net)
|
||||
{
|
||||
return &nf_ct_icmpv6_timeout;
|
||||
return &icmpv6_pernet(net)->timeout;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -1 for invalid. */
|
||||
|
@ -281,16 +286,18 @@ static int icmpv6_nlattr_tuple_size(void)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeout = data;
|
||||
struct nf_icmp_net *in = icmpv6_pernet(net);
|
||||
|
||||
if (tb[CTA_TIMEOUT_ICMPV6_TIMEOUT]) {
|
||||
*timeout =
|
||||
ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMPV6_TIMEOUT])) * HZ;
|
||||
} else {
|
||||
/* Set default ICMPv6 timeout. */
|
||||
*timeout = nf_ct_icmpv6_timeout;
|
||||
*timeout = in->timeout;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,11 +322,9 @@ icmpv6_timeout_nla_policy[CTA_TIMEOUT_ICMPV6_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table_header *icmpv6_sysctl_header;
|
||||
static struct ctl_table icmpv6_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_icmpv6_timeout",
|
||||
.data = &nf_ct_icmpv6_timeout,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -328,6 +333,22 @@ static struct ctl_table icmpv6_sysctl_table[] = {
|
|||
};
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int icmpv6_init_net(struct net *net)
|
||||
{
|
||||
struct nf_icmp_net *in = icmpv6_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)in;
|
||||
in->timeout = nf_ct_icmpv6_timeout;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
pn->ctl_table = kmemdup(icmpv6_sysctl_table,
|
||||
sizeof(icmpv6_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
pn->ctl_table[0].data = &in->timeout;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
|
||||
{
|
||||
.l3proto = PF_INET6,
|
||||
|
@ -355,8 +376,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
|
|||
.nla_policy = icmpv6_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_header = &icmpv6_sysctl_header,
|
||||
.ctl_table = icmpv6_sysctl_table,
|
||||
#endif
|
||||
.init_net = icmpv6_init_net,
|
||||
};
|
||||
|
|
|
@ -1742,7 +1742,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC - 2,
|
||||
},
|
||||
|
@ -1752,7 +1752,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_remote_request4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC - 1,
|
||||
},
|
||||
|
@ -1760,7 +1760,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_local_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_NAT_DST + 1,
|
||||
},
|
||||
|
@ -1768,7 +1768,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_local_request4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_NAT_DST + 2,
|
||||
},
|
||||
|
@ -1777,7 +1777,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_forward_icmp,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 99,
|
||||
},
|
||||
|
@ -1785,7 +1785,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 100,
|
||||
},
|
||||
|
@ -1794,7 +1794,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_NAT_SRC - 2,
|
||||
},
|
||||
|
@ -1804,7 +1804,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_remote_request6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_NAT_SRC - 1,
|
||||
},
|
||||
|
@ -1812,7 +1812,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_local_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_NAT_DST + 1,
|
||||
},
|
||||
|
@ -1820,7 +1820,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_local_request6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_NAT_DST + 2,
|
||||
},
|
||||
|
@ -1829,7 +1829,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_forward_icmp_v6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 99,
|
||||
},
|
||||
|
@ -1837,7 +1837,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
|||
{
|
||||
.hook = ip_vs_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 100,
|
||||
},
|
||||
|
|
|
@ -1333,7 +1333,6 @@ static void nf_conntrack_cleanup_init_net(void)
|
|||
while (untrack_refs() > 0)
|
||||
schedule();
|
||||
|
||||
nf_conntrack_proto_fini();
|
||||
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||
nf_ct_extend_unregister(&nf_ct_zone_extend);
|
||||
#endif
|
||||
|
@ -1372,7 +1371,7 @@ void nf_conntrack_cleanup(struct net *net)
|
|||
netfilter framework. Roll on, two-stage module
|
||||
delete... */
|
||||
synchronize_net();
|
||||
|
||||
nf_conntrack_proto_fini(net);
|
||||
nf_conntrack_cleanup_net(net);
|
||||
|
||||
if (net_eq(net, &init_net)) {
|
||||
|
@ -1496,11 +1495,6 @@ static int nf_conntrack_init_init_net(void)
|
|||
printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n",
|
||||
NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
|
||||
nf_conntrack_max);
|
||||
|
||||
ret = nf_conntrack_proto_init();
|
||||
if (ret < 0)
|
||||
goto err_proto;
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||
ret = nf_ct_extend_register(&nf_ct_zone_extend);
|
||||
if (ret < 0)
|
||||
|
@ -1518,9 +1512,7 @@ static int nf_conntrack_init_init_net(void)
|
|||
|
||||
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||
err_extend:
|
||||
nf_conntrack_proto_fini();
|
||||
#endif
|
||||
err_proto:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1583,9 +1575,7 @@ static int nf_conntrack_init_net(struct net *net)
|
|||
ret = nf_conntrack_helper_init(net);
|
||||
if (ret < 0)
|
||||
goto err_helper;
|
||||
|
||||
return 0;
|
||||
|
||||
err_helper:
|
||||
nf_conntrack_timeout_fini(net);
|
||||
err_timeout:
|
||||
|
@ -1622,6 +1612,9 @@ int nf_conntrack_init(struct net *net)
|
|||
if (ret < 0)
|
||||
goto out_init_net;
|
||||
}
|
||||
ret = nf_conntrack_proto_init(net);
|
||||
if (ret < 0)
|
||||
goto out_proto;
|
||||
ret = nf_conntrack_init_net(net);
|
||||
if (ret < 0)
|
||||
goto out_net;
|
||||
|
@ -1637,6 +1630,8 @@ int nf_conntrack_init(struct net *net)
|
|||
return 0;
|
||||
|
||||
out_net:
|
||||
nf_conntrack_proto_fini(net);
|
||||
out_proto:
|
||||
if (net_eq(net, &init_net))
|
||||
nf_conntrack_cleanup_init_net();
|
||||
out_init_net:
|
||||
|
|
|
@ -36,28 +36,35 @@ static DEFINE_MUTEX(nf_ct_proto_mutex);
|
|||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static int
|
||||
nf_ct_register_sysctl(struct ctl_table_header **header, const char *path,
|
||||
struct ctl_table *table, unsigned int *users)
|
||||
nf_ct_register_sysctl(struct net *net,
|
||||
struct ctl_table_header **header,
|
||||
const char *path,
|
||||
struct ctl_table *table,
|
||||
unsigned int *users)
|
||||
{
|
||||
if (*header == NULL) {
|
||||
*header = register_net_sysctl(&init_net, path, table);
|
||||
*header = register_net_sysctl(net, path, table);
|
||||
if (*header == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (users != NULL)
|
||||
(*users)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nf_ct_unregister_sysctl(struct ctl_table_header **header,
|
||||
struct ctl_table *table, unsigned int *users)
|
||||
struct ctl_table **table,
|
||||
unsigned int *users)
|
||||
{
|
||||
if (users != NULL && --*users > 0)
|
||||
return;
|
||||
|
||||
unregister_net_sysctl_table(*header);
|
||||
kfree(*table);
|
||||
*header = NULL;
|
||||
*table = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -161,30 +168,57 @@ static int kill_l4proto(struct nf_conn *i, void *data)
|
|||
nf_ct_l3num(i) == l4proto->l3proto;
|
||||
}
|
||||
|
||||
static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
|
||||
static struct nf_ip_net *nf_ct_l3proto_net(struct net *net,
|
||||
struct nf_conntrack_l3proto *l3proto)
|
||||
{
|
||||
if (l3proto->l3proto == PF_INET)
|
||||
return &net->ct.nf_ct_proto;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int nf_ct_l3proto_register_sysctl(struct net *net,
|
||||
struct nf_conntrack_l3proto *l3proto)
|
||||
{
|
||||
int err = 0;
|
||||
struct nf_ip_net *in = nf_ct_l3proto_net(net, l3proto);
|
||||
/* nf_conntrack_l3proto_ipv6 doesn't support sysctl */
|
||||
if (in == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (l3proto->ctl_table != NULL) {
|
||||
err = nf_ct_register_sysctl(&l3proto->ctl_table_header,
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
if (in->ctl_table != NULL) {
|
||||
err = nf_ct_register_sysctl(net,
|
||||
&in->ctl_table_header,
|
||||
l3proto->ctl_table_path,
|
||||
l3proto->ctl_table, NULL);
|
||||
in->ctl_table,
|
||||
NULL);
|
||||
if (err < 0) {
|
||||
kfree(in->ctl_table);
|
||||
in->ctl_table = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto)
|
||||
static void nf_ct_l3proto_unregister_sysctl(struct net *net,
|
||||
struct nf_conntrack_l3proto *l3proto)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (l3proto->ctl_table_header != NULL)
|
||||
nf_ct_unregister_sysctl(&l3proto->ctl_table_header,
|
||||
l3proto->ctl_table, NULL);
|
||||
struct nf_ip_net *in = nf_ct_l3proto_net(net, l3proto);
|
||||
|
||||
if (in == NULL)
|
||||
return;
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
if (in->ctl_table_header != NULL)
|
||||
nf_ct_unregister_sysctl(&in->ctl_table_header,
|
||||
&in->ctl_table,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
|
||||
static int
|
||||
nf_conntrack_l3proto_register_net(struct nf_conntrack_l3proto *proto)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nf_conntrack_l3proto *old;
|
||||
|
@ -203,10 +237,6 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = nf_ct_l3proto_register_sysctl(proto);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
if (proto->nlattr_tuple_size)
|
||||
proto->nla_size = 3 * proto->nlattr_tuple_size();
|
||||
|
||||
|
@ -215,13 +245,32 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
|
|||
out_unlock:
|
||||
mutex_unlock(&nf_ct_proto_mutex);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int nf_conntrack_l3proto_register(struct net *net,
|
||||
struct nf_conntrack_l3proto *proto)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (net == &init_net)
|
||||
ret = nf_conntrack_l3proto_register_net(proto);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (proto->init_net) {
|
||||
ret = proto->init_net(net);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return nf_ct_l3proto_register_sysctl(net, proto);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
|
||||
|
||||
void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
|
||||
static void
|
||||
nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto)
|
||||
{
|
||||
struct net *net;
|
||||
|
||||
BUG_ON(proto->l3proto >= AF_MAX);
|
||||
|
||||
mutex_lock(&nf_ct_proto_mutex);
|
||||
|
@ -230,42 +279,88 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
|
|||
) != proto);
|
||||
rcu_assign_pointer(nf_ct_l3protos[proto->l3proto],
|
||||
&nf_conntrack_l3proto_generic);
|
||||
nf_ct_l3proto_unregister_sysctl(proto);
|
||||
mutex_unlock(&nf_ct_proto_mutex);
|
||||
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
void nf_conntrack_l3proto_unregister(struct net *net,
|
||||
struct nf_conntrack_l3proto *proto)
|
||||
{
|
||||
if (net == &init_net)
|
||||
nf_conntrack_l3proto_unregister_net(proto);
|
||||
|
||||
nf_ct_l3proto_unregister_sysctl(net, proto);
|
||||
|
||||
/* Remove all contrack entries for this protocol */
|
||||
rtnl_lock();
|
||||
for_each_net(net)
|
||||
nf_ct_iterate_cleanup(net, kill_l3proto, proto);
|
||||
nf_ct_iterate_cleanup(net, kill_l3proto, proto);
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
|
||||
|
||||
static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto)
|
||||
static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
|
||||
struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
switch (l4proto->l4proto) {
|
||||
case IPPROTO_TCP:
|
||||
return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp;
|
||||
case IPPROTO_UDP:
|
||||
return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp;
|
||||
case IPPROTO_ICMP:
|
||||
return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmp;
|
||||
case IPPROTO_ICMPV6:
|
||||
return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmpv6;
|
||||
case 255: /* l4proto_generic */
|
||||
return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic;
|
||||
default:
|
||||
if (l4proto->net_id)
|
||||
return net_generic(net, *l4proto->net_id);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
int nf_ct_l4proto_register_sysctl(struct net *net,
|
||||
struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
int err = 0;
|
||||
struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
|
||||
if (pn == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (l4proto->ctl_table != NULL) {
|
||||
err = nf_ct_register_sysctl(l4proto->ctl_table_header,
|
||||
if (pn->ctl_table != NULL) {
|
||||
err = nf_ct_register_sysctl(net,
|
||||
&pn->ctl_table_header,
|
||||
"net/netfilter",
|
||||
l4proto->ctl_table,
|
||||
l4proto->ctl_table_users);
|
||||
if (err < 0)
|
||||
pn->ctl_table,
|
||||
&pn->users);
|
||||
if (err < 0) {
|
||||
if (!pn->users) {
|
||||
kfree(pn->ctl_table);
|
||||
pn->ctl_table = NULL;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
if (l4proto->ctl_compat_table != NULL) {
|
||||
err = nf_ct_register_sysctl(&l4proto->ctl_compat_table_header,
|
||||
if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) {
|
||||
err = nf_ct_register_sysctl(net,
|
||||
&pn->ctl_compat_header,
|
||||
"net/ipv4/netfilter",
|
||||
l4proto->ctl_compat_table, NULL);
|
||||
pn->ctl_compat_table,
|
||||
NULL);
|
||||
if (err == 0)
|
||||
goto out;
|
||||
nf_ct_unregister_sysctl(l4proto->ctl_table_header,
|
||||
l4proto->ctl_table,
|
||||
l4proto->ctl_table_users);
|
||||
|
||||
kfree(pn->ctl_compat_table);
|
||||
pn->ctl_compat_table = NULL;
|
||||
nf_ct_unregister_sysctl(&pn->ctl_table_header,
|
||||
&pn->ctl_table,
|
||||
&pn->users);
|
||||
}
|
||||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
out:
|
||||
|
@ -273,25 +368,34 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto)
|
||||
static
|
||||
void nf_ct_l4proto_unregister_sysctl(struct net *net,
|
||||
struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
|
||||
if (pn == NULL)
|
||||
return;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (l4proto->ctl_table_header != NULL &&
|
||||
*l4proto->ctl_table_header != NULL)
|
||||
nf_ct_unregister_sysctl(l4proto->ctl_table_header,
|
||||
l4proto->ctl_table,
|
||||
l4proto->ctl_table_users);
|
||||
if (pn->ctl_table_header != NULL)
|
||||
nf_ct_unregister_sysctl(&pn->ctl_table_header,
|
||||
&pn->ctl_table,
|
||||
&pn->users);
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
if (l4proto->ctl_compat_table_header != NULL)
|
||||
nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header,
|
||||
l4proto->ctl_compat_table, NULL);
|
||||
if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL)
|
||||
nf_ct_unregister_sysctl(&pn->ctl_compat_header,
|
||||
&pn->ctl_compat_table,
|
||||
NULL);
|
||||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#else
|
||||
pn->users--;
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
}
|
||||
|
||||
/* FIXME: Allow NULL functions and sub in pointers to generic for
|
||||
them. --RR */
|
||||
int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
|
||||
static int
|
||||
nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -333,10 +437,6 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = nf_ct_l4proto_register_sysctl(l4proto);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
l4proto->nla_size = 0;
|
||||
if (l4proto->nlattr_size)
|
||||
l4proto->nla_size += l4proto->nlattr_size();
|
||||
|
@ -345,17 +445,34 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
|
|||
|
||||
rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
|
||||
l4proto);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&nf_ct_proto_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nf_conntrack_l4proto_register(struct net *net,
|
||||
struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
int ret = 0;
|
||||
if (net == &init_net)
|
||||
ret = nf_conntrack_l4proto_register_net(l4proto);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (l4proto->init_net)
|
||||
ret = l4proto->init_net(net);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return nf_ct_l4proto_register_sysctl(net, l4proto);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
|
||||
|
||||
void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
|
||||
static void
|
||||
nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
struct net *net;
|
||||
|
||||
BUG_ON(l4proto->l3proto >= PF_MAX);
|
||||
|
||||
mutex_lock(&nf_ct_proto_mutex);
|
||||
|
@ -365,41 +482,53 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
|
|||
) != l4proto);
|
||||
rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
|
||||
&nf_conntrack_l4proto_generic);
|
||||
nf_ct_l4proto_unregister_sysctl(l4proto);
|
||||
mutex_unlock(&nf_ct_proto_mutex);
|
||||
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
void nf_conntrack_l4proto_unregister(struct net *net,
|
||||
struct nf_conntrack_l4proto *l4proto)
|
||||
{
|
||||
if (net == &init_net)
|
||||
nf_conntrack_l4proto_unregister_net(l4proto);
|
||||
|
||||
nf_ct_l4proto_unregister_sysctl(net, l4proto);
|
||||
/* Remove all contrack entries for this protocol */
|
||||
rtnl_lock();
|
||||
for_each_net(net)
|
||||
nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
|
||||
nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
|
||||
|
||||
int nf_conntrack_proto_init(void)
|
||||
int nf_conntrack_proto_init(struct net *net)
|
||||
{
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
err = nf_ct_l4proto_register_sysctl(&nf_conntrack_l4proto_generic);
|
||||
err = nf_conntrack_l4proto_generic.init_net(net);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = nf_ct_l4proto_register_sysctl(net,
|
||||
&nf_conntrack_l4proto_generic);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < AF_MAX; i++)
|
||||
rcu_assign_pointer(nf_ct_l3protos[i],
|
||||
&nf_conntrack_l3proto_generic);
|
||||
if (net == &init_net) {
|
||||
for (i = 0; i < AF_MAX; i++)
|
||||
rcu_assign_pointer(nf_ct_l3protos[i],
|
||||
&nf_conntrack_l3proto_generic);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nf_conntrack_proto_fini(void)
|
||||
void nf_conntrack_proto_fini(struct net *net)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
nf_ct_l4proto_unregister_sysctl(&nf_conntrack_l4proto_generic);
|
||||
|
||||
/* free l3proto protocol tables */
|
||||
for (i = 0; i < PF_MAX; i++)
|
||||
kfree(nf_ct_protos[i]);
|
||||
nf_ct_l4proto_unregister_sysctl(net,
|
||||
&nf_conntrack_l4proto_generic);
|
||||
if (net == &init_net) {
|
||||
/* free l3proto protocol tables */
|
||||
for (i = 0; i < PF_MAX; i++)
|
||||
kfree(nf_ct_protos[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,12 +387,9 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
|
|||
/* this module per-net specifics */
|
||||
static int dccp_net_id __read_mostly;
|
||||
struct dccp_net {
|
||||
struct nf_proto_net np;
|
||||
int dccp_loose;
|
||||
unsigned int dccp_timeout[CT_DCCP_MAX + 1];
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *sysctl_header;
|
||||
struct ctl_table *sysctl_table;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct dccp_net *dccp_pernet(struct net *net)
|
||||
|
@ -715,9 +712,10 @@ static int dccp_nlattr_size(void)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
struct dccp_net *dn = dccp_pernet(&init_net);
|
||||
struct dccp_net *dn = dccp_pernet(net);
|
||||
unsigned int *timeouts = data;
|
||||
int i;
|
||||
|
||||
|
@ -817,6 +815,45 @@ static struct ctl_table dccp_sysctl_table[] = {
|
|||
};
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int dccp_init_net(struct net *net)
|
||||
{
|
||||
struct dccp_net *dn = dccp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)dn;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!pn->ctl_table) {
|
||||
#else
|
||||
if (!pn->users++) {
|
||||
#endif
|
||||
/* default values */
|
||||
dn->dccp_loose = 1;
|
||||
dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
pn->ctl_table = kmemdup(dccp_sysctl_table,
|
||||
sizeof(dccp_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
|
||||
pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
|
||||
pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
|
||||
pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
|
||||
pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
|
||||
pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
|
||||
pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
|
||||
pn->ctl_table[7].data = &dn->dccp_loose;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
|
||||
.l3proto = AF_INET,
|
||||
.l4proto = IPPROTO_DCCP,
|
||||
|
@ -847,6 +884,8 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
|
|||
.nla_policy = dccp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
.net_id = &dccp_net_id,
|
||||
.init_net = dccp_init_net,
|
||||
};
|
||||
|
||||
static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
|
||||
|
@ -879,55 +918,39 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
|
|||
.nla_policy = dccp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
.net_id = &dccp_net_id,
|
||||
.init_net = dccp_init_net,
|
||||
};
|
||||
|
||||
static __net_init int dccp_net_init(struct net *net)
|
||||
{
|
||||
struct dccp_net *dn = dccp_pernet(net);
|
||||
|
||||
/* default values */
|
||||
dn->dccp_loose = 1;
|
||||
dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
|
||||
dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
|
||||
dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
dn->sysctl_table = kmemdup(dccp_sysctl_table,
|
||||
sizeof(dccp_sysctl_table), GFP_KERNEL);
|
||||
if (!dn->sysctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
dn->sysctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
|
||||
dn->sysctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
|
||||
dn->sysctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
|
||||
dn->sysctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
|
||||
dn->sysctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
|
||||
dn->sysctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
|
||||
dn->sysctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
|
||||
dn->sysctl_table[7].data = &dn->dccp_loose;
|
||||
|
||||
dn->sysctl_header = register_net_sysctl(net, "net/netfilter",
|
||||
dn->sysctl_table);
|
||||
if (!dn->sysctl_header) {
|
||||
kfree(dn->sysctl_table);
|
||||
return -ENOMEM;
|
||||
int ret = 0;
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&dccp_proto4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_dccp4 :protocol register failed.\n");
|
||||
goto out;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&dccp_proto6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_dccp6 :protocol register failed.\n");
|
||||
goto cleanup_dccp4;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
cleanup_dccp4:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&dccp_proto4);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __net_exit void dccp_net_exit(struct net *net)
|
||||
{
|
||||
struct dccp_net *dn = dccp_pernet(net);
|
||||
#ifdef CONFIG_SYSCTL
|
||||
unregister_net_sysctl_table(dn->sysctl_header);
|
||||
kfree(dn->sysctl_table);
|
||||
#endif
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&dccp_proto6);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&dccp_proto4);
|
||||
}
|
||||
|
||||
static struct pernet_operations dccp_net_ops = {
|
||||
|
@ -939,34 +962,12 @@ static struct pernet_operations dccp_net_ops = {
|
|||
|
||||
static int __init nf_conntrack_proto_dccp_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = register_pernet_subsys(&dccp_net_ops);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
err = nf_conntrack_l4proto_register(&dccp_proto4);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
err = nf_conntrack_l4proto_register(&dccp_proto6);
|
||||
if (err < 0)
|
||||
goto err3;
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
nf_conntrack_l4proto_unregister(&dccp_proto4);
|
||||
err2:
|
||||
unregister_pernet_subsys(&dccp_net_ops);
|
||||
err1:
|
||||
return err;
|
||||
return register_pernet_subsys(&dccp_net_ops);
|
||||
}
|
||||
|
||||
static void __exit nf_conntrack_proto_dccp_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&dccp_net_ops);
|
||||
nf_conntrack_l4proto_unregister(&dccp_proto6);
|
||||
nf_conntrack_l4proto_unregister(&dccp_proto4);
|
||||
}
|
||||
|
||||
module_init(nf_conntrack_proto_dccp_init);
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
|
||||
static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
|
||||
|
||||
static inline struct nf_generic_net *generic_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.generic;
|
||||
}
|
||||
|
||||
static bool generic_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
|
@ -42,7 +47,7 @@ static int generic_print_tuple(struct seq_file *s,
|
|||
|
||||
static unsigned int *generic_get_timeouts(struct net *net)
|
||||
{
|
||||
return &nf_ct_generic_timeout;
|
||||
return &(generic_pernet(net)->timeout);
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -1 for invalid. */
|
||||
|
@ -70,16 +75,18 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeout = data;
|
||||
struct nf_generic_net *gn = generic_pernet(net);
|
||||
|
||||
if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
|
||||
*timeout =
|
||||
ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
|
||||
else {
|
||||
/* Set default generic timeout. */
|
||||
*timeout = nf_ct_generic_timeout;
|
||||
*timeout = gn->timeout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -106,11 +113,9 @@ generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table_header *generic_sysctl_header;
|
||||
static struct ctl_table generic_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_generic_timeout",
|
||||
.data = &nf_ct_generic_timeout,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -121,7 +126,6 @@ static struct ctl_table generic_sysctl_table[] = {
|
|||
static struct ctl_table generic_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_generic_timeout",
|
||||
.data = &nf_ct_generic_timeout,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -131,6 +135,34 @@ static struct ctl_table generic_compat_sysctl_table[] = {
|
|||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int generic_init_net(struct net *net)
|
||||
{
|
||||
struct nf_generic_net *gn = generic_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)gn;
|
||||
gn->timeout = nf_ct_generic_timeout;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
pn->ctl_table = kmemdup(generic_sysctl_table,
|
||||
sizeof(generic_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
pn->ctl_table[0].data = &gn->timeout;
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
|
||||
sizeof(generic_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table) {
|
||||
kfree(pn->ctl_table);
|
||||
pn->ctl_table = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
pn->ctl_compat_table[0].data = &gn->timeout;
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
|
||||
{
|
||||
.l3proto = PF_UNSPEC,
|
||||
|
@ -151,11 +183,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
|
|||
.nla_policy = generic_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_header = &generic_sysctl_header,
|
||||
.ctl_table = generic_sysctl_table,
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
.ctl_compat_table = generic_compat_sysctl_table,
|
||||
#endif
|
||||
#endif
|
||||
.init_net = generic_init_net,
|
||||
};
|
||||
|
|
|
@ -54,13 +54,20 @@ static unsigned int gre_timeouts[GRE_CT_MAX] = {
|
|||
|
||||
static int proto_gre_net_id __read_mostly;
|
||||
struct netns_proto_gre {
|
||||
struct nf_proto_net nf;
|
||||
rwlock_t keymap_lock;
|
||||
struct list_head keymap_list;
|
||||
unsigned int gre_timeouts[GRE_CT_MAX];
|
||||
};
|
||||
|
||||
static inline struct netns_proto_gre *gre_pernet(struct net *net)
|
||||
{
|
||||
return net_generic(net, proto_gre_net_id);
|
||||
}
|
||||
|
||||
void nf_ct_gre_keymap_flush(struct net *net)
|
||||
{
|
||||
struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
struct nf_ct_gre_keymap *km, *tmp;
|
||||
|
||||
write_lock_bh(&net_gre->keymap_lock);
|
||||
|
@ -85,7 +92,7 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
|
|||
/* look up the source key for a given tuple */
|
||||
static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
|
||||
{
|
||||
struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
struct nf_ct_gre_keymap *km;
|
||||
__be16 key = 0;
|
||||
|
||||
|
@ -109,7 +116,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
|
|||
struct nf_conntrack_tuple *t)
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
struct nf_conn_help *help = nfct_help(ct);
|
||||
struct nf_ct_gre_keymap **kmp, *km;
|
||||
|
||||
|
@ -150,7 +157,7 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
|
|||
void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
struct nf_conn_help *help = nfct_help(ct);
|
||||
enum ip_conntrack_dir dir;
|
||||
|
||||
|
@ -237,7 +244,7 @@ static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)
|
|||
|
||||
static unsigned int *gre_get_timeouts(struct net *net)
|
||||
{
|
||||
return gre_timeouts;
|
||||
return gre_pernet(net)->gre_timeouts;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, and may modify conntrack */
|
||||
|
@ -297,13 +304,15 @@ static void gre_destroy(struct nf_conn *ct)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int gre_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeouts = data;
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
|
||||
/* set default timeouts for GRE. */
|
||||
timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED];
|
||||
timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED];
|
||||
timeouts[GRE_CT_UNREPLIED] = net_gre->gre_timeouts[GRE_CT_UNREPLIED];
|
||||
timeouts[GRE_CT_REPLIED] = net_gre->gre_timeouts[GRE_CT_REPLIED];
|
||||
|
||||
if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) {
|
||||
timeouts[GRE_CT_UNREPLIED] =
|
||||
|
@ -339,6 +348,19 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = {
|
|||
};
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
static int gre_init_net(struct net *net)
|
||||
{
|
||||
struct netns_proto_gre *net_gre = gre_pernet(net);
|
||||
int i;
|
||||
|
||||
rwlock_init(&net_gre->keymap_lock);
|
||||
INIT_LIST_HEAD(&net_gre->keymap_list);
|
||||
for (i = 0; i < GRE_CT_MAX; i++)
|
||||
net_gre->gre_timeouts[i] = gre_timeouts[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* protocol helper struct */
|
||||
static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
|
||||
.l3proto = AF_INET,
|
||||
|
@ -368,20 +390,22 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
|
|||
.nla_policy = gre_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
.net_id = &proto_gre_net_id,
|
||||
.init_net = gre_init_net,
|
||||
};
|
||||
|
||||
static int proto_gre_net_init(struct net *net)
|
||||
{
|
||||
struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
|
||||
|
||||
rwlock_init(&net_gre->keymap_lock);
|
||||
INIT_LIST_HEAD(&net_gre->keymap_list);
|
||||
|
||||
return 0;
|
||||
int ret = 0;
|
||||
ret = nf_conntrack_l4proto_register(net, &nf_conntrack_l4proto_gre4);
|
||||
if (ret < 0)
|
||||
pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void proto_gre_net_exit(struct net *net)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_gre4);
|
||||
nf_ct_gre_keymap_flush(net);
|
||||
}
|
||||
|
||||
|
@ -394,20 +418,11 @@ static struct pernet_operations proto_gre_net_ops = {
|
|||
|
||||
static int __init nf_ct_proto_gre_init(void)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
rv = register_pernet_subsys(&proto_gre_net_ops);
|
||||
if (rv < 0)
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
|
||||
return rv;
|
||||
return register_pernet_subsys(&proto_gre_net_ops);
|
||||
}
|
||||
|
||||
static void __exit nf_ct_proto_gre_fini(void)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
|
||||
unregister_pernet_subsys(&proto_gre_net_ops);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,17 @@ static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
|
|||
}
|
||||
};
|
||||
|
||||
static int sctp_net_id __read_mostly;
|
||||
struct sctp_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeouts[SCTP_CONNTRACK_MAX];
|
||||
};
|
||||
|
||||
static inline struct sctp_net *sctp_pernet(struct net *net)
|
||||
{
|
||||
return net_generic(net, sctp_net_id);
|
||||
}
|
||||
|
||||
static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
|
@ -281,7 +292,7 @@ static int sctp_new_state(enum ip_conntrack_dir dir,
|
|||
|
||||
static unsigned int *sctp_get_timeouts(struct net *net)
|
||||
{
|
||||
return sctp_timeouts;
|
||||
return sctp_pernet(net)->timeouts;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
|
||||
|
@ -551,14 +562,16 @@ static int sctp_nlattr_size(void)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeouts = data;
|
||||
struct sctp_net *sn = sctp_pernet(net);
|
||||
int i;
|
||||
|
||||
/* set default SCTP timeouts. */
|
||||
for (i=0; i<SCTP_CONNTRACK_MAX; i++)
|
||||
timeouts[i] = sctp_timeouts[i];
|
||||
timeouts[i] = sn->timeouts[i];
|
||||
|
||||
/* there's a 1:1 mapping between attributes and protocol states. */
|
||||
for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
|
||||
|
@ -599,54 +612,45 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
|
|||
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static unsigned int sctp_sysctl_table_users;
|
||||
static struct ctl_table_header *sctp_sysctl_header;
|
||||
static struct ctl_table sctp_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_closed",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_cookie_wait",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_cookie_echoed",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_established",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_shutdown_sent",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_shutdown_recd",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -658,49 +662,42 @@ static struct ctl_table sctp_sysctl_table[] = {
|
|||
static struct ctl_table sctp_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_closed",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_cookie_wait",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_cookie_echoed",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_established",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_shutdown_sent",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_shutdown_recd",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
|
||||
.data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -710,6 +707,101 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
|
|||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif
|
||||
|
||||
static void sctp_init_net_data(struct sctp_net *sn)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!sn->pn.ctl_table) {
|
||||
#else
|
||||
if (!sn->pn.users++) {
|
||||
#endif
|
||||
for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
|
||||
sn->timeouts[i] = sctp_timeouts[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct sctp_net *sn = (struct sctp_net *)pn;
|
||||
if (pn->ctl_table)
|
||||
return 0;
|
||||
|
||||
pn->ctl_table = kmemdup(sctp_sysctl_table,
|
||||
sizeof(sctp_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED];
|
||||
pn->ctl_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT];
|
||||
pn->ctl_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED];
|
||||
pn->ctl_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED];
|
||||
pn->ctl_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT];
|
||||
pn->ctl_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD];
|
||||
pn->ctl_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct sctp_net *sn = (struct sctp_net *)pn;
|
||||
pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table,
|
||||
sizeof(sctp_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_compat_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED];
|
||||
pn->ctl_compat_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT];
|
||||
pn->ctl_compat_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED];
|
||||
pn->ctl_compat_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED];
|
||||
pn->ctl_compat_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT];
|
||||
pn->ctl_compat_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD];
|
||||
pn->ctl_compat_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT];
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sctpv4_init_net(struct net *net)
|
||||
{
|
||||
int ret;
|
||||
struct sctp_net *sn = sctp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)sn;
|
||||
|
||||
sctp_init_net_data(sn);
|
||||
|
||||
ret = sctp_kmemdup_compat_sysctl_table(pn);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = sctp_kmemdup_sysctl_table(pn);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
if (ret < 0) {
|
||||
|
||||
kfree(pn->ctl_compat_table);
|
||||
pn->ctl_compat_table = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sctpv6_init_net(struct net *net)
|
||||
{
|
||||
struct sctp_net *sn = sctp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)sn;
|
||||
|
||||
sctp_init_net_data(sn);
|
||||
return sctp_kmemdup_sysctl_table(pn);
|
||||
}
|
||||
|
||||
static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
|
||||
.l3proto = PF_INET,
|
||||
.l4proto = IPPROTO_SCTP,
|
||||
|
@ -740,14 +832,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
|
|||
.nla_policy = sctp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &sctp_sysctl_table_users,
|
||||
.ctl_table_header = &sctp_sysctl_header,
|
||||
.ctl_table = sctp_sysctl_table,
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
.ctl_compat_table = sctp_compat_sysctl_table,
|
||||
#endif
|
||||
#endif
|
||||
.net_id = &sctp_net_id,
|
||||
.init_net = sctpv4_init_net,
|
||||
};
|
||||
|
||||
static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
|
||||
|
@ -780,40 +866,58 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
|
|||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#endif
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &sctp_sysctl_table_users,
|
||||
.ctl_table_header = &sctp_sysctl_header,
|
||||
.ctl_table = sctp_sysctl_table,
|
||||
#endif
|
||||
.net_id = &sctp_net_id,
|
||||
.init_net = sctpv6_init_net,
|
||||
};
|
||||
|
||||
static int sctp_net_init(struct net *net)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_sctp4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_sctp4 :protocol register failed.\n");
|
||||
goto out;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_sctp6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_sctp6 :protocol register failed.\n");
|
||||
goto cleanup_sctp4;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup_sctp4:
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_sctp4);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sctp_net_exit(struct net *net)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_sctp6);
|
||||
nf_conntrack_l4proto_unregister(net,
|
||||
&nf_conntrack_l4proto_sctp4);
|
||||
}
|
||||
|
||||
static struct pernet_operations sctp_net_ops = {
|
||||
.init = sctp_net_init,
|
||||
.exit = sctp_net_exit,
|
||||
.id = &sctp_net_id,
|
||||
.size = sizeof(struct sctp_net),
|
||||
};
|
||||
|
||||
static int __init nf_conntrack_proto_sctp_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
|
||||
if (ret) {
|
||||
pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
|
||||
if (ret) {
|
||||
pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n");
|
||||
goto cleanup_sctp4;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
cleanup_sctp4:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
|
||||
out:
|
||||
return ret;
|
||||
return register_pernet_subsys(&sctp_net_ops);
|
||||
}
|
||||
|
||||
static void __exit nf_conntrack_proto_sctp_fini(void)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
|
||||
unregister_pernet_subsys(&sctp_net_ops);
|
||||
}
|
||||
|
||||
module_init(nf_conntrack_proto_sctp_init);
|
||||
|
|
|
@ -270,6 +270,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
|
|||
}
|
||||
};
|
||||
|
||||
static inline struct nf_tcp_net *tcp_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.tcp;
|
||||
}
|
||||
|
||||
static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
|
@ -516,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
|
|||
u_int8_t pf)
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
struct ip_ct_tcp_state *sender = &state->seen[dir];
|
||||
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
|
||||
const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
|
||||
|
@ -720,7 +726,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
|
|||
} else {
|
||||
res = false;
|
||||
if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
|
||||
nf_ct_tcp_be_liberal)
|
||||
tn->tcp_be_liberal)
|
||||
res = true;
|
||||
if (!res && LOG_INVALID(net, IPPROTO_TCP))
|
||||
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
|
||||
|
@ -828,6 +834,7 @@ static int tcp_packet(struct nf_conn *ct,
|
|||
unsigned int *timeouts)
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
struct nf_conntrack_tuple *tuple;
|
||||
enum tcp_conntrack new_state, old_state;
|
||||
enum ip_conntrack_dir dir;
|
||||
|
@ -1020,7 +1027,7 @@ static int tcp_packet(struct nf_conn *ct,
|
|||
&& new_state == TCP_CONNTRACK_FIN_WAIT)
|
||||
ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
|
||||
|
||||
if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
|
||||
if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
|
||||
timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
|
||||
timeout = timeouts[TCP_CONNTRACK_RETRANS];
|
||||
else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
|
||||
|
@ -1065,6 +1072,8 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
|||
enum tcp_conntrack new_state;
|
||||
const struct tcphdr *th;
|
||||
struct tcphdr _tcph;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
|
||||
const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
|
||||
|
||||
|
@ -1093,7 +1102,7 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
|||
ct->proto.tcp.seen[0].td_end;
|
||||
|
||||
tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
|
||||
} else if (nf_ct_tcp_loose == 0) {
|
||||
} else if (tn->tcp_loose == 0) {
|
||||
/* Don't try to pick up connections. */
|
||||
return false;
|
||||
} else {
|
||||
|
@ -1251,14 +1260,16 @@ static int tcp_nlattr_tuple_size(void)
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeouts = data;
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
int i;
|
||||
|
||||
/* set default TCP timeouts. */
|
||||
for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++)
|
||||
timeouts[i] = tcp_timeouts[i];
|
||||
timeouts[i] = tn->timeouts[i];
|
||||
|
||||
if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) {
|
||||
timeouts[TCP_CONNTRACK_SYN_SENT] =
|
||||
|
@ -1355,96 +1366,81 @@ static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static unsigned int tcp_sysctl_table_users;
|
||||
static struct ctl_table_header *tcp_sysctl_header;
|
||||
static struct ctl_table tcp_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_syn_sent",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_syn_recv",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_established",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_fin_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_close_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_last_ack",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_time_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_close",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_max_retrans",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_RETRANS],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_timeout_unacknowledged",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_UNACK],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_loose",
|
||||
.data = &nf_ct_tcp_loose,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_be_liberal",
|
||||
.data = &nf_ct_tcp_be_liberal,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_tcp_max_retrans",
|
||||
.data = &nf_ct_tcp_max_retrans,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
|
@ -1456,91 +1452,78 @@ static struct ctl_table tcp_sysctl_table[] = {
|
|||
static struct ctl_table tcp_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_syn_sent",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_syn_sent2",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT2],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_syn_recv",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_established",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_fin_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_close_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_last_ack",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_time_wait",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_close",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_timeout_max_retrans",
|
||||
.data = &tcp_timeouts[TCP_CONNTRACK_RETRANS],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_loose",
|
||||
.data = &nf_ct_tcp_loose,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_be_liberal",
|
||||
.data = &nf_ct_tcp_be_liberal,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_tcp_max_retrans",
|
||||
.data = &nf_ct_tcp_max_retrans,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
|
@ -1550,6 +1533,125 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
|
|||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
|
||||
|
||||
if (pn->ctl_table)
|
||||
return 0;
|
||||
|
||||
pn->ctl_table = kmemdup(tcp_sysctl_table,
|
||||
sizeof(tcp_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
|
||||
pn->ctl_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
|
||||
pn->ctl_table[2].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
|
||||
pn->ctl_table[3].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
|
||||
pn->ctl_table[4].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
|
||||
pn->ctl_table[5].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
|
||||
pn->ctl_table[6].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
|
||||
pn->ctl_table[7].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
|
||||
pn->ctl_table[8].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
|
||||
pn->ctl_table[9].data = &tn->timeouts[TCP_CONNTRACK_UNACK];
|
||||
pn->ctl_table[10].data = &tn->tcp_loose;
|
||||
pn->ctl_table[11].data = &tn->tcp_be_liberal;
|
||||
pn->ctl_table[12].data = &tn->tcp_max_retrans;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
|
||||
pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table,
|
||||
sizeof(tcp_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_compat_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
|
||||
pn->ctl_compat_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT2];
|
||||
pn->ctl_compat_table[2].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
|
||||
pn->ctl_compat_table[3].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
|
||||
pn->ctl_compat_table[4].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
|
||||
pn->ctl_compat_table[5].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
|
||||
pn->ctl_compat_table[6].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
|
||||
pn->ctl_compat_table[7].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
|
||||
pn->ctl_compat_table[8].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
|
||||
pn->ctl_compat_table[9].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
|
||||
pn->ctl_compat_table[10].data = &tn->tcp_loose;
|
||||
pn->ctl_compat_table[11].data = &tn->tcp_be_liberal;
|
||||
pn->ctl_compat_table[12].data = &tn->tcp_max_retrans;
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcpv4_init_net(struct net *net)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)tn;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!pn->ctl_table) {
|
||||
#else
|
||||
if (!pn->user++) {
|
||||
#endif
|
||||
for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
|
||||
tn->timeouts[i] = tcp_timeouts[i];
|
||||
|
||||
tn->tcp_loose = nf_ct_tcp_loose;
|
||||
tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
|
||||
tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
|
||||
}
|
||||
|
||||
ret = tcp_kmemdup_compat_sysctl_table(pn);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tcp_kmemdup_sysctl_table(pn);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
if (ret < 0) {
|
||||
kfree(pn->ctl_compat_table);
|
||||
pn->ctl_compat_table = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcpv6_init_net(struct net *net)
|
||||
{
|
||||
int i;
|
||||
struct nf_tcp_net *tn = tcp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)tn;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!pn->ctl_table) {
|
||||
#else
|
||||
if (!pn->user++) {
|
||||
#endif
|
||||
for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
|
||||
tn->timeouts[i] = tcp_timeouts[i];
|
||||
tn->tcp_loose = nf_ct_tcp_loose;
|
||||
tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
|
||||
tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
|
||||
}
|
||||
|
||||
return tcp_kmemdup_sysctl_table(pn);
|
||||
}
|
||||
|
||||
struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
|
||||
{
|
||||
.l3proto = PF_INET,
|
||||
|
@ -1582,14 +1684,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
|
|||
.nla_policy = tcp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &tcp_sysctl_table_users,
|
||||
.ctl_table_header = &tcp_sysctl_header,
|
||||
.ctl_table = tcp_sysctl_table,
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
.ctl_compat_table = tcp_compat_sysctl_table,
|
||||
#endif
|
||||
#endif
|
||||
.init_net = tcpv4_init_net,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
|
||||
|
||||
|
@ -1625,10 +1720,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
|
|||
.nla_policy = tcp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &tcp_sysctl_table_users,
|
||||
.ctl_table_header = &tcp_sysctl_header,
|
||||
.ctl_table = tcp_sysctl_table,
|
||||
#endif
|
||||
.init_net = tcpv6_init_net,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
|
||||
|
|
|
@ -25,17 +25,16 @@
|
|||
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
||||
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||
|
||||
enum udp_conntrack {
|
||||
UDP_CT_UNREPLIED,
|
||||
UDP_CT_REPLIED,
|
||||
UDP_CT_MAX
|
||||
};
|
||||
|
||||
static unsigned int udp_timeouts[UDP_CT_MAX] = {
|
||||
[UDP_CT_UNREPLIED] = 30*HZ,
|
||||
[UDP_CT_REPLIED] = 180*HZ,
|
||||
};
|
||||
|
||||
static inline struct nf_udp_net *udp_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.udp;
|
||||
}
|
||||
|
||||
static bool udp_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
|
@ -73,7 +72,7 @@ static int udp_print_tuple(struct seq_file *s,
|
|||
|
||||
static unsigned int *udp_get_timeouts(struct net *net)
|
||||
{
|
||||
return udp_timeouts;
|
||||
return udp_pernet(net)->timeouts;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, and may modify conntracktype */
|
||||
|
@ -157,13 +156,15 @@ static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int udp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeouts = data;
|
||||
struct nf_udp_net *un = udp_pernet(net);
|
||||
|
||||
/* set default timeouts for UDP. */
|
||||
timeouts[UDP_CT_UNREPLIED] = udp_timeouts[UDP_CT_UNREPLIED];
|
||||
timeouts[UDP_CT_REPLIED] = udp_timeouts[UDP_CT_REPLIED];
|
||||
timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED];
|
||||
timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED];
|
||||
|
||||
if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) {
|
||||
timeouts[UDP_CT_UNREPLIED] =
|
||||
|
@ -200,19 +201,15 @@ udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static unsigned int udp_sysctl_table_users;
|
||||
static struct ctl_table_header *udp_sysctl_header;
|
||||
static struct ctl_table udp_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_udp_timeout",
|
||||
.data = &udp_timeouts[UDP_CT_UNREPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_udp_timeout_stream",
|
||||
.data = &udp_timeouts[UDP_CT_REPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -223,14 +220,12 @@ static struct ctl_table udp_sysctl_table[] = {
|
|||
static struct ctl_table udp_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_udp_timeout",
|
||||
.data = &udp_timeouts[UDP_CT_UNREPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_udp_timeout_stream",
|
||||
.data = &udp_timeouts[UDP_CT_REPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -240,6 +235,87 @@ static struct ctl_table udp_compat_sysctl_table[] = {
|
|||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct nf_udp_net *un = (struct nf_udp_net *)pn;
|
||||
if (pn->ctl_table)
|
||||
return 0;
|
||||
pn->ctl_table = kmemdup(udp_sysctl_table,
|
||||
sizeof(udp_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
pn->ctl_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
|
||||
pn->ctl_table[1].data = &un->timeouts[UDP_CT_REPLIED];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct nf_udp_net *un = (struct nf_udp_net *)pn;
|
||||
pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table,
|
||||
sizeof(udp_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_compat_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
|
||||
pn->ctl_compat_table[1].data = &un->timeouts[UDP_CT_REPLIED];
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void udp_init_net_data(struct nf_udp_net *un)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!un->pn.ctl_table) {
|
||||
#else
|
||||
if (!un->pn.user++) {
|
||||
#endif
|
||||
for (i = 0; i < UDP_CT_MAX; i++)
|
||||
un->timeouts[i] = udp_timeouts[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int udpv4_init_net(struct net *net)
|
||||
{
|
||||
int ret;
|
||||
struct nf_udp_net *un = udp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)un;
|
||||
|
||||
udp_init_net_data(un);
|
||||
|
||||
ret = udp_kmemdup_compat_sysctl_table(pn);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = udp_kmemdup_sysctl_table(pn);
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
if (ret < 0) {
|
||||
kfree(pn->ctl_compat_table);
|
||||
pn->ctl_compat_table = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int udpv6_init_net(struct net *net)
|
||||
{
|
||||
struct nf_udp_net *un = udp_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)un;
|
||||
|
||||
udp_init_net_data(un);
|
||||
return udp_kmemdup_sysctl_table(pn);
|
||||
}
|
||||
|
||||
struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
|
||||
{
|
||||
.l3proto = PF_INET,
|
||||
|
@ -267,14 +343,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
|
|||
.nla_policy = udp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &udp_sysctl_table_users,
|
||||
.ctl_table_header = &udp_sysctl_header,
|
||||
.ctl_table = udp_sysctl_table,
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
.ctl_compat_table = udp_compat_sysctl_table,
|
||||
#endif
|
||||
#endif
|
||||
.init_net = udpv4_init_net,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
|
||||
|
||||
|
@ -305,10 +374,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
|
|||
.nla_policy = udp_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &udp_sysctl_table_users,
|
||||
.ctl_table_header = &udp_sysctl_header,
|
||||
.ctl_table = udp_sysctl_table,
|
||||
#endif
|
||||
.init_net = udpv6_init_net,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
|
||||
|
|
|
@ -35,6 +35,17 @@ static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = {
|
|||
[UDPLITE_CT_REPLIED] = 180*HZ,
|
||||
};
|
||||
|
||||
static int udplite_net_id __read_mostly;
|
||||
struct udplite_net {
|
||||
struct nf_proto_net pn;
|
||||
unsigned int timeouts[UDPLITE_CT_MAX];
|
||||
};
|
||||
|
||||
static inline struct udplite_net *udplite_pernet(struct net *net)
|
||||
{
|
||||
return net_generic(net, udplite_net_id);
|
||||
}
|
||||
|
||||
static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
|
@ -70,7 +81,7 @@ static int udplite_print_tuple(struct seq_file *s,
|
|||
|
||||
static unsigned int *udplite_get_timeouts(struct net *net)
|
||||
{
|
||||
return udplite_timeouts;
|
||||
return udplite_pernet(net)->timeouts;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, and may modify conntracktype */
|
||||
|
@ -161,13 +172,15 @@ static int udplite_error(struct net *net, struct nf_conn *tmpl,
|
|||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_cttimeout.h>
|
||||
|
||||
static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
|
||||
static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[],
|
||||
struct net *net, void *data)
|
||||
{
|
||||
unsigned int *timeouts = data;
|
||||
struct udplite_net *un = udplite_pernet(net);
|
||||
|
||||
/* set default timeouts for UDPlite. */
|
||||
timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED];
|
||||
timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED];
|
||||
timeouts[UDPLITE_CT_UNREPLIED] = un->timeouts[UDPLITE_CT_UNREPLIED];
|
||||
timeouts[UDPLITE_CT_REPLIED] = un->timeouts[UDPLITE_CT_REPLIED];
|
||||
|
||||
if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) {
|
||||
timeouts[UDPLITE_CT_UNREPLIED] =
|
||||
|
@ -204,19 +217,15 @@ udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = {
|
|||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static unsigned int udplite_sysctl_table_users;
|
||||
static struct ctl_table_header *udplite_sysctl_header;
|
||||
static struct ctl_table udplite_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_udplite_timeout",
|
||||
.data = &udplite_timeouts[UDPLITE_CT_UNREPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "nf_conntrack_udplite_timeout_stream",
|
||||
.data = &udplite_timeouts[UDPLITE_CT_REPLIED],
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
|
@ -225,6 +234,31 @@ static struct ctl_table udplite_sysctl_table[] = {
|
|||
};
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int udplite_init_net(struct net *net)
|
||||
{
|
||||
int i;
|
||||
struct udplite_net *un = udplite_pernet(net);
|
||||
struct nf_proto_net *pn = (struct nf_proto_net *)un;
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (!pn->ctl_table) {
|
||||
#else
|
||||
if (!pn->users++) {
|
||||
#endif
|
||||
for (i = 0 ; i < UDPLITE_CT_MAX; i++)
|
||||
un->timeouts[i] = udplite_timeouts[i];
|
||||
#ifdef CONFIG_SYSCTL
|
||||
pn->ctl_table = kmemdup(udplite_sysctl_table,
|
||||
sizeof(udplite_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_table)
|
||||
return -ENOMEM;
|
||||
pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED];
|
||||
pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED];
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
|
||||
{
|
||||
.l3proto = PF_INET,
|
||||
|
@ -253,11 +287,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
|
|||
.nla_policy = udplite_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &udplite_sysctl_table_users,
|
||||
.ctl_table_header = &udplite_sysctl_header,
|
||||
.ctl_table = udplite_sysctl_table,
|
||||
#endif
|
||||
.net_id = &udplite_net_id,
|
||||
.init_net = udplite_init_net,
|
||||
};
|
||||
|
||||
static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
|
||||
|
@ -288,34 +319,55 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
|
|||
.nla_policy = udplite_timeout_nla_policy,
|
||||
},
|
||||
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
.ctl_table_users = &udplite_sysctl_table_users,
|
||||
.ctl_table_header = &udplite_sysctl_header,
|
||||
.ctl_table = udplite_sysctl_table,
|
||||
#endif
|
||||
.net_id = &udplite_net_id,
|
||||
.init_net = udplite_init_net,
|
||||
};
|
||||
|
||||
static int udplite_net_init(struct net *net)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_udplite4);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
|
||||
goto out;
|
||||
}
|
||||
ret = nf_conntrack_l4proto_register(net,
|
||||
&nf_conntrack_l4proto_udplite6);
|
||||
if (ret < 0) {
|
||||
pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
|
||||
goto cleanup_udplite4;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup_udplite4:
|
||||
nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void udplite_net_exit(struct net *net)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite6);
|
||||
nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
|
||||
}
|
||||
|
||||
static struct pernet_operations udplite_net_ops = {
|
||||
.init = udplite_net_init,
|
||||
.exit = udplite_net_exit,
|
||||
.id = &udplite_net_id,
|
||||
.size = sizeof(struct udplite_net),
|
||||
};
|
||||
|
||||
static int __init nf_conntrack_proto_udplite_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
return 0;
|
||||
err2:
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
|
||||
err1:
|
||||
return err;
|
||||
return register_pernet_subsys(&udplite_net_ops);
|
||||
}
|
||||
|
||||
static void __exit nf_conntrack_proto_udplite_exit(void)
|
||||
{
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
|
||||
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
|
||||
unregister_pernet_subsys(&udplite_net_ops);
|
||||
}
|
||||
|
||||
module_init(nf_conntrack_proto_udplite_init);
|
||||
|
|
|
@ -49,8 +49,9 @@ static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
|
|||
|
||||
static int
|
||||
ctnl_timeout_parse_policy(struct ctnl_timeout *timeout,
|
||||
struct nf_conntrack_l4proto *l4proto,
|
||||
const struct nlattr *attr)
|
||||
struct nf_conntrack_l4proto *l4proto,
|
||||
struct net *net,
|
||||
const struct nlattr *attr)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -60,7 +61,8 @@ ctnl_timeout_parse_policy(struct ctnl_timeout *timeout,
|
|||
nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max,
|
||||
attr, l4proto->ctnl_timeout.nla_policy);
|
||||
|
||||
ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, &timeout->data);
|
||||
ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net,
|
||||
&timeout->data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -74,6 +76,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
|
|||
__u8 l4num;
|
||||
struct nf_conntrack_l4proto *l4proto;
|
||||
struct ctnl_timeout *timeout, *matching = NULL;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
|
@ -117,7 +120,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
|
|||
goto err_proto_put;
|
||||
}
|
||||
|
||||
ret = ctnl_timeout_parse_policy(matching, l4proto,
|
||||
ret = ctnl_timeout_parse_policy(matching, l4proto, net,
|
||||
cda[CTA_TIMEOUT_DATA]);
|
||||
return ret;
|
||||
}
|
||||
|
@ -132,7 +135,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
|
|||
goto err_proto_put;
|
||||
}
|
||||
|
||||
ret = ctnl_timeout_parse_policy(timeout, l4proto,
|
||||
ret = ctnl_timeout_parse_policy(timeout, l4proto, net,
|
||||
cda[CTA_TIMEOUT_DATA]);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
|
|
@ -52,6 +52,7 @@ struct nfqnl_instance {
|
|||
|
||||
u_int16_t queue_num; /* number of this queue */
|
||||
u_int8_t copy_mode;
|
||||
u_int32_t flags; /* Set using NFQA_CFG_FLAGS */
|
||||
/*
|
||||
* Following fields are dirtied for each queued packet,
|
||||
* keep them in same cache line if possible.
|
||||
|
@ -406,6 +407,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|||
struct nfqnl_instance *queue;
|
||||
int err = -ENOBUFS;
|
||||
__be32 *packet_id_ptr;
|
||||
int failopen = 0;
|
||||
|
||||
/* rcu_read_lock()ed by nf_hook_slow() */
|
||||
queue = instance_lookup(queuenum);
|
||||
|
@ -431,9 +433,14 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|||
goto err_out_free_nskb;
|
||||
}
|
||||
if (queue->queue_total >= queue->queue_maxlen) {
|
||||
queue->queue_dropped++;
|
||||
net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n",
|
||||
queue->queue_total);
|
||||
if (queue->flags & NFQA_CFG_F_FAIL_OPEN) {
|
||||
failopen = 1;
|
||||
err = 0;
|
||||
} else {
|
||||
queue->queue_dropped++;
|
||||
net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n",
|
||||
queue->queue_total);
|
||||
}
|
||||
goto err_out_free_nskb;
|
||||
}
|
||||
entry->id = ++queue->id_sequence;
|
||||
|
@ -455,6 +462,8 @@ err_out_free_nskb:
|
|||
kfree_skb(nskb);
|
||||
err_out_unlock:
|
||||
spin_unlock_bh(&queue->lock);
|
||||
if (failopen)
|
||||
nf_reinject(entry, NF_ACCEPT);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
@ -858,6 +867,31 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|||
spin_unlock_bh(&queue->lock);
|
||||
}
|
||||
|
||||
if (nfqa[NFQA_CFG_FLAGS]) {
|
||||
__u32 flags, mask;
|
||||
|
||||
if (!queue) {
|
||||
ret = -ENODEV;
|
||||
goto err_out_unlock;
|
||||
}
|
||||
|
||||
if (!nfqa[NFQA_CFG_MASK]) {
|
||||
/* A mask is needed to specify which flags are being
|
||||
* changed.
|
||||
*/
|
||||
ret = -EINVAL;
|
||||
goto err_out_unlock;
|
||||
}
|
||||
|
||||
flags = ntohl(nla_get_be32(nfqa[NFQA_CFG_FLAGS]));
|
||||
mask = ntohl(nla_get_be32(nfqa[NFQA_CFG_MASK]));
|
||||
|
||||
spin_lock_bh(&queue->lock);
|
||||
queue->flags &= ~mask;
|
||||
queue->flags |= flags & mask;
|
||||
spin_unlock_bh(&queue->lock);
|
||||
}
|
||||
|
||||
err_out_unlock:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
|
|
|
@ -41,26 +41,36 @@ nfqueue_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
static u32 hash_v4(const struct sk_buff *skb)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
__be32 ipaddr;
|
||||
|
||||
/* packets in either direction go into same queue */
|
||||
ipaddr = iph->saddr ^ iph->daddr;
|
||||
if (iph->saddr < iph->daddr)
|
||||
return jhash_3words((__force u32)iph->saddr,
|
||||
(__force u32)iph->daddr, iph->protocol, jhash_initval);
|
||||
|
||||
return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval);
|
||||
return jhash_3words((__force u32)iph->daddr,
|
||||
(__force u32)iph->saddr, iph->protocol, jhash_initval);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
|
||||
static u32 hash_v6(const struct sk_buff *skb)
|
||||
{
|
||||
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
|
||||
__be32 addr[4];
|
||||
u32 a, b, c;
|
||||
|
||||
addr[0] = ip6h->saddr.s6_addr32[0] ^ ip6h->daddr.s6_addr32[0];
|
||||
addr[1] = ip6h->saddr.s6_addr32[1] ^ ip6h->daddr.s6_addr32[1];
|
||||
addr[2] = ip6h->saddr.s6_addr32[2] ^ ip6h->daddr.s6_addr32[2];
|
||||
addr[3] = ip6h->saddr.s6_addr32[3] ^ ip6h->daddr.s6_addr32[3];
|
||||
if (ip6h->saddr.s6_addr32[3] < ip6h->daddr.s6_addr32[3]) {
|
||||
a = (__force u32) ip6h->saddr.s6_addr32[3];
|
||||
b = (__force u32) ip6h->daddr.s6_addr32[3];
|
||||
} else {
|
||||
b = (__force u32) ip6h->saddr.s6_addr32[3];
|
||||
a = (__force u32) ip6h->daddr.s6_addr32[3];
|
||||
}
|
||||
|
||||
return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval);
|
||||
if (ip6h->saddr.s6_addr32[1] < ip6h->daddr.s6_addr32[1])
|
||||
c = (__force u32) ip6h->saddr.s6_addr32[1];
|
||||
else
|
||||
c = (__force u32) ip6h->daddr.s6_addr32[1];
|
||||
|
||||
return jhash_3words(a, b, c, jhash_initval);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -274,38 +274,25 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
|
|||
kfree(info->data);
|
||||
}
|
||||
|
||||
static struct xt_match connlimit_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "connlimit",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.checkentry = connlimit_mt_check,
|
||||
.match = connlimit_mt,
|
||||
.matchsize = sizeof(struct xt_connlimit_info),
|
||||
.destroy = connlimit_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "connlimit",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.checkentry = connlimit_mt_check,
|
||||
.match = connlimit_mt,
|
||||
.matchsize = sizeof(struct xt_connlimit_info),
|
||||
.destroy = connlimit_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
static struct xt_match connlimit_mt_reg __read_mostly = {
|
||||
.name = "connlimit",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.checkentry = connlimit_mt_check,
|
||||
.match = connlimit_mt,
|
||||
.matchsize = sizeof(struct xt_connlimit_info),
|
||||
.destroy = connlimit_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init connlimit_mt_init(void)
|
||||
{
|
||||
return xt_register_matches(connlimit_mt_reg,
|
||||
ARRAY_SIZE(connlimit_mt_reg));
|
||||
return xt_register_match(&connlimit_mt_reg);
|
||||
}
|
||||
|
||||
static void __exit connlimit_mt_exit(void)
|
||||
{
|
||||
xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
|
||||
xt_unregister_match(&connlimit_mt_reg);
|
||||
}
|
||||
|
||||
module_init(connlimit_mt_init);
|
||||
|
|
|
@ -75,6 +75,7 @@ struct recent_entry {
|
|||
struct recent_table {
|
||||
struct list_head list;
|
||||
char name[XT_RECENT_NAME_LEN];
|
||||
union nf_inet_addr mask;
|
||||
unsigned int refcnt;
|
||||
unsigned int entries;
|
||||
struct list_head lru_list;
|
||||
|
@ -228,10 +229,10 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
{
|
||||
struct net *net = dev_net(par->in ? par->in : par->out);
|
||||
struct recent_net *recent_net = recent_pernet(net);
|
||||
const struct xt_recent_mtinfo *info = par->matchinfo;
|
||||
const struct xt_recent_mtinfo_v1 *info = par->matchinfo;
|
||||
struct recent_table *t;
|
||||
struct recent_entry *e;
|
||||
union nf_inet_addr addr = {};
|
||||
union nf_inet_addr addr = {}, addr_mask;
|
||||
u_int8_t ttl;
|
||||
bool ret = info->invert;
|
||||
|
||||
|
@ -261,12 +262,15 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
|
||||
spin_lock_bh(&recent_lock);
|
||||
t = recent_table_lookup(recent_net, info->name);
|
||||
e = recent_entry_lookup(t, &addr, par->family,
|
||||
|
||||
nf_inet_addr_mask(&addr, &addr_mask, &t->mask);
|
||||
|
||||
e = recent_entry_lookup(t, &addr_mask, par->family,
|
||||
(info->check_set & XT_RECENT_TTL) ? ttl : 0);
|
||||
if (e == NULL) {
|
||||
if (!(info->check_set & XT_RECENT_SET))
|
||||
goto out;
|
||||
e = recent_entry_init(t, &addr, par->family, ttl);
|
||||
e = recent_entry_init(t, &addr_mask, par->family, ttl);
|
||||
if (e == NULL)
|
||||
par->hotdrop = true;
|
||||
ret = !ret;
|
||||
|
@ -306,10 +310,10 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int recent_mt_check(const struct xt_mtchk_param *par)
|
||||
static int recent_mt_check(const struct xt_mtchk_param *par,
|
||||
const struct xt_recent_mtinfo_v1 *info)
|
||||
{
|
||||
struct recent_net *recent_net = recent_pernet(par->net);
|
||||
const struct xt_recent_mtinfo *info = par->matchinfo;
|
||||
struct recent_table *t;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *pde;
|
||||
|
@ -361,6 +365,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par)
|
|||
goto out;
|
||||
}
|
||||
t->refcnt = 1;
|
||||
|
||||
memcpy(&t->mask, &info->mask, sizeof(t->mask));
|
||||
strcpy(t->name, info->name);
|
||||
INIT_LIST_HEAD(&t->lru_list);
|
||||
for (i = 0; i < ip_list_hash_size; i++)
|
||||
|
@ -385,10 +391,28 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int recent_mt_check_v0(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_recent_mtinfo_v0 *info_v0 = par->matchinfo;
|
||||
struct xt_recent_mtinfo_v1 info_v1;
|
||||
|
||||
/* Copy revision 0 structure to revision 1 */
|
||||
memcpy(&info_v1, info_v0, sizeof(struct xt_recent_mtinfo));
|
||||
/* Set default mask to ensure backward compatible behaviour */
|
||||
memset(info_v1.mask.all, 0xFF, sizeof(info_v1.mask.all));
|
||||
|
||||
return recent_mt_check(par, &info_v1);
|
||||
}
|
||||
|
||||
static int recent_mt_check_v1(const struct xt_mtchk_param *par)
|
||||
{
|
||||
return recent_mt_check(par, par->matchinfo);
|
||||
}
|
||||
|
||||
static void recent_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
{
|
||||
struct recent_net *recent_net = recent_pernet(par->net);
|
||||
const struct xt_recent_mtinfo *info = par->matchinfo;
|
||||
const struct xt_recent_mtinfo_v1 *info = par->matchinfo;
|
||||
struct recent_table *t;
|
||||
|
||||
mutex_lock(&recent_mutex);
|
||||
|
@ -625,7 +649,7 @@ static struct xt_match recent_mt_reg[] __read_mostly = {
|
|||
.family = NFPROTO_IPV4,
|
||||
.match = recent_mt,
|
||||
.matchsize = sizeof(struct xt_recent_mtinfo),
|
||||
.checkentry = recent_mt_check,
|
||||
.checkentry = recent_mt_check_v0,
|
||||
.destroy = recent_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
|
@ -635,10 +659,30 @@ static struct xt_match recent_mt_reg[] __read_mostly = {
|
|||
.family = NFPROTO_IPV6,
|
||||
.match = recent_mt,
|
||||
.matchsize = sizeof(struct xt_recent_mtinfo),
|
||||
.checkentry = recent_mt_check,
|
||||
.checkentry = recent_mt_check_v0,
|
||||
.destroy = recent_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "recent",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = recent_mt,
|
||||
.matchsize = sizeof(struct xt_recent_mtinfo_v1),
|
||||
.checkentry = recent_mt_check_v1,
|
||||
.destroy = recent_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "recent",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.match = recent_mt,
|
||||
.matchsize = sizeof(struct xt_recent_mtinfo_v1),
|
||||
.checkentry = recent_mt_check_v1,
|
||||
.destroy = recent_mt_destroy,
|
||||
.me = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init recent_mt_init(void)
|
||||
|
|
|
@ -5763,21 +5763,21 @@ static struct nf_hook_ops selinux_ipv4_ops[] = {
|
|||
{
|
||||
.hook = selinux_ipv4_postroute,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_SELINUX_LAST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv4_forward,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv4_output,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
}
|
||||
|
@ -5789,14 +5789,14 @@ static struct nf_hook_ops selinux_ipv6_ops[] = {
|
|||
{
|
||||
.hook = selinux_ipv6_postroute,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_SELINUX_LAST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv6_forward,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP6_PRI_SELINUX_FIRST,
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче