From 2c9a645b10ccf7c7bd790f56f7f7a2edc7788817 Mon Sep 17 00:00:00 2001 From: Sven Auhagen Date: Fri, 1 Mar 2024 10:20:28 +0100 Subject: [PATCH] NFTables: Add backwards compatibility for IPv4 NAT NFtables uses the INET table for NAT which combines IPv4 and IPv6. Older systems might not have this option and use the ip table instead. This adds a flag to fall back to the ip table style. Signed-Off-By: Sven Auhagen --- miniupnpd/commonrdr.h | 1 + miniupnpd/miniupnpd.c | 3 +++ miniupnpd/miniupnpd.conf | 1 + miniupnpd/netfilter_nft/README.md | 3 +++ miniupnpd/netfilter_nft/nftnlrdr.c | 14 +++++++++++--- miniupnpd/netfilter_nft/nftnlrdr_misc.c | 11 +++++++---- miniupnpd/netfilter_nft/nftnlrdr_misc.h | 3 +++ miniupnpd/netfilter_nft/nftpinhole.c | 4 ++-- miniupnpd/options.c | 1 + miniupnpd/options.h | 1 + 10 files changed, 33 insertions(+), 9 deletions(-) diff --git a/miniupnpd/commonrdr.h b/miniupnpd/commonrdr.h index d36e284..272091e 100644 --- a/miniupnpd/commonrdr.h +++ b/miniupnpd/commonrdr.h @@ -81,6 +81,7 @@ typedef enum { RDR_NAT_PREROUTING_CHAIN_NAME, RDR_NAT_POSTROUTING_CHAIN_NAME, RDR_FORWARD_CHAIN_NAME, + RDR_FAMILY_SPLIT, } rdr_name_type; /* diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index 1303186..3755c63 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -1353,6 +1353,9 @@ init(int argc, char * * argv, struct runtime_vars * v) case UPNPNATPOSTCHAIN: set_rdr_name(RDR_NAT_POSTROUTING_CHAIN_NAME, ary_options[i].value); break; + case UPNPNFFAMILYSPLIT: + set_rdr_name(RDR_FAMILY_SPLIT, ary_options[i].value); + break; #endif /* USE_NETFILTER */ case UPNPNOTIFY_INTERVAL: v->notify_interval = atoi(ary_options[i].value); diff --git a/miniupnpd/miniupnpd.conf b/miniupnpd/miniupnpd.conf index 90d18ce..9bf0c69 100644 --- a/miniupnpd/miniupnpd.conf +++ b/miniupnpd/miniupnpd.conf @@ -89,6 +89,7 @@ #upnp_forward_chain=forwardUPnP #upnp_nat_chain=UPnP #upnp_nat_postrouting_chain=UPnP-Postrouting +#upnp_nftables_family_split=no # Lease file location #lease_file=/var/log/upnp.leases diff --git a/miniupnpd/netfilter_nft/README.md b/miniupnpd/netfilter_nft/README.md index 20f8b47..5f8314e 100644 --- a/miniupnpd/netfilter_nft/README.md +++ b/miniupnpd/netfilter_nft/README.md @@ -72,3 +72,6 @@ and the following config settings can be used to change the tables and chains : upnp_forward_chain=miniupnpd upnp_nat_chain=prerouting_miniupnpd upnp_nat_postrouting_chain=postrouting_miniupnpd + +If you need to use the old ipv4 NAT family style set the flag upnp_nftables_family_split to yes. +Default is to use INET family which combines IPv4 and IPv6. diff --git a/miniupnpd/netfilter_nft/nftnlrdr.c b/miniupnpd/netfilter_nft/nftnlrdr.c index fd979a1..1922f2c 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr.c +++ b/miniupnpd/netfilter_nft/nftnlrdr.c @@ -113,6 +113,14 @@ set_rdr_name(rdr_name_type param, const char *string) case RDR_FORWARD_CHAIN_NAME: nft_forward_chain = string; break; + case RDR_FAMILY_SPLIT: + if(strcmp(string, "yes") == 0) { + nft_nat_family = NFPROTO_IPV4; + nft_ipv4_family = NFPROTO_IPV4; + nft_ipv6_family = NFPROTO_IPV6; + syslog(LOG_INFO, "using IPv4/IPv6 Table"); + } + break; default: syslog(LOG_ERR, "%s(): tried to set invalid string parameter: %d", "set_rdr_name", param); return -2; @@ -191,7 +199,7 @@ add_redirect_rule2(const char * ifname, d_printf(("add redirect rule2(%s, %s, %u, %s, %u, %d, %s)!\n", ifname, rhost, eport, iaddr, iport, proto, desc)); - r = rule_set_dnat(NFPROTO_INET, ifname, proto, + r = rule_set_dnat(nft_nat_family, ifname, proto, 0, eport, inet_addr(iaddr), iport, desc, NULL); @@ -220,7 +228,7 @@ add_peer_redirect_rule2(const char * ifname, d_printf(("add peer redirect rule2()!\n")); - r = rule_set_snat(NFPROTO_INET, proto, + r = rule_set_snat(nft_nat_family, proto, inet_addr(rhost), rport, inet_addr(eaddr), eport, inet_addr(iaddr), iport, desc, NULL); @@ -249,7 +257,7 @@ add_filter_rule2(const char * ifname, if (rhost != NULL && strcmp(rhost, "") != 0 && strcmp(rhost, "*") != 0) { rhost_addr = inet_addr(rhost); } - r = rule_set_filter(NFPROTO_INET, ifname, proto, + r = rule_set_filter(nft_nat_family, ifname, proto, rhost_addr, inet_addr(iaddr), eport, iport, 0, desc, 0); diff --git a/miniupnpd/netfilter_nft/nftnlrdr_misc.c b/miniupnpd/netfilter_nft/nftnlrdr_misc.c index 6574611..cac805c 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr_misc.c +++ b/miniupnpd/netfilter_nft/nftnlrdr_misc.c @@ -68,6 +68,9 @@ const char * nft_nat_table = "filter"; const char * nft_prerouting_chain = "prerouting_miniupnpd"; const char * nft_postrouting_chain = "postrouting_miniupnpd"; const char * nft_forward_chain = "miniupnpd"; +int nft_nat_family = NFPROTO_INET; +int nft_ipv4_family = NFPROTO_INET; +int nft_ipv6_family = NFPROTO_INET; static struct mnl_socket *mnl_sock = NULL; static uint32_t mnl_portid = 0; @@ -628,7 +631,7 @@ int refresh_nft_cache_filter(void) { if (rule_list_filter_validate != RULE_CACHE_VALID) { - if (refresh_nft_cache(&head_filter, nft_table, nft_forward_chain, NFPROTO_INET, RULE_FILTER) < 0) + if (refresh_nft_cache(&head_filter, nft_table, nft_forward_chain, nft_ipv4_family, RULE_FILTER) < 0) return -1; rule_list_filter_validate = RULE_CACHE_VALID; } @@ -639,7 +642,7 @@ int refresh_nft_cache_peer(void) { if (rule_list_peer_validate != RULE_CACHE_VALID) { - if (refresh_nft_cache(&head_peer, nft_nat_table, nft_postrouting_chain, NFPROTO_INET, RULE_NAT) < 0) + if (refresh_nft_cache(&head_peer, nft_nat_table, nft_postrouting_chain, nft_nat_family, RULE_NAT) < 0) return -1; rule_list_peer_validate = RULE_CACHE_VALID; } @@ -650,7 +653,7 @@ int refresh_nft_cache_redirect(void) { if (rule_list_redirect_validate != RULE_CACHE_VALID) { - if (refresh_nft_cache(&head_redirect, nft_nat_table, nft_prerouting_chain, NFPROTO_INET, RULE_NAT) < 0) + if (refresh_nft_cache(&head_redirect, nft_nat_table, nft_prerouting_chain, nft_nat_family, RULE_NAT) < 0) return -1; rule_list_redirect_validate = RULE_CACHE_VALID; } @@ -1166,7 +1169,7 @@ rule_del_handle(rule_t *rule) if (rule->type == RULE_NAT) { // NAT Family is not chain/rule family - nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, NFPROTO_INET); + nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, nft_nat_family); } else { nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, rule->family); } diff --git a/miniupnpd/netfilter_nft/nftnlrdr_misc.h b/miniupnpd/netfilter_nft/nftnlrdr_misc.h index 1d1c7bf..2e24b3c 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr_misc.h +++ b/miniupnpd/netfilter_nft/nftnlrdr_misc.h @@ -15,6 +15,9 @@ extern const char * nft_nat_table; extern const char * nft_prerouting_chain; extern const char * nft_postrouting_chain; extern const char * nft_forward_chain; +extern int nft_nat_family; +extern int nft_ipv4_family; +extern int nft_ipv6_family; #define NFT_DESCR_SIZE 1024 diff --git a/miniupnpd/netfilter_nft/nftpinhole.c b/miniupnpd/netfilter_nft/nftpinhole.c index 95cf5b5..5db2749 100644 --- a/miniupnpd/netfilter_nft/nftpinhole.c +++ b/miniupnpd/netfilter_nft/nftpinhole.c @@ -97,7 +97,7 @@ int add_pinhole(const char * ifname, snprintf(comment, NFT_DESCR_SIZE, PINEHOLE_LABEL_FORMAT, uid, timestamp, desc); - r = rule_set_filter6(NFPROTO_INET, ifname, proto, + r = rule_set_filter6(nft_ipv6_family, ifname, proto, rhost_addr_p, &ihost_addr, 0, int_port, rem_port, comment, 0); @@ -304,7 +304,7 @@ update_pinhole(unsigned short uid, unsigned int timestamp) d_printf(("update add_pinhole(%s, %s, %s, %d, %d, %d, %s)\n", ifname, raddr, inet_ntop(AF_INET6, &ihost_addr, iaddr, INET6_ADDRSTRLEN), rport, iport, proto, comment)); - r = rule_set_filter6(NFPROTO_INET, ifname, proto, + r = rule_set_filter6(nft_ipv6_family, ifname, proto, rhost_addr_p, &ihost_addr, 0, iport, rport, comment, 0); diff --git a/miniupnpd/options.c b/miniupnpd/options.c index 8fc9f06..c32e85a 100644 --- a/miniupnpd/options.c +++ b/miniupnpd/options.c @@ -73,6 +73,7 @@ static const struct { { UPNPFORWARDCHAIN, "upnp_forward_chain"}, { UPNPNATCHAIN, "upnp_nat_chain"}, { UPNPNATPOSTCHAIN, "upnp_nat_postrouting_chain"}, + { UPNPNFFAMILYSPLIT, "upnp_nftables_family_split"}, #endif #ifdef ENABLE_NATPMP /* both NAT-PMP and PCP (when PCP is enabled at compile time) */ diff --git a/miniupnpd/options.h b/miniupnpd/options.h index bd193cb..184f815 100644 --- a/miniupnpd/options.h +++ b/miniupnpd/options.h @@ -62,6 +62,7 @@ enum upnpconfigoptions { UPNPFORWARDCHAIN, UPNPNATCHAIN, UPNPNATPOSTCHAIN, + UPNPNFFAMILYSPLIT, #endif #ifdef USE_PF UPNPANCHOR, /* anchor */