netfilter: flowtable: inline vlan encapsulation in xmit path
Push the vlan header from the flowtable xmit path, instead of passing the packet to the vlan device. This is based on a patch originally written by wenxu. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
b5964aac51
commit
c653d5a78f
|
|
@ -413,6 +413,25 @@ static int nf_flow_offload_forward(struct nf_flowtable_ctx *ctx,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int nf_flow_encap_push(struct sk_buff *skb,
|
||||
struct flow_offload_tuple *tuple)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tuple->encap_num; i++) {
|
||||
switch (tuple->encap[i].proto) {
|
||||
case htons(ETH_P_8021Q):
|
||||
case htons(ETH_P_8021AD):
|
||||
if (skb_vlan_push(skb, tuple->encap[i].proto,
|
||||
tuple->encap[i].id) < 0)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
|
|
@ -450,6 +469,9 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
|||
dir = tuplehash->tuple.dir;
|
||||
flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
|
||||
|
||||
if (nf_flow_encap_push(skb, &flow->tuplehash[!dir].tuple) < 0)
|
||||
return NF_DROP;
|
||||
|
||||
switch (tuplehash->tuple.xmit_type) {
|
||||
case FLOW_OFFLOAD_XMIT_NEIGH:
|
||||
rt = dst_rtable(tuplehash->tuple.dst_cache);
|
||||
|
|
@ -754,6 +776,9 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
|
|||
dir = tuplehash->tuple.dir;
|
||||
flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
|
||||
|
||||
if (nf_flow_encap_push(skb, &flow->tuplehash[!dir].tuple) < 0)
|
||||
return NF_DROP;
|
||||
|
||||
switch (tuplehash->tuple.xmit_type) {
|
||||
case FLOW_OFFLOAD_XMIT_NEIGH:
|
||||
rt = dst_rt6_info(tuplehash->tuple.dst_cache);
|
||||
|
|
|
|||
|
|
@ -119,13 +119,14 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
|
|||
info->indev = NULL;
|
||||
break;
|
||||
}
|
||||
if (!info->outdev)
|
||||
info->outdev = path->dev;
|
||||
info->encap[info->num_encaps].id = path->encap.id;
|
||||
info->encap[info->num_encaps].proto = path->encap.proto;
|
||||
info->num_encaps++;
|
||||
if (path->type == DEV_PATH_PPPOE)
|
||||
if (path->type == DEV_PATH_PPPOE) {
|
||||
if (!info->outdev)
|
||||
info->outdev = path->dev;
|
||||
memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
|
||||
}
|
||||
break;
|
||||
case DEV_PATH_BRIDGE:
|
||||
if (is_zero_ether_addr(info->h_source))
|
||||
|
|
|
|||
Loading…
Reference in New Issue