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