Hi Pabo, I think it's the problem of their iptables offload patch. https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/generic/hack-4.19/650-netfilter-add-xt_OFFLOAD-target.patch @304, It gets the this_dst and other_dst according to src ip of tuple. It is not correct. That's why they swap iifdx and oifdx can work around It should like nftables do. this_dst=skb_dst and other_dst get route through src ip of tuple in origin dir. 294 +static struct dst_entry * 295 +xt_flowoffload_dst(const struct nf_conn *ct, enum ip_conntrack_dir dir, 296 + const struct xt_action_param *par) 297 +{ 298 + struct dst_entry *dst = NULL; 299 + struct flowi fl; 300 + 301 + memset(&fl, 0, sizeof(fl)); 302 + switch (xt_family(par)) { 303 + case NFPROTO_IPV4: 304 + fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip; 305 + break; 306 + case NFPROTO_IPV6: 307 + fl.u.ip6.saddr = ct->tuplehash[dir].tuple.dst.u3.in6; 308 + fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6; 309 + break; 310 + } 311 + 312 + nf_route(xt_net(par), &dst, &fl, false, xt_family(par)); 313 + 314 + return dst; 315 +} 316 + 317 +static int 318 +xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, 319 + const struct xt_action_param *par, 320 + struct nf_flow_route *route, enum ip_conntrack_dir dir) 321 +{ 322 + struct dst_entry *this_dst, *other_dst; 323 + 324 + this_dst = xt_flowoffload_dst(ct, dir, par); 325 + other_dst = xt_flowoffload_dst(ct, !dir, par); 326 + if (!this_dst || !other_dst) 327 + return -ENOENT; 328 + 329 + if (dst_xfrm(this_dst) || dst_xfrm(other_dst)) 330 + return -EINVAL; 331 + 332 + route->tuple[dir].dst = this_dst; 333 + route->tuple[!dir].dst = other_dst; On 7/25/2019 6:10 PM, Pablo Neira Ayuso wrote: > Hi, > > There are reports > > https://github.com/openwrt/openwrt/pull/2266#issuecomment-514681715 > > This report might not be your fault, but you can probably help fixing > bugs before we move on anywhere else. >