forked from mirrors/linux
		
	sock: Make sk_protocol a 16-bit value
Match the 16-bit width of skbuff->protocol. Fills an 8-bit hole so sizeof(struct sock) does not change. Also take care of BPF field access for sk_type/sk_protocol. Both of them are now outside the bitfield, so we can use load instructions without further shifting/masking. v5 -> v6: - update eBPF accessors, too (Intel's kbuild test robot) v2 -> v3: - keep 'sk_type' 2 bytes aligned (Eric) v1 -> v2: - preserve sk_pacing_shift as bit field (Eric) Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: bpf@vger.kernel.org Co-developed-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									e9cdced78d
								
							
						
					
					
						commit
						bf9765145b
					
				
					 3 changed files with 28 additions and 59 deletions
				
			
		|  | @ -436,30 +436,15 @@ struct sock { | ||||||
| 	 * Because of non atomicity rules, all | 	 * Because of non atomicity rules, all | ||||||
| 	 * changes are protected by socket lock. | 	 * changes are protected by socket lock. | ||||||
| 	 */ | 	 */ | ||||||
| 	unsigned int		__sk_flags_offset[0]; | 	u8			sk_padding : 1, | ||||||
| #ifdef __BIG_ENDIAN_BITFIELD |  | ||||||
| #define SK_FL_PROTO_SHIFT  16 |  | ||||||
| #define SK_FL_PROTO_MASK   0x00ff0000 |  | ||||||
| 
 |  | ||||||
| #define SK_FL_TYPE_SHIFT   0 |  | ||||||
| #define SK_FL_TYPE_MASK    0x0000ffff |  | ||||||
| #else |  | ||||||
| #define SK_FL_PROTO_SHIFT  8 |  | ||||||
| #define SK_FL_PROTO_MASK   0x0000ff00 |  | ||||||
| 
 |  | ||||||
| #define SK_FL_TYPE_SHIFT   16 |  | ||||||
| #define SK_FL_TYPE_MASK    0xffff0000 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 	unsigned int		sk_padding : 1, |  | ||||||
| 				sk_kern_sock : 1, | 				sk_kern_sock : 1, | ||||||
| 				sk_no_check_tx : 1, | 				sk_no_check_tx : 1, | ||||||
| 				sk_no_check_rx : 1, | 				sk_no_check_rx : 1, | ||||||
| 				sk_userlocks : 4, | 				sk_userlocks : 4; | ||||||
| 				sk_protocol  : 8, |  | ||||||
| 				sk_type      : 16; |  | ||||||
| 	u16			sk_gso_max_segs; |  | ||||||
| 	u8			sk_pacing_shift; | 	u8			sk_pacing_shift; | ||||||
|  | 	u16			sk_type; | ||||||
|  | 	u16			sk_protocol; | ||||||
|  | 	u16			sk_gso_max_segs; | ||||||
| 	unsigned long	        sk_lingertime; | 	unsigned long	        sk_lingertime; | ||||||
| 	struct proto		*sk_prot_creator; | 	struct proto		*sk_prot_creator; | ||||||
| 	rwlock_t		sk_callback_lock; | 	rwlock_t		sk_callback_lock; | ||||||
|  |  | ||||||
|  | @ -147,7 +147,7 @@ TRACE_EVENT(inet_sock_set_state, | ||||||
| 		__field(__u16, sport) | 		__field(__u16, sport) | ||||||
| 		__field(__u16, dport) | 		__field(__u16, dport) | ||||||
| 		__field(__u16, family) | 		__field(__u16, family) | ||||||
| 		__field(__u8, protocol) | 		__field(__u16, protocol) | ||||||
| 		__array(__u8, saddr, 4) | 		__array(__u8, saddr, 4) | ||||||
| 		__array(__u8, daddr, 4) | 		__array(__u8, daddr, 4) | ||||||
| 		__array(__u8, saddr_v6, 16) | 		__array(__u8, saddr_v6, 16) | ||||||
|  |  | ||||||
|  | @ -7607,21 +7607,21 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock, type): | 	case offsetof(struct bpf_sock, type): | ||||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_TYPE_MASK) != BITS_PER_BYTE * 2); | 		*insn++ = BPF_LDX_MEM( | ||||||
| 		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, | 			BPF_FIELD_SIZEOF(struct sock, sk_type), | ||||||
| 				      offsetof(struct sock, __sk_flags_offset)); | 			si->dst_reg, si->src_reg, | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_TYPE_MASK); | 			bpf_target_off(struct sock, sk_type, | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, SK_FL_TYPE_SHIFT); | 				       sizeof_field(struct sock, sk_type), | ||||||
| 		*target_size = 2; | 				       target_size)); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock, protocol): | 	case offsetof(struct bpf_sock, protocol): | ||||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_PROTO_MASK) != BITS_PER_BYTE); | 		*insn++ = BPF_LDX_MEM( | ||||||
| 		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, | 			BPF_FIELD_SIZEOF(struct sock, sk_protocol), | ||||||
| 				      offsetof(struct sock, __sk_flags_offset)); | 			si->dst_reg, si->src_reg, | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_PROTO_MASK); | 			bpf_target_off(struct sock, sk_protocol, | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, SK_FL_PROTO_SHIFT); | 				       sizeof_field(struct sock, sk_protocol), | ||||||
| 		*target_size = 1; | 				       target_size)); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock, src_ip4): | 	case offsetof(struct bpf_sock, src_ip4): | ||||||
|  | @ -7903,20 +7903,13 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type, | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock_addr, type): | 	case offsetof(struct bpf_sock_addr, type): | ||||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF( | 		SOCK_ADDR_LOAD_NESTED_FIELD(struct bpf_sock_addr_kern, | ||||||
| 			struct bpf_sock_addr_kern, struct sock, sk, | 					    struct sock, sk, sk_type); | ||||||
| 			__sk_flags_offset, BPF_W, 0); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_TYPE_MASK); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, SK_FL_TYPE_SHIFT); |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock_addr, protocol): | 	case offsetof(struct bpf_sock_addr, protocol): | ||||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF( | 		SOCK_ADDR_LOAD_NESTED_FIELD(struct bpf_sock_addr_kern, | ||||||
| 			struct bpf_sock_addr_kern, struct sock, sk, | 					    struct sock, sk, sk_protocol); | ||||||
| 			__sk_flags_offset, BPF_W, 0); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_PROTO_MASK); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, |  | ||||||
| 					SK_FL_PROTO_SHIFT); |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct bpf_sock_addr, msg_src_ip4): | 	case offsetof(struct bpf_sock_addr, msg_src_ip4): | ||||||
|  | @ -8835,11 +8828,11 @@ sk_reuseport_is_valid_access(int off, int size, | ||||||
| 				    skb,				\ | 				    skb,				\ | ||||||
| 				    SKB_FIELD) | 				    SKB_FIELD) | ||||||
| 
 | 
 | ||||||
| #define SK_REUSEPORT_LOAD_SK_FIELD_SIZE_OFF(SK_FIELD, BPF_SIZE, EXTRA_OFF) \ | #define SK_REUSEPORT_LOAD_SK_FIELD(SK_FIELD)				\ | ||||||
| 	SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF(struct sk_reuseport_kern,	\ | 	SOCK_ADDR_LOAD_NESTED_FIELD(struct sk_reuseport_kern,		\ | ||||||
| 					     struct sock,		\ | 				    struct sock,			\ | ||||||
| 					     sk,			\ | 				    sk,					\ | ||||||
| 					     SK_FIELD, BPF_SIZE, EXTRA_OFF) | 				    SK_FIELD) | ||||||
| 
 | 
 | ||||||
| static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type, | static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type, | ||||||
| 					   const struct bpf_insn *si, | 					   const struct bpf_insn *si, | ||||||
|  | @ -8863,16 +8856,7 @@ static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type, | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct sk_reuseport_md, ip_protocol): | 	case offsetof(struct sk_reuseport_md, ip_protocol): | ||||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_PROTO_MASK) != BITS_PER_BYTE); | 		SK_REUSEPORT_LOAD_SK_FIELD(sk_protocol); | ||||||
| 		SK_REUSEPORT_LOAD_SK_FIELD_SIZE_OFF(__sk_flags_offset, |  | ||||||
| 						    BPF_W, 0); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_PROTO_MASK); |  | ||||||
| 		*insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, |  | ||||||
| 					SK_FL_PROTO_SHIFT); |  | ||||||
| 		/* SK_FL_PROTO_MASK and SK_FL_PROTO_SHIFT are endian
 |  | ||||||
| 		 * aware.  No further narrowing or masking is needed. |  | ||||||
| 		 */ |  | ||||||
| 		*target_size = 1; |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case offsetof(struct sk_reuseport_md, data_end): | 	case offsetof(struct sk_reuseport_md, data_end): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Mat Martineau
						Mat Martineau