diff --git a/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch b/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch new file mode 100644 index 000000000..a81445bb9 --- /dev/null +++ b/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch @@ -0,0 +1,87 @@ +From: Konstantin Vasin +Date: Mon, 9 Mar 2020 18:38:54 +0300 +Subject: [PATCH] netfilter: nf_flow_table_hw: fix incorrect ethernet dst + address + +Ethernet destination for original traffic takes the source ethernet +address in the reply direction. For reply traffic, this takes +the source ethernet address of the original destination. + +This fix is based on the upstream commit 1b67e506: +("netfilter: nf_flow_table_offload: fix incorrect ethernet dst address") +from wenxu + +Signed-off-by: Konstantin Vasin +--- + +--- a/net/netfilter/nf_flow_table_hw.c ++++ b/net/netfilter/nf_flow_table_hw.c +@@ -24,17 +24,23 @@ struct flow_offload_hw { + struct flow_offload_hw_path dest; + }; + +-static void flow_offload_check_ethernet(struct flow_offload_tuple *tuple, ++static void flow_offload_check_ethernet(struct flow_offload *flow, ++ enum flow_offload_tuple_dir dir, + struct flow_offload_hw_path *path) + { + struct net_device *dev = path->dev; + struct neighbour *n; ++ const void *daddr; ++ const struct dst_entry *dst_cache; + + if (dev->type != ARPHRD_ETHER) + return; + + memcpy(path->eth_src, path->dev->dev_addr, ETH_ALEN); +- n = dst_neigh_lookup(tuple->dst_cache, &tuple->src_v4); ++ ++ daddr = &flow->tuplehash[dir].tuple.src_v4; ++ dst_cache = flow->tuplehash[!dir].tuple.dst_cache; ++ n = dst_neigh_lookup(dst_cache, daddr); + if (!n) + return; + +@@ -44,17 +50,18 @@ static void flow_offload_check_ethernet(struct flow_offload_tuple *tuple, + } + + static int flow_offload_check_path(struct net *net, +- struct flow_offload_tuple *tuple, ++ struct flow_offload *flow, ++ enum flow_offload_tuple_dir dir, + struct flow_offload_hw_path *path) + { + struct net_device *dev; + +- dev = dev_get_by_index_rcu(net, tuple->iifidx); ++ dev = dev_get_by_index_rcu(net, flow->tuplehash[dir].tuple.iifidx); + if (!dev) + return -ENOENT; + + path->dev = dev; +- flow_offload_check_ethernet(tuple, path); ++ flow_offload_check_ethernet(flow, dir, path); + + if (dev->netdev_ops->ndo_flow_offload_check) + return dev->netdev_ops->ndo_flow_offload_check(path); +@@ -133,17 +140,14 @@ flow_offload_hw_prepare(struct net *net, struct flow_offload *flow) + { + struct flow_offload_hw_path src = {}; + struct flow_offload_hw_path dest = {}; +- struct flow_offload_tuple *tuple; + struct flow_offload_hw *offload = NULL; + + rcu_read_lock_bh(); + +- tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple; +- if (flow_offload_check_path(net, tuple, &src)) ++ if (flow_offload_check_path(net, flow, FLOW_OFFLOAD_DIR_ORIGINAL, &src)) + goto out; + +- tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple; +- if (flow_offload_check_path(net, tuple, &dest)) ++ if (flow_offload_check_path(net, flow, FLOW_OFFLOAD_DIR_REPLY, &dest)) + goto out; + + if (!src.dev->netdev_ops->ndo_flow_offload) + diff --git a/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch b/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch new file mode 100644 index 000000000..ed4a1e3a3 --- /dev/null +++ b/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch @@ -0,0 +1,32 @@ +From: Konstantin Vasin +Date: Mon, 9 Mar 2020 17:41:22 +0300 +Subject: [PATCH] netfilter: nf_flow_table_hw: check the status of + dst_neigh + +It's better to check the nud_state is VALID. +If there is not neigh previos, the lookup will +create a non NUD_VALID with 00:00:00:00:00:00 mac. + +This fix is based on the upstream commit f31ad71c44 +("netfilter: nf_flow_table_offload: check the status of dst_neigh") +from wenxu + +Signed-off-by: Konstantin Vasin +--- + +index e831c8830e91..1238d675a316 100644 +--- a/net/netfilter/nf_flow_table_hw.c ++++ b/net/netfilter/nf_flow_table_hw.c +@@ -44,8 +44,10 @@ static void flow_offload_check_ethernet(struct flow_offload *flow, + if (!n) + return; + +- memcpy(path->eth_dest, n->ha, ETH_ALEN); +- path->flags |= FLOW_OFFLOAD_PATH_ETHERNET; ++ if (n->nud_state & NUD_VALID) { ++ memcpy(path->eth_dest, n->ha, ETH_ALEN); ++ path->flags |= FLOW_OFFLOAD_PATH_ETHERNET; ++ } + neigh_release(n); + } +