forked from mirrors/linux
		
	netlink: introduce NLA_POLICY_MAX_BE
netlink allows to specify allowed ranges for integer types. Unfortunately, nfnetlink passes integers in big endian, so the existing NLA_POLICY_MAX() cannot be used. At the moment, nfnetlink users, such as nf_tables, need to resort to programmatic checking via helpers such as nft_parse_u32_check(). This is both cumbersome and error prone. This adds NLA_POLICY_MAX_BE which adds range check support for BE16, BE32 and BE64 integers. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									98ba81081b
								
							
						
					
					
						commit
						08724ef699
					
				
					 2 changed files with 36 additions and 4 deletions
				
			
		|  | @ -325,6 +325,7 @@ struct nla_policy { | |||
| 		struct netlink_range_validation_signed *range_signed; | ||||
| 		struct { | ||||
| 			s16 min, max; | ||||
| 			u8 network_byte_order:1; | ||||
| 		}; | ||||
| 		int (*validate)(const struct nlattr *attr, | ||||
| 				struct netlink_ext_ack *extack); | ||||
|  | @ -418,6 +419,14 @@ struct nla_policy { | |||
| 	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\ | ||||
| 	.validation_type = NLA_VALIDATE_MAX,		\ | ||||
| 	.max = _max,					\ | ||||
| 	.network_byte_order = 0,			\ | ||||
| } | ||||
| 
 | ||||
| #define NLA_POLICY_MAX_BE(tp, _max) {			\ | ||||
| 	.type = NLA_ENSURE_UINT_TYPE(tp),		\ | ||||
| 	.validation_type = NLA_VALIDATE_MAX,		\ | ||||
| 	.max = _max,					\ | ||||
| 	.network_byte_order = 1,			\ | ||||
| } | ||||
| 
 | ||||
| #define NLA_POLICY_MASK(tp, _mask) {			\ | ||||
|  |  | |||
							
								
								
									
										31
									
								
								lib/nlattr.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								lib/nlattr.c
									
									
									
									
									
								
							|  | @ -159,6 +159,31 @@ void nla_get_range_unsigned(const struct nla_policy *pt, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static u64 nla_get_attr_bo(const struct nla_policy *pt, | ||||
| 			   const struct nlattr *nla) | ||||
| { | ||||
| 	switch (pt->type) { | ||||
| 	case NLA_U16: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return ntohs(nla_get_be16(nla)); | ||||
| 
 | ||||
| 		return nla_get_u16(nla); | ||||
| 	case NLA_U32: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return ntohl(nla_get_be32(nla)); | ||||
| 
 | ||||
| 		return nla_get_u32(nla); | ||||
| 	case NLA_U64: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return be64_to_cpu(nla_get_be64(nla)); | ||||
| 
 | ||||
| 		return nla_get_u64(nla); | ||||
| 	} | ||||
| 
 | ||||
| 	WARN_ON_ONCE(1); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int nla_validate_range_unsigned(const struct nla_policy *pt, | ||||
| 				       const struct nlattr *nla, | ||||
| 				       struct netlink_ext_ack *extack, | ||||
|  | @ -172,12 +197,10 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt, | |||
| 		value = nla_get_u8(nla); | ||||
| 		break; | ||||
| 	case NLA_U16: | ||||
| 		value = nla_get_u16(nla); | ||||
| 		break; | ||||
| 	case NLA_U32: | ||||
| 		value = nla_get_u32(nla); | ||||
| 		break; | ||||
| 	case NLA_U64: | ||||
| 		value = nla_get_attr_bo(pt, nla); | ||||
| 		break; | ||||
| 	case NLA_MSECS: | ||||
| 		value = nla_get_u64(nla); | ||||
| 		break; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Florian Westphal
						Florian Westphal