Commit c653d5a7 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

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: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent b5964aac
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -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);
+4 −3
Original line number Diff line number Diff line
@@ -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))