kernel: netfilter: fix dst entries in flowtable offload
[openwrt/openwrt.git] / target / linux / generic / hack-4.14 / 650-netfilter-add-xt_OFFLOAD-target.patch
index 85826b87065ce3fb4eab52dde786fbd8c3f2d940..7296cfa6c460649ffa79bf26c9ece7ddd583219b 100644 (file)
@@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
 --- /dev/null
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,340 @@
+@@ -0,0 +1,351 @@
 +/*
 + * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
 + *
@@ -290,27 +290,38 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +      return false;
 +}
 +
-+static int
-+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
-+                 const struct xt_action_param *par,
-+                 struct nf_flow_route *route, enum ip_conntrack_dir dir)
++static struct dst_entry *
++xt_flowoffload_dst(const struct nf_conn *ct, enum ip_conntrack_dir dir,
++                 const struct xt_action_param *par)
 +{
-+      struct dst_entry *this_dst = skb_dst(skb);
-+      struct dst_entry *other_dst = NULL;
++      struct dst_entry *dst;
 +      struct flowi fl;
 +
 +      memset(&fl, 0, sizeof(fl));
 +      switch (xt_family(par)) {
 +      case NFPROTO_IPV4:
-+              fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.dst.u3.ip;
++              fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
 +              break;
 +      case NFPROTO_IPV6:
-+              fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
++              fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
 +              break;
 +      }
 +
-+      nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
-+      if (!other_dst)
++      nf_route(xt_net(par), &dst, &fl, false, xt_family(par));
++
++      return dst;
++}
++
++static int
++xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
++                 const struct xt_action_param *par,
++                 struct nf_flow_route *route, enum ip_conntrack_dir dir)
++{
++      struct dst_entry *this_dst, *other_dst;
++
++      this_dst = xt_flowoffload_dst(ct, dir, par);
++      other_dst = xt_flowoffload_dst(ct, !dir, par);
++      if (!this_dst || !other_dst)
 +              return -ENOENT;
 +
 +      route->tuple[dir].dst           = this_dst;