]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nf_conntrack_pptp: move GRE specific cleanup to GRE tracker
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 4 Jun 2026 06:21:10 +0000 (08:21 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 5 Jun 2026 14:16:44 +0000 (16:16 +0200)
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 <pablo@netfilter.org>
include/net/netfilter/ipv4/nf_conntrack_ipv4.h
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_gre.c

index b39417ad955ecd0f16c2c62e9156f117bab6032b..0b07d5e69c159e392ab4547896a0eb7fd53f45e9 100644 (file)
@@ -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*/
index edc85a3eef1e1f0550bfbc896f6c15be75bd1f5e..ed567a1cf7fd7e2916fd19d776edf95cf3224183 100644 (file)
@@ -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)
 {
@@ -343,7 +284,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:
@@ -593,7 +534,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);
 }
index 35e22082d65ac5e8068d7efc81e7ad82d4c87728..473658259f1a2b14895e6e6c896bfa4328b1cc87 100644 (file)
@@ -349,6 +349,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);