Loading net/netfilter/xt_CT.c +56 −89 Original line number Diff line number Diff line Loading @@ -20,12 +20,8 @@ #include <net/netfilter/nf_conntrack_timeout.h> #include <net/netfilter/nf_conntrack_zones.h> static unsigned int xt_ct_target_v0(struct sk_buff *skb, const struct xt_action_param *par) static inline int xt_ct_target(struct sk_buff *skb, struct nf_conn *ct) { const struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; /* Previously seen (loopback)? Ignore. */ if (skb->nfct != NULL) return XT_CONTINUE; Loading @@ -37,21 +33,22 @@ static unsigned int xt_ct_target_v0(struct sk_buff *skb, return XT_CONTINUE; } static unsigned int xt_ct_target_v1(struct sk_buff *skb, static unsigned int xt_ct_target_v0(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info_v1 *info = par->targinfo; const struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; /* Previously seen (loopback)? Ignore. */ if (skb->nfct != NULL) return XT_CONTINUE; return xt_ct_target(skb, ct); } atomic_inc(&ct->ct_general.use); skb->nfct = &ct->ct_general; skb->nfctinfo = IP_CT_NEW; static unsigned int xt_ct_target_v1(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conn *ct = info->ct; return XT_CONTINUE; return xt_ct_target(skb, ct); } static u8 xt_ct_find_proto(const struct xt_tgchk_param *par) Loading Loading @@ -104,67 +101,6 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name, return 0; } static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) { struct xt_ct_target_info *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; int ret = -EOPNOTSUPP; if (info->flags & ~XT_CT_NOTRACK) return -EINVAL; if (info->flags & XT_CT_NOTRACK) { ct = nf_ct_untracked_get(); atomic_inc(&ct->ct_general.use); goto out; } #ifndef CONFIG_NF_CONNTRACK_ZONES if (info->zone) goto err1; #endif ret = nf_ct_l3proto_try_module_get(par->family); if (ret < 0) goto err1; memset(&t, 0, sizeof(t)); ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL); ret = PTR_ERR(ct); if (IS_ERR(ct)) goto err2; ret = 0; if ((info->ct_events || info->exp_events) && !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, GFP_KERNEL)) goto err3; if (info->helper[0]) { ret = xt_ct_set_helper(ct, info->helper, par); if (ret < 0) goto err3; } __set_bit(IPS_TEMPLATE_BIT, &ct->status); __set_bit(IPS_CONFIRMED_BIT, &ct->status); /* Overload tuple linked list to put us in template list. */ hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, &par->net->ct.tmpl); out: info->ct = ct; return 0; err3: nf_conntrack_free(ct); err2: nf_ct_l3proto_module_put(par->family); err1: return ret; } #ifdef CONFIG_NF_CONNTRACK_TIMEOUT static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) { Loading Loading @@ -242,9 +178,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, #endif } static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) static int xt_ct_tg_check(const struct xt_tgchk_param *par, struct xt_ct_target_info_v1 *info) { struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; int ret = -EOPNOTSUPP; Loading Loading @@ -309,20 +245,31 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) return ret; } static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par) static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) { struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; struct nf_conn_help *help; struct xt_ct_target_info_v1 info_v1 = { .flags = info->flags, .zone = info->zone, .ct_events = info->ct_events, .exp_events = info->exp_events, }; int ret; if (!nf_ct_is_untracked(ct)) { help = nfct_help(ct); if (help) module_put(help->helper->me); memcpy(info_v1.helper, info->helper, sizeof(info->helper)); nf_ct_l3proto_module_put(par->family); ret = xt_ct_tg_check(par, &info_v1); if (ret < 0) return ret; info->ct = info_v1.ct; return ret; } nf_ct_put(info->ct); static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) { return xt_ct_tg_check(par, par->targinfo); } static void xt_ct_destroy_timeout(struct nf_conn *ct) Loading @@ -343,9 +290,9 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct) #endif } static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, struct xt_ct_target_info_v1 *info) { struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conn *ct = info->ct; struct nf_conn_help *help; Loading @@ -361,6 +308,26 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) nf_ct_put(info->ct); } static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par) { struct xt_ct_target_info *info = par->targinfo; struct xt_ct_target_info_v1 info_v1 = { .flags = info->flags, .zone = info->zone, .ct_events = info->ct_events, .exp_events = info->exp_events, .ct = info->ct, }; memcpy(info_v1.helper, info->helper, sizeof(info->helper)); xt_ct_tg_destroy(par, &info_v1); } static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) { xt_ct_tg_destroy(par, par->targinfo); } static struct xt_target xt_ct_tg_reg[] __read_mostly = { { .name = "CT", Loading Loading
net/netfilter/xt_CT.c +56 −89 Original line number Diff line number Diff line Loading @@ -20,12 +20,8 @@ #include <net/netfilter/nf_conntrack_timeout.h> #include <net/netfilter/nf_conntrack_zones.h> static unsigned int xt_ct_target_v0(struct sk_buff *skb, const struct xt_action_param *par) static inline int xt_ct_target(struct sk_buff *skb, struct nf_conn *ct) { const struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; /* Previously seen (loopback)? Ignore. */ if (skb->nfct != NULL) return XT_CONTINUE; Loading @@ -37,21 +33,22 @@ static unsigned int xt_ct_target_v0(struct sk_buff *skb, return XT_CONTINUE; } static unsigned int xt_ct_target_v1(struct sk_buff *skb, static unsigned int xt_ct_target_v0(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info_v1 *info = par->targinfo; const struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; /* Previously seen (loopback)? Ignore. */ if (skb->nfct != NULL) return XT_CONTINUE; return xt_ct_target(skb, ct); } atomic_inc(&ct->ct_general.use); skb->nfct = &ct->ct_general; skb->nfctinfo = IP_CT_NEW; static unsigned int xt_ct_target_v1(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conn *ct = info->ct; return XT_CONTINUE; return xt_ct_target(skb, ct); } static u8 xt_ct_find_proto(const struct xt_tgchk_param *par) Loading Loading @@ -104,67 +101,6 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name, return 0; } static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) { struct xt_ct_target_info *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; int ret = -EOPNOTSUPP; if (info->flags & ~XT_CT_NOTRACK) return -EINVAL; if (info->flags & XT_CT_NOTRACK) { ct = nf_ct_untracked_get(); atomic_inc(&ct->ct_general.use); goto out; } #ifndef CONFIG_NF_CONNTRACK_ZONES if (info->zone) goto err1; #endif ret = nf_ct_l3proto_try_module_get(par->family); if (ret < 0) goto err1; memset(&t, 0, sizeof(t)); ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL); ret = PTR_ERR(ct); if (IS_ERR(ct)) goto err2; ret = 0; if ((info->ct_events || info->exp_events) && !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, GFP_KERNEL)) goto err3; if (info->helper[0]) { ret = xt_ct_set_helper(ct, info->helper, par); if (ret < 0) goto err3; } __set_bit(IPS_TEMPLATE_BIT, &ct->status); __set_bit(IPS_CONFIRMED_BIT, &ct->status); /* Overload tuple linked list to put us in template list. */ hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, &par->net->ct.tmpl); out: info->ct = ct; return 0; err3: nf_conntrack_free(ct); err2: nf_ct_l3proto_module_put(par->family); err1: return ret; } #ifdef CONFIG_NF_CONNTRACK_TIMEOUT static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) { Loading Loading @@ -242,9 +178,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, #endif } static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) static int xt_ct_tg_check(const struct xt_tgchk_param *par, struct xt_ct_target_info_v1 *info) { struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; int ret = -EOPNOTSUPP; Loading Loading @@ -309,20 +245,31 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) return ret; } static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par) static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) { struct xt_ct_target_info *info = par->targinfo; struct nf_conn *ct = info->ct; struct nf_conn_help *help; struct xt_ct_target_info_v1 info_v1 = { .flags = info->flags, .zone = info->zone, .ct_events = info->ct_events, .exp_events = info->exp_events, }; int ret; if (!nf_ct_is_untracked(ct)) { help = nfct_help(ct); if (help) module_put(help->helper->me); memcpy(info_v1.helper, info->helper, sizeof(info->helper)); nf_ct_l3proto_module_put(par->family); ret = xt_ct_tg_check(par, &info_v1); if (ret < 0) return ret; info->ct = info_v1.ct; return ret; } nf_ct_put(info->ct); static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) { return xt_ct_tg_check(par, par->targinfo); } static void xt_ct_destroy_timeout(struct nf_conn *ct) Loading @@ -343,9 +290,9 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct) #endif } static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, struct xt_ct_target_info_v1 *info) { struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conn *ct = info->ct; struct nf_conn_help *help; Loading @@ -361,6 +308,26 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) nf_ct_put(info->ct); } static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par) { struct xt_ct_target_info *info = par->targinfo; struct xt_ct_target_info_v1 info_v1 = { .flags = info->flags, .zone = info->zone, .ct_events = info->ct_events, .exp_events = info->exp_events, .ct = info->ct, }; memcpy(info_v1.helper, info->helper, sizeof(info->helper)); xt_ct_tg_destroy(par, &info_v1); } static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) { xt_ct_tg_destroy(par, par->targinfo); } static struct xt_target xt_ct_tg_reg[] __read_mostly = { { .name = "CT", Loading