aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chion Tang <sdspeedonion@gmail.com> 2018-04-28 13:37:45 +0100
committerGravatar Chion Tang <sdspeedonion@gmail.com> 2018-04-28 13:37:45 +0100
commite1825c42584c56140478acbd59ad130b9c610fdc (patch)
tree5c3a019b9b53e8539c3ffae0548416727e525d0c
parentfix: conntrack rcu reference leak (diff)
downloadnetfilter-full-cone-nat-e1825c42584c56140478acbd59ad130b9c610fdc.tar.gz
netfilter-full-cone-nat-e1825c42584c56140478acbd59ad130b9c610fdc.tar.bz2
netfilter-full-cone-nat-e1825c42584c56140478acbd59ad130b9c610fdc.zip
feature: find ifindex by dst ip
-rw-r--r--xt_FULLCONENAT.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/xt_FULLCONENAT.c b/xt_FULLCONENAT.c
index cf6f8aa..4787992 100644
--- a/xt_FULLCONENAT.c
+++ b/xt_FULLCONENAT.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/hashtable.h>
+#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
@@ -326,15 +327,21 @@ out:
static __be32 get_device_ip(const struct net_device* dev) {
struct in_device* in_dev;
struct in_ifaddr* if_info;
+ __be32 result;
+ rcu_read_lock();
in_dev = dev->ip_ptr;
if (in_dev == NULL) {
+ rcu_read_unlock();
return 0;
}
if_info = in_dev->ifa_list;
if (if_info) {
- return if_info->ifa_local;
+ result = if_info->ifa_local;
+ rcu_read_unlock();
+ return result;
} else {
+ rcu_read_unlock();
return 0;
}
}
@@ -401,6 +408,8 @@ static unsigned int fullconenat_tg(struct sk_buff *skb, const struct xt_action_p
enum ip_conntrack_info ctinfo;
struct nf_conntrack_tuple *ct_tuple, *ct_tuple_origin;
+ struct net_device *net_dev;
+
struct nat_mapping *mapping, *src_mapping;
unsigned int ret;
struct nf_nat_range newrange;
@@ -440,9 +449,15 @@ static unsigned int fullconenat_tg(struct sk_buff *skb, const struct xt_action_p
if (protonum != IPPROTO_UDP) {
return ret;
}
- ip = (ct_tuple_origin->src).u3.ip;
+ ip = (ct_tuple_origin->dst).u3.ip;
port = be16_to_cpu((ct_tuple_origin->dst).u.udp.port);
+ net_dev = ip_dev_find(net, ip);
+ if (net_dev != NULL) {
+ ifindex = net_dev->ifindex;
+ dev_put(net_dev);
+ }
+
spin_lock(&fullconenat_lock);
/* find an active mapping based on the inbound port */