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 */