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 | ||||
| 	 * changes are protected by socket lock. | ||||
| 	 */ | ||||
| 	unsigned int		__sk_flags_offset[0]; | ||||
| #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, | ||||
| 	u8			sk_padding : 1, | ||||
| 				sk_kern_sock : 1, | ||||
| 				sk_no_check_tx : 1, | ||||
| 				sk_no_check_rx : 1, | ||||
| 				sk_userlocks : 4, | ||||
| 				sk_protocol  : 8, | ||||
| 				sk_type      : 16; | ||||
| 	u16			sk_gso_max_segs; | ||||
| 				sk_userlocks : 4; | ||||
| 	u8			sk_pacing_shift; | ||||
| 	u16			sk_type; | ||||
| 	u16			sk_protocol; | ||||
| 	u16			sk_gso_max_segs; | ||||
| 	unsigned long	        sk_lingertime; | ||||
| 	struct proto		*sk_prot_creator; | ||||
| 	rwlock_t		sk_callback_lock; | ||||
|  |  | |||
|  | @ -147,7 +147,7 @@ TRACE_EVENT(inet_sock_set_state, | |||
| 		__field(__u16, sport) | ||||
| 		__field(__u16, dport) | ||||
| 		__field(__u16, family) | ||||
| 		__field(__u8, protocol) | ||||
| 		__field(__u16, protocol) | ||||
| 		__array(__u8, saddr, 4) | ||||
| 		__array(__u8, daddr, 4) | ||||
| 		__array(__u8, saddr_v6, 16) | ||||
|  |  | |||
|  | @ -7607,21 +7607,21 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, | |||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock, type): | ||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_TYPE_MASK) != BITS_PER_BYTE * 2); | ||||
| 		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, | ||||
| 				      offsetof(struct sock, __sk_flags_offset)); | ||||
| 		*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); | ||||
| 		*target_size = 2; | ||||
| 		*insn++ = BPF_LDX_MEM( | ||||
| 			BPF_FIELD_SIZEOF(struct sock, sk_type), | ||||
| 			si->dst_reg, si->src_reg, | ||||
| 			bpf_target_off(struct sock, sk_type, | ||||
| 				       sizeof_field(struct sock, sk_type), | ||||
| 				       target_size)); | ||||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock, protocol): | ||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_PROTO_MASK) != BITS_PER_BYTE); | ||||
| 		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, | ||||
| 				      offsetof(struct sock, __sk_flags_offset)); | ||||
| 		*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); | ||||
| 		*target_size = 1; | ||||
| 		*insn++ = BPF_LDX_MEM( | ||||
| 			BPF_FIELD_SIZEOF(struct sock, sk_protocol), | ||||
| 			si->dst_reg, si->src_reg, | ||||
| 			bpf_target_off(struct sock, sk_protocol, | ||||
| 				       sizeof_field(struct sock, sk_protocol), | ||||
| 				       target_size)); | ||||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock, src_ip4): | ||||
|  | @ -7903,20 +7903,13 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type, | |||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock_addr, type): | ||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF( | ||||
| 			struct bpf_sock_addr_kern, struct sock, sk, | ||||
| 			__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); | ||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD(struct bpf_sock_addr_kern, | ||||
| 					    struct sock, sk, sk_type); | ||||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock_addr, protocol): | ||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF( | ||||
| 			struct bpf_sock_addr_kern, struct sock, sk, | ||||
| 			__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); | ||||
| 		SOCK_ADDR_LOAD_NESTED_FIELD(struct bpf_sock_addr_kern, | ||||
| 					    struct sock, sk, sk_protocol); | ||||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct bpf_sock_addr, msg_src_ip4): | ||||
|  | @ -8835,11 +8828,11 @@ sk_reuseport_is_valid_access(int off, int size, | |||
| 				    skb,				\ | ||||
| 				    SKB_FIELD) | ||||
| 
 | ||||
| #define SK_REUSEPORT_LOAD_SK_FIELD_SIZE_OFF(SK_FIELD, BPF_SIZE, EXTRA_OFF) \ | ||||
| 	SOCK_ADDR_LOAD_NESTED_FIELD_SIZE_OFF(struct sk_reuseport_kern,	\ | ||||
| 					     struct sock,		\ | ||||
| 					     sk,			\ | ||||
| 					     SK_FIELD, BPF_SIZE, EXTRA_OFF) | ||||
| #define SK_REUSEPORT_LOAD_SK_FIELD(SK_FIELD)				\ | ||||
| 	SOCK_ADDR_LOAD_NESTED_FIELD(struct sk_reuseport_kern,		\ | ||||
| 				    struct sock,			\ | ||||
| 				    sk,					\ | ||||
| 				    SK_FIELD) | ||||
| 
 | ||||
| static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type, | ||||
| 					   const struct bpf_insn *si, | ||||
|  | @ -8863,16 +8856,7 @@ static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type, | |||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct sk_reuseport_md, ip_protocol): | ||||
| 		BUILD_BUG_ON(HWEIGHT32(SK_FL_PROTO_MASK) != BITS_PER_BYTE); | ||||
| 		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; | ||||
| 		SK_REUSEPORT_LOAD_SK_FIELD(sk_protocol); | ||||
| 		break; | ||||
| 
 | ||||
| 	case offsetof(struct sk_reuseport_md, data_end): | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Mat Martineau
						Mat Martineau