]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/core/filter.c
bpf: sockmap, convert bpf_compute_data_pointers to bpf_*_sk_skb
[linux.git] / net / core / filter.c
index 3095f1ba7015f560cccf96c45642490b20c96cc1..470268024a40de7ea29847a22a83d77dc0b121ef 100644 (file)
@@ -1762,6 +1762,37 @@ static const struct bpf_func_proto bpf_skb_pull_data_proto = {
        .arg2_type      = ARG_ANYTHING,
 };
 
+static inline int sk_skb_try_make_writable(struct sk_buff *skb,
+                                          unsigned int write_len)
+{
+       int err = __bpf_try_make_writable(skb, write_len);
+
+       bpf_compute_data_end_sk_skb(skb);
+       return err;
+}
+
+BPF_CALL_2(sk_skb_pull_data, struct sk_buff *, skb, u32, len)
+{
+       /* Idea is the following: should the needed direct read/write
+        * test fail during runtime, we can pull in more data and redo
+        * again, since implicitly, we invalidate previous checks here.
+        *
+        * Or, since we know how much we need to make read/writeable,
+        * this can be done once at the program beginning for direct
+        * access case. By this we overcome limitations of only current
+        * headroom being accessible.
+        */
+       return sk_skb_try_make_writable(skb, len ? : skb_headlen(skb));
+}
+
+static const struct bpf_func_proto sk_skb_pull_data_proto = {
+       .func           = sk_skb_pull_data,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_PTR_TO_CTX,
+       .arg2_type      = ARG_ANYTHING,
+};
+
 BPF_CALL_5(bpf_l3_csum_replace, struct sk_buff *, skb, u32, offset,
           u64, from, u64, to, u64, flags)
 {
@@ -2864,8 +2895,8 @@ static int bpf_skb_trim_rcsum(struct sk_buff *skb, unsigned int new_len)
        return __skb_trim_rcsum(skb, new_len);
 }
 
-BPF_CALL_3(bpf_skb_change_tail, struct sk_buff *, skb, u32, new_len,
-          u64, flags)
+static inline int __bpf_skb_change_tail(struct sk_buff *skb, u32 new_len,
+                                       u64 flags)
 {
        u32 max_len = __bpf_skb_max_len(skb);
        u32 min_len = __bpf_skb_min_len(skb);
@@ -2901,6 +2932,13 @@ BPF_CALL_3(bpf_skb_change_tail, struct sk_buff *, skb, u32, new_len,
                if (!ret && skb_is_gso(skb))
                        skb_gso_reset(skb);
        }
+       return ret;
+}
+
+BPF_CALL_3(bpf_skb_change_tail, struct sk_buff *, skb, u32, new_len,
+          u64, flags)
+{
+       int ret = __bpf_skb_change_tail(skb, new_len, flags);
 
        bpf_compute_data_pointers(skb);
        return ret;
@@ -2915,8 +2953,26 @@ static const struct bpf_func_proto bpf_skb_change_tail_proto = {
        .arg3_type      = ARG_ANYTHING,
 };
 
-BPF_CALL_3(bpf_skb_change_head, struct sk_buff *, skb, u32, head_room,
+BPF_CALL_3(sk_skb_change_tail, struct sk_buff *, skb, u32, new_len,
           u64, flags)
+{
+       int ret = __bpf_skb_change_tail(skb, new_len, flags);
+
+       bpf_compute_data_end_sk_skb(skb);
+       return ret;
+}
+
+static const struct bpf_func_proto sk_skb_change_tail_proto = {
+       .func           = sk_skb_change_tail,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_PTR_TO_CTX,
+       .arg2_type      = ARG_ANYTHING,
+       .arg3_type      = ARG_ANYTHING,
+};
+
+static inline int __bpf_skb_change_head(struct sk_buff *skb, u32 head_room,
+                                       u64 flags)
 {
        u32 max_len = __bpf_skb_max_len(skb);
        u32 new_len = skb->len + head_room;
@@ -2942,8 +2998,16 @@ BPF_CALL_3(bpf_skb_change_head, struct sk_buff *, skb, u32, head_room,
                skb_reset_mac_header(skb);
        }
 
+       return ret;
+}
+
+BPF_CALL_3(bpf_skb_change_head, struct sk_buff *, skb, u32, head_room,
+          u64, flags)
+{
+       int ret = __bpf_skb_change_head(skb, head_room, flags);
+
        bpf_compute_data_pointers(skb);
-       return 0;
+       return ret;
 }
 
 static const struct bpf_func_proto bpf_skb_change_head_proto = {
@@ -2955,6 +3019,23 @@ static const struct bpf_func_proto bpf_skb_change_head_proto = {
        .arg3_type      = ARG_ANYTHING,
 };
 
+BPF_CALL_3(sk_skb_change_head, struct sk_buff *, skb, u32, head_room,
+          u64, flags)
+{
+       int ret = __bpf_skb_change_head(skb, head_room, flags);
+
+       bpf_compute_data_end_sk_skb(skb);
+       return ret;
+}
+
+static const struct bpf_func_proto sk_skb_change_head_proto = {
+       .func           = sk_skb_change_head,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_PTR_TO_CTX,
+       .arg2_type      = ARG_ANYTHING,
+       .arg3_type      = ARG_ANYTHING,
+};
 static unsigned long xdp_get_metalen(const struct xdp_buff *xdp)
 {
        return xdp_data_meta_unsupported(xdp) ? 0 :
@@ -4618,9 +4699,12 @@ bool bpf_helper_changes_pkt_data(void *func)
            func == bpf_skb_store_bytes ||
            func == bpf_skb_change_proto ||
            func == bpf_skb_change_head ||
+           func == sk_skb_change_head ||
            func == bpf_skb_change_tail ||
+           func == sk_skb_change_tail ||
            func == bpf_skb_adjust_room ||
            func == bpf_skb_pull_data ||
+           func == sk_skb_pull_data ||
            func == bpf_clone_redirect ||
            func == bpf_l3_csum_replace ||
            func == bpf_l4_csum_replace ||
@@ -4872,11 +4956,11 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
        case BPF_FUNC_skb_load_bytes:
                return &bpf_skb_load_bytes_proto;
        case BPF_FUNC_skb_pull_data:
-               return &bpf_skb_pull_data_proto;
+               return &sk_skb_pull_data_proto;
        case BPF_FUNC_skb_change_tail:
-               return &bpf_skb_change_tail_proto;
+               return &sk_skb_change_tail_proto;
        case BPF_FUNC_skb_change_head:
-               return &bpf_skb_change_head_proto;
+               return &sk_skb_change_head_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_cookie_proto;
        case BPF_FUNC_get_socket_uid: