Commit 73327d47 authored by wenxu's avatar wenxu Committed by Pablo Neira Ayuso

netfilter: nf_flow_table_offload: fix the nat port mangle.

Shift on 32-bit word to define the port number depends on the flow
direction.

Fixes: c29f74e0 ("netfilter: nf_flow_table: hardware offload support")
Fixes: 7acd9378 ("netfilter: nf_flow_table_offload: Correct memcpy size for flow_overload_mangle()")
Signed-off-by: default avatarwenxu <wenxu@ucloud.cn>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent f31ad71c
...@@ -349,22 +349,26 @@ static void flow_offload_port_snat(struct net *net, ...@@ -349,22 +349,26 @@ static void flow_offload_port_snat(struct net *net,
struct nf_flow_rule *flow_rule) struct nf_flow_rule *flow_rule)
{ {
struct flow_action_entry *entry = flow_action_entry_next(flow_rule); struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask = ~htonl(0xffff0000), port; u32 mask, port;
u32 offset; u32 offset;
switch (dir) { switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL: case FLOW_OFFLOAD_DIR_ORIGINAL:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port);
offset = 0; /* offsetof(struct tcphdr, source); */ offset = 0; /* offsetof(struct tcphdr, source); */
port = htonl(port << 16);
mask = ~htonl(0xffff0000);
break; break;
case FLOW_OFFLOAD_DIR_REPLY: case FLOW_OFFLOAD_DIR_REPLY:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port);
offset = 0; /* offsetof(struct tcphdr, dest); */ offset = 0; /* offsetof(struct tcphdr, dest); */
port = htonl(port);
mask = ~htonl(0xffff);
break; break;
default: default:
return; return;
} }
port = htonl(port << 16);
flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, flow_offload_mangle(entry, flow_offload_l4proto(flow), offset,
&port, &mask); &port, &mask);
} }
...@@ -375,22 +379,26 @@ static void flow_offload_port_dnat(struct net *net, ...@@ -375,22 +379,26 @@ static void flow_offload_port_dnat(struct net *net,
struct nf_flow_rule *flow_rule) struct nf_flow_rule *flow_rule)
{ {
struct flow_action_entry *entry = flow_action_entry_next(flow_rule); struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask = ~htonl(0xffff), port; u32 mask, port;
u32 offset; u32 offset;
switch (dir) { switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL: case FLOW_OFFLOAD_DIR_ORIGINAL:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port);
offset = 0; /* offsetof(struct tcphdr, source); */ offset = 0; /* offsetof(struct tcphdr, dest); */
port = htonl(port);
mask = ~htonl(0xffff);
break; break;
case FLOW_OFFLOAD_DIR_REPLY: case FLOW_OFFLOAD_DIR_REPLY:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port);
offset = 0; /* offsetof(struct tcphdr, dest); */ offset = 0; /* offsetof(struct tcphdr, source); */
port = htonl(port << 16);
mask = ~htonl(0xffff0000);
break; break;
default: default:
return; return;
} }
port = htonl(port);
flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, flow_offload_mangle(entry, flow_offload_l4proto(flow), offset,
&port, &mask); &port, &mask);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment