Move the GRE specific cleanup to nf_conntrack_proto_gre.c to ensure that the .destroy callback for the pptp helper is still reachable by existing conntrack entries while pptp module is being removed. This is a preparation patch, no functional changes are intended. Signed-off-by: Pablo Neira Ayuso --- .../net/netfilter/ipv4/nf_conntrack_ipv4.h | 4 ++ net/netfilter/nf_conntrack_pptp.c | 63 +------------------ net/netfilter/nf_conntrack_proto_gre.c | 61 ++++++++++++++++++ 3 files changed, 67 insertions(+), 61 deletions(-) diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index b39417ad955e..0b07d5e69c15 100644 --- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -20,4 +20,8 @@ extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp; extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre; #endif +#if IS_ENABLED(CONFIG_NF_CONNTRACK_PPTP) +void gre_pptp_destroy_siblings(struct nf_conn *ct); +#endif + #endif /*_NF_CONNTRACK_IPV4_H*/ diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 1c0b310d4b63..16147cf71088 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -124,65 +124,6 @@ static void pptp_expectfn(struct nf_conn *ct, } } -static int destroy_sibling_or_exp(struct net *net, struct nf_conn *ct, - const struct nf_conntrack_tuple *t) -{ - const struct nf_conntrack_tuple_hash *h; - const struct nf_conntrack_zone *zone; - struct nf_conntrack_expect *exp; - struct nf_conn *sibling; - - pr_debug("trying to timeout ct or exp for tuple "); - nf_ct_dump_tuple(t); - - zone = nf_ct_zone(ct); - h = nf_conntrack_find_get(net, zone, t); - if (h) { - sibling = nf_ct_tuplehash_to_ctrack(h); - pr_debug("setting timeout of conntrack %p to 0\n", sibling); - sibling->proto.gre.timeout = 0; - sibling->proto.gre.stream_timeout = 0; - nf_ct_kill(sibling); - nf_ct_put(sibling); - return 1; - } else { - exp = nf_ct_expect_find_get(net, zone, t); - if (exp) { - pr_debug("unexpect_related of expect %p\n", exp); - nf_ct_unexpect_related(exp); - nf_ct_expect_put(exp); - return 1; - } - } - return 0; -} - -/* timeout GRE data connections */ -static void pptp_destroy_siblings(struct nf_conn *ct) -{ - struct net *net = nf_ct_net(ct); - const struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); - struct nf_conntrack_tuple t; - - nf_ct_gre_keymap_destroy(ct); - - /* try original (pns->pac) tuple */ - memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t)); - t.dst.protonum = IPPROTO_GRE; - t.src.u.gre.key = ct_pptp_info->pns_call_id; - t.dst.u.gre.key = ct_pptp_info->pac_call_id; - if (!destroy_sibling_or_exp(net, ct, &t)) - pr_debug("failed to timeout original pns->pac ct/exp\n"); - - /* try reply (pac->pns) tuple */ - memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t)); - t.dst.protonum = IPPROTO_GRE; - t.src.u.gre.key = ct_pptp_info->pac_call_id; - t.dst.u.gre.key = ct_pptp_info->pns_call_id; - if (!destroy_sibling_or_exp(net, ct, &t)) - pr_debug("failed to timeout reply pac->pns ct/exp\n"); -} - /* expect GRE connections (PNS->PAC and PAC->PNS direction) */ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid) { @@ -347,7 +288,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, info->cstate = PPTP_CALL_NONE; /* untrack this call id, unexpect GRE packets */ - pptp_destroy_siblings(ct); + gre_pptp_destroy_siblings(ct); break; case PPTP_WAN_ERROR_NOTIFY: @@ -597,7 +538,7 @@ static int __init nf_conntrack_pptp_init(void) "pptp", PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, &pptp_exp_policy, 0, conntrack_pptp_help, NULL, THIS_MODULE); - pptp.destroy = pptp_destroy_siblings; + pptp.destroy = gre_pptp_destroy_siblings; return nf_conntrack_helper_register(&pptp, &pptp_ptr); } diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 94c19bc4edc5..a3f907416ff3 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -293,6 +293,67 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = { }; #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ +#if IS_ENABLED(CONFIG_NF_CONNTRACK_PPTP) +static int destroy_sibling_or_exp(struct net *net, struct nf_conn *ct, + const struct nf_conntrack_tuple *t) +{ + const struct nf_conntrack_tuple_hash *h; + const struct nf_conntrack_zone *zone; + struct nf_conntrack_expect *exp; + struct nf_conn *sibling; + + pr_debug("trying to timeout ct or exp for tuple "); + nf_ct_dump_tuple(t); + + zone = nf_ct_zone(ct); + h = nf_conntrack_find_get(net, zone, t); + if (h) { + sibling = nf_ct_tuplehash_to_ctrack(h); + pr_debug("setting timeout of conntrack %p to 0\n", sibling); + sibling->proto.gre.timeout = 0; + sibling->proto.gre.stream_timeout = 0; + nf_ct_kill(sibling); + nf_ct_put(sibling); + return 1; + } else { + exp = nf_ct_expect_find_get(net, zone, t); + if (exp) { + pr_debug("unexpect_related of expect %p\n", exp); + nf_ct_unexpect_related(exp); + nf_ct_expect_put(exp); + return 1; + } + } + return 0; +} + +void gre_pptp_destroy_siblings(struct nf_conn *ct) +{ + struct net *net = nf_ct_net(ct); + const struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); + struct nf_conntrack_tuple t; + + nf_ct_gre_keymap_destroy(ct); + + /* try original (pns->pac) tuple */ + memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t)); + t.dst.protonum = IPPROTO_GRE; + t.src.u.gre.key = ct_pptp_info->pns_call_id; + t.dst.u.gre.key = ct_pptp_info->pac_call_id; + if (!destroy_sibling_or_exp(net, ct, &t)) + pr_debug("failed to timeout original pns->pac ct/exp\n"); + + /* try reply (pac->pns) tuple */ + memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t)); + t.dst.protonum = IPPROTO_GRE; + t.src.u.gre.key = ct_pptp_info->pac_call_id; + t.dst.u.gre.key = ct_pptp_info->pns_call_id; + if (!destroy_sibling_or_exp(net, ct, &t)) + pr_debug("failed to timeout reply pac->pns ct/exp\n"); +} +EXPORT_SYMBOL_GPL(gre_pptp_destroy_siblings); +#endif + void nf_conntrack_gre_init_net(struct net *net) { struct nf_gre_net *net_gre = gre_pernet(net); -- 2.47.3