summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compat.h36
-rw-r--r--quicktun.c16
2 files changed, 40 insertions, 12 deletions
diff --git a/compat.h b/compat.h
new file mode 100644
index 0000000..39cb8ac
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,36 @@
+#ifndef __QUICKTUN_COMPAT_H
+#define __QUICKTUN_COMPAT_H
+
+#include <linux/version.h>
+#include <net/inet_sock.h>
+#include <net/route.h>
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
+static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk,
+ __be32 daddr, __be32 saddr,
+ __be16 dport, __be16 sport,
+ __u8 proto, __u8 tos, int oif)
+{
+ struct rtable *rt;
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .saddr = saddr,
+ .daddr = daddr,
+ .tos = tos,
+ }
+ },
+ .oif = oif,
+ .proto = proto
+ };
+
+ if (ip_route_output_key(net, &rt, &fl))
+ return NULL;
+
+ return rt;
+
+}
+#endif
+
+#endif /* __QUICKTUN_COMPAT_H */
diff --git a/quicktun.c b/quicktun.c
index f57e480..5d9724e 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -14,6 +14,7 @@
#include <net/sock.h>
#include "quicktun.h"
+#include "compat.h"
#define DRV_NAME "quicktun"
@@ -66,18 +67,9 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
remote_addr = rcu_dereference(tun->remote_address);
if (likely(remote_addr->addr.sin_addr.s_addr)) {
- struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .saddr = tun->local_address.sin_addr.s_addr,
- .daddr = remote_addr->addr.sin_addr.s_addr,
- .tos = 0,
- }
- },
- .proto = IPPROTO_UDP
- };
-
- if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
+ rt = ip_route_output_ports(dev_net(dev), NULL, remote_addr->addr.sin_addr.s_addr, tun->local_address.sin_addr.s_addr,
+ remote_addr->addr.sin_port, tun->local_address.sin_port, IPPROTO_UDP, 0, 0);
+ if (!rt) {
tun->dev->stats.tx_carrier_errors++;
goto error;
}