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:
Родитель
e9cdced78d
Коммит
bf9765145b
|
@ -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):
|
||||||
|
|
Загрузка…
Ссылка в новой задаче