Merge branch 'nf_tables_offload-vlan-matching-support'
Pablo Neira Ayuso says: ==================== nf_tables_offload: vlan matching support The following patchset contains Netfilter support for vlan matching offloads: 1) Constify nft_reg_load() as a preparation patch. 2) Restrict rule matching to ingress interface type ARPHRD_ETHER. 3) Add new vlan_tci field to flow_dissector_key_vlan structure, to allow to set up vlan_id, vlan_dei and vlan_priority in one go. 4) C-VLAN matching support. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b9242da6f6
@ -48,9 +48,12 @@ struct flow_dissector_key_tags {
|
||||
};
|
||||
|
||||
struct flow_dissector_key_vlan {
|
||||
u16 vlan_id:12,
|
||||
vlan_dei:1,
|
||||
vlan_priority:3;
|
||||
union {
|
||||
u16 vlan_id:12,
|
||||
vlan_dei:1,
|
||||
vlan_priority:3;
|
||||
__be16 vlan_tci;
|
||||
};
|
||||
__be16 vlan_tpid;
|
||||
};
|
||||
|
||||
@ -203,9 +206,11 @@ struct flow_dissector_key_ip {
|
||||
/**
|
||||
* struct flow_dissector_key_meta:
|
||||
* @ingress_ifindex: ingress ifindex
|
||||
* @ingress_iftype: ingress interface type
|
||||
*/
|
||||
struct flow_dissector_key_meta {
|
||||
int ingress_ifindex;
|
||||
u16 ingress_iftype;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -114,7 +114,7 @@ static inline void nft_reg_store8(u32 *dreg, u8 val)
|
||||
*(u8 *)dreg = val;
|
||||
}
|
||||
|
||||
static inline u8 nft_reg_load8(u32 *sreg)
|
||||
static inline u8 nft_reg_load8(const u32 *sreg)
|
||||
{
|
||||
return *(u8 *)sreg;
|
||||
}
|
||||
@ -125,7 +125,7 @@ static inline void nft_reg_store16(u32 *dreg, u16 val)
|
||||
*(u16 *)dreg = val;
|
||||
}
|
||||
|
||||
static inline u16 nft_reg_load16(u32 *sreg)
|
||||
static inline u16 nft_reg_load16(const u32 *sreg)
|
||||
{
|
||||
return *(u16 *)sreg;
|
||||
}
|
||||
@ -135,7 +135,7 @@ static inline void nft_reg_store64(u32 *dreg, u64 val)
|
||||
put_unaligned(val, (u64 *)dreg);
|
||||
}
|
||||
|
||||
static inline u64 nft_reg_load64(u32 *sreg)
|
||||
static inline u64 nft_reg_load64(const u32 *sreg)
|
||||
{
|
||||
return get_unaligned((u64 *)sreg);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
#include <net/netfilter/nf_tables_offload.h>
|
||||
@ -125,6 +126,11 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
|
||||
flow->match.dissector.used_keys |= BIT(reg->key);
|
||||
flow->match.dissector.offset[reg->key] = reg->base_offset;
|
||||
|
||||
if (reg->key == FLOW_DISSECTOR_KEY_META &&
|
||||
reg->offset == offsetof(struct nft_flow_key, meta.ingress_iftype) &&
|
||||
nft_reg_load16(priv->data.data) != ARPHRD_ETHER)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
nft_offload_update_dependency(ctx, &priv->data, priv->len);
|
||||
|
||||
return 0;
|
||||
|
@ -551,6 +551,10 @@ static int nft_meta_get_offload(struct nft_offload_ctx *ctx,
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta,
|
||||
ingress_ifindex, sizeof(__u32), reg);
|
||||
break;
|
||||
case NFT_META_IIFTYPE:
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta,
|
||||
ingress_iftype, sizeof(__u16), reg);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -182,6 +182,44 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
|
||||
dst, ETH_ALEN, reg);
|
||||
break;
|
||||
case offsetof(struct ethhdr, h_proto):
|
||||
if (priv->len != sizeof(__be16))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic,
|
||||
n_proto, sizeof(__be16), reg);
|
||||
nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
|
||||
break;
|
||||
case offsetof(struct vlan_ethhdr, h_vlan_TCI):
|
||||
if (priv->len != sizeof(__be16))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
|
||||
vlan_tci, sizeof(__be16), reg);
|
||||
break;
|
||||
case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto):
|
||||
if (priv->len != sizeof(__be16))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
|
||||
vlan_tpid, sizeof(__be16), reg);
|
||||
nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
|
||||
break;
|
||||
case offsetof(struct vlan_ethhdr, h_vlan_TCI) + sizeof(struct vlan_hdr):
|
||||
if (priv->len != sizeof(__be16))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan,
|
||||
vlan_tci, sizeof(__be16), reg);
|
||||
break;
|
||||
case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) +
|
||||
sizeof(struct vlan_hdr):
|
||||
if (priv->len != sizeof(__be16))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan,
|
||||
vlan_tpid, sizeof(__be16), reg);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user