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 {
|
struct flow_dissector_key_vlan {
|
||||||
u16 vlan_id:12,
|
union {
|
||||||
vlan_dei:1,
|
u16 vlan_id:12,
|
||||||
vlan_priority:3;
|
vlan_dei:1,
|
||||||
|
vlan_priority:3;
|
||||||
|
__be16 vlan_tci;
|
||||||
|
};
|
||||||
__be16 vlan_tpid;
|
__be16 vlan_tpid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -203,9 +206,11 @@ struct flow_dissector_key_ip {
|
|||||||
/**
|
/**
|
||||||
* struct flow_dissector_key_meta:
|
* struct flow_dissector_key_meta:
|
||||||
* @ingress_ifindex: ingress ifindex
|
* @ingress_ifindex: ingress ifindex
|
||||||
|
* @ingress_iftype: ingress interface type
|
||||||
*/
|
*/
|
||||||
struct flow_dissector_key_meta {
|
struct flow_dissector_key_meta {
|
||||||
int ingress_ifindex;
|
int ingress_ifindex;
|
||||||
|
u16 ingress_iftype;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +114,7 @@ static inline void nft_reg_store8(u32 *dreg, u8 val)
|
|||||||
*(u8 *)dreg = val;
|
*(u8 *)dreg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 nft_reg_load8(u32 *sreg)
|
static inline u8 nft_reg_load8(const u32 *sreg)
|
||||||
{
|
{
|
||||||
return *(u8 *)sreg;
|
return *(u8 *)sreg;
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ static inline void nft_reg_store16(u32 *dreg, u16 val)
|
|||||||
*(u16 *)dreg = val;
|
*(u16 *)dreg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u16 nft_reg_load16(u32 *sreg)
|
static inline u16 nft_reg_load16(const u32 *sreg)
|
||||||
{
|
{
|
||||||
return *(u16 *)sreg;
|
return *(u16 *)sreg;
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ static inline void nft_reg_store64(u32 *dreg, u64 val)
|
|||||||
put_unaligned(val, (u64 *)dreg);
|
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);
|
return get_unaligned((u64 *)sreg);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
#include <linux/netfilter/nf_tables.h>
|
#include <linux/netfilter/nf_tables.h>
|
||||||
#include <net/netfilter/nf_tables_core.h>
|
#include <net/netfilter/nf_tables_core.h>
|
||||||
#include <net/netfilter/nf_tables_offload.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.used_keys |= BIT(reg->key);
|
||||||
flow->match.dissector.offset[reg->key] = reg->base_offset;
|
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);
|
nft_offload_update_dependency(ctx, &priv->data, priv->len);
|
||||||
|
|
||||||
return 0;
|
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,
|
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta,
|
||||||
ingress_ifindex, sizeof(__u32), reg);
|
ingress_ifindex, sizeof(__u32), reg);
|
||||||
break;
|
break;
|
||||||
|
case NFT_META_IIFTYPE:
|
||||||
|
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta,
|
||||||
|
ingress_iftype, sizeof(__u16), reg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
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,
|
NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
|
||||||
dst, ETH_ALEN, reg);
|
dst, ETH_ALEN, reg);
|
||||||
break;
|
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:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user