tc, bpf: finalize eBPF support for cls and act front-end

This work finalizes both eBPF front-ends for the classifier and action
part in tc, it allows for custom ELF section selection, a simplified tc
command frontend (while keeping compat), reusing of common maps between
classifier and actions residing in the same object file, and exporting
of all map fds to an eBPF agent for handing off further control in user
space.

It also adds an extensive example of how eBPF can be used, and a minimal
self-contained example agent that dumps map data. The example is well
documented and hopefully provides a good starting point into programming
cls_bpf and act_bpf.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
diff --git a/tc/tc_bpf.h b/tc/tc_bpf.h
index ce64747..8b214b8 100644
--- a/tc/tc_bpf.h
+++ b/tc/tc_bpf.h
@@ -24,32 +24,6 @@
 
 #include "utils.h"
 
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-};
-
 int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len,
 		     char **bpf_string, bool *need_release,
 		     const char separator);
@@ -57,28 +31,40 @@
 		  bool from_file);
 void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len);
 
+const char *bpf_default_section(const enum bpf_prog_type type);
+
+#ifdef HAVE_ELF
+int bpf_open_object(const char *path, enum bpf_prog_type type,
+		    const char *sec);
+int bpf_handoff_map_fds(const char *path, const char *obj);
+
 static inline __u64 bpf_ptr_to_u64(const void *ptr)
 {
 	return (__u64) (unsigned long) ptr;
 }
 
-#ifdef HAVE_ELF
-int bpf_open_object(const char *path, enum bpf_prog_type type);
-
 static inline int bpf(int cmd, union bpf_attr *attr, unsigned int size)
 {
 #ifdef __NR_bpf
 	return syscall(__NR_bpf, cmd, attr, size);
 #else
+	fprintf(stderr, "No bpf syscall, kernel headers too old?\n");
 	errno = ENOSYS;
 	return -1;
 #endif
 }
 #else
-static inline int bpf_open_object(const char *path, enum bpf_prog_type type)
+static inline int bpf_open_object(const char *path, enum bpf_prog_type type,
+				  const char *sec)
 {
+	fprintf(stderr, "No ELF library support compiled in.\n");
 	errno = ENOSYS;
 	return -1;
 }
+
+static inline int bpf_handoff_map_fds(const char *path, const char *obj)
+{
+	return 0;
+}
 #endif /* HAVE_ELF */
 #endif /* _TC_BPF_H_ */