Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Cgroup

Cgroup BPF programs enforce per-cgroup network and socket policies. The kernel automatically sets expected_attach_type based on the section name, so the loader does not require extra configuration.

Program Subtypes

cgroup_skb

Per-cgroup packet filtering at the SKB level. Return 1 to allow, 0 to drop.

SectionDirection
"cgroup_skb/ingress"Inbound packets
"cgroup_skb/egress"Outbound packets
(defprog count-egress (:type :cgroup-skb
                     :section "cgroup_skb/egress")
  ;; allow all, but could inspect and drop
  1)

cgroup_sock

Socket lifecycle hooks. Return 1 to allow, 0 to deny.

SectionEvent
"cgroup/sock_create"Socket creation
"cgroup/sock_release"Socket close
(defprog audit-sock (:type :cgroup-sock
                     :section "cgroup/sock_create")
  ;; allow all socket creation
  1)

cgroup_sock_addr

Connection and message authorization. Return 1 to allow, 0 to block.

SectionOperation
"cgroup/connect4"IPv4 connect
"cgroup/connect6"IPv6 connect
"cgroup/sendmsg4"IPv4 UDP sendmsg
"cgroup/sendmsg6"IPv6 UDP sendmsg
(defprog filter-connect (:type :cgroup-sock-addr
                         :section "cgroup/connect4")
  ;; allow all IPv4 connections
  1)

BPF Helpers

The following helpers are available in cgroup programs:

HelperIDDescription
get-socket-cookie47Unique cookie identifying the socket
get-current-pid-tgid14PID and TGID of current task
get-current-uid-gid15UID and GID of current task
ktime-get-coarse-ns161Coarse monotonic timestamp

Attachment

Standalone

Use attach-cgroup with the cgroup filesystem path and the appropriate attach type constant:

(attach-cgroup prog "/sys/fs/cgroup"
               :attach-type +bpf-cgroup-inet-egress+)

Attach type constants:

ConstantSubtype
+bpf-cgroup-inet-ingress+cgroup_skb ingress
+bpf-cgroup-inet-egress+cgroup_skb egress
+bpf-cgroup-inet-sock-create+cgroup_sock create
+bpf-cgroup-inet-sock-release+cgroup_sock release
+bpf-cgroup-inet4-connect+cgroup_sock_addr connect4
+bpf-cgroup-inet6-connect+cgroup_sock_addr connect6
+bpf-cgroup-udp4-sendmsg+cgroup_sock_addr sendmsg4
+bpf-cgroup-udp6-sendmsg+cgroup_sock_addr sendmsg6

with-bpf-session

Inside a with-bpf-session, bpf:attach auto-detects the attach type from the program's section name:

(with-bpf-session (session "count-egress.o")
  (bpf:attach session "count-egress"
              :cgroup-path "/sys/fs/cgroup"))

Example: Count Egress Packets

A complete program that counts outbound packets for the root cgroup.

BPF program

(defmap pkt-count :type :array
  :key-size 4
  :value-size 8
  :max-entries 1)

(defprog count-egress (:type :cgroup-skb
                     :section "cgroup_skb/egress")
  (let ((key (u32 0))
        (val (map-lookup pkt-count key)))
    (when val
      (atomic-add val 1)))
  1)

Standalone loader

(let* ((obj (bpf:open-object "count-egress.o"))
       (prog (bpf:find-program obj "count-egress"))
       (loaded (bpf:load-program prog)))
  (attach-cgroup loaded "/sys/fs/cgroup"
                 :attach-type +bpf-cgroup-inet-egress+)
  ;; read the counter
  (let ((map (bpf:find-map obj "pkt-count")))
    (format t "packets: ~a~%" (bpf:map-lookup map 0))))

with-bpf-session loader

(with-bpf-session (session "count-egress.o")
  (bpf:attach session "count-egress"
              :cgroup-path "/sys/fs/cgroup")
  ;; session auto-detaches on scope exit
  (let ((map (bpf:find-map session "pkt-count")))
    (loop
      (sleep 1)
      (format t "packets: ~a~%" (bpf:map-lookup map 0)))))