Re: [PATCH bpf-next 06/11] bpf: add bpf_skb_cgroup_id helper

2018-05-29 Thread Daniel Borkmann
On 05/29/2018 02:15 PM, Quentin Monnet wrote:
> Hi Daniel,
> 
> 2018-05-28 02:43 UTC+0200 ~ Daniel Borkmann 
>> Add a new bpf_skb_cgroup_id() helper that allows to retrieve the
>> cgroup id from the skb's socket. This is useful in particular to
>> enable bpf_get_cgroup_classid()-like behavior for cgroup v1 in
>> cgroup v2 by allowing ID based matching on egress. This can in
>> particular be used in combination with applying policy e.g. from
>> map lookups, and also complements the older bpf_skb_under_cgroup()
>> interface. In user space the cgroup id for a given path can be
>> retrieved through the f_handle as demonstrated in [0] recently.
>>
>>   [0] https://lkml.org/lkml/2018/5/22/1190
>>
>> Signed-off-by: Daniel Borkmann 
>> Acked-by: Alexei Starovoitov 
>> ---
>>  include/uapi/linux/bpf.h | 17 -
>>  net/core/filter.c| 29 +++--
>>  2 files changed, 43 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 9b8c6e3..e2853aa 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -2004,6 +2004,20 @@ union bpf_attr {
>>   *  direct packet access.
>>   *  Return
>>   *  0 on success, or a negative error in case of failure.
>> + *
>> + * uint64_t bpf_skb_cgroup_id(struct sk_buff *skb)
>> + *  Description
>> + *  Return the cgroup v2 id of the socket associated with the *skb*.
>> + *  This is roughly similar to the **bpf_get_cgroup_classid**\ ()
>> + *  helper for cgroup v1 by providing a tag resp. identifier that
>> + *  can be matched on or used for map lookups e.g. to implement
>> + *  policy. The cgroup v2 id of a given path in the hierarchy is
>> + *  exposed in user space through the f_handle API in order to get
>> + *  to the same 64-bit id.
>> + *
>> + *  This helper can be used on TC egress path, but not on ingress.
> 
> Nitpick: Maybe mention that the kernel must be built with
> CONFIG_SOCK_CGROUP_DATA option for the helper to be available?

Yeah that's fine. I was planning on a minor respin anyway some time today,
so I'll also update the description along with it.

Cheers,
Daniel


Re: [PATCH bpf-next 06/11] bpf: add bpf_skb_cgroup_id helper

2018-05-29 Thread Quentin Monnet
Hi Daniel,

2018-05-28 02:43 UTC+0200 ~ Daniel Borkmann 
> Add a new bpf_skb_cgroup_id() helper that allows to retrieve the
> cgroup id from the skb's socket. This is useful in particular to
> enable bpf_get_cgroup_classid()-like behavior for cgroup v1 in
> cgroup v2 by allowing ID based matching on egress. This can in
> particular be used in combination with applying policy e.g. from
> map lookups, and also complements the older bpf_skb_under_cgroup()
> interface. In user space the cgroup id for a given path can be
> retrieved through the f_handle as demonstrated in [0] recently.
> 
>   [0] https://lkml.org/lkml/2018/5/22/1190
> 
> Signed-off-by: Daniel Borkmann 
> Acked-by: Alexei Starovoitov 
> ---
>  include/uapi/linux/bpf.h | 17 -
>  net/core/filter.c| 29 +++--
>  2 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 9b8c6e3..e2853aa 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2004,6 +2004,20 @@ union bpf_attr {
>   *   direct packet access.
>   *   Return
>   *   0 on success, or a negative error in case of failure.
> + *
> + * uint64_t bpf_skb_cgroup_id(struct sk_buff *skb)
> + *   Description
> + *   Return the cgroup v2 id of the socket associated with the *skb*.
> + *   This is roughly similar to the **bpf_get_cgroup_classid**\ ()
> + *   helper for cgroup v1 by providing a tag resp. identifier that
> + *   can be matched on or used for map lookups e.g. to implement
> + *   policy. The cgroup v2 id of a given path in the hierarchy is
> + *   exposed in user space through the f_handle API in order to get
> + *   to the same 64-bit id.
> + *
> + *   This helper can be used on TC egress path, but not on ingress.

Nitpick: Maybe mention that the kernel must be built with
CONFIG_SOCK_CGROUP_DATA option for the helper to be available?

Best,
Quentin


> + *   Return
> + *   The id is returned or 0 in case the id could not be retrieved.
>   */
>  #define __BPF_FUNC_MAPPER(FN)\
>   FN(unspec), \
> @@ -2082,7 +2096,8 @@ union bpf_attr {
>   FN(lwt_push_encap), \
>   FN(lwt_seg6_store_bytes),   \
>   FN(lwt_seg6_adjust_srh),\
> - FN(lwt_seg6_action),
> + FN(lwt_seg6_action),\
> + FN(skb_cgroup_id),
>  
>  /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>   * function eBPF program intends to call
> diff --git a/net/core/filter.c b/net/core/filter.c
> index acf1f4f..717c740 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -3661,6 +3661,27 @@ static const struct bpf_func_proto 
> bpf_skb_under_cgroup_proto = {
>   .arg3_type  = ARG_ANYTHING,
>  };
>  
> +#ifdef CONFIG_SOCK_CGROUP_DATA
> +BPF_CALL_1(bpf_skb_cgroup_id, const struct sk_buff *, skb)
> +{
> + struct sock *sk = skb_to_full_sk(skb);
> + struct cgroup *cgrp;
> +
> + if (!sk || !sk_fullsock(sk))
> + return 0;
> +
> + cgrp = sock_cgroup_ptr(>sk_cgrp_data);
> + return cgrp->kn->id.id;
> +}
> +
> +static const struct bpf_func_proto bpf_skb_cgroup_id_proto = {
> + .func   = bpf_skb_cgroup_id,
> + .gpl_only   = false,
> + .ret_type   = RET_INTEGER,
> + .arg1_type  = ARG_PTR_TO_CTX,
> +};
> +#endif
> +
>  static unsigned long bpf_xdp_copy(void *dst_buff, const void *src_buff,
> unsigned long off, unsigned long len)
>  {
> @@ -4741,12 +4762,16 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const 
> struct bpf_prog *prog)
>   return _get_socket_cookie_proto;
>   case BPF_FUNC_get_socket_uid:
>   return _get_socket_uid_proto;
> + case BPF_FUNC_fib_lookup:
> + return _skb_fib_lookup_proto;
>  #ifdef CONFIG_XFRM
>   case BPF_FUNC_skb_get_xfrm_state:
>   return _skb_get_xfrm_state_proto;
>  #endif
> - case BPF_FUNC_fib_lookup:
> - return _skb_fib_lookup_proto;
> +#ifdef CONFIG_SOCK_CGROUP_DATA
> + case BPF_FUNC_skb_cgroup_id:
> + return _skb_cgroup_id_proto;
> +#endif
>   default:
>   return bpf_base_func_proto(func_id);
>   }
> 



[PATCH bpf-next 06/11] bpf: add bpf_skb_cgroup_id helper

2018-05-27 Thread Daniel Borkmann
Add a new bpf_skb_cgroup_id() helper that allows to retrieve the
cgroup id from the skb's socket. This is useful in particular to
enable bpf_get_cgroup_classid()-like behavior for cgroup v1 in
cgroup v2 by allowing ID based matching on egress. This can in
particular be used in combination with applying policy e.g. from
map lookups, and also complements the older bpf_skb_under_cgroup()
interface. In user space the cgroup id for a given path can be
retrieved through the f_handle as demonstrated in [0] recently.

  [0] https://lkml.org/lkml/2018/5/22/1190

Signed-off-by: Daniel Borkmann 
Acked-by: Alexei Starovoitov 
---
 include/uapi/linux/bpf.h | 17 -
 net/core/filter.c| 29 +++--
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 9b8c6e3..e2853aa 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2004,6 +2004,20 @@ union bpf_attr {
  * direct packet access.
  * Return
  * 0 on success, or a negative error in case of failure.
+ *
+ * uint64_t bpf_skb_cgroup_id(struct sk_buff *skb)
+ * Description
+ * Return the cgroup v2 id of the socket associated with the *skb*.
+ * This is roughly similar to the **bpf_get_cgroup_classid**\ ()
+ * helper for cgroup v1 by providing a tag resp. identifier that
+ * can be matched on or used for map lookups e.g. to implement
+ * policy. The cgroup v2 id of a given path in the hierarchy is
+ * exposed in user space through the f_handle API in order to get
+ * to the same 64-bit id.
+ *
+ * This helper can be used on TC egress path, but not on ingress.
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
  */
 #define __BPF_FUNC_MAPPER(FN)  \
FN(unspec), \
@@ -2082,7 +2096,8 @@ union bpf_attr {
FN(lwt_push_encap), \
FN(lwt_seg6_store_bytes),   \
FN(lwt_seg6_adjust_srh),\
-   FN(lwt_seg6_action),
+   FN(lwt_seg6_action),\
+   FN(skb_cgroup_id),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
diff --git a/net/core/filter.c b/net/core/filter.c
index acf1f4f..717c740 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3661,6 +3661,27 @@ static const struct bpf_func_proto 
bpf_skb_under_cgroup_proto = {
.arg3_type  = ARG_ANYTHING,
 };
 
+#ifdef CONFIG_SOCK_CGROUP_DATA
+BPF_CALL_1(bpf_skb_cgroup_id, const struct sk_buff *, skb)
+{
+   struct sock *sk = skb_to_full_sk(skb);
+   struct cgroup *cgrp;
+
+   if (!sk || !sk_fullsock(sk))
+   return 0;
+
+   cgrp = sock_cgroup_ptr(>sk_cgrp_data);
+   return cgrp->kn->id.id;
+}
+
+static const struct bpf_func_proto bpf_skb_cgroup_id_proto = {
+   .func   = bpf_skb_cgroup_id,
+   .gpl_only   = false,
+   .ret_type   = RET_INTEGER,
+   .arg1_type  = ARG_PTR_TO_CTX,
+};
+#endif
+
 static unsigned long bpf_xdp_copy(void *dst_buff, const void *src_buff,
  unsigned long off, unsigned long len)
 {
@@ -4741,12 +4762,16 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const 
struct bpf_prog *prog)
return _get_socket_cookie_proto;
case BPF_FUNC_get_socket_uid:
return _get_socket_uid_proto;
+   case BPF_FUNC_fib_lookup:
+   return _skb_fib_lookup_proto;
 #ifdef CONFIG_XFRM
case BPF_FUNC_skb_get_xfrm_state:
return _skb_get_xfrm_state_proto;
 #endif
-   case BPF_FUNC_fib_lookup:
-   return _skb_fib_lookup_proto;
+#ifdef CONFIG_SOCK_CGROUP_DATA
+   case BPF_FUNC_skb_cgroup_id:
+   return _skb_cgroup_id_proto;
+#endif
default:
return bpf_base_func_proto(func_id);
}
-- 
2.9.5