[PATCH nf-next] netfilter: Remove useless param helper of nf_ct_helper_ext_add
From: Gao Feng The param helper of nf_ct_helper_ext_add is useless now, then remove it now. Signed-off-by: Gao Feng --- include/net/netfilter/nf_conntrack_helper.h | 4 +--- net/netfilter/nf_conntrack_core.c | 3 +-- net/netfilter/nf_conntrack_helper.c | 5 ++--- net/netfilter/nf_conntrack_netlink.c| 2 +- net/netfilter/nft_ct.c | 2 +- net/netfilter/xt_CT.c | 2 +- net/openvswitch/conntrack.c | 2 +- 7 files changed, 8 insertions(+), 12 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 32c2a94..2492120 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -103,9 +103,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, void nf_conntrack_helpers_unregister(struct nf_conntrack_helper *, unsigned int); -struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, - struct nf_conntrack_helper *helper, - gfp_t gfp); +struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp); int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, gfp_t flags); diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 6c2d22d..2d01dd5 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1387,8 +1387,7 @@ void nf_conntrack_free(struct nf_conn *ct) /* exp->master safe, refcnt bumped in nf_ct_find_expectation */ ct->master = exp->master; if (exp->helper) { - help = nf_ct_helper_ext_add(ct, exp->helper, - GFP_ATOMIC); + help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); if (help) rcu_assign_pointer(help->helper, exp->helper); } diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index eaa3565..571f97f 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -192,8 +192,7 @@ void nf_conntrack_helper_put(struct nf_conntrack_helper *helper) EXPORT_SYMBOL_GPL(nf_conntrack_helper_put); struct nf_conn_help * -nf_ct_helper_ext_add(struct nf_conn *ct, -struct nf_conntrack_helper *helper, gfp_t gfp) +nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) { struct nf_conn_help *help; @@ -262,7 +261,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, } if (help == NULL) { - help = nf_ct_helper_ext_add(ct, helper, flags); + help = nf_ct_helper_ext_add(ct, flags); if (help == NULL) return -ENOMEM; } else { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 40152b9..f981bfa 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1947,7 +1947,7 @@ static int ctnetlink_change_synproxy(struct nf_conn *ct, } else { struct nf_conn_help *help; - help = nf_ct_helper_ext_add(ct, helper, GFP_ATOMIC); + help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); if (help == NULL) { err = -ENOMEM; goto err2; diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 1435ffc..3bc82ee 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -870,7 +870,7 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj, if (test_bit(IPS_HELPER_BIT, &ct->status)) return; - help = nf_ct_helper_ext_add(ct, to_assign, GFP_ATOMIC); + help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); if (help) { rcu_assign_pointer(help->helper, to_assign); set_bit(IPS_HELPER_BIT, &ct->status); diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 03b9a50..7ba454e 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -93,7 +93,7 @@ static u8 xt_ct_find_proto(const struct xt_tgchk_param *par) return -ENOENT; } - help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL); + help = nf_ct_helper_ext_add(ct, GFP_KERNEL); if (help == NULL) { nf_conntrack_helper_put(helper); return -ENOMEM; diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index e05bd3e..3e33c38 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -1303,7 +1303,7 @@ static int ovs_ct_
[PATCH nf] netfilter: helper: Fix possible panic after nf_conntrack_helper_unregister
From: Gao Feng The helper module would be unloaded after nf_conntrack_helper_unregister, so it may cause a possible panic caused by race. nf_ct_iterate_destroy(unhelp, me) reset the helper of conntrack as NULL, but maybe someone has gotten the helper pointer during this period. Then it would panic, when it accesses the helper and the module was unloaded. Take an example as following: CPU0 CPU1 ctnetlink_dump_helpinfo helper = rcu_dereference(help->helper); unhelp set helper as NULL unload helper module helper->to_nlattr(skb, ct); As above, the cpu0 tries to access the helper and its module is unloaded, then the panic happens. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_helper.c | 5 + 1 file changed, 5 insertions(+) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 551a1ed..b5b655d 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -465,6 +465,11 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) nf_ct_expect_iterate_destroy(expect_iter_me, NULL); nf_ct_iterate_destroy(unhelp, me); + + /* Maybe someone has gotten the helper already when unhelp above. +* So need to wait it. +*/ + synchronize_rcu(); } EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next] netfilter: nf_conntrack: Increase __IPS_MAX_BIT with new bit IPS_OFFLOAD_BIT
From: Gao Feng The __IPS_MAX_BIT is used in __ctnetlink_change_status as the max bit value. When add new bit IPS_OFFLOAD_BIT whose value is 14, we should increase the __IPS_MAX_BIT too, from 14 to 15. There is no any bug in current codes, although it lost one loop in __ctnetlink_change_status. Because the new bit IPS_OFFLOAD_BIT belongs the IPS_UNCHANGEABLE_MASK. Signed-off-by: Gao Feng --- include/uapi/linux/netfilter/nf_conntrack_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h index c712eb6..336014b 100644 --- a/include/uapi/linux/netfilter/nf_conntrack_common.h +++ b/include/uapi/linux/netfilter/nf_conntrack_common.h @@ -112,7 +112,7 @@ enum ip_conntrack_status { IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_OFFLOAD), - __IPS_MAX_BIT = 14, + __IPS_MAX_BIT = 15, }; /* Connection tracking event types */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2] netfilter: xt_CT: Reject the non-null terminated string from user space
From: Gao Feng The helper and timeout strings are from user-space, we need to make sure they are null terminated. If not, evil user could make kernel read the unexpected memory, even print it when fail to find by the following codes. pr_info_ratelimited("No such helper \"%s\"\n", helper_name); Signed-off-by: Gao Feng --- v2: reject the non-null terminated string directly, per Pablo v1: initial version net/netfilter/xt_CT.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 8790190..03b9a50 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -245,12 +245,22 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, } if (info->helper[0]) { + if (strnlen(info->helper, sizeof(info->helper)) == sizeof(info->helper)) { + ret = -ENAMETOOLONG; + goto err3; + } + ret = xt_ct_set_helper(ct, info->helper, par); if (ret < 0) goto err3; } if (info->timeout[0]) { + if (strnlen(info->timeout, sizeof(info->timeout)) == sizeof(info->timeout)) { + ret = -ENAMETOOLONG; + goto err4; + } + ret = xt_ct_set_timeout(ct, par, info->timeout); if (ret < 0) goto err4; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf] netfilter: xt_CT: Force user-space strings as null terminated
From: Gao Feng The helper and timeout strings are from user-space, we need to make sure they are null terminated. If not, evil user could make kernel read the unexpected memory, even print it when fail to find by the following codes. pr_info_ratelimited("No such helper \"%s\"\n", helper_name); Signed-off-by: Gao Feng --- net/netfilter/xt_CT.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 8790190..f4b7d31 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -245,12 +245,14 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, } if (info->helper[0]) { + info->helper[sizeof(info->helper) - 1] = '\0'; ret = xt_ct_set_helper(ct, info->helper, par); if (ret < 0) goto err3; } if (info->timeout[0]) { + info->timeout[sizeof(info->timeout) - 1] = '\0'; ret = xt_ct_set_timeout(ct, par, info->timeout); if (ret < 0) goto err4; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next] netfilter: ipvs: Remove useless ipvsh param of frag_safe_skb_hp
From: Gao Feng The param of frag_safe_skb_hp, ipvsh, isn't used now. So remove it and update the callers' codes too. Signed-off-by: Gao Feng --- Simon advise me send the patch to netfilter group include/net/ip_vs.h | 3 +-- net/netfilter/ipvs/ip_vs_conn.c | 2 +- net/netfilter/ipvs/ip_vs_core.c | 12 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 5d08c19..acbc09d 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -69,8 +69,7 @@ struct ip_vs_iphdr { }; static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, - int len, void *buffer, - const struct ip_vs_iphdr *ipvsh) + int len, void *buffer) { return skb_header_pointer(skb, offset, len, buffer); } diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index f73561c..a35fade 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -322,7 +322,7 @@ struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p) { __be16 _ports[2], *pptr; - pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); + pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports); if (pptr == NULL) return 1; diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 5cb7cac..5f6f73c 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -433,7 +433,7 @@ struct ip_vs_conn * /* * IPv6 frags, only the first hit here. */ - pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); + pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports); if (pptr == NULL) return NULL; @@ -566,7 +566,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, struct netns_ipvs *ipvs = svc->ipvs; struct net *net = ipvs->net; - pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); + pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports); if (!pptr) return NF_DROP; dport = likely(!ip_vs_iph_inverse(iph)) ? pptr[1] : pptr[0]; @@ -982,7 +982,7 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb, unsigned int offset; *related = 1; - ic = frag_safe_skb_hp(skb, ipvsh->len, sizeof(_icmph), &_icmph, ipvsh); + ic = frag_safe_skb_hp(skb, ipvsh->len, sizeof(_icmph), &_icmph); if (ic == NULL) return NF_DROP; @@ -1214,7 +1214,7 @@ static struct ip_vs_conn *__ip_vs_rs_conn_out(unsigned int hooknum, return NULL; pptr = frag_safe_skb_hp(skb, iph->len, - sizeof(_ports), _ports, iph); + sizeof(_ports), _ports); if (!pptr) return NULL; @@ -1407,7 +1407,7 @@ static struct ip_vs_conn *__ip_vs_rs_conn_out(unsigned int hooknum, __be16 _ports[2], *pptr; pptr = frag_safe_skb_hp(skb, iph.len, -sizeof(_ports), _ports, &iph); +sizeof(_ports), _ports); if (pptr == NULL) return NF_ACCEPT; /* Not for me */ if (ip_vs_has_real_service(ipvs, af, iph.protocol, &iph.saddr, @@ -1741,7 +1741,7 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb, *related = 1; - ic = frag_safe_skb_hp(skb, iph->len, sizeof(_icmph), &_icmph, iph); + ic = frag_safe_skb_hp(skb, iph->len, sizeof(_icmph), &_icmph); if (ic == NULL) return NF_DROP; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 nf-next] netfilter: ebt: Use new helper ebt_invalid_target to check target
From: Gao Feng Use the new helper function ebt_invalid_target instead of the old macro INVALID_TARGET and other duplicated codes to enhance the readability. Signed-off-by: Gao Feng --- v2: Replace the target check of ebt_mark/snat, per Pablo v1: Initial version include/linux/netfilter_bridge/ebtables.h | 2 -- net/bridge/netfilter/ebt_dnat.c | 2 +- net/bridge/netfilter/ebt_mark.c | 2 +- net/bridge/netfilter/ebt_redirect.c | 2 +- net/bridge/netfilter/ebt_snat.c | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index e0cbf17..2c2a551 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -122,8 +122,6 @@ extern unsigned int ebt_do_table(struct sk_buff *skb, #define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS)) /* Clear the bit in the hook mask that tells if the rule is on a base chain */ #define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS)) -/* True if the target is not a standard target */ -#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) static inline bool ebt_invalid_target(int target) { diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index e0bb624..dfc86a0 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -61,7 +61,7 @@ static int ebt_dnat_tg_check(const struct xt_tgchk_param *par) (strcmp(par->table, "broute") != 0 || hook_mask & ~(1 << NF_BR_BROUTING))) return -EINVAL; - if (INVALID_TARGET) + if (ebt_invalid_target(info->target)) return -EINVAL; return 0; } diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c index 66697cb..19f0f95 100644 --- a/net/bridge/netfilter/ebt_mark.c +++ b/net/bridge/netfilter/ebt_mark.c @@ -44,7 +44,7 @@ static int ebt_mark_tg_check(const struct xt_tgchk_param *par) tmp = info->target | ~EBT_VERDICT_BITS; if (BASE_CHAIN && tmp == EBT_RETURN) return -EINVAL; - if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) + if (ebt_invalid_target(tmp)) return -EINVAL; tmp = info->target & ~EBT_VERDICT_BITS; if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index 8d2a85e..a7223ea 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c @@ -47,7 +47,7 @@ static int ebt_redirect_tg_check(const struct xt_tgchk_param *par) (strcmp(par->table, "broute") != 0 || hook_mask & ~(1 << NF_BR_BROUTING))) return -EINVAL; - if (INVALID_TARGET) + if (ebt_invalid_target(info->target)) return -EINVAL; return 0; } diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index e56ccd0..11cf9e9 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c @@ -51,7 +51,7 @@ static int ebt_snat_tg_check(const struct xt_tgchk_param *par) if (BASE_CHAIN && tmp == EBT_RETURN) return -EINVAL; - if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) + if (ebt_invalid_target(tmp)) return -EINVAL; tmp = info->target | EBT_VERDICT_BITS; if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next] netfilter: ebt: Use ebt_invalid_target instead of INVALID_TARGET
From: Gao Feng Use the new helper function ebt_invalid_target instead of the old macro INVALID_TARGET to enhance the readability. Signed-off-by: Gao Feng --- include/linux/netfilter_bridge/ebtables.h | 2 -- net/bridge/netfilter/ebt_dnat.c | 2 +- net/bridge/netfilter/ebt_redirect.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index e0cbf17..2c2a551 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -122,8 +122,6 @@ extern unsigned int ebt_do_table(struct sk_buff *skb, #define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS)) /* Clear the bit in the hook mask that tells if the rule is on a base chain */ #define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS)) -/* True if the target is not a standard target */ -#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) static inline bool ebt_invalid_target(int target) { diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index e0bb624..dfc86a0 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -61,7 +61,7 @@ static int ebt_dnat_tg_check(const struct xt_tgchk_param *par) (strcmp(par->table, "broute") != 0 || hook_mask & ~(1 << NF_BR_BROUTING))) return -EINVAL; - if (INVALID_TARGET) + if (ebt_invalid_target(info->target)) return -EINVAL; return 0; } diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index 8d2a85e..a7223ea 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c @@ -47,7 +47,7 @@ static int ebt_redirect_tg_check(const struct xt_tgchk_param *par) (strcmp(par->table, "broute") != 0 || hook_mask & ~(1 << NF_BR_BROUTING))) return -EINVAL; - if (INVALID_TARGET) + if (ebt_invalid_target(info->target)) return -EINVAL; return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2] ebtables: arpreply: Add the standard target sanity check
From: Gao Feng The info->target is from userspace and it would be used directly. So we need to add the sanity check to make sure it is a valid standard target, although the ebtables tool has already checked it. Kernel need to check anything from userspace. If the target was set as an evil value, it would break the ebtables and cause a panic. Because the non-standard target is treated as one offset. Now add one helper function ebt_invalid_target, and we would replace the macro INVALID_TARGET later. Signed-off-by: Gao Feng --- v2: Add one helper function ebt_invalid_target instead of INVALID_TARGET, per Pablo v1: initial version include/linux/netfilter_bridge/ebtables.h | 5 + net/bridge/netfilter/ebt_arpreply.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index a30efb4..e0cbf17 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -125,4 +125,9 @@ extern unsigned int ebt_do_table(struct sk_buff *skb, /* True if the target is not a standard target */ #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) +static inline bool ebt_invalid_target(int target) +{ + return (target < -NUM_STANDARD_TARGETS || target >= 0); +} + #endif diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c index 5929309..db85230 100644 --- a/net/bridge/netfilter/ebt_arpreply.c +++ b/net/bridge/netfilter/ebt_arpreply.c @@ -68,6 +68,9 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par) if (e->ethproto != htons(ETH_P_ARP) || e->invflags & EBT_IPROTO) return -EINVAL; + if (ebt_invalid_target(info->target)) + return -EINVAL; + return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf] ebtables: arpreply: Add the standard target sanity check
From: Gao Feng The info->target is from userspace and it would be used directly. So we need to add the sanity check to make sure it is a valid standard target, although the ebtables tool has already checked it. Kernel need to check anything from userspace. If the target was set as an evil value, it would break the ebtables and cause a panic. Because the non-standard target is treated as one offset. Signed-off-by: Gao Feng --- net/bridge/netfilter/ebt_arpreply.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c index 5929309..c4886d9 100644 --- a/net/bridge/netfilter/ebt_arpreply.c +++ b/net/bridge/netfilter/ebt_arpreply.c @@ -68,6 +68,9 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par) if (e->ethproto != htons(ETH_P_ARP) || e->invflags & EBT_IPROTO) return -EINVAL; + if (INVALID_TARGET) + return -EINVAL; + return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v6 1/3] netfilter: helper: Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper
From: Gao Feng Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper, and rename other functions or variables which refer to it. The new name is better than the old one. Signed-off-by: Gao Feng --- v6: Rename the helper name of ftp, tftp.. to ftp-nat-follow-master, per Pablo v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_helper.h | 14 ++--- net/ipv4/netfilter/nf_nat_h323.c| 12 +-- net/netfilter/nf_conntrack_helper.c | 32 ++--- net/netfilter/nf_conntrack_netlink.c| 16 +++ net/netfilter/nf_nat_core.c | 6 +++--- net/netfilter/nf_nat_sip.c | 6 +++--- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1eaac1f..d14fe493 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -111,7 +111,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, enum ip_conntrack_info ctinfo, unsigned int timeout); -struct nf_ct_helper_expectfn { +struct nf_ct_nat_helper { struct list_head head; const char *name; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); @@ -121,12 +121,12 @@ struct nf_ct_helper_expectfn { void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, const char *fmt, ...); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n); -void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_name(const char *name); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_symbol(const void *symbol); +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n); +void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_name(const char *name); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_symbol(const void *symbol); extern struct hlist_head *nf_ct_helper_hash; extern unsigned int nf_ct_helper_hsize; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 574f7eb..346e764 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -567,12 +567,12 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, return 0; } -static struct nf_ct_helper_expectfn q931_nat = { +static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", .expectfn = ip_nat_q931_expect, }; -static struct nf_ct_helper_expectfn callforwarding_nat = { +static struct nf_ct_nat_helper callforwarding_nat = { .name = "callforwarding", .expectfn = ip_nat_callforwarding_expect, }; @@ -599,8 +599,8 @@ static int __init init(void) RCU_INIT_POINTER(nat_h245_hook, nat_h245); RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding); RCU_INIT_POINTER(nat_q931_hook, nat_q931); - nf_ct_helper_expectfn_register(&q931_nat); - nf_ct_helper_expectfn_register(&callforwarding_nat); + nf_ct_nat_helper_register(&q931_nat); + nf_ct_nat_helper_register(&callforwarding_nat); return 0; } @@ -616,8 +616,8 @@ static void __exit fini(void) RCU_INIT_POINTER(nat_h245_hook, NULL); RCU_INIT_POINTER(nat_callforwarding_hook, NULL); RCU_INIT_POINTER(nat_q931_hook, NULL); - nf_ct_helper_expectfn_unregister(&q931_nat); - nf_ct_helper_expectfn_unregister(&callforwarding_nat); + nf_ct_nat_helper_unregister(&q931_nat); + nf_ct_nat_helper_unregister(&callforwarding_nat); synchronize_rcu(); } diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 99bcd44..1fd739c 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -302,32 +302,32 @@ void nf_ct_helper_destroy(struct nf_conn *ct) } } -static LIST_HEAD(nf_ct_helper_expectfn_list); +static LIST_HEAD(nf_ct_nat_helper_list); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n) +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n) { spin_lock_bh(&nf_conntrack_expect_lock); - list_add_rcu(&n->head, &nf_ct_helper_expectfn_list); + list_add_rcu(&n->head, &nf_ct_nat_helper_list); spin_unlock_bh(&nf_conntrack_expect_lock); } -EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register); +EXPORT_SYMBOL_GPL(nf_ct_nat_helper_register); -void nf_ct_helper_expectfn_unregister(struct nf_c
[PATCH nf v6 3/3] netfilter: nat_helper: Remove the expectations when its module is unloaded
From: Gao Feng Because the conntrack NAT module could be rmmod anytime, so we should really leave things in clean state if such thing happens and make sure we don't leave any packet running over code that will be gone after the removal. We only removed the expectations when unregister conntrack helper before. Actually it is necessary too when remove the nat helper. Now add one new struct module member "me" in the nf_ct_nat_helper to represent which module it belongs to. Signed-off-by: Gao Feng --- v6: Rename the helper name of ftp, tftp.. to ftp-nat-follow-master, per Pablo v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_helper.h | 1 + net/ipv4/netfilter/nf_nat_h323.c| 3 ++ net/netfilter/ipvs/ip_vs_nfct.c | 1 + net/netfilter/nf_conntrack_helper.c | 62 +++-- net/netfilter/nf_conntrack_pptp.c | 1 + net/netfilter/nf_nat_amanda.c | 1 + net/netfilter/nf_nat_core.c | 1 + net/netfilter/nf_nat_ftp.c | 1 + net/netfilter/nf_nat_irc.c | 1 + net/netfilter/nf_nat_sip.c | 1 + net/netfilter/nf_nat_tftp.c | 1 + 11 files changed, 52 insertions(+), 22 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index e8d31ca..d70c5be 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -114,6 +114,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, struct nf_ct_nat_helper { struct list_head head; const char *name; + struct module *me; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); }; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index ce2095c..d7b40ac 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -28,16 +28,19 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new, static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", + .me = THIS_MODULE, .expectfn = ip_nat_q931_expect, }; static struct nf_ct_nat_helper callforwarding_nat = { .name = "callforwarding", + .me = THIS_MODULE, .expectfn = ip_nat_callforwarding_expect, }; static struct nf_ct_nat_helper follow_master_nat = { .name = "h323-nat-follow-master", + .me = THIS_MODULE, .expectfn = nf_nat_follow_master, }; diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c index fc5af4f..d61c236 100644 --- a/net/netfilter/ipvs/ip_vs_nfct.c +++ b/net/netfilter/ipvs/ip_vs_nfct.c @@ -222,6 +222,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, static struct nf_ct_nat_helper ip_vs_nat = { .name = "ip-vs-nat", + .me = THIS_MODULE, .expectfn = ip_vs_nfct_expect_callback, }; diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 1fd739c..c12de31 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -130,6 +130,37 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple) return NULL; } +static void +nf_ct_flush_expect(const struct module *me) +{ + struct nf_conntrack_expect *exp; + const struct hlist_node *next; + u32 i; + + if (!me) + return; + + /* Get rid of expectations */ + spin_lock_bh(&nf_conntrack_expect_lock); + for (i = 0; i < nf_ct_expect_hsize; i++) { + hlist_for_each_entry_safe(exp, next, + &nf_ct_expect_hash[i], hnode) { + struct nf_conn_help *master_help = nfct_help(exp->master); + + if ((master_help->helper && master_help->helper->me == me) || + (exp->helper && exp->helper->me == me) || + (exp->nat_helper && exp->nat_helper->me == me)) { + /* This expect belongs to the dying module */ + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + } + } + } + } + spin_unlock_bh(&nf_conntrack_expect_lock); +} + struct nf_conntrack_helper * __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum) { @@ -317,6 +348,12 @@ void nf_ct_nat_helper_unregister(struct nf_ct_nat
[PATCH nf v6 2/3] netfilter: nat_helper: Register one nf_ct_nat_helper each proto nat module
From: Gao Feng There are multiple proto nat modules which depend on the follow_master_nat in the nf_nat_core. When this module is gone, all modules which refers to it could not work well. Now register one struct nf_ct_nat_helper in every proto nat module, it makes sure every nat module could not effect each other, and it is helpful to maintain the codes. The new nf_ct_nat_helper could be found by ctlink with its name too, while the original "nat-follow-master" helper is not effected. ctlink still could specify the "nat-follow-master" for ftp, but recommend use the ftp's nat_helper "ftp-nat-follow-master" as the ftp nat_helper. The following are all modifications. 1. Every proto nat module registers one nat_helper at least; 2. Replace the expectfn with nat_helper in the nf_conntrack_expect; It is used to the latter commit which add the nat_helper module check. 3. Remove nf_ct_nat_helper_find_by_symbol, it is useless now. Signed-off-by: Gao Feng --- v6: Rename the helper name of ftp, tftp.. to ftp-nat-follow-master, per Pablo v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_expect.h | 5 ++-- include/net/netfilter/nf_conntrack_helper.h | 2 -- net/ipv4/netfilter/nf_nat_h323.c| 44 ++--- net/netfilter/ipvs/ip_vs_nfct.c | 7 - net/netfilter/nf_conntrack_broadcast.c | 2 +- net/netfilter/nf_conntrack_core.c | 4 +-- net/netfilter/nf_conntrack_expect.c | 2 +- net/netfilter/nf_conntrack_netlink.c| 14 - net/netfilter/nf_conntrack_pptp.c | 14 +++-- net/netfilter/nf_nat_amanda.c | 9 +- net/netfilter/nf_nat_ftp.c | 9 +- net/netfilter/nf_nat_irc.c | 9 +- net/netfilter/nf_nat_sip.c | 18 ++-- net/netfilter/nf_nat_tftp.c | 9 +- 14 files changed, 101 insertions(+), 47 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5ed33ea..f665a6b 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -23,9 +23,8 @@ struct nf_conntrack_expect { struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple_mask mask; - /* Function to call after setup and insertion */ - void (*expectfn)(struct nf_conn *new, -struct nf_conntrack_expect *this); + /* Expectation function owner */ + struct nf_ct_nat_helper *nat_helper; /* Helper to assign to new connection */ struct nf_conntrack_helper *helper; diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index d14fe493..e8d31ca 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -125,8 +125,6 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n); struct nf_ct_nat_helper * nf_ct_nat_helper_find_by_name(const char *name); -struct nf_ct_nat_helper * -nf_ct_nat_helper_find_by_symbol(const void *symbol); extern struct hlist_head *nf_ct_helper_hash; extern unsigned int nf_ct_helper_hsize; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 346e764..ce2095c 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -21,6 +21,26 @@ #include // +static void ip_nat_q931_expect(struct nf_conn *new, + struct nf_conntrack_expect *this); +static void ip_nat_callforwarding_expect(struct nf_conn *new, +struct nf_conntrack_expect *this); + +static struct nf_ct_nat_helper q931_nat = { + .name = "Q.931", + .expectfn = ip_nat_q931_expect, +}; + +static struct nf_ct_nat_helper callforwarding_nat = { + .name = "callforwarding", + .expectfn = ip_nat_callforwarding_expect, +}; + +static struct nf_ct_nat_helper follow_master_nat = { + .name = "h323-nat-follow-master", + .expectfn = nf_nat_follow_master, +}; + static int set_addr(struct sk_buff *skb, unsigned int protoff, unsigned char **data, int dataoff, unsigned int addroff, __be32 ip, __be16 port) @@ -187,10 +207,10 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; - rtp_exp->expectfn = nf_nat_follow_master; + rtp_exp->n
[PATCH nf-next v3] netfilter: SYNPROXY: Return NF_STOLEN instead of NF_DROP during handshaking
From: Gao Feng Current SYNPROXY codes return NF_DROP during normal TCP handshaking, it is not friendly to caller. Because the nf_hook_slow would treat the NF_DROP as an error, and return -EPERM. As a result, it may cause the top caller think it meets one error. For example, the following codes are from cfv_rx_poll() err = netif_receive_skb(skb); if (unlikely(err)) { ++cfv->ndev->stats.rx_dropped; } else { ++cfv->ndev->stats.rx_packets; cfv->ndev->stats.rx_bytes += skb_len; } When SYNPROXY returns NF_DROP, then netif_receive_skb returns -EPERM. As a result, the cfv driver would treat it as an error, and increase the rx_dropped counter. So use NF_STOLEN instead of NF_DROP now because there is no error happened indeed, and free the skb directly. Signed-off-by: Gao Feng --- v2: Add more comments v2: Add the check for synproxy_recv_client_ack, per Gao Feng, v1: initial version net/ipv4/netfilter/ipt_SYNPROXY.c | 21 ++--- net/ipv6/netfilter/ip6t_SYNPROXY.c | 20 ++-- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 3240a26..ab0f576 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -293,12 +293,16 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; - + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ - synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } return XT_CONTINUE; @@ -367,10 +371,13 @@ static unsigned int ipv4_synproxy_hook(void *priv, * number match the one of first SYN. */ if (synproxy_recv_client_ack(net, skb, th, &opts, -ntohl(th->seq) + 1)) +ntohl(th->seq) + 1)) { this_cpu_inc(snet->stats->cookie_retrans); - - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } synproxy->isn = ntohl(th->ack_seq); diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index 4ef1ddd..6a4f49e 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -307,12 +307,17 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ - synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } return XT_CONTINUE; @@ -388,10 +393,13 @@ static unsigned int ipv6_synproxy_hook(void *priv, * number match the one of first SYN. */ if (synproxy_recv_client_ack(net, skb, th, &opts, -ntohl(th->seq) + 1)) +ntohl(th->seq) + 1)) { this_cpu_inc(snet->stats->cookie_retrans); - - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } synproxy->isn = ntohl(th->ack_seq); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next] netfilter: tcp: Use TCP_MAX_WSCALE instead of literal 14
From: Gao Feng The window scale may be enlarged from 14 to 15 according to the itef draft https://tools.ietf.org/html/draft-nishida-tcpm-maxwin-03. Use the macro TCP_MAX_WSCALE to support it easily with TCP stack in the future. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_proto_tcp.c | 7 +++ net/netfilter/nf_synproxy_core.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index b122e9d..741acdc 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -419,10 +419,9 @@ static void tcp_options(const struct sk_buff *skb, && opsize == TCPOLEN_WINDOW) { state->td_scale = *(u_int8_t *)ptr; - if (state->td_scale > 14) { - /* See RFC1323 */ - state->td_scale = 14; - } + if (state->td_scale > TCP_MAX_WSCALE) + state->td_scale = TCP_MAX_WSCALE; + state->flags |= IP_CT_TCP_FLAG_WINDOW_SCALE; } diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index abe03e8..a504e87 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -66,8 +66,8 @@ case TCPOPT_WINDOW: if (opsize == TCPOLEN_WINDOW) { opts->wscale = *ptr; - if (opts->wscale > 14) - opts->wscale = 14; + if (opts->wscale > TCP_MAX_WSCALE) + opts->wscale = TCP_MAX_WSCALE; opts->options |= XT_SYNPROXY_OPT_WSCALE; } break; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v3] netfilter: xt_CT: fix refcnt leak on error path
From: Gao Feng There are two cases which causes refcnt leak. 1. When nf_ct_timeout_ext_add failed in xt_ct_set_timeout, it should free the timeout refcnt. Now goto the err_put_timeout error handler instead of going ahead. 2. When the time policy is not found, we should call module_put. Otherwise, the related cthelper module cannot be removed anymore. It is easy to reproduce by typing the following command: # iptables -t raw -A OUTPUT -p tcp -j CT --helper ftp --timeout xxx Signed-off-by: Gao Feng Signed-off-by: Liping Zhang --- v3: Merge the patch of Liping together v2: enhance the patch v1: initial version net/netfilter/xt_CT.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index b008db0..81fdcdc 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -167,8 +167,10 @@ static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) goto err_put_timeout; } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); - if (timeout_ext == NULL) + if (!timeout_ext) { ret = -ENOMEM; + goto err_put_timeout; + } rcu_read_unlock(); return ret; @@ -200,6 +202,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, struct xt_ct_target_info_v1 *info) { struct nf_conntrack_zone zone; + struct nf_conn_help *help; struct nf_conn *ct; int ret = -EOPNOTSUPP; @@ -248,7 +251,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, if (info->timeout[0]) { ret = xt_ct_set_timeout(ct, par, info->timeout); if (ret < 0) - goto err3; + goto err4; } __set_bit(IPS_CONFIRMED_BIT, &ct->status); nf_conntrack_get(&ct->ct_general); @@ -256,6 +259,10 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, info->ct = ct; return 0; +err4: + help = nfct_help(ct); + if (help) + module_put(help->helper->me); err3: nf_ct_tmpl_free(ct); err2: -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2] netfilter: cttimeout: Fix one possible use-after-free issue
From: Gao Feng The function ctnl_untimeout is used to untimeout every conntrack which is using the timeout. But it is necessary to add one barrier synchronize_rcu because of racing. Maybe one conntrack has already owned this timeout, but it is not inserted into unconfirmed list or the hash list, when ctnl_untimeout untimeout the conntracks Let me describe it with a call path CPU1CPU2 alloc new conn add timeout ext ctnl_timeout_try_del untimeout all conns in list kfree_rcu. conn is confirmed. As the show above, when cpu2 untimeout all conns in list and the new conn of cpu1 is not confirmed, the new conn still owns the timeout pointer. After the timeout mem is freed really, it points to one invalid mem. Signed-off-by: Gao Feng --- v2: Add the call path in the comment v1: initial version net/netfilter/nfnetlink_cttimeout.c | 5 + 1 file changed, 5 insertions(+) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 47d6656..af0cc87 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -304,6 +304,11 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout) spinlock_t *lock; int i, cpu; + /* Make sure the conntrack using the timeout already in the unconfirmed +* list or in the hash table. +*/ + synchronize_rcu(); + for_each_possible_cpu(cpu) { struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: ecache: Refine the nf_ct_deliver_cached_events
From: Gao Feng 1. Remove single !events condition check to deliver the missed event even though there is no new event happened. Consider this case: 1) nf_ct_deliver_cached_events is invoked at the first time, the event is failed to deliver, then the missed is set. 2) nf_ct_deliver_cached_events is invoked again, but there is no any new event happened. The missed event is lost really. It would try to send the missed event again after remove this check. And it is ok if there is no missed event because the latter check !((events | missed) & e->ctmask) could avoid it. 2. Correct the return value check of notify->fcn. When send the event successfully, it returns 0, not postive value. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_ecache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index da9df2d..1e4e257 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c @@ -195,7 +195,7 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct) events = xchg(&e->cache, 0); - if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events) + if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct)) goto out_unlock; /* We make a copy of the missed event cache without taking @@ -212,7 +212,7 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct) ret = notify->fcn(events | missed, &item); - if (likely(ret >= 0 && !missed)) + if (likely(ret == 0 && !missed)) goto out_unlock; spin_lock_bh(&ct->lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: nf_nat: Fix return NF_DROP in nfnetlink_parse_nat_setup
From: Gao Feng The __nf_nat_alloc_null_binding invokes nf_nat_setup_info which may return NF_DROP when memory is exhausted, so convert NF_DROP to -ENOMEM to make ctnetlink happy. Or ctnetlink_setup_nat treats it as a success when one error NF_DROP happens actully. Signed-off-by: Gao Feng --- net/netfilter/nf_nat_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index 82802e4..55746cd 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -819,7 +819,7 @@ static int nfnetlink_parse_nat_proto(struct nlattr *attr, /* No NAT information has been passed, allocate the null-binding */ if (attr == NULL) - return __nf_nat_alloc_null_binding(ct, manip); + return __nf_nat_alloc_null_binding(ct, manip) == NF_DROP ? -ENOMEM : 0; err = nfnetlink_parse_nat(attr, ct, &range, l3proto); if (err < 0) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next v2 1/1] netfilter: SYNPROXY: Return NF_STOLEN instead of NF_DROP during handshaking
From: Gao Feng Current SYNPROXY codes return NF_DROP during normal TCP handshaking, it is not friendly to caller. Because the nf_hook_slow would treat the NF_DROP as an error, and return -EPERM. As a result, it may cause the top caller think it meets one error. So use NF_STOLEN instead of NF_DROP now because there is no error happened indeed, and free the skb directly. Signed-off-by: Gao Feng --- v2: Add the check for synproxy_recv_client_ack, per Gao Feng, v1: initial version net/ipv4/netfilter/ipt_SYNPROXY.c | 21 ++--- net/ipv6/netfilter/ip6t_SYNPROXY.c | 20 ++-- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 3240a26..ab0f576 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -293,12 +293,16 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; - + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ - synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } return XT_CONTINUE; @@ -367,10 +371,13 @@ static unsigned int ipv4_synproxy_hook(void *priv, * number match the one of first SYN. */ if (synproxy_recv_client_ack(net, skb, th, &opts, -ntohl(th->seq) + 1)) +ntohl(th->seq) + 1)) { this_cpu_inc(snet->stats->cookie_retrans); - - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } synproxy->isn = ntohl(th->ack_seq); diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index 4ef1ddd..6a4f49e 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -307,12 +307,17 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ - synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } return XT_CONTINUE; @@ -388,10 +393,13 @@ static unsigned int ipv6_synproxy_hook(void *priv, * number match the one of first SYN. */ if (synproxy_recv_client_ack(net, skb, th, &opts, -ntohl(th->seq) + 1)) +ntohl(th->seq) + 1)) { this_cpu_inc(snet->stats->cookie_retrans); - - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; + } else { + return NF_DROP; + } } synproxy->isn = ntohl(th->ack_seq); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: SYNPROXY: Return NF_STOLEN instead of NF_DROP during handshaking
From: Gao Feng Current SYNPROXY codes return NF_DROP during normal TCP handshaking, it is not friendly to caller. Because the nf_hook_slow would treat the NF_DROP as an error, and return -EPERM. As a result, it may cause the top caller think it meets one error. So use NF_STOLEN instead of NF_DROP now because there is no error happened indeed, and free the skb directly. Signed-off-by: Gao Feng --- net/ipv4/netfilter/ipt_SYNPROXY.c | 7 --- net/ipv6/netfilter/ip6t_SYNPROXY.c | 6 -- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 3240a26..9ed80d4 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -293,12 +293,13 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; - + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; } return XT_CONTINUE; diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index 4ef1ddd..d5d5725 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -307,12 +307,14 @@ XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(net, skb, th, &opts); - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); - return NF_DROP; + consume_skb(skb); + return NF_STOLEN; } return XT_CONTINUE; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: seqadj: Fix possible non-linear data access for TCP header
From: Gao Feng The current call path of nf_ct_tcp_seqadj_set is the following. nfqnl_recv_verdict->ctnetlink_glue_hook->ctnetlink_glue_seqadj ->nf_ct_tcp_seqadj_set. It couldn't make sure the TCP header is in the linear data part. So use the skb_header_pointer instead of the current codes. BTW, the nf_ct_tcp_seqadj_set is one external function of netfilter which works in the network layer, it should not assume the transport header is in the linear data. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_seqadj.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_seqadj.c b/net/netfilter/nf_conntrack_seqadj.c index ef7063e..80394ab 100644 --- a/net/netfilter/nf_conntrack_seqadj.c +++ b/net/netfilter/nf_conntrack_seqadj.c @@ -61,11 +61,14 @@ void nf_ct_tcp_seqadj_set(struct sk_buff *skb, s32 off) { const struct tcphdr *th; + struct tcphdr tcph; if (nf_ct_protonum(ct) != IPPROTO_TCP) return; - th = (struct tcphdr *)(skb_network_header(skb) + ip_hdrlen(skb)); + th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(tcph), &tcph); + if (!th) + return; nf_ct_seqadj_set(ct, ctinfo, th->seq, off); } EXPORT_SYMBOL_GPL(nf_ct_tcp_seqadj_set); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: cttimeout: Refine cttimeout_del_timeout
From: Gao Feng 1. Return one error when try to delete all timeouts and meet one erorr; 2. Delete the condition block when fail to delete specified timeout. It is more clear that it would stop the loop when find one matched timeout. Signed-off-by: Gao Feng --- net/netfilter/nfnetlink_cttimeout.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index baa75f3..220847a 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -361,11 +361,17 @@ static int cttimeout_del_timeout(struct net *net, struct sock *ctnl, char *name; if (!cda[CTA_TIMEOUT_NAME]) { + int cur_ret; + + ret = 0; list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, -head) - ctnl_timeout_try_del(net, cur); +head) { + cur_ret = ctnl_timeout_try_del(net, cur); + if (cur_ret && !ret) + ret = cur_ret; + } - return 0; + return ret; } name = nla_data(cda[CTA_TIMEOUT_NAME]); @@ -374,9 +380,6 @@ static int cttimeout_del_timeout(struct net *net, struct sock *ctnl, continue; ret = ctnl_timeout_try_del(net, cur); - if (ret < 0) - return ret; - break; } return ret; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2 1/1] netfilter: xt_CT: Fix one possible memleak of timeout
From: Gao Feng When nf_ct_timeout_ext_add failed in xt_ct_set_timeout, it should free the timeout refcnt. Now goto the err_put_timeout error handler instead of going ahead. Signed-off-by: Gao Feng --- v2: Keep the ret = -ENOMEM, per Gao Feng v1: initial version net/netfilter/xt_CT.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index b008db0..a1783b6 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -167,8 +167,10 @@ static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) goto err_put_timeout; } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); - if (timeout_ext == NULL) + if (!timeout_ext) { ret = -ENOMEM; + goto err_put_timeout; + } rcu_read_unlock(); return ret; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: cttimeout: Return -EOPNOTSUPP if l4proto doesn't support
From: Gao Feng Return -EOPNOTSUPP instead of success when l4proto doesn't support set the timeout attribute. It is better to return error when fail to set timeout. Signed-off-by: Gao Feng --- net/netfilter/nfnetlink_cttimeout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index baa75f3..0b12e8c6 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -50,7 +50,7 @@ ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto, struct net *net, const struct nlattr *attr) { - int ret = 0; + int ret = -EOPNOTSUPP; if (likely(l4proto->ctnl_timeout.nlattr_to_obj)) { struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1]; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: cttimeout: Fix one possible use-after-free issue
From: Gao Feng The function ctnl_untimeout is used to untimeout every conntrack which is using the timeout. But it is necessary to add one barrier synchronize_rcu because of racing. Maybe one conntrack has already owned this timeout, but it is not inserted into unconfirmed list or the hash list, when ctnl_untimeout untimeout the conntracks Signed-off-by: Gao Feng --- net/netfilter/nfnetlink_cttimeout.c | 5 + 1 file changed, 5 insertions(+) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 47d6656..af0cc87 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -304,6 +304,11 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout) spinlock_t *lock; int i, cpu; + /* Make sure the conntrack using the timeout already in the unconfirmed +* list or in the hash table. +*/ + synchronize_rcu(); + for_each_possible_cpu(cpu) { struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: xt_CT: Fix one possible memleak of timeout
From: Gao Feng When nf_ct_timeout_ext_add failed in xt_ct_set_timeout, it should free the timeout refcnt. Now goto the err_put_timeout error handler instead of going ahead. Signed-off-by: Gao Feng --- net/netfilter/xt_CT.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index b008db0..3cd812c 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -168,7 +168,7 @@ static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); if (timeout_ext == NULL) - ret = -ENOMEM; + goto err_put_timeout; rcu_read_unlock(); return ret; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: CLUSTERIP: Fix one wrong refcnt usage
From: Gao Feng Current codes invoke wrongly nf_ct_netns_get in the destroy routine, it should use nf_ct_netns_put, not nf_ct_netns_get. It could cause some modules could not be unloaded. Signed-off-by: Gao Feng --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 52f2645..9b88413 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -461,7 +461,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par) clusterip_config_put(cipinfo->config); - nf_ct_netns_get(par->net, par->family); + nf_ct_netns_put(par->net, par->family); } #ifdef CONFIG_COMPAT -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: Remove useless variable timeouts in init_conntrack
From: Gao Feng All l4_proto->new callbacks don't use the param timeouts currently, so remove it from param list. Then the variable timeouts isn't used as right value in init_conntrack, so remove it too. Signed-off-by: Gao Feng --- include/net/netfilter/nf_conntrack_l4proto.h | 2 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 +- net/netfilter/nf_conntrack_core.c| 13 ++--- net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 2 +- net/netfilter/nf_conntrack_proto_tcp.c | 2 +- net/netfilter/nf_conntrack_proto_udp.c | 2 +- 7 files changed, 8 insertions(+), 17 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 85e993e..fafe65a 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -49,7 +49,7 @@ struct nf_conntrack_l4proto { /* Called when a new connection for this protocol found; * returns TRUE if it's OK. If so, packet() called next. */ bool (*new)(struct nf_conn *ct, const struct sk_buff *skb, - unsigned int dataoff, unsigned int *timeouts); + unsigned int dataoff); /* Called when a conntrack entry is destroyed */ void (*destroy)(struct nf_conn *ct); diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 73c591d..5bb8c12 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -105,7 +105,7 @@ static int icmp_packet(struct nf_conn *ct, /* Called when a new connection for this protocol found. */ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, -unsigned int dataoff, unsigned int *timeouts) +unsigned int dataoff) { static const u_int8_t valid_new[] = { [ICMP_ECHO] = 1, diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index b0f2e8e..1fac417 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1145,7 +1145,6 @@ void nf_conntrack_free(struct nf_conn *ct) const struct nf_conntrack_zone *zone; struct nf_conn_timeout *timeout_ext; struct nf_conntrack_zone tmp; - unsigned int *timeouts; if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) { pr_debug("Can't invert tuple.\n"); @@ -1163,21 +1162,13 @@ void nf_conntrack_free(struct nf_conn *ct) return ERR_PTR(-ENOMEM); } - timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; - if (timeout_ext) { - timeouts = nf_ct_timeout_data(timeout_ext); - if (unlikely(!timeouts)) - timeouts = l4proto->get_timeouts(net); - } else { - timeouts = l4proto->get_timeouts(net); - } - - if (!l4proto->new(ct, skb, dataoff, timeouts)) { + if (!l4proto->new(ct, skb, dataoff)) { nf_conntrack_free(ct); pr_debug("can't track with proto module\n"); return NULL; } + timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; if (timeout_ext) nf_ct_timeout_ext_add(ct, rcu_dereference(timeout_ext->timeout), GFP_ATOMIC); diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 93dd1c5..52f2ce4 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -412,7 +412,7 @@ static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv, } static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, -unsigned int dataoff, unsigned int *timeouts) +unsigned int dataoff) { struct net *net = nf_ct_net(ct); struct nf_dccp_net *dn; diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 33279aa..102ab80 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -432,7 +432,7 @@ static int sctp_packet(struct nf_conn *ct, /* Called when a new connection for this protocol found. */ static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb, -unsigned int dataoff, unsigned int *timeouts) +unsigned int dataoff) { enum sctp_conntrack new_state; const struct sctphdr *sh; diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index b122e9d..aebaf7d 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1098,7 +1098,7 @@ static int tcp_packet(struct nf_conn *ct, /* Called when a new connection for this protocol found. */ static bool tcp_new(struct n
[PATCH nf-next v2 1/1] netfilter: udplite: Remove duplicated udplite4/6 declaration
From: Gao Feng There are two nf_conntrack_l4proto_udp4 declarations in the head file nf_conntrack_ipv4/6.h. Now remove one which is not enbraced by the macro CONFIG_NF_CT_PROTO_UDPLITE. Signed-off-by: Gao Feng --- v2: Remove the duplicated declaration in ipv6, per Gao Feng v1: initial version include/net/netfilter/ipv4/nf_conntrack_ipv4.h | 1 - include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 1 - 2 files changed, 2 deletions(-) diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index 6ff3281..919e4e8 100644 --- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -14,7 +14,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4; -extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp; #ifdef CONFIG_NF_CT_PROTO_DCCP extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4; diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index c59b824..eaea968 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h @@ -5,7 +5,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; -extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; #ifdef CONFIG_NF_CT_PROTO_DCCP extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next 1/1] netfilter: udplite4: Remove duplicated udplite4 declaration
From: Gao Feng There are two nf_conntrack_l4proto_udp4 declarations in the head file nf_conntrack_ipv4.h. Now remove one which is not enbraced by the macro CONFIG_NF_CT_PROTO_UDPLITE. Signed-off-by: Gao Feng --- include/net/netfilter/ipv4/nf_conntrack_ipv4.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index 6ff3281..919e4e8 100644 --- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -14,7 +14,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4; -extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp; #ifdef CONFIG_NF_CT_PROTO_DCCP extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v5 2/3] netfilter: nat_helper: Make sure every proto nat module uses its nat_helper
From: Gao Feng Make sure every proto nat module owns one struct nat_helper at least, and it only uses its nat_helper. 1. Every proto nat module registers one nat_helper at least; 2. Replace the expectfn with nat_helper in the nf_conntrack_expect; It is helpful to maintain the nat_helper codes 3. Make sure the nat module only uses its nat_helper; 4. Remove nf_ct_nat_helper_find_by_symbol, it is useless now. Signed-off-by: Gao Feng --- v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_expect.h | 5 ++-- include/net/netfilter/nf_conntrack_helper.h | 2 -- net/ipv4/netfilter/nf_nat_h323.c| 44 ++--- net/netfilter/ipvs/ip_vs_nfct.c | 7 - net/netfilter/nf_conntrack_broadcast.c | 2 +- net/netfilter/nf_conntrack_core.c | 4 +-- net/netfilter/nf_conntrack_expect.c | 2 +- net/netfilter/nf_conntrack_netlink.c| 14 - net/netfilter/nf_conntrack_pptp.c | 14 +++-- net/netfilter/nf_nat_amanda.c | 9 +- net/netfilter/nf_nat_ftp.c | 9 +- net/netfilter/nf_nat_irc.c | 9 +- net/netfilter/nf_nat_sip.c | 18 ++-- net/netfilter/nf_nat_tftp.c | 9 +- 14 files changed, 101 insertions(+), 47 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5ed33ea..f665a6b 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -23,9 +23,8 @@ struct nf_conntrack_expect { struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple_mask mask; - /* Function to call after setup and insertion */ - void (*expectfn)(struct nf_conn *new, -struct nf_conntrack_expect *this); + /* Expectation function owner */ + struct nf_ct_nat_helper *nat_helper; /* Helper to assign to new connection */ struct nf_conntrack_helper *helper; diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index d14fe493..e8d31ca 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -125,8 +125,6 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n); struct nf_ct_nat_helper * nf_ct_nat_helper_find_by_name(const char *name); -struct nf_ct_nat_helper * -nf_ct_nat_helper_find_by_symbol(const void *symbol); extern struct hlist_head *nf_ct_helper_hash; extern unsigned int nf_ct_helper_hsize; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 346e764..9101c48 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -21,6 +21,26 @@ #include // +static void ip_nat_q931_expect(struct nf_conn *new, + struct nf_conntrack_expect *this); +static void ip_nat_callforwarding_expect(struct nf_conn *new, +struct nf_conntrack_expect *this); + +static struct nf_ct_nat_helper q931_nat = { + .name = "Q.931", + .expectfn = ip_nat_q931_expect, +}; + +static struct nf_ct_nat_helper callforwarding_nat = { + .name = "callforwarding", + .expectfn = ip_nat_callforwarding_expect, +}; + +static struct nf_ct_nat_helper follow_master_nat = { + .name = "h323_follow_master", + .expectfn = nf_nat_follow_master, +}; + static int set_addr(struct sk_buff *skb, unsigned int protoff, unsigned char **data, int dataoff, unsigned int addroff, __be32 ip, __be16 port) @@ -187,10 +207,10 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; - rtp_exp->expectfn = nf_nat_follow_master; + rtp_exp->nat_helper = &follow_master_nat; rtp_exp->dir = !dir; rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port; - rtcp_exp->expectfn = nf_nat_follow_master; + rtcp_exp->nat_helper = &follow_master_nat; rtcp_exp->dir = !dir; /* Lookup existing expects */ @@ -289,7 +309,7 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; - exp->expectfn = nf_nat_follow_master; + exp->nat_helper = &follow_master_nat; exp->dir = !dir;
[PATCH nf v5 1/3] netfilter: helper: Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper
From: Gao Feng Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper, and rename other functions or variables which refer to it. The new name is better than the old one. Signed-off-by: Gao Feng --- v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_helper.h | 14 ++--- net/ipv4/netfilter/nf_nat_h323.c| 12 +-- net/netfilter/nf_conntrack_helper.c | 32 ++--- net/netfilter/nf_conntrack_netlink.c| 16 +++ net/netfilter/nf_nat_core.c | 6 +++--- net/netfilter/nf_nat_sip.c | 6 +++--- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1eaac1f..d14fe493 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -111,7 +111,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, enum ip_conntrack_info ctinfo, unsigned int timeout); -struct nf_ct_helper_expectfn { +struct nf_ct_nat_helper { struct list_head head; const char *name; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); @@ -121,12 +121,12 @@ struct nf_ct_helper_expectfn { void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, const char *fmt, ...); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n); -void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_name(const char *name); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_symbol(const void *symbol); +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n); +void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_name(const char *name); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_symbol(const void *symbol); extern struct hlist_head *nf_ct_helper_hash; extern unsigned int nf_ct_helper_hsize; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 574f7eb..346e764 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -567,12 +567,12 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, return 0; } -static struct nf_ct_helper_expectfn q931_nat = { +static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", .expectfn = ip_nat_q931_expect, }; -static struct nf_ct_helper_expectfn callforwarding_nat = { +static struct nf_ct_nat_helper callforwarding_nat = { .name = "callforwarding", .expectfn = ip_nat_callforwarding_expect, }; @@ -599,8 +599,8 @@ static int __init init(void) RCU_INIT_POINTER(nat_h245_hook, nat_h245); RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding); RCU_INIT_POINTER(nat_q931_hook, nat_q931); - nf_ct_helper_expectfn_register(&q931_nat); - nf_ct_helper_expectfn_register(&callforwarding_nat); + nf_ct_nat_helper_register(&q931_nat); + nf_ct_nat_helper_register(&callforwarding_nat); return 0; } @@ -616,8 +616,8 @@ static void __exit fini(void) RCU_INIT_POINTER(nat_h245_hook, NULL); RCU_INIT_POINTER(nat_callforwarding_hook, NULL); RCU_INIT_POINTER(nat_q931_hook, NULL); - nf_ct_helper_expectfn_unregister(&q931_nat); - nf_ct_helper_expectfn_unregister(&callforwarding_nat); + nf_ct_nat_helper_unregister(&q931_nat); + nf_ct_nat_helper_unregister(&callforwarding_nat); synchronize_rcu(); } diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..0eaa01e 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -293,32 +293,32 @@ void nf_ct_helper_destroy(struct nf_conn *ct) } } -static LIST_HEAD(nf_ct_helper_expectfn_list); +static LIST_HEAD(nf_ct_nat_helper_list); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n) +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n) { spin_lock_bh(&nf_conntrack_expect_lock); - list_add_rcu(&n->head, &nf_ct_helper_expectfn_list); + list_add_rcu(&n->head, &nf_ct_nat_helper_list); spin_unlock_bh(&nf_conntrack_expect_lock); } -EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register); +EXPORT_SYMBOL_GPL(nf_ct_nat_helper_register); -void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) +void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper
[PATCH nf v5 3/3] netfilter: nat_helper: Remove the expectations when its module is unloaded
From: Gao Feng Because the conntrack NAT module could be rmmod anytime, so we should really leave things in clean state if such thing happens and make sure we don't leave any packet running over code that will be gone after the removal. We only removed the expectations when unregister conntrack helper before. Actually it is necessary too when remove the nat helper. Now add one new struct module member "me" in the nf_ct_nat_helper to represent which module it belongs to. Signed-off-by: Gao Feng --- v5: Register one nat_helper for every nat module, per Pablo v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_helper.h | 1 + net/ipv4/netfilter/nf_nat_h323.c| 3 ++ net/netfilter/ipvs/ip_vs_nfct.c | 1 + net/netfilter/nf_conntrack_expect.c | 8 net/netfilter/nf_conntrack_helper.c | 62 +++-- net/netfilter/nf_conntrack_pptp.c | 1 + net/netfilter/nf_nat_amanda.c | 1 + net/netfilter/nf_nat_core.c | 1 + net/netfilter/nf_nat_ftp.c | 1 + net/netfilter/nf_nat_irc.c | 1 + net/netfilter/nf_nat_sip.c | 1 + net/netfilter/nf_nat_tftp.c | 1 + 12 files changed, 60 insertions(+), 22 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index e8d31ca..d70c5be 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -114,6 +114,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, struct nf_ct_nat_helper { struct list_head head; const char *name; + struct module *me; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); }; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 9101c48..c75583f 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -28,16 +28,19 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new, static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", + .me = THIS_MODULE, .expectfn = ip_nat_q931_expect, }; static struct nf_ct_nat_helper callforwarding_nat = { .name = "callforwarding", + .me = THIS_MODULE, .expectfn = ip_nat_callforwarding_expect, }; static struct nf_ct_nat_helper follow_master_nat = { .name = "h323_follow_master", + .me = THIS_MODULE, .expectfn = nf_nat_follow_master, }; diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c index 83ad79f..44cd98e 100644 --- a/net/netfilter/ipvs/ip_vs_nfct.c +++ b/net/netfilter/ipvs/ip_vs_nfct.c @@ -222,6 +222,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, static struct nf_ct_nat_helper ip_vs_nat = { .name = "ip_vs_nat", + .me = THIS_MODULE, .expectfn = ip_vs_nfct_expect_callback, }; diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index ba5a55e..9653847 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -416,6 +416,14 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) ret = -ESHUTDOWN; goto out; } + + /* Make sure the helper and nat_helper belong to the same module */ + if (expect->helper && expect->nat_helper && + expect->helper->me != expect->nat_helper->me) { + ret = -EINVAL; + goto out; + } + h = nf_ct_expect_dst_hash(net, &expect->tuple); hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) { if (expect_matches(i, expect)) { diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 0eaa01e..1a161a6 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -130,6 +130,37 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple) return NULL; } +static void +nf_ct_flush_expect(const struct module *me) +{ + struct nf_conntrack_expect *exp; + const struct hlist_node *next; + u32 i; + + if (!me) + return; + + /* Get rid of expectations */ + spin_lock_bh(&nf_conntrack_expect_lock); + for (i = 0; i < nf_ct_expect_hsize; i++) { + hlist_for_each_entry_safe(exp, next, + &nf_ct_expect_hash[i], hnode) { + struct nf_conn_help *master_help = nfct_help(exp->master); + + if ((master_help->h
[PATCH nf v5 0/3] Refine the robust of helper expectfn
From: Gao Feng These patches are used to refine the codes of helper expectfn, and enhance its robust, including fixing possible panic bug. Gao Feng (3): netfilter: helper: Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper netfilter: nat_helper: Make sure every proto nat module uses its nat_helper netfilter: nat_helper: Remove the expectations when its module is unloaded include/net/netfilter/nf_conntrack_expect.h | 5 +- include/net/netfilter/nf_conntrack_helper.h | 13 ++-- net/ipv4/netfilter/nf_nat_h323.c| 55 +++-- net/netfilter/ipvs/ip_vs_nfct.c | 8 ++- net/netfilter/nf_conntrack_broadcast.c | 2 +- net/netfilter/nf_conntrack_core.c | 4 +- net/netfilter/nf_conntrack_expect.c | 10 ++- net/netfilter/nf_conntrack_helper.c | 94 + net/netfilter/nf_conntrack_netlink.c| 20 +++--- net/netfilter/nf_conntrack_pptp.c | 15 - net/netfilter/nf_nat_amanda.c | 10 ++- net/netfilter/nf_nat_core.c | 7 ++- net/netfilter/nf_nat_ftp.c | 10 ++- net/netfilter/nf_nat_irc.c | 10 ++- net/netfilter/nf_nat_sip.c | 23 --- net/netfilter/nf_nat_tftp.c | 10 ++- 16 files changed, 194 insertions(+), 102 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v3 1/1] netfilter: helper: Add the rcu lock when call __nf_conntrack_helper_find
From: Gao Feng When invoke __nf_conntrack_helper_find, it needs the rcu lock to protect the helper module which would not be unloaded. Now there are two caller nf_conntrack_helper_try_module_get and ctnetlink_create_expect which don't hold rcu lock. And the other callers left like ctnetlink_change_helper, ctnetlink_create_conntrack, and ctnetlink_glue_attach_expect, they already hold the rcu lock or spin_lock_bh. Remove the rcu lock in functions nf_ct_helper_expectfn_find_by_name and nf_ct_helper_expectfn_find_by_symbol. Because they return one pointer which needs rcu lock, so their caller should hold the rcu lock, not in these two functions. Signed-off-by: Gao Feng --- v3: Merge another refine patch, remove useless rcu lock, per Pablo v2: add the rcu lock in nf_conntrack_helper_try_module_get v1: initial version net/netfilter/nf_conntrack_helper.c | 17 - net/netfilter/nf_conntrack_netlink.c | 10 -- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..4eeb341 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -158,16 +158,25 @@ struct nf_conntrack_helper * { struct nf_conntrack_helper *h; + rcu_read_lock(); + h = __nf_conntrack_helper_find(name, l3num, protonum); #ifdef CONFIG_MODULES if (h == NULL) { - if (request_module("nfct-helper-%s", name) == 0) + rcu_read_unlock(); + if (request_module("nfct-helper-%s", name) == 0) { + rcu_read_lock(); h = __nf_conntrack_helper_find(name, l3num, protonum); + } else { + return h; + } } #endif if (h != NULL && !try_module_get(h->me)) h = NULL; + rcu_read_unlock(); + return h; } EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get); @@ -311,38 +320,36 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister); +/* Caller should hold the rcu lock */ struct nf_ct_helper_expectfn * nf_ct_helper_expectfn_find_by_name(const char *name) { struct nf_ct_helper_expectfn *cur; bool found = false; - rcu_read_lock(); list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) { if (!strcmp(cur->name, name)) { found = true; break; } } - rcu_read_unlock(); return found ? cur : NULL; } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_name); +/* Caller should hold the rcu lock */ struct nf_ct_helper_expectfn * nf_ct_helper_expectfn_find_by_symbol(const void *symbol) { struct nf_ct_helper_expectfn *cur; bool found = false; - rcu_read_lock(); list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) { if (cur->expectfn == symbol) { found = true; break; } } - rcu_read_unlock(); return found ? cur : NULL; } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6806b5e..f6d1d63 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -3133,23 +3133,27 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, return -ENOENT; ct = nf_ct_tuplehash_to_ctrack(h); + rcu_read_lock(); if (cda[CTA_EXPECT_HELP_NAME]) { const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper == NULL) { + rcu_read_unlock(); #ifdef CONFIG_MODULES if (request_module("nfct-helper-%s", helpname) < 0) { err = -EOPNOTSUPP; goto err_ct; } + rcu_read_lock(); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper) { err = -EAGAIN; - goto err_ct; + goto err_rcu; } + rcu_read_unlock(); #endif err = -EOPNOTSUPP; goto err_ct; @@ -3159,11 +3163,13 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask); if (IS_ERR(exp)) { err = P
[PATCH nf-next 1/1] netfilter: ctlink: Return error directly when create expect without help
From: Gao Feng The expect check func "__nf_ct_expect_check" asks the master_help is necessary. So it is unnecessary to go ahead in ctnetlink_alloc_expect when there is no help. Actually the commit bc01befdcf3e ("netfilter: ctnetlink: add support for user-space expectation helpers") permits ctlink create one expect even though there is no master help. But the latter commit 3d058d7bc2c5 ("netfilter: rework user-space expectation helper support") disables it again. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_netlink.c | 14 ++ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d49cc1e..c9af545 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -3049,18 +3049,8 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, help = nfct_help(ct); if (!help) { - if (!cda[CTA_EXPECT_TIMEOUT]) { - err = -EINVAL; - goto err_out; - } - exp->timeout.expires = - jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ; - - exp->flags = NF_CT_EXPECT_USERSPACE; - if (cda[CTA_EXPECT_FLAGS]) { - exp->flags |= - ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); - } + err = -EOPNOTSUPP; + goto err_out; } else { if (cda[CTA_EXPECT_FLAGS]) { exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next v2 1/1] netfilter: nat: Correct the return value check for nat mangled packet
From: Gao Feng The return value type of function nf_nat_mangle_tcp/udp_packet is int, but actually it is used as bool type. And most codes follow this rule, for example, the sip, h323, and ftp. But some codes treat the return value as NF_ACCEPT and NF_DROP, like amanda and irc. Now use the bool type instead of the int to make it clear. Signed-off-by: Gao Feng --- v2: Merge two patches into one, and enhance the subject, per Pablo v1: init version include/net/netfilter/nf_nat_helper.h | 14 ++-- net/ipv4/netfilter/nf_nat_pptp.c | 20 +- net/netfilter/nf_nat_amanda.c | 11 +- net/netfilter/nf_nat_helper.c | 40 +-- net/netfilter/nf_nat_irc.c| 9 5 files changed, 46 insertions(+), 48 deletions(-) diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h index 01bcc6b..b27c391 100644 --- a/include/net/netfilter/nf_nat_helper.h +++ b/include/net/netfilter/nf_nat_helper.h @@ -7,13 +7,13 @@ struct sk_buff; /* These return true or false. */ -int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, struct nf_conn *ct, +bool __nf_nat_mangle_tcp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int protoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len, bool adjust); -static inline int nf_nat_mangle_tcp_packet(struct sk_buff *skb, +static inline bool nf_nat_mangle_tcp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int protoff, @@ -27,11 +27,11 @@ static inline int nf_nat_mangle_tcp_packet(struct sk_buff *skb, rep_buffer, rep_len, true); } -int nf_nat_mangle_udp_packet(struct sk_buff *skb, struct nf_conn *ct, -enum ip_conntrack_info ctinfo, -unsigned int protoff, unsigned int match_offset, -unsigned int match_len, const char *rep_buffer, -unsigned int rep_len); +bool nf_nat_mangle_udp_packet(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int protoff, unsigned int match_offset, + unsigned int match_len, const char *rep_buffer, + unsigned int rep_len); /* Setup NAT on this expected conntrack so it follows master, but goes * to port ct->master->saved_proto. */ diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index b3ca21b..211fee5 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c @@ -177,11 +177,11 @@ pptp_outbound_pkt(struct sk_buff *skb, ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid)); /* mangle packet */ - if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, -cid_off + sizeof(struct pptp_pkt_hdr) + -sizeof(struct PptpControlHeader), -sizeof(new_callid), (char *)&new_callid, -sizeof(new_callid)) == 0) + if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, + cid_off + sizeof(struct pptp_pkt_hdr) + + sizeof(struct PptpControlHeader), + sizeof(new_callid), (char *)&new_callid, + sizeof(new_callid))) return NF_DROP; return NF_ACCEPT; } @@ -271,11 +271,11 @@ pptp_inbound_pkt(struct sk_buff *skb, pr_debug("altering peer call id from 0x%04x to 0x%04x\n", ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid)); - if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, -pcid_off + sizeof(struct pptp_pkt_hdr) + -sizeof(struct PptpControlHeader), -sizeof(new_pcid), (char *)&new_pcid, -sizeof(new_pcid)) == 0) + if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, + pcid_off + sizeof(struct pptp_pkt_hdr) + + sizeof(struct PptpControlHeader), + sizeof(new_pcid), (char *)&new_pcid, + sizeof(new_pcid))) return NF_DROP; return NF_ACCEPT; } diff --git a/net/netfilter/nf_nat_amanda.c b/net/netfilter/nf_nat_amanda.c index eb77238..e4d61a7 100644
[PATCH nf-next 1/1] netfilter: expect: Add one common func nf_ct_remove_expect to simplify codes
From: Gao Feng When remove one expect, it needs three statements. And there are multiple duplicated codes in current codes. So add one common func nf_ct_remove_expect to simplify the codes. Signed-off-by: Gao Feng --- include/net/netfilter/nf_conntrack_expect.h | 1 + net/netfilter/nf_conntrack_expect.c | 33 +++-- net/netfilter/nf_conntrack_helper.c | 6 ++ net/netfilter/nf_conntrack_sip.c| 4 +--- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 65cc2cb..dff3068 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -104,6 +104,7 @@ static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); +bool nf_ct_remove_expect(struct nf_conntrack_expect *exp); /* Allocate space for an expectation: this is mandatory before calling nf_ct_expect_related. You will have to call put afterwards. */ diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index cb29e59..bbffe6a 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -103,6 +103,18 @@ static unsigned int nf_ct_expect_dst_hash(const struct net *n, const struct nf_c nf_ct_zone_equal_any(i->master, zone); } +bool +nf_ct_remove_expect(struct nf_conntrack_expect *exp) +{ + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(nf_ct_remove_expect); + struct nf_conntrack_expect * __nf_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone, @@ -211,10 +223,7 @@ void nf_ct_remove_expectations(struct nf_conn *ct) spin_lock_bh(&nf_conntrack_expect_lock); hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) { - if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); - nf_ct_expect_put(exp); - } + nf_ct_remove_expect(exp); } spin_unlock_bh(&nf_conntrack_expect_lock); } @@ -255,10 +264,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a, void nf_ct_unexpect_related(struct nf_conntrack_expect *exp) { spin_lock_bh(&nf_conntrack_expect_lock); - if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); - nf_ct_expect_put(exp); - } + nf_ct_remove_expect(exp); spin_unlock_bh(&nf_conntrack_expect_lock); } EXPORT_SYMBOL_GPL(nf_ct_unexpect_related); @@ -394,10 +400,8 @@ static void evict_oldest_expect(struct nf_conn *master, last = exp; } - if (last && del_timer(&last->timeout)) { - nf_ct_unlink_expect(last); - nf_ct_expect_put(last); - } + if (last) + nf_ct_remove_expect(last); } static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) @@ -419,11 +423,8 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) h = nf_ct_expect_dst_hash(net, &expect->tuple); hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) { if (expect_matches(i, expect)) { - if (del_timer(&i->timeout)) { - nf_ct_unlink_expect(i); - nf_ct_expect_put(i); + if (nf_ct_remove_expect(expect)) break; - } } else if (expect_clash(i, expect)) { ret = -EBUSY; goto out; diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..97bc0d2 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -448,10 +448,8 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) if ((rcu_dereference_protected( help->helper, lockdep_is_held(&nf_conntrack_expect_lock) - ) == me || exp->helper == me) && - del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); - nf_ct_expect_put(exp); + ) == me || exp->helper == me)) { + nf_ct_remove_expect(exp); } } } diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 0d17894..91a9c97 10
[PATCH nf v5 1/1] netfilter: snmp: Fix one possible panic when snmp_trap_helper fail to register
From: Gao Feng In the commit 93557f53e1fb ("netfilter: nf_conntrack: nf_conntrack snmp helper"), the snmp_helper is replaced by nf_nat_snmp_hook. So the snmp_helper is never registered. But it still tries to unregister the snmp_helper, it could cause the panic. Now remove the useless snmp_helper and the unregister call in the error handler. Fixes: 93557f53e1fb ("netfilter: nf_conntrack: nf_conntrack snmp helper") Signed-off-by: Gao Feng --- v5: Remove useless variable, per Liping v4: Simplify the codes, per Pablo v3: Remove the angle brackets in description, per Sergei v2: Add the SHA1 ID in the description, per Sergei v1: Initial version net/ipv4/netfilter/nf_nat_snmp_basic.c | 19 +-- 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index c9b52c3..6309c40 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -1260,16 +1260,6 @@ static int help(struct sk_buff *skb, unsigned int protoff, .timeout= 180, }; -static struct nf_conntrack_helper snmp_helper __read_mostly = { - .me = THIS_MODULE, - .help = help, - .expect_policy = &snmp_exp_policy, - .name = "snmp", - .tuple.src.l3num= AF_INET, - .tuple.src.u.udp.port = cpu_to_be16(SNMP_PORT), - .tuple.dst.protonum = IPPROTO_UDP, -}; - static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { .me = THIS_MODULE, .help = help, @@ -1288,17 +1278,10 @@ static int help(struct sk_buff *skb, unsigned int protoff, static int __init nf_nat_snmp_basic_init(void) { - int ret = 0; - BUG_ON(nf_nat_snmp_hook != NULL); RCU_INIT_POINTER(nf_nat_snmp_hook, help); - ret = nf_conntrack_helper_register(&snmp_trap_helper); - if (ret < 0) { - nf_conntrack_helper_unregister(&snmp_helper); - return ret; - } - return ret; + return nf_conntrack_helper_register(&snmp_trap_helper); } static void __exit nf_nat_snmp_basic_fini(void) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v4 1/1] netfilter: snmp: Fix one possible panic when snmp_trap_helper fail to register
From: Gao Feng In the commit 93557f53e1fb ("netfilter: nf_conntrack: nf_conntrack snmp helper"), the snmp_helper is replaced by nf_nat_snmp_hook. So the snmp_helper is never registered. But it still tries to unregister the snmp_helper, it could cause the panic. Now remove the useless snmp_helper and the unregister call in the error handler. Fixes: 93557f53e1fb ("netfilter: nf_conntrack: nf_conntrack snmp helper") Signed-off-by: Gao Feng --- v4: Simplify the codes, per Pablo v3: Remove the angle brackets in description, per Sergei v2: Add the SHA1 ID in the description, per Sergei v1: Initial version net/ipv4/netfilter/nf_nat_snmp_basic.c | 17 + 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index c9b52c3..36d16e5 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -1260,16 +1260,6 @@ static int help(struct sk_buff *skb, unsigned int protoff, .timeout= 180, }; -static struct nf_conntrack_helper snmp_helper __read_mostly = { - .me = THIS_MODULE, - .help = help, - .expect_policy = &snmp_exp_policy, - .name = "snmp", - .tuple.src.l3num= AF_INET, - .tuple.src.u.udp.port = cpu_to_be16(SNMP_PORT), - .tuple.dst.protonum = IPPROTO_UDP, -}; - static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { .me = THIS_MODULE, .help = help, @@ -1293,12 +1283,7 @@ static int __init nf_nat_snmp_basic_init(void) BUG_ON(nf_nat_snmp_hook != NULL); RCU_INIT_POINTER(nf_nat_snmp_hook, help); - ret = nf_conntrack_helper_register(&snmp_trap_helper); - if (ret < 0) { - nf_conntrack_helper_unregister(&snmp_helper); - return ret; - } - return ret; + return nf_conntrack_helper_register(&snmp_trap_helper); } static void __exit nf_nat_snmp_basic_fini(void) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2 1/1] netfilter: expect: Make sure the max_expected limit is effective
From: Gao Feng Because the type of expecting, the member of nf_conn_help, is u8, it would overflow after reach U8_MAX(255). So it doesn't work when we configure the max_expected exceeds 255 with expect policy. Now add the check for max_expected. Return the -EINVAL when it exceeds the limit. Signed-off-by: Gao Feng --- v2: Check the modparam of irc, per Pablo v1: initial version include/net/netfilter/nf_conntrack_expect.h | 1 + net/netfilter/nf_conntrack_helper.c | 3 +++ net/netfilter/nf_conntrack_irc.c| 6 ++ net/netfilter/nfnetlink_cthelper.c | 6 ++ 4 files changed, 16 insertions(+) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5ed33ea..80f2ff6 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -71,6 +71,7 @@ struct nf_conntrack_expect_policy { }; #define NF_CT_EXPECT_CLASS_DEFAULT 0 +#define NF_CT_EXPECT_MAX_CNT 255 int nf_conntrack_expect_pernet_init(struct net *net); void nf_conntrack_expect_pernet_fini(struct net *net); diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..752a977 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -385,6 +385,9 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1); + if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; + mutex_lock(&nf_ct_helper_mutex); hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) { if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) { diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 1972a14..1a5af4d 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -243,6 +243,12 @@ static int __init nf_conntrack_irc_init(void) return -EINVAL; } + if (max_dcc_channels > NF_CT_EXPECT_MAX_CNT) { + pr_err("max_dcc_channels must not be more than %u\n", + NF_CT_EXPECT_MAX_CNT); + return -EINVAL; + } + irc_exp_policy.max_expected = max_dcc_channels; irc_exp_policy.timeout = dcc_timeout; diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 2b987d2..d150679 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -143,6 +143,9 @@ nla_data(tb[NFCTH_POLICY_NAME]), NF_CT_HELPER_NAME_LEN); expect_policy->max_expected = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); + if (expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; + expect_policy->timeout = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])); @@ -280,6 +283,9 @@ new_policy->max_expected = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); + if (new_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; + new_policy->timeout = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf 1/1] netfilter: expect: Make sure the max_expected limit is effective
From: Gao Feng Because the type of expecting, the member of nf_conn_help, is u8, it would overflow after reach U8_MAX(255). So it doesn't work when we configure the max_expected exceeds 255 with expect policy. Now add the check for max_expected. Return the -EINVAL when it exceeds the limit. Signed-off-by: Gao Feng --- include/net/netfilter/nf_conntrack_expect.h | 1 + net/netfilter/nf_conntrack_helper.c | 3 +++ net/netfilter/nfnetlink_cthelper.c | 4 3 files changed, 8 insertions(+) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5ed33ea..aa36a31 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -71,6 +71,7 @@ struct nf_conntrack_expect_policy { }; #define NF_CT_EXPECT_CLASS_DEFAULT 0 +#define NF_CT_EXPECT_MAX_CNT U8_MAX int nf_conntrack_expect_pernet_init(struct net *net); void nf_conntrack_expect_pernet_fini(struct net *net); diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..752a977 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -385,6 +385,9 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1); + if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; + mutex_lock(&nf_ct_helper_mutex); hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) { if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) { diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 2b987d2..de841b3 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -143,6 +143,8 @@ nla_data(tb[NFCTH_POLICY_NAME]), NF_CT_HELPER_NAME_LEN); expect_policy->max_expected = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); + if (expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; expect_policy->timeout = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])); @@ -280,6 +282,8 @@ new_policy->max_expected = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); + if (new_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; new_policy->timeout = ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v2 1/1] netfilter: helper: Add the rcu lock when call __nf_conntrack_helper_find
From: Gao Feng When invoke __nf_conntrack_helper_find, it needs the rcu lock to protect the helper module which would not be unloaded. Now there are two caller nf_conntrack_helper_try_module_get and ctnetlink_create_expect which don't hold rcu lock. And the other callers left like ctnetlink_change_helper, ctnetlink_create_conntrack, and ctnetlink_glue_attach_expect, they already hold the rcu lock or spin_lock_bh. Signed-off-by: Gao Feng --- v2: add the rcu lock in nf_conntrack_helper_try_module_get v1: initial version net/netfilter/nf_conntrack_helper.c | 11 ++- net/netfilter/nf_conntrack_netlink.c | 10 -- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..023af78 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -158,16 +158,25 @@ struct nf_conntrack_helper * { struct nf_conntrack_helper *h; + rcu_read_lock(); + h = __nf_conntrack_helper_find(name, l3num, protonum); #ifdef CONFIG_MODULES if (h == NULL) { - if (request_module("nfct-helper-%s", name) == 0) + rcu_read_unlock(); + if (request_module("nfct-helper-%s", name) == 0) { + rcu_read_lock(); h = __nf_conntrack_helper_find(name, l3num, protonum); + } else { + return h; + } } #endif if (h != NULL && !try_module_get(h->me)) h = NULL; + rcu_read_unlock(); + return h; } EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6806b5e..f6d1d63 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -3133,23 +3133,27 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, return -ENOENT; ct = nf_ct_tuplehash_to_ctrack(h); + rcu_read_lock(); if (cda[CTA_EXPECT_HELP_NAME]) { const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper == NULL) { + rcu_read_unlock(); #ifdef CONFIG_MODULES if (request_module("nfct-helper-%s", helpname) < 0) { err = -EOPNOTSUPP; goto err_ct; } + rcu_read_lock(); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper) { err = -EAGAIN; - goto err_ct; + goto err_rcu; } + rcu_read_unlock(); #endif err = -EOPNOTSUPP; goto err_ct; @@ -3159,11 +3163,13 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask); if (IS_ERR(exp)) { err = PTR_ERR(exp); - goto err_ct; + goto err_rcu; } err = nf_ct_expect_related_report(exp, portid, report); nf_ct_expect_put(exp); +err_rcu: + rcu_read_unlock(); err_ct: nf_ct_put(ct); return err; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf-next v2 1/1] netfilter: helper: Remove useless rcu lock when get expectfn
From: Gao Feng Because these two functions return the nf_ct_helper_expectfn pointer which should be protected by rcu lock. So it should makes sure the caller should hold the rcu lock, not inside these functions. Signed-off-by: Gao Feng --- v2: Shorter subject, per Pablo v1: Initial version net/netfilter/nf_conntrack_helper.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..bce3d1f 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -311,38 +311,36 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister); +/* Caller should hold the rcu lock */ struct nf_ct_helper_expectfn * nf_ct_helper_expectfn_find_by_name(const char *name) { struct nf_ct_helper_expectfn *cur; bool found = false; - rcu_read_lock(); list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) { if (!strcmp(cur->name, name)) { found = true; break; } } - rcu_read_unlock(); return found ? cur : NULL; } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_name); +/* Caller should hold the rcu lock */ struct nf_ct_helper_expectfn * nf_ct_helper_expectfn_find_by_symbol(const void *symbol) { struct nf_ct_helper_expectfn *cur; bool found = false; - rcu_read_lock(); list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) { if (cur->expectfn == symbol) { found = true; break; } } - rcu_read_unlock(); return found ? cur : NULL; } EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESENT nf 1/1] netfilter: ctlink: Fix one possible use-after-free in ctnetlink_create_expect
From: Gao Feng There is no rcu_read_lock during ctlink gets the helper and inserts the expectation. So there is one possible use-after-free issue when unload the helper module. For example: CPU1CPU2 ctlink gets the helper helper module unload and remove all expectations insert the expectation Now there is one expectation which references one helper whose module is unloaded. Signed-off-by: Gao Feng --- net/netfilter/nf_conntrack_netlink.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6806b5e..f6d1d63 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -3133,23 +3133,27 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, return -ENOENT; ct = nf_ct_tuplehash_to_ctrack(h); + rcu_read_lock(); if (cda[CTA_EXPECT_HELP_NAME]) { const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper == NULL) { + rcu_read_unlock(); #ifdef CONFIG_MODULES if (request_module("nfct-helper-%s", helpname) < 0) { err = -EOPNOTSUPP; goto err_ct; } + rcu_read_lock(); helper = __nf_conntrack_helper_find(helpname, u3, nf_ct_protonum(ct)); if (helper) { err = -EAGAIN; - goto err_ct; + goto err_rcu; } + rcu_read_unlock(); #endif err = -EOPNOTSUPP; goto err_ct; @@ -3159,11 +3163,13 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask); if (IS_ERR(exp)) { err = PTR_ERR(exp); - goto err_ct; + goto err_rcu; } err = nf_ct_expect_related_report(exp, portid, report); nf_ct_expect_put(exp); +err_rcu: + rcu_read_unlock(); err_ct: nf_ct_put(ct); return err; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v4 0/2] Fix invoking expectfn unloaded
From: Gao Feng It is possible that invoke one expectfn whose module is already unloaded. These two patches are used to fix it. Gao Feng (2): netfilter: helper: Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper netfilter: helper: Fix possible panic caused by invoking expectfn unloaded include/net/netfilter/nf_conntrack_expect.h | 2 + include/net/netfilter/nf_conntrack_helper.h | 15 ++--- net/ipv4/netfilter/nf_nat_h323.c| 20 -- net/netfilter/nf_conntrack_broadcast.c | 1 + net/netfilter/nf_conntrack_expect.c | 1 + net/netfilter/nf_conntrack_helper.c | 95 + net/netfilter/nf_conntrack_netlink.c| 21 --- net/netfilter/nf_conntrack_pptp.c | 2 + net/netfilter/nf_nat_amanda.c | 1 + net/netfilter/nf_nat_core.c | 7 ++- net/netfilter/nf_nat_ftp.c | 1 + net/netfilter/nf_nat_irc.c | 1 + net/netfilter/nf_nat_sip.c | 10 ++- net/netfilter/nf_nat_tftp.c | 1 + 14 files changed, 110 insertions(+), 68 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH nf v4 1/2] netfilter: helper: Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper
From: Gao Feng Rename struct nf_ct_helper_expectfn to nf_ct_nat_helper, and rename other functions or variables which refer to it. The new name is better than the old one. Signed-off-by: Gao Feng --- v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo, v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_helper.h | 14 ++--- net/ipv4/netfilter/nf_nat_h323.c| 12 +-- net/netfilter/nf_conntrack_helper.c | 32 ++--- net/netfilter/nf_conntrack_netlink.c| 16 +++ net/netfilter/nf_nat_core.c | 6 +++--- net/netfilter/nf_nat_sip.c | 6 +++--- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1eaac1f..d14fe493 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -111,7 +111,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, enum ip_conntrack_info ctinfo, unsigned int timeout); -struct nf_ct_helper_expectfn { +struct nf_ct_nat_helper { struct list_head head; const char *name; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); @@ -121,12 +121,12 @@ struct nf_ct_helper_expectfn { void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, const char *fmt, ...); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n); -void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_name(const char *name); -struct nf_ct_helper_expectfn * -nf_ct_helper_expectfn_find_by_symbol(const void *symbol); +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n); +void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_name(const char *name); +struct nf_ct_nat_helper * +nf_ct_nat_helper_find_by_symbol(const void *symbol); extern struct hlist_head *nf_ct_helper_hash; extern unsigned int nf_ct_helper_hsize; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 574f7eb..346e764 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -567,12 +567,12 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, return 0; } -static struct nf_ct_helper_expectfn q931_nat = { +static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", .expectfn = ip_nat_q931_expect, }; -static struct nf_ct_helper_expectfn callforwarding_nat = { +static struct nf_ct_nat_helper callforwarding_nat = { .name = "callforwarding", .expectfn = ip_nat_callforwarding_expect, }; @@ -599,8 +599,8 @@ static int __init init(void) RCU_INIT_POINTER(nat_h245_hook, nat_h245); RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding); RCU_INIT_POINTER(nat_q931_hook, nat_q931); - nf_ct_helper_expectfn_register(&q931_nat); - nf_ct_helper_expectfn_register(&callforwarding_nat); + nf_ct_nat_helper_register(&q931_nat); + nf_ct_nat_helper_register(&callforwarding_nat); return 0; } @@ -616,8 +616,8 @@ static void __exit fini(void) RCU_INIT_POINTER(nat_h245_hook, NULL); RCU_INIT_POINTER(nat_callforwarding_hook, NULL); RCU_INIT_POINTER(nat_q931_hook, NULL); - nf_ct_helper_expectfn_unregister(&q931_nat); - nf_ct_helper_expectfn_unregister(&callforwarding_nat); + nf_ct_nat_helper_unregister(&q931_nat); + nf_ct_nat_helper_unregister(&callforwarding_nat); synchronize_rcu(); } diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9..0eaa01e 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -293,32 +293,32 @@ void nf_ct_helper_destroy(struct nf_conn *ct) } } -static LIST_HEAD(nf_ct_helper_expectfn_list); +static LIST_HEAD(nf_ct_nat_helper_list); -void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n) +void nf_ct_nat_helper_register(struct nf_ct_nat_helper *n) { spin_lock_bh(&nf_conntrack_expect_lock); - list_add_rcu(&n->head, &nf_ct_helper_expectfn_list); + list_add_rcu(&n->head, &nf_ct_nat_helper_list); spin_unlock_bh(&nf_conntrack_expect_lock); } -EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register); +EXPORT_SYMBOL_GPL(nf_ct_nat_helper_register); -void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) +void nf_ct_nat_helper_unregister(struct nf_ct_nat_helper *n) { spin_lock_bh(&nf_conntrack_expect_lock); list_del_rcu(&n->head); spin_unlock_bh(&nf_connt
[PATCH nf v4 2/2] netfilter: helper: Fix possible panic caused by invoking expectfn unloaded
From: Gao Feng Because the conntrack NAT module could be rmmod anytime, so we should really leave things in clean state if such thing happens and make sure we don't leave any packet running over code that will be gone after the removal. We only removed the expectations when unregister conntrack helper before. Actually it is necessary too when remove the nat helper. Signed-off-by: Gao Feng --- v4: Cover the nat_module assignment in dataplane, per Pablo v3: Rename the nf_ct_helper_expectfn, func, and member, per Pablo v2: Use the module as the identifier when flush expect v1: initial version include/net/netfilter/nf_conntrack_expect.h | 2 + include/net/netfilter/nf_conntrack_helper.h | 1 + net/ipv4/netfilter/nf_nat_h323.c| 8 net/netfilter/nf_conntrack_broadcast.c | 1 + net/netfilter/nf_conntrack_expect.c | 1 + net/netfilter/nf_conntrack_helper.c | 63 ++--- net/netfilter/nf_conntrack_netlink.c| 5 ++- net/netfilter/nf_conntrack_pptp.c | 2 + net/netfilter/nf_nat_amanda.c | 1 + net/netfilter/nf_nat_core.c | 1 + net/netfilter/nf_nat_ftp.c | 1 + net/netfilter/nf_nat_irc.c | 1 + net/netfilter/nf_nat_sip.c | 4 ++ net/netfilter/nf_nat_tftp.c | 1 + 14 files changed, 67 insertions(+), 25 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5ed33ea..f2bc64e 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -26,6 +26,8 @@ struct nf_conntrack_expect { /* Function to call after setup and insertion */ void (*expectfn)(struct nf_conn *new, struct nf_conntrack_expect *this); + /* The module which expectfn belongs to */ + struct module *nat_module; /* Helper to assign to new connection */ struct nf_conntrack_helper *helper; diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index d14fe493..dd1a687 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -113,6 +113,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff, struct nf_ct_nat_helper { struct list_head head; + struct module *me; const char *name; void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); }; diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 346e764..df57219 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -188,9 +188,11 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; rtp_exp->expectfn = nf_nat_follow_master; + rtp_exp->nat_module = THIS_MODULE; rtp_exp->dir = !dir; rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port; rtcp_exp->expectfn = nf_nat_follow_master; + rtcp_exp->nat_module = THIS_MODULE; rtcp_exp->dir = !dir; /* Lookup existing expects */ @@ -290,6 +292,7 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->expectfn = nf_nat_follow_master; + exp->nat_module = THIS_MODULE; exp->dir = !dir; /* Try to get same port: if not, try to change it. */ @@ -342,6 +345,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->expectfn = nf_nat_follow_master; + exp->nat_module = THIS_MODULE; exp->dir = !dir; /* Check existing expects */ @@ -434,6 +438,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, /* Set expectations for NAT */ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->expectfn = ip_nat_q931_expect; + exp->nat_module = THIS_MODULE; exp->dir = !dir; /* Check existing expects */ @@ -528,6 +533,7 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip; exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->expectfn = ip_nat_callforwarding_expect; + exp->nat_module = THIS_MODULE; exp->dir = !dir; /* Try to get same port: if not, try to change it. */ @@ -569,11 +575,13 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, static struct nf_ct_nat_helper q931_nat = { .name = "Q.931", + .me = THIS_MODULE, .expectfn = ip_nat_q931_e