OSDN Git Service

sock: Make sk_protocol a 16-bit value
authorMat Martineau <mathew.j.martineau@linux.intel.com>
Thu, 9 Jan 2020 15:59:15 +0000 (07:59 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 10 Jan 2020 02:41:41 +0000 (18:41 -0800)
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>
include/net/sock.h
include/trace/events/sock.h
net/core/filter.c

index 091e554..8766f9b 100644 (file)
@@ -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;
index 51fe9f6..3ff12b9 100644 (file)
@@ -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)
index 42fd17c..ef01c55 100644 (file)
@@ -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):