diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 46a0f974f87c1b888370c51ae7d3f52895126705..1350e47b0234d6ca79a2e2a9dc35c488b5ff0b5d 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -4,6 +4,62 @@ #define XT_FUNCTION_MAXNAMELEN 30 #define XT_TABLE_MAXNAMELEN 32 +struct xt_entry_match +{ + union { + struct { + u_int16_t match_size; + + /* Used by userspace */ + char name[XT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + } user; + struct { + u_int16_t match_size; + + /* Used inside the kernel */ + struct xt_match *match; + } kernel; + + /* Total length */ + u_int16_t match_size; + } u; + + unsigned char data[0]; +}; + +struct xt_entry_target +{ + union { + struct { + u_int16_t target_size; + + /* Used by userspace */ + char name[XT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + } user; + struct { + u_int16_t target_size; + + /* Used inside the kernel */ + struct xt_target *target; + } kernel; + + /* Total length */ + u_int16_t target_size; + } u; + + unsigned char data[0]; +}; + +struct xt_standard_target +{ + struct xt_entry_target target; + int verdict; +}; + /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision * kernel supports, if >= revision. */ struct xt_get_revision @@ -220,10 +276,10 @@ struct xt_table_info char *entries[NR_CPUS]; }; -extern int xt_register_target(int af, struct xt_target *target); -extern void xt_unregister_target(int af, struct xt_target *target); -extern int xt_register_match(int af, struct xt_match *target); -extern void xt_unregister_match(int af, struct xt_match *target); +extern int xt_register_target(struct xt_target *target); +extern void xt_unregister_target(struct xt_target *target); +extern int xt_register_match(struct xt_match *target); +extern void xt_unregister_match(struct xt_match *target); extern int xt_check_match(const struct xt_match *match, unsigned short family, unsigned int size, const char *table, unsigned int hook, diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index fd21796e513141af6f77239a9ddd9a1df06f956e..62cc27daca4efe2a4fb1b2ac1a384c06229e2ff4 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -65,35 +65,8 @@ struct arpt_arp { u_int16_t invflags; }; -struct arpt_entry_target -{ - union { - struct { - u_int16_t target_size; - - /* Used by userspace */ - char name[ARPT_FUNCTION_MAXNAMELEN-1]; - u_int8_t revision; - } user; - struct { - u_int16_t target_size; - - /* Used inside the kernel */ - struct arpt_target *target; - } kernel; - - /* Total length */ - u_int16_t target_size; - } u; - - unsigned char data[0]; -}; - -struct arpt_standard_target -{ - struct arpt_entry_target target; - int verdict; -}; +#define arpt_entry_target xt_entry_target +#define arpt_standard_target xt_standard_target /* Values for "flag" field in struct arpt_ip (general arp structure). * No flags defined yet. @@ -263,8 +236,10 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e */ #ifdef __KERNEL__ -#define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt) -#define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt) +#define arpt_register_target(tgt) \ +({ (tgt)->family = NF_ARP; \ + xt_register_target(tgt); }) +#define arpt_unregister_target(tgt) xt_unregister_target(tgt) extern int arpt_register_table(struct arpt_table *table, const struct arpt_replace *repl); diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 76ba24b68515db87fb7e05ba635bb30926f4f915..d5b8c0d6a12b3dfef2f688c2294886358f9397fe 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -52,61 +52,9 @@ struct ipt_ip { u_int8_t invflags; }; -struct ipt_entry_match -{ - union { - struct { - u_int16_t match_size; - - /* Used by userspace */ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - } user; - struct { - u_int16_t match_size; - - /* Used inside the kernel */ - struct ipt_match *match; - } kernel; - - /* Total length */ - u_int16_t match_size; - } u; - - unsigned char data[0]; -}; - -struct ipt_entry_target -{ - union { - struct { - u_int16_t target_size; - - /* Used by userspace */ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - } user; - struct { - u_int16_t target_size; - - /* Used inside the kernel */ - struct ipt_target *target; - } kernel; - - /* Total length */ - u_int16_t target_size; - } u; - - unsigned char data[0]; -}; - -struct ipt_standard_target -{ - struct ipt_entry_target target; - int verdict; -}; +#define ipt_entry_match xt_entry_match +#define ipt_entry_target xt_entry_target +#define ipt_standard_target xt_standard_target #define ipt_counters xt_counters @@ -321,11 +269,15 @@ ipt_get_target(struct ipt_entry *e) #include extern void ipt_init(void) __init; -#define ipt_register_target(tgt) xt_register_target(AF_INET, tgt) -#define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt) +#define ipt_register_target(tgt) \ +({ (tgt)->family = AF_INET; \ + xt_register_target(tgt); }) +#define ipt_unregister_target(tgt) xt_unregister_target(tgt) -#define ipt_register_match(mtch) xt_register_match(AF_INET, mtch) -#define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch) +#define ipt_register_match(mtch) \ +({ (mtch)->family = AF_INET; \ + xt_register_match(mtch); }) +#define ipt_unregister_match(mtch) xt_unregister_match(mtch) //#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) //#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index f249b574f0fa0e5ef8cb7fb2ff4cc1fcd7c2278b..d0d5d1ee4be31c64e9b64df889c68d68d73db46a 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -56,60 +56,9 @@ struct ip6t_ip6 { u_int8_t invflags; }; -/* FIXME: If alignment in kernel different from userspace? --RR */ -struct ip6t_entry_match -{ - union { - struct { - u_int16_t match_size; - - /* Used by userspace */ - char name[IP6T_FUNCTION_MAXNAMELEN-1]; - u_int8_t revision; - } user; - struct { - u_int16_t match_size; - - /* Used inside the kernel */ - struct ip6t_match *match; - } kernel; - - /* Total length */ - u_int16_t match_size; - } u; - - unsigned char data[0]; -}; - -struct ip6t_entry_target -{ - union { - struct { - u_int16_t target_size; - - /* Used by userspace */ - char name[IP6T_FUNCTION_MAXNAMELEN-1]; - u_int8_t revision; - } user; - struct { - u_int16_t target_size; - - /* Used inside the kernel */ - struct ip6t_target *target; - } kernel; - - /* Total length */ - u_int16_t target_size; - } u; - - unsigned char data[0]; -}; - -struct ip6t_standard_target -{ - struct ip6t_entry_target target; - int verdict; -}; +#define ip6t_entry_match xt_entry_match +#define ip6t_entry_target xt_entry_target +#define ip6t_standard_target xt_standard_target #define ip6t_counters xt_counters @@ -334,11 +283,15 @@ ip6t_get_target(struct ip6t_entry *e) #include extern void ip6t_init(void) __init; -#define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt) -#define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt) +#define ip6t_register_target(tgt) \ +({ (tgt)->family = AF_INET6; \ + xt_register_target(tgt); }) +#define ip6t_unregister_target(tgt) xt_unregister_target(tgt) -#define ip6t_register_match(match) xt_register_match(AF_INET6, match) -#define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match) +#define ip6t_register_match(match) \ +({ (match)->family = AF_INET6; \ + xt_register_match(match); }) +#define ip6t_unregister_match(match) xt_unregister_match(match) extern int ip6t_register_table(struct ip6t_table *table, const struct ip6t_replace *repl); diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 2743c156caa00056232f7d516f3cf838409edef0..b6f0905a4ee2b99b12645100f4f8d318ebdf2fc3 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -195,6 +195,10 @@ static inline void nf_ct_put(struct nf_conn *ct) nf_conntrack_put(&ct->ct_general); } +/* Protocol module loading */ +extern int nf_ct_l3proto_try_module_get(unsigned short l3proto); +extern void nf_ct_l3proto_module_put(unsigned short l3proto); + extern struct nf_conntrack_tuple_hash * __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, const struct nf_conn *ignored_conntrack); diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h index 02eccebd55ae50508cb28f083df59aa068fda746..cb37ad08427faca6d51ac7975c4108fdb6822f71 100644 --- a/include/net/tc_act/tc_ipt.h +++ b/include/net/tc_act/tc_ipt.h @@ -3,14 +3,14 @@ #include -struct ipt_entry_target; +struct xt_entry_target; struct tcf_ipt { tca_gen(ipt); u32 hook; char *tname; - struct ipt_entry_target *t; + struct xt_entry_target *t; }; #endif diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 8ee4d016740d925f3781b8fc7842c99ed2145c27..f75ff1d96551d1e03cbfba7153c1bedb9b6e36df 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1249,11 +1249,7 @@ int ip_push_pending_frames(struct sock *sk) iph->tos = inet->tos; iph->tot_len = htons(skb->len); iph->frag_off = df; - if (!df) { - __ip_select_ident(iph, &rt->u.dst, 0); - } else { - iph->id = htons(inet->id++); - } + ip_select_ident(iph, &rt->u.dst, sk); iph->ttl = ttl; iph->protocol = sk->sk_protocol; iph->saddr = rt->rt_src; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f7efb3f27bf599b070d25521372d6cd11466ac2e..ff0c594a4198659f98be5c81828296ff78058c1a 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1146,12 +1146,14 @@ void arpt_unregister_table(struct arpt_table *table) static struct arpt_target arpt_standard_target = { .name = ARPT_STANDARD_TARGET, .targetsize = sizeof(int), + .family = NF_ARP, }; static struct arpt_target arpt_error_target = { .name = ARPT_ERROR_TARGET, .target = arpt_error, .targetsize = ARPT_FUNCTION_MAXNAMELEN, + .family = NF_ARP, }; static struct nf_sockopt_ops arpt_sockopts = { @@ -1171,8 +1173,8 @@ static int __init init(void) xt_proto_init(NF_ARP); /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(NF_ARP, &arpt_standard_target); - xt_register_target(NF_ARP, &arpt_error_target); + xt_register_target(&arpt_standard_target); + xt_register_target(&arpt_error_target); /* Register setsockopt */ ret = nf_register_sockopt(&arpt_sockopts); diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 84c66dbfedaf83505434124e6bf39621bc84ec96..9e34034729a6cad30daa7b65457034a70ab2508c 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -77,8 +77,8 @@ unsigned int ip_ct_log_invalid; static LIST_HEAD(unconfirmed); static int ip_conntrack_vmalloc; -static unsigned int ip_conntrack_next_id = 1; -static unsigned int ip_conntrack_expect_next_id = 1; +static unsigned int ip_conntrack_next_id; +static unsigned int ip_conntrack_expect_next_id; #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS struct notifier_block *ip_conntrack_chain; struct notifier_block *ip_conntrack_expect_chain; diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 20da6730b86056d64f3959d6495448065a50fcd6..daeb1395faa4db85096a108489b70645d9c9955b 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -639,8 +639,8 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new, } /****************************************************************************/ -static int get_h225_addr(unsigned char *data, TransportAddress * addr, - u_int32_t * ip, u_int16_t * port) +int get_h225_addr(unsigned char *data, TransportAddress * addr, + u_int32_t * ip, u_int16_t * port) { unsigned char *p; diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 5ce2e3fc2c7f18b16452ff9838a8e34f08bbc1ba..9b6e19bae90feeb5faa54dcd258df56517d643cb 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c @@ -4,7 +4,7 @@ * (C) 2001 by Jay Schulist * (C) 2002-2005 by Harald Welte * (C) 2003 by Patrick Mchardy - * (C) 2005 by Pablo Neira Ayuso + * (C) 2005-2006 by Pablo Neira Ayuso * * I've reworked this stuff to use attributes instead of conntrack * structures. 5.44 am. I need more tea. --pablo 05/07/11. @@ -53,20 +53,18 @@ static char __initdata version[] = "0.90"; static inline int ctnetlink_dump_tuples_proto(struct sk_buff *skb, - const struct ip_conntrack_tuple *tuple) + const struct ip_conntrack_tuple *tuple, + struct ip_conntrack_protocol *proto) { - struct ip_conntrack_protocol *proto; int ret = 0; + struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); - /* If no protocol helper is found, this function will return the - * generic protocol helper, so proto won't *ever* be NULL */ - proto = ip_conntrack_proto_find_get(tuple->dst.protonum); if (likely(proto->tuple_to_nfattr)) ret = proto->tuple_to_nfattr(skb, tuple); - ip_conntrack_proto_put(proto); + NFA_NEST_END(skb, nest_parms); return ret; @@ -75,27 +73,40 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb, } static inline int -ctnetlink_dump_tuples(struct sk_buff *skb, - const struct ip_conntrack_tuple *tuple) +ctnetlink_dump_tuples_ip(struct sk_buff *skb, + const struct ip_conntrack_tuple *tuple) { - struct nfattr *nest_parms; - int ret; + struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); - nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip); - NFA_NEST_END(skb, nest_parms); - nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); - ret = ctnetlink_dump_tuples_proto(skb, tuple); NFA_NEST_END(skb, nest_parms); - return ret; + return 0; nfattr_failure: return -1; } +static inline int +ctnetlink_dump_tuples(struct sk_buff *skb, + const struct ip_conntrack_tuple *tuple) +{ + int ret; + struct ip_conntrack_protocol *proto; + + ret = ctnetlink_dump_tuples_ip(skb, tuple); + if (unlikely(ret < 0)) + return ret; + + proto = ip_conntrack_proto_find_get(tuple->dst.protonum); + ret = ctnetlink_dump_tuples_proto(skb, tuple, proto); + ip_conntrack_proto_put(proto); + + return ret; +} + static inline int ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct) { @@ -1134,6 +1145,33 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb, return -1; } +static inline int +ctnetlink_exp_dump_mask(struct sk_buff *skb, + const struct ip_conntrack_tuple *tuple, + const struct ip_conntrack_tuple *mask) +{ + int ret; + struct ip_conntrack_protocol *proto; + struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); + + ret = ctnetlink_dump_tuples_ip(skb, mask); + if (unlikely(ret < 0)) + goto nfattr_failure; + + proto = ip_conntrack_proto_find_get(tuple->dst.protonum); + ret = ctnetlink_dump_tuples_proto(skb, mask, proto); + ip_conntrack_proto_put(proto); + if (unlikely(ret < 0)) + goto nfattr_failure; + + NFA_NEST_END(skb, nest_parms); + + return 0; + +nfattr_failure: + return -1; +} + static inline int ctnetlink_exp_dump_expect(struct sk_buff *skb, const struct ip_conntrack_expect *exp) @@ -1144,7 +1182,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) goto nfattr_failure; - if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) + if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) goto nfattr_failure; if (ctnetlink_exp_dump_tuple(skb, &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 39705f9bc1546ea55dc69a5aeca6ae304da1e9f7..a7b194c4d79d72e131249a6296873693727da832 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1335,12 +1335,14 @@ icmp_checkentry(const char *tablename, static struct ipt_target ipt_standard_target = { .name = IPT_STANDARD_TARGET, .targetsize = sizeof(int), + .family = AF_INET, }; static struct ipt_target ipt_error_target = { .name = IPT_ERROR_TARGET, .target = ipt_error, .targetsize = IPT_FUNCTION_MAXNAMELEN, + .family = AF_INET, }; static struct nf_sockopt_ops ipt_sockopts = { @@ -1358,6 +1360,7 @@ static struct ipt_match icmp_matchstruct = { .match = icmp_match, .matchsize = sizeof(struct ipt_icmp), .proto = IPPROTO_ICMP, + .family = AF_INET, .checkentry = icmp_checkentry, }; @@ -1368,9 +1371,9 @@ static int __init init(void) xt_proto_init(AF_INET); /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(AF_INET, &ipt_standard_target); - xt_register_target(AF_INET, &ipt_error_target); - xt_register_match(AF_INET, &icmp_matchstruct); + xt_register_target(&ipt_standard_target); + xt_register_target(&ipt_error_target); + xt_register_match(&icmp_matchstruct); /* Register setsockopt */ ret = nf_register_sockopt(&ipt_sockopts); @@ -1387,9 +1390,9 @@ static void __exit fini(void) { nf_unregister_sockopt(&ipt_sockopts); - xt_unregister_match(AF_INET, &icmp_matchstruct); - xt_unregister_target(AF_INET, &ipt_error_target); - xt_unregister_target(AF_INET, &ipt_standard_target); + xt_unregister_match(&icmp_matchstruct); + xt_unregister_target(&ipt_error_target); + xt_unregister_target(&ipt_standard_target); xt_proto_fini(AF_INET); } diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index cb9c661f3f331c5fb64f805bbfdff5f8a7e70b3e..c8abc9d859b96d946fbde352df73c4de8e7996d1 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -568,6 +568,7 @@ static int init_or_cleanup(int init) return ret; } +MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); MODULE_LICENSE("GPL"); static int __init init(void) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 602feec477381ff03f5e598ba533cad8c750de83..4c20eeb3d56844859754cb207c8ad705f6558c4b 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -907,7 +907,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER /* we need to exclude all possible EINVALs except default case */ - if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && + if (err == -EINVAL && optname != IPV6_ADDRFORM && optname != MCAST_MSFILTER) { int len; @@ -944,7 +944,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER /* we need to exclude all possible EINVALs except default case */ - if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && + if (err == -EINVAL && optname != IPV6_ADDRFORM && optname != MCAST_MSFILTER) { int len; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 5a2063bda67689fa591f4aea62317902ad3b4053..db3c9ae98e95a5264af072a7b98054610573cc40 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1377,12 +1377,14 @@ icmp6_checkentry(const char *tablename, static struct ip6t_target ip6t_standard_target = { .name = IP6T_STANDARD_TARGET, .targetsize = sizeof(int), + .family = AF_INET6, }; static struct ip6t_target ip6t_error_target = { .name = IP6T_ERROR_TARGET, .target = ip6t_error, .targetsize = IP6T_FUNCTION_MAXNAMELEN, + .family = AF_INET6, }; static struct nf_sockopt_ops ip6t_sockopts = { @@ -1401,6 +1403,7 @@ static struct ip6t_match icmp6_matchstruct = { .matchsize = sizeof(struct ip6t_icmp), .checkentry = icmp6_checkentry, .proto = IPPROTO_ICMPV6, + .family = AF_INET6, }; static int __init init(void) @@ -1410,9 +1413,9 @@ static int __init init(void) xt_proto_init(AF_INET6); /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(AF_INET6, &ip6t_standard_target); - xt_register_target(AF_INET6, &ip6t_error_target); - xt_register_match(AF_INET6, &icmp6_matchstruct); + xt_register_target(&ip6t_standard_target); + xt_register_target(&ip6t_error_target); + xt_register_match(&icmp6_matchstruct); /* Register setsockopt */ ret = nf_register_sockopt(&ip6t_sockopts); @@ -1429,9 +1432,9 @@ static int __init init(void) static void __exit fini(void) { nf_unregister_sockopt(&ip6t_sockopts); - xt_unregister_match(AF_INET6, &icmp6_matchstruct); - xt_unregister_target(AF_INET6, &ip6t_error_target); - xt_unregister_target(AF_INET6, &ip6t_standard_target); + xt_unregister_match(&icmp6_matchstruct); + xt_unregister_target(&ip6t_error_target); + xt_unregister_target(&ip6t_standard_target); xt_proto_fini(AF_INET6); } diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ac35f95263687f1cac3e7bddfeb3e9a04d9e1c79..c16f62934bd9199ef2c76cbb0e16b2b52e0c7c9f 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -584,6 +584,7 @@ static int init_or_cleanup(int init) return ret; } +MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI "); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 17402780914851ef3bb657639111b2ed2c47ca95..332acb37b3855e698c239adfc8d42f48ae203528 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -11,7 +11,7 @@ config NETFILTER_NETLINK_QUEUE tristate "Netfilter NFQUEUE over NFNETLINK interface" depends on NETFILTER_NETLINK help - If this option isenabled, the kernel will include support + If this option is enabled, the kernel will include support for queueing packets via NFNETLINK. config NETFILTER_NETLINK_LOG @@ -66,7 +66,7 @@ config NF_CONNTRACK_EVENTS help If this option is enabled, the connection tracking code will provide a notifier chain that can be used by other kernel code - to get notified aboutchanges in the connection tracking state. + to get notified about changes in the connection tracking state. If unsure, say `N'. @@ -153,7 +153,7 @@ config NETFILTER_XT_TARGET_NFQUEUE tristate '"NFQUEUE" target Support' depends on NETFILTER_XTABLES help - This Target replaced the old obsolete QUEUE target. + This target replaced the old obsolete QUEUE target. As opposed to QUEUE, it supports 65535 different queues, not just one. diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index f6498234e26427d16e390ce925e9d8111d214347..0ae281d9bfc3f16cda2b7e36c34b109145045d1a 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -23,6 +23,8 @@ * 26 Jan 2006: Harald Welte * - restructure nf_conn (introduce nf_conn_help) * - redesign 'features' how they were originally intended + * 26 Feb 2006: Pablo Neira Ayuso + * - add support for L3 protocol module load on demand. * * Derived from net/ipv4/netfilter/ip_conntrack_core.c */ @@ -85,8 +87,8 @@ unsigned int nf_ct_log_invalid; static LIST_HEAD(unconfirmed); static int nf_conntrack_vmalloc; -static unsigned int nf_conntrack_next_id = 1; -static unsigned int nf_conntrack_expect_next_id = 1; +static unsigned int nf_conntrack_next_id; +static unsigned int nf_conntrack_expect_next_id; #ifdef CONFIG_NF_CONNTRACK_EVENTS struct notifier_block *nf_conntrack_chain; struct notifier_block *nf_conntrack_expect_chain; @@ -241,6 +243,35 @@ void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p) module_put(p->me); } +int +nf_ct_l3proto_try_module_get(unsigned short l3proto) +{ + int ret; + struct nf_conntrack_l3proto *p; + +retry: p = nf_ct_l3proto_find_get(l3proto); + if (p == &nf_conntrack_generic_l3proto) { + ret = request_module("nf_conntrack-%d", l3proto); + if (!ret) + goto retry; + + return -EPROTOTYPE; + } + + return 0; +} + +void nf_ct_l3proto_module_put(unsigned short l3proto) +{ + struct nf_conntrack_l3proto *p; + + preempt_disable(); + p = __nf_ct_l3proto_find(l3proto); + preempt_enable(); + + module_put(p->me); +} + static int nf_conntrack_hash_rnd_initted; static unsigned int nf_conntrack_hash_rnd; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5eadf009bb157b5a24b8100852d34d41e85d7bb8..0e0e9d7b34c806d4ea1594f821cb4b2125fd248a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -4,7 +4,7 @@ * (C) 2001 by Jay Schulist * (C) 2002-2006 by Harald Welte * (C) 2003 by Patrick Mchardy - * (C) 2005 by Pablo Neira Ayuso + * (C) 2005-2006 by Pablo Neira Ayuso * * I've reworked this stuff to use attributes instead of conntrack * structures. 5.44 am. I need more tea. --pablo 05/07/11. @@ -55,20 +55,18 @@ static char __initdata version[] = "0.93"; static inline int ctnetlink_dump_tuples_proto(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) + const struct nf_conntrack_tuple *tuple, + struct nf_conntrack_protocol *proto) { - struct nf_conntrack_protocol *proto; int ret = 0; + struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); - /* If no protocol helper is found, this function will return the - * generic protocol helper, so proto won't *ever* be NULL */ - proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); if (likely(proto->tuple_to_nfattr)) ret = proto->tuple_to_nfattr(skb, tuple); - nf_ct_proto_put(proto); + NFA_NEST_END(skb, nest_parms); return ret; @@ -77,33 +75,44 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb, } static inline int -ctnetlink_dump_tuples(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) +ctnetlink_dump_tuples_ip(struct sk_buff *skb, + const struct nf_conntrack_tuple *tuple, + struct nf_conntrack_l3proto *l3proto) { - struct nfattr *nest_parms; - struct nf_conntrack_l3proto *l3proto; int ret = 0; - - l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); - - nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); + struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); + if (likely(l3proto->tuple_to_nfattr)) ret = l3proto->tuple_to_nfattr(skb, tuple); + NFA_NEST_END(skb, nest_parms); + return ret; + +nfattr_failure: + return -1; +} + +static inline int +ctnetlink_dump_tuples(struct sk_buff *skb, + const struct nf_conntrack_tuple *tuple) +{ + int ret; + struct nf_conntrack_l3proto *l3proto; + struct nf_conntrack_protocol *proto; + + l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); + ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); nf_ct_l3proto_put(l3proto); if (unlikely(ret < 0)) return ret; - nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); - ret = ctnetlink_dump_tuples_proto(skb, tuple); - NFA_NEST_END(skb, nest_parms); + proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); + ret = ctnetlink_dump_tuples_proto(skb, tuple, proto); + nf_ct_proto_put(proto); return ret; - -nfattr_failure: - return -1; } static inline int @@ -1152,6 +1161,37 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb, return -1; } +static inline int +ctnetlink_exp_dump_mask(struct sk_buff *skb, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_tuple *mask) +{ + int ret; + struct nf_conntrack_l3proto *l3proto; + struct nf_conntrack_protocol *proto; + struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); + + l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); + ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto); + nf_ct_l3proto_put(l3proto); + + if (unlikely(ret < 0)) + goto nfattr_failure; + + proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); + ret = ctnetlink_dump_tuples_proto(skb, mask, proto); + nf_ct_proto_put(proto); + if (unlikely(ret < 0)) + goto nfattr_failure; + + NFA_NEST_END(skb, nest_parms); + + return 0; + +nfattr_failure: + return -1; +} + static inline int ctnetlink_exp_dump_expect(struct sk_buff *skb, const struct nf_conntrack_expect *exp) @@ -1162,7 +1202,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) goto nfattr_failure; - if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) + if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) goto nfattr_failure; if (ctnetlink_exp_dump_tuple(skb, &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 290d5a0c559b6d4a760fd1c2b41c23cd73e0501a..75577e175b35a3a44f9bb3d1a3318a84c930d2bd 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -834,6 +834,8 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init); EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); #endif +EXPORT_SYMBOL(nf_ct_l3proto_try_module_get); +EXPORT_SYMBOL(nf_ct_l3proto_module_put); EXPORT_SYMBOL(nf_conntrack_l3proto_register); EXPORT_SYMBOL(nf_conntrack_l3proto_unregister); EXPORT_SYMBOL(nf_conntrack_protocol_register); diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 2cf5fb8322c4942ab3fce8158cf1f4333ab037d2..b5701662182ecbc064fce8c5f036b176574101a9 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -354,16 +354,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, QDEBUG("entered\n"); /* all macros expand to constant values at compile time */ - size = NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hdr)) - + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + + + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hdr)) + + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ #ifdef CONFIG_BRIDGE_NETFILTER - + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ + + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ #endif - + NLMSG_SPACE(sizeof(u_int32_t)) /* mark */ - + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw)) - + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); + + NFA_SPACE(sizeof(u_int32_t)) /* mark */ + + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hw)) + + NFA_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); outdev = entinf->outdev; @@ -388,7 +389,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, else data_len = queue->copy_range; - size += NLMSG_SPACE(data_len); + size += NFA_SPACE(data_len); break; default: diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 750b928297660b141db59c5f45ec8d4be0321f77..0a29a24d9a72f8344e88f509254cca4845018dbc 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -60,9 +60,9 @@ static const char *xt_prefix[NPROTO] = { /* Registration hooks for targets. */ int -xt_register_target(int af, struct xt_target *target) +xt_register_target(struct xt_target *target) { - int ret; + int ret, af = target->family; ret = down_interruptible(&xt[af].mutex); if (ret != 0) @@ -74,8 +74,10 @@ xt_register_target(int af, struct xt_target *target) EXPORT_SYMBOL(xt_register_target); void -xt_unregister_target(int af, struct xt_target *target) +xt_unregister_target(struct xt_target *target) { + int af = target->family; + down(&xt[af].mutex); LIST_DELETE(&xt[af].target, target); up(&xt[af].mutex); @@ -83,9 +85,9 @@ xt_unregister_target(int af, struct xt_target *target) EXPORT_SYMBOL(xt_unregister_target); int -xt_register_match(int af, struct xt_match *match) +xt_register_match(struct xt_match *match) { - int ret; + int ret, af = match->family; ret = down_interruptible(&xt[af].mutex); if (ret != 0) @@ -99,8 +101,10 @@ xt_register_match(int af, struct xt_match *match) EXPORT_SYMBOL(xt_register_match); void -xt_unregister_match(int af, struct xt_match *match) +xt_unregister_match(struct xt_match *match) { + int af = match->family; + down(&xt[af].mutex); LIST_DELETE(&xt[af].match, match); up(&xt[af].mutex); diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c index 3224ed87d4c71b4f2fc597c3a65ff69348fe6f3e..3cd2ac90a25b3ad6318f247fdd68e6283a79f5a7 100644 --- a/net/netfilter/xt_CLASSIFY.c +++ b/net/netfilter/xt_CLASSIFY.c @@ -47,6 +47,7 @@ static struct xt_target classify_reg = { .table = "mangle", .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING), + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_target classify6_reg = { @@ -56,6 +57,7 @@ static struct xt_target classify6_reg = { .table = "mangle", .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING), + .family = AF_INET6, .me = THIS_MODULE, }; @@ -64,21 +66,21 @@ static int __init init(void) { int ret; - ret = xt_register_target(AF_INET, &classify_reg); + ret = xt_register_target(&classify_reg); if (ret) return ret; - ret = xt_register_target(AF_INET6, &classify6_reg); + ret = xt_register_target(&classify6_reg); if (ret) - xt_unregister_target(AF_INET, &classify_reg); + xt_unregister_target(&classify_reg); return ret; } static void __exit fini(void) { - xt_unregister_target(AF_INET, &classify_reg); - xt_unregister_target(AF_INET6, &classify6_reg); + xt_unregister_target(&classify_reg); + xt_unregister_target(&classify6_reg); } module_init(init); diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index df2486a3efd542700dbac7a7972b925e92618485..35448b8e68835879aba19fc105f660bd56c0cf88 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c @@ -102,6 +102,7 @@ static struct xt_target connmark_reg = { .target = target, .targetsize = sizeof(struct xt_connmark_target_info), .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE }; @@ -110,6 +111,7 @@ static struct xt_target connmark6_reg = { .target = target, .targetsize = sizeof(struct xt_connmark_target_info), .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE }; @@ -119,21 +121,21 @@ static int __init init(void) need_conntrack(); - ret = xt_register_target(AF_INET, &connmark_reg); + ret = xt_register_target(&connmark_reg); if (ret) return ret; - ret = xt_register_target(AF_INET6, &connmark6_reg); + ret = xt_register_target(&connmark6_reg); if (ret) - xt_unregister_target(AF_INET, &connmark_reg); + xt_unregister_target(&connmark_reg); return ret; } static void __exit fini(void) { - xt_unregister_target(AF_INET, &connmark_reg); - xt_unregister_target(AF_INET6, &connmark6_reg); + xt_unregister_target(&connmark_reg); + xt_unregister_target(&connmark6_reg); } module_init(init); diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c index dcb5266efae08419f0c1e1ee166a89e87377e8ef..73bdd5c80e174bb29997de73f34096c9fa7220fa 100644 --- a/net/netfilter/xt_MARK.c +++ b/net/netfilter/xt_MARK.c @@ -119,6 +119,7 @@ static struct xt_target ipt_mark_reg_v0 = { .table = "mangle", .checkentry = checkentry_v0, .me = THIS_MODULE, + .family = AF_INET, .revision = 0, }; @@ -129,6 +130,7 @@ static struct xt_target ipt_mark_reg_v1 = { .table = "mangle", .checkentry = checkentry_v1, .me = THIS_MODULE, + .family = AF_INET, .revision = 1, }; @@ -139,6 +141,7 @@ static struct xt_target ip6t_mark_reg_v0 = { .table = "mangle", .checkentry = checkentry_v0, .me = THIS_MODULE, + .family = AF_INET6, .revision = 0, }; @@ -146,18 +149,18 @@ static int __init init(void) { int err; - err = xt_register_target(AF_INET, &ipt_mark_reg_v0); + err = xt_register_target(&ipt_mark_reg_v0); if (err) return err; - err = xt_register_target(AF_INET, &ipt_mark_reg_v1); + err = xt_register_target(&ipt_mark_reg_v1); if (err) - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); + xt_unregister_target(&ipt_mark_reg_v0); - err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); + err = xt_register_target(&ip6t_mark_reg_v0); if (err) { - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); - xt_unregister_target(AF_INET, &ipt_mark_reg_v1); + xt_unregister_target(&ipt_mark_reg_v0); + xt_unregister_target(&ipt_mark_reg_v1); } return err; @@ -165,9 +168,9 @@ static int __init init(void) static void __exit fini(void) { - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); - xt_unregister_target(AF_INET, &ipt_mark_reg_v1); - xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); + xt_unregister_target(&ipt_mark_reg_v0); + xt_unregister_target(&ipt_mark_reg_v1); + xt_unregister_target(&ip6t_mark_reg_v0); } module_init(init); diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c index 39a963edf16b7651a916dc1b329892dea1211705..2873e1c60f686484feb2eae991edcf9e18ec04e3 100644 --- a/net/netfilter/xt_NFQUEUE.c +++ b/net/netfilter/xt_NFQUEUE.c @@ -41,6 +41,7 @@ static struct xt_target ipt_NFQ_reg = { .name = "NFQUEUE", .target = target, .targetsize = sizeof(struct xt_NFQ_info), + .family = AF_INET, .me = THIS_MODULE, }; @@ -48,6 +49,7 @@ static struct xt_target ip6t_NFQ_reg = { .name = "NFQUEUE", .target = target, .targetsize = sizeof(struct xt_NFQ_info), + .family = AF_INET6, .me = THIS_MODULE, }; @@ -55,36 +57,37 @@ static struct xt_target arpt_NFQ_reg = { .name = "NFQUEUE", .target = target, .targetsize = sizeof(struct xt_NFQ_info), + .family = NF_ARP, .me = THIS_MODULE, }; static int __init init(void) { int ret; - ret = xt_register_target(AF_INET, &ipt_NFQ_reg); + ret = xt_register_target(&ipt_NFQ_reg); if (ret) return ret; - ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); + ret = xt_register_target(&ip6t_NFQ_reg); if (ret) goto out_ip; - ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); + ret = xt_register_target(&arpt_NFQ_reg); if (ret) goto out_ip6; return ret; out_ip6: - xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); + xt_unregister_target(&ip6t_NFQ_reg); out_ip: - xt_unregister_target(AF_INET, &ipt_NFQ_reg); + xt_unregister_target(&ipt_NFQ_reg); return ret; } static void __exit fini(void) { - xt_unregister_target(NF_ARP, &arpt_NFQ_reg); - xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); - xt_unregister_target(AF_INET, &ipt_NFQ_reg); + xt_unregister_target(&arpt_NFQ_reg); + xt_unregister_target(&ip6t_NFQ_reg); + xt_unregister_target(&ipt_NFQ_reg); } module_init(init); diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c index b8634e3f616955854db853c96de47fa972472b8d..cf2ebd76fd6f6e3dc8c64eae2ae7b8ac3440e501 100644 --- a/net/netfilter/xt_NOTRACK.c +++ b/net/netfilter/xt_NOTRACK.c @@ -39,6 +39,7 @@ static struct xt_target notrack_reg = { .target = target, .targetsize = 0, .table = "raw", + .family = AF_INET, .me = THIS_MODULE, }; @@ -47,6 +48,7 @@ static struct xt_target notrack6_reg = { .target = target, .targetsize = 0, .table = "raw", + .family = AF_INET6, .me = THIS_MODULE, }; @@ -54,21 +56,21 @@ static int __init init(void) { int ret; - ret = xt_register_target(AF_INET, ¬rack_reg); + ret = xt_register_target(¬rack_reg); if (ret) return ret; - ret = xt_register_target(AF_INET6, ¬rack6_reg); + ret = xt_register_target(¬rack6_reg); if (ret) - xt_unregister_target(AF_INET, ¬rack_reg); + xt_unregister_target(¬rack_reg); return ret; } static void __exit fini(void) { - xt_unregister_target(AF_INET6, ¬rack6_reg); - xt_unregister_target(AF_INET, ¬rack_reg); + xt_unregister_target(¬rack6_reg); + xt_unregister_target(¬rack_reg); } module_init(init); diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c index 03d9d741231c6881b9e0be81bd5aceb85971b9a6..2637724b498dc3f96ff4e21b838d789918f46f1e 100644 --- a/net/netfilter/xt_comment.c +++ b/net/netfilter/xt_comment.c @@ -33,6 +33,7 @@ static struct xt_match comment_match = { .name = "comment", .match = match, .matchsize = sizeof(struct xt_comment_info), + .family = AF_INET, .me = THIS_MODULE }; @@ -40,6 +41,7 @@ static struct xt_match comment6_match = { .name = "comment", .match = match, .matchsize = sizeof(struct xt_comment_info), + .family = AF_INET6, .me = THIS_MODULE }; @@ -47,21 +49,21 @@ static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &comment_match); + ret = xt_register_match(&comment_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &comment6_match); + ret = xt_register_match(&comment6_match); if (ret) - xt_unregister_match(AF_INET, &comment_match); + xt_unregister_match(&comment_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &comment_match); - xt_unregister_match(AF_INET6, &comment6_match); + xt_unregister_match(&comment_match); + xt_unregister_match(&comment6_match); } module_init(init); diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index f34ecb9485c7f820047b8ac9d5207a0a2676cc30..4985f5ec58caa3aac0f2135450805c1d7ed192f2 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -148,6 +148,7 @@ static struct xt_match connbytes_match = { .match = match, .checkentry = check, .matchsize = sizeof(struct xt_connbytes_info), + .family = AF_INET, .me = THIS_MODULE }; static struct xt_match connbytes6_match = { @@ -155,26 +156,27 @@ static struct xt_match connbytes6_match = { .match = match, .checkentry = check, .matchsize = sizeof(struct xt_connbytes_info), + .family = AF_INET6, .me = THIS_MODULE }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &connbytes_match); + ret = xt_register_match(&connbytes_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &connbytes6_match); + ret = xt_register_match(&connbytes6_match); if (ret) - xt_unregister_match(AF_INET, &connbytes_match); + xt_unregister_match(&connbytes_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &connbytes_match); - xt_unregister_match(AF_INET6, &connbytes6_match); + xt_unregister_match(&connbytes_match); + xt_unregister_match(&connbytes6_match); } module_init(init); diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index 51822471e919136220e5e8b8349eaeb9ef33ee3f..7b16f1ee16b4a8c78f4b8810e4a78194c2afe150 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c @@ -64,14 +64,31 @@ checkentry(const char *tablename, printk(KERN_WARNING "connmark: only support 32bit mark\n"); return 0; } +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (nf_ct_l3proto_try_module_get(match->family) < 0) { + printk(KERN_WARNING "can't load nf_conntrack support for " + "proto=%d\n", match->family); + return 0; + } +#endif return 1; } +static void +destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_ct_l3proto_module_put(match->family); +#endif +} + static struct xt_match connmark_match = { .name = "connmark", .match = match, .matchsize = sizeof(struct xt_connmark_info), .checkentry = checkentry, + .destroy = destroy, + .family = AF_INET, .me = THIS_MODULE }; @@ -80,6 +97,8 @@ static struct xt_match connmark6_match = { .match = match, .matchsize = sizeof(struct xt_connmark_info), .checkentry = checkentry, + .destroy = destroy, + .family = AF_INET6, .me = THIS_MODULE }; @@ -89,20 +108,20 @@ static int __init init(void) need_conntrack(); - ret = xt_register_match(AF_INET, &connmark_match); + ret = xt_register_match(&connmark_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &connmark6_match); + ret = xt_register_match(&connmark6_match); if (ret) - xt_unregister_match(AF_INET, &connmark_match); + xt_unregister_match(&connmark_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &connmark6_match); - xt_unregister_match(AF_INET, &connmark_match); + xt_unregister_match(&connmark6_match); + xt_unregister_match(&connmark_match); } module_init(init); diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 39fc29496e00dcd1ffe529c0113f31be989d6ffb..65a84809fd3054a7c47eb3363c8146136eeb285e 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -203,10 +203,39 @@ match(const struct sk_buff *skb, #endif /* CONFIG_NF_IP_CONNTRACK */ +static int +checkentry(const char *tablename, + const void *ip, + const struct xt_match *match, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (nf_ct_l3proto_try_module_get(match->family) < 0) { + printk(KERN_WARNING "can't load nf_conntrack support for " + "proto=%d\n", match->family); + return 0; + } +#endif + return 1; +} + +static void +destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_ct_l3proto_module_put(match->family); +#endif +} + static struct xt_match conntrack_match = { .name = "conntrack", .match = match, + .checkentry = checkentry, + .destroy = destroy, .matchsize = sizeof(struct xt_conntrack_info), + .family = AF_INET, .me = THIS_MODULE, }; @@ -214,14 +243,14 @@ static int __init init(void) { int ret; need_conntrack(); - ret = xt_register_match(AF_INET, &conntrack_match); + ret = xt_register_match(&conntrack_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &conntrack_match); + xt_unregister_match(&conntrack_match); } module_init(init); diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c index db6b70cdc7708c3c2afd192ff4163ed09564f6a3..2f331decd151fb6bef15a94ce9d7e1db94f26859 100644 --- a/net/netfilter/xt_dccp.c +++ b/net/netfilter/xt_dccp.c @@ -149,6 +149,7 @@ static struct xt_match dccp_match = .matchsize = sizeof(struct xt_dccp_info), .proto = IPPROTO_DCCP, .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_match dccp6_match = @@ -158,6 +159,7 @@ static struct xt_match dccp6_match = .matchsize = sizeof(struct xt_dccp_info), .proto = IPPROTO_DCCP, .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -172,17 +174,17 @@ static int __init init(void) dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); if (!dccp_optbuf) return -ENOMEM; - ret = xt_register_match(AF_INET, &dccp_match); + ret = xt_register_match(&dccp_match); if (ret) goto out_kfree; - ret = xt_register_match(AF_INET6, &dccp6_match); + ret = xt_register_match(&dccp6_match); if (ret) goto out_unreg; return ret; out_unreg: - xt_unregister_match(AF_INET, &dccp_match); + xt_unregister_match(&dccp_match); out_kfree: kfree(dccp_optbuf); @@ -191,8 +193,8 @@ static int __init init(void) static void __exit fini(void) { - xt_unregister_match(AF_INET6, &dccp6_match); - xt_unregister_match(AF_INET, &dccp_match); + xt_unregister_match(&dccp6_match); + xt_unregister_match(&dccp_match); kfree(dccp_optbuf); } diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index ef8e54d40c9225afbe95d99e702f7136d56c7e29..101f0005e987556d50b2dfbfcdd92abb4fe1f2e7 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c @@ -144,15 +144,32 @@ static int check(const char *tablename, { struct xt_helper_info *info = matchinfo; +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (nf_ct_l3proto_try_module_get(match->family) < 0) { + printk(KERN_WARNING "can't load nf_conntrack support for " + "proto=%d\n", match->family); + return 0; + } +#endif info->name[29] = '\0'; return 1; } +static void +destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_ct_l3proto_module_put(match->family); +#endif +} + static struct xt_match helper_match = { .name = "helper", .match = match, .matchsize = sizeof(struct xt_helper_info), .checkentry = check, + .destroy = destroy, + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_match helper6_match = { @@ -160,6 +177,8 @@ static struct xt_match helper6_match = { .match = match, .matchsize = sizeof(struct xt_helper_info), .checkentry = check, + .destroy = destroy, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -168,21 +187,21 @@ static int __init init(void) int ret; need_conntrack(); - ret = xt_register_match(AF_INET, &helper_match); + ret = xt_register_match(&helper_match); if (ret < 0) return ret; - ret = xt_register_match(AF_INET6, &helper6_match); + ret = xt_register_match(&helper6_match); if (ret < 0) - xt_unregister_match(AF_INET, &helper_match); + xt_unregister_match(&helper_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &helper_match); - xt_unregister_match(AF_INET6, &helper6_match); + xt_unregister_match(&helper_match); + xt_unregister_match(&helper6_match); } module_init(init); diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c index b9e60f041a64d19f5bf41bead3cccb95d86942cc..38560caef7573daef536d9694d7ce1e8ab361653 100644 --- a/net/netfilter/xt_length.c +++ b/net/netfilter/xt_length.c @@ -56,6 +56,7 @@ static struct xt_match length_match = { .name = "length", .match = match, .matchsize = sizeof(struct xt_length_info), + .family = AF_INET, .me = THIS_MODULE, }; @@ -63,26 +64,27 @@ static struct xt_match length6_match = { .name = "length", .match = match6, .matchsize = sizeof(struct xt_length_info), + .family = AF_INET6, .me = THIS_MODULE, }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &length_match); + ret = xt_register_match(&length_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &length6_match); + ret = xt_register_match(&length6_match); if (ret) - xt_unregister_match(AF_INET, &length_match); + xt_unregister_match(&length_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &length_match); - xt_unregister_match(AF_INET6, &length6_match); + xt_unregister_match(&length_match); + xt_unregister_match(&length6_match); } module_init(init); diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 3049e6f8889e57fe466c1bcdfe91f6cec31cb895..e91c1a444e7798255860c6b50071641aad7c3eca 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c @@ -141,6 +141,7 @@ static struct xt_match ipt_limit_reg = { .match = ipt_limit_match, .matchsize = sizeof(struct xt_rateinfo), .checkentry = ipt_limit_checkentry, + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_match limit6_reg = { @@ -148,6 +149,7 @@ static struct xt_match limit6_reg = { .match = ipt_limit_match, .matchsize = sizeof(struct xt_rateinfo), .checkentry = ipt_limit_checkentry, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -155,21 +157,21 @@ static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &ipt_limit_reg); + ret = xt_register_match(&ipt_limit_reg); if (ret) return ret; - ret = xt_register_match(AF_INET6, &limit6_reg); + ret = xt_register_match(&limit6_reg); if (ret) - xt_unregister_match(AF_INET, &ipt_limit_reg); + xt_unregister_match(&ipt_limit_reg); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &ipt_limit_reg); - xt_unregister_match(AF_INET6, &limit6_reg); + xt_unregister_match(&ipt_limit_reg); + xt_unregister_match(&limit6_reg); } module_init(init); diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c index b4559a46dce8308df295a1cb29b20226b9b42cc9..f4defa28a6ecffa05b9e74e05ee9b70342c239f5 100644 --- a/net/netfilter/xt_mac.c +++ b/net/netfilter/xt_mac.c @@ -49,6 +49,7 @@ static struct xt_match mac_match = { .matchsize = sizeof(struct xt_mac_info), .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_match mac6_match = { @@ -57,27 +58,28 @@ static struct xt_match mac6_match = { .matchsize = sizeof(struct xt_mac_info), .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), + .family = AF_INET6, .me = THIS_MODULE, }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &mac_match); + ret = xt_register_match(&mac_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &mac6_match); + ret = xt_register_match(&mac6_match); if (ret) - xt_unregister_match(AF_INET, &mac_match); + xt_unregister_match(&mac_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &mac_match); - xt_unregister_match(AF_INET6, &mac6_match); + xt_unregister_match(&mac_match); + xt_unregister_match(&mac6_match); } module_init(init); diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c index c1a8f0f587f03ea18c515a1b4dde1e16b02583c6..ce0badfeef9a77e910fe2bdf78c4c41207647ec0 100644 --- a/net/netfilter/xt_mark.c +++ b/net/netfilter/xt_mark.c @@ -56,6 +56,7 @@ static struct xt_match mark_match = { .match = match, .matchsize = sizeof(struct xt_mark_info), .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE, }; @@ -64,27 +65,28 @@ static struct xt_match mark6_match = { .match = match, .matchsize = sizeof(struct xt_mark_info), .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE, }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &mark_match); + ret = xt_register_match(&mark_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &mark6_match); + ret = xt_register_match(&mark6_match); if (ret) - xt_unregister_match(AF_INET, &mark_match); + xt_unregister_match(&mark_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &mark_match); - xt_unregister_match(AF_INET6, &mark6_match); + xt_unregister_match(&mark_match); + xt_unregister_match(&mark6_match); } module_init(init); diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index f788e8e762540aad0409e55d1b632fd618005b6b..089f4f7e8636a326dfa49e63b098c48038620eb9 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c @@ -121,6 +121,7 @@ static struct xt_match physdev_match = { .match = match, .matchsize = sizeof(struct xt_physdev_info), .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE, }; @@ -129,6 +130,7 @@ static struct xt_match physdev6_match = { .match = match, .matchsize = sizeof(struct xt_physdev_info), .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -136,21 +138,21 @@ static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &physdev_match); + ret = xt_register_match(&physdev_match); if (ret < 0) return ret; - ret = xt_register_match(AF_INET6, &physdev6_match); + ret = xt_register_match(&physdev6_match); if (ret < 0) - xt_unregister_match(AF_INET, &physdev_match); + xt_unregister_match(&physdev_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &physdev_match); - xt_unregister_match(AF_INET6, &physdev6_match); + xt_unregister_match(&physdev_match); + xt_unregister_match(&physdev6_match); } module_init(init); diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c index f38638dfd139e55beba2af0ada34a59fdb674566..8b8bca988ac68834068745afb9062cdccf271258 100644 --- a/net/netfilter/xt_pkttype.c +++ b/net/netfilter/xt_pkttype.c @@ -37,6 +37,7 @@ static struct xt_match pkttype_match = { .name = "pkttype", .match = match, .matchsize = sizeof(struct xt_pkttype_info), + .family = AF_INET, .me = THIS_MODULE, }; @@ -44,27 +45,28 @@ static struct xt_match pkttype6_match = { .name = "pkttype", .match = match, .matchsize = sizeof(struct xt_pkttype_info), + .family = AF_INET6, .me = THIS_MODULE, }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &pkttype_match); + ret = xt_register_match(&pkttype_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &pkttype6_match); + ret = xt_register_match(&pkttype6_match); if (ret) - xt_unregister_match(AF_INET, &pkttype_match); + xt_unregister_match(&pkttype_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &pkttype_match); - xt_unregister_match(AF_INET6, &pkttype6_match); + xt_unregister_match(&pkttype_match); + xt_unregister_match(&pkttype6_match); } module_init(init); diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c index 1ec22082f04d48b12e7b2ae6d98217704db861b5..1099cb005fcc3c7dbf4a8ca4795862f2b093b1e0 100644 --- a/net/netfilter/xt_policy.c +++ b/net/netfilter/xt_policy.c @@ -27,9 +27,9 @@ xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m, { switch (family) { case AF_INET: - return (a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr; + return !((a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr); case AF_INET6: - return ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6); + return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6); } return 0; } @@ -44,7 +44,7 @@ match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e, #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) && - MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr.a4) && + MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr) && MATCH(proto, x->id.proto) && MATCH(mode, x->props.mode) && MATCH(spi, x->id.spi) && @@ -172,6 +172,7 @@ static struct xt_match policy_match = { .match = match, .matchsize = sizeof(struct xt_policy_info), .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE, }; @@ -181,6 +182,7 @@ static struct xt_match policy6_match = { .match = match, .matchsize = sizeof(struct xt_policy_info), .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -188,19 +190,19 @@ static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &policy_match); + ret = xt_register_match(&policy_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &policy6_match); + ret = xt_register_match(&policy6_match); if (ret) - xt_unregister_match(AF_INET, &policy_match); + xt_unregister_match(&policy_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &policy6_match); - xt_unregister_match(AF_INET, &policy_match); + xt_unregister_match(&policy6_match); + xt_unregister_match(&policy_match); } module_init(init); diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c index 57815a07db678f10deb558e5fc822cb9cde790d9..5e31a4a835bfd32d5c1dc12a49f61f5eb5573031 100644 --- a/net/netfilter/xt_realm.c +++ b/net/netfilter/xt_realm.c @@ -45,17 +45,18 @@ static struct xt_match realm_match = { .matchsize = sizeof(struct xt_realm_info), .hooks = (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN), + .family = AF_INET, .me = THIS_MODULE }; static int __init init(void) { - return xt_register_match(AF_INET, &realm_match); + return xt_register_match(&realm_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &realm_match); + xt_unregister_match(&realm_match); } module_init(init); diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c index f5d698ba03ca612c29edb2d7bcca17ff6900adff..c6eb24a2fe13e2eb90e48253d580daaf673e71b5 100644 --- a/net/netfilter/xt_sctp.c +++ b/net/netfilter/xt_sctp.c @@ -186,6 +186,7 @@ static struct xt_match sctp_match = { .matchsize = sizeof(struct xt_sctp_info), .proto = IPPROTO_SCTP, .checkentry = checkentry, + .family = AF_INET, .me = THIS_MODULE }; @@ -195,27 +196,28 @@ static struct xt_match sctp6_match = { .matchsize = sizeof(struct xt_sctp_info), .proto = IPPROTO_SCTP, .checkentry = checkentry, + .family = AF_INET6, .me = THIS_MODULE }; static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &sctp_match); + ret = xt_register_match(&sctp_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &sctp6_match); + ret = xt_register_match(&sctp6_match); if (ret) - xt_unregister_match(AF_INET, &sctp_match); + xt_unregister_match(&sctp_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &sctp6_match); - xt_unregister_match(AF_INET, &sctp_match); + xt_unregister_match(&sctp6_match); + xt_unregister_match(&sctp_match); } module_init(init); diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index b8ec00cd51fc1d16b4c04c17dbbbed0e5b57af0b..e6c0be9d94d2130cf076bd1f47b00aa867dd7406 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c @@ -44,17 +44,48 @@ match(const struct sk_buff *skb, return (sinfo->statemask & statebit); } +static int check(const char *tablename, + const void *inf, + const struct xt_match *match, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (nf_ct_l3proto_try_module_get(match->family) < 0) { + printk(KERN_WARNING "can't load nf_conntrack support for " + "proto=%d\n", match->family); + return 0; + } +#endif + return 1; +} + +static void +destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_ct_l3proto_module_put(match->family); +#endif +} + static struct xt_match state_match = { .name = "state", .match = match, + .checkentry = check, + .destroy = destroy, .matchsize = sizeof(struct xt_state_info), + .family = AF_INET, .me = THIS_MODULE, }; static struct xt_match state6_match = { .name = "state", .match = match, + .checkentry = check, + .destroy = destroy, .matchsize = sizeof(struct xt_state_info), + .family = AF_INET6, .me = THIS_MODULE, }; @@ -64,21 +95,21 @@ static int __init init(void) need_conntrack(); - ret = xt_register_match(AF_INET, &state_match); + ret = xt_register_match(&state_match); if (ret < 0) return ret; - ret = xt_register_match(AF_INET6, &state6_match); + ret = xt_register_match(&state6_match); if (ret < 0) - xt_unregister_match(AF_INET,&state_match); + xt_unregister_match(&state_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &state_match); - xt_unregister_match(AF_INET6, &state6_match); + xt_unregister_match(&state_match); + xt_unregister_match(&state6_match); } module_init(init); diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index fccbad6a7f402ab9fba0f418dd9ffbe3f2be0d70..703d80fccacfe6e77417afe68c46fc6815750253 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c @@ -78,6 +78,7 @@ static struct xt_match string_match = { .matchsize = sizeof(struct xt_string_info), .checkentry = checkentry, .destroy = destroy, + .family = AF_INET, .me = THIS_MODULE }; static struct xt_match string6_match = { @@ -86,6 +87,7 @@ static struct xt_match string6_match = { .matchsize = sizeof(struct xt_string_info), .checkentry = checkentry, .destroy = destroy, + .family = AF_INET6, .me = THIS_MODULE }; @@ -93,20 +95,20 @@ static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &string_match); + ret = xt_register_match(&string_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &string6_match); + ret = xt_register_match(&string6_match); if (ret) - xt_unregister_match(AF_INET, &string_match); + xt_unregister_match(&string_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &string_match); - xt_unregister_match(AF_INET6, &string6_match); + xt_unregister_match(&string_match); + xt_unregister_match(&string6_match); } module_init(init); diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c index 4925fc98f4aeadca025c3aaec83b105949dab5d2..70a8858ae3f17f052e104ee5afc739a1e4bb9bdf 100644 --- a/net/netfilter/xt_tcpmss.c +++ b/net/netfilter/xt_tcpmss.c @@ -98,6 +98,7 @@ static struct xt_match tcpmss_match = { .match = match, .matchsize = sizeof(struct xt_tcpmss_match_info), .proto = IPPROTO_TCP, + .family = AF_INET, .me = THIS_MODULE, }; @@ -106,6 +107,7 @@ static struct xt_match tcpmss6_match = { .match = match, .matchsize = sizeof(struct xt_tcpmss_match_info), .proto = IPPROTO_TCP, + .family = AF_INET6, .me = THIS_MODULE, }; @@ -113,21 +115,21 @@ static struct xt_match tcpmss6_match = { static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &tcpmss_match); + ret = xt_register_match(&tcpmss_match); if (ret) return ret; - ret = xt_register_match(AF_INET6, &tcpmss6_match); + ret = xt_register_match(&tcpmss6_match); if (ret) - xt_unregister_match(AF_INET, &tcpmss_match); + xt_unregister_match(&tcpmss_match); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &tcpmss6_match); - xt_unregister_match(AF_INET, &tcpmss_match); + xt_unregister_match(&tcpmss6_match); + xt_unregister_match(&tcpmss_match); } module_init(init); diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c index b5cd0dd4e41fa270abf3fffeda2b9e16f79e6f7c..14a990eb666ae2a7496d91b745d698a1c49be7b4 100644 --- a/net/netfilter/xt_tcpudp.c +++ b/net/netfilter/xt_tcpudp.c @@ -204,6 +204,7 @@ static struct xt_match tcp_matchstruct = { .match = tcp_match, .matchsize = sizeof(struct xt_tcp), .proto = IPPROTO_TCP, + .family = AF_INET, .checkentry = tcp_checkentry, .me = THIS_MODULE, }; @@ -213,6 +214,7 @@ static struct xt_match tcp6_matchstruct = { .match = tcp_match, .matchsize = sizeof(struct xt_tcp), .proto = IPPROTO_TCP, + .family = AF_INET6, .checkentry = tcp_checkentry, .me = THIS_MODULE, }; @@ -222,6 +224,7 @@ static struct xt_match udp_matchstruct = { .match = udp_match, .matchsize = sizeof(struct xt_udp), .proto = IPPROTO_UDP, + .family = AF_INET, .checkentry = udp_checkentry, .me = THIS_MODULE, }; @@ -230,6 +233,7 @@ static struct xt_match udp6_matchstruct = { .match = udp_match, .matchsize = sizeof(struct xt_udp), .proto = IPPROTO_UDP, + .family = AF_INET6, .checkentry = udp_checkentry, .me = THIS_MODULE, }; @@ -237,39 +241,39 @@ static struct xt_match udp6_matchstruct = { static int __init init(void) { int ret; - ret = xt_register_match(AF_INET, &tcp_matchstruct); + ret = xt_register_match(&tcp_matchstruct); if (ret) return ret; - ret = xt_register_match(AF_INET6, &tcp6_matchstruct); + ret = xt_register_match(&tcp6_matchstruct); if (ret) goto out_unreg_tcp; - ret = xt_register_match(AF_INET, &udp_matchstruct); + ret = xt_register_match(&udp_matchstruct); if (ret) goto out_unreg_tcp6; - ret = xt_register_match(AF_INET6, &udp6_matchstruct); + ret = xt_register_match(&udp6_matchstruct); if (ret) goto out_unreg_udp; return ret; out_unreg_udp: - xt_unregister_match(AF_INET, &tcp_matchstruct); + xt_unregister_match(&tcp_matchstruct); out_unreg_tcp6: - xt_unregister_match(AF_INET6, &tcp6_matchstruct); + xt_unregister_match(&tcp6_matchstruct); out_unreg_tcp: - xt_unregister_match(AF_INET, &tcp_matchstruct); + xt_unregister_match(&tcp_matchstruct); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &udp6_matchstruct); - xt_unregister_match(AF_INET, &udp_matchstruct); - xt_unregister_match(AF_INET6, &tcp6_matchstruct); - xt_unregister_match(AF_INET, &tcp_matchstruct); + xt_unregister_match(&udp6_matchstruct); + xt_unregister_match(&udp_matchstruct); + xt_unregister_match(&tcp6_matchstruct); + xt_unregister_match(&tcp_matchstruct); } module_init(init);