tc-bpf(8)


NAME

   BPF  -  BPF  programmable  classifier  and  actions  for ingress/egress
   queueing disciplines

SYNOPSIS

   eBPF classifier (filter) or action:
   tc filter ... bpf [ object-file OBJ_FILE  ]  [  section  CLS_NAME  ]  [
   export  UDS_FILE  ]  [  verbose  ]  [  police  POLICE_SPEC  ]  [ action
   ACTION_SPEC ] [ classid CLASSID ]
   tc action ... bpf [ object-file OBJ_FILE  ]  [  section  CLS_NAME  ]  [
   export UDS_FILE ] [ verbose ]

   cBPF classifier (filter) or action:
   tc  filter ... bpf [ bytecode-file BPF_FILE | bytecode BPF_BYTECODE ] [
   police POLICE_SPEC ] [ action ACTION_SPEC ] [ classid CLASSID ]
   tc action ... bpf [ bytecode-file BPF_FILE | bytecode BPF_BYTECODE ]

DESCRIPTION

   Extended Berkeley Packet Filter ( eBPF ) and  classic  Berkeley  Packet
   Filter  (originally known as BPF, for better distinction referred to as
   cBPF here) are both  available  as  a  fully  programmable  and  highly
   efficient classifier and actions. They both offer a minimal instruction
   set for implementing small programs which can safely be loaded into the
   kernel  and  thus executed in a tiny virtual machine from kernel space.
   An in-kernel  verifier  guarantees  that  a  specified  program  always
   terminates and neither crashes nor leaks data from the kernel.

   In Linux, it's generally considered that eBPF is the successor of cBPF.
   The kernel internally transforms cBPF expressions into eBPF expressions
   and  executes  the  latter.  Execution  of  them can be performed in an
   interpreter or  at  setup  time,  they  can  be  just-in-time  compiled
   (JIT'ed)  to  run  as native machine code. Currently, x86_64, ARM64 and
   s390 architectures have eBPF JIT support, whereas PPC, SPARC,  ARM  and
   MIPS have cBPF, but did not (yet) switch to eBPF JIT support.

   eBPF's  instruction  set  has similar underlying principles as the cBPF
   instruction set, it  however  is  modelled  closer  to  the  underlying
   architecture  to  better  mimic native instruction sets with the aim to
   achieve a better run-time performance. It is designed to be JIT'ed with
   a  one  to  one  mapping,  which  can  also open up the possibility for
   compilers to generate optimized eBPF code through an eBPF backend  that
   performs  almost  as  fast  as  natively compiled code. Given that LLVM
   provides such an eBPF backend, eBPF programs can  therefore  easily  be
   programmed  in  a  subset  of  the  C  language.  Other than that, eBPF
   infrastructure also comes with a construct called "maps". eBPF maps are
   key/value  stores  that  are shared between multiple eBPF programs, but
   also between eBPF programs and user space applications.

   For the traffic control subsystem, classifier and actions that  can  be
   attached  to  ingress and egress qdiscs can be written in eBPF or cBPF.
   The advantage over other  classifier  and  actions  is  that  eBPF/cBPF
   provides  the generic framework, while users can implement their highly
   specialized use cases efficiently. This means that  the  classifier  or
   action  written  that  way  will not suffer from feature bloat, and can
   therefore execute its task highly efficient. It allows  for  non-linear
   classification   and   even   merging   the   action   part   into  the
   classification. Combined with efficient eBPF map data structures,  user
   space  can  push  new  policies  like  classids into the kernel without
   reloading a classifier, or it can gather  statistics  that  are  pushed
   into one map and use another one for dynamically load balancing traffic
   based on the determined load, just to provide a few examples.

PARAMETERS

   object-file
   points to an object file that has an  executable  and  linkable  format
   (ELF)  and  contains  eBPF  opcodes  and eBPF map definitions. The LLVM
   compiler infrastructure with clang(1) as a C language front end is  one
   project  that supports emitting eBPF object files that can be passed to
   the eBPF classifier (more details in the EXAMPLES section). This option
   is mandatory when an eBPF classifier or action is to be loaded.

   section
   is  the  name  of  the ELF section from the object file, where the eBPF
   classifier or action resides. By  default  the  section  name  for  the
   classifier  is  called "classifier", and for the action "action". Given
   that a single object file can contain multiple classifier and  actions,
   the  corresponding  section  name  needs to be specified, if it differs
   from the defaults.

   export
   points to a Unix domain socket file. In case the eBPF object file  also
   contains  a section named "maps" with eBPF map specifications, then the
   map file descriptors can be handed off via the Unix domain socket to an
   eBPF  "agent"  herding  all  descriptors after tc lifetime. This can be
   some third party application implementing the IPC counterpart  for  the
   import,  that uses them for calling into bpf(2) system call to read out
   or update eBPF map data from user space, for  example,  for  monitoring
   purposes or to push down new policies.

   verbose
   if set, it will dump the eBPF verifier output, even if loading the eBPF
   program was successful. By default, only on error, the verifier log  is
   being emitted to the user.

   police
   is  an  optional parameter for an eBPF/cBPF classifier that specifies a
   police in tc(1) which is attached to the classifier, for example, on an
   ingress qdisc.

   action
   is  an  optional parameter for an eBPF/cBPF classifier that specifies a
   subsequent action in tc(1) which is attached to a classifier.

   classid
   flowid
   provides  the  default  traffic  control  class  identifier  for   this
   eBPF/cBPF   classifier.  The  default  class  identifier  can  also  be
   overwritten by the return code of  the  eBPF/cBPF  program.  A  default
   return  code of -1 specifies the here provided default class identifier
   to be used. A return code of the eBPF/cBPF program of 0 implies that no
   match  took place, and a return code other than these two will override
   the  default   classid.   This   allows   for   efficient,   non-linear
   classification  with  only  a  single  eBPF/cBPF  program as opposed to
   having multiple individual programs for various class identifiers which
   would need to reparse packet contents.

   bytecode
   is  being  used  for loading cBPF classifier and actions only. The cBPF
   bytecode is directly passed as a text string in the form of  s,c  t  f
   k,c  t  f  k,c  t  f  k,... , where s denotes the number of subsequent
   4-tuples. One such 4-tuple consists of  c  t  f  k  decimals,  where  c
   represents  the  cBPF opcode, t the jump true offset target, f the jump
   false offset target and k the  immediate  constant/literal.  There  are
   various  tools that generate code in this loadable format, for example,
   bpf_asm that ships with the Linux kernel source tree under tools/net/ ,
   so  it  is certainly not expected to hack this by hand. The bytecode or
   bytecode-file option is mandatory when a cBPF classifier or  action  is
   to be loaded.

   bytecode-file
   also  being  used to load a cBPF classifier or action. It's effectively
   the same as bytecode only that the cBPF bytecode is not passed directly
   via command line, but rather resides in a text file.

EXAMPLES

   eBPF TOOLING
   A  full blown example including eBPF agent code can be found inside the
   iproute2 source package under: examples/bpf/

   As prerequisites, the kernel needs to have the eBPF system call  namely
   bpf(2)  enabled  and  ships with cls_bpf and act_bpf kernel modules for
   the  traffic  control  subsystem.  To  enable  eBPF/eBPF  JIT  support,
   depending which of the two the given architecture supports:

       echo 1 > /proc/sys/net/core/bpf_jit_enable

   A given restricted C file can be compiled via LLVM as:

       clang  -O2  -emit-llvm -c bpf.c -o - | llc -march=bpf -filetype=obj
       -o bpf.o

   The compiler invocation might still simplify in  future,  so  for  now,
   it's  quite  handy  to  alias this construct in one way or another, for
   example:

       __bcc() {
               clang -O2 -emit-llvm -c $1 -o - | \
               llc -march=bpf -filetype=obj -o "`basename $1 .c`.o"
       }

       alias bcc=__bcc

   A minimal, stand-alone unit, which matches  on  all  traffic  with  the
   default classid (return code of -1) looks like:

       #include <linux/bpf.h>

       #ifndef __section
       # define __section(x)  __attribute__((section(x), used))
       #endif

       __section("classifier") int cls_main(struct __sk_buff *skb)
       {
               return -1;
       }

       char __license[] __section("license") = "GPL";

   More examples can be found further below in subsection eBPF PROGRAMMING
   as focus here will be on tooling.

   There can be various other sections, for  example,  also  for  actions.
   Thus,  an  object  file  in  eBPF can contain multiple entrance points.
   Always a specific entrance  point,  however,  must  be  specified  when
   configuring  with  tc.  A license must be part of the restricted C code
   and the license string syntax is the same as with Linux kernel modules.
   The  kernel  reserves  its right that some eBPF helper functions can be
   restricted to GPL compatible licenses  only,  and  thus  may  reject  a
   program  from  loading  into  the  kernel  when such a license mismatch
   occurs.

   The resulting object file from the compilation can  be  inspected  with
   the  usual  set  of tools that also operate on normal object files, for
   example objdump(1) for inspecting ELF section headers:

       objdump -h bpf.o
       [...]
       3 classifier    000007f8  0000000000000000  0000000000000000  00000040  2**3
                       CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
       4 action-mark   00000088  0000000000000000  0000000000000000  00000838  2**3
                       CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
       5 action-rand   00000098  0000000000000000  0000000000000000  000008c0  2**3
                       CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
       6 maps          00000030  0000000000000000  0000000000000000  00000958  2**2
                       CONTENTS, ALLOC, LOAD, DATA
       7 license       00000004  0000000000000000  0000000000000000  00000988  2**0
                       CONTENTS, ALLOC, LOAD, DATA
       [...]

   Adding  an  eBPF  classifier  from  an  object  file  that  contains  a
   classifier  in the default ELF section is trivial (note that instead of
   "object-file" also shortcuts such as "obj" can be used):

       bcc bpf.c
       tc filter add dev em1 parent 1: bpf obj bpf.o flowid 1:1

   In case the classifier resides in ELF section "mycls", then  that  same
   command needs to be invoked as:

       tc filter add dev em1 parent 1: bpf obj bpf.o sec mycls flowid 1:1

   Dumping  the  classifier  configuration  will  tell the location of the
   classifier, in other words that it's from  object  file  "bpf.o"  under
   section "mycls":

       tc filter show dev em1
       filter parent 1: protocol all pref 49152 bpf
       filter  parent 1: protocol all pref 49152 bpf handle 0x1 flowid 1:1
       bpf.o:[mycls]

   The same program can also be installed on ingress qdisc side as opposed
   to egress ...

       tc qdisc add dev em1 handle ffff: ingress
       tc  filter  add dev em1 parent ffff: bpf obj bpf.o sec mycls flowid
       ffff:1

   ... and again dumped from there:

       tc filter show dev em1 parent ffff:
       filter protocol all pref 49152 bpf
       filter protocol  all  pref  49152  bpf  handle  0x1  flowid  ffff:1
       bpf.o:[mycls]

   Attaching  a  classifier and action on ingress has the restriction that
   it doesn't have an actual underlying queueing discipline. What  ingress
   can  do is to classify, mangle, redirect or drop packets. When queueing
   is required on ingress side, then ingress must redirect packets to  the
   ifb  device,  otherwise  policing can be used. Moreover, ingress can be
   used to have an early drop point of unwanted packets  before  they  hit
   upper  layers  of the networking stack, perform network accounting with
   eBPF maps that could be shared with egress, or  have  an  early  mangle
   and/or redirection point to different networking devices.

   Multiple eBPF actions and classifier can be placed into a single object
   file within various sections. In that case, non-default  section  names
   must be provided, which is the case for both actions in this example:

       tc filter add dev em1 parent 1: bpf obj bpf.o flowid 1:1 \
                                action bpf obj bpf.o sec action-mark \
                                action bpf obj bpf.o sec action-rand ok

   The  advantage  of  this is that the classifier and the two actions can
   then share eBPF maps with each other, if implemented in the programs.

   In order to access  eBPF  maps  from  user  space  beyond  tc(8)  setup
   lifetime,  the  ownership  can be transferred to an eBPF agent via Unix
   domain sockets. There are two possibilities for implementing this:

   1) implementation of an own eBPF agent that takes care  of  setting  up
   the  Unix  domain  socket  and  implementing  the  protocol  that tc(8)
   dictates. A code example of this  can  be  found  inside  the  iproute2
   source package under: examples/bpf/

   2) use tc exec for transferring the eBPF map file descriptors through a
   Unix domain socket, and spawning an application such as  sh(1)  .  This
   approach's  advantage  is  that tc will place the file descriptors into
   the environment and thus make them available just like  stdin,  stdout,
   stderr  file  descriptors,  meaning, in case user applications run from
   within this fd-owner shell, they  can  terminate  and  restart  without
   loosing  eBPF  maps  file  descriptors.  Example  invocation  with  the
   previous classifier and action mixture:

       tc exec bpf imp /tmp/bpf
       tc filter add dev em1 parent 1: bpf obj bpf.o exp  /tmp/bpf  flowid
       1:1 \
                                action bpf obj bpf.o sec action-mark \
                                action bpf obj bpf.o sec action-rand ok

   Assuming  that  eBPF  maps are shared with classifier and actions, it's
   enough to export them once, for example, from within the classifier  or
   action command. tc will setup all eBPF map file descriptors at the time
   when the object file is first parsed.

   When a shell has been spawned, the environment will have  a  couple  of
   eBPF  related variables. BPF_NUM_MAPS provides the total number of maps
   that have been transferred over the Unix  domain  socket.  BPF_MAP<X>'s
   value  is the file descriptor number that can be accessed in eBPF agent
   applications, in other words, it can  directly  be  used  as  the  file
   descriptor  value  for the bpf(2) system call to retrieve or alter eBPF
   map values. <X> denotes the identifier of the eBPF map. It  corresponds
   to  the  id  member  of  struct  bpf_elf_map    from  the  tc  eBPF map
   specification.

   The environment in this example looks as follows:

       sh# env | grep BPF
           BPF_NUM_MAPS=3
           BPF_MAP1=6
           BPF_MAP0=5
           BPF_MAP2=7
       sh# ls -la /proc/self/fd
           [...]
           lrwx------. 1 root root 64 Apr 14 16:46 5 -> anon_inode:bpf-map
           lrwx------. 1 root root 64 Apr 14 16:46 6 -> anon_inode:bpf-map
           lrwx------. 1 root root 64 Apr 14 16:46 7 -> anon_inode:bpf-map
       sh# my_bpf_agent

   eBPF agents are very useful in that they can prepopulate eBPF maps from
   user space, monitor statistics via maps and based on that feedback, for
   example, rewrite classids in eBPF map values during runtime. Given that
   eBPF  agents  are  implemented  as  normal  applications, they can also
   dynamically receive traffic control policies from external  controllers
   and  thus push them down into eBPF maps to dynamically adapt to network
   conditions. Moreover, eBPF maps can also  be  shared  with  other  eBPF
   program  types  (e.g.  tracing),  thus  very  powerful  combination can
   therefore be implemented.

   eBPF PROGRAMMING
   eBPF classifier and actions  are  being  implemented  in  restricted  C
   syntax  (in  future, there could additionally be new language frontends
   supported).

   The header file linux/bpf.h provides eBPF helper functions that can  be
   called  from  an  eBPF  program.   This  man page will only provide two
   minimal, stand-alone examples, have a look  at  examples/bpf  from  the
   iproute2  source  package for a fully fledged flow dissector example to
   better demonstrate some of the possibilities with eBPF.

   Supported 32 bit classifier return codes from the C program  and  their
   meanings:
       0 , denotes a mismatch
       -1 , denotes the default classid configured from the command line
       else , everything else will override the default classid to provide
       a facility for non-linear matching

   Supported 32 bit action return codes  from  the  C  program  and  their
   meanings ( linux/pkt_cls.h ):
       TC_ACT_OK  (0)  , will terminate the packet processing pipeline and
       allows the packet to proceed
       TC_ACT_SHOT (2) , will terminate the packet processing pipeline and
       drops the packet
       TC_ACT_UNSPEC (-1) , will use the default action configured from tc
       (similarly as returning -1 from a classifier)
       TC_ACT_PIPE (3) , will iterate to the next action, if available
       TC_ACT_RECLASSIFY  (1)  ,  will  terminate  the  packet  processing
       pipeline and start classification from the beginning
       else , everything else is an unspecified return code

   Both  classifier and action return codes are supported in eBPF and cBPF
   programs.

   To demonstrate restricted C syntax, a minimal toy classifier example is
   provided,  which  assumes that egress packets, for instance originating
   from a container, have previously been marked in interval [0, 255]. The
   program keeps statistics on different marks for user space and maps the
   classid to the root qdisc with the marking itself as the minor handle:

       #include <stdint.h>
       #include <asm/types.h>

       #include <linux/bpf.h>
       #include <linux/pkt_sched.h>

       #include "helpers.h"

       struct tuple {
               long packets;
               long bytes;
       };

       #define BPF_MAP_ID_STATS        1 /* agent's map identifier */
       #define BPF_MAX_MARK            256

       struct bpf_elf_map __section("maps") map_stats = {
               .type           =       BPF_MAP_TYPE_ARRAY,
               .id             =       BPF_MAP_ID_STATS,
               .size_key       =       sizeof(uint32_t),
               .size_value     =       sizeof(struct tuple),
               .max_elem       =       BPF_MAX_MARK,
       };

       static inline void cls_update_stats(const struct __sk_buff *skb,
                                           uint32_t mark)
       {
               struct tuple *tu;

               tu = bpf_map_lookup_elem(&map_stats, &mark);
               if (likely(tu)) {
                       __sync_fetch_and_add(&tu->packets, 1);
                       __sync_fetch_and_add(&tu->bytes, skb->len);
               }
       }

       __section("cls") int cls_main(struct __sk_buff *skb)
       {
               uint32_t mark = skb->mark;

               if (unlikely(mark >= BPF_MAX_MARK))
                       return 0;

               cls_update_stats(skb, mark);

               return TC_H_MAKE(TC_H_ROOT, mark);
       }

       char __license[] __section("license") = "GPL";

   Another small example is a port redirector  which  demuxes  destination
   port 80 into the interval [8080, 8087] steered by RSS, that can then be
   attached  to  ingress  qdisc.  The  exercise  of  adding   the   egress
   counterpart and IPv6 support is left to the reader:

       #include <asm/types.h>
       #include <asm/byteorder.h>

       #include <linux/bpf.h>
       #include <linux/filter.h>
       #include <linux/in.h>
       #include <linux/if_ether.h>
       #include <linux/ip.h>
       #include <linux/tcp.h>

       #include "helpers.h"

       static inline void set_tcp_dport(struct __sk_buff *skb, int nh_off,
                                        __u16 old_port, __u16 new_port)
       {
               bpf_l4_csum_replace(skb, nh_off + offsetof(struct tcphdr, check),
                                   old_port, new_port, sizeof(new_port));
               bpf_skb_store_bytes(skb, nh_off + offsetof(struct tcphdr, dest),
                                   &new_port, sizeof(new_port), 0);
       }

       static inline int lb_do_ipv4(struct __sk_buff *skb, int nh_off)
       {
               __u16 dport, dport_new = 8080, off;
               __u8 ip_proto, ip_vl;

               ip_proto = load_byte(skb, nh_off +
                                    offsetof(struct iphdr, protocol));
               if (ip_proto != IPPROTO_TCP)
                       return 0;

               ip_vl = load_byte(skb, nh_off);
               if (likely(ip_vl == 0x45))
                       nh_off += sizeof(struct iphdr);
               else
                       nh_off += (ip_vl & 0xF) << 2;

               dport = load_half(skb, nh_off + offsetof(struct tcphdr, dest));
               if (dport != 80)
                       return 0;

               off = skb->queue_mapping & 7;
               set_tcp_dport(skb, nh_off - BPF_LL_OFF, __constant_htons(80),
                             __cpu_to_be16(dport_new + off));
               return -1;
       }

       __section("lb") int lb_main(struct __sk_buff *skb)
       {
               int ret = 0, nh_off = BPF_LL_OFF + ETH_HLEN;

               if (likely(skb->protocol == __constant_htons(ETH_P_IP)))
                       ret = lb_do_ipv4(skb, nh_off);

               return ret;
       }

       char __license[] __section("license") = "GPL";

   The related helper header file helpers.h in both examples was:

       /* Misc helper macros. */
       #define __section(x) __attribute__((section(x), used))
       #define offsetof(x, y) __builtin_offsetof(x, y)
       #define likely(x) __builtin_expect(!!(x), 1)
       #define unlikely(x) __builtin_expect(!!(x), 0)

       /* Used map structure */
       struct bpf_elf_map {
           __u32 type;
           __u32 size_key;
           __u32 size_value;
           __u32 max_elem;
           __u32 id;
       };

       /* Some used BPF function calls. */
       static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from,
                                         int len, int flags) =
             (void *) BPF_FUNC_skb_store_bytes;
       static int (*bpf_l4_csum_replace)(void *ctx, int off, int from,
                                         int to, int flags) =
             (void *) BPF_FUNC_l4_csum_replace;
       static void *(*bpf_map_lookup_elem)(void *map, void *key) =
             (void *) BPF_FUNC_map_lookup_elem;

       /* Some used BPF intrinsics. */
       unsigned long long load_byte(void *skb, unsigned long long off)
           asm ("llvm.bpf.load.byte");
       unsigned long long load_half(void *skb, unsigned long long off)
           asm ("llvm.bpf.load.half");

   Best  practice,  we  recommend  to  only  have a single eBPF classifier
   loaded in tc and perform all necessary matching and mangling from there
   instead of a list of individual classifier and separate actions. Just a
   single classifier tailored for a given use-case will be most  efficient
   to run.

   eBPF DEBUGGING
   Both  tc filter and action commands for bpf support an optional verbose
   parameter that can be used to inspect the  eBPF  verifier  log.  It  is
   dumped by default in case of an error.

   In  case  the  eBPF/cBPF  JIT compiler has been enabled, it can also be
   instructed to emit a debug output of the resulting  opcode  image  into
   the kernel log, which can be read via dmesg(1) :

       echo 2 > /proc/sys/net/core/bpf_jit_enable

   The  Linux  kernel  source  tree  ships additionally under tools/net/ a
   small helper called bpf_jit_disasm that reads out the opcode image dump
   from the kernel log and dumps the resulting disassembly:

       bpf_jit_disasm -o

   Other  than that, the Linux kernel also contains an extensive eBPF/cBPF
   test suite module called test_bpf . Upon ...

       modprobe test_bpf

   ... it performs a diversity of test cases and dumps  the  results  into
   the  kernel  log  that can be inspected with dmesg(1) . The results can
   differ depending on whether the JIT compiler is enabled or not. In case
   of  failed  test cases, the module will fail to load. In such cases, we
   urge you to file a bug report to the related JIT authors, Linux  kernel
   and networking mailing lists.

   cBPF
   Although   we   generally  recommend  switching  to  implementing  eBPF
   classifier and actions, for the sake of completeness, a  few  words  on
   how to program in cBPF will be lost here.

   Likewise,  the  bpf_jit_enable  switch  can  be  enabled  as  mentioned
   already. Tooling such as bpf_jit_disasm  is  also  independent  whether
   eBPF or cBPF code is being loaded.

   Unlike in eBPF, classifier and action are not implemented in restricted
   C, but rather in a minimal assembler-like language or with the help  of
   other tooling.

   The raw interface with tc takes opcodes directly. For example, the most
   minimal classifier matching on every packet resulting  in  the  default
   classid of 1:1 looks like:

       tc  filter add dev em1 parent 1: bpf bytecode '1,6 0 0 4294967295,'
       flowid 1:1

   The first decimal of  the  bytecode  sequence  denotes  the  number  of
   subsequent  4-tuples  of  cBPF  opcodes.  As  mentioned, such a 4-tuple
   consists of c t f k decimals, where c represents the cBPF opcode, t the
   jump  true  offset  target,  f  the  jump false offset target and k the
   immediate constant/literal. Here, this denotes an unconditional  return
   from the program with immediate value of -1.

   Thus, for egress classification, Willem de Bruijn implemented a minimal
   stand-alone helper tool under the GNU General Public License version  2
   for  iptables(8)  BPF  extension,  which  abuses  the  libpcap internal
   classic BPF compiler, his code derived here for usage with tc(8) :

       #include <pcap.h>
       #include <stdio.h>

       int main(int argc, char **argv)
       {
               struct bpf_program prog;
               struct bpf_insn *ins;
               int i, ret, dlt = DLT_RAW;

               if (argc < 2 || argc > 3)
                       return 1;
               if (argc == 3) {
                       dlt = pcap_datalink_name_to_val(argv[1]);
                       if (dlt == -1)
                               return 1;
               }

               ret = pcap_compile_nopcap(-1, dlt, &prog, argv[argc - 1],
                                         1, PCAP_NETMASK_UNKNOWN);
               if (ret)
                       return 1;

               printf("%d,", prog.bf_len);
               ins = prog.bf_insns;

               for (i = 0; i < prog.bf_len - 1; ++ins, ++i)
                       printf("%u %u %u %u,", ins->code,
                              ins->jt, ins->jf, ins->k);
               printf("%u %u %u %u",
                      ins->code, ins->jt, ins->jf, ins->k);

               pcap_freecode(&prog);
               return 0;
       }

   Given this small helper, any tcpdump(8) filter expression can be abused
   as a classifier where a match will result in the default classid:

       bpftool EN10MB 'tcp[tcpflags] & tcp-syn != 0' > /var/bpf/tcp-syn
       tc  filter add dev em1 parent 1: bpf bytecode-file /var/bpf/tcp-syn
       flowid 1:1

   Basically, such a minimal generator is equivalent to:

       tcpdump -iem1 -ddd 'tcp[tcpflags] & tcp-syn != 0' |  tr  '0  ','  >
       /var/bpf/tcp-syn

   Since  libpcap  does not support all Linux' specific cBPF extensions in
   its compiler, the Linux kernel also ships under  tools/net/  a  minimal
   BPF  assembler  called bpf_asm for providing full control. For detailed
   syntax and  semantics  on  implementing  such  programs  by  hand,  see
   references under FURTHER READING .

   Trivial  toy example in bpf_asm for classifying IPv4/TCP packets, saved
   in a text file called foobar :

       ldh [12]
       jne #0x800, drop
       ldb [23]
       jneq #6, drop
       ret #-1
       drop: ret #0

   Similarly, such a classifier can be loaded as:

       bpf_asm foobar > /var/bpf/tcp-syn
       tc filter add dev em1 parent 1: bpf bytecode-file  /var/bpf/tcp-syn
       flowid 1:1

   For  BPF  classifiers,  the  Linux  kernel  provides additionally under
   tools/net/ a small BPF debugger called bpf_dbg , which can be  used  to
   test  a  classifier  against  pcap  files,  single-step  or add various
   breakpoints into the classifier  program  and  dump  register  contents
   during runtime.

   Implementing  an  action  in classic BPF is rather limited in the sense
   that packet  mangling  is  not  supported.  Therefore,  it's  generally
   recommended to make the switch to eBPF, whenever possible.

FURTHER READING

   Further  and  more  technical details about the BPF architecture can be
   found     in     the     Linux     kernel     source     tree     under
   Documentation/networking/filter.txt .

   Further  details  on  eBPF  tc(8) examples can be found in the iproute2
   source tree under examples/bpf/ .

SEE ALSO

   tc(8), tc-ematch(8) bpf(2) bpf(4)

AUTHORS

   Manpage written by Daniel Borkmann.

   Please  report  corrections  or  improvements  to  the   Linux   kernel
   networking mailing list: <netdev@vger.kernel.org>

iproute2                          18 May 20BPF classifier and actions in tc(8)





Opportunity


Personal Opportunity - Free software gives you access to billions of dollars of software at no cost. Use this software for your business, personal use or to develop a profitable skill. Access to source code provides access to a level of capabilities/information that companies protect though copyrights. Open source is a core component of the Internet and it is available to you. Leverage the billions of dollars in resources and capabilities to build a career, establish a business or change the world. The potential is endless for those who understand the opportunity.

Business Opportunity - Goldman Sachs, IBM and countless large corporations are leveraging open source to reduce costs, develop products and increase their bottom lines. Learn what these companies know about open source and how open source can give you the advantage.





Free Software


Free Software provides computer programs and capabilities at no cost but more importantly, it provides the freedom to run, edit, contribute to, and share the software. The importance of free software is a matter of access, not price. Software at no cost is a benefit but ownership rights to the software and source code is far more significant.


Free Office Software - The Libre Office suite provides top desktop productivity tools for free. This includes, a word processor, spreadsheet, presentation engine, drawing and flowcharting, database and math applications. Libre Office is available for Linux or Windows.





Free Books


The Free Books Library is a collection of thousands of the most popular public domain books in an online readable format. The collection includes great classical literature and more recent works where the U.S. copyright has expired. These books are yours to read and use without restrictions.


Source Code - Want to change a program or know how it works? Open Source provides the source code for its programs so that anyone can use, modify or learn how to write those programs themselves. Visit the GNU source code repositories to download the source.





Education


Study at Harvard, Stanford or MIT - Open edX provides free online courses from Harvard, MIT, Columbia, UC Berkeley and other top Universities. Hundreds of courses for almost all major subjects and course levels. Open edx also offers some paid courses and selected certifications.


Linux Manual Pages - A man or manual page is a form of software documentation found on Linux/Unix operating systems. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts.