[v5,1/1] package/systemd: bump version to 242
diff mbox series

Message ID 20190618133830.22729-1-james.hilliard1@gmail.com
State Superseded, archived
Headers show
Series
  • [v5,1/1] package/systemd: bump version to 242
Related show

Commit Message

James Hilliard June 18, 2019, 1:38 p.m. UTC
Removed patches that have been committed upstream.

Backport patches required to build systemd on older kernels.

Added symlinks required to enable some services.

After extensive discussion with upstream it does not seem there is any
acceptable option to have symlink installation handled on their side.

The recommended solution from upstream is to have systemctl handle
service installation, however this has a number of downsides such as
requiring us to build a host-systemd just to install a few symlinks.

Since we already customize service installation it is simpler for us
to create the symlinks ourselves, this will also simplify service
customization on our side as we will not need to disable any systemd
default services in cases where we need to make customizations.

In addition using systemctl would introduce a minimum host headers
dependency in which we don't have the infrastructure to handle
properly.

The downside to this approach is that we need to track service creation
changes from upstream ourselves, however this is relatively straightforward
and since upstream service file locations are relatively stable regressions
should be limited. This will mostly be a concern in regards to adding
support for new systemd features.

Details:
https://github.com/systemd/systemd/issues/12767
https://github.com/systemd/systemd/pull/12164
https://github.com/systemd/systemd/pull/12769
https://github.com/systemd/systemd/pull/12775

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
 ...age-paths-longer-than-BUS_PATH_SIZE_.patch |    53 -
 ...everal-missing_-.h-and-import-releva.patch | 14874 ++++++++++++++++
 ...ry-strings-to-hold-dbus-paths-on-the.patch |   194 -
 ...vice.h-from-shared-linux-to-basic-li.patch |   190 +
 ...t-linux-in.h-and-in6.h-from-kernel-5.patch |   655 +
 ...drop-misplaced-Wl-undefined-argument.patch |    51 -
 ...x-also-import-l2tp.h-from-kernel-5.0.patch |   242 +
 package/systemd/systemd.hash                  |     2 +-
 package/systemd/systemd.mk                    |    73 +-
 9 files changed, 16031 insertions(+), 303 deletions(-)
 delete mode 100644 package/systemd/0002-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch
 create mode 100644 package/systemd/0002-tree-wide-drop-several-missing_-.h-and-import-releva.patch
 delete mode 100644 package/systemd/0003-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch
 create mode 100644 package/systemd/0003-linux-move-netdevice.h-from-shared-linux-to-basic-li.patch
 create mode 100644 package/systemd/0004-linux-also-import-linux-in.h-and-in6.h-from-kernel-5.patch
 delete mode 100644 package/systemd/0004-meson-drop-misplaced-Wl-undefined-argument.patch
 create mode 100644 package/systemd/0005-linux-also-import-l2tp.h-from-kernel-5.0.patch

Patch
diff mbox series

diff --git a/package/systemd/0002-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch b/package/systemd/0002-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch
deleted file mode 100644
index 2de3b71b5c..0000000000
--- a/package/systemd/0002-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch
+++ /dev/null
@@ -1,53 +0,0 @@ 
-From febef5e18558c114f4fb7c94f6c8ed3520c50cdf Mon Sep 17 00:00:00 2001
-From: Riccardo Schirone <rschiron@redhat.com>
-Date: Mon, 4 Feb 2019 14:29:09 +0100
-Subject: [PATCH] Refuse dbus message paths longer than BUS_PATH_SIZE_MAX
- limit.
-
-Even though the dbus specification does not enforce any length limit on the
-path of a dbus message, having to analyze too long strings in PID1 may be
-time-consuming and it may have security impacts.
-
-In any case, the limit is set so high that real-life applications should not
-have a problem with it.
-
-(cherry picked from commit 61397a60d98e368a5720b37e83f3169e3eb511c4)
-Signed-off-by: Baruch Siach <baruch@tkos.co.il>
----
-Upstream status: commit 61397a60d98
-
- src/libsystemd/sd-bus/bus-internal.c | 2 +-
- src/libsystemd/sd-bus/bus-internal.h | 4 ++++
- 2 files changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c
-index 40acae213381..598b7f110c73 100644
---- a/src/libsystemd/sd-bus/bus-internal.c
-+++ b/src/libsystemd/sd-bus/bus-internal.c
-@@ -43,7 +43,7 @@ bool object_path_is_valid(const char *p) {
-         if (slash)
-                 return false;
- 
--        return true;
-+        return (q - p) <= BUS_PATH_SIZE_MAX;
- }
- 
- char* object_path_startswith(const char *a, const char *b) {
-diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
-index f208b294d8f1..a8d61bf72a4e 100644
---- a/src/libsystemd/sd-bus/bus-internal.h
-+++ b/src/libsystemd/sd-bus/bus-internal.h
-@@ -332,6 +332,10 @@ struct sd_bus {
- 
- #define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
- #define BUS_AUTH_SIZE_MAX (64*1024)
-+/* Note that the D-Bus specification states that bus paths shall have no size limit. We enforce here one
-+ * anyway, since truly unbounded strings are a security problem. The limit we pick is relatively large however,
-+ * to not clash unnecessarily with real-life applications. */
-+#define BUS_PATH_SIZE_MAX (64*1024)
- 
- #define BUS_CONTAINER_DEPTH 128
- 
--- 
-2.20.1
-
diff --git a/package/systemd/0002-tree-wide-drop-several-missing_-.h-and-import-releva.patch b/package/systemd/0002-tree-wide-drop-several-missing_-.h-and-import-releva.patch
new file mode 100644
index 0000000000..89d991ec1b
--- /dev/null
+++ b/package/systemd/0002-tree-wide-drop-several-missing_-.h-and-import-releva.patch
@@ -0,0 +1,14874 @@ 
+From 01234e1fe777602265ffd25ab6e73823c62b0efe Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Wed, 10 Apr 2019 19:55:53 +0900
+Subject: [PATCH] tree-wide: drop several missing_*.h and import relevant
+ headers from kernel-5.0
+
+[james.hilliard1@gmail.com: backport from upstream commit
+01234e1fe777602265ffd25ab6e73823c62b0efe]
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+---
+ meson.build                                |   93 -
+ src/basic/arphrd-list.c                    |    3 +-
+ src/basic/btrfs-util.c                     |    3 +-
+ src/basic/generate-arphrd-list.sh          |    2 +-
+ src/basic/linux/README                     |    3 +
+ src/basic/linux/btrfs.h                    |  945 ++++++
+ src/basic/linux/btrfs_tree.h               |  974 ++++++
+ src/basic/linux/can/vxcan.h                |   13 +
+ src/basic/linux/fib_rules.h                |   90 +
+ src/basic/linux/fou.h                      |   42 +
+ src/basic/linux/if.h                       |  294 ++
+ src/basic/linux/if_addr.h                  |   72 +
+ src/basic/linux/if_arp.h                   |  164 +
+ src/basic/linux/if_bonding.h               |  131 +
+ src/basic/linux/if_bridge.h                |  316 ++
+ src/basic/linux/if_link.h                  | 1024 ++++++
+ src/basic/linux/if_tun.h                   |  113 +
+ src/basic/linux/if_tunnel.h                |  183 +
+ src/basic/linux/libc-compat.h              |  267 ++
+ src/basic/linux/netlink.h                  |  252 ++
+ src/basic/linux/rtnetlink.h                |  751 +++++
+ src/basic/linux/wireguard.h                |  190 ++
+ src/basic/meson.build                      |   29 +-
+ src/basic/missing.h                        |    1 -
+ src/basic/missing_btrfs.h                  |   22 -
+ src/basic/missing_btrfs_tree.h             |  109 -
+ src/basic/missing_ethtool.h                |  131 -
+ src/basic/missing_fib_rules.h              |   45 -
+ src/basic/missing_fou.h                    |   55 -
+ src/basic/missing_if_bridge.h              |   21 -
+ src/basic/missing_if_link.h                |  393 ---
+ src/basic/missing_if_tunnel.h              |   59 -
+ src/basic/missing_network.h                |  144 +-
+ src/basic/missing_vxcan.h                  |   12 -
+ src/core/bpf-devices.c                     |    2 +-
+ src/core/bpf-firewall.c                    |    2 +-
+ src/libsystemd/sd-netlink/netlink-types.c  |   12 +-
+ src/network/netdev/fou-tunnel.h            |    3 -
+ src/network/netdev/ipvlan.h                |    1 -
+ src/network/netdev/tunnel.c                |    6 +-
+ src/network/netdev/vxcan.c                 |    3 -
+ src/network/netdev/wireguard.c             |    1 -
+ src/network/netdev/wireguard.h             |    3 +-
+ src/network/networkd-brvlan.c              |    1 -
+ src/network/networkd-network.c             |    4 +-
+ src/network/networkd-routing-policy-rule.h |    1 -
+ src/partition/growfs.c                     |    1 +
+ src/resolve/resolved-link.c                |    3 +-
+ src/shared/dissect-image.c                 |    3 +-
+ src/shared/linux-3.13/dm-ioctl.h           |  355 --
+ src/shared/linux/README                    |    8 +
+ src/shared/linux/auto_dev-ioctl.h          |   33 +-
+ src/shared/linux/bpf.h                     | 3536 +++++++++++++++-----
+ src/shared/linux/bpf_common.h              |   14 +-
+ src/shared/linux/bpf_insn.h                |  205 ++
+ src/shared/linux/dm-ioctl.h                |  363 ++
+ src/shared/linux/ethtool.h                 | 1843 ++++++++++
+ src/shared/linux/libbpf.h                  |  207 --
+ src/shared/linux/netdevice.h               |   66 +
+ src/shared/meson.build                     |    8 +-
+ src/shared/wireguard-netlink.h             |  179 -
+ src/shutdown/umount.c                      |    2 +-
+ src/test/test-arphrd-list.c                |    3 +-
+ src/test/test-bpf.c                        |    2 +-
+ src/test/test-netlink-manual.c             |    3 +-
+ src/udev/net/ethtool-util.h                |    1 -
+ src/udev/net/link-config.c                 |    2 +-
+ src/udev/udev-builtin-btrfs.c              |    2 +-
+ 68 files changed, 11124 insertions(+), 2700 deletions(-)
+ create mode 100644 src/basic/linux/README
+ create mode 100644 src/basic/linux/btrfs.h
+ create mode 100644 src/basic/linux/btrfs_tree.h
+ create mode 100644 src/basic/linux/can/vxcan.h
+ create mode 100644 src/basic/linux/fib_rules.h
+ create mode 100644 src/basic/linux/fou.h
+ create mode 100644 src/basic/linux/if.h
+ create mode 100644 src/basic/linux/if_addr.h
+ create mode 100644 src/basic/linux/if_arp.h
+ create mode 100644 src/basic/linux/if_bonding.h
+ create mode 100644 src/basic/linux/if_bridge.h
+ create mode 100644 src/basic/linux/if_link.h
+ create mode 100644 src/basic/linux/if_tun.h
+ create mode 100644 src/basic/linux/if_tunnel.h
+ create mode 100644 src/basic/linux/libc-compat.h
+ create mode 100644 src/basic/linux/netlink.h
+ create mode 100644 src/basic/linux/rtnetlink.h
+ create mode 100644 src/basic/linux/wireguard.h
+ delete mode 100644 src/basic/missing_btrfs.h
+ delete mode 100644 src/basic/missing_btrfs_tree.h
+ delete mode 100644 src/basic/missing_ethtool.h
+ delete mode 100644 src/basic/missing_fib_rules.h
+ delete mode 100644 src/basic/missing_fou.h
+ delete mode 100644 src/basic/missing_if_bridge.h
+ delete mode 100644 src/basic/missing_if_link.h
+ delete mode 100644 src/basic/missing_if_tunnel.h
+ delete mode 100644 src/basic/missing_vxcan.h
+ delete mode 100644 src/shared/linux-3.13/dm-ioctl.h
+ create mode 100644 src/shared/linux/README
+ create mode 100644 src/shared/linux/bpf_insn.h
+ create mode 100644 src/shared/linux/dm-ioctl.h
+ create mode 100644 src/shared/linux/ethtool.h
+ delete mode 100644 src/shared/linux/libbpf.h
+ create mode 100644 src/shared/linux/netdevice.h
+ delete mode 100644 src/shared/wireguard-netlink.h
+
+diff --git a/meson.build b/meson.build
+index 79195c9748..15e3394b91 100644
+--- a/meson.build
++++ b/meson.build
+@@ -454,96 +454,6 @@ endforeach
+ 
+ conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
+ 
+-foreach decl : [['ETHTOOL_LINK_MODE_10baseT_Half_BIT',      'linux/ethtool.h'],
+-                ['ETHTOOL_LINK_MODE_25000baseCR_Full_BIT',  'linux/ethtool.h'],
+-                ['ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT', 'linux/ethtool.h'],
+-                ['ETHTOOL_LINK_MODE_1000baseX_Full_BIT',    'linux/ethtool.h'],
+-                ['ETHTOOL_LINK_MODE_2500baseT_Full_BIT',    'linux/ethtool.h'],
+-                ['ETHTOOL_LINK_MODE_FEC_NONE_BIT',          'linux/ethtool.h'],
+-                ['FRA_TUN_ID',                              'linux/fib_rules.h'],
+-                ['FRA_SUPPRESS_PREFIXLEN',                  'linux/fib_rules.h'],
+-                ['FRA_PAD',                                 'linux/fib_rules.h'],
+-                ['FRA_L3MDEV',                              'linux/fib_rules.h'],
+-                ['FRA_UID_RANGE',                           'linux/fib_rules.h'],
+-                ['FRA_DPORT_RANGE',                         'linux/fib_rules.h'],
+-                ['FOU_ATTR_REMCSUM_NOPARTIAL',              'linux/fou.h'],
+-                ['FOU_CMD_GET',                             'linux/fou.h'],
+-                ['IFA_FLAGS',                               'linux/if_addr.h'],
+-                ['IFLA_BRIDGE_VLAN_TUNNEL_INFO',            'linux/if_bridge.h'],
+-                ['IFLA_INET6_ADDR_GEN_MODE',                'linux/if_link.h'],
+-                ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY',        'linux/if_link.h'],
+-                ['IN6_ADDR_GEN_MODE_RANDOM',                'linux/if_link.h'],
+-                ['IFLA_IPVLAN_MODE',                        'linux/if_link.h'],
+-                ['IPVLAN_MODE_L3S',                         'linux/if_link.h'],
+-                ['IFLA_IPVLAN_FLAGS',                       'linux/if_link.h'],
+-                ['IFLA_PHYS_PORT_ID',                       'linux/if_link.h'],
+-                ['IFLA_CARRIER_CHANGES',                    'linux/if_link.h'],
+-                ['IFLA_PHYS_SWITCH_ID',                     'linux/if_link.h'],
+-                ['IFLA_LINK_NETNSID',                       'linux/if_link.h'],
+-                ['IFLA_PHYS_PORT_NAME',                     'linux/if_link.h'],
+-                ['IFLA_PROTO_DOWN',                         'linux/if_link.h'],
+-                ['IFLA_GSO_MAX_SIZE',                       'linux/if_link.h'],
+-                ['IFLA_PAD',                                'linux/if_link.h'],
+-                ['IFLA_XDP',                                'linux/if_link.h'],
+-                ['IFLA_EVENT',                              'linux/if_link.h'],
+-                ['IFLA_IF_NETNSID',                         'linux/if_link.h'],
+-                ['IFLA_TARGET_NETNSID',                     'linux/if_link.h'],
+-                ['IFLA_NEW_IFINDEX',                        'linux/if_link.h'],
+-                ['IFLA_MAX_MTU',                            'linux/if_link.h'],
+-                ['IFLA_BOND_MODE',                          'linux/if_link.h'],
+-                ['IFLA_BOND_ACTIVE_SLAVE',                  'linux/if_link.h'],
+-                ['IFLA_BOND_AD_INFO',                       'linux/if_link.h'],
+-                ['IFLA_BOND_AD_ACTOR_SYSTEM',               'linux/if_link.h'],
+-                ['IFLA_BOND_TLB_DYNAMIC_LB',                'linux/if_link.h'],
+-                ['IFLA_VXLAN_UDP_ZERO_CSUM6_RX',            'linux/if_link.h'],
+-                ['IFLA_VXLAN_REMCSUM_NOPARTIAL',            'linux/if_link.h'],
+-                ['IFLA_VXLAN_COLLECT_METADATA',             'linux/if_link.h'],
+-                ['IFLA_VXLAN_LABEL',                        'linux/if_link.h'],
+-                ['IFLA_VXLAN_GPE',                          'linux/if_link.h'],
+-                ['IFLA_VXLAN_TTL_INHERIT',                  'linux/if_link.h'],
+-                ['IFLA_GENEVE_TOS',                         'linux/if_link.h'],
+-                ['IFLA_GENEVE_COLLECT_METADATA',            'linux/if_link.h'],
+-                ['IFLA_GENEVE_REMOTE6',                     'linux/if_link.h'],
+-                ['IFLA_GENEVE_UDP_ZERO_CSUM6_RX',           'linux/if_link.h'],
+-                ['IFLA_GENEVE_LABEL',                       'linux/if_link.h'],
+-                ['IFLA_GENEVE_TTL_INHERIT',                 'linux/if_link.h'],
+-                ['IFLA_BR_MAX_AGE',                         'linux/if_link.h'],
+-                ['IFLA_BR_PRIORITY',                        'linux/if_link.h'],
+-                ['IFLA_BR_VLAN_PROTOCOL',                   'linux/if_link.h'],
+-                ['IFLA_BR_VLAN_DEFAULT_PVID',               'linux/if_link.h'],
+-                ['IFLA_BR_VLAN_STATS_ENABLED',              'linux/if_link.h'],
+-                ['IFLA_BR_MCAST_STATS_ENABLED',             'linux/if_link.h'],
+-                ['IFLA_BR_MCAST_MLD_VERSION',               'linux/if_link.h'],
+-                ['IFLA_BR_VLAN_STATS_PER_PORT',             'linux/if_link.h'],
+-                ['IFLA_BRPORT_LEARNING_SYNC',               'linux/if_link.h'],
+-                ['IFLA_BRPORT_PROXYARP_WIFI',               'linux/if_link.h'],
+-                ['IFLA_BRPORT_MULTICAST_ROUTER',            'linux/if_link.h'],
+-                ['IFLA_BRPORT_PAD',                         'linux/if_link.h'],
+-                ['IFLA_BRPORT_MCAST_FLOOD',                 'linux/if_link.h'],
+-                ['IFLA_BRPORT_VLAN_TUNNEL',                 'linux/if_link.h'],
+-                ['IFLA_BRPORT_BCAST_FLOOD',                 'linux/if_link.h'],
+-                ['IFLA_BRPORT_NEIGH_SUPPRESS',              'linux/if_link.h'],
+-                ['IFLA_BRPORT_ISOLATED',                    'linux/if_link.h'],
+-                ['IFLA_BRPORT_BACKUP_PORT',                 'linux/if_link.h'],
+-                ['IFLA_VRF_TABLE',                          'linux/if_link.h'],
+-                # if_tunnel.h is buggy and cannot be included on its own
+-                ['IFLA_VTI_FWMARK',                         'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_IPTUN_ENCAP_DPORT',                  'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_IPTUN_COLLECT_METADATA',             'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_IPTUN_FWMARK',                       'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_ENCAP_DPORT',                    'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_COLLECT_METADATA',               'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_IGNORE_DF',                      'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_FWMARK',                         'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_ERSPAN_INDEX',                   'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['IFLA_GRE_ERSPAN_HWID',                    'linux/if_tunnel.h', '#include <net/if.h>'],
+-                ['LO_FLAGS_PARTSCAN',                       'linux/loop.h'],
+-               ]
+-        prefix = decl.length() > 2 ? decl[2] : ''
+-        have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
+-        conf.set10('HAVE_' + decl[0], have)
+-endforeach
+-
+ foreach ident : ['secure_getenv', '__secure_getenv']
+         conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
+ endforeach
+@@ -680,11 +590,8 @@ if not cc.has_header('sys/capability.h')
+         error('POSIX caps headers not found')
+ endif
+ foreach header : ['crypt.h',
+-                  'linux/btrfs_tree.h',
+-                  'linux/fou.h',
+                   'linux/memfd.h',
+                   'linux/vm_sockets.h',
+-                  'linux/can/vxcan.h',
+                   'sys/auxv.h',
+                   'valgrind/memcheck.h',
+                   'valgrind/valgrind.h',
+diff --git a/src/basic/arphrd-list.c b/src/basic/arphrd-list.c
+index b6e2486b67..b9a9cb7ed4 100644
+--- a/src/basic/arphrd-list.c
++++ b/src/basic/arphrd-list.c
+@@ -1,12 +1,11 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include <errno.h>
+-#include <net/if_arp.h>
++#include <linux/if_arp.h>
+ #include <string.h>
+ 
+ #include "arphrd-list.h"
+ #include "macro.h"
+-#include "missing_network.h"
+ 
+ static const struct arphrd_name* lookup_arphrd(register const char *str, register GPERF_LEN_TYPE len);
+ 
+diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
+index b1519cc4eb..db6c0c3f1e 100644
+--- a/src/basic/btrfs-util.c
++++ b/src/basic/btrfs-util.c
+@@ -3,8 +3,10 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <inttypes.h>
++#include <linux/btrfs_tree.h>
+ #include <linux/fs.h>
+ #include <linux/loop.h>
++#include <linux/magic.h>
+ #include <stddef.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -26,7 +28,6 @@
+ #include "fs-util.h"
+ #include "io-util.h"
+ #include "macro.h"
+-#include "missing.h"
+ #include "path-util.h"
+ #include "rm-rf.h"
+ #include "smack-util.h"
+diff --git a/src/basic/generate-arphrd-list.sh b/src/basic/generate-arphrd-list.sh
+index e6e874a8fd..6db931c52b 100755
+--- a/src/basic/generate-arphrd-list.sh
++++ b/src/basic/generate-arphrd-list.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ set -eu
+ 
+-$1 -dM -include net/if_arp.h -include "$2" -include "$3" - </dev/null | \
++$1 -dM -include linux/if_arp.h -include "$2" - </dev/null | \
+         awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
+         sed -e 's/ARPHRD_//'
+diff --git a/src/basic/linux/README b/src/basic/linux/README
+new file mode 100644
+index 0000000000..f849f34951
+--- /dev/null
++++ b/src/basic/linux/README
+@@ -0,0 +1,3 @@
++The files in this directory are copied from kernel-5.0, and the following modifications are applied:
++- btrfs.h: drop '__user' attributes
++- if.h: drop '#include <linux/compiler.h>' and '__user' attributes
+diff --git a/src/basic/linux/btrfs.h b/src/basic/linux/btrfs.h
+new file mode 100644
+index 0000000000..22455c4cd7
+--- /dev/null
++++ b/src/basic/linux/btrfs.h
+@@ -0,0 +1,945 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/*
++ * Copyright (C) 2007 Oracle.  All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public
++ * License v2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 021110-1307, USA.
++ */
++
++#ifndef _UAPI_LINUX_BTRFS_H
++#define _UAPI_LINUX_BTRFS_H
++#include <linux/types.h>
++#include <linux/ioctl.h>
++
++#define BTRFS_IOCTL_MAGIC 0x94
++#define BTRFS_VOL_NAME_MAX 255
++#define BTRFS_LABEL_SIZE 256
++
++/* this should be 4k */
++#define BTRFS_PATH_NAME_MAX 4087
++struct btrfs_ioctl_vol_args {
++	__s64 fd;
++	char name[BTRFS_PATH_NAME_MAX + 1];
++};
++
++#define BTRFS_DEVICE_PATH_NAME_MAX	1024
++#define BTRFS_SUBVOL_NAME_MAX 		4039
++
++#define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
++#define BTRFS_SUBVOL_RDONLY		(1ULL << 1)
++#define BTRFS_SUBVOL_QGROUP_INHERIT	(1ULL << 2)
++
++#define BTRFS_DEVICE_SPEC_BY_ID		(1ULL << 3)
++
++#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED		\
++			(BTRFS_SUBVOL_CREATE_ASYNC |	\
++			BTRFS_SUBVOL_RDONLY |		\
++			BTRFS_SUBVOL_QGROUP_INHERIT |	\
++			BTRFS_DEVICE_SPEC_BY_ID)
++
++#define BTRFS_FSID_SIZE 16
++#define BTRFS_UUID_SIZE 16
++#define BTRFS_UUID_UNPARSED_SIZE	37
++
++/*
++ * flags definition for qgroup limits
++ *
++ * Used by:
++ * struct btrfs_qgroup_limit.flags
++ * struct btrfs_qgroup_limit_item.flags
++ */
++#define BTRFS_QGROUP_LIMIT_MAX_RFER	(1ULL << 0)
++#define BTRFS_QGROUP_LIMIT_MAX_EXCL	(1ULL << 1)
++#define BTRFS_QGROUP_LIMIT_RSV_RFER	(1ULL << 2)
++#define BTRFS_QGROUP_LIMIT_RSV_EXCL	(1ULL << 3)
++#define BTRFS_QGROUP_LIMIT_RFER_CMPR	(1ULL << 4)
++#define BTRFS_QGROUP_LIMIT_EXCL_CMPR	(1ULL << 5)
++
++struct btrfs_qgroup_limit {
++	__u64	flags;
++	__u64	max_rfer;
++	__u64	max_excl;
++	__u64	rsv_rfer;
++	__u64	rsv_excl;
++};
++
++/*
++ * flags definition for qgroup inheritance
++ *
++ * Used by:
++ * struct btrfs_qgroup_inherit.flags
++ */
++#define BTRFS_QGROUP_INHERIT_SET_LIMITS	(1ULL << 0)
++
++struct btrfs_qgroup_inherit {
++	__u64	flags;
++	__u64	num_qgroups;
++	__u64	num_ref_copies;
++	__u64	num_excl_copies;
++	struct btrfs_qgroup_limit lim;
++	__u64	qgroups[0];
++};
++
++struct btrfs_ioctl_qgroup_limit_args {
++	__u64	qgroupid;
++	struct btrfs_qgroup_limit lim;
++};
++
++/*
++ * flags for subvolumes
++ *
++ * Used by:
++ * struct btrfs_ioctl_vol_args_v2.flags
++ *
++ * BTRFS_SUBVOL_RDONLY is also provided/consumed by the following ioctls:
++ * - BTRFS_IOC_SUBVOL_GETFLAGS
++ * - BTRFS_IOC_SUBVOL_SETFLAGS
++ */
++
++struct btrfs_ioctl_vol_args_v2 {
++	__s64 fd;
++	__u64 transid;
++	__u64 flags;
++	union {
++		struct {
++			__u64 size;
++			struct btrfs_qgroup_inherit *qgroup_inherit;
++		};
++		__u64 unused[4];
++	};
++	union {
++		char name[BTRFS_SUBVOL_NAME_MAX + 1];
++		__u64 devid;
++	};
++};
++
++/*
++ * structure to report errors and progress to userspace, either as a
++ * result of a finished scrub, a canceled scrub or a progress inquiry
++ */
++struct btrfs_scrub_progress {
++	__u64 data_extents_scrubbed;	/* # of data extents scrubbed */
++	__u64 tree_extents_scrubbed;	/* # of tree extents scrubbed */
++	__u64 data_bytes_scrubbed;	/* # of data bytes scrubbed */
++	__u64 tree_bytes_scrubbed;	/* # of tree bytes scrubbed */
++	__u64 read_errors;		/* # of read errors encountered (EIO) */
++	__u64 csum_errors;		/* # of failed csum checks */
++	__u64 verify_errors;		/* # of occurences, where the metadata
++					 * of a tree block did not match the
++					 * expected values, like generation or
++					 * logical */
++	__u64 no_csum;			/* # of 4k data block for which no csum
++					 * is present, probably the result of
++					 * data written with nodatasum */
++	__u64 csum_discards;		/* # of csum for which no data was found
++					 * in the extent tree. */
++	__u64 super_errors;		/* # of bad super blocks encountered */
++	__u64 malloc_errors;		/* # of internal kmalloc errors. These
++					 * will likely cause an incomplete
++					 * scrub */
++	__u64 uncorrectable_errors;	/* # of errors where either no intact
++					 * copy was found or the writeback
++					 * failed */
++	__u64 corrected_errors;		/* # of errors corrected */
++	__u64 last_physical;		/* last physical address scrubbed. In
++					 * case a scrub was aborted, this can
++					 * be used to restart the scrub */
++	__u64 unverified_errors;	/* # of occurences where a read for a
++					 * full (64k) bio failed, but the re-
++					 * check succeeded for each 4k piece.
++					 * Intermittent error. */
++};
++
++#define BTRFS_SCRUB_READONLY	1
++struct btrfs_ioctl_scrub_args {
++	__u64 devid;				/* in */
++	__u64 start;				/* in */
++	__u64 end;				/* in */
++	__u64 flags;				/* in */
++	struct btrfs_scrub_progress progress;	/* out */
++	/* pad to 1k */
++	__u64 unused[(1024-32-sizeof(struct btrfs_scrub_progress))/8];
++};
++
++#define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS	0
++#define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID	1
++struct btrfs_ioctl_dev_replace_start_params {
++	__u64 srcdevid;	/* in, if 0, use srcdev_name instead */
++	__u64 cont_reading_from_srcdev_mode;	/* in, see #define
++						 * above */
++	__u8 srcdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];	/* in */
++	__u8 tgtdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];	/* in */
++};
++
++#define BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED	0
++#define BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED		1
++#define BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED		2
++#define BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED		3
++#define BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED		4
++struct btrfs_ioctl_dev_replace_status_params {
++	__u64 replace_state;	/* out, see #define above */
++	__u64 progress_1000;	/* out, 0 <= x <= 1000 */
++	__u64 time_started;	/* out, seconds since 1-Jan-1970 */
++	__u64 time_stopped;	/* out, seconds since 1-Jan-1970 */
++	__u64 num_write_errors;	/* out */
++	__u64 num_uncorrectable_read_errors;	/* out */
++};
++
++#define BTRFS_IOCTL_DEV_REPLACE_CMD_START			0
++#define BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS			1
++#define BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL			2
++#define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR			0
++#define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED		1
++#define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED		2
++#define BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS		3
++struct btrfs_ioctl_dev_replace_args {
++	__u64 cmd;	/* in */
++	__u64 result;	/* out */
++
++	union {
++		struct btrfs_ioctl_dev_replace_start_params start;
++		struct btrfs_ioctl_dev_replace_status_params status;
++	};	/* in/out */
++
++	__u64 spare[64];
++};
++
++struct btrfs_ioctl_dev_info_args {
++	__u64 devid;				/* in/out */
++	__u8 uuid[BTRFS_UUID_SIZE];		/* in/out */
++	__u64 bytes_used;			/* out */
++	__u64 total_bytes;			/* out */
++	__u64 unused[379];			/* pad to 4k */
++	__u8 path[BTRFS_DEVICE_PATH_NAME_MAX];	/* out */
++};
++
++struct btrfs_ioctl_fs_info_args {
++	__u64 max_id;				/* out */
++	__u64 num_devices;			/* out */
++	__u8 fsid[BTRFS_FSID_SIZE];		/* out */
++	__u32 nodesize;				/* out */
++	__u32 sectorsize;			/* out */
++	__u32 clone_alignment;			/* out */
++	__u32 reserved32;
++	__u64 reserved[122];			/* pad to 1k */
++};
++
++/*
++ * feature flags
++ *
++ * Used by:
++ * struct btrfs_ioctl_feature_flags
++ */
++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE		(1ULL << 0)
++/*
++ * Older kernels (< 4.9) on big-endian systems produced broken free space tree
++ * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions
++ * < 4.7.3).  If this bit is clear, then the free space tree cannot be trusted.
++ * btrfs-progs can also intentionally clear this bit to ask the kernel to
++ * rebuild the free space tree, however this might not work on older kernels
++ * that do not know about this bit. If not sure, clear the cache manually on
++ * first mount when booting older kernel versions.
++ */
++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID	(1ULL << 1)
++
++#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0)
++#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(1ULL << 1)
++#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS	(1ULL << 2)
++#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO	(1ULL << 3)
++#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD	(1ULL << 4)
++
++/*
++ * older kernels tried to do bigger metadata blocks, but the
++ * code was pretty buggy.  Lets not let them try anymore.
++ */
++#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA	(1ULL << 5)
++
++#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF	(1ULL << 6)
++#define BTRFS_FEATURE_INCOMPAT_RAID56		(1ULL << 7)
++#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA	(1ULL << 8)
++#define BTRFS_FEATURE_INCOMPAT_NO_HOLES		(1ULL << 9)
++#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID	(1ULL << 10)
++
++struct btrfs_ioctl_feature_flags {
++	__u64 compat_flags;
++	__u64 compat_ro_flags;
++	__u64 incompat_flags;
++};
++
++/* balance control ioctl modes */
++#define BTRFS_BALANCE_CTL_PAUSE		1
++#define BTRFS_BALANCE_CTL_CANCEL	2
++
++/*
++ * this is packed, because it should be exactly the same as its disk
++ * byte order counterpart (struct btrfs_disk_balance_args)
++ */
++struct btrfs_balance_args {
++	__u64 profiles;
++	union {
++		__u64 usage;
++		struct {
++			__u32 usage_min;
++			__u32 usage_max;
++		};
++	};
++	__u64 devid;
++	__u64 pstart;
++	__u64 pend;
++	__u64 vstart;
++	__u64 vend;
++
++	__u64 target;
++
++	__u64 flags;
++
++	/*
++	 * BTRFS_BALANCE_ARGS_LIMIT with value 'limit'
++	 * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum
++	 * and maximum
++	 */
++	union {
++		__u64 limit;		/* limit number of processed chunks */
++		struct {
++			__u32 limit_min;
++			__u32 limit_max;
++		};
++	};
++
++	/*
++	 * Process chunks that cross stripes_min..stripes_max devices,
++	 * BTRFS_BALANCE_ARGS_STRIPES_RANGE
++	 */
++	__u32 stripes_min;
++	__u32 stripes_max;
++
++	__u64 unused[6];
++} __attribute__ ((__packed__));
++
++/* report balance progress to userspace */
++struct btrfs_balance_progress {
++	__u64 expected;		/* estimated # of chunks that will be
++				 * relocated to fulfill the request */
++	__u64 considered;	/* # of chunks we have considered so far */
++	__u64 completed;	/* # of chunks relocated so far */
++};
++
++/*
++ * flags definition for balance
++ *
++ * Restriper's general type filter
++ *
++ * Used by:
++ * btrfs_ioctl_balance_args.flags
++ * btrfs_balance_control.flags (internal)
++ */
++#define BTRFS_BALANCE_DATA		(1ULL << 0)
++#define BTRFS_BALANCE_SYSTEM		(1ULL << 1)
++#define BTRFS_BALANCE_METADATA		(1ULL << 2)
++
++#define BTRFS_BALANCE_TYPE_MASK		(BTRFS_BALANCE_DATA |	    \
++					 BTRFS_BALANCE_SYSTEM |	    \
++					 BTRFS_BALANCE_METADATA)
++
++#define BTRFS_BALANCE_FORCE		(1ULL << 3)
++#define BTRFS_BALANCE_RESUME		(1ULL << 4)
++
++/*
++ * flags definitions for per-type balance args
++ *
++ * Balance filters
++ *
++ * Used by:
++ * struct btrfs_balance_args
++ */
++#define BTRFS_BALANCE_ARGS_PROFILES	(1ULL << 0)
++#define BTRFS_BALANCE_ARGS_USAGE	(1ULL << 1)
++#define BTRFS_BALANCE_ARGS_DEVID	(1ULL << 2)
++#define BTRFS_BALANCE_ARGS_DRANGE	(1ULL << 3)
++#define BTRFS_BALANCE_ARGS_VRANGE	(1ULL << 4)
++#define BTRFS_BALANCE_ARGS_LIMIT	(1ULL << 5)
++#define BTRFS_BALANCE_ARGS_LIMIT_RANGE	(1ULL << 6)
++#define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7)
++#define BTRFS_BALANCE_ARGS_USAGE_RANGE	(1ULL << 10)
++
++#define BTRFS_BALANCE_ARGS_MASK			\
++	(BTRFS_BALANCE_ARGS_PROFILES |		\
++	 BTRFS_BALANCE_ARGS_USAGE |		\
++	 BTRFS_BALANCE_ARGS_DEVID | 		\
++	 BTRFS_BALANCE_ARGS_DRANGE |		\
++	 BTRFS_BALANCE_ARGS_VRANGE |		\
++	 BTRFS_BALANCE_ARGS_LIMIT |		\
++	 BTRFS_BALANCE_ARGS_LIMIT_RANGE |	\
++	 BTRFS_BALANCE_ARGS_STRIPES_RANGE |	\
++	 BTRFS_BALANCE_ARGS_USAGE_RANGE)
++
++/*
++ * Profile changing flags.  When SOFT is set we won't relocate chunk if
++ * it already has the target profile (even though it may be
++ * half-filled).
++ */
++#define BTRFS_BALANCE_ARGS_CONVERT	(1ULL << 8)
++#define BTRFS_BALANCE_ARGS_SOFT		(1ULL << 9)
++
++
++/*
++ * flags definition for balance state
++ *
++ * Used by:
++ * struct btrfs_ioctl_balance_args.state
++ */
++#define BTRFS_BALANCE_STATE_RUNNING	(1ULL << 0)
++#define BTRFS_BALANCE_STATE_PAUSE_REQ	(1ULL << 1)
++#define BTRFS_BALANCE_STATE_CANCEL_REQ	(1ULL << 2)
++
++struct btrfs_ioctl_balance_args {
++	__u64 flags;				/* in/out */
++	__u64 state;				/* out */
++
++	struct btrfs_balance_args data;		/* in/out */
++	struct btrfs_balance_args meta;		/* in/out */
++	struct btrfs_balance_args sys;		/* in/out */
++
++	struct btrfs_balance_progress stat;	/* out */
++
++	__u64 unused[72];			/* pad to 1k */
++};
++
++#define BTRFS_INO_LOOKUP_PATH_MAX 4080
++struct btrfs_ioctl_ino_lookup_args {
++	__u64 treeid;
++	__u64 objectid;
++	char name[BTRFS_INO_LOOKUP_PATH_MAX];
++};
++
++#define BTRFS_INO_LOOKUP_USER_PATH_MAX (4080 - BTRFS_VOL_NAME_MAX - 1)
++struct btrfs_ioctl_ino_lookup_user_args {
++	/* in, inode number containing the subvolume of 'subvolid' */
++	__u64 dirid;
++	/* in */
++	__u64 treeid;
++	/* out, name of the subvolume of 'treeid' */
++	char name[BTRFS_VOL_NAME_MAX + 1];
++	/*
++	 * out, constructed path from the directory with which the ioctl is
++	 * called to dirid
++	 */
++	char path[BTRFS_INO_LOOKUP_USER_PATH_MAX];
++};
++
++/* Search criteria for the btrfs SEARCH ioctl family. */
++struct btrfs_ioctl_search_key {
++	/*
++	 * The tree we're searching in. 1 is the tree of tree roots, 2 is the
++	 * extent tree, etc...
++	 *
++	 * A special tree_id value of 0 will cause a search in the subvolume
++	 * tree that the inode which is passed to the ioctl is part of.
++	 */
++	__u64 tree_id;		/* in */
++
++	/*
++	 * When doing a tree search, we're actually taking a slice from a
++	 * linear search space of 136-bit keys.
++	 *
++	 * A full 136-bit tree key is composed as:
++	 *   (objectid << 72) + (type << 64) + offset
++	 *
++	 * The individual min and max values for objectid, type and offset
++	 * define the min_key and max_key values for the search range. All
++	 * metadata items with a key in the interval [min_key, max_key] will be
++	 * returned.
++	 *
++	 * Additionally, we can filter the items returned on transaction id of
++	 * the metadata block they're stored in by specifying a transid range.
++	 * Be aware that this transaction id only denotes when the metadata
++	 * page that currently contains the item got written the last time as
++	 * result of a COW operation.  The number does not have any meaning
++	 * related to the transaction in which an individual item that is being
++	 * returned was created or changed.
++	 */
++	__u64 min_objectid;	/* in */
++	__u64 max_objectid;	/* in */
++	__u64 min_offset;	/* in */
++	__u64 max_offset;	/* in */
++	__u64 min_transid;	/* in */
++	__u64 max_transid;	/* in */
++	__u32 min_type;		/* in */
++	__u32 max_type;		/* in */
++
++	/*
++	 * input: The maximum amount of results desired.
++	 * output: The actual amount of items returned, restricted by any of:
++	 *  - reaching the upper bound of the search range
++	 *  - reaching the input nr_items amount of items
++	 *  - completely filling the supplied memory buffer
++	 */
++	__u32 nr_items;		/* in/out */
++
++	/* align to 64 bits */
++	__u32 unused;
++
++	/* some extra for later */
++	__u64 unused1;
++	__u64 unused2;
++	__u64 unused3;
++	__u64 unused4;
++};
++
++struct btrfs_ioctl_search_header {
++	__u64 transid;
++	__u64 objectid;
++	__u64 offset;
++	__u32 type;
++	__u32 len;
++};
++
++#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
++/*
++ * the buf is an array of search headers where
++ * each header is followed by the actual item
++ * the type field is expanded to 32 bits for alignment
++ */
++struct btrfs_ioctl_search_args {
++	struct btrfs_ioctl_search_key key;
++	char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
++};
++
++struct btrfs_ioctl_search_args_v2 {
++	struct btrfs_ioctl_search_key key; /* in/out - search parameters */
++	__u64 buf_size;		   /* in - size of buffer
++					    * out - on EOVERFLOW: needed size
++					    *       to store item */
++	__u64 buf[0];                       /* out - found items */
++};
++
++struct btrfs_ioctl_clone_range_args {
++  __s64 src_fd;
++  __u64 src_offset, src_length;
++  __u64 dest_offset;
++};
++
++/*
++ * flags definition for the defrag range ioctl
++ *
++ * Used by:
++ * struct btrfs_ioctl_defrag_range_args.flags
++ */
++#define BTRFS_DEFRAG_RANGE_COMPRESS 1
++#define BTRFS_DEFRAG_RANGE_START_IO 2
++struct btrfs_ioctl_defrag_range_args {
++	/* start of the defrag operation */
++	__u64 start;
++
++	/* number of bytes to defrag, use (u64)-1 to say all */
++	__u64 len;
++
++	/*
++	 * flags for the operation, which can include turning
++	 * on compression for this one defrag
++	 */
++	__u64 flags;
++
++	/*
++	 * any extent bigger than this will be considered
++	 * already defragged.  Use 0 to take the kernel default
++	 * Use 1 to say every single extent must be rewritten
++	 */
++	__u32 extent_thresh;
++
++	/*
++	 * which compression method to use if turning on compression
++	 * for this defrag operation.  If unspecified, zlib will
++	 * be used
++	 */
++	__u32 compress_type;
++
++	/* spare for later */
++	__u32 unused[4];
++};
++
++
++#define BTRFS_SAME_DATA_DIFFERS	1
++/* For extent-same ioctl */
++struct btrfs_ioctl_same_extent_info {
++	__s64 fd;		/* in - destination file */
++	__u64 logical_offset;	/* in - start of extent in destination */
++	__u64 bytes_deduped;	/* out - total # of bytes we were able
++				 * to dedupe from this file */
++	/* status of this dedupe operation:
++	 * 0 if dedup succeeds
++	 * < 0 for error
++	 * == BTRFS_SAME_DATA_DIFFERS if data differs
++	 */
++	__s32 status;		/* out - see above description */
++	__u32 reserved;
++};
++
++struct btrfs_ioctl_same_args {
++	__u64 logical_offset;	/* in - start of extent in source */
++	__u64 length;		/* in - length of extent */
++	__u16 dest_count;	/* in - total elements in info array */
++	__u16 reserved1;
++	__u32 reserved2;
++	struct btrfs_ioctl_same_extent_info info[0];
++};
++
++struct btrfs_ioctl_space_info {
++	__u64 flags;
++	__u64 total_bytes;
++	__u64 used_bytes;
++};
++
++struct btrfs_ioctl_space_args {
++	__u64 space_slots;
++	__u64 total_spaces;
++	struct btrfs_ioctl_space_info spaces[0];
++};
++
++struct btrfs_data_container {
++	__u32	bytes_left;	/* out -- bytes not needed to deliver output */
++	__u32	bytes_missing;	/* out -- additional bytes needed for result */
++	__u32	elem_cnt;	/* out */
++	__u32	elem_missed;	/* out */
++	__u64	val[0];		/* out */
++};
++
++struct btrfs_ioctl_ino_path_args {
++	__u64				inum;		/* in */
++	__u64				size;		/* in */
++	__u64				reserved[4];
++	/* struct btrfs_data_container	*fspath;	   out */
++	__u64				fspath;		/* out */
++};
++
++struct btrfs_ioctl_logical_ino_args {
++	__u64				logical;	/* in */
++	__u64				size;		/* in */
++	__u64				reserved[3];	/* must be 0 for now */
++	__u64				flags;		/* in, v2 only */
++	/* struct btrfs_data_container	*inodes;	out   */
++	__u64				inodes;
++};
++/* Return every ref to the extent, not just those containing logical block.
++ * Requires logical == extent bytenr. */
++#define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET	(1ULL << 0)
++
++enum btrfs_dev_stat_values {
++	/* disk I/O failure stats */
++	BTRFS_DEV_STAT_WRITE_ERRS, /* EIO or EREMOTEIO from lower layers */
++	BTRFS_DEV_STAT_READ_ERRS, /* EIO or EREMOTEIO from lower layers */
++	BTRFS_DEV_STAT_FLUSH_ERRS, /* EIO or EREMOTEIO from lower layers */
++
++	/* stats for indirect indications for I/O failures */
++	BTRFS_DEV_STAT_CORRUPTION_ERRS, /* checksum error, bytenr error or
++					 * contents is illegal: this is an
++					 * indication that the block was damaged
++					 * during read or write, or written to
++					 * wrong location or read from wrong
++					 * location */
++	BTRFS_DEV_STAT_GENERATION_ERRS, /* an indication that blocks have not
++					 * been written */
++
++	BTRFS_DEV_STAT_VALUES_MAX
++};
++
++/* Reset statistics after reading; needs SYS_ADMIN capability */
++#define	BTRFS_DEV_STATS_RESET		(1ULL << 0)
++
++struct btrfs_ioctl_get_dev_stats {
++	__u64 devid;				/* in */
++	__u64 nr_items;				/* in/out */
++	__u64 flags;				/* in/out */
++
++	/* out values: */
++	__u64 values[BTRFS_DEV_STAT_VALUES_MAX];
++
++	__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */
++};
++
++#define BTRFS_QUOTA_CTL_ENABLE	1
++#define BTRFS_QUOTA_CTL_DISABLE	2
++#define BTRFS_QUOTA_CTL_RESCAN__NOTUSED	3
++struct btrfs_ioctl_quota_ctl_args {
++	__u64 cmd;
++	__u64 status;
++};
++
++struct btrfs_ioctl_quota_rescan_args {
++	__u64	flags;
++	__u64   progress;
++	__u64   reserved[6];
++};
++
++struct btrfs_ioctl_qgroup_assign_args {
++	__u64 assign;
++	__u64 src;
++	__u64 dst;
++};
++
++struct btrfs_ioctl_qgroup_create_args {
++	__u64 create;
++	__u64 qgroupid;
++};
++struct btrfs_ioctl_timespec {
++	__u64 sec;
++	__u32 nsec;
++};
++
++struct btrfs_ioctl_received_subvol_args {
++	char	uuid[BTRFS_UUID_SIZE];	/* in */
++	__u64	stransid;		/* in */
++	__u64	rtransid;		/* out */
++	struct btrfs_ioctl_timespec stime; /* in */
++	struct btrfs_ioctl_timespec rtime; /* out */
++	__u64	flags;			/* in */
++	__u64	reserved[16];		/* in */
++};
++
++/*
++ * Caller doesn't want file data in the send stream, even if the
++ * search of clone sources doesn't find an extent. UPDATE_EXTENT
++ * commands will be sent instead of WRITE commands.
++ */
++#define BTRFS_SEND_FLAG_NO_FILE_DATA		0x1
++
++/*
++ * Do not add the leading stream header. Used when multiple snapshots
++ * are sent back to back.
++ */
++#define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER	0x2
++
++/*
++ * Omit the command at the end of the stream that indicated the end
++ * of the stream. This option is used when multiple snapshots are
++ * sent back to back.
++ */
++#define BTRFS_SEND_FLAG_OMIT_END_CMD		0x4
++
++#define BTRFS_SEND_FLAG_MASK \
++	(BTRFS_SEND_FLAG_NO_FILE_DATA | \
++	 BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | \
++	 BTRFS_SEND_FLAG_OMIT_END_CMD)
++
++struct btrfs_ioctl_send_args {
++	__s64 send_fd;			/* in */
++	__u64 clone_sources_count;	/* in */
++	__u64 *clone_sources;	/* in */
++	__u64 parent_root;		/* in */
++	__u64 flags;			/* in */
++	__u64 reserved[4];		/* in */
++};
++
++/*
++ * Information about a fs tree root.
++ *
++ * All items are filled by the ioctl
++ */
++struct btrfs_ioctl_get_subvol_info_args {
++	/* Id of this subvolume */
++	__u64 treeid;
++
++	/* Name of this subvolume, used to get the real name at mount point */
++	char name[BTRFS_VOL_NAME_MAX + 1];
++
++	/*
++	 * Id of the subvolume which contains this subvolume.
++	 * Zero for top-level subvolume or a deleted subvolume.
++	 */
++	__u64 parent_id;
++
++	/*
++	 * Inode number of the directory which contains this subvolume.
++	 * Zero for top-level subvolume or a deleted subvolume
++	 */
++	__u64 dirid;
++
++	/* Latest transaction id of this subvolume */
++	__u64 generation;
++
++	/* Flags of this subvolume */
++	__u64 flags;
++
++	/* UUID of this subvolume */
++	__u8 uuid[BTRFS_UUID_SIZE];
++
++	/*
++	 * UUID of the subvolume of which this subvolume is a snapshot.
++	 * All zero for a non-snapshot subvolume.
++	 */
++	__u8 parent_uuid[BTRFS_UUID_SIZE];
++
++	/*
++	 * UUID of the subvolume from which this subvolume was received.
++	 * All zero for non-received subvolume.
++	 */
++	__u8 received_uuid[BTRFS_UUID_SIZE];
++
++	/* Transaction id indicating when change/create/send/receive happened */
++	__u64 ctransid;
++	__u64 otransid;
++	__u64 stransid;
++	__u64 rtransid;
++	/* Time corresponding to c/o/s/rtransid */
++	struct btrfs_ioctl_timespec ctime;
++	struct btrfs_ioctl_timespec otime;
++	struct btrfs_ioctl_timespec stime;
++	struct btrfs_ioctl_timespec rtime;
++
++	/* Must be zero */
++	__u64 reserved[8];
++};
++
++#define BTRFS_MAX_ROOTREF_BUFFER_NUM 255
++struct btrfs_ioctl_get_subvol_rootref_args {
++		/* in/out, minimum id of rootref's treeid to be searched */
++		__u64 min_treeid;
++
++		/* out */
++		struct {
++			__u64 treeid;
++			__u64 dirid;
++		} rootref[BTRFS_MAX_ROOTREF_BUFFER_NUM];
++
++		/* out, number of found items */
++		__u8 num_items;
++		__u8 align[7];
++};
++
++/* Error codes as returned by the kernel */
++enum btrfs_err_code {
++	BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET = 1,
++	BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET,
++	BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET,
++	BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET,
++	BTRFS_ERROR_DEV_TGT_REPLACE,
++	BTRFS_ERROR_DEV_MISSING_NOT_FOUND,
++	BTRFS_ERROR_DEV_ONLY_WRITABLE,
++	BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
++};
++
++#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
++				   struct btrfs_ioctl_vol_args)
++/* trans start and trans end are dangerous, and only for
++ * use by applications that know how to avoid the
++ * resulting deadlocks
++ */
++#define BTRFS_IOC_TRANS_START  _IO(BTRFS_IOCTL_MAGIC, 6)
++#define BTRFS_IOC_TRANS_END    _IO(BTRFS_IOCTL_MAGIC, 7)
++#define BTRFS_IOC_SYNC         _IO(BTRFS_IOCTL_MAGIC, 8)
++
++#define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)
++#define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
++				   struct btrfs_ioctl_vol_args)
++
++#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \
++				  struct btrfs_ioctl_clone_range_args)
++
++#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \
++				   struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
++				struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \
++				struct btrfs_ioctl_defrag_range_args)
++#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
++				   struct btrfs_ioctl_search_args)
++#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
++					   struct btrfs_ioctl_search_args_v2)
++#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
++				   struct btrfs_ioctl_ino_lookup_args)
++#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64)
++#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
++				    struct btrfs_ioctl_space_args)
++#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
++#define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
++#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
++				   struct btrfs_ioctl_vol_args_v2)
++#define BTRFS_IOC_SUBVOL_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 24, \
++				   struct btrfs_ioctl_vol_args_v2)
++#define BTRFS_IOC_SUBVOL_GETFLAGS _IOR(BTRFS_IOCTL_MAGIC, 25, __u64)
++#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64)
++#define BTRFS_IOC_SCRUB _IOWR(BTRFS_IOCTL_MAGIC, 27, \
++			      struct btrfs_ioctl_scrub_args)
++#define BTRFS_IOC_SCRUB_CANCEL _IO(BTRFS_IOCTL_MAGIC, 28)
++#define BTRFS_IOC_SCRUB_PROGRESS _IOWR(BTRFS_IOCTL_MAGIC, 29, \
++				       struct btrfs_ioctl_scrub_args)
++#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
++				 struct btrfs_ioctl_dev_info_args)
++#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
++			       struct btrfs_ioctl_fs_info_args)
++#define BTRFS_IOC_BALANCE_V2 _IOWR(BTRFS_IOCTL_MAGIC, 32, \
++				   struct btrfs_ioctl_balance_args)
++#define BTRFS_IOC_BALANCE_CTL _IOW(BTRFS_IOCTL_MAGIC, 33, int)
++#define BTRFS_IOC_BALANCE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 34, \
++					struct btrfs_ioctl_balance_args)
++#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
++					struct btrfs_ioctl_ino_path_args)
++#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
++					struct btrfs_ioctl_logical_ino_args)
++#define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, \
++				struct btrfs_ioctl_received_subvol_args)
++#define BTRFS_IOC_SEND _IOW(BTRFS_IOCTL_MAGIC, 38, struct btrfs_ioctl_send_args)
++#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, \
++				     struct btrfs_ioctl_vol_args)
++#define BTRFS_IOC_QUOTA_CTL _IOWR(BTRFS_IOCTL_MAGIC, 40, \
++			       struct btrfs_ioctl_quota_ctl_args)
++#define BTRFS_IOC_QGROUP_ASSIGN _IOW(BTRFS_IOCTL_MAGIC, 41, \
++			       struct btrfs_ioctl_qgroup_assign_args)
++#define BTRFS_IOC_QGROUP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 42, \
++			       struct btrfs_ioctl_qgroup_create_args)
++#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
++			       struct btrfs_ioctl_qgroup_limit_args)
++#define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \
++			       struct btrfs_ioctl_quota_rescan_args)
++#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
++			       struct btrfs_ioctl_quota_rescan_args)
++#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
++#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
++				   char[BTRFS_LABEL_SIZE])
++#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
++				   char[BTRFS_LABEL_SIZE])
++#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
++				      struct btrfs_ioctl_get_dev_stats)
++#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \
++				    struct btrfs_ioctl_dev_replace_args)
++#define BTRFS_IOC_FILE_EXTENT_SAME _IOWR(BTRFS_IOCTL_MAGIC, 54, \
++					 struct btrfs_ioctl_same_args)
++#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
++				   struct btrfs_ioctl_feature_flags)
++#define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
++				   struct btrfs_ioctl_feature_flags[2])
++#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
++				   struct btrfs_ioctl_feature_flags[3])
++#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
++				   struct btrfs_ioctl_vol_args_v2)
++#define BTRFS_IOC_LOGICAL_INO_V2 _IOWR(BTRFS_IOCTL_MAGIC, 59, \
++					struct btrfs_ioctl_logical_ino_args)
++#define BTRFS_IOC_GET_SUBVOL_INFO _IOR(BTRFS_IOCTL_MAGIC, 60, \
++				struct btrfs_ioctl_get_subvol_info_args)
++#define BTRFS_IOC_GET_SUBVOL_ROOTREF _IOWR(BTRFS_IOCTL_MAGIC, 61, \
++				struct btrfs_ioctl_get_subvol_rootref_args)
++#define BTRFS_IOC_INO_LOOKUP_USER _IOWR(BTRFS_IOCTL_MAGIC, 62, \
++				struct btrfs_ioctl_ino_lookup_user_args)
++
++#endif /* _UAPI_LINUX_BTRFS_H */
+diff --git a/src/basic/linux/btrfs_tree.h b/src/basic/linux/btrfs_tree.h
+new file mode 100644
+index 0000000000..e974f4bb53
+--- /dev/null
++++ b/src/basic/linux/btrfs_tree.h
+@@ -0,0 +1,974 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _BTRFS_CTREE_H_
++#define _BTRFS_CTREE_H_
++
++#include <linux/btrfs.h>
++#include <linux/types.h>
++
++/*
++ * This header contains the structure definitions and constants used
++ * by file system objects that can be retrieved using
++ * the BTRFS_IOC_SEARCH_TREE ioctl.  That means basically anything that
++ * is needed to describe a leaf node's key or item contents.
++ */
++
++/* holds pointers to all of the tree roots */
++#define BTRFS_ROOT_TREE_OBJECTID 1ULL
++
++/* stores information about which extents are in use, and reference counts */
++#define BTRFS_EXTENT_TREE_OBJECTID 2ULL
++
++/*
++ * chunk tree stores translations from logical -> physical block numbering
++ * the super block points to the chunk tree
++ */
++#define BTRFS_CHUNK_TREE_OBJECTID 3ULL
++
++/*
++ * stores information about which areas of a given device are in use.
++ * one per device.  The tree of tree roots points to the device tree
++ */
++#define BTRFS_DEV_TREE_OBJECTID 4ULL
++
++/* one per subvolume, storing files and directories */
++#define BTRFS_FS_TREE_OBJECTID 5ULL
++
++/* directory objectid inside the root tree */
++#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
++
++/* holds checksums of all the data extents */
++#define BTRFS_CSUM_TREE_OBJECTID 7ULL
++
++/* holds quota configuration and tracking */
++#define BTRFS_QUOTA_TREE_OBJECTID 8ULL
++
++/* for storing items that use the BTRFS_UUID_KEY* types */
++#define BTRFS_UUID_TREE_OBJECTID 9ULL
++
++/* tracks free space in block groups. */
++#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
++
++/* device stats in the device tree */
++#define BTRFS_DEV_STATS_OBJECTID 0ULL
++
++/* for storing balance parameters in the root tree */
++#define BTRFS_BALANCE_OBJECTID -4ULL
++
++/* orhpan objectid for tracking unlinked/truncated files */
++#define BTRFS_ORPHAN_OBJECTID -5ULL
++
++/* does write ahead logging to speed up fsyncs */
++#define BTRFS_TREE_LOG_OBJECTID -6ULL
++#define BTRFS_TREE_LOG_FIXUP_OBJECTID -7ULL
++
++/* for space balancing */
++#define BTRFS_TREE_RELOC_OBJECTID -8ULL
++#define BTRFS_DATA_RELOC_TREE_OBJECTID -9ULL
++
++/*
++ * extent checksums all have this objectid
++ * this allows them to share the logging tree
++ * for fsyncs
++ */
++#define BTRFS_EXTENT_CSUM_OBJECTID -10ULL
++
++/* For storing free space cache */
++#define BTRFS_FREE_SPACE_OBJECTID -11ULL
++
++/*
++ * The inode number assigned to the special inode for storing
++ * free ino cache
++ */
++#define BTRFS_FREE_INO_OBJECTID -12ULL
++
++/* dummy objectid represents multiple objectids */
++#define BTRFS_MULTIPLE_OBJECTIDS -255ULL
++
++/*
++ * All files have objectids in this range.
++ */
++#define BTRFS_FIRST_FREE_OBJECTID 256ULL
++#define BTRFS_LAST_FREE_OBJECTID -256ULL
++#define BTRFS_FIRST_CHUNK_TREE_OBJECTID 256ULL
++
++
++/*
++ * the device items go into the chunk tree.  The key is in the form
++ * [ 1 BTRFS_DEV_ITEM_KEY device_id ]
++ */
++#define BTRFS_DEV_ITEMS_OBJECTID 1ULL
++
++#define BTRFS_BTREE_INODE_OBJECTID 1
++
++#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2
++
++#define BTRFS_DEV_REPLACE_DEVID 0ULL
++
++/*
++ * inode items have the data typically returned from stat and store other
++ * info about object characteristics.  There is one for every file and dir in
++ * the FS
++ */
++#define BTRFS_INODE_ITEM_KEY		1
++#define BTRFS_INODE_REF_KEY		12
++#define BTRFS_INODE_EXTREF_KEY		13
++#define BTRFS_XATTR_ITEM_KEY		24
++#define BTRFS_ORPHAN_ITEM_KEY		48
++/* reserve 2-15 close to the inode for later flexibility */
++
++/*
++ * dir items are the name -> inode pointers in a directory.  There is one
++ * for every name in a directory.
++ */
++#define BTRFS_DIR_LOG_ITEM_KEY  60
++#define BTRFS_DIR_LOG_INDEX_KEY 72
++#define BTRFS_DIR_ITEM_KEY	84
++#define BTRFS_DIR_INDEX_KEY	96
++/*
++ * extent data is for file data
++ */
++#define BTRFS_EXTENT_DATA_KEY	108
++
++/*
++ * extent csums are stored in a separate tree and hold csums for
++ * an entire extent on disk.
++ */
++#define BTRFS_EXTENT_CSUM_KEY	128
++
++/*
++ * root items point to tree roots.  They are typically in the root
++ * tree used by the super block to find all the other trees
++ */
++#define BTRFS_ROOT_ITEM_KEY	132
++
++/*
++ * root backrefs tie subvols and snapshots to the directory entries that
++ * reference them
++ */
++#define BTRFS_ROOT_BACKREF_KEY	144
++
++/*
++ * root refs make a fast index for listing all of the snapshots and
++ * subvolumes referenced by a given root.  They point directly to the
++ * directory item in the root that references the subvol
++ */
++#define BTRFS_ROOT_REF_KEY	156
++
++/*
++ * extent items are in the extent map tree.  These record which blocks
++ * are used, and how many references there are to each block
++ */
++#define BTRFS_EXTENT_ITEM_KEY	168
++
++/*
++ * The same as the BTRFS_EXTENT_ITEM_KEY, except it's metadata we already know
++ * the length, so we save the level in key->offset instead of the length.
++ */
++#define BTRFS_METADATA_ITEM_KEY	169
++
++#define BTRFS_TREE_BLOCK_REF_KEY	176
++
++#define BTRFS_EXTENT_DATA_REF_KEY	178
++
++#define BTRFS_EXTENT_REF_V0_KEY		180
++
++#define BTRFS_SHARED_BLOCK_REF_KEY	182
++
++#define BTRFS_SHARED_DATA_REF_KEY	184
++
++/*
++ * block groups give us hints into the extent allocation trees.  Which
++ * blocks are free etc etc
++ */
++#define BTRFS_BLOCK_GROUP_ITEM_KEY 192
++
++/*
++ * Every block group is represented in the free space tree by a free space info
++ * item, which stores some accounting information. It is keyed on
++ * (block_group_start, FREE_SPACE_INFO, block_group_length).
++ */
++#define BTRFS_FREE_SPACE_INFO_KEY 198
++
++/*
++ * A free space extent tracks an extent of space that is free in a block group.
++ * It is keyed on (start, FREE_SPACE_EXTENT, length).
++ */
++#define BTRFS_FREE_SPACE_EXTENT_KEY 199
++
++/*
++ * When a block group becomes very fragmented, we convert it to use bitmaps
++ * instead of extents. A free space bitmap is keyed on
++ * (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with
++ * (length / sectorsize) bits.
++ */
++#define BTRFS_FREE_SPACE_BITMAP_KEY 200
++
++#define BTRFS_DEV_EXTENT_KEY	204
++#define BTRFS_DEV_ITEM_KEY	216
++#define BTRFS_CHUNK_ITEM_KEY	228
++
++/*
++ * Records the overall state of the qgroups.
++ * There's only one instance of this key present,
++ * (0, BTRFS_QGROUP_STATUS_KEY, 0)
++ */
++#define BTRFS_QGROUP_STATUS_KEY         240
++/*
++ * Records the currently used space of the qgroup.
++ * One key per qgroup, (0, BTRFS_QGROUP_INFO_KEY, qgroupid).
++ */
++#define BTRFS_QGROUP_INFO_KEY           242
++/*
++ * Contains the user configured limits for the qgroup.
++ * One key per qgroup, (0, BTRFS_QGROUP_LIMIT_KEY, qgroupid).
++ */
++#define BTRFS_QGROUP_LIMIT_KEY          244
++/*
++ * Records the child-parent relationship of qgroups. For
++ * each relation, 2 keys are present:
++ * (childid, BTRFS_QGROUP_RELATION_KEY, parentid)
++ * (parentid, BTRFS_QGROUP_RELATION_KEY, childid)
++ */
++#define BTRFS_QGROUP_RELATION_KEY       246
++
++/*
++ * Obsolete name, see BTRFS_TEMPORARY_ITEM_KEY.
++ */
++#define BTRFS_BALANCE_ITEM_KEY	248
++
++/*
++ * The key type for tree items that are stored persistently, but do not need to
++ * exist for extended period of time. The items can exist in any tree.
++ *
++ * [subtype, BTRFS_TEMPORARY_ITEM_KEY, data]
++ *
++ * Existing items:
++ *
++ * - balance status item
++ *   (BTRFS_BALANCE_OBJECTID, BTRFS_TEMPORARY_ITEM_KEY, 0)
++ */
++#define BTRFS_TEMPORARY_ITEM_KEY	248
++
++/*
++ * Obsolete name, see BTRFS_PERSISTENT_ITEM_KEY
++ */
++#define BTRFS_DEV_STATS_KEY		249
++
++/*
++ * The key type for tree items that are stored persistently and usually exist
++ * for a long period, eg. filesystem lifetime. The item kinds can be status
++ * information, stats or preference values. The item can exist in any tree.
++ *
++ * [subtype, BTRFS_PERSISTENT_ITEM_KEY, data]
++ *
++ * Existing items:
++ *
++ * - device statistics, store IO stats in the device tree, one key for all
++ *   stats
++ *   (BTRFS_DEV_STATS_OBJECTID, BTRFS_DEV_STATS_KEY, 0)
++ */
++#define BTRFS_PERSISTENT_ITEM_KEY	249
++
++/*
++ * Persistantly stores the device replace state in the device tree.
++ * The key is built like this: (0, BTRFS_DEV_REPLACE_KEY, 0).
++ */
++#define BTRFS_DEV_REPLACE_KEY	250
++
++/*
++ * Stores items that allow to quickly map UUIDs to something else.
++ * These items are part of the filesystem UUID tree.
++ * The key is built like this:
++ * (UUID_upper_64_bits, BTRFS_UUID_KEY*, UUID_lower_64_bits).
++ */
++#if BTRFS_UUID_SIZE != 16
++#error "UUID items require BTRFS_UUID_SIZE == 16!"
++#endif
++#define BTRFS_UUID_KEY_SUBVOL	251	/* for UUIDs assigned to subvols */
++#define BTRFS_UUID_KEY_RECEIVED_SUBVOL	252	/* for UUIDs assigned to
++						 * received subvols */
++
++/*
++ * string items are for debugging.  They just store a short string of
++ * data in the FS
++ */
++#define BTRFS_STRING_ITEM_KEY	253
++
++
++
++/* 32 bytes in various csum fields */
++#define BTRFS_CSUM_SIZE 32
++
++/* csum types */
++#define BTRFS_CSUM_TYPE_CRC32	0
++
++/*
++ * flags definitions for directory entry item type
++ *
++ * Used by:
++ * struct btrfs_dir_item.type
++ */
++#define BTRFS_FT_UNKNOWN	0
++#define BTRFS_FT_REG_FILE	1
++#define BTRFS_FT_DIR		2
++#define BTRFS_FT_CHRDEV		3
++#define BTRFS_FT_BLKDEV		4
++#define BTRFS_FT_FIFO		5
++#define BTRFS_FT_SOCK		6
++#define BTRFS_FT_SYMLINK	7
++#define BTRFS_FT_XATTR		8
++#define BTRFS_FT_MAX		9
++
++/*
++ * The key defines the order in the tree, and so it also defines (optimal)
++ * block layout.
++ *
++ * objectid corresponds to the inode number.
++ *
++ * type tells us things about the object, and is a kind of stream selector.
++ * so for a given inode, keys with type of 1 might refer to the inode data,
++ * type of 2 may point to file data in the btree and type == 3 may point to
++ * extents.
++ *
++ * offset is the starting byte offset for this key in the stream.
++ *
++ * btrfs_disk_key is in disk byte order.  struct btrfs_key is always
++ * in cpu native order.  Otherwise they are identical and their sizes
++ * should be the same (ie both packed)
++ */
++struct btrfs_disk_key {
++	__le64 objectid;
++	__u8 type;
++	__le64 offset;
++} __attribute__ ((__packed__));
++
++struct btrfs_key {
++	__u64 objectid;
++	__u8 type;
++	__u64 offset;
++} __attribute__ ((__packed__));
++
++struct btrfs_dev_item {
++	/* the internal btrfs device id */
++	__le64 devid;
++
++	/* size of the device */
++	__le64 total_bytes;
++
++	/* bytes used */
++	__le64 bytes_used;
++
++	/* optimal io alignment for this device */
++	__le32 io_align;
++
++	/* optimal io width for this device */
++	__le32 io_width;
++
++	/* minimal io size for this device */
++	__le32 sector_size;
++
++	/* type and info about this device */
++	__le64 type;
++
++	/* expected generation for this device */
++	__le64 generation;
++
++	/*
++	 * starting byte of this partition on the device,
++	 * to allow for stripe alignment in the future
++	 */
++	__le64 start_offset;
++
++	/* grouping information for allocation decisions */
++	__le32 dev_group;
++
++	/* seek speed 0-100 where 100 is fastest */
++	__u8 seek_speed;
++
++	/* bandwidth 0-100 where 100 is fastest */
++	__u8 bandwidth;
++
++	/* btrfs generated uuid for this device */
++	__u8 uuid[BTRFS_UUID_SIZE];
++
++	/* uuid of FS who owns this device */
++	__u8 fsid[BTRFS_UUID_SIZE];
++} __attribute__ ((__packed__));
++
++struct btrfs_stripe {
++	__le64 devid;
++	__le64 offset;
++	__u8 dev_uuid[BTRFS_UUID_SIZE];
++} __attribute__ ((__packed__));
++
++struct btrfs_chunk {
++	/* size of this chunk in bytes */
++	__le64 length;
++
++	/* objectid of the root referencing this chunk */
++	__le64 owner;
++
++	__le64 stripe_len;
++	__le64 type;
++
++	/* optimal io alignment for this chunk */
++	__le32 io_align;
++
++	/* optimal io width for this chunk */
++	__le32 io_width;
++
++	/* minimal io size for this chunk */
++	__le32 sector_size;
++
++	/* 2^16 stripes is quite a lot, a second limit is the size of a single
++	 * item in the btree
++	 */
++	__le16 num_stripes;
++
++	/* sub stripes only matter for raid10 */
++	__le16 sub_stripes;
++	struct btrfs_stripe stripe;
++	/* additional stripes go here */
++} __attribute__ ((__packed__));
++
++#define BTRFS_FREE_SPACE_EXTENT	1
++#define BTRFS_FREE_SPACE_BITMAP	2
++
++struct btrfs_free_space_entry {
++	__le64 offset;
++	__le64 bytes;
++	__u8 type;
++} __attribute__ ((__packed__));
++
++struct btrfs_free_space_header {
++	struct btrfs_disk_key location;
++	__le64 generation;
++	__le64 num_entries;
++	__le64 num_bitmaps;
++} __attribute__ ((__packed__));
++
++#define BTRFS_HEADER_FLAG_WRITTEN	(1ULL << 0)
++#define BTRFS_HEADER_FLAG_RELOC		(1ULL << 1)
++
++/* Super block flags */
++/* Errors detected */
++#define BTRFS_SUPER_FLAG_ERROR		(1ULL << 2)
++
++#define BTRFS_SUPER_FLAG_SEEDING	(1ULL << 32)
++#define BTRFS_SUPER_FLAG_METADUMP	(1ULL << 33)
++#define BTRFS_SUPER_FLAG_METADUMP_V2	(1ULL << 34)
++#define BTRFS_SUPER_FLAG_CHANGING_FSID	(1ULL << 35)
++#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36)
++
++
++/*
++ * items in the extent btree are used to record the objectid of the
++ * owner of the block and the number of references
++ */
++
++struct btrfs_extent_item {
++	__le64 refs;
++	__le64 generation;
++	__le64 flags;
++} __attribute__ ((__packed__));
++
++struct btrfs_extent_item_v0 {
++	__le32 refs;
++} __attribute__ ((__packed__));
++
++
++#define BTRFS_EXTENT_FLAG_DATA		(1ULL << 0)
++#define BTRFS_EXTENT_FLAG_TREE_BLOCK	(1ULL << 1)
++
++/* following flags only apply to tree blocks */
++
++/* use full backrefs for extent pointers in the block */
++#define BTRFS_BLOCK_FLAG_FULL_BACKREF	(1ULL << 8)
++
++/*
++ * this flag is only used internally by scrub and may be changed at any time
++ * it is only declared here to avoid collisions
++ */
++#define BTRFS_EXTENT_FLAG_SUPER		(1ULL << 48)
++
++struct btrfs_tree_block_info {
++	struct btrfs_disk_key key;
++	__u8 level;
++} __attribute__ ((__packed__));
++
++struct btrfs_extent_data_ref {
++	__le64 root;
++	__le64 objectid;
++	__le64 offset;
++	__le32 count;
++} __attribute__ ((__packed__));
++
++struct btrfs_shared_data_ref {
++	__le32 count;
++} __attribute__ ((__packed__));
++
++struct btrfs_extent_inline_ref {
++	__u8 type;
++	__le64 offset;
++} __attribute__ ((__packed__));
++
++/* old style backrefs item */
++struct btrfs_extent_ref_v0 {
++	__le64 root;
++	__le64 generation;
++	__le64 objectid;
++	__le32 count;
++} __attribute__ ((__packed__));
++
++
++/* dev extents record free space on individual devices.  The owner
++ * field points back to the chunk allocation mapping tree that allocated
++ * the extent.  The chunk tree uuid field is a way to double check the owner
++ */
++struct btrfs_dev_extent {
++	__le64 chunk_tree;
++	__le64 chunk_objectid;
++	__le64 chunk_offset;
++	__le64 length;
++	__u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
++} __attribute__ ((__packed__));
++
++struct btrfs_inode_ref {
++	__le64 index;
++	__le16 name_len;
++	/* name goes here */
++} __attribute__ ((__packed__));
++
++struct btrfs_inode_extref {
++	__le64 parent_objectid;
++	__le64 index;
++	__le16 name_len;
++	__u8   name[0];
++	/* name goes here */
++} __attribute__ ((__packed__));
++
++struct btrfs_timespec {
++	__le64 sec;
++	__le32 nsec;
++} __attribute__ ((__packed__));
++
++struct btrfs_inode_item {
++	/* nfs style generation number */
++	__le64 generation;
++	/* transid that last touched this inode */
++	__le64 transid;
++	__le64 size;
++	__le64 nbytes;
++	__le64 block_group;
++	__le32 nlink;
++	__le32 uid;
++	__le32 gid;
++	__le32 mode;
++	__le64 rdev;
++	__le64 flags;
++
++	/* modification sequence number for NFS */
++	__le64 sequence;
++
++	/*
++	 * a little future expansion, for more than this we can
++	 * just grow the inode item and version it
++	 */
++	__le64 reserved[4];
++	struct btrfs_timespec atime;
++	struct btrfs_timespec ctime;
++	struct btrfs_timespec mtime;
++	struct btrfs_timespec otime;
++} __attribute__ ((__packed__));
++
++struct btrfs_dir_log_item {
++	__le64 end;
++} __attribute__ ((__packed__));
++
++struct btrfs_dir_item {
++	struct btrfs_disk_key location;
++	__le64 transid;
++	__le16 data_len;
++	__le16 name_len;
++	__u8 type;
++} __attribute__ ((__packed__));
++
++#define BTRFS_ROOT_SUBVOL_RDONLY	(1ULL << 0)
++
++/*
++ * Internal in-memory flag that a subvolume has been marked for deletion but
++ * still visible as a directory
++ */
++#define BTRFS_ROOT_SUBVOL_DEAD		(1ULL << 48)
++
++struct btrfs_root_item {
++	struct btrfs_inode_item inode;
++	__le64 generation;
++	__le64 root_dirid;
++	__le64 bytenr;
++	__le64 byte_limit;
++	__le64 bytes_used;
++	__le64 last_snapshot;
++	__le64 flags;
++	__le32 refs;
++	struct btrfs_disk_key drop_progress;
++	__u8 drop_level;
++	__u8 level;
++
++	/*
++	 * The following fields appear after subvol_uuids+subvol_times
++	 * were introduced.
++	 */
++
++	/*
++	 * This generation number is used to test if the new fields are valid
++	 * and up to date while reading the root item. Every time the root item
++	 * is written out, the "generation" field is copied into this field. If
++	 * anyone ever mounted the fs with an older kernel, we will have
++	 * mismatching generation values here and thus must invalidate the
++	 * new fields. See btrfs_update_root and btrfs_find_last_root for
++	 * details.
++	 * the offset of generation_v2 is also used as the start for the memset
++	 * when invalidating the fields.
++	 */
++	__le64 generation_v2;
++	__u8 uuid[BTRFS_UUID_SIZE];
++	__u8 parent_uuid[BTRFS_UUID_SIZE];
++	__u8 received_uuid[BTRFS_UUID_SIZE];
++	__le64 ctransid; /* updated when an inode changes */
++	__le64 otransid; /* trans when created */
++	__le64 stransid; /* trans when sent. non-zero for received subvol */
++	__le64 rtransid; /* trans when received. non-zero for received subvol */
++	struct btrfs_timespec ctime;
++	struct btrfs_timespec otime;
++	struct btrfs_timespec stime;
++	struct btrfs_timespec rtime;
++	__le64 reserved[8]; /* for future */
++} __attribute__ ((__packed__));
++
++/*
++ * this is used for both forward and backward root refs
++ */
++struct btrfs_root_ref {
++	__le64 dirid;
++	__le64 sequence;
++	__le16 name_len;
++} __attribute__ ((__packed__));
++
++struct btrfs_disk_balance_args {
++	/*
++	 * profiles to operate on, single is denoted by
++	 * BTRFS_AVAIL_ALLOC_BIT_SINGLE
++	 */
++	__le64 profiles;
++
++	/*
++	 * usage filter
++	 * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'
++	 * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max
++	 */
++	union {
++		__le64 usage;
++		struct {
++			__le32 usage_min;
++			__le32 usage_max;
++		};
++	};
++
++	/* devid filter */
++	__le64 devid;
++
++	/* devid subset filter [pstart..pend) */
++	__le64 pstart;
++	__le64 pend;
++
++	/* btrfs virtual address space subset filter [vstart..vend) */
++	__le64 vstart;
++	__le64 vend;
++
++	/*
++	 * profile to convert to, single is denoted by
++	 * BTRFS_AVAIL_ALLOC_BIT_SINGLE
++	 */
++	__le64 target;
++
++	/* BTRFS_BALANCE_ARGS_* */
++	__le64 flags;
++
++	/*
++	 * BTRFS_BALANCE_ARGS_LIMIT with value 'limit'
++	 * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum
++	 * and maximum
++	 */
++	union {
++		__le64 limit;
++		struct {
++			__le32 limit_min;
++			__le32 limit_max;
++		};
++	};
++
++	/*
++	 * Process chunks that cross stripes_min..stripes_max devices,
++	 * BTRFS_BALANCE_ARGS_STRIPES_RANGE
++	 */
++	__le32 stripes_min;
++	__le32 stripes_max;
++
++	__le64 unused[6];
++} __attribute__ ((__packed__));
++
++/*
++ * store balance parameters to disk so that balance can be properly
++ * resumed after crash or unmount
++ */
++struct btrfs_balance_item {
++	/* BTRFS_BALANCE_* */
++	__le64 flags;
++
++	struct btrfs_disk_balance_args data;
++	struct btrfs_disk_balance_args meta;
++	struct btrfs_disk_balance_args sys;
++
++	__le64 unused[4];
++} __attribute__ ((__packed__));
++
++#define BTRFS_FILE_EXTENT_INLINE 0
++#define BTRFS_FILE_EXTENT_REG 1
++#define BTRFS_FILE_EXTENT_PREALLOC 2
++#define BTRFS_FILE_EXTENT_TYPES	2
++
++struct btrfs_file_extent_item {
++	/*
++	 * transaction id that created this extent
++	 */
++	__le64 generation;
++	/*
++	 * max number of bytes to hold this extent in ram
++	 * when we split a compressed extent we can't know how big
++	 * each of the resulting pieces will be.  So, this is
++	 * an upper limit on the size of the extent in ram instead of
++	 * an exact limit.
++	 */
++	__le64 ram_bytes;
++
++	/*
++	 * 32 bits for the various ways we might encode the data,
++	 * including compression and encryption.  If any of these
++	 * are set to something a given disk format doesn't understand
++	 * it is treated like an incompat flag for reading and writing,
++	 * but not for stat.
++	 */
++	__u8 compression;
++	__u8 encryption;
++	__le16 other_encoding; /* spare for later use */
++
++	/* are we inline data or a real extent? */
++	__u8 type;
++
++	/*
++	 * disk space consumed by the extent, checksum blocks are included
++	 * in these numbers
++	 *
++	 * At this offset in the structure, the inline extent data start.
++	 */
++	__le64 disk_bytenr;
++	__le64 disk_num_bytes;
++	/*
++	 * the logical offset in file blocks (no csums)
++	 * this extent record is for.  This allows a file extent to point
++	 * into the middle of an existing extent on disk, sharing it
++	 * between two snapshots (useful if some bytes in the middle of the
++	 * extent have changed
++	 */
++	__le64 offset;
++	/*
++	 * the logical number of file blocks (no csums included).  This
++	 * always reflects the size uncompressed and without encoding.
++	 */
++	__le64 num_bytes;
++
++} __attribute__ ((__packed__));
++
++struct btrfs_csum_item {
++	__u8 csum;
++} __attribute__ ((__packed__));
++
++struct btrfs_dev_stats_item {
++	/*
++	 * grow this item struct at the end for future enhancements and keep
++	 * the existing values unchanged
++	 */
++	__le64 values[BTRFS_DEV_STAT_VALUES_MAX];
++} __attribute__ ((__packed__));
++
++#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_ALWAYS	0
++#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_AVOID	1
++#define BTRFS_DEV_REPLACE_ITEM_STATE_NEVER_STARTED	0
++#define BTRFS_DEV_REPLACE_ITEM_STATE_STARTED		1
++#define BTRFS_DEV_REPLACE_ITEM_STATE_SUSPENDED		2
++#define BTRFS_DEV_REPLACE_ITEM_STATE_FINISHED		3
++#define BTRFS_DEV_REPLACE_ITEM_STATE_CANCELED		4
++
++struct btrfs_dev_replace_item {
++	/*
++	 * grow this item struct at the end for future enhancements and keep
++	 * the existing values unchanged
++	 */
++	__le64 src_devid;
++	__le64 cursor_left;
++	__le64 cursor_right;
++	__le64 cont_reading_from_srcdev_mode;
++
++	__le64 replace_state;
++	__le64 time_started;
++	__le64 time_stopped;
++	__le64 num_write_errors;
++	__le64 num_uncorrectable_read_errors;
++} __attribute__ ((__packed__));
++
++/* different types of block groups (and chunks) */
++#define BTRFS_BLOCK_GROUP_DATA		(1ULL << 0)
++#define BTRFS_BLOCK_GROUP_SYSTEM	(1ULL << 1)
++#define BTRFS_BLOCK_GROUP_METADATA	(1ULL << 2)
++#define BTRFS_BLOCK_GROUP_RAID0		(1ULL << 3)
++#define BTRFS_BLOCK_GROUP_RAID1		(1ULL << 4)
++#define BTRFS_BLOCK_GROUP_DUP		(1ULL << 5)
++#define BTRFS_BLOCK_GROUP_RAID10	(1ULL << 6)
++#define BTRFS_BLOCK_GROUP_RAID5         (1ULL << 7)
++#define BTRFS_BLOCK_GROUP_RAID6         (1ULL << 8)
++#define BTRFS_BLOCK_GROUP_RESERVED	(BTRFS_AVAIL_ALLOC_BIT_SINGLE | \
++					 BTRFS_SPACE_INFO_GLOBAL_RSV)
++
++enum btrfs_raid_types {
++	BTRFS_RAID_RAID10,
++	BTRFS_RAID_RAID1,
++	BTRFS_RAID_DUP,
++	BTRFS_RAID_RAID0,
++	BTRFS_RAID_SINGLE,
++	BTRFS_RAID_RAID5,
++	BTRFS_RAID_RAID6,
++	BTRFS_NR_RAID_TYPES
++};
++
++#define BTRFS_BLOCK_GROUP_TYPE_MASK	(BTRFS_BLOCK_GROUP_DATA |    \
++					 BTRFS_BLOCK_GROUP_SYSTEM |  \
++					 BTRFS_BLOCK_GROUP_METADATA)
++
++#define BTRFS_BLOCK_GROUP_PROFILE_MASK	(BTRFS_BLOCK_GROUP_RAID0 |   \
++					 BTRFS_BLOCK_GROUP_RAID1 |   \
++					 BTRFS_BLOCK_GROUP_RAID5 |   \
++					 BTRFS_BLOCK_GROUP_RAID6 |   \
++					 BTRFS_BLOCK_GROUP_DUP |     \
++					 BTRFS_BLOCK_GROUP_RAID10)
++#define BTRFS_BLOCK_GROUP_RAID56_MASK	(BTRFS_BLOCK_GROUP_RAID5 |   \
++					 BTRFS_BLOCK_GROUP_RAID6)
++
++/*
++ * We need a bit for restriper to be able to tell when chunks of type
++ * SINGLE are available.  This "extended" profile format is used in
++ * fs_info->avail_*_alloc_bits (in-memory) and balance item fields
++ * (on-disk).  The corresponding on-disk bit in chunk.type is reserved
++ * to avoid remappings between two formats in future.
++ */
++#define BTRFS_AVAIL_ALLOC_BIT_SINGLE	(1ULL << 48)
++
++/*
++ * A fake block group type that is used to communicate global block reserve
++ * size to userspace via the SPACE_INFO ioctl.
++ */
++#define BTRFS_SPACE_INFO_GLOBAL_RSV	(1ULL << 49)
++
++#define BTRFS_EXTENDED_PROFILE_MASK	(BTRFS_BLOCK_GROUP_PROFILE_MASK | \
++					 BTRFS_AVAIL_ALLOC_BIT_SINGLE)
++
++static inline __u64 chunk_to_extended(__u64 flags)
++{
++	if ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)
++		flags |= BTRFS_AVAIL_ALLOC_BIT_SINGLE;
++
++	return flags;
++}
++static inline __u64 extended_to_chunk(__u64 flags)
++{
++	return flags & ~BTRFS_AVAIL_ALLOC_BIT_SINGLE;
++}
++
++struct btrfs_block_group_item {
++	__le64 used;
++	__le64 chunk_objectid;
++	__le64 flags;
++} __attribute__ ((__packed__));
++
++struct btrfs_free_space_info {
++	__le32 extent_count;
++	__le32 flags;
++} __attribute__ ((__packed__));
++
++#define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0)
++
++#define BTRFS_QGROUP_LEVEL_SHIFT		48
++static inline __u64 btrfs_qgroup_level(__u64 qgroupid)
++{
++	return qgroupid >> BTRFS_QGROUP_LEVEL_SHIFT;
++}
++
++/*
++ * is subvolume quota turned on?
++ */
++#define BTRFS_QGROUP_STATUS_FLAG_ON		(1ULL << 0)
++/*
++ * RESCAN is set during the initialization phase
++ */
++#define BTRFS_QGROUP_STATUS_FLAG_RESCAN		(1ULL << 1)
++/*
++ * Some qgroup entries are known to be out of date,
++ * either because the configuration has changed in a way that
++ * makes a rescan necessary, or because the fs has been mounted
++ * with a non-qgroup-aware version.
++ * Turning qouta off and on again makes it inconsistent, too.
++ */
++#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT	(1ULL << 2)
++
++#define BTRFS_QGROUP_STATUS_VERSION        1
++
++struct btrfs_qgroup_status_item {
++	__le64 version;
++	/*
++	 * the generation is updated during every commit. As older
++	 * versions of btrfs are not aware of qgroups, it will be
++	 * possible to detect inconsistencies by checking the
++	 * generation on mount time
++	 */
++	__le64 generation;
++
++	/* flag definitions see above */
++	__le64 flags;
++
++	/*
++	 * only used during scanning to record the progress
++	 * of the scan. It contains a logical address
++	 */
++	__le64 rescan;
++} __attribute__ ((__packed__));
++
++struct btrfs_qgroup_info_item {
++	__le64 generation;
++	__le64 rfer;
++	__le64 rfer_cmpr;
++	__le64 excl;
++	__le64 excl_cmpr;
++} __attribute__ ((__packed__));
++
++struct btrfs_qgroup_limit_item {
++	/*
++	 * only updated when any of the other values change
++	 */
++	__le64 flags;
++	__le64 max_rfer;
++	__le64 max_excl;
++	__le64 rsv_rfer;
++	__le64 rsv_excl;
++} __attribute__ ((__packed__));
++
++#endif /* _BTRFS_CTREE_H_ */
+diff --git a/src/basic/linux/can/vxcan.h b/src/basic/linux/can/vxcan.h
+new file mode 100644
+index 0000000000..066812d118
+--- /dev/null
++++ b/src/basic/linux/can/vxcan.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI_CAN_VXCAN_H
++#define _UAPI_CAN_VXCAN_H
++
++enum {
++	VXCAN_INFO_UNSPEC,
++	VXCAN_INFO_PEER,
++
++	__VXCAN_INFO_MAX
++#define VXCAN_INFO_MAX	(__VXCAN_INFO_MAX - 1)
++};
++
++#endif
+diff --git a/src/basic/linux/fib_rules.h b/src/basic/linux/fib_rules.h
+new file mode 100644
+index 0000000000..232df14e12
+--- /dev/null
++++ b/src/basic/linux/fib_rules.h
+@@ -0,0 +1,90 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef __LINUX_FIB_RULES_H
++#define __LINUX_FIB_RULES_H
++
++#include <linux/types.h>
++#include <linux/rtnetlink.h>
++
++/* rule is permanent, and cannot be deleted */
++#define FIB_RULE_PERMANENT	0x00000001
++#define FIB_RULE_INVERT		0x00000002
++#define FIB_RULE_UNRESOLVED	0x00000004
++#define FIB_RULE_IIF_DETACHED	0x00000008
++#define FIB_RULE_DEV_DETACHED	FIB_RULE_IIF_DETACHED
++#define FIB_RULE_OIF_DETACHED	0x00000010
++
++/* try to find source address in routing lookups */
++#define FIB_RULE_FIND_SADDR	0x00010000
++
++struct fib_rule_hdr {
++	__u8		family;
++	__u8		dst_len;
++	__u8		src_len;
++	__u8		tos;
++
++	__u8		table;
++	__u8		res1;   /* reserved */
++	__u8		res2;	/* reserved */
++	__u8		action;
++
++	__u32		flags;
++};
++
++struct fib_rule_uid_range {
++	__u32		start;
++	__u32		end;
++};
++
++struct fib_rule_port_range {
++	__u16		start;
++	__u16		end;
++};
++
++enum {
++	FRA_UNSPEC,
++	FRA_DST,	/* destination address */
++	FRA_SRC,	/* source address */
++	FRA_IIFNAME,	/* interface name */
++#define FRA_IFNAME	FRA_IIFNAME
++	FRA_GOTO,	/* target to jump to (FR_ACT_GOTO) */
++	FRA_UNUSED2,
++	FRA_PRIORITY,	/* priority/preference */
++	FRA_UNUSED3,
++	FRA_UNUSED4,
++	FRA_UNUSED5,
++	FRA_FWMARK,	/* mark */
++	FRA_FLOW,	/* flow/class id */
++	FRA_TUN_ID,
++	FRA_SUPPRESS_IFGROUP,
++	FRA_SUPPRESS_PREFIXLEN,
++	FRA_TABLE,	/* Extended table id */
++	FRA_FWMASK,	/* mask for netfilter mark */
++	FRA_OIFNAME,
++	FRA_PAD,
++	FRA_L3MDEV,	/* iif or oif is l3mdev goto its table */
++	FRA_UID_RANGE,	/* UID range */
++	FRA_PROTOCOL,   /* Originator of the rule */
++	FRA_IP_PROTO,	/* ip proto */
++	FRA_SPORT_RANGE, /* sport */
++	FRA_DPORT_RANGE, /* dport */
++	__FRA_MAX
++};
++
++#define FRA_MAX (__FRA_MAX - 1)
++
++enum {
++	FR_ACT_UNSPEC,
++	FR_ACT_TO_TBL,		/* Pass to fixed table */
++	FR_ACT_GOTO,		/* Jump to another rule */
++	FR_ACT_NOP,		/* No operation */
++	FR_ACT_RES3,
++	FR_ACT_RES4,
++	FR_ACT_BLACKHOLE,	/* Drop without notification */
++	FR_ACT_UNREACHABLE,	/* Drop with ENETUNREACH */
++	FR_ACT_PROHIBIT,	/* Drop with EACCES */
++	__FR_ACT_MAX,
++};
++
++#define FR_ACT_MAX (__FR_ACT_MAX - 1)
++
++#endif
+diff --git a/src/basic/linux/fou.h b/src/basic/linux/fou.h
+new file mode 100644
+index 0000000000..f2ea833a28
+--- /dev/null
++++ b/src/basic/linux/fou.h
+@@ -0,0 +1,42 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/* fou.h - FOU Interface */
++
++#ifndef _UAPI_LINUX_FOU_H
++#define _UAPI_LINUX_FOU_H
++
++/* NETLINK_GENERIC related info
++ */
++#define FOU_GENL_NAME		"fou"
++#define FOU_GENL_VERSION	0x1
++
++enum {
++	FOU_ATTR_UNSPEC,
++	FOU_ATTR_PORT,				/* u16 */
++	FOU_ATTR_AF,				/* u8 */
++	FOU_ATTR_IPPROTO,			/* u8 */
++	FOU_ATTR_TYPE,				/* u8 */
++	FOU_ATTR_REMCSUM_NOPARTIAL,		/* flag */
++
++	__FOU_ATTR_MAX,
++};
++
++#define FOU_ATTR_MAX		(__FOU_ATTR_MAX - 1)
++
++enum {
++	FOU_CMD_UNSPEC,
++	FOU_CMD_ADD,
++	FOU_CMD_DEL,
++	FOU_CMD_GET,
++
++	__FOU_CMD_MAX,
++};
++
++enum {
++	FOU_ENCAP_UNSPEC,
++	FOU_ENCAP_DIRECT,
++	FOU_ENCAP_GUE,
++};
++
++#define FOU_CMD_MAX	(__FOU_CMD_MAX - 1)
++
++#endif /* _UAPI_LINUX_FOU_H */
+diff --git a/src/basic/linux/if.h b/src/basic/linux/if.h
+new file mode 100644
+index 0000000000..cbabdde8f9
+--- /dev/null
++++ b/src/basic/linux/if.h
+@@ -0,0 +1,294 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET		An implementation of the TCP/IP protocol suite for the LINUX
++ *		operating system.  INET is implemented using the  BSD Socket
++ *		interface as the means of communication with the user level.
++ *
++ *		Global definitions for the INET interface module.
++ *
++ * Version:	@(#)if.h	1.0.2	04/18/93
++ *
++ * Authors:	Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988
++ *		Ross Biro
++ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *
++ *		This program is free software; you can redistribute it and/or
++ *		modify it under the terms of the GNU General Public License
++ *		as published by the Free Software Foundation; either version
++ *		2 of the License, or (at your option) any later version.
++ */
++#ifndef _LINUX_IF_H
++#define _LINUX_IF_H
++
++#include <linux/libc-compat.h>          /* for compatibility with glibc */
++#include <linux/types.h>		/* for "__kernel_caddr_t" et al	*/
++#include <linux/socket.h>		/* for "struct sockaddr" et al	*/
++
++#ifndef __KERNEL__
++#include <sys/socket.h>			/* for struct sockaddr.		*/
++#endif
++
++#if __UAPI_DEF_IF_IFNAMSIZ
++#define	IFNAMSIZ	16
++#endif /* __UAPI_DEF_IF_IFNAMSIZ */
++#define	IFALIASZ	256
++#include <linux/hdlc/ioctl.h>
++
++/* For glibc compatibility. An empty enum does not compile. */
++#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || \
++    __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
++/**
++ * enum net_device_flags - &struct net_device flags
++ *
++ * These are the &struct net_device flags, they can be set by drivers, the
++ * kernel and some can be triggered by userspace. Userspace can query and
++ * set these flags using userspace utilities but there is also a sysfs
++ * entry available for all dev flags which can be queried and set. These flags
++ * are shared for all types of net_devices. The sysfs entries are available
++ * via /sys/class/net/<dev>/flags. Flags which can be toggled through sysfs
++ * are annotated below, note that only a few flags can be toggled and some
++ * other flags are always preserved from the original net_device flags
++ * even if you try to set them via sysfs. Flags which are always preserved
++ * are kept under the flag grouping @IFF_VOLATILE. Flags which are volatile
++ * are annotated below as such.
++ *
++ * You should have a pretty good reason to be extending these flags.
++ *
++ * @IFF_UP: interface is up. Can be toggled through sysfs.
++ * @IFF_BROADCAST: broadcast address valid. Volatile.
++ * @IFF_DEBUG: turn on debugging. Can be toggled through sysfs.
++ * @IFF_LOOPBACK: is a loopback net. Volatile.
++ * @IFF_POINTOPOINT: interface is has p-p link. Volatile.
++ * @IFF_NOTRAILERS: avoid use of trailers. Can be toggled through sysfs.
++ *	Volatile.
++ * @IFF_RUNNING: interface RFC2863 OPER_UP. Volatile.
++ * @IFF_NOARP: no ARP protocol. Can be toggled through sysfs. Volatile.
++ * @IFF_PROMISC: receive all packets. Can be toggled through sysfs.
++ * @IFF_ALLMULTI: receive all multicast packets. Can be toggled through
++ *	sysfs.
++ * @IFF_MASTER: master of a load balancer. Volatile.
++ * @IFF_SLAVE: slave of a load balancer. Volatile.
++ * @IFF_MULTICAST: Supports multicast. Can be toggled through sysfs.
++ * @IFF_PORTSEL: can set media type. Can be toggled through sysfs.
++ * @IFF_AUTOMEDIA: auto media select active. Can be toggled through sysfs.
++ * @IFF_DYNAMIC: dialup device with changing addresses. Can be toggled
++ *	through sysfs.
++ * @IFF_LOWER_UP: driver signals L1 up. Volatile.
++ * @IFF_DORMANT: driver signals dormant. Volatile.
++ * @IFF_ECHO: echo sent packets. Volatile.
++ */
++enum net_device_flags {
++/* for compatibility with glibc net/if.h */
++#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
++	IFF_UP				= 1<<0,  /* sysfs */
++	IFF_BROADCAST			= 1<<1,  /* volatile */
++	IFF_DEBUG			= 1<<2,  /* sysfs */
++	IFF_LOOPBACK			= 1<<3,  /* volatile */
++	IFF_POINTOPOINT			= 1<<4,  /* volatile */
++	IFF_NOTRAILERS			= 1<<5,  /* sysfs */
++	IFF_RUNNING			= 1<<6,  /* volatile */
++	IFF_NOARP			= 1<<7,  /* sysfs */
++	IFF_PROMISC			= 1<<8,  /* sysfs */
++	IFF_ALLMULTI			= 1<<9,  /* sysfs */
++	IFF_MASTER			= 1<<10, /* volatile */
++	IFF_SLAVE			= 1<<11, /* volatile */
++	IFF_MULTICAST			= 1<<12, /* sysfs */
++	IFF_PORTSEL			= 1<<13, /* sysfs */
++	IFF_AUTOMEDIA			= 1<<14, /* sysfs */
++	IFF_DYNAMIC			= 1<<15, /* sysfs */
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
++#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
++	IFF_LOWER_UP			= 1<<16, /* volatile */
++	IFF_DORMANT			= 1<<17, /* volatile */
++	IFF_ECHO			= 1<<18, /* volatile */
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
++};
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
++
++/* for compatibility with glibc net/if.h */
++#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
++#define IFF_UP				IFF_UP
++#define IFF_BROADCAST			IFF_BROADCAST
++#define IFF_DEBUG			IFF_DEBUG
++#define IFF_LOOPBACK			IFF_LOOPBACK
++#define IFF_POINTOPOINT			IFF_POINTOPOINT
++#define IFF_NOTRAILERS			IFF_NOTRAILERS
++#define IFF_RUNNING			IFF_RUNNING
++#define IFF_NOARP			IFF_NOARP
++#define IFF_PROMISC			IFF_PROMISC
++#define IFF_ALLMULTI			IFF_ALLMULTI
++#define IFF_MASTER			IFF_MASTER
++#define IFF_SLAVE			IFF_SLAVE
++#define IFF_MULTICAST			IFF_MULTICAST
++#define IFF_PORTSEL			IFF_PORTSEL
++#define IFF_AUTOMEDIA			IFF_AUTOMEDIA
++#define IFF_DYNAMIC			IFF_DYNAMIC
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
++
++#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
++#define IFF_LOWER_UP			IFF_LOWER_UP
++#define IFF_DORMANT			IFF_DORMANT
++#define IFF_ECHO			IFF_ECHO
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
++
++#define IFF_VOLATILE	(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
++		IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
++
++#define IF_GET_IFACE	0x0001		/* for querying only */
++#define IF_GET_PROTO	0x0002
++
++/* For definitions see hdlc.h */
++#define IF_IFACE_V35	0x1000		/* V.35 serial interface	*/
++#define IF_IFACE_V24	0x1001		/* V.24 serial interface	*/
++#define IF_IFACE_X21	0x1002		/* X.21 serial interface	*/
++#define IF_IFACE_T1	0x1003		/* T1 telco serial interface	*/
++#define IF_IFACE_E1	0x1004		/* E1 telco serial interface	*/
++#define IF_IFACE_SYNC_SERIAL 0x1005	/* can't be set by software	*/
++#define IF_IFACE_X21D   0x1006          /* X.21 Dual Clocking (FarSite) */
++
++/* For definitions see hdlc.h */
++#define IF_PROTO_HDLC	0x2000		/* raw HDLC protocol		*/
++#define IF_PROTO_PPP	0x2001		/* PPP protocol			*/
++#define IF_PROTO_CISCO	0x2002		/* Cisco HDLC protocol		*/
++#define IF_PROTO_FR	0x2003		/* Frame Relay protocol		*/
++#define IF_PROTO_FR_ADD_PVC 0x2004	/*    Create FR PVC		*/
++#define IF_PROTO_FR_DEL_PVC 0x2005	/*    Delete FR PVC		*/
++#define IF_PROTO_X25	0x2006		/* X.25				*/
++#define IF_PROTO_HDLC_ETH 0x2007	/* raw HDLC, Ethernet emulation	*/
++#define IF_PROTO_FR_ADD_ETH_PVC 0x2008	/*  Create FR Ethernet-bridged PVC */
++#define IF_PROTO_FR_DEL_ETH_PVC 0x2009	/*  Delete FR Ethernet-bridged PVC */
++#define IF_PROTO_FR_PVC	0x200A		/* for reading PVC status	*/
++#define IF_PROTO_FR_ETH_PVC 0x200B
++#define IF_PROTO_RAW    0x200C          /* RAW Socket                   */
++
++/* RFC 2863 operational status */
++enum {
++	IF_OPER_UNKNOWN,
++	IF_OPER_NOTPRESENT,
++	IF_OPER_DOWN,
++	IF_OPER_LOWERLAYERDOWN,
++	IF_OPER_TESTING,
++	IF_OPER_DORMANT,
++	IF_OPER_UP,
++};
++
++/* link modes */
++enum {
++	IF_LINK_MODE_DEFAULT,
++	IF_LINK_MODE_DORMANT,	/* limit upward transition to dormant */
++};
++
++/*
++ *	Device mapping structure. I'd just gone off and designed a
++ *	beautiful scheme using only loadable modules with arguments
++ *	for driver options and along come the PCMCIA people 8)
++ *
++ *	Ah well. The get() side of this is good for WDSETUP, and it'll
++ *	be handy for debugging things. The set side is fine for now and
++ *	being very small might be worth keeping for clean configuration.
++ */
++
++/* for compatibility with glibc net/if.h */
++#if __UAPI_DEF_IF_IFMAP
++struct ifmap {
++	unsigned long mem_start;
++	unsigned long mem_end;
++	unsigned short base_addr;
++	unsigned char irq;
++	unsigned char dma;
++	unsigned char port;
++	/* 3 bytes spare */
++};
++#endif /* __UAPI_DEF_IF_IFMAP */
++
++struct if_settings {
++	unsigned int type;	/* Type of physical device or protocol */
++	unsigned int size;	/* Size of the data allocated by the caller */
++	union {
++		/* {atm/eth/dsl}_settings anyone ? */
++		raw_hdlc_proto		*raw_hdlc;
++		cisco_proto		*cisco;
++		fr_proto		*fr;
++		fr_proto_pvc		*fr_pvc;
++		fr_proto_pvc_info	*fr_pvc_info;
++
++		/* interface settings */
++		sync_serial_settings	*sync;
++		te1_settings		*te1;
++	} ifs_ifsu;
++};
++
++/*
++ * Interface request structure used for socket
++ * ioctl's.  All interface ioctl's must have parameter
++ * definitions which begin with ifr_name.  The
++ * remainder may be interface specific.
++ */
++
++/* for compatibility with glibc net/if.h */
++#if __UAPI_DEF_IF_IFREQ
++struct ifreq {
++#define IFHWADDRLEN	6
++	union
++	{
++		char	ifrn_name[IFNAMSIZ];		/* if name, e.g. "en0" */
++	} ifr_ifrn;
++
++	union {
++		struct	sockaddr ifru_addr;
++		struct	sockaddr ifru_dstaddr;
++		struct	sockaddr ifru_broadaddr;
++		struct	sockaddr ifru_netmask;
++		struct  sockaddr ifru_hwaddr;
++		short	ifru_flags;
++		int	ifru_ivalue;
++		int	ifru_mtu;
++		struct  ifmap ifru_map;
++		char	ifru_slave[IFNAMSIZ];	/* Just fits the size */
++		char	ifru_newname[IFNAMSIZ];
++		void *	ifru_data;
++		struct	if_settings ifru_settings;
++	} ifr_ifru;
++};
++#endif /* __UAPI_DEF_IF_IFREQ */
++
++#define ifr_name	ifr_ifrn.ifrn_name	/* interface name 	*/
++#define ifr_hwaddr	ifr_ifru.ifru_hwaddr	/* MAC address 		*/
++#define	ifr_addr	ifr_ifru.ifru_addr	/* address		*/
++#define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-p lnk	*/
++#define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address	*/
++#define	ifr_netmask	ifr_ifru.ifru_netmask	/* interface net mask	*/
++#define	ifr_flags	ifr_ifru.ifru_flags	/* flags		*/
++#define	ifr_metric	ifr_ifru.ifru_ivalue	/* metric		*/
++#define	ifr_mtu		ifr_ifru.ifru_mtu	/* mtu			*/
++#define ifr_map		ifr_ifru.ifru_map	/* device map		*/
++#define ifr_slave	ifr_ifru.ifru_slave	/* slave device		*/
++#define	ifr_data	ifr_ifru.ifru_data	/* for use by interface	*/
++#define ifr_ifindex	ifr_ifru.ifru_ivalue	/* interface index	*/
++#define ifr_bandwidth	ifr_ifru.ifru_ivalue    /* link bandwidth	*/
++#define ifr_qlen	ifr_ifru.ifru_ivalue	/* Queue length 	*/
++#define ifr_newname	ifr_ifru.ifru_newname	/* New name		*/
++#define ifr_settings	ifr_ifru.ifru_settings	/* Device/proto settings*/
++
++/*
++ * Structure used in SIOCGIFCONF request.
++ * Used to retrieve interface configuration
++ * for machine (useful for programs which
++ * must know all networks accessible).
++ */
++
++/* for compatibility with glibc net/if.h */
++#if __UAPI_DEF_IF_IFCONF
++struct ifconf  {
++	int	ifc_len;			/* size of buffer	*/
++	union {
++		char *ifcu_buf;
++		struct ifreq *ifcu_req;
++	} ifc_ifcu;
++};
++#endif /* __UAPI_DEF_IF_IFCONF */
++
++#define	ifc_buf	ifc_ifcu.ifcu_buf		/* buffer address	*/
++#define	ifc_req	ifc_ifcu.ifcu_req		/* array of structures	*/
++
++#endif /* _LINUX_IF_H */
+diff --git a/src/basic/linux/if_addr.h b/src/basic/linux/if_addr.h
+new file mode 100644
+index 0000000000..dfcf3ce009
+--- /dev/null
++++ b/src/basic/linux/if_addr.h
+@@ -0,0 +1,72 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef __LINUX_IF_ADDR_H
++#define __LINUX_IF_ADDR_H
++
++#include <linux/types.h>
++#include <linux/netlink.h>
++
++struct ifaddrmsg {
++	__u8		ifa_family;
++	__u8		ifa_prefixlen;	/* The prefix length		*/
++	__u8		ifa_flags;	/* Flags			*/
++	__u8		ifa_scope;	/* Address scope		*/
++	__u32		ifa_index;	/* Link index			*/
++};
++
++/*
++ * Important comment:
++ * IFA_ADDRESS is prefix address, rather than local interface address.
++ * It makes no difference for normally configured broadcast interfaces,
++ * but for point-to-point IFA_ADDRESS is DESTINATION address,
++ * local address is supplied in IFA_LOCAL attribute.
++ *
++ * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
++ * If present, the value from struct ifaddrmsg will be ignored.
++ */
++enum {
++	IFA_UNSPEC,
++	IFA_ADDRESS,
++	IFA_LOCAL,
++	IFA_LABEL,
++	IFA_BROADCAST,
++	IFA_ANYCAST,
++	IFA_CACHEINFO,
++	IFA_MULTICAST,
++	IFA_FLAGS,
++	IFA_RT_PRIORITY,  /* u32, priority/metric for prefix route */
++	IFA_TARGET_NETNSID,
++	__IFA_MAX,
++};
++
++#define IFA_MAX (__IFA_MAX - 1)
++
++/* ifa_flags */
++#define IFA_F_SECONDARY		0x01
++#define IFA_F_TEMPORARY		IFA_F_SECONDARY
++
++#define	IFA_F_NODAD		0x02
++#define IFA_F_OPTIMISTIC	0x04
++#define IFA_F_DADFAILED		0x08
++#define	IFA_F_HOMEADDRESS	0x10
++#define IFA_F_DEPRECATED	0x20
++#define IFA_F_TENTATIVE		0x40
++#define IFA_F_PERMANENT		0x80
++#define IFA_F_MANAGETEMPADDR	0x100
++#define IFA_F_NOPREFIXROUTE	0x200
++#define IFA_F_MCAUTOJOIN	0x400
++#define IFA_F_STABLE_PRIVACY	0x800
++
++struct ifa_cacheinfo {
++	__u32	ifa_prefered;
++	__u32	ifa_valid;
++	__u32	cstamp; /* created timestamp, hundredths of seconds */
++	__u32	tstamp; /* updated timestamp, hundredths of seconds */
++};
++
++/* backwards compatibility for userspace */
++#ifndef __KERNEL__
++#define IFA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
++#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
++#endif
++
++#endif
+diff --git a/src/basic/linux/if_arp.h b/src/basic/linux/if_arp.h
+new file mode 100644
+index 0000000000..c3cc5a9e5e
+--- /dev/null
++++ b/src/basic/linux/if_arp.h
+@@ -0,0 +1,164 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET		An implementation of the TCP/IP protocol suite for the LINUX
++ *		operating system.  INET is implemented using the  BSD Socket
++ *		interface as the means of communication with the user level.
++ *
++ *		Global definitions for the ARP (RFC 826) protocol.
++ *
++ * Version:	@(#)if_arp.h	1.0.1	04/16/93
++ *
++ * Authors:	Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
++ *		Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
++ *		Ross Biro
++ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *		Florian La Roche,
++ *		Jonathan Layes <layes@loran.com>
++ *		Arnaldo Carvalho de Melo <acme@conectiva.com.br> ARPHRD_HWX25
++ *
++ *		This program is free software; you can redistribute it and/or
++ *		modify it under the terms of the GNU General Public License
++ *		as published by the Free Software Foundation; either version
++ *		2 of the License, or (at your option) any later version.
++ */
++#ifndef _UAPI_LINUX_IF_ARP_H
++#define _UAPI_LINUX_IF_ARP_H
++
++#include <linux/netdevice.h>
++
++/* ARP protocol HARDWARE identifiers. */
++#define ARPHRD_NETROM	0		/* from KA9Q: NET/ROM pseudo	*/
++#define ARPHRD_ETHER 	1		/* Ethernet 10Mbps		*/
++#define	ARPHRD_EETHER	2		/* Experimental Ethernet	*/
++#define	ARPHRD_AX25	3		/* AX.25 Level 2		*/
++#define	ARPHRD_PRONET	4		/* PROnet token ring		*/
++#define	ARPHRD_CHAOS	5		/* Chaosnet			*/
++#define	ARPHRD_IEEE802	6		/* IEEE 802.2 Ethernet/TR/TB	*/
++#define	ARPHRD_ARCNET	7		/* ARCnet			*/
++#define	ARPHRD_APPLETLK	8		/* APPLEtalk			*/
++#define ARPHRD_DLCI	15		/* Frame Relay DLCI		*/
++#define ARPHRD_ATM	19		/* ATM 				*/
++#define ARPHRD_METRICOM	23		/* Metricom STRIP (new IANA id)	*/
++#define	ARPHRD_IEEE1394	24		/* IEEE 1394 IPv4 - RFC 2734	*/
++#define ARPHRD_EUI64	27		/* EUI-64                       */
++#define ARPHRD_INFINIBAND 32		/* InfiniBand			*/
++
++/* Dummy types for non ARP hardware */
++#define ARPHRD_SLIP	256
++#define ARPHRD_CSLIP	257
++#define ARPHRD_SLIP6	258
++#define ARPHRD_CSLIP6	259
++#define ARPHRD_RSRVD	260		/* Notional KISS type 		*/
++#define ARPHRD_ADAPT	264
++#define ARPHRD_ROSE	270
++#define ARPHRD_X25	271		/* CCITT X.25			*/
++#define ARPHRD_HWX25	272		/* Boards with X.25 in firmware	*/
++#define ARPHRD_CAN	280		/* Controller Area Network      */
++#define ARPHRD_PPP	512
++#define ARPHRD_CISCO	513		/* Cisco HDLC	 		*/
++#define ARPHRD_HDLC	ARPHRD_CISCO
++#define ARPHRD_LAPB	516		/* LAPB				*/
++#define ARPHRD_DDCMP    517		/* Digital's DDCMP protocol     */
++#define ARPHRD_RAWHDLC	518		/* Raw HDLC			*/
++#define ARPHRD_RAWIP    519		/* Raw IP                       */
++
++#define ARPHRD_TUNNEL	768		/* IPIP tunnel			*/
++#define ARPHRD_TUNNEL6	769		/* IP6IP6 tunnel       		*/
++#define ARPHRD_FRAD	770             /* Frame Relay Access Device    */
++#define ARPHRD_SKIP	771		/* SKIP vif			*/
++#define ARPHRD_LOOPBACK	772		/* Loopback device		*/
++#define ARPHRD_LOCALTLK 773		/* Localtalk device		*/
++#define ARPHRD_FDDI	774		/* Fiber Distributed Data Interface */
++#define ARPHRD_BIF      775             /* AP1000 BIF                   */
++#define ARPHRD_SIT	776		/* sit0 device - IPv6-in-IPv4	*/
++#define ARPHRD_IPDDP	777		/* IP over DDP tunneller	*/
++#define ARPHRD_IPGRE	778		/* GRE over IP			*/
++#define ARPHRD_PIMREG	779		/* PIMSM register interface	*/
++#define ARPHRD_HIPPI	780		/* High Performance Parallel Interface */
++#define ARPHRD_ASH	781		/* Nexus 64Mbps Ash		*/
++#define ARPHRD_ECONET	782		/* Acorn Econet			*/
++#define ARPHRD_IRDA 	783		/* Linux-IrDA			*/
++/* ARP works differently on different FC media .. so  */
++#define ARPHRD_FCPP	784		/* Point to point fibrechannel	*/
++#define ARPHRD_FCAL	785		/* Fibrechannel arbitrated loop */
++#define ARPHRD_FCPL	786		/* Fibrechannel public loop	*/
++#define ARPHRD_FCFABRIC	787		/* Fibrechannel fabric		*/
++	/* 787->799 reserved for fibrechannel media types */
++#define ARPHRD_IEEE802_TR 800		/* Magic type ident for TR	*/
++#define ARPHRD_IEEE80211 801		/* IEEE 802.11			*/
++#define ARPHRD_IEEE80211_PRISM 802	/* IEEE 802.11 + Prism2 header  */
++#define ARPHRD_IEEE80211_RADIOTAP 803	/* IEEE 802.11 + radiotap header */
++#define ARPHRD_IEEE802154	  804
++#define ARPHRD_IEEE802154_MONITOR 805	/* IEEE 802.15.4 network monitor */
++
++#define ARPHRD_PHONET	820		/* PhoNet media type		*/
++#define ARPHRD_PHONET_PIPE 821		/* PhoNet pipe header		*/
++#define ARPHRD_CAIF	822		/* CAIF media type		*/
++#define ARPHRD_IP6GRE	823		/* GRE over IPv6		*/
++#define ARPHRD_NETLINK	824		/* Netlink header		*/
++#define ARPHRD_6LOWPAN	825		/* IPv6 over LoWPAN             */
++#define ARPHRD_VSOCKMON	826		/* Vsock monitor header		*/
++
++#define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
++#define ARPHRD_NONE	  0xFFFE	/* zero header length */
++
++/* ARP protocol opcodes. */
++#define	ARPOP_REQUEST	1		/* ARP request			*/
++#define	ARPOP_REPLY	2		/* ARP reply			*/
++#define	ARPOP_RREQUEST	3		/* RARP request			*/
++#define	ARPOP_RREPLY	4		/* RARP reply			*/
++#define	ARPOP_InREQUEST	8		/* InARP request		*/
++#define	ARPOP_InREPLY	9		/* InARP reply			*/
++#define	ARPOP_NAK	10		/* (ATM)ARP NAK			*/
++
++
++/* ARP ioctl request. */
++struct arpreq {
++	struct sockaddr	arp_pa;		/* protocol address		 */
++	struct sockaddr	arp_ha;		/* hardware address		 */
++	int		arp_flags;	/* flags			 */
++	struct sockaddr arp_netmask;    /* netmask (only for proxy arps) */
++	char		arp_dev[IFNAMSIZ];
++};
++
++struct arpreq_old {
++	struct sockaddr	arp_pa;		/* protocol address		 */
++	struct sockaddr	arp_ha;		/* hardware address		 */
++	int		arp_flags;	/* flags			 */
++	struct sockaddr	arp_netmask;    /* netmask (only for proxy arps) */
++};
++
++/* ARP Flag values. */
++#define ATF_COM		0x02		/* completed entry (ha valid)	*/
++#define	ATF_PERM	0x04		/* permanent entry		*/
++#define	ATF_PUBL	0x08		/* publish entry		*/
++#define	ATF_USETRAILERS	0x10		/* has requested trailers	*/
++#define ATF_NETMASK     0x20            /* want to use a netmask (only
++					   for proxy entries) */
++#define ATF_DONTPUB	0x40		/* don't answer this addresses	*/
++
++/*
++ *	This structure defines an ethernet arp header.
++ */
++
++struct arphdr {
++	__be16		ar_hrd;		/* format of hardware address	*/
++	__be16		ar_pro;		/* format of protocol address	*/
++	unsigned char	ar_hln;		/* length of hardware address	*/
++	unsigned char	ar_pln;		/* length of protocol address	*/
++	__be16		ar_op;		/* ARP opcode (command)		*/
++
++#if 0
++	 /*
++	  *	 Ethernet looks like this : This bit is variable sized however...
++	  */
++	unsigned char		ar_sha[ETH_ALEN];	/* sender hardware address	*/
++	unsigned char		ar_sip[4];		/* sender IP address		*/
++	unsigned char		ar_tha[ETH_ALEN];	/* target hardware address	*/
++	unsigned char		ar_tip[4];		/* target IP address		*/
++#endif
++
++};
++
++
++#endif /* _UAPI_LINUX_IF_ARP_H */
+diff --git a/src/basic/linux/if_bonding.h b/src/basic/linux/if_bonding.h
+new file mode 100644
+index 0000000000..61a1bf6e86
+--- /dev/null
++++ b/src/basic/linux/if_bonding.h
+@@ -0,0 +1,131 @@
++/* SPDX-License-Identifier: GPL-1.0+ WITH Linux-syscall-note */
++/*
++ * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
++ *
++ *
++ * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
++ * NCM: Network and Communications Management, Inc.
++ *
++ * BUT, I'm the one who modified it for ethernet, so:
++ * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov
++ *
++ *	This software may be used and distributed according to the terms
++ *	of the GNU Public License, incorporated herein by reference.
++ *
++ * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
++ *	- Added support for getting slave's speed and duplex via ethtool.
++ *	  Needed for 802.3ad and other future modes.
++ *
++ * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
++ *		Shmulik Hen <shmulik.hen at intel dot com>
++ *	- Enable support of modes that need to use the unique mac address of
++ *	  each slave.
++ *
++ * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
++ *		Amir Noam <amir.noam at intel dot com>
++ *	- Moved driver's private data types to bonding.h
++ *
++ * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
++ *		Tsippy Mendelson <tsippy.mendelson at intel dot com> and
++ *		Shmulik Hen <shmulik.hen at intel dot com>
++ *	- Added support for IEEE 802.3ad Dynamic link aggregation mode.
++ *
++ * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
++ *	- Added ABI version control to restore compatibility between
++ *	  new/old ifenslave and new/old bonding.
++ *
++ * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
++ *	- Code cleanup and style changes
++ *
++ * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
++ *      - added definitions for various XOR hashing policies
++ */
++
++#ifndef _LINUX_IF_BONDING_H
++#define _LINUX_IF_BONDING_H
++
++#include <linux/if.h>
++#include <linux/types.h>
++#include <linux/if_ether.h>
++
++/* userland - kernel ABI version (2003/05/08) */
++#define BOND_ABI_VERSION 2
++
++/*
++ * We can remove these ioctl definitions in 2.5.  People should use the
++ * SIOC*** versions of them instead
++ */
++#define BOND_ENSLAVE_OLD		(SIOCDEVPRIVATE)
++#define BOND_RELEASE_OLD		(SIOCDEVPRIVATE + 1)
++#define BOND_SETHWADDR_OLD		(SIOCDEVPRIVATE + 2)
++#define BOND_SLAVE_INFO_QUERY_OLD	(SIOCDEVPRIVATE + 11)
++#define BOND_INFO_QUERY_OLD		(SIOCDEVPRIVATE + 12)
++#define BOND_CHANGE_ACTIVE_OLD		(SIOCDEVPRIVATE + 13)
++
++#define BOND_CHECK_MII_STATUS	(SIOCGMIIPHY)
++
++#define BOND_MODE_ROUNDROBIN	0
++#define BOND_MODE_ACTIVEBACKUP	1
++#define BOND_MODE_XOR		2
++#define BOND_MODE_BROADCAST	3
++#define BOND_MODE_8023AD        4
++#define BOND_MODE_TLB           5
++#define BOND_MODE_ALB		6 /* TLB + RLB (receive load balancing) */
++
++/* each slave's link has 4 states */
++#define BOND_LINK_UP    0           /* link is up and running */
++#define BOND_LINK_FAIL  1           /* link has just gone down */
++#define BOND_LINK_DOWN  2           /* link has been down for too long time */
++#define BOND_LINK_BACK  3           /* link is going back */
++
++/* each slave has several states */
++#define BOND_STATE_ACTIVE       0   /* link is active */
++#define BOND_STATE_BACKUP       1   /* link is backup */
++
++#define BOND_DEFAULT_MAX_BONDS  1   /* Default maximum number of devices to support */
++
++#define BOND_DEFAULT_TX_QUEUES 16   /* Default number of tx queues per device */
++
++#define BOND_DEFAULT_RESEND_IGMP	1 /* Default number of IGMP membership reports */
++
++/* hashing types */
++#define BOND_XMIT_POLICY_LAYER2		0 /* layer 2 (MAC only), default */
++#define BOND_XMIT_POLICY_LAYER34	1 /* layer 3+4 (IP ^ (TCP || UDP)) */
++#define BOND_XMIT_POLICY_LAYER23	2 /* layer 2+3 (IP ^ MAC) */
++#define BOND_XMIT_POLICY_ENCAP23	3 /* encapsulated layer 2+3 */
++#define BOND_XMIT_POLICY_ENCAP34	4 /* encapsulated layer 3+4 */
++
++typedef struct ifbond {
++	__s32 bond_mode;
++	__s32 num_slaves;
++	__s32 miimon;
++} ifbond;
++
++typedef struct ifslave {
++	__s32 slave_id; /* Used as an IN param to the BOND_SLAVE_INFO_QUERY ioctl */
++	char slave_name[IFNAMSIZ];
++	__s8 link;
++	__s8 state;
++	__u32  link_failure_count;
++} ifslave;
++
++struct ad_info {
++	__u16 aggregator_id;
++	__u16 ports;
++	__u16 actor_key;
++	__u16 partner_key;
++	__u8 partner_system[ETH_ALEN];
++};
++
++#endif /* _LINUX_IF_BONDING_H */
++
++/*
++ * Local variables:
++ *  version-control: t
++ *  kept-new-versions: 5
++ *  c-indent-level: 8
++ *  c-basic-offset: 8
++ *  tab-width: 8
++ * End:
++ */
++
+diff --git a/src/basic/linux/if_bridge.h b/src/basic/linux/if_bridge.h
+new file mode 100644
+index 0000000000..773e476a8e
+--- /dev/null
++++ b/src/basic/linux/if_bridge.h
+@@ -0,0 +1,316 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ *	Linux ethernet bridge
++ *
++ *	Authors:
++ *	Lennert Buytenhek		<buytenh@gnu.org>
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the GNU General Public License
++ *	as published by the Free Software Foundation; either version
++ *	2 of the License, or (at your option) any later version.
++ */
++
++#ifndef _UAPI_LINUX_IF_BRIDGE_H
++#define _UAPI_LINUX_IF_BRIDGE_H
++
++#include <linux/types.h>
++#include <linux/if_ether.h>
++#include <linux/in6.h>
++
++#define SYSFS_BRIDGE_ATTR	"bridge"
++#define SYSFS_BRIDGE_FDB	"brforward"
++#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
++#define SYSFS_BRIDGE_PORT_ATTR	"brport"
++#define SYSFS_BRIDGE_PORT_LINK	"bridge"
++
++#define BRCTL_VERSION 1
++
++#define BRCTL_GET_VERSION 0
++#define BRCTL_GET_BRIDGES 1
++#define BRCTL_ADD_BRIDGE 2
++#define BRCTL_DEL_BRIDGE 3
++#define BRCTL_ADD_IF 4
++#define BRCTL_DEL_IF 5
++#define BRCTL_GET_BRIDGE_INFO 6
++#define BRCTL_GET_PORT_LIST 7
++#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
++#define BRCTL_SET_BRIDGE_HELLO_TIME 9
++#define BRCTL_SET_BRIDGE_MAX_AGE 10
++#define BRCTL_SET_AGEING_TIME 11
++#define BRCTL_SET_GC_INTERVAL 12
++#define BRCTL_GET_PORT_INFO 13
++#define BRCTL_SET_BRIDGE_STP_STATE 14
++#define BRCTL_SET_BRIDGE_PRIORITY 15
++#define BRCTL_SET_PORT_PRIORITY 16
++#define BRCTL_SET_PATH_COST 17
++#define BRCTL_GET_FDB_ENTRIES 18
++
++#define BR_STATE_DISABLED 0
++#define BR_STATE_LISTENING 1
++#define BR_STATE_LEARNING 2
++#define BR_STATE_FORWARDING 3
++#define BR_STATE_BLOCKING 4
++
++struct __bridge_info {
++	__u64 designated_root;
++	__u64 bridge_id;
++	__u32 root_path_cost;
++	__u32 max_age;
++	__u32 hello_time;
++	__u32 forward_delay;
++	__u32 bridge_max_age;
++	__u32 bridge_hello_time;
++	__u32 bridge_forward_delay;
++	__u8 topology_change;
++	__u8 topology_change_detected;
++	__u8 root_port;
++	__u8 stp_enabled;
++	__u32 ageing_time;
++	__u32 gc_interval;
++	__u32 hello_timer_value;
++	__u32 tcn_timer_value;
++	__u32 topology_change_timer_value;
++	__u32 gc_timer_value;
++};
++
++struct __port_info {
++	__u64 designated_root;
++	__u64 designated_bridge;
++	__u16 port_id;
++	__u16 designated_port;
++	__u32 path_cost;
++	__u32 designated_cost;
++	__u8 state;
++	__u8 top_change_ack;
++	__u8 config_pending;
++	__u8 unused0;
++	__u32 message_age_timer_value;
++	__u32 forward_delay_timer_value;
++	__u32 hold_timer_value;
++};
++
++struct __fdb_entry {
++	__u8 mac_addr[ETH_ALEN];
++	__u8 port_no;
++	__u8 is_local;
++	__u32 ageing_timer_value;
++	__u8 port_hi;
++	__u8 pad0;
++	__u16 unused;
++};
++
++/* Bridge Flags */
++#define BRIDGE_FLAGS_MASTER	1	/* Bridge command to/from master */
++#define BRIDGE_FLAGS_SELF	2	/* Bridge command to/from lowerdev */
++
++#define BRIDGE_MODE_VEB		0	/* Default loopback mode */
++#define BRIDGE_MODE_VEPA	1	/* 802.1Qbg defined VEPA mode */
++#define BRIDGE_MODE_UNDEF	0xFFFF  /* mode undefined */
++
++/* Bridge management nested attributes
++ * [IFLA_AF_SPEC] = {
++ *     [IFLA_BRIDGE_FLAGS]
++ *     [IFLA_BRIDGE_MODE]
++ *     [IFLA_BRIDGE_VLAN_INFO]
++ * }
++ */
++enum {
++	IFLA_BRIDGE_FLAGS,
++	IFLA_BRIDGE_MODE,
++	IFLA_BRIDGE_VLAN_INFO,
++	IFLA_BRIDGE_VLAN_TUNNEL_INFO,
++	__IFLA_BRIDGE_MAX,
++};
++#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
++
++#define BRIDGE_VLAN_INFO_MASTER	(1<<0)	/* Operate on Bridge device as well */
++#define BRIDGE_VLAN_INFO_PVID	(1<<1)	/* VLAN is PVID, ingress untagged */
++#define BRIDGE_VLAN_INFO_UNTAGGED	(1<<2)	/* VLAN egresses untagged */
++#define BRIDGE_VLAN_INFO_RANGE_BEGIN	(1<<3) /* VLAN is start of vlan range */
++#define BRIDGE_VLAN_INFO_RANGE_END	(1<<4) /* VLAN is end of vlan range */
++#define BRIDGE_VLAN_INFO_BRENTRY	(1<<5) /* Global bridge VLAN entry */
++
++struct bridge_vlan_info {
++	__u16 flags;
++	__u16 vid;
++};
++
++enum {
++	IFLA_BRIDGE_VLAN_TUNNEL_UNSPEC,
++	IFLA_BRIDGE_VLAN_TUNNEL_ID,
++	IFLA_BRIDGE_VLAN_TUNNEL_VID,
++	IFLA_BRIDGE_VLAN_TUNNEL_FLAGS,
++	__IFLA_BRIDGE_VLAN_TUNNEL_MAX,
++};
++
++#define IFLA_BRIDGE_VLAN_TUNNEL_MAX (__IFLA_BRIDGE_VLAN_TUNNEL_MAX - 1)
++
++struct bridge_vlan_xstats {
++	__u64 rx_bytes;
++	__u64 rx_packets;
++	__u64 tx_bytes;
++	__u64 tx_packets;
++	__u16 vid;
++	__u16 flags;
++	__u32 pad2;
++};
++
++/* Bridge multicast database attributes
++ * [MDBA_MDB] = {
++ *     [MDBA_MDB_ENTRY] = {
++ *         [MDBA_MDB_ENTRY_INFO] {
++ *		struct br_mdb_entry
++ *		[MDBA_MDB_EATTR attributes]
++ *         }
++ *     }
++ * }
++ * [MDBA_ROUTER] = {
++ *    [MDBA_ROUTER_PORT] = {
++ *        u32 ifindex
++ *        [MDBA_ROUTER_PATTR attributes]
++ *    }
++ * }
++ */
++enum {
++	MDBA_UNSPEC,
++	MDBA_MDB,
++	MDBA_ROUTER,
++	__MDBA_MAX,
++};
++#define MDBA_MAX (__MDBA_MAX - 1)
++
++enum {
++	MDBA_MDB_UNSPEC,
++	MDBA_MDB_ENTRY,
++	__MDBA_MDB_MAX,
++};
++#define MDBA_MDB_MAX (__MDBA_MDB_MAX - 1)
++
++enum {
++	MDBA_MDB_ENTRY_UNSPEC,
++	MDBA_MDB_ENTRY_INFO,
++	__MDBA_MDB_ENTRY_MAX,
++};
++#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1)
++
++/* per mdb entry additional attributes */
++enum {
++	MDBA_MDB_EATTR_UNSPEC,
++	MDBA_MDB_EATTR_TIMER,
++	__MDBA_MDB_EATTR_MAX
++};
++#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
++
++/* multicast router types */
++enum {
++	MDB_RTR_TYPE_DISABLED,
++	MDB_RTR_TYPE_TEMP_QUERY,
++	MDB_RTR_TYPE_PERM,
++	MDB_RTR_TYPE_TEMP
++};
++
++enum {
++	MDBA_ROUTER_UNSPEC,
++	MDBA_ROUTER_PORT,
++	__MDBA_ROUTER_MAX,
++};
++#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
++
++/* router port attributes */
++enum {
++	MDBA_ROUTER_PATTR_UNSPEC,
++	MDBA_ROUTER_PATTR_TIMER,
++	MDBA_ROUTER_PATTR_TYPE,
++	__MDBA_ROUTER_PATTR_MAX
++};
++#define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
++
++struct br_port_msg {
++	__u8  family;
++	__u32 ifindex;
++};
++
++struct br_mdb_entry {
++	__u32 ifindex;
++#define MDB_TEMPORARY 0
++#define MDB_PERMANENT 1
++	__u8 state;
++#define MDB_FLAGS_OFFLOAD	(1 << 0)
++	__u8 flags;
++	__u16 vid;
++	struct {
++		union {
++			__be32	ip4;
++			struct in6_addr ip6;
++		} u;
++		__be16		proto;
++	} addr;
++};
++
++enum {
++	MDBA_SET_ENTRY_UNSPEC,
++	MDBA_SET_ENTRY,
++	__MDBA_SET_ENTRY_MAX,
++};
++#define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1)
++
++/* Embedded inside LINK_XSTATS_TYPE_BRIDGE */
++enum {
++	BRIDGE_XSTATS_UNSPEC,
++	BRIDGE_XSTATS_VLAN,
++	BRIDGE_XSTATS_MCAST,
++	BRIDGE_XSTATS_PAD,
++	__BRIDGE_XSTATS_MAX
++};
++#define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1)
++
++enum {
++	BR_MCAST_DIR_RX,
++	BR_MCAST_DIR_TX,
++	BR_MCAST_DIR_SIZE
++};
++
++/* IGMP/MLD statistics */
++struct br_mcast_stats {
++	__u64 igmp_v1queries[BR_MCAST_DIR_SIZE];
++	__u64 igmp_v2queries[BR_MCAST_DIR_SIZE];
++	__u64 igmp_v3queries[BR_MCAST_DIR_SIZE];
++	__u64 igmp_leaves[BR_MCAST_DIR_SIZE];
++	__u64 igmp_v1reports[BR_MCAST_DIR_SIZE];
++	__u64 igmp_v2reports[BR_MCAST_DIR_SIZE];
++	__u64 igmp_v3reports[BR_MCAST_DIR_SIZE];
++	__u64 igmp_parse_errors;
++
++	__u64 mld_v1queries[BR_MCAST_DIR_SIZE];
++	__u64 mld_v2queries[BR_MCAST_DIR_SIZE];
++	__u64 mld_leaves[BR_MCAST_DIR_SIZE];
++	__u64 mld_v1reports[BR_MCAST_DIR_SIZE];
++	__u64 mld_v2reports[BR_MCAST_DIR_SIZE];
++	__u64 mld_parse_errors;
++
++	__u64 mcast_bytes[BR_MCAST_DIR_SIZE];
++	__u64 mcast_packets[BR_MCAST_DIR_SIZE];
++};
++
++/* bridge boolean options
++ * BR_BOOLOPT_NO_LL_LEARN - disable learning from link-local packets
++ *
++ * IMPORTANT: if adding a new option do not forget to handle
++ *            it in br_boolopt_toggle/get and bridge sysfs
++ */
++enum br_boolopt_id {
++	BR_BOOLOPT_NO_LL_LEARN,
++	BR_BOOLOPT_MAX
++};
++
++/* struct br_boolopt_multi - change multiple bridge boolean options
++ *
++ * @optval: new option values (bit per option)
++ * @optmask: options to change (bit per option)
++ */
++struct br_boolopt_multi {
++	__u32 optval;
++	__u32 optmask;
++};
++#endif /* _UAPI_LINUX_IF_BRIDGE_H */
+diff --git a/src/basic/linux/if_link.h b/src/basic/linux/if_link.h
+new file mode 100644
+index 0000000000..d653382812
+--- /dev/null
++++ b/src/basic/linux/if_link.h
+@@ -0,0 +1,1024 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI_LINUX_IF_LINK_H
++#define _UAPI_LINUX_IF_LINK_H
++
++#include <linux/types.h>
++#include <linux/netlink.h>
++
++/* This struct should be in sync with struct rtnl_link_stats64 */
++struct rtnl_link_stats {
++	__u32	rx_packets;		/* total packets received	*/
++	__u32	tx_packets;		/* total packets transmitted	*/
++	__u32	rx_bytes;		/* total bytes received 	*/
++	__u32	tx_bytes;		/* total bytes transmitted	*/
++	__u32	rx_errors;		/* bad packets received		*/
++	__u32	tx_errors;		/* packet transmit problems	*/
++	__u32	rx_dropped;		/* no space in linux buffers	*/
++	__u32	tx_dropped;		/* no space available in linux	*/
++	__u32	multicast;		/* multicast packets received	*/
++	__u32	collisions;
++
++	/* detailed rx_errors: */
++	__u32	rx_length_errors;
++	__u32	rx_over_errors;		/* receiver ring buff overflow	*/
++	__u32	rx_crc_errors;		/* recved pkt with crc error	*/
++	__u32	rx_frame_errors;	/* recv'd frame alignment error */
++	__u32	rx_fifo_errors;		/* recv'r fifo overrun		*/
++	__u32	rx_missed_errors;	/* receiver missed packet	*/
++
++	/* detailed tx_errors */
++	__u32	tx_aborted_errors;
++	__u32	tx_carrier_errors;
++	__u32	tx_fifo_errors;
++	__u32	tx_heartbeat_errors;
++	__u32	tx_window_errors;
++
++	/* for cslip etc */
++	__u32	rx_compressed;
++	__u32	tx_compressed;
++
++	__u32	rx_nohandler;		/* dropped, no handler found	*/
++};
++
++/* The main device statistics structure */
++struct rtnl_link_stats64 {
++	__u64	rx_packets;		/* total packets received	*/
++	__u64	tx_packets;		/* total packets transmitted	*/
++	__u64	rx_bytes;		/* total bytes received 	*/
++	__u64	tx_bytes;		/* total bytes transmitted	*/
++	__u64	rx_errors;		/* bad packets received		*/
++	__u64	tx_errors;		/* packet transmit problems	*/
++	__u64	rx_dropped;		/* no space in linux buffers	*/
++	__u64	tx_dropped;		/* no space available in linux	*/
++	__u64	multicast;		/* multicast packets received	*/
++	__u64	collisions;
++
++	/* detailed rx_errors: */
++	__u64	rx_length_errors;
++	__u64	rx_over_errors;		/* receiver ring buff overflow	*/
++	__u64	rx_crc_errors;		/* recved pkt with crc error	*/
++	__u64	rx_frame_errors;	/* recv'd frame alignment error */
++	__u64	rx_fifo_errors;		/* recv'r fifo overrun		*/
++	__u64	rx_missed_errors;	/* receiver missed packet	*/
++
++	/* detailed tx_errors */
++	__u64	tx_aborted_errors;
++	__u64	tx_carrier_errors;
++	__u64	tx_fifo_errors;
++	__u64	tx_heartbeat_errors;
++	__u64	tx_window_errors;
++
++	/* for cslip etc */
++	__u64	rx_compressed;
++	__u64	tx_compressed;
++
++	__u64	rx_nohandler;		/* dropped, no handler found	*/
++};
++
++/* The struct should be in sync with struct ifmap */
++struct rtnl_link_ifmap {
++	__u64	mem_start;
++	__u64	mem_end;
++	__u64	base_addr;
++	__u16	irq;
++	__u8	dma;
++	__u8	port;
++};
++
++/*
++ * IFLA_AF_SPEC
++ *   Contains nested attributes for address family specific attributes.
++ *   Each address family may create a attribute with the address family
++ *   number as type and create its own attribute structure in it.
++ *
++ *   Example:
++ *   [IFLA_AF_SPEC] = {
++ *       [AF_INET] = {
++ *           [IFLA_INET_CONF] = ...,
++ *       },
++ *       [AF_INET6] = {
++ *           [IFLA_INET6_FLAGS] = ...,
++ *           [IFLA_INET6_CONF] = ...,
++ *       }
++ *   }
++ */
++
++enum {
++	IFLA_UNSPEC,
++	IFLA_ADDRESS,
++	IFLA_BROADCAST,
++	IFLA_IFNAME,
++	IFLA_MTU,
++	IFLA_LINK,
++	IFLA_QDISC,
++	IFLA_STATS,
++	IFLA_COST,
++#define IFLA_COST IFLA_COST
++	IFLA_PRIORITY,
++#define IFLA_PRIORITY IFLA_PRIORITY
++	IFLA_MASTER,
++#define IFLA_MASTER IFLA_MASTER
++	IFLA_WIRELESS,		/* Wireless Extension event - see wireless.h */
++#define IFLA_WIRELESS IFLA_WIRELESS
++	IFLA_PROTINFO,		/* Protocol specific information for a link */
++#define IFLA_PROTINFO IFLA_PROTINFO
++	IFLA_TXQLEN,
++#define IFLA_TXQLEN IFLA_TXQLEN
++	IFLA_MAP,
++#define IFLA_MAP IFLA_MAP
++	IFLA_WEIGHT,
++#define IFLA_WEIGHT IFLA_WEIGHT
++	IFLA_OPERSTATE,
++	IFLA_LINKMODE,
++	IFLA_LINKINFO,
++#define IFLA_LINKINFO IFLA_LINKINFO
++	IFLA_NET_NS_PID,
++	IFLA_IFALIAS,
++	IFLA_NUM_VF,		/* Number of VFs if device is SR-IOV PF */
++	IFLA_VFINFO_LIST,
++	IFLA_STATS64,
++	IFLA_VF_PORTS,
++	IFLA_PORT_SELF,
++	IFLA_AF_SPEC,
++	IFLA_GROUP,		/* Group the device belongs to */
++	IFLA_NET_NS_FD,
++	IFLA_EXT_MASK,		/* Extended info mask, VFs, etc */
++	IFLA_PROMISCUITY,	/* Promiscuity count: > 0 means acts PROMISC */
++#define IFLA_PROMISCUITY IFLA_PROMISCUITY
++	IFLA_NUM_TX_QUEUES,
++	IFLA_NUM_RX_QUEUES,
++	IFLA_CARRIER,
++	IFLA_PHYS_PORT_ID,
++	IFLA_CARRIER_CHANGES,
++	IFLA_PHYS_SWITCH_ID,
++	IFLA_LINK_NETNSID,
++	IFLA_PHYS_PORT_NAME,
++	IFLA_PROTO_DOWN,
++	IFLA_GSO_MAX_SEGS,
++	IFLA_GSO_MAX_SIZE,
++	IFLA_PAD,
++	IFLA_XDP,
++	IFLA_EVENT,
++	IFLA_NEW_NETNSID,
++	IFLA_IF_NETNSID,
++	IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */
++	IFLA_CARRIER_UP_COUNT,
++	IFLA_CARRIER_DOWN_COUNT,
++	IFLA_NEW_IFINDEX,
++	IFLA_MIN_MTU,
++	IFLA_MAX_MTU,
++	__IFLA_MAX
++};
++
++
++#define IFLA_MAX (__IFLA_MAX - 1)
++
++/* backwards compatibility for userspace */
++#ifndef __KERNEL__
++#define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
++#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
++#endif
++
++enum {
++	IFLA_INET_UNSPEC,
++	IFLA_INET_CONF,
++	__IFLA_INET_MAX,
++};
++
++#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
++
++/* ifi_flags.
++
++   IFF_* flags.
++
++   The only change is:
++   IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
++   more not changeable by user. They describe link media
++   characteristics and set by device driver.
++
++   Comments:
++   - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
++   - If neither of these three flags are set;
++     the interface is NBMA.
++
++   - IFF_MULTICAST does not mean anything special:
++   multicasts can be used on all not-NBMA links.
++   IFF_MULTICAST means that this media uses special encapsulation
++   for multicast frames. Apparently, all IFF_POINTOPOINT and
++   IFF_BROADCAST devices are able to use multicasts too.
++ */
++
++/* IFLA_LINK.
++   For usual devices it is equal ifi_index.
++   If it is a "virtual interface" (f.e. tunnel), ifi_link
++   can point to real physical interface (f.e. for bandwidth calculations),
++   or maybe 0, what means, that real media is unknown (usual
++   for IPIP tunnels, when route to endpoint is allowed to change)
++ */
++
++/* Subtype attributes for IFLA_PROTINFO */
++enum {
++	IFLA_INET6_UNSPEC,
++	IFLA_INET6_FLAGS,	/* link flags			*/
++	IFLA_INET6_CONF,	/* sysctl parameters		*/
++	IFLA_INET6_STATS,	/* statistics			*/
++	IFLA_INET6_MCAST,	/* MC things. What of them?	*/
++	IFLA_INET6_CACHEINFO,	/* time values and max reasm size */
++	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
++	IFLA_INET6_TOKEN,	/* device token			*/
++	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
++	__IFLA_INET6_MAX
++};
++
++#define IFLA_INET6_MAX	(__IFLA_INET6_MAX - 1)
++
++enum in6_addr_gen_mode {
++	IN6_ADDR_GEN_MODE_EUI64,
++	IN6_ADDR_GEN_MODE_NONE,
++	IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
++	IN6_ADDR_GEN_MODE_RANDOM,
++};
++
++/* Bridge section */
++
++enum {
++	IFLA_BR_UNSPEC,
++	IFLA_BR_FORWARD_DELAY,
++	IFLA_BR_HELLO_TIME,
++	IFLA_BR_MAX_AGE,
++	IFLA_BR_AGEING_TIME,
++	IFLA_BR_STP_STATE,
++	IFLA_BR_PRIORITY,
++	IFLA_BR_VLAN_FILTERING,
++	IFLA_BR_VLAN_PROTOCOL,
++	IFLA_BR_GROUP_FWD_MASK,
++	IFLA_BR_ROOT_ID,
++	IFLA_BR_BRIDGE_ID,
++	IFLA_BR_ROOT_PORT,
++	IFLA_BR_ROOT_PATH_COST,
++	IFLA_BR_TOPOLOGY_CHANGE,
++	IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
++	IFLA_BR_HELLO_TIMER,
++	IFLA_BR_TCN_TIMER,
++	IFLA_BR_TOPOLOGY_CHANGE_TIMER,
++	IFLA_BR_GC_TIMER,
++	IFLA_BR_GROUP_ADDR,
++	IFLA_BR_FDB_FLUSH,
++	IFLA_BR_MCAST_ROUTER,
++	IFLA_BR_MCAST_SNOOPING,
++	IFLA_BR_MCAST_QUERY_USE_IFADDR,
++	IFLA_BR_MCAST_QUERIER,
++	IFLA_BR_MCAST_HASH_ELASTICITY,
++	IFLA_BR_MCAST_HASH_MAX,
++	IFLA_BR_MCAST_LAST_MEMBER_CNT,
++	IFLA_BR_MCAST_STARTUP_QUERY_CNT,
++	IFLA_BR_MCAST_LAST_MEMBER_INTVL,
++	IFLA_BR_MCAST_MEMBERSHIP_INTVL,
++	IFLA_BR_MCAST_QUERIER_INTVL,
++	IFLA_BR_MCAST_QUERY_INTVL,
++	IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
++	IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
++	IFLA_BR_NF_CALL_IPTABLES,
++	IFLA_BR_NF_CALL_IP6TABLES,
++	IFLA_BR_NF_CALL_ARPTABLES,
++	IFLA_BR_VLAN_DEFAULT_PVID,
++	IFLA_BR_PAD,
++	IFLA_BR_VLAN_STATS_ENABLED,
++	IFLA_BR_MCAST_STATS_ENABLED,
++	IFLA_BR_MCAST_IGMP_VERSION,
++	IFLA_BR_MCAST_MLD_VERSION,
++	IFLA_BR_VLAN_STATS_PER_PORT,
++	IFLA_BR_MULTI_BOOLOPT,
++	__IFLA_BR_MAX,
++};
++
++#define IFLA_BR_MAX	(__IFLA_BR_MAX - 1)
++
++struct ifla_bridge_id {
++	__u8	prio[2];
++	__u8	addr[6]; /* ETH_ALEN */
++};
++
++enum {
++	BRIDGE_MODE_UNSPEC,
++	BRIDGE_MODE_HAIRPIN,
++};
++
++enum {
++	IFLA_BRPORT_UNSPEC,
++	IFLA_BRPORT_STATE,	/* Spanning tree state     */
++	IFLA_BRPORT_PRIORITY,	/* "             priority  */
++	IFLA_BRPORT_COST,	/* "             cost      */
++	IFLA_BRPORT_MODE,	/* mode (hairpin)          */
++	IFLA_BRPORT_GUARD,	/* bpdu guard              */
++	IFLA_BRPORT_PROTECT,	/* root port protection    */
++	IFLA_BRPORT_FAST_LEAVE,	/* multicast fast leave    */
++	IFLA_BRPORT_LEARNING,	/* mac learning */
++	IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
++	IFLA_BRPORT_PROXYARP,	/* proxy ARP */
++	IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
++	IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */
++	IFLA_BRPORT_ROOT_ID,	/* designated root */
++	IFLA_BRPORT_BRIDGE_ID,	/* designated bridge */
++	IFLA_BRPORT_DESIGNATED_PORT,
++	IFLA_BRPORT_DESIGNATED_COST,
++	IFLA_BRPORT_ID,
++	IFLA_BRPORT_NO,
++	IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
++	IFLA_BRPORT_CONFIG_PENDING,
++	IFLA_BRPORT_MESSAGE_AGE_TIMER,
++	IFLA_BRPORT_FORWARD_DELAY_TIMER,
++	IFLA_BRPORT_HOLD_TIMER,
++	IFLA_BRPORT_FLUSH,
++	IFLA_BRPORT_MULTICAST_ROUTER,
++	IFLA_BRPORT_PAD,
++	IFLA_BRPORT_MCAST_FLOOD,
++	IFLA_BRPORT_MCAST_TO_UCAST,
++	IFLA_BRPORT_VLAN_TUNNEL,
++	IFLA_BRPORT_BCAST_FLOOD,
++	IFLA_BRPORT_GROUP_FWD_MASK,
++	IFLA_BRPORT_NEIGH_SUPPRESS,
++	IFLA_BRPORT_ISOLATED,
++	IFLA_BRPORT_BACKUP_PORT,
++	__IFLA_BRPORT_MAX
++};
++#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
++
++struct ifla_cacheinfo {
++	__u32	max_reasm_len;
++	__u32	tstamp;		/* ipv6InterfaceTable updated timestamp */
++	__u32	reachable_time;
++	__u32	retrans_time;
++};
++
++enum {
++	IFLA_INFO_UNSPEC,
++	IFLA_INFO_KIND,
++	IFLA_INFO_DATA,
++	IFLA_INFO_XSTATS,
++	IFLA_INFO_SLAVE_KIND,
++	IFLA_INFO_SLAVE_DATA,
++	__IFLA_INFO_MAX,
++};
++
++#define IFLA_INFO_MAX	(__IFLA_INFO_MAX - 1)
++
++/* VLAN section */
++
++enum {
++	IFLA_VLAN_UNSPEC,
++	IFLA_VLAN_ID,
++	IFLA_VLAN_FLAGS,
++	IFLA_VLAN_EGRESS_QOS,
++	IFLA_VLAN_INGRESS_QOS,
++	IFLA_VLAN_PROTOCOL,
++	__IFLA_VLAN_MAX,
++};
++
++#define IFLA_VLAN_MAX	(__IFLA_VLAN_MAX - 1)
++
++struct ifla_vlan_flags {
++	__u32	flags;
++	__u32	mask;
++};
++
++enum {
++	IFLA_VLAN_QOS_UNSPEC,
++	IFLA_VLAN_QOS_MAPPING,
++	__IFLA_VLAN_QOS_MAX
++};
++
++#define IFLA_VLAN_QOS_MAX	(__IFLA_VLAN_QOS_MAX - 1)
++
++struct ifla_vlan_qos_mapping {
++	__u32 from;
++	__u32 to;
++};
++
++/* MACVLAN section */
++enum {
++	IFLA_MACVLAN_UNSPEC,
++	IFLA_MACVLAN_MODE,
++	IFLA_MACVLAN_FLAGS,
++	IFLA_MACVLAN_MACADDR_MODE,
++	IFLA_MACVLAN_MACADDR,
++	IFLA_MACVLAN_MACADDR_DATA,
++	IFLA_MACVLAN_MACADDR_COUNT,
++	__IFLA_MACVLAN_MAX,
++};
++
++#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
++
++enum macvlan_mode {
++	MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
++	MACVLAN_MODE_VEPA    = 2, /* talk to other ports through ext bridge */
++	MACVLAN_MODE_BRIDGE  = 4, /* talk to bridge ports directly */
++	MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
++	MACVLAN_MODE_SOURCE  = 16,/* use source MAC address list to assign */
++};
++
++enum macvlan_macaddr_mode {
++	MACVLAN_MACADDR_ADD,
++	MACVLAN_MACADDR_DEL,
++	MACVLAN_MACADDR_FLUSH,
++	MACVLAN_MACADDR_SET,
++};
++
++#define MACVLAN_FLAG_NOPROMISC	1
++
++/* VRF section */
++enum {
++	IFLA_VRF_UNSPEC,
++	IFLA_VRF_TABLE,
++	__IFLA_VRF_MAX
++};
++
++#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
++
++enum {
++	IFLA_VRF_PORT_UNSPEC,
++	IFLA_VRF_PORT_TABLE,
++	__IFLA_VRF_PORT_MAX
++};
++
++#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
++
++/* MACSEC section */
++enum {
++	IFLA_MACSEC_UNSPEC,
++	IFLA_MACSEC_SCI,
++	IFLA_MACSEC_PORT,
++	IFLA_MACSEC_ICV_LEN,
++	IFLA_MACSEC_CIPHER_SUITE,
++	IFLA_MACSEC_WINDOW,
++	IFLA_MACSEC_ENCODING_SA,
++	IFLA_MACSEC_ENCRYPT,
++	IFLA_MACSEC_PROTECT,
++	IFLA_MACSEC_INC_SCI,
++	IFLA_MACSEC_ES,
++	IFLA_MACSEC_SCB,
++	IFLA_MACSEC_REPLAY_PROTECT,
++	IFLA_MACSEC_VALIDATION,
++	IFLA_MACSEC_PAD,
++	__IFLA_MACSEC_MAX,
++};
++
++#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
++
++/* XFRM section */
++enum {
++	IFLA_XFRM_UNSPEC,
++	IFLA_XFRM_LINK,
++	IFLA_XFRM_IF_ID,
++	__IFLA_XFRM_MAX
++};
++
++#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1)
++
++enum macsec_validation_type {
++	MACSEC_VALIDATE_DISABLED = 0,
++	MACSEC_VALIDATE_CHECK = 1,
++	MACSEC_VALIDATE_STRICT = 2,
++	__MACSEC_VALIDATE_END,
++	MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
++};
++
++/* IPVLAN section */
++enum {
++	IFLA_IPVLAN_UNSPEC,
++	IFLA_IPVLAN_MODE,
++	IFLA_IPVLAN_FLAGS,
++	__IFLA_IPVLAN_MAX
++};
++
++#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
++
++enum ipvlan_mode {
++	IPVLAN_MODE_L2 = 0,
++	IPVLAN_MODE_L3,
++	IPVLAN_MODE_L3S,
++	IPVLAN_MODE_MAX
++};
++
++#define IPVLAN_F_PRIVATE	0x01
++#define IPVLAN_F_VEPA		0x02
++
++/* VXLAN section */
++enum {
++	IFLA_VXLAN_UNSPEC,
++	IFLA_VXLAN_ID,
++	IFLA_VXLAN_GROUP,	/* group or remote address */
++	IFLA_VXLAN_LINK,
++	IFLA_VXLAN_LOCAL,
++	IFLA_VXLAN_TTL,
++	IFLA_VXLAN_TOS,
++	IFLA_VXLAN_LEARNING,
++	IFLA_VXLAN_AGEING,
++	IFLA_VXLAN_LIMIT,
++	IFLA_VXLAN_PORT_RANGE,	/* source port */
++	IFLA_VXLAN_PROXY,
++	IFLA_VXLAN_RSC,
++	IFLA_VXLAN_L2MISS,
++	IFLA_VXLAN_L3MISS,
++	IFLA_VXLAN_PORT,	/* destination port */
++	IFLA_VXLAN_GROUP6,
++	IFLA_VXLAN_LOCAL6,
++	IFLA_VXLAN_UDP_CSUM,
++	IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
++	IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
++	IFLA_VXLAN_REMCSUM_TX,
++	IFLA_VXLAN_REMCSUM_RX,
++	IFLA_VXLAN_GBP,
++	IFLA_VXLAN_REMCSUM_NOPARTIAL,
++	IFLA_VXLAN_COLLECT_METADATA,
++	IFLA_VXLAN_LABEL,
++	IFLA_VXLAN_GPE,
++	IFLA_VXLAN_TTL_INHERIT,
++	IFLA_VXLAN_DF,
++	__IFLA_VXLAN_MAX
++};
++#define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
++
++struct ifla_vxlan_port_range {
++	__be16	low;
++	__be16	high;
++};
++
++enum ifla_vxlan_df {
++	VXLAN_DF_UNSET = 0,
++	VXLAN_DF_SET,
++	VXLAN_DF_INHERIT,
++	__VXLAN_DF_END,
++	VXLAN_DF_MAX = __VXLAN_DF_END - 1,
++};
++
++/* GENEVE section */
++enum {
++	IFLA_GENEVE_UNSPEC,
++	IFLA_GENEVE_ID,
++	IFLA_GENEVE_REMOTE,
++	IFLA_GENEVE_TTL,
++	IFLA_GENEVE_TOS,
++	IFLA_GENEVE_PORT,	/* destination port */
++	IFLA_GENEVE_COLLECT_METADATA,
++	IFLA_GENEVE_REMOTE6,
++	IFLA_GENEVE_UDP_CSUM,
++	IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
++	IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
++	IFLA_GENEVE_LABEL,
++	IFLA_GENEVE_TTL_INHERIT,
++	IFLA_GENEVE_DF,
++	__IFLA_GENEVE_MAX
++};
++#define IFLA_GENEVE_MAX	(__IFLA_GENEVE_MAX - 1)
++
++enum ifla_geneve_df {
++	GENEVE_DF_UNSET = 0,
++	GENEVE_DF_SET,
++	GENEVE_DF_INHERIT,
++	__GENEVE_DF_END,
++	GENEVE_DF_MAX = __GENEVE_DF_END - 1,
++};
++
++/* PPP section */
++enum {
++	IFLA_PPP_UNSPEC,
++	IFLA_PPP_DEV_FD,
++	__IFLA_PPP_MAX
++};
++#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
++
++/* GTP section */
++
++enum ifla_gtp_role {
++	GTP_ROLE_GGSN = 0,
++	GTP_ROLE_SGSN,
++};
++
++enum {
++	IFLA_GTP_UNSPEC,
++	IFLA_GTP_FD0,
++	IFLA_GTP_FD1,
++	IFLA_GTP_PDP_HASHSIZE,
++	IFLA_GTP_ROLE,
++	__IFLA_GTP_MAX,
++};
++#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
++
++/* Bonding section */
++
++enum {
++	IFLA_BOND_UNSPEC,
++	IFLA_BOND_MODE,
++	IFLA_BOND_ACTIVE_SLAVE,
++	IFLA_BOND_MIIMON,
++	IFLA_BOND_UPDELAY,
++	IFLA_BOND_DOWNDELAY,
++	IFLA_BOND_USE_CARRIER,
++	IFLA_BOND_ARP_INTERVAL,
++	IFLA_BOND_ARP_IP_TARGET,
++	IFLA_BOND_ARP_VALIDATE,
++	IFLA_BOND_ARP_ALL_TARGETS,
++	IFLA_BOND_PRIMARY,
++	IFLA_BOND_PRIMARY_RESELECT,
++	IFLA_BOND_FAIL_OVER_MAC,
++	IFLA_BOND_XMIT_HASH_POLICY,
++	IFLA_BOND_RESEND_IGMP,
++	IFLA_BOND_NUM_PEER_NOTIF,
++	IFLA_BOND_ALL_SLAVES_ACTIVE,
++	IFLA_BOND_MIN_LINKS,
++	IFLA_BOND_LP_INTERVAL,
++	IFLA_BOND_PACKETS_PER_SLAVE,
++	IFLA_BOND_AD_LACP_RATE,
++	IFLA_BOND_AD_SELECT,
++	IFLA_BOND_AD_INFO,
++	IFLA_BOND_AD_ACTOR_SYS_PRIO,
++	IFLA_BOND_AD_USER_PORT_KEY,
++	IFLA_BOND_AD_ACTOR_SYSTEM,
++	IFLA_BOND_TLB_DYNAMIC_LB,
++	__IFLA_BOND_MAX,
++};
++
++#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
++
++enum {
++	IFLA_BOND_AD_INFO_UNSPEC,
++	IFLA_BOND_AD_INFO_AGGREGATOR,
++	IFLA_BOND_AD_INFO_NUM_PORTS,
++	IFLA_BOND_AD_INFO_ACTOR_KEY,
++	IFLA_BOND_AD_INFO_PARTNER_KEY,
++	IFLA_BOND_AD_INFO_PARTNER_MAC,
++	__IFLA_BOND_AD_INFO_MAX,
++};
++
++#define IFLA_BOND_AD_INFO_MAX	(__IFLA_BOND_AD_INFO_MAX - 1)
++
++enum {
++	IFLA_BOND_SLAVE_UNSPEC,
++	IFLA_BOND_SLAVE_STATE,
++	IFLA_BOND_SLAVE_MII_STATUS,
++	IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
++	IFLA_BOND_SLAVE_PERM_HWADDR,
++	IFLA_BOND_SLAVE_QUEUE_ID,
++	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
++	IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
++	IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
++	__IFLA_BOND_SLAVE_MAX,
++};
++
++#define IFLA_BOND_SLAVE_MAX	(__IFLA_BOND_SLAVE_MAX - 1)
++
++/* SR-IOV virtual function management section */
++
++enum {
++	IFLA_VF_INFO_UNSPEC,
++	IFLA_VF_INFO,
++	__IFLA_VF_INFO_MAX,
++};
++
++#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
++
++enum {
++	IFLA_VF_UNSPEC,
++	IFLA_VF_MAC,		/* Hardware queue specific attributes */
++	IFLA_VF_VLAN,		/* VLAN ID and QoS */
++	IFLA_VF_TX_RATE,	/* Max TX Bandwidth Allocation */
++	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
++	IFLA_VF_LINK_STATE,	/* link state enable/disable/auto switch */
++	IFLA_VF_RATE,		/* Min and Max TX Bandwidth Allocation */
++	IFLA_VF_RSS_QUERY_EN,	/* RSS Redirection Table and Hash Key query
++				 * on/off switch
++				 */
++	IFLA_VF_STATS,		/* network device statistics */
++	IFLA_VF_TRUST,		/* Trust VF */
++	IFLA_VF_IB_NODE_GUID,	/* VF Infiniband node GUID */
++	IFLA_VF_IB_PORT_GUID,	/* VF Infiniband port GUID */
++	IFLA_VF_VLAN_LIST,	/* nested list of vlans, option for QinQ */
++	__IFLA_VF_MAX,
++};
++
++#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
++
++struct ifla_vf_mac {
++	__u32 vf;
++	__u8 mac[32]; /* MAX_ADDR_LEN */
++};
++
++struct ifla_vf_vlan {
++	__u32 vf;
++	__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
++	__u32 qos;
++};
++
++enum {
++	IFLA_VF_VLAN_INFO_UNSPEC,
++	IFLA_VF_VLAN_INFO,	/* VLAN ID, QoS and VLAN protocol */
++	__IFLA_VF_VLAN_INFO_MAX,
++};
++
++#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
++#define MAX_VLAN_LIST_LEN 1
++
++struct ifla_vf_vlan_info {
++	__u32 vf;
++	__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
++	__u32 qos;
++	__be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
++};
++
++struct ifla_vf_tx_rate {
++	__u32 vf;
++	__u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
++};
++
++struct ifla_vf_rate {
++	__u32 vf;
++	__u32 min_tx_rate; /* Min Bandwidth in Mbps */
++	__u32 max_tx_rate; /* Max Bandwidth in Mbps */
++};
++
++struct ifla_vf_spoofchk {
++	__u32 vf;
++	__u32 setting;
++};
++
++struct ifla_vf_guid {
++	__u32 vf;
++	__u64 guid;
++};
++
++enum {
++	IFLA_VF_LINK_STATE_AUTO,	/* link state of the uplink */
++	IFLA_VF_LINK_STATE_ENABLE,	/* link always up */
++	IFLA_VF_LINK_STATE_DISABLE,	/* link always down */
++	__IFLA_VF_LINK_STATE_MAX,
++};
++
++struct ifla_vf_link_state {
++	__u32 vf;
++	__u32 link_state;
++};
++
++struct ifla_vf_rss_query_en {
++	__u32 vf;
++	__u32 setting;
++};
++
++enum {
++	IFLA_VF_STATS_RX_PACKETS,
++	IFLA_VF_STATS_TX_PACKETS,
++	IFLA_VF_STATS_RX_BYTES,
++	IFLA_VF_STATS_TX_BYTES,
++	IFLA_VF_STATS_BROADCAST,
++	IFLA_VF_STATS_MULTICAST,
++	IFLA_VF_STATS_PAD,
++	IFLA_VF_STATS_RX_DROPPED,
++	IFLA_VF_STATS_TX_DROPPED,
++	__IFLA_VF_STATS_MAX,
++};
++
++#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
++
++struct ifla_vf_trust {
++	__u32 vf;
++	__u32 setting;
++};
++
++/* VF ports management section
++ *
++ *	Nested layout of set/get msg is:
++ *
++ *		[IFLA_NUM_VF]
++ *		[IFLA_VF_PORTS]
++ *			[IFLA_VF_PORT]
++ *				[IFLA_PORT_*], ...
++ *			[IFLA_VF_PORT]
++ *				[IFLA_PORT_*], ...
++ *			...
++ *		[IFLA_PORT_SELF]
++ *			[IFLA_PORT_*], ...
++ */
++
++enum {
++	IFLA_VF_PORT_UNSPEC,
++	IFLA_VF_PORT,			/* nest */
++	__IFLA_VF_PORT_MAX,
++};
++
++#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
++
++enum {
++	IFLA_PORT_UNSPEC,
++	IFLA_PORT_VF,			/* __u32 */
++	IFLA_PORT_PROFILE,		/* string */
++	IFLA_PORT_VSI_TYPE,		/* 802.1Qbg (pre-)standard VDP */
++	IFLA_PORT_INSTANCE_UUID,	/* binary UUID */
++	IFLA_PORT_HOST_UUID,		/* binary UUID */
++	IFLA_PORT_REQUEST,		/* __u8 */
++	IFLA_PORT_RESPONSE,		/* __u16, output only */
++	__IFLA_PORT_MAX,
++};
++
++#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
++
++#define PORT_PROFILE_MAX	40
++#define PORT_UUID_MAX		16
++#define PORT_SELF_VF		-1
++
++enum {
++	PORT_REQUEST_PREASSOCIATE = 0,
++	PORT_REQUEST_PREASSOCIATE_RR,
++	PORT_REQUEST_ASSOCIATE,
++	PORT_REQUEST_DISASSOCIATE,
++};
++
++enum {
++	PORT_VDP_RESPONSE_SUCCESS = 0,
++	PORT_VDP_RESPONSE_INVALID_FORMAT,
++	PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
++	PORT_VDP_RESPONSE_UNUSED_VTID,
++	PORT_VDP_RESPONSE_VTID_VIOLATION,
++	PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
++	PORT_VDP_RESPONSE_OUT_OF_SYNC,
++	/* 0x08-0xFF reserved for future VDP use */
++	PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
++	PORT_PROFILE_RESPONSE_INPROGRESS,
++	PORT_PROFILE_RESPONSE_INVALID,
++	PORT_PROFILE_RESPONSE_BADSTATE,
++	PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
++	PORT_PROFILE_RESPONSE_ERROR,
++};
++
++struct ifla_port_vsi {
++	__u8 vsi_mgr_id;
++	__u8 vsi_type_id[3];
++	__u8 vsi_type_version;
++	__u8 pad[3];
++};
++
++
++/* IPoIB section */
++
++enum {
++	IFLA_IPOIB_UNSPEC,
++	IFLA_IPOIB_PKEY,
++	IFLA_IPOIB_MODE,
++	IFLA_IPOIB_UMCAST,
++	__IFLA_IPOIB_MAX
++};
++
++enum {
++	IPOIB_MODE_DATAGRAM  = 0, /* using unreliable datagram QPs */
++	IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
++};
++
++#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
++
++
++/* HSR section */
++
++enum {
++	IFLA_HSR_UNSPEC,
++	IFLA_HSR_SLAVE1,
++	IFLA_HSR_SLAVE2,
++	IFLA_HSR_MULTICAST_SPEC,	/* Last byte of supervision addr */
++	IFLA_HSR_SUPERVISION_ADDR,	/* Supervision frame multicast addr */
++	IFLA_HSR_SEQ_NR,
++	IFLA_HSR_VERSION,		/* HSR version */
++	__IFLA_HSR_MAX,
++};
++
++#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
++
++/* STATS section */
++
++struct if_stats_msg {
++	__u8  family;
++	__u8  pad1;
++	__u16 pad2;
++	__u32 ifindex;
++	__u32 filter_mask;
++};
++
++/* A stats attribute can be netdev specific or a global stat.
++ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
++ */
++enum {
++	IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
++	IFLA_STATS_LINK_64,
++	IFLA_STATS_LINK_XSTATS,
++	IFLA_STATS_LINK_XSTATS_SLAVE,
++	IFLA_STATS_LINK_OFFLOAD_XSTATS,
++	IFLA_STATS_AF_SPEC,
++	__IFLA_STATS_MAX,
++};
++
++#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
++
++#define IFLA_STATS_FILTER_BIT(ATTR)	(1 << (ATTR - 1))
++
++/* These are embedded into IFLA_STATS_LINK_XSTATS:
++ * [IFLA_STATS_LINK_XSTATS]
++ * -> [LINK_XSTATS_TYPE_xxx]
++ *    -> [rtnl link type specific attributes]
++ */
++enum {
++	LINK_XSTATS_TYPE_UNSPEC,
++	LINK_XSTATS_TYPE_BRIDGE,
++	__LINK_XSTATS_TYPE_MAX
++};
++#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
++
++/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */
++enum {
++	IFLA_OFFLOAD_XSTATS_UNSPEC,
++	IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */
++	__IFLA_OFFLOAD_XSTATS_MAX
++};
++#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
++
++/* XDP section */
++
++#define XDP_FLAGS_UPDATE_IF_NOEXIST	(1U << 0)
++#define XDP_FLAGS_SKB_MODE		(1U << 1)
++#define XDP_FLAGS_DRV_MODE		(1U << 2)
++#define XDP_FLAGS_HW_MODE		(1U << 3)
++#define XDP_FLAGS_MODES			(XDP_FLAGS_SKB_MODE | \
++					 XDP_FLAGS_DRV_MODE | \
++					 XDP_FLAGS_HW_MODE)
++#define XDP_FLAGS_MASK			(XDP_FLAGS_UPDATE_IF_NOEXIST | \
++					 XDP_FLAGS_MODES)
++
++/* These are stored into IFLA_XDP_ATTACHED on dump. */
++enum {
++	XDP_ATTACHED_NONE = 0,
++	XDP_ATTACHED_DRV,
++	XDP_ATTACHED_SKB,
++	XDP_ATTACHED_HW,
++	XDP_ATTACHED_MULTI,
++};
++
++enum {
++	IFLA_XDP_UNSPEC,
++	IFLA_XDP_FD,
++	IFLA_XDP_ATTACHED,
++	IFLA_XDP_FLAGS,
++	IFLA_XDP_PROG_ID,
++	IFLA_XDP_DRV_PROG_ID,
++	IFLA_XDP_SKB_PROG_ID,
++	IFLA_XDP_HW_PROG_ID,
++	__IFLA_XDP_MAX,
++};
++
++#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
++
++enum {
++	IFLA_EVENT_NONE,
++	IFLA_EVENT_REBOOT,		/* internal reset / reboot */
++	IFLA_EVENT_FEATURES,		/* change in offload features */
++	IFLA_EVENT_BONDING_FAILOVER,	/* change in active slave */
++	IFLA_EVENT_NOTIFY_PEERS,	/* re-sent grat. arp/ndisc */
++	IFLA_EVENT_IGMP_RESEND,		/* re-sent IGMP JOIN */
++	IFLA_EVENT_BONDING_OPTIONS,	/* change in bonding options */
++};
++
++/* tun section */
++
++enum {
++	IFLA_TUN_UNSPEC,
++	IFLA_TUN_OWNER,
++	IFLA_TUN_GROUP,
++	IFLA_TUN_TYPE,
++	IFLA_TUN_PI,
++	IFLA_TUN_VNET_HDR,
++	IFLA_TUN_PERSIST,
++	IFLA_TUN_MULTI_QUEUE,
++	IFLA_TUN_NUM_QUEUES,
++	IFLA_TUN_NUM_DISABLED_QUEUES,
++	__IFLA_TUN_MAX,
++};
++
++#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
++
++/* rmnet section */
++
++#define RMNET_FLAGS_INGRESS_DEAGGREGATION         (1U << 0)
++#define RMNET_FLAGS_INGRESS_MAP_COMMANDS          (1U << 1)
++#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4           (1U << 2)
++#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4            (1U << 3)
++
++enum {
++	IFLA_RMNET_UNSPEC,
++	IFLA_RMNET_MUX_ID,
++	IFLA_RMNET_FLAGS,
++	__IFLA_RMNET_MAX,
++};
++
++#define IFLA_RMNET_MAX	(__IFLA_RMNET_MAX - 1)
++
++struct ifla_rmnet_flags {
++	__u32	flags;
++	__u32	mask;
++};
++
++#endif /* _UAPI_LINUX_IF_LINK_H */
+diff --git a/src/basic/linux/if_tun.h b/src/basic/linux/if_tun.h
+new file mode 100644
+index 0000000000..23a6753b37
+--- /dev/null
++++ b/src/basic/linux/if_tun.h
+@@ -0,0 +1,113 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ *  Universal TUN/TAP device driver.
++ *  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ *  GNU General Public License for more details.
++ */
++
++#ifndef _UAPI__IF_TUN_H
++#define _UAPI__IF_TUN_H
++
++#include <linux/types.h>
++#include <linux/if_ether.h>
++#include <linux/filter.h>
++
++/* Read queue size */
++#define TUN_READQ_SIZE	500
++/* TUN device type flags: deprecated. Use IFF_TUN/IFF_TAP instead. */
++#define TUN_TUN_DEV 	IFF_TUN
++#define TUN_TAP_DEV	IFF_TAP
++#define TUN_TYPE_MASK   0x000f
++
++/* Ioctl defines */
++#define TUNSETNOCSUM  _IOW('T', 200, int) 
++#define TUNSETDEBUG   _IOW('T', 201, int) 
++#define TUNSETIFF     _IOW('T', 202, int) 
++#define TUNSETPERSIST _IOW('T', 203, int) 
++#define TUNSETOWNER   _IOW('T', 204, int)
++#define TUNSETLINK    _IOW('T', 205, int)
++#define TUNSETGROUP   _IOW('T', 206, int)
++#define TUNGETFEATURES _IOR('T', 207, unsigned int)
++#define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
++#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
++#define TUNGETIFF      _IOR('T', 210, unsigned int)
++#define TUNGETSNDBUF   _IOR('T', 211, int)
++#define TUNSETSNDBUF   _IOW('T', 212, int)
++#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
++#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
++#define TUNGETVNETHDRSZ _IOR('T', 215, int)
++#define TUNSETVNETHDRSZ _IOW('T', 216, int)
++#define TUNSETQUEUE  _IOW('T', 217, int)
++#define TUNSETIFINDEX	_IOW('T', 218, unsigned int)
++#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
++#define TUNSETVNETLE _IOW('T', 220, int)
++#define TUNGETVNETLE _IOR('T', 221, int)
++/* The TUNSETVNETBE and TUNGETVNETBE ioctls are for cross-endian support on
++ * little-endian hosts. Not all kernel configurations support them, but all
++ * configurations that support SET also support GET.
++ */
++#define TUNSETVNETBE _IOW('T', 222, int)
++#define TUNGETVNETBE _IOR('T', 223, int)
++#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
++#define TUNSETFILTEREBPF _IOR('T', 225, int)
++#define TUNSETCARRIER _IOW('T', 226, int)
++
++/* TUNSETIFF ifr flags */
++#define IFF_TUN		0x0001
++#define IFF_TAP		0x0002
++#define IFF_NAPI	0x0010
++#define IFF_NAPI_FRAGS	0x0020
++#define IFF_NO_PI	0x1000
++/* This flag has no real effect */
++#define IFF_ONE_QUEUE	0x2000
++#define IFF_VNET_HDR	0x4000
++#define IFF_TUN_EXCL	0x8000
++#define IFF_MULTI_QUEUE 0x0100
++#define IFF_ATTACH_QUEUE 0x0200
++#define IFF_DETACH_QUEUE 0x0400
++/* read-only flag */
++#define IFF_PERSIST	0x0800
++#define IFF_NOFILTER	0x1000
++
++/* Socket options */
++#define TUN_TX_TIMESTAMP 1
++
++/* Features for GSO (TUNSETOFFLOAD). */
++#define TUN_F_CSUM	0x01	/* You can hand me unchecksummed packets. */
++#define TUN_F_TSO4	0x02	/* I can handle TSO for IPv4 packets */
++#define TUN_F_TSO6	0x04	/* I can handle TSO for IPv6 packets */
++#define TUN_F_TSO_ECN	0x08	/* I can handle TSO with ECN bits. */
++#define TUN_F_UFO	0x10	/* I can handle UFO packets */
++
++/* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
++#define TUN_PKT_STRIP	0x0001
++struct tun_pi {
++	__u16  flags;
++	__be16 proto;
++};
++
++/*
++ * Filter spec (used for SETXXFILTER ioctls)
++ * This stuff is applicable only to the TAP (Ethernet) devices.
++ * If the count is zero the filter is disabled and the driver accepts
++ * all packets (promisc mode).
++ * If the filter is enabled in order to accept broadcast packets
++ * broadcast addr must be explicitly included in the addr list.
++ */
++#define TUN_FLT_ALLMULTI 0x0001 /* Accept all multicast packets */
++struct tun_filter {
++	__u16  flags; /* TUN_FLT_ flags see above */
++	__u16  count; /* Number of addresses */
++	__u8   addr[0][ETH_ALEN];
++};
++
++#endif /* _UAPI__IF_TUN_H */
+diff --git a/src/basic/linux/if_tunnel.h b/src/basic/linux/if_tunnel.h
+new file mode 100644
+index 0000000000..7d9105533c
+--- /dev/null
++++ b/src/basic/linux/if_tunnel.h
+@@ -0,0 +1,183 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI_IF_TUNNEL_H_
++#define _UAPI_IF_TUNNEL_H_
++
++#include <linux/types.h>
++#include <linux/if.h>
++#include <linux/ip.h>
++#include <linux/in6.h>
++#include <asm/byteorder.h>
++
++
++#define SIOCGETTUNNEL   (SIOCDEVPRIVATE + 0)
++#define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
++#define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
++#define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
++#define SIOCGETPRL      (SIOCDEVPRIVATE + 4)
++#define SIOCADDPRL      (SIOCDEVPRIVATE + 5)
++#define SIOCDELPRL      (SIOCDEVPRIVATE + 6)
++#define SIOCCHGPRL      (SIOCDEVPRIVATE + 7)
++#define SIOCGET6RD      (SIOCDEVPRIVATE + 8)
++#define SIOCADD6RD      (SIOCDEVPRIVATE + 9)
++#define SIOCDEL6RD      (SIOCDEVPRIVATE + 10)
++#define SIOCCHG6RD      (SIOCDEVPRIVATE + 11)
++
++#define GRE_CSUM	__cpu_to_be16(0x8000)
++#define GRE_ROUTING	__cpu_to_be16(0x4000)
++#define GRE_KEY		__cpu_to_be16(0x2000)
++#define GRE_SEQ		__cpu_to_be16(0x1000)
++#define GRE_STRICT	__cpu_to_be16(0x0800)
++#define GRE_REC		__cpu_to_be16(0x0700)
++#define GRE_ACK		__cpu_to_be16(0x0080)
++#define GRE_FLAGS	__cpu_to_be16(0x0078)
++#define GRE_VERSION	__cpu_to_be16(0x0007)
++
++#define GRE_IS_CSUM(f)		((f) & GRE_CSUM)
++#define GRE_IS_ROUTING(f)	((f) & GRE_ROUTING)
++#define GRE_IS_KEY(f)		((f) & GRE_KEY)
++#define GRE_IS_SEQ(f)		((f) & GRE_SEQ)
++#define GRE_IS_STRICT(f)	((f) & GRE_STRICT)
++#define GRE_IS_REC(f)		((f) & GRE_REC)
++#define GRE_IS_ACK(f)		((f) & GRE_ACK)
++
++#define GRE_VERSION_0		__cpu_to_be16(0x0000)
++#define GRE_VERSION_1		__cpu_to_be16(0x0001)
++#define GRE_PROTO_PPP		__cpu_to_be16(0x880b)
++#define GRE_PPTP_KEY_MASK	__cpu_to_be32(0xffff)
++
++struct ip_tunnel_parm {
++	char			name[IFNAMSIZ];
++	int			link;
++	__be16			i_flags;
++	__be16			o_flags;
++	__be32			i_key;
++	__be32			o_key;
++	struct iphdr		iph;
++};
++
++enum {
++	IFLA_IPTUN_UNSPEC,
++	IFLA_IPTUN_LINK,
++	IFLA_IPTUN_LOCAL,
++	IFLA_IPTUN_REMOTE,
++	IFLA_IPTUN_TTL,
++	IFLA_IPTUN_TOS,
++	IFLA_IPTUN_ENCAP_LIMIT,
++	IFLA_IPTUN_FLOWINFO,
++	IFLA_IPTUN_FLAGS,
++	IFLA_IPTUN_PROTO,
++	IFLA_IPTUN_PMTUDISC,
++	IFLA_IPTUN_6RD_PREFIX,
++	IFLA_IPTUN_6RD_RELAY_PREFIX,
++	IFLA_IPTUN_6RD_PREFIXLEN,
++	IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
++	IFLA_IPTUN_ENCAP_TYPE,
++	IFLA_IPTUN_ENCAP_FLAGS,
++	IFLA_IPTUN_ENCAP_SPORT,
++	IFLA_IPTUN_ENCAP_DPORT,
++	IFLA_IPTUN_COLLECT_METADATA,
++	IFLA_IPTUN_FWMARK,
++	__IFLA_IPTUN_MAX,
++};
++#define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
++
++enum tunnel_encap_types {
++	TUNNEL_ENCAP_NONE,
++	TUNNEL_ENCAP_FOU,
++	TUNNEL_ENCAP_GUE,
++	TUNNEL_ENCAP_MPLS,
++};
++
++#define TUNNEL_ENCAP_FLAG_CSUM		(1<<0)
++#define TUNNEL_ENCAP_FLAG_CSUM6		(1<<1)
++#define TUNNEL_ENCAP_FLAG_REMCSUM	(1<<2)
++
++/* SIT-mode i_flags */
++#define	SIT_ISATAP	0x0001
++
++struct ip_tunnel_prl {
++	__be32			addr;
++	__u16			flags;
++	__u16			__reserved;
++	__u32			datalen;
++	__u32			__reserved2;
++	/* data follows */
++};
++
++/* PRL flags */
++#define	PRL_DEFAULT		0x0001
++
++struct ip_tunnel_6rd {
++	struct in6_addr		prefix;
++	__be32			relay_prefix;
++	__u16			prefixlen;
++	__u16			relay_prefixlen;
++};
++
++enum {
++	IFLA_GRE_UNSPEC,
++	IFLA_GRE_LINK,
++	IFLA_GRE_IFLAGS,
++	IFLA_GRE_OFLAGS,
++	IFLA_GRE_IKEY,
++	IFLA_GRE_OKEY,
++	IFLA_GRE_LOCAL,
++	IFLA_GRE_REMOTE,
++	IFLA_GRE_TTL,
++	IFLA_GRE_TOS,
++	IFLA_GRE_PMTUDISC,
++	IFLA_GRE_ENCAP_LIMIT,
++	IFLA_GRE_FLOWINFO,
++	IFLA_GRE_FLAGS,
++	IFLA_GRE_ENCAP_TYPE,
++	IFLA_GRE_ENCAP_FLAGS,
++	IFLA_GRE_ENCAP_SPORT,
++	IFLA_GRE_ENCAP_DPORT,
++	IFLA_GRE_COLLECT_METADATA,
++	IFLA_GRE_IGNORE_DF,
++	IFLA_GRE_FWMARK,
++	IFLA_GRE_ERSPAN_INDEX,
++	IFLA_GRE_ERSPAN_VER,
++	IFLA_GRE_ERSPAN_DIR,
++	IFLA_GRE_ERSPAN_HWID,
++	__IFLA_GRE_MAX,
++};
++
++#define IFLA_GRE_MAX	(__IFLA_GRE_MAX - 1)
++
++/* VTI-mode i_flags */
++#define VTI_ISVTI ((__force __be16)0x0001)
++
++enum {
++	IFLA_VTI_UNSPEC,
++	IFLA_VTI_LINK,
++	IFLA_VTI_IKEY,
++	IFLA_VTI_OKEY,
++	IFLA_VTI_LOCAL,
++	IFLA_VTI_REMOTE,
++	IFLA_VTI_FWMARK,
++	__IFLA_VTI_MAX,
++};
++
++#define IFLA_VTI_MAX	(__IFLA_VTI_MAX - 1)
++
++#define TUNNEL_CSUM		__cpu_to_be16(0x01)
++#define TUNNEL_ROUTING		__cpu_to_be16(0x02)
++#define TUNNEL_KEY		__cpu_to_be16(0x04)
++#define TUNNEL_SEQ		__cpu_to_be16(0x08)
++#define TUNNEL_STRICT		__cpu_to_be16(0x10)
++#define TUNNEL_REC		__cpu_to_be16(0x20)
++#define TUNNEL_VERSION		__cpu_to_be16(0x40)
++#define TUNNEL_NO_KEY		__cpu_to_be16(0x80)
++#define TUNNEL_DONT_FRAGMENT    __cpu_to_be16(0x0100)
++#define TUNNEL_OAM		__cpu_to_be16(0x0200)
++#define TUNNEL_CRIT_OPT		__cpu_to_be16(0x0400)
++#define TUNNEL_GENEVE_OPT	__cpu_to_be16(0x0800)
++#define TUNNEL_VXLAN_OPT	__cpu_to_be16(0x1000)
++#define TUNNEL_NOCACHE		__cpu_to_be16(0x2000)
++#define TUNNEL_ERSPAN_OPT	__cpu_to_be16(0x4000)
++
++#define TUNNEL_OPTIONS_PRESENT \
++		(TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT)
++
++#endif /* _UAPI_IF_TUNNEL_H_ */
+diff --git a/src/basic/linux/libc-compat.h b/src/basic/linux/libc-compat.h
+new file mode 100644
+index 0000000000..8254c937c9
+--- /dev/null
++++ b/src/basic/linux/libc-compat.h
+@@ -0,0 +1,267 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/*
++ * Compatibility interface for userspace libc header coordination:
++ *
++ * Define compatibility macros that are used to control the inclusion or
++ * exclusion of UAPI structures and definitions in coordination with another
++ * userspace C library.
++ *
++ * This header is intended to solve the problem of UAPI definitions that
++ * conflict with userspace definitions. If a UAPI header has such conflicting
++ * definitions then the solution is as follows:
++ *
++ * * Synchronize the UAPI header and the libc headers so either one can be
++ *   used and such that the ABI is preserved. If this is not possible then
++ *   no simple compatibility interface exists (you need to write translating
++ *   wrappers and rename things) and you can't use this interface.
++ *
++ * Then follow this process:
++ *
++ * (a) Include libc-compat.h in the UAPI header.
++ *      e.g. #include <linux/libc-compat.h>
++ *     This include must be as early as possible.
++ *
++ * (b) In libc-compat.h add enough code to detect that the comflicting
++ *     userspace libc header has been included first.
++ *
++ * (c) If the userspace libc header has been included first define a set of
++ *     guard macros of the form __UAPI_DEF_FOO and set their values to 1, else
++ *     set their values to 0.
++ *
++ * (d) Back in the UAPI header with the conflicting definitions, guard the
++ *     definitions with:
++ *     #if __UAPI_DEF_FOO
++ *       ...
++ *     #endif
++ *
++ * This fixes the situation where the linux headers are included *after* the
++ * libc headers. To fix the problem with the inclusion in the other order the
++ * userspace libc headers must be fixed like this:
++ *
++ * * For all definitions that conflict with kernel definitions wrap those
++ *   defines in the following:
++ *   #if !__UAPI_DEF_FOO
++ *     ...
++ *   #endif
++ *
++ * This prevents the redefinition of a construct already defined by the kernel.
++ */
++#ifndef _UAPI_LIBC_COMPAT_H
++#define _UAPI_LIBC_COMPAT_H
++
++/* We have included glibc headers... */
++#if defined(__GLIBC__)
++
++/* Coordinate with glibc net/if.h header. */
++#if defined(_NET_IF_H) && defined(__USE_MISC)
++
++/* GLIBC headers included first so don't define anything
++ * that would already be defined. */
++
++#define __UAPI_DEF_IF_IFCONF 0
++#define __UAPI_DEF_IF_IFMAP 0
++#define __UAPI_DEF_IF_IFNAMSIZ 0
++#define __UAPI_DEF_IF_IFREQ 0
++/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
++/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
++#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
++#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
++
++#else /* _NET_IF_H */
++
++/* Linux headers included first, and we must define everything
++ * we need. The expectation is that glibc will check the
++ * __UAPI_DEF_* defines and adjust appropriately. */
++
++#define __UAPI_DEF_IF_IFCONF 1
++#define __UAPI_DEF_IF_IFMAP 1
++#define __UAPI_DEF_IF_IFNAMSIZ 1
++#define __UAPI_DEF_IF_IFREQ 1
++/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
++/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
++
++#endif /* _NET_IF_H */
++
++/* Coordinate with glibc netinet/in.h header. */
++#if defined(_NETINET_IN_H)
++
++/* GLIBC headers included first so don't define anything
++ * that would already be defined. */
++#define __UAPI_DEF_IN_ADDR		0
++#define __UAPI_DEF_IN_IPPROTO		0
++#define __UAPI_DEF_IN_PKTINFO		0
++#define __UAPI_DEF_IP_MREQ		0
++#define __UAPI_DEF_SOCKADDR_IN		0
++#define __UAPI_DEF_IN_CLASS		0
++
++#define __UAPI_DEF_IN6_ADDR		0
++/* The exception is the in6_addr macros which must be defined
++ * if the glibc code didn't define them. This guard matches
++ * the guard in glibc/inet/netinet/in.h which defines the
++ * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */
++#if defined(__USE_MISC) || defined (__USE_GNU)
++#define __UAPI_DEF_IN6_ADDR_ALT		0
++#else
++#define __UAPI_DEF_IN6_ADDR_ALT		1
++#endif
++#define __UAPI_DEF_SOCKADDR_IN6		0
++#define __UAPI_DEF_IPV6_MREQ		0
++#define __UAPI_DEF_IPPROTO_V6		0
++#define __UAPI_DEF_IPV6_OPTIONS		0
++#define __UAPI_DEF_IN6_PKTINFO		0
++#define __UAPI_DEF_IP6_MTUINFO		0
++
++#else
++
++/* Linux headers included first, and we must define everything
++ * we need. The expectation is that glibc will check the
++ * __UAPI_DEF_* defines and adjust appropriately. */
++#define __UAPI_DEF_IN_ADDR		1
++#define __UAPI_DEF_IN_IPPROTO		1
++#define __UAPI_DEF_IN_PKTINFO		1
++#define __UAPI_DEF_IP_MREQ		1
++#define __UAPI_DEF_SOCKADDR_IN		1
++#define __UAPI_DEF_IN_CLASS		1
++
++#define __UAPI_DEF_IN6_ADDR		1
++/* We unconditionally define the in6_addr macros and glibc must
++ * coordinate. */
++#define __UAPI_DEF_IN6_ADDR_ALT		1
++#define __UAPI_DEF_SOCKADDR_IN6		1
++#define __UAPI_DEF_IPV6_MREQ		1
++#define __UAPI_DEF_IPPROTO_V6		1
++#define __UAPI_DEF_IPV6_OPTIONS		1
++#define __UAPI_DEF_IN6_PKTINFO		1
++#define __UAPI_DEF_IP6_MTUINFO		1
++
++#endif /* _NETINET_IN_H */
++
++/* Coordinate with glibc netipx/ipx.h header. */
++#if defined(__NETIPX_IPX_H)
++
++#define __UAPI_DEF_SOCKADDR_IPX			0
++#define __UAPI_DEF_IPX_ROUTE_DEFINITION		0
++#define __UAPI_DEF_IPX_INTERFACE_DEFINITION	0
++#define __UAPI_DEF_IPX_CONFIG_DATA		0
++#define __UAPI_DEF_IPX_ROUTE_DEF		0
++
++#else /* defined(__NETIPX_IPX_H) */
++
++#define __UAPI_DEF_SOCKADDR_IPX			1
++#define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
++#define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
++#define __UAPI_DEF_IPX_CONFIG_DATA		1
++#define __UAPI_DEF_IPX_ROUTE_DEF		1
++
++#endif /* defined(__NETIPX_IPX_H) */
++
++/* Definitions for xattr.h */
++#if defined(_SYS_XATTR_H)
++#define __UAPI_DEF_XATTR		0
++#else
++#define __UAPI_DEF_XATTR		1
++#endif
++
++/* If we did not see any headers from any supported C libraries,
++ * or we are being included in the kernel, then define everything
++ * that we need. Check for previous __UAPI_* definitions to give
++ * unsupported C libraries a way to opt out of any kernel definition. */
++#else /* !defined(__GLIBC__) */
++
++/* Definitions for if.h */
++#ifndef __UAPI_DEF_IF_IFCONF
++#define __UAPI_DEF_IF_IFCONF 1
++#endif
++#ifndef __UAPI_DEF_IF_IFMAP
++#define __UAPI_DEF_IF_IFMAP 1
++#endif
++#ifndef __UAPI_DEF_IF_IFNAMSIZ
++#define __UAPI_DEF_IF_IFNAMSIZ 1
++#endif
++#ifndef __UAPI_DEF_IF_IFREQ
++#define __UAPI_DEF_IF_IFREQ 1
++#endif
++/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
++#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
++#endif
++/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
++#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
++#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
++#endif
++
++/* Definitions for in.h */
++#ifndef __UAPI_DEF_IN_ADDR
++#define __UAPI_DEF_IN_ADDR		1
++#endif
++#ifndef __UAPI_DEF_IN_IPPROTO
++#define __UAPI_DEF_IN_IPPROTO		1
++#endif
++#ifndef __UAPI_DEF_IN_PKTINFO
++#define __UAPI_DEF_IN_PKTINFO		1
++#endif
++#ifndef __UAPI_DEF_IP_MREQ
++#define __UAPI_DEF_IP_MREQ		1
++#endif
++#ifndef __UAPI_DEF_SOCKADDR_IN
++#define __UAPI_DEF_SOCKADDR_IN		1
++#endif
++#ifndef __UAPI_DEF_IN_CLASS
++#define __UAPI_DEF_IN_CLASS		1
++#endif
++
++/* Definitions for in6.h */
++#ifndef __UAPI_DEF_IN6_ADDR
++#define __UAPI_DEF_IN6_ADDR		1
++#endif
++#ifndef __UAPI_DEF_IN6_ADDR_ALT
++#define __UAPI_DEF_IN6_ADDR_ALT		1
++#endif
++#ifndef __UAPI_DEF_SOCKADDR_IN6
++#define __UAPI_DEF_SOCKADDR_IN6		1
++#endif
++#ifndef __UAPI_DEF_IPV6_MREQ
++#define __UAPI_DEF_IPV6_MREQ		1
++#endif
++#ifndef __UAPI_DEF_IPPROTO_V6
++#define __UAPI_DEF_IPPROTO_V6		1
++#endif
++#ifndef __UAPI_DEF_IPV6_OPTIONS
++#define __UAPI_DEF_IPV6_OPTIONS		1
++#endif
++#ifndef __UAPI_DEF_IN6_PKTINFO
++#define __UAPI_DEF_IN6_PKTINFO		1
++#endif
++#ifndef __UAPI_DEF_IP6_MTUINFO
++#define __UAPI_DEF_IP6_MTUINFO		1
++#endif
++
++/* Definitions for ipx.h */
++#ifndef __UAPI_DEF_SOCKADDR_IPX
++#define __UAPI_DEF_SOCKADDR_IPX			1
++#endif
++#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
++#define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
++#endif
++#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
++#define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
++#endif
++#ifndef __UAPI_DEF_IPX_CONFIG_DATA
++#define __UAPI_DEF_IPX_CONFIG_DATA		1
++#endif
++#ifndef __UAPI_DEF_IPX_ROUTE_DEF
++#define __UAPI_DEF_IPX_ROUTE_DEF		1
++#endif
++
++/* Definitions for xattr.h */
++#ifndef __UAPI_DEF_XATTR
++#define __UAPI_DEF_XATTR		1
++#endif
++
++#endif /* __GLIBC__ */
++
++#endif /* _UAPI_LIBC_COMPAT_H */
+diff --git a/src/basic/linux/netlink.h b/src/basic/linux/netlink.h
+new file mode 100644
+index 0000000000..0a4d733177
+--- /dev/null
++++ b/src/basic/linux/netlink.h
+@@ -0,0 +1,252 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI__LINUX_NETLINK_H
++#define _UAPI__LINUX_NETLINK_H
++
++#include <linux/kernel.h>
++#include <linux/socket.h> /* for __kernel_sa_family_t */
++#include <linux/types.h>
++
++#define NETLINK_ROUTE		0	/* Routing/device hook				*/
++#define NETLINK_UNUSED		1	/* Unused number				*/
++#define NETLINK_USERSOCK	2	/* Reserved for user mode socket protocols 	*/
++#define NETLINK_FIREWALL	3	/* Unused number, formerly ip_queue		*/
++#define NETLINK_SOCK_DIAG	4	/* socket monitoring				*/
++#define NETLINK_NFLOG		5	/* netfilter/iptables ULOG */
++#define NETLINK_XFRM		6	/* ipsec */
++#define NETLINK_SELINUX		7	/* SELinux event notifications */
++#define NETLINK_ISCSI		8	/* Open-iSCSI */
++#define NETLINK_AUDIT		9	/* auditing */
++#define NETLINK_FIB_LOOKUP	10	
++#define NETLINK_CONNECTOR	11
++#define NETLINK_NETFILTER	12	/* netfilter subsystem */
++#define NETLINK_IP6_FW		13
++#define NETLINK_DNRTMSG		14	/* DECnet routing messages */
++#define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
++#define NETLINK_GENERIC		16
++/* leave room for NETLINK_DM (DM Events) */
++#define NETLINK_SCSITRANSPORT	18	/* SCSI Transports */
++#define NETLINK_ECRYPTFS	19
++#define NETLINK_RDMA		20
++#define NETLINK_CRYPTO		21	/* Crypto layer */
++#define NETLINK_SMC		22	/* SMC monitoring */
++
++#define NETLINK_INET_DIAG	NETLINK_SOCK_DIAG
++
++#define MAX_LINKS 32		
++
++struct sockaddr_nl {
++	__kernel_sa_family_t	nl_family;	/* AF_NETLINK	*/
++	unsigned short	nl_pad;		/* zero		*/
++	__u32		nl_pid;		/* port ID	*/
++       	__u32		nl_groups;	/* multicast groups mask */
++};
++
++struct nlmsghdr {
++	__u32		nlmsg_len;	/* Length of message including header */
++	__u16		nlmsg_type;	/* Message content */
++	__u16		nlmsg_flags;	/* Additional flags */
++	__u32		nlmsg_seq;	/* Sequence number */
++	__u32		nlmsg_pid;	/* Sending process port ID */
++};
++
++/* Flags values */
++
++#define NLM_F_REQUEST		0x01	/* It is request message. 	*/
++#define NLM_F_MULTI		0x02	/* Multipart message, terminated by NLMSG_DONE */
++#define NLM_F_ACK		0x04	/* Reply with ack, with zero or error code */
++#define NLM_F_ECHO		0x08	/* Echo this request 		*/
++#define NLM_F_DUMP_INTR		0x10	/* Dump was inconsistent due to sequence change */
++#define NLM_F_DUMP_FILTERED	0x20	/* Dump was filtered as requested */
++
++/* Modifiers to GET request */
++#define NLM_F_ROOT	0x100	/* specify tree	root	*/
++#define NLM_F_MATCH	0x200	/* return all matching	*/
++#define NLM_F_ATOMIC	0x400	/* atomic GET		*/
++#define NLM_F_DUMP	(NLM_F_ROOT|NLM_F_MATCH)
++
++/* Modifiers to NEW request */
++#define NLM_F_REPLACE	0x100	/* Override existing		*/
++#define NLM_F_EXCL	0x200	/* Do not touch, if it exists	*/
++#define NLM_F_CREATE	0x400	/* Create, if it does not exist	*/
++#define NLM_F_APPEND	0x800	/* Add to end of list		*/
++
++/* Modifiers to DELETE request */
++#define NLM_F_NONREC	0x100	/* Do not delete recursively	*/
++
++/* Flags for ACK message */
++#define NLM_F_CAPPED	0x100	/* request was capped */
++#define NLM_F_ACK_TLVS	0x200	/* extended ACK TVLs were included */
++
++/*
++   4.4BSD ADD		NLM_F_CREATE|NLM_F_EXCL
++   4.4BSD CHANGE	NLM_F_REPLACE
++
++   True CHANGE		NLM_F_CREATE|NLM_F_REPLACE
++   Append		NLM_F_CREATE
++   Check		NLM_F_EXCL
++ */
++
++#define NLMSG_ALIGNTO	4U
++#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
++#define NLMSG_HDRLEN	 ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
++#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
++#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
++#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
++#define NLMSG_NEXT(nlh,len)	 ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
++				  (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
++#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
++			   (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
++			   (nlh)->nlmsg_len <= (len))
++#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
++
++#define NLMSG_NOOP		0x1	/* Nothing.		*/
++#define NLMSG_ERROR		0x2	/* Error		*/
++#define NLMSG_DONE		0x3	/* End of a dump	*/
++#define NLMSG_OVERRUN		0x4	/* Data lost		*/
++
++#define NLMSG_MIN_TYPE		0x10	/* < 0x10: reserved control messages */
++
++struct nlmsgerr {
++	int		error;
++	struct nlmsghdr msg;
++	/*
++	 * followed by the message contents unless NETLINK_CAP_ACK was set
++	 * or the ACK indicates success (error == 0)
++	 * message length is aligned with NLMSG_ALIGN()
++	 */
++	/*
++	 * followed by TLVs defined in enum nlmsgerr_attrs
++	 * if NETLINK_EXT_ACK was set
++	 */
++};
++
++/**
++ * enum nlmsgerr_attrs - nlmsgerr attributes
++ * @NLMSGERR_ATTR_UNUSED: unused
++ * @NLMSGERR_ATTR_MSG: error message string (string)
++ * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
++ *	 message, counting from the beginning of the header (u32)
++ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
++ *	be used - in the success case - to identify a created
++ *	object or operation or similar (binary)
++ * @__NLMSGERR_ATTR_MAX: number of attributes
++ * @NLMSGERR_ATTR_MAX: highest attribute number
++ */
++enum nlmsgerr_attrs {
++	NLMSGERR_ATTR_UNUSED,
++	NLMSGERR_ATTR_MSG,
++	NLMSGERR_ATTR_OFFS,
++	NLMSGERR_ATTR_COOKIE,
++
++	__NLMSGERR_ATTR_MAX,
++	NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
++};
++
++#define NETLINK_ADD_MEMBERSHIP		1
++#define NETLINK_DROP_MEMBERSHIP		2
++#define NETLINK_PKTINFO			3
++#define NETLINK_BROADCAST_ERROR		4
++#define NETLINK_NO_ENOBUFS		5
++#ifndef __KERNEL__
++#define NETLINK_RX_RING			6
++#define NETLINK_TX_RING			7
++#endif
++#define NETLINK_LISTEN_ALL_NSID		8
++#define NETLINK_LIST_MEMBERSHIPS	9
++#define NETLINK_CAP_ACK			10
++#define NETLINK_EXT_ACK			11
++#define NETLINK_GET_STRICT_CHK		12
++
++struct nl_pktinfo {
++	__u32	group;
++};
++
++struct nl_mmap_req {
++	unsigned int	nm_block_size;
++	unsigned int	nm_block_nr;
++	unsigned int	nm_frame_size;
++	unsigned int	nm_frame_nr;
++};
++
++struct nl_mmap_hdr {
++	unsigned int	nm_status;
++	unsigned int	nm_len;
++	__u32		nm_group;
++	/* credentials */
++	__u32		nm_pid;
++	__u32		nm_uid;
++	__u32		nm_gid;
++};
++
++#ifndef __KERNEL__
++enum nl_mmap_status {
++	NL_MMAP_STATUS_UNUSED,
++	NL_MMAP_STATUS_RESERVED,
++	NL_MMAP_STATUS_VALID,
++	NL_MMAP_STATUS_COPY,
++	NL_MMAP_STATUS_SKIP,
++};
++
++#define NL_MMAP_MSG_ALIGNMENT		NLMSG_ALIGNTO
++#define NL_MMAP_MSG_ALIGN(sz)		__ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
++#define NL_MMAP_HDRLEN			NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
++#endif
++
++#define NET_MAJOR 36		/* Major 36 is reserved for networking 						*/
++
++enum {
++	NETLINK_UNCONNECTED = 0,
++	NETLINK_CONNECTED,
++};
++
++/*
++ *  <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
++ * +---------------------+- - -+- - - - - - - - - -+- - -+
++ * |        Header       | Pad |     Payload       | Pad |
++ * |   (struct nlattr)   | ing |                   | ing |
++ * +---------------------+- - -+- - - - - - - - - -+- - -+
++ *  <-------------- nlattr->nla_len -------------->
++ */
++
++struct nlattr {
++	__u16           nla_len;
++	__u16           nla_type;
++};
++
++/*
++ * nla_type (16 bits)
++ * +---+---+-------------------------------+
++ * | N | O | Attribute Type                |
++ * +---+---+-------------------------------+
++ * N := Carries nested attributes
++ * O := Payload stored in network byte order
++ *
++ * Note: The N and O flag are mutually exclusive.
++ */
++#define NLA_F_NESTED		(1 << 15)
++#define NLA_F_NET_BYTEORDER	(1 << 14)
++#define NLA_TYPE_MASK		~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
++
++#define NLA_ALIGNTO		4
++#define NLA_ALIGN(len)		(((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
++#define NLA_HDRLEN		((int) NLA_ALIGN(sizeof(struct nlattr)))
++
++/* Generic 32 bitflags attribute content sent to the kernel.
++ *
++ * The value is a bitmap that defines the values being set
++ * The selector is a bitmask that defines which value is legit
++ *
++ * Examples:
++ *  value = 0x0, and selector = 0x1
++ *  implies we are selecting bit 1 and we want to set its value to 0.
++ *
++ *  value = 0x2, and selector = 0x2
++ *  implies we are selecting bit 2 and we want to set its value to 1.
++ *
++ */
++struct nla_bitfield32 {
++	__u32 value;
++	__u32 selector;
++};
++
++#endif /* _UAPI__LINUX_NETLINK_H */
+diff --git a/src/basic/linux/rtnetlink.h b/src/basic/linux/rtnetlink.h
+new file mode 100644
+index 0000000000..4639936762
+--- /dev/null
++++ b/src/basic/linux/rtnetlink.h
+@@ -0,0 +1,751 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI__LINUX_RTNETLINK_H
++#define _UAPI__LINUX_RTNETLINK_H
++
++#include <linux/types.h>
++#include <linux/netlink.h>
++#include <linux/if_link.h>
++#include <linux/if_addr.h>
++#include <linux/neighbour.h>
++
++/* rtnetlink families. Values up to 127 are reserved for real address
++ * families, values above 128 may be used arbitrarily.
++ */
++#define RTNL_FAMILY_IPMR		128
++#define RTNL_FAMILY_IP6MR		129
++#define RTNL_FAMILY_MAX			129
++
++/****
++ *		Routing/neighbour discovery messages.
++ ****/
++
++/* Types of messages */
++
++enum {
++	RTM_BASE	= 16,
++#define RTM_BASE	RTM_BASE
++
++	RTM_NEWLINK	= 16,
++#define RTM_NEWLINK	RTM_NEWLINK
++	RTM_DELLINK,
++#define RTM_DELLINK	RTM_DELLINK
++	RTM_GETLINK,
++#define RTM_GETLINK	RTM_GETLINK
++	RTM_SETLINK,
++#define RTM_SETLINK	RTM_SETLINK
++
++	RTM_NEWADDR	= 20,
++#define RTM_NEWADDR	RTM_NEWADDR
++	RTM_DELADDR,
++#define RTM_DELADDR	RTM_DELADDR
++	RTM_GETADDR,
++#define RTM_GETADDR	RTM_GETADDR
++
++	RTM_NEWROUTE	= 24,
++#define RTM_NEWROUTE	RTM_NEWROUTE
++	RTM_DELROUTE,
++#define RTM_DELROUTE	RTM_DELROUTE
++	RTM_GETROUTE,
++#define RTM_GETROUTE	RTM_GETROUTE
++
++	RTM_NEWNEIGH	= 28,
++#define RTM_NEWNEIGH	RTM_NEWNEIGH
++	RTM_DELNEIGH,
++#define RTM_DELNEIGH	RTM_DELNEIGH
++	RTM_GETNEIGH,
++#define RTM_GETNEIGH	RTM_GETNEIGH
++
++	RTM_NEWRULE	= 32,
++#define RTM_NEWRULE	RTM_NEWRULE
++	RTM_DELRULE,
++#define RTM_DELRULE	RTM_DELRULE
++	RTM_GETRULE,
++#define RTM_GETRULE	RTM_GETRULE
++
++	RTM_NEWQDISC	= 36,
++#define RTM_NEWQDISC	RTM_NEWQDISC
++	RTM_DELQDISC,
++#define RTM_DELQDISC	RTM_DELQDISC
++	RTM_GETQDISC,
++#define RTM_GETQDISC	RTM_GETQDISC
++
++	RTM_NEWTCLASS	= 40,
++#define RTM_NEWTCLASS	RTM_NEWTCLASS
++	RTM_DELTCLASS,
++#define RTM_DELTCLASS	RTM_DELTCLASS
++	RTM_GETTCLASS,
++#define RTM_GETTCLASS	RTM_GETTCLASS
++
++	RTM_NEWTFILTER	= 44,
++#define RTM_NEWTFILTER	RTM_NEWTFILTER
++	RTM_DELTFILTER,
++#define RTM_DELTFILTER	RTM_DELTFILTER
++	RTM_GETTFILTER,
++#define RTM_GETTFILTER	RTM_GETTFILTER
++
++	RTM_NEWACTION	= 48,
++#define RTM_NEWACTION   RTM_NEWACTION
++	RTM_DELACTION,
++#define RTM_DELACTION   RTM_DELACTION
++	RTM_GETACTION,
++#define RTM_GETACTION   RTM_GETACTION
++
++	RTM_NEWPREFIX	= 52,
++#define RTM_NEWPREFIX	RTM_NEWPREFIX
++
++	RTM_GETMULTICAST = 58,
++#define RTM_GETMULTICAST RTM_GETMULTICAST
++
++	RTM_GETANYCAST	= 62,
++#define RTM_GETANYCAST	RTM_GETANYCAST
++
++	RTM_NEWNEIGHTBL	= 64,
++#define RTM_NEWNEIGHTBL	RTM_NEWNEIGHTBL
++	RTM_GETNEIGHTBL	= 66,
++#define RTM_GETNEIGHTBL	RTM_GETNEIGHTBL
++	RTM_SETNEIGHTBL,
++#define RTM_SETNEIGHTBL	RTM_SETNEIGHTBL
++
++	RTM_NEWNDUSEROPT = 68,
++#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
++
++	RTM_NEWADDRLABEL = 72,
++#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
++	RTM_DELADDRLABEL,
++#define RTM_DELADDRLABEL RTM_DELADDRLABEL
++	RTM_GETADDRLABEL,
++#define RTM_GETADDRLABEL RTM_GETADDRLABEL
++
++	RTM_GETDCB = 78,
++#define RTM_GETDCB RTM_GETDCB
++	RTM_SETDCB,
++#define RTM_SETDCB RTM_SETDCB
++
++	RTM_NEWNETCONF = 80,
++#define RTM_NEWNETCONF RTM_NEWNETCONF
++	RTM_DELNETCONF,
++#define RTM_DELNETCONF RTM_DELNETCONF
++	RTM_GETNETCONF = 82,
++#define RTM_GETNETCONF RTM_GETNETCONF
++
++	RTM_NEWMDB = 84,
++#define RTM_NEWMDB RTM_NEWMDB
++	RTM_DELMDB = 85,
++#define RTM_DELMDB RTM_DELMDB
++	RTM_GETMDB = 86,
++#define RTM_GETMDB RTM_GETMDB
++
++	RTM_NEWNSID = 88,
++#define RTM_NEWNSID RTM_NEWNSID
++	RTM_DELNSID = 89,
++#define RTM_DELNSID RTM_DELNSID
++	RTM_GETNSID = 90,
++#define RTM_GETNSID RTM_GETNSID
++
++	RTM_NEWSTATS = 92,
++#define RTM_NEWSTATS RTM_NEWSTATS
++	RTM_GETSTATS = 94,
++#define RTM_GETSTATS RTM_GETSTATS
++
++	RTM_NEWCACHEREPORT = 96,
++#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
++
++	RTM_NEWCHAIN = 100,
++#define RTM_NEWCHAIN RTM_NEWCHAIN
++	RTM_DELCHAIN,
++#define RTM_DELCHAIN RTM_DELCHAIN
++	RTM_GETCHAIN,
++#define RTM_GETCHAIN RTM_GETCHAIN
++
++	__RTM_MAX,
++#define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
++};
++
++#define RTM_NR_MSGTYPES	(RTM_MAX + 1 - RTM_BASE)
++#define RTM_NR_FAMILIES	(RTM_NR_MSGTYPES >> 2)
++#define RTM_FAM(cmd)	(((cmd) - RTM_BASE) >> 2)
++
++/* 
++   Generic structure for encapsulation of optional route information.
++   It is reminiscent of sockaddr, but with sa_family replaced
++   with attribute type.
++ */
++
++struct rtattr {
++	unsigned short	rta_len;
++	unsigned short	rta_type;
++};
++
++/* Macros to handle rtattributes */
++
++#define RTA_ALIGNTO	4U
++#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
++#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
++			 (rta)->rta_len >= sizeof(struct rtattr) && \
++			 (rta)->rta_len <= (len))
++#define RTA_NEXT(rta,attrlen)	((attrlen) -= RTA_ALIGN((rta)->rta_len), \
++				 (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
++#define RTA_LENGTH(len)	(RTA_ALIGN(sizeof(struct rtattr)) + (len))
++#define RTA_SPACE(len)	RTA_ALIGN(RTA_LENGTH(len))
++#define RTA_DATA(rta)   ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
++#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
++
++
++
++
++/******************************************************************************
++ *		Definitions used in routing table administration.
++ ****/
++
++struct rtmsg {
++	unsigned char		rtm_family;
++	unsigned char		rtm_dst_len;
++	unsigned char		rtm_src_len;
++	unsigned char		rtm_tos;
++
++	unsigned char		rtm_table;	/* Routing table id */
++	unsigned char		rtm_protocol;	/* Routing protocol; see below	*/
++	unsigned char		rtm_scope;	/* See below */	
++	unsigned char		rtm_type;	/* See below	*/
++
++	unsigned		rtm_flags;
++};
++
++/* rtm_type */
++
++enum {
++	RTN_UNSPEC,
++	RTN_UNICAST,		/* Gateway or direct route	*/
++	RTN_LOCAL,		/* Accept locally		*/
++	RTN_BROADCAST,		/* Accept locally as broadcast,
++				   send as broadcast */
++	RTN_ANYCAST,		/* Accept locally as broadcast,
++				   but send as unicast */
++	RTN_MULTICAST,		/* Multicast route		*/
++	RTN_BLACKHOLE,		/* Drop				*/
++	RTN_UNREACHABLE,	/* Destination is unreachable   */
++	RTN_PROHIBIT,		/* Administratively prohibited	*/
++	RTN_THROW,		/* Not in this table		*/
++	RTN_NAT,		/* Translate this address	*/
++	RTN_XRESOLVE,		/* Use external resolver	*/
++	__RTN_MAX
++};
++
++#define RTN_MAX (__RTN_MAX - 1)
++
++
++/* rtm_protocol */
++
++#define RTPROT_UNSPEC	0
++#define RTPROT_REDIRECT	1	/* Route installed by ICMP redirects;
++				   not used by current IPv4 */
++#define RTPROT_KERNEL	2	/* Route installed by kernel		*/
++#define RTPROT_BOOT	3	/* Route installed during boot		*/
++#define RTPROT_STATIC	4	/* Route installed by administrator	*/
++
++/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
++   they are just passed from user and back as is.
++   It will be used by hypothetical multiple routing daemons.
++   Note that protocol values should be standardized in order to
++   avoid conflicts.
++ */
++
++#define RTPROT_GATED	8	/* Apparently, GateD */
++#define RTPROT_RA	9	/* RDISC/ND router advertisements */
++#define RTPROT_MRT	10	/* Merit MRT */
++#define RTPROT_ZEBRA	11	/* Zebra */
++#define RTPROT_BIRD	12	/* BIRD */
++#define RTPROT_DNROUTED	13	/* DECnet routing daemon */
++#define RTPROT_XORP	14	/* XORP */
++#define RTPROT_NTK	15	/* Netsukuku */
++#define RTPROT_DHCP	16      /* DHCP client */
++#define RTPROT_MROUTED	17      /* Multicast daemon */
++#define RTPROT_BABEL	42      /* Babel daemon */
++#define RTPROT_BGP	186     /* BGP Routes */
++#define RTPROT_ISIS	187     /* ISIS Routes */
++#define RTPROT_OSPF	188     /* OSPF Routes */
++#define RTPROT_RIP	189     /* RIP Routes */
++#define RTPROT_EIGRP	192     /* EIGRP Routes */
++
++/* rtm_scope
++
++   Really it is not scope, but sort of distance to the destination.
++   NOWHERE are reserved for not existing destinations, HOST is our
++   local addresses, LINK are destinations, located on directly attached
++   link and UNIVERSE is everywhere in the Universe.
++
++   Intermediate values are also possible f.e. interior routes
++   could be assigned a value between UNIVERSE and LINK.
++*/
++
++enum rt_scope_t {
++	RT_SCOPE_UNIVERSE=0,
++/* User defined values  */
++	RT_SCOPE_SITE=200,
++	RT_SCOPE_LINK=253,
++	RT_SCOPE_HOST=254,
++	RT_SCOPE_NOWHERE=255
++};
++
++/* rtm_flags */
++
++#define RTM_F_NOTIFY		0x100	/* Notify user of route change	*/
++#define RTM_F_CLONED		0x200	/* This route is cloned		*/
++#define RTM_F_EQUALIZE		0x400	/* Multipath equalizer: NI	*/
++#define RTM_F_PREFIX		0x800	/* Prefix addresses		*/
++#define RTM_F_LOOKUP_TABLE	0x1000	/* set rtm_table to FIB lookup result */
++#define RTM_F_FIB_MATCH	        0x2000	/* return full fib lookup match */
++
++/* Reserved table identifiers */
++
++enum rt_class_t {
++	RT_TABLE_UNSPEC=0,
++/* User defined values */
++	RT_TABLE_COMPAT=252,
++	RT_TABLE_DEFAULT=253,
++	RT_TABLE_MAIN=254,
++	RT_TABLE_LOCAL=255,
++	RT_TABLE_MAX=0xFFFFFFFF
++};
++
++
++/* Routing message attributes */
++
++enum rtattr_type_t {
++	RTA_UNSPEC,
++	RTA_DST,
++	RTA_SRC,
++	RTA_IIF,
++	RTA_OIF,
++	RTA_GATEWAY,
++	RTA_PRIORITY,
++	RTA_PREFSRC,
++	RTA_METRICS,
++	RTA_MULTIPATH,
++	RTA_PROTOINFO, /* no longer used */
++	RTA_FLOW,
++	RTA_CACHEINFO,
++	RTA_SESSION, /* no longer used */
++	RTA_MP_ALGO, /* no longer used */
++	RTA_TABLE,
++	RTA_MARK,
++	RTA_MFC_STATS,
++	RTA_VIA,
++	RTA_NEWDST,
++	RTA_PREF,
++	RTA_ENCAP_TYPE,
++	RTA_ENCAP,
++	RTA_EXPIRES,
++	RTA_PAD,
++	RTA_UID,
++	RTA_TTL_PROPAGATE,
++	RTA_IP_PROTO,
++	RTA_SPORT,
++	RTA_DPORT,
++	__RTA_MAX
++};
++
++#define RTA_MAX (__RTA_MAX - 1)
++
++#define RTM_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
++#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
++
++/* RTM_MULTIPATH --- array of struct rtnexthop.
++ *
++ * "struct rtnexthop" describes all necessary nexthop information,
++ * i.e. parameters of path to a destination via this nexthop.
++ *
++ * At the moment it is impossible to set different prefsrc, mtu, window
++ * and rtt for different paths from multipath.
++ */
++
++struct rtnexthop {
++	unsigned short		rtnh_len;
++	unsigned char		rtnh_flags;
++	unsigned char		rtnh_hops;
++	int			rtnh_ifindex;
++};
++
++/* rtnh_flags */
++
++#define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
++#define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
++#define RTNH_F_ONLINK		4	/* Gateway is forced on link	*/
++#define RTNH_F_OFFLOAD		8	/* offloaded route */
++#define RTNH_F_LINKDOWN		16	/* carrier-down on nexthop */
++#define RTNH_F_UNRESOLVED	32	/* The entry is unresolved (ipmr) */
++
++#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
++
++/* Macros to handle hexthops */
++
++#define RTNH_ALIGNTO	4
++#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
++#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
++			   ((int)(rtnh)->rtnh_len) <= (len))
++#define RTNH_NEXT(rtnh)	((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
++#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
++#define RTNH_SPACE(len)	RTNH_ALIGN(RTNH_LENGTH(len))
++#define RTNH_DATA(rtnh)   ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
++
++/* RTA_VIA */
++struct rtvia {
++	__kernel_sa_family_t	rtvia_family;
++	__u8			rtvia_addr[0];
++};
++
++/* RTM_CACHEINFO */
++
++struct rta_cacheinfo {
++	__u32	rta_clntref;
++	__u32	rta_lastuse;
++	__s32	rta_expires;
++	__u32	rta_error;
++	__u32	rta_used;
++
++#define RTNETLINK_HAVE_PEERINFO 1
++	__u32	rta_id;
++	__u32	rta_ts;
++	__u32	rta_tsage;
++};
++
++/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
++
++enum {
++	RTAX_UNSPEC,
++#define RTAX_UNSPEC RTAX_UNSPEC
++	RTAX_LOCK,
++#define RTAX_LOCK RTAX_LOCK
++	RTAX_MTU,
++#define RTAX_MTU RTAX_MTU
++	RTAX_WINDOW,
++#define RTAX_WINDOW RTAX_WINDOW
++	RTAX_RTT,
++#define RTAX_RTT RTAX_RTT
++	RTAX_RTTVAR,
++#define RTAX_RTTVAR RTAX_RTTVAR
++	RTAX_SSTHRESH,
++#define RTAX_SSTHRESH RTAX_SSTHRESH
++	RTAX_CWND,
++#define RTAX_CWND RTAX_CWND
++	RTAX_ADVMSS,
++#define RTAX_ADVMSS RTAX_ADVMSS
++	RTAX_REORDERING,
++#define RTAX_REORDERING RTAX_REORDERING
++	RTAX_HOPLIMIT,
++#define RTAX_HOPLIMIT RTAX_HOPLIMIT
++	RTAX_INITCWND,
++#define RTAX_INITCWND RTAX_INITCWND
++	RTAX_FEATURES,
++#define RTAX_FEATURES RTAX_FEATURES
++	RTAX_RTO_MIN,
++#define RTAX_RTO_MIN RTAX_RTO_MIN
++	RTAX_INITRWND,
++#define RTAX_INITRWND RTAX_INITRWND
++	RTAX_QUICKACK,
++#define RTAX_QUICKACK RTAX_QUICKACK
++	RTAX_CC_ALGO,
++#define RTAX_CC_ALGO RTAX_CC_ALGO
++	RTAX_FASTOPEN_NO_COOKIE,
++#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE
++	__RTAX_MAX
++};
++
++#define RTAX_MAX (__RTAX_MAX - 1)
++
++#define RTAX_FEATURE_ECN	(1 << 0)
++#define RTAX_FEATURE_SACK	(1 << 1)
++#define RTAX_FEATURE_TIMESTAMP	(1 << 2)
++#define RTAX_FEATURE_ALLFRAG	(1 << 3)
++
++#define RTAX_FEATURE_MASK	(RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | \
++				 RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG)
++
++struct rta_session {
++	__u8	proto;
++	__u8	pad1;
++	__u16	pad2;
++
++	union {
++		struct {
++			__u16	sport;
++			__u16	dport;
++		} ports;
++
++		struct {
++			__u8	type;
++			__u8	code;
++			__u16	ident;
++		} icmpt;
++
++		__u32		spi;
++	} u;
++};
++
++struct rta_mfc_stats {
++	__u64	mfcs_packets;
++	__u64	mfcs_bytes;
++	__u64	mfcs_wrong_if;
++};
++
++/****
++ *		General form of address family dependent message.
++ ****/
++
++struct rtgenmsg {
++	unsigned char		rtgen_family;
++};
++
++/*****************************************************************
++ *		Link layer specific messages.
++ ****/
++
++/* struct ifinfomsg
++ * passes link level specific information, not dependent
++ * on network protocol.
++ */
++
++struct ifinfomsg {
++	unsigned char	ifi_family;
++	unsigned char	__ifi_pad;
++	unsigned short	ifi_type;		/* ARPHRD_* */
++	int		ifi_index;		/* Link index	*/
++	unsigned	ifi_flags;		/* IFF_* flags	*/
++	unsigned	ifi_change;		/* IFF_* change mask */
++};
++
++/********************************************************************
++ *		prefix information 
++ ****/
++
++struct prefixmsg {
++	unsigned char	prefix_family;
++	unsigned char	prefix_pad1;
++	unsigned short	prefix_pad2;
++	int		prefix_ifindex;
++	unsigned char	prefix_type;
++	unsigned char	prefix_len;
++	unsigned char	prefix_flags;
++	unsigned char	prefix_pad3;
++};
++
++enum 
++{
++	PREFIX_UNSPEC,
++	PREFIX_ADDRESS,
++	PREFIX_CACHEINFO,
++	__PREFIX_MAX
++};
++
++#define PREFIX_MAX	(__PREFIX_MAX - 1)
++
++struct prefix_cacheinfo {
++	__u32	preferred_time;
++	__u32	valid_time;
++};
++
++
++/*****************************************************************
++ *		Traffic control messages.
++ ****/
++
++struct tcmsg {
++	unsigned char	tcm_family;
++	unsigned char	tcm__pad1;
++	unsigned short	tcm__pad2;
++	int		tcm_ifindex;
++	__u32		tcm_handle;
++	__u32		tcm_parent;
++/* tcm_block_index is used instead of tcm_parent
++ * in case tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK
++ */
++#define tcm_block_index tcm_parent
++	__u32		tcm_info;
++};
++
++/* For manipulation of filters in shared block, tcm_ifindex is set to
++ * TCM_IFINDEX_MAGIC_BLOCK, and tcm_parent is aliased to tcm_block_index
++ * which is the block index.
++ */
++#define TCM_IFINDEX_MAGIC_BLOCK (0xFFFFFFFFU)
++
++enum {
++	TCA_UNSPEC,
++	TCA_KIND,
++	TCA_OPTIONS,
++	TCA_STATS,
++	TCA_XSTATS,
++	TCA_RATE,
++	TCA_FCNT,
++	TCA_STATS2,
++	TCA_STAB,
++	TCA_PAD,
++	TCA_DUMP_INVISIBLE,
++	TCA_CHAIN,
++	TCA_HW_OFFLOAD,
++	TCA_INGRESS_BLOCK,
++	TCA_EGRESS_BLOCK,
++	__TCA_MAX
++};
++
++#define TCA_MAX (__TCA_MAX - 1)
++
++#define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
++#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
++
++/********************************************************************
++ *		Neighbor Discovery userland options
++ ****/
++
++struct nduseroptmsg {
++	unsigned char	nduseropt_family;
++	unsigned char	nduseropt_pad1;
++	unsigned short	nduseropt_opts_len;	/* Total length of options */
++	int		nduseropt_ifindex;
++	__u8		nduseropt_icmp_type;
++	__u8		nduseropt_icmp_code;
++	unsigned short	nduseropt_pad2;
++	unsigned int	nduseropt_pad3;
++	/* Followed by one or more ND options */
++};
++
++enum {
++	NDUSEROPT_UNSPEC,
++	NDUSEROPT_SRCADDR,
++	__NDUSEROPT_MAX
++};
++
++#define NDUSEROPT_MAX	(__NDUSEROPT_MAX - 1)
++
++#ifndef __KERNEL__
++/* RTnetlink multicast groups - backwards compatibility for userspace */
++#define RTMGRP_LINK		1
++#define RTMGRP_NOTIFY		2
++#define RTMGRP_NEIGH		4
++#define RTMGRP_TC		8
++
++#define RTMGRP_IPV4_IFADDR	0x10
++#define RTMGRP_IPV4_MROUTE	0x20
++#define RTMGRP_IPV4_ROUTE	0x40
++#define RTMGRP_IPV4_RULE	0x80
++
++#define RTMGRP_IPV6_IFADDR	0x100
++#define RTMGRP_IPV6_MROUTE	0x200
++#define RTMGRP_IPV6_ROUTE	0x400
++#define RTMGRP_IPV6_IFINFO	0x800
++
++#define RTMGRP_DECnet_IFADDR    0x1000
++#define RTMGRP_DECnet_ROUTE     0x4000
++
++#define RTMGRP_IPV6_PREFIX	0x20000
++#endif
++
++/* RTnetlink multicast groups */
++enum rtnetlink_groups {
++	RTNLGRP_NONE,
++#define RTNLGRP_NONE		RTNLGRP_NONE
++	RTNLGRP_LINK,
++#define RTNLGRP_LINK		RTNLGRP_LINK
++	RTNLGRP_NOTIFY,
++#define RTNLGRP_NOTIFY		RTNLGRP_NOTIFY
++	RTNLGRP_NEIGH,
++#define RTNLGRP_NEIGH		RTNLGRP_NEIGH
++	RTNLGRP_TC,
++#define RTNLGRP_TC		RTNLGRP_TC
++	RTNLGRP_IPV4_IFADDR,
++#define RTNLGRP_IPV4_IFADDR	RTNLGRP_IPV4_IFADDR
++	RTNLGRP_IPV4_MROUTE,
++#define	RTNLGRP_IPV4_MROUTE	RTNLGRP_IPV4_MROUTE
++	RTNLGRP_IPV4_ROUTE,
++#define RTNLGRP_IPV4_ROUTE	RTNLGRP_IPV4_ROUTE
++	RTNLGRP_IPV4_RULE,
++#define RTNLGRP_IPV4_RULE	RTNLGRP_IPV4_RULE
++	RTNLGRP_IPV6_IFADDR,
++#define RTNLGRP_IPV6_IFADDR	RTNLGRP_IPV6_IFADDR
++	RTNLGRP_IPV6_MROUTE,
++#define RTNLGRP_IPV6_MROUTE	RTNLGRP_IPV6_MROUTE
++	RTNLGRP_IPV6_ROUTE,
++#define RTNLGRP_IPV6_ROUTE	RTNLGRP_IPV6_ROUTE
++	RTNLGRP_IPV6_IFINFO,
++#define RTNLGRP_IPV6_IFINFO	RTNLGRP_IPV6_IFINFO
++	RTNLGRP_DECnet_IFADDR,
++#define RTNLGRP_DECnet_IFADDR	RTNLGRP_DECnet_IFADDR
++	RTNLGRP_NOP2,
++	RTNLGRP_DECnet_ROUTE,
++#define RTNLGRP_DECnet_ROUTE	RTNLGRP_DECnet_ROUTE
++	RTNLGRP_DECnet_RULE,
++#define RTNLGRP_DECnet_RULE	RTNLGRP_DECnet_RULE
++	RTNLGRP_NOP4,
++	RTNLGRP_IPV6_PREFIX,
++#define RTNLGRP_IPV6_PREFIX	RTNLGRP_IPV6_PREFIX
++	RTNLGRP_IPV6_RULE,
++#define RTNLGRP_IPV6_RULE	RTNLGRP_IPV6_RULE
++	RTNLGRP_ND_USEROPT,
++#define RTNLGRP_ND_USEROPT	RTNLGRP_ND_USEROPT
++	RTNLGRP_PHONET_IFADDR,
++#define RTNLGRP_PHONET_IFADDR	RTNLGRP_PHONET_IFADDR
++	RTNLGRP_PHONET_ROUTE,
++#define RTNLGRP_PHONET_ROUTE	RTNLGRP_PHONET_ROUTE
++	RTNLGRP_DCB,
++#define RTNLGRP_DCB		RTNLGRP_DCB
++	RTNLGRP_IPV4_NETCONF,
++#define RTNLGRP_IPV4_NETCONF	RTNLGRP_IPV4_NETCONF
++	RTNLGRP_IPV6_NETCONF,
++#define RTNLGRP_IPV6_NETCONF	RTNLGRP_IPV6_NETCONF
++	RTNLGRP_MDB,
++#define RTNLGRP_MDB		RTNLGRP_MDB
++	RTNLGRP_MPLS_ROUTE,
++#define RTNLGRP_MPLS_ROUTE	RTNLGRP_MPLS_ROUTE
++	RTNLGRP_NSID,
++#define RTNLGRP_NSID		RTNLGRP_NSID
++	RTNLGRP_MPLS_NETCONF,
++#define RTNLGRP_MPLS_NETCONF	RTNLGRP_MPLS_NETCONF
++	RTNLGRP_IPV4_MROUTE_R,
++#define RTNLGRP_IPV4_MROUTE_R	RTNLGRP_IPV4_MROUTE_R
++	RTNLGRP_IPV6_MROUTE_R,
++#define RTNLGRP_IPV6_MROUTE_R	RTNLGRP_IPV6_MROUTE_R
++	__RTNLGRP_MAX
++};
++#define RTNLGRP_MAX	(__RTNLGRP_MAX - 1)
++
++/* TC action piece */
++struct tcamsg {
++	unsigned char	tca_family;
++	unsigned char	tca__pad1;
++	unsigned short	tca__pad2;
++};
++
++enum {
++	TCA_ROOT_UNSPEC,
++	TCA_ROOT_TAB,
++#define TCA_ACT_TAB TCA_ROOT_TAB
++#define TCAA_MAX TCA_ROOT_TAB
++	TCA_ROOT_FLAGS,
++	TCA_ROOT_COUNT,
++	TCA_ROOT_TIME_DELTA, /* in msecs */
++	__TCA_ROOT_MAX,
++#define	TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
++};
++
++#define TA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
++#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
++/* tcamsg flags stored in attribute TCA_ROOT_FLAGS
++ *
++ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
++ * actions in a dump. All dump responses will contain the number of actions
++ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
++ *
++ */
++#define TCA_FLAG_LARGE_DUMP_ON		(1 << 0)
++
++/* New extended info filters for IFLA_EXT_MASK */
++#define RTEXT_FILTER_VF		(1 << 0)
++#define RTEXT_FILTER_BRVLAN	(1 << 1)
++#define RTEXT_FILTER_BRVLAN_COMPRESSED	(1 << 2)
++#define	RTEXT_FILTER_SKIP_STATS	(1 << 3)
++
++/* End of information exported to user level */
++
++
++
++#endif /* _UAPI__LINUX_RTNETLINK_H */
+diff --git a/src/basic/linux/wireguard.h b/src/basic/linux/wireguard.h
+new file mode 100644
+index 0000000000..071ce4167f
+--- /dev/null
++++ b/src/basic/linux/wireguard.h
+@@ -0,0 +1,190 @@
++/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
++/*
++ * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
++ *
++ * Documentation
++ * =============
++ *
++ * The below enums and macros are for interfacing with WireGuard, using generic
++ * netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two
++ * methods: get and set. Note that while they share many common attributes,
++ * these two functions actually accept a slightly different set of inputs and
++ * outputs.
++ *
++ * WG_CMD_GET_DEVICE
++ * -----------------
++ *
++ * May only be called via NLM_F_REQUEST | NLM_F_DUMP. The command should contain
++ * one but not both of:
++ *
++ *    WGDEVICE_A_IFINDEX: NLA_U32
++ *    WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
++ *
++ * The kernel will then return several messages (NLM_F_MULTI) containing the
++ * following tree of nested items:
++ *
++ *    WGDEVICE_A_IFINDEX: NLA_U32
++ *    WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
++ *    WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN
++ *    WGDEVICE_A_PUBLIC_KEY: len WG_KEY_LEN
++ *    WGDEVICE_A_LISTEN_PORT: NLA_U16
++ *    WGDEVICE_A_FWMARK: NLA_U32
++ *    WGDEVICE_A_PEERS: NLA_NESTED
++ *        0: NLA_NESTED
++ *            WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
++ *            WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN
++ *            WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
++ *            WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16
++ *            WGPEER_A_LAST_HANDSHAKE_TIME: struct __kernel_timespec
++ *            WGPEER_A_RX_BYTES: NLA_U64
++ *            WGPEER_A_TX_BYTES: NLA_U64
++ *            WGPEER_A_ALLOWEDIPS: NLA_NESTED
++ *                0: NLA_NESTED
++ *                    WGALLOWEDIP_A_FAMILY: NLA_U16
++ *                    WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
++ *                    WGALLOWEDIP_A_CIDR_MASK: NLA_U8
++ *                0: NLA_NESTED
++ *                    ...
++ *                0: NLA_NESTED
++ *                    ...
++ *                ...
++ *            WGPEER_A_PROTOCOL_VERSION: NLA_U32
++ *        0: NLA_NESTED
++ *            ...
++ *        ...
++ *
++ * It is possible that all of the allowed IPs of a single peer will not
++ * fit within a single netlink message. In that case, the same peer will
++ * be written in the following message, except it will only contain
++ * WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several
++ * times in a row for the same peer. It is then up to the receiver to
++ * coalesce adjacent peers. Likewise, it is possible that all peers will
++ * not fit within a single message. So, subsequent peers will be sent
++ * in following messages, except those will only contain WGDEVICE_A_IFNAME
++ * and WGDEVICE_A_PEERS. It is then up to the receiver to coalesce these
++ * messages to form the complete list of peers.
++ *
++ * Since this is an NLA_F_DUMP command, the final message will always be
++ * NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message
++ * contains an integer error code. It is either zero or a negative error
++ * code corresponding to the errno.
++ *
++ * WG_CMD_SET_DEVICE
++ * -----------------
++ *
++ * May only be called via NLM_F_REQUEST. The command should contain the
++ * following tree of nested items, containing one but not both of
++ * WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME:
++ *
++ *    WGDEVICE_A_IFINDEX: NLA_U32
++ *    WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
++ *    WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
++ *                      peers should be removed prior to adding the list below.
++ *    WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
++ *    WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly
++ *    WGDEVICE_A_FWMARK: NLA_U32, 0 to disable
++ *    WGDEVICE_A_PEERS: NLA_NESTED
++ *        0: NLA_NESTED
++ *            WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
++ *            WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the
++ *                            specified peer should be removed rather than
++ *                            added/updated and/or WGPEER_F_REPLACE_ALLOWEDIPS
++ *                            if all current allowed IPs of this peer should be
++ *                            removed prior to adding the list below.
++ *            WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove
++ *            WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
++ *            WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable
++ *            WGPEER_A_ALLOWEDIPS: NLA_NESTED
++ *                0: NLA_NESTED
++ *                    WGALLOWEDIP_A_FAMILY: NLA_U16
++ *                    WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
++ *                    WGALLOWEDIP_A_CIDR_MASK: NLA_U8
++ *                0: NLA_NESTED
++ *                    ...
++ *                0: NLA_NESTED
++ *                    ...
++ *                ...
++ *            WGPEER_A_PROTOCOL_VERSION: NLA_U32, should not be set or used at
++ *                                       all by most users of this API, as the
++ *                                       most recent protocol will be used when
++ *                                       this is unset. Otherwise, must be set
++ *                                       to 1.
++ *        0: NLA_NESTED
++ *            ...
++ *        ...
++ *
++ * It is possible that the amount of configuration data exceeds that of
++ * the maximum message length accepted by the kernel. In that case, several
++ * messages should be sent one after another, with each successive one
++ * filling in information not contained in the prior. Note that if
++ * WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably
++ * should not be specified in fragments that come after, so that the list
++ * of peers is only cleared the first time but appened after. Likewise for
++ * peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message
++ * of a peer, it likely should not be specified in subsequent fragments.
++ *
++ * If an error occurs, NLMSG_ERROR will reply containing an errno.
++ */
++
++#ifndef _WG_UAPI_WIREGUARD_H
++#define _WG_UAPI_WIREGUARD_H
++
++#define WG_GENL_NAME "wireguard"
++#define WG_GENL_VERSION 1
++
++#define WG_KEY_LEN 32
++
++enum wg_cmd {
++	WG_CMD_GET_DEVICE,
++	WG_CMD_SET_DEVICE,
++	__WG_CMD_MAX
++};
++#define WG_CMD_MAX (__WG_CMD_MAX - 1)
++
++enum wgdevice_flag {
++	WGDEVICE_F_REPLACE_PEERS = 1U << 0
++};
++enum wgdevice_attribute {
++	WGDEVICE_A_UNSPEC,
++	WGDEVICE_A_IFINDEX,
++	WGDEVICE_A_IFNAME,
++	WGDEVICE_A_PRIVATE_KEY,
++	WGDEVICE_A_PUBLIC_KEY,
++	WGDEVICE_A_FLAGS,
++	WGDEVICE_A_LISTEN_PORT,
++	WGDEVICE_A_FWMARK,
++	WGDEVICE_A_PEERS,
++	__WGDEVICE_A_LAST
++};
++#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
++
++enum wgpeer_flag {
++	WGPEER_F_REMOVE_ME = 1U << 0,
++	WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
++};
++enum wgpeer_attribute {
++	WGPEER_A_UNSPEC,
++	WGPEER_A_PUBLIC_KEY,
++	WGPEER_A_PRESHARED_KEY,
++	WGPEER_A_FLAGS,
++	WGPEER_A_ENDPOINT,
++	WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
++	WGPEER_A_LAST_HANDSHAKE_TIME,
++	WGPEER_A_RX_BYTES,
++	WGPEER_A_TX_BYTES,
++	WGPEER_A_ALLOWEDIPS,
++	WGPEER_A_PROTOCOL_VERSION,
++	__WGPEER_A_LAST
++};
++#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)
++
++enum wgallowedip_attribute {
++	WGALLOWEDIP_A_UNSPEC,
++	WGALLOWEDIP_A_FAMILY,
++	WGALLOWEDIP_A_IPADDR,
++	WGALLOWEDIP_A_CIDR_MASK,
++	__WGALLOWEDIP_A_LAST
++};
++#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1)
++
++#endif /* _WG_UAPI_WIREGUARD_H */
+diff --git a/src/basic/meson.build b/src/basic/meson.build
+index 91e0df3d2f..de1e42013d 100644
+--- a/src/basic/meson.build
++++ b/src/basic/meson.build
+@@ -84,6 +84,23 @@ basic_sources = files('''
+         label.h
+         limits-util.c
+         limits-util.h
++        linux/btrfs.h
++        linux/btrfs_tree.h
++        linux/can/vxcan.h
++        linux/fib_rules.h
++        linux/fou.h
++        linux/if.h
++        linux/if_addr.h
++        linux/if_arp.h
++        linux/if_bonding.h
++        linux/if_bridge.h
++        linux/if_link.h
++        linux/if_tun.h
++        linux/if_tunnel.h
++        linux/libc-compat.h
++        linux/netlink.h
++        linux/rtnetlink.h
++        linux/wireguard.h
+         list.h
+         locale-util.c
+         locale-util.h
+@@ -100,18 +117,10 @@ basic_sources = files('''
+         mempool.h
+         missing.h
+         missing_audit.h
+-        missing_btrfs.h
+-        missing_btrfs_tree.h
+         missing_capability.h
+         missing_drm.h
+-        missing_ethtool.h
+         missing_fcntl.h
+-        missing_fib_rules.h
+-        missing_fou.h
+         missing_fs.h
+-        missing_if_bridge.h
+-        missing_if_link.h
+-        missing_if_tunnel.h
+         missing_input.h
+         missing_keyctl.h
+         missing_magic.h
+@@ -128,7 +137,6 @@ basic_sources = files('''
+         missing_syscall.h
+         missing_timerfd.h
+         missing_type.h
+-        missing_vxcan.h
+         mkdir-label.c
+         mkdir.c
+         mkdir.h
+@@ -227,7 +235,6 @@ basic_sources = files('''
+ 
+ missing_audit_h = files('missing_audit.h')
+ missing_capability_h = files('missing_capability.h')
+-missing_network_h = files('missing_network.h')
+ missing_socket_h = files('missing_socket.h')
+ 
+ generate_af_list = find_program('generate-af-list.sh')
+@@ -241,7 +248,7 @@ generate_arphrd_list = find_program('generate-arphrd-list.sh')
+ arphrd_list_txt = custom_target(
+         'arphrd-list.txt',
+         output : 'arphrd-list.txt',
+-        command : [generate_arphrd_list, cpp, config_h, missing_network_h],
++        command : [generate_arphrd_list, cpp, config_h],
+         capture : true)
+ 
+ generate_cap_list = find_program('generate-cap-list.sh')
+diff --git a/src/basic/missing.h b/src/basic/missing.h
+index 5067c8fd00..9ea4d9467c 100644
+--- a/src/basic/missing.h
++++ b/src/basic/missing.h
+@@ -4,7 +4,6 @@
+ /* Missing glibc definitions to access certain kernel APIs */
+ 
+ #include "missing_audit.h"
+-#include "missing_btrfs_tree.h"
+ #include "missing_capability.h"
+ #include "missing_drm.h"
+ #include "missing_fcntl.h"
+diff --git a/src/basic/missing_btrfs.h b/src/basic/missing_btrfs.h
+deleted file mode 100644
+index 34c382ff0b..0000000000
+--- a/src/basic/missing_btrfs.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-/* Old btrfs.h requires stddef.h to be included before btrfs.h */
+-#include <stddef.h>
+-
+-#include <linux/btrfs.h>
+-
+-/* linux@57254b6ebce4ceca02d9c8b615f6059c56c19238 (3.11) */
+-#ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT
+-#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
+-#endif
+-
+-/* linux@83288b60bf6668933689078973136e0c9d387b38 (4.7) */
+-#ifndef BTRFS_QGROUP_LIMIT_MAX_RFER
+-#define BTRFS_QGROUP_LIMIT_MAX_RFER	(1ULL << 0)
+-#define BTRFS_QGROUP_LIMIT_MAX_EXCL	(1ULL << 1)
+-#define BTRFS_QGROUP_LIMIT_RSV_RFER	(1ULL << 2)
+-#define BTRFS_QGROUP_LIMIT_RSV_EXCL	(1ULL << 3)
+-#define BTRFS_QGROUP_LIMIT_RFER_CMPR	(1ULL << 4)
+-#define BTRFS_QGROUP_LIMIT_EXCL_CMPR	(1ULL << 5)
+-#endif
+diff --git a/src/basic/missing_btrfs_tree.h b/src/basic/missing_btrfs_tree.h
+deleted file mode 100644
+index 555f90fe1b..0000000000
+--- a/src/basic/missing_btrfs_tree.h
++++ /dev/null
+@@ -1,109 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#include <linux/types.h>
+-
+-#include "missing_btrfs.h"
+-
+-/* linux@db6711600e27c885aed89751f04e727f3af26715 (4.7) */
+-#if HAVE_LINUX_BTRFS_TREE_H
+-#include <linux/btrfs_tree.h>
+-#else
+-#define BTRFS_ROOT_TREE_OBJECTID  1
+-#define BTRFS_QUOTA_TREE_OBJECTID 8
+-#define BTRFS_FIRST_FREE_OBJECTID 256
+-#define BTRFS_LAST_FREE_OBJECTID -256ULL
+-
+-#define BTRFS_ROOT_ITEM_KEY       132
+-#define BTRFS_ROOT_BACKREF_KEY    144
+-#define BTRFS_QGROUP_STATUS_KEY   240
+-#define BTRFS_QGROUP_INFO_KEY     242
+-#define BTRFS_QGROUP_LIMIT_KEY    244
+-#define BTRFS_QGROUP_RELATION_KEY 246
+-
+-struct btrfs_disk_key {
+-        __le64 objectid;
+-        __u8 type;
+-        __le64 offset;
+-} __attribute__ ((__packed__));
+-
+-struct btrfs_timespec {
+-        __le64 sec;
+-        __le32 nsec;
+-} __attribute__ ((__packed__));
+-
+-struct btrfs_inode_item {
+-        __le64 generation;
+-        __le64 transid;
+-        __le64 size;
+-        __le64 nbytes;
+-        __le64 block_group;
+-        __le32 nlink;
+-        __le32 uid;
+-        __le32 gid;
+-        __le32 mode;
+-        __le64 rdev;
+-        __le64 flags;
+-        __le64 sequence;
+-        __le64 reserved[4];
+-        struct btrfs_timespec atime;
+-        struct btrfs_timespec ctime;
+-        struct btrfs_timespec mtime;
+-        struct btrfs_timespec otime;
+-} __attribute__ ((__packed__));
+-
+-#define BTRFS_ROOT_SUBVOL_RDONLY (1ULL << 0)
+-
+-struct btrfs_root_item {
+-        struct btrfs_inode_item inode;
+-        __le64 generation;
+-        __le64 root_dirid;
+-        __le64 bytenr;
+-        __le64 byte_limit;
+-        __le64 bytes_used;
+-        __le64 last_snapshot;
+-        __le64 flags;
+-        __le32 refs;
+-        struct btrfs_disk_key drop_progress;
+-        __u8 drop_level;
+-        __u8 level;
+-
+-        __le64 generation_v2;
+-        __u8 uuid[BTRFS_UUID_SIZE];
+-        __u8 parent_uuid[BTRFS_UUID_SIZE];
+-        __u8 received_uuid[BTRFS_UUID_SIZE];
+-        __le64 ctransid; /* updated when an inode changes */
+-        __le64 otransid; /* trans when created */
+-        __le64 stransid; /* trans when sent. non-zero for received subvol */
+-        __le64 rtransid; /* trans when received. non-zero for received subvol */
+-        struct btrfs_timespec ctime;
+-        struct btrfs_timespec otime;
+-        struct btrfs_timespec stime;
+-        struct btrfs_timespec rtime;
+-        __le64 reserved[8]; /* for future */
+-} __attribute__ ((__packed__));
+-
+-struct btrfs_root_ref {
+-        __le64 dirid;
+-        __le64 sequence;
+-        __le16 name_len;
+-} __attribute__ ((__packed__));
+-
+-#define BTRFS_QGROUP_LEVEL_SHIFT  48
+-
+-struct btrfs_qgroup_info_item {
+-        __le64 generation;
+-        __le64 rfer;
+-        __le64 rfer_cmpr;
+-        __le64 excl;
+-        __le64 excl_cmpr;
+-} __attribute__ ((__packed__));
+-
+-struct btrfs_qgroup_limit_item {
+-        __le64 flags;
+-        __le64 max_rfer;
+-        __le64 max_excl;
+-        __le64 rsv_rfer;
+-        __le64 rsv_excl;
+-} __attribute__ ((__packed__));
+-#endif
+diff --git a/src/basic/missing_ethtool.h b/src/basic/missing_ethtool.h
+deleted file mode 100644
+index 9ba929c632..0000000000
+--- a/src/basic/missing_ethtool.h
++++ /dev/null
+@@ -1,131 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#include <linux/types.h>
+-
+-/* Missing definitions in ethtool.h */
+-
+-#if !HAVE_ETHTOOL_LINK_MODE_10baseT_Half_BIT /* linux@3f1ac7a700d039c61d8d8b99f28d605d489a60cf (4.6) */
+-
+-#define ETHTOOL_GLINKSETTINGS   0x0000004c /* Get ethtool_link_settings */
+-#define ETHTOOL_SLINKSETTINGS   0x0000004d /* Set ethtool_link_settings */
+-
+-struct ethtool_link_settings {
+-        __u32 cmd;
+-        __u32 speed;
+-        __u8  duplex;
+-        __u8  port;
+-        __u8  phy_address;
+-        __u8  autoneg;
+-        __u8  mdio_support;
+-        __u8  eth_tp_mdix;
+-        __u8  eth_tp_mdix_ctrl;
+-        __s8  link_mode_masks_nwords;
+-        __u8  transceiver;
+-        __u8  reserved1[3];
+-        __u32 reserved[7];
+-        __u32 link_mode_masks[0];
+-        /* layout of link_mode_masks fields:
+-         * __u32 map_supported[link_mode_masks_nwords];
+-         * __u32 map_advertising[link_mode_masks_nwords];
+-         * __u32 map_lp_advertising[link_mode_masks_nwords];
+-         */
+-};
+-
+-enum ethtool_link_mode_bit_indices {
+-        ETHTOOL_LINK_MODE_10baseT_Half_BIT           = 0,
+-        ETHTOOL_LINK_MODE_10baseT_Full_BIT           = 1,
+-        ETHTOOL_LINK_MODE_100baseT_Half_BIT          = 2,
+-        ETHTOOL_LINK_MODE_100baseT_Full_BIT          = 3,
+-        ETHTOOL_LINK_MODE_1000baseT_Half_BIT         = 4,
+-        ETHTOOL_LINK_MODE_1000baseT_Full_BIT         = 5,
+-        ETHTOOL_LINK_MODE_Autoneg_BIT                = 6,
+-        ETHTOOL_LINK_MODE_TP_BIT                     = 7,
+-        ETHTOOL_LINK_MODE_AUI_BIT                    = 8,
+-        ETHTOOL_LINK_MODE_MII_BIT                    = 9,
+-        ETHTOOL_LINK_MODE_FIBRE_BIT                  = 10,
+-        ETHTOOL_LINK_MODE_BNC_BIT                    = 11,
+-        ETHTOOL_LINK_MODE_10000baseT_Full_BIT        = 12,
+-        ETHTOOL_LINK_MODE_Pause_BIT                  = 13,
+-        ETHTOOL_LINK_MODE_Asym_Pause_BIT             = 14,
+-        ETHTOOL_LINK_MODE_2500baseX_Full_BIT         = 15,
+-        ETHTOOL_LINK_MODE_Backplane_BIT              = 16,
+-        ETHTOOL_LINK_MODE_1000baseKX_Full_BIT        = 17,
+-        ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT      = 18,
+-        ETHTOOL_LINK_MODE_10000baseKR_Full_BIT       = 19,
+-        ETHTOOL_LINK_MODE_10000baseR_FEC_BIT         = 20,
+-        ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT     = 21,
+-        ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT      = 22,
+-        ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT      = 23,
+-        ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT      = 24,
+-        ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT      = 25,
+-        ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT      = 26,
+-        ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT      = 27,
+-        ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT      = 28,
+-        ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT      = 29,
+-        ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT      = 30,
+-        ETHTOOL_LINK_MODE_25000baseCR_Full_BIT       = 31,
+-        ETHTOOL_LINK_MODE_25000baseKR_Full_BIT       = 32,
+-        ETHTOOL_LINK_MODE_25000baseSR_Full_BIT       = 33,
+-        ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT      = 34,
+-        ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT      = 35,
+-        ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT     = 36,
+-        ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT     = 37,
+-        ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT     = 38,
+-        ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39,
+-        ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT      = 40,
+-        ETHTOOL_LINK_MODE_1000baseX_Full_BIT         = 41,
+-        ETHTOOL_LINK_MODE_10000baseCR_Full_BIT       = 42,
+-        ETHTOOL_LINK_MODE_10000baseSR_Full_BIT       = 43,
+-        ETHTOOL_LINK_MODE_10000baseLR_Full_BIT       = 44,
+-        ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT      = 45,
+-        ETHTOOL_LINK_MODE_10000baseER_Full_BIT       = 46,
+-        ETHTOOL_LINK_MODE_2500baseT_Full_BIT         = 47,
+-        ETHTOOL_LINK_MODE_5000baseT_Full_BIT         = 48,
+-
+-        ETHTOOL_LINK_MODE_FEC_NONE_BIT               = 49,
+-        ETHTOOL_LINK_MODE_FEC_RS_BIT                 = 50,
+-        ETHTOOL_LINK_MODE_FEC_BASER_BIT              = 51,
+-
+-        /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
+-         * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
+-         * macro for bits > 31. The only way to use indices > 31 is to
+-         * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API.
+-         */
+-
+-        __ETHTOOL_LINK_MODE_LAST
+-          = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
+-};
+-#else
+-#if !HAVE_ETHTOOL_LINK_MODE_25000baseCR_Full_BIT /* linux@3851112e4737cd52aaeda0ce8d084be9ee128106 (4.7) */
+-#define ETHTOOL_LINK_MODE_25000baseCR_Full_BIT       31
+-#define ETHTOOL_LINK_MODE_25000baseKR_Full_BIT       32
+-#define ETHTOOL_LINK_MODE_25000baseSR_Full_BIT       33
+-#define ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT      34
+-#define ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT      35
+-#define ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT     36
+-#define ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT     37
+-#define ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT     38
+-#define ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT 39
+-#endif
+-#if !HAVE_ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT /* linux@89da45b8b5b2187734a11038b8593714f964ffd1 (4.8) */
+-#define ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT      40
+-#endif
+-#if !HAVE_ETHTOOL_LINK_MODE_1000baseX_Full_BIT /* linux@5711a98221443aec54c4c81ee98c6ae46acccb65 (4.9) */
+-#define ETHTOOL_LINK_MODE_1000baseX_Full_BIT         41
+-#define ETHTOOL_LINK_MODE_10000baseCR_Full_BIT       42
+-#define ETHTOOL_LINK_MODE_10000baseSR_Full_BIT       43
+-#define ETHTOOL_LINK_MODE_10000baseLR_Full_BIT       44
+-#define ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT      45
+-#define ETHTOOL_LINK_MODE_10000baseER_Full_BIT       46
+-#endif
+-#if !HAVE_ETHTOOL_LINK_MODE_2500baseT_Full_BIT /* linux@94842b4fc4d6b1691cfc86c6f5251f299d27f4ba (4.10) */
+-#define ETHTOOL_LINK_MODE_2500baseT_Full_BIT         47
+-#define ETHTOOL_LINK_MODE_5000baseT_Full_BIT         48
+-#endif
+-#if !HAVE_ETHTOOL_LINK_MODE_FEC_NONE_BIT /* linux@1a5f3da20bd966220931239fbd31e6ac6ff42251 (4.14) */
+-#define ETHTOOL_LINK_MODE_FEC_NONE_BIT               49
+-#define ETHTOOL_LINK_MODE_FEC_RS_BIT                 50
+-#define ETHTOOL_LINK_MODE_FEC_BASER_BIT              51
+-#endif
+-#endif
+diff --git a/src/basic/missing_fib_rules.h b/src/basic/missing_fib_rules.h
+deleted file mode 100644
+index df120d7bcd..0000000000
+--- a/src/basic/missing_fib_rules.h
++++ /dev/null
+@@ -1,45 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#include <linux/types.h>
+-
+-#if !HAVE_FRA_TUN_ID /* linux@e7030878fc8448492b6e5cecd574043f63271298 (4.3) */
+-#define FRA_TUN_ID      12
+-#endif
+-
+-#if !HAVE_FRA_SUPPRESS_PREFIXLEN /* linux@6ef94cfafba159d6b1a902ccb3349ac6a34ff6ad, 73f5698e77219bfc3ea1903759fe8e20ab5b285e (3.12) */
+-#define FRA_SUPPRESS_IFGROUP 13
+-#define FRA_SUPPRESS_PREFIXLEN 14
+-#endif
+-
+-#if !HAVE_FRA_PAD /* linux@b46f6ded906ef0be52a4881ba50a084aeca64d7e (4.7) */
+-#define FRA_PAD         18
+-#endif
+-
+-#if !HAVE_FRA_L3MDEV /* linux@96c63fa7393d0a346acfe5a91e0c7d4c7782641b (4.8) */
+-#define FRA_L3MDEV      19
+-#endif
+-
+-#if !HAVE_FRA_UID_RANGE /* linux@622ec2c9d52405973c9f1ca5116eb1c393adfc7d (4.10) */
+-#define FRA_UID_RANGE   20
+-
+-struct fib_rule_uid_range {
+-        __u32 start;
+-        __u32 end;
+-};
+-#endif
+-
+-#if !HAVE_FRA_DPORT_RANGE /* linux@1b71af6053af1bd2f849e9fda4f71c1e3f145dcf, bfff4862653bb96001ab57c1edd6d03f48e5f035 (4.17) */
+-#define FRA_PROTOCOL    21
+-#define FRA_IP_PROTO    22
+-#define FRA_SPORT_RANGE 23
+-#define FRA_DPORT_RANGE 24
+-
+-#undef  FRA_MAX
+-#define FRA_MAX         24
+-
+-struct fib_rule_port_range {
+-        __u16 start;
+-        __u16 end;
+-};
+-#endif
+diff --git a/src/basic/missing_fou.h b/src/basic/missing_fou.h
+deleted file mode 100644
+index d8c743577c..0000000000
+--- a/src/basic/missing_fou.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#if !HAVE_LINUX_FOU_H /* linux@23461551c00628c3f3fe9cf837bf53cf8f212b63 (3.18) */
+-
+-#define FOU_GENL_NAME           "fou"
+-#define FOU_GENL_VERSION        0x1
+-
+-enum {
+-        FOU_ATTR_UNSPEC,
+-        FOU_ATTR_PORT,                  /* u16 */
+-        FOU_ATTR_AF,                    /* u8 */
+-        FOU_ATTR_IPPROTO,               /* u8 */
+-        FOU_ATTR_TYPE,                  /* u8 */
+-        FOU_ATTR_REMCSUM_NOPARTIAL,     /* flag */
+-
+-        __FOU_ATTR_MAX,
+-};
+-
+-#define FOU_ATTR_MAX                (__FOU_ATTR_MAX - 1)
+-
+-enum {
+-        FOU_CMD_UNSPEC,
+-        FOU_CMD_ADD,
+-        FOU_CMD_DEL,
+-        FOU_CMD_GET,
+-
+-        __FOU_CMD_MAX,
+-};
+-
+-enum {
+-        FOU_ENCAP_UNSPEC,
+-        FOU_ENCAP_DIRECT,
+-        FOU_ENCAP_GUE,
+-};
+-
+-#define FOU_CMD_MAX        (__FOU_CMD_MAX - 1)
+-
+-#else
+-
+-#if !HAVE_FOU_ATTR_REMCSUM_NOPARTIAL /* linux@fe881ef11cf0220f118816181930494d484c4883 (4.0) */
+-#define FOU_ATTR_REMCSUM_NOPARTIAL 5
+-
+-#undef  FOU_ATTR_MAX
+-#define FOU_ATTR_MAX               5
+-#endif
+-
+-#if !HAVE_FOU_CMD_GET /* linux@7a6c8c34e5b71ac50e39588e20b39494a9e1d8e5 (4.1) */
+-#define FOU_CMD_GET 3
+-
+-#undef  FOU_CMD_MAX
+-#define FOU_CMD_MAX 3
+-#endif
+-
+-#endif
+diff --git a/src/basic/missing_if_bridge.h b/src/basic/missing_if_bridge.h
+deleted file mode 100644
+index 9306062fc2..0000000000
+--- a/src/basic/missing_if_bridge.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#if !HAVE_IFLA_BRIDGE_VLAN_TUNNEL_INFO /* linux@b3c7ef0adadc5768e0baa786213c6bd1ce521a77 (4.11) */
+-#define IFLA_BRIDGE_VLAN_TUNNEL_INFO 3
+-
+-#undef  IFLA_BRIDGE_MAX
+-#define IFLA_BRIDGE_MAX              3
+-#endif
+-
+-#ifndef BRIDGE_VLAN_INFO_RANGE_BEGIN
+-#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */
+-#endif
+-
+-#ifndef BRIDGE_VLAN_INFO_RANGE_END
+-#define BRIDGE_VLAN_INFO_RANGE_END   (1<<4) /* VLAN is end of vlan range */
+-#endif
+-
+-#ifndef BRIDGE_VLAN_INFO_BRENTRY
+-#define BRIDGE_VLAN_INFO_BRENTRY     (1<<5) /* Global bridge VLAN entry */
+-#endif
+diff --git a/src/basic/missing_if_link.h b/src/basic/missing_if_link.h
+deleted file mode 100644
+index 761797f56a..0000000000
+--- a/src/basic/missing_if_link.h
++++ /dev/null
+@@ -1,393 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#if !HAVE_IFLA_INET6_ADDR_GEN_MODE /* linux@bc91b0f07ada5535427373a4e2050877bcc12218 (3.17) */
+-#define IFLA_INET6_ADDR_GEN_MODE 8
+-
+-#undef  IFLA_INET6_MAX
+-#define IFLA_INET6_MAX           8
+-
+-enum in6_addr_gen_mode {
+-        IN6_ADDR_GEN_MODE_EUI64,
+-        IN6_ADDR_GEN_MODE_NONE,
+-        IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+-        IN6_ADDR_GEN_MODE_RANDOM,
+-};
+-#else
+-#if !HAVE_IN6_ADDR_GEN_MODE_STABLE_PRIVACY /* linux@622c81d57b392cc9be836670eb464a4dfaa9adfe (4.1) */
+-#define IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2
+-#endif
+-#if !HAVE_IN6_ADDR_GEN_MODE_RANDOM /* linux@cc9da6cc4f56e05cc9e591459fe0192727ff58b3 (4.5) */
+-#define IN6_ADDR_GEN_MODE_RANDOM         3
+-#endif
+-#endif /* !HAVE_IFLA_INET6_ADDR_GEN_MODE */
+-
+-#if !HAVE_IFLA_IPVLAN_MODE /* linux@2ad7bf3638411cb547f2823df08166c13ab04269 (3.19) */
+-enum {
+-        IFLA_IPVLAN_UNSPEC,
+-        IFLA_IPVLAN_MODE,
+-        IFLA_IPVLAN_FLAGS,
+-        __IFLA_IPVLAN_MAX
+-};
+-#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
+-enum ipvlan_mode {
+-        IPVLAN_MODE_L2 = 0,
+-        IPVLAN_MODE_L3,
+-        IPVLAN_MODE_L3S,
+-        IPVLAN_MODE_MAX
+-};
+-#else
+-#if !HAVE_IPVLAN_MODE_L3S /* linux@4fbae7d83c98c30efcf0a2a2ac55fbb75ef5a1a5 (4.9) */
+-#define IPVLAN_MODE_L3S   2
+-#define IPVLAN_MODE_MAX   3
+-#endif
+-#if !HAVE_IFLA_IPVLAN_FLAGS /* linux@a190d04db93710ae166749055b6985397c6d13f5 (4.15) */
+-#define IFLA_IPVLAN_FLAGS 2
+-
+-#undef  IFLA_IPVLAN_MAX
+-#define IFLA_IPVLAN_MAX   2
+-#endif
+-#endif /* !HAVE_IFLA_IPVLAN_MODE */
+-
+-/* linux@a190d04db93710ae166749055b6985397c6d13f5 (4.15) */
+-#ifndef IPVLAN_F_PRIVATE
+-#define IPVLAN_F_PRIVATE 0x01
+-#endif
+-
+-/* linux@fe89aa6b250c1011ccf425fbb7998e96bd54263f (4.15) */
+-#ifndef IPVLAN_F_VEPA
+-#define IPVLAN_F_VEPA    0x02
+-#endif
+-
+-#if !HAVE_IFLA_PHYS_PORT_ID /* linux@66cae9ed6bc46b8cc57a9693f99f69926f3cc7ef (3.12) */
+-#define IFLA_PHYS_PORT_ID       34
+-#endif
+-#if !HAVE_IFLA_CARRIER_CHANGES /* linux@2d3b479df41a10e2f41f9259fcba775bd34de6e4 (3.15) */
+-#define IFLA_CARRIER_CHANGES    35
+-#endif
+-#if !HAVE_IFLA_PHYS_SWITCH_ID /* linux@82f2841291cfaf4d225aa1766424280254d3e3b2 (3.19) */
+-#define IFLA_PHYS_SWITCH_ID     36
+-#endif
+-#if !HAVE_IFLA_LINK_NETNSID /* linux@d37512a277dfb2cef8a578e25a3246f61399a55a (4.0) */
+-#define IFLA_LINK_NETNSID       37
+-#endif
+-#if !HAVE_IFLA_PHYS_PORT_NAME /* linux@db24a9044ee191c397dcd1c6574f56d67d7c8df5 (4.1) */
+-#define IFLA_PHYS_PORT_NAME     38
+-#endif
+-#if !HAVE_IFLA_PROTO_DOWN /* linux@88d6378bd6c096cb8440face3ae3f33d55a2e6e4 (4.3) */
+-#define IFLA_PROTO_DOWN         39
+-#endif
+-#if !HAVE_IFLA_GSO_MAX_SIZE /* linux@c70ce028e834f8e51306217dbdbd441d851c64d3 (4.6) */
+-#define IFLA_GSO_MAX_SEGS       40
+-#define IFLA_GSO_MAX_SIZE       41
+-#endif
+-#if !HAVE_IFLA_PAD /* linux@18402843bf88c2e9674e1a3a05c73b7d9b09ee05 (4.7) */
+-#define IFLA_PAD                42
+-#endif
+-#if !HAVE_IFLA_XDP /* linux@d1fdd9138682e0f272beee0cb08b6328c5478b26 (4.8) */
+-#define IFLA_XDP                43
+-#endif
+-#if !HAVE_IFLA_EVENT /* linux@3d3ea5af5c0b382bc9d9aed378fd814fb5d4a011 (4.13) */
+-#define IFLA_EVENT              44
+-#endif
+-#if !HAVE_IFLA_IF_NETNSID /* linux@6621dd29eb9b5e6774ec7a9a75161352fdea47fc, 79e1ad148c844f5c8b9d76b36b26e3886dca95ae (4.15) */
+-#define IFLA_IF_NETNSID         45
+-#define IFLA_NEW_NETNSID        46
+-#endif
+-#if !HAVE_IFLA_TARGET_NETNSID /* linux@19d8f1ad12fd746e60707a58d954980013c7a35a (4.20) */
+-#define IFLA_TARGET_NETNSID IFLA_IF_NETNSID
+-#endif
+-#if !HAVE_IFLA_NEW_IFINDEX /* linux@b2d3bcfa26a7a8de41f358a6cae8b848673b3c6e, 38e01b30563a5b5ade7b54e5d739d16a2b02fe82 (4.16) */
+-#define IFLA_CARRIER_UP_COUNT   47
+-#define IFLA_CARRIER_DOWN_COUNT 48
+-#define IFLA_NEW_IFINDEX        49
+-#endif
+-#if !HAVE_IFLA_MAX_MTU /* linux@3e7a50ceb11ea75c27e944f1a01e478fd62a2d8d (4.19) */
+-#define IFLA_MIN_MTU            50
+-#define IFLA_MAX_MTU            51
+-
+-#undef  IFLA_MAX
+-#define IFLA_MAX                51
+-#endif
+-
+-#if !HAVE_IFLA_BOND_MODE /* linux@90af231106c0b8d223c27d35464af95cb3d9cacf (3.13) */
+-#define IFLA_BOND_MODE              1
+-#endif
+-#if !HAVE_IFLA_BOND_ACTIVE_SLAVE /* linux@ec76aa49855f6d6fea5e01de179fb57dd47c619d (3.13) */
+-#define IFLA_BOND_ACTIVE_SLAVE      2
+-#endif
+-#if !HAVE_IFLA_BOND_AD_INFO /* linux@4ee7ac7526d4a9413cafa733d824edfe49fdcc46 (3.14) */
+-#define IFLA_BOND_MIIMON            3
+-#define IFLA_BOND_UPDELAY           4
+-#define IFLA_BOND_DOWNDELAY         5
+-#define IFLA_BOND_USE_CARRIER       6
+-#define IFLA_BOND_ARP_INTERVAL      7
+-#define IFLA_BOND_ARP_IP_TARGET     8
+-#define IFLA_BOND_ARP_VALIDATE      9
+-#define IFLA_BOND_ARP_ALL_TARGETS   10
+-#define IFLA_BOND_PRIMARY           11
+-#define IFLA_BOND_PRIMARY_RESELECT  12
+-#define IFLA_BOND_FAIL_OVER_MAC     13
+-#define IFLA_BOND_XMIT_HASH_POLICY  14
+-#define IFLA_BOND_RESEND_IGMP       15
+-#define IFLA_BOND_NUM_PEER_NOTIF    16
+-#define IFLA_BOND_ALL_SLAVES_ACTIVE 17
+-#define IFLA_BOND_MIN_LINKS         18
+-#define IFLA_BOND_LP_INTERVAL       19
+-#define IFLA_BOND_PACKETS_PER_SLAVE 20
+-#define IFLA_BOND_AD_LACP_RATE      21
+-#define IFLA_BOND_AD_SELECT         22
+-#define IFLA_BOND_AD_INFO           23
+-#endif
+-#if !HAVE_IFLA_BOND_AD_ACTOR_SYSTEM /* linux@171a42c38c6e1a5a076d6276e94e55a0b5b7868c (4.2) */
+-#define IFLA_BOND_AD_ACTOR_SYS_PRIO 24
+-#define IFLA_BOND_AD_USER_PORT_KEY  25
+-#define IFLA_BOND_AD_ACTOR_SYSTEM   26
+-#endif
+-#if !HAVE_IFLA_BOND_TLB_DYNAMIC_LB /* linux@0f7bffd9e512b77279bbce704fad3cb1d6887958 (4.3) */
+-#define IFLA_BOND_TLB_DYNAMIC_LB    27
+-
+-#undef  IFLA_BOND_MAX
+-#define IFLA_BOND_MAX               27
+-#endif
+-
+-#if !HAVE_IFLA_VXLAN_UDP_ZERO_CSUM6_RX /* linux@359a0ea9875ef4f32c8425bbe1ae348e1fd2ed2a (3.16) */
+-#define IFLA_VXLAN_UDP_CSUM          18
+-#define IFLA_VXLAN_UDP_ZERO_CSUM6_TX 19
+-#define IFLA_VXLAN_UDP_ZERO_CSUM6_RX 20
+-#endif
+-#if !HAVE_IFLA_VXLAN_REMCSUM_NOPARTIAL /* linux@dfd8645ea1bd91277f841e74c33e1f4dbbede808..0ace2ca89cbd6bcdf2b9d2df1fa0fa24ea9d1653 (4.0) */
+-#define IFLA_VXLAN_REMCSUM_TX        21
+-#define IFLA_VXLAN_REMCSUM_RX        22
+-#define IFLA_VXLAN_GBP               23
+-#define IFLA_VXLAN_REMCSUM_NOPARTIAL 24
+-#endif
+-#if !HAVE_IFLA_VXLAN_COLLECT_METADATA /* linux@f8a9b1bc1b238eed9987da747a0e52f5bb009980 (4.3) */
+-#define IFLA_VXLAN_COLLECT_METADATA  25
+-#endif
+-#if !HAVE_IFLA_VXLAN_LABEL /* linux@e7f70af111f086a20800ad2e17f544b2e3e0f375 (4.6) */
+-#define IFLA_VXLAN_LABEL             26
+-#endif
+-#if !HAVE_IFLA_VXLAN_GPE /* linux@e1e5314de08ba6003b358125eafc9ad9e75a950c (4.7) */
+-#define IFLA_VXLAN_GPE               27
+-#endif
+-#if !HAVE_IFLA_VXLAN_TTL_INHERIT /* linux@72f6d71e491e6ce269b564865b21fab0a4402dd3 (4.18) */
+-#define IFLA_VXLAN_TTL_INHERIT       28
+-
+-#undef  IFLA_VXLAN_MAX
+-#define IFLA_VXLAN_MAX               28
+-#endif
+-
+-#if !HAVE_IFLA_GENEVE_TOS /* linux@2d07dc79fe04a43d82a346ced6bbf07bdb523f1b..d89511251f6519599b109dc6cda87a6ab314ed8c (4.2) */
+-enum {
+-        IFLA_GENEVE_UNSPEC,
+-        IFLA_GENEVE_ID,
+-        IFLA_GENEVE_REMOTE,
+-        IFLA_GENEVE_TTL,
+-        IFLA_GENEVE_TOS,
+-        IFLA_GENEVE_PORT,        /* destination port */
+-        IFLA_GENEVE_COLLECT_METADATA,
+-        IFLA_GENEVE_REMOTE6,
+-        IFLA_GENEVE_UDP_CSUM,
+-        IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+-        IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+-        IFLA_GENEVE_LABEL,
+-        IFLA_GENEVE_TTL_INHERIT,
+-        __IFLA_GENEVE_MAX
+-};
+-#define IFLA_GENEVE_MAX        (__IFLA_GENEVE_MAX - 1)
+-#else
+-#if !HAVE_IFLA_GENEVE_COLLECT_METADATA /* linux@e305ac6cf5a1e1386aedce7ef9cb773635d5845c (4.3) */
+-#define IFLA_GENEVE_PORT              5
+-#define IFLA_GENEVE_COLLECT_METADATA  6
+-#endif
+-#if !HAVE_IFLA_GENEVE_REMOTE6 /* linux@8ed66f0e8235118a31720acdab3bbbe9debd0f6a (4.4) */
+-#define IFLA_GENEVE_REMOTE6           7
+-#endif
+-#if !HAVE_IFLA_GENEVE_UDP_ZERO_CSUM6_RX /* linux@abe492b4f50c3ae2ebcfaa2f5c16176aebaa1c68 (4.5) */
+-#define IFLA_GENEVE_UDP_CSUM          8
+-#define IFLA_GENEVE_UDP_ZERO_CSUM6_TX 9
+-#define IFLA_GENEVE_UDP_ZERO_CSUM6_RX 10
+-#endif
+-#if !HAVE_IFLA_GENEVE_LABEL /* linux@8eb3b99554b82da968d1fbc00df9f3156c5e2d63 (4.6) */
+-#define IFLA_GENEVE_LABEL             11
+-#endif
+-#if !HAVE_IFLA_GENEVE_TTL_INHERIT /* linux@52d0d404d39dd9eac71a181615d6ca15e23d8e38 (4.20) */
+-#define IFLA_GENEVE_TTL_INHERIT       12
+-
+-#undef  IFLA_GENEVE_MAX
+-#define IFLA_GENEVE_MAX               12
+-#endif
+-#endif
+-
+-#if !HAVE_IFLA_BR_MAX_AGE /* linux@e5c3ea5c668033b303e7ac835d7d91da32d97958 (3.18) */
+-enum {
+-        IFLA_BR_UNSPEC,
+-        IFLA_BR_FORWARD_DELAY,
+-        IFLA_BR_HELLO_TIME,
+-        IFLA_BR_MAX_AGE,
+-        IFLA_BR_AGEING_TIME,
+-        IFLA_BR_STP_STATE,
+-        IFLA_BR_PRIORITY,
+-        IFLA_BR_VLAN_FILTERING,
+-        IFLA_BR_VLAN_PROTOCOL,
+-        IFLA_BR_GROUP_FWD_MASK,
+-        IFLA_BR_ROOT_ID,
+-        IFLA_BR_BRIDGE_ID,
+-        IFLA_BR_ROOT_PORT,
+-        IFLA_BR_ROOT_PATH_COST,
+-        IFLA_BR_TOPOLOGY_CHANGE,
+-        IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+-        IFLA_BR_HELLO_TIMER,
+-        IFLA_BR_TCN_TIMER,
+-        IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+-        IFLA_BR_GC_TIMER,
+-        IFLA_BR_GROUP_ADDR,
+-        IFLA_BR_FDB_FLUSH,
+-        IFLA_BR_MCAST_ROUTER,
+-        IFLA_BR_MCAST_SNOOPING,
+-        IFLA_BR_MCAST_QUERY_USE_IFADDR,
+-        IFLA_BR_MCAST_QUERIER,
+-        IFLA_BR_MCAST_HASH_ELASTICITY,
+-        IFLA_BR_MCAST_HASH_MAX,
+-        IFLA_BR_MCAST_LAST_MEMBER_CNT,
+-        IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+-        IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+-        IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+-        IFLA_BR_MCAST_QUERIER_INTVL,
+-        IFLA_BR_MCAST_QUERY_INTVL,
+-        IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+-        IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+-        IFLA_BR_NF_CALL_IPTABLES,
+-        IFLA_BR_NF_CALL_IP6TABLES,
+-        IFLA_BR_NF_CALL_ARPTABLES,
+-        IFLA_BR_VLAN_DEFAULT_PVID,
+-        IFLA_BR_PAD,
+-        IFLA_BR_VLAN_STATS_ENABLED,
+-        IFLA_BR_MCAST_STATS_ENABLED,
+-        IFLA_BR_MCAST_IGMP_VERSION,
+-        IFLA_BR_MCAST_MLD_VERSION,
+-        IFLA_BR_VLAN_STATS_PER_PORT,
+-        __IFLA_BR_MAX,
+-};
+-
+-#define IFLA_BR_MAX        (__IFLA_BR_MAX - 1)
+-#else
+-#if !HAVE_IFLA_BR_PRIORITY /* linux@af615762e972be0c66cf1d156ca4fac13b93c0b0 (4.1) */
+-#define IFLA_BR_AGEING_TIME                4
+-#define IFLA_BR_STP_STATE                  5
+-#define IFLA_BR_PRIORITY                   6
+-#endif
+-#if !HAVE_IFLA_BR_VLAN_PROTOCOL /* linux@a7854037da006a7472c48773e3190db55217ec9b, d2d427b3927bd7a0348fc7f323d0e291f79a2779 (4.3) */
+-#define IFLA_BR_VLAN_FILTERING             7
+-#define IFLA_BR_VLAN_PROTOCOL              8
+-#endif
+-#if !HAVE_IFLA_BR_VLAN_DEFAULT_PVID /* linux@7910228b6bb35f3c8e0bc72a8d84c29616cb1b90..0f963b7592ef9e054974b6672b86ec1edd84b4bc (4.4) */
+-#define IFLA_BR_GROUP_FWD_MASK             9
+-#define IFLA_BR_ROOT_ID                    10
+-#define IFLA_BR_BRIDGE_ID                  11
+-#define IFLA_BR_ROOT_PORT                  12
+-#define IFLA_BR_ROOT_PATH_COST             13
+-#define IFLA_BR_TOPOLOGY_CHANGE            14
+-#define IFLA_BR_TOPOLOGY_CHANGE_DETECTED   15
+-#define IFLA_BR_HELLO_TIMER                16
+-#define IFLA_BR_TCN_TIMER                  17
+-#define IFLA_BR_TOPOLOGY_CHANGE_TIMER      18
+-#define IFLA_BR_GC_TIMER                   19
+-#define IFLA_BR_GROUP_ADDR                 20
+-#define IFLA_BR_FDB_FLUSH                  21
+-#define IFLA_BR_MCAST_ROUTER               22
+-#define IFLA_BR_MCAST_SNOOPING             23
+-#define IFLA_BR_MCAST_QUERY_USE_IFADDR     24
+-#define IFLA_BR_MCAST_QUERIER              25
+-#define IFLA_BR_MCAST_HASH_ELASTICITY      26
+-#define IFLA_BR_MCAST_HASH_MAX             27
+-#define IFLA_BR_MCAST_LAST_MEMBER_CNT      28
+-#define IFLA_BR_MCAST_STARTUP_QUERY_CNT    29
+-#define IFLA_BR_MCAST_LAST_MEMBER_INTVL    30
+-#define IFLA_BR_MCAST_MEMBERSHIP_INTVL     31
+-#define IFLA_BR_MCAST_QUERIER_INTVL        32
+-#define IFLA_BR_MCAST_QUERY_INTVL          33
+-#define IFLA_BR_MCAST_QUERY_RESPONSE_INTVL 34
+-#define IFLA_BR_MCAST_STARTUP_QUERY_INTVL  35
+-#define IFLA_BR_NF_CALL_IPTABLES           36
+-#define IFLA_BR_NF_CALL_IP6TABLES          37
+-#define IFLA_BR_NF_CALL_ARPTABLES          38
+-#define IFLA_BR_VLAN_DEFAULT_PVID          39
+-#endif
+-#if !HAVE_IFLA_BR_VLAN_STATS_ENABLED /* linux@12a0faa3bd76157b9dc096758d6818ff535e4586, 6dada9b10a0818ba72c249526a742c8c41274a73 (4.7) */
+-#define IFLA_BR_PAD                        40
+-#define IFLA_BR_VLAN_STATS_ENABLED         41
+-#endif
+-#if !HAVE_IFLA_BR_MCAST_STATS_ENABLED /* linux@1080ab95e3c7bdd77870e209aff83c763fdcf439 (4.8) */
+-#define IFLA_BR_MCAST_STATS_ENABLED        42
+-#endif
+-#if !HAVE_IFLA_BR_MCAST_MLD_VERSION /* linux@5e9235853d652a295d5f56cb8652950b6b5bf56b, aa2ae3e71c74cc00ec22f133dc900b3817415785 (4.10) */
+-#define IFLA_BR_MCAST_IGMP_VERSION         43
+-#define IFLA_BR_MCAST_MLD_VERSION          44
+-#endif
+-#if !HAVE_IFLA_BR_VLAN_STATS_PER_PORT /* linux@9163a0fc1f0c0980f117cc25f4fa6ba9b0750a36 (4.20) */
+-#define IFLA_BR_VLAN_STATS_PER_PORT        45
+-
+-#undef  IFLA_BR_MAX
+-#define IFLA_BR_MAX                        45
+-#endif
+-#endif
+-
+-#if !HAVE_IFLA_BRPORT_LEARNING_SYNC /* linux@958501163ddd6ea22a98f94fa0e7ce6d4734e5c4, efacacdaf7cb5a0592ed772e3731636b2742e34a (3.19)*/
+-#define IFLA_BRPORT_PROXYARP            10
+-#define IFLA_BRPORT_LEARNING_SYNC       11
+-#endif
+-#if !HAVE_IFLA_BRPORT_PROXYARP_WIFI /* linux@842a9ae08a25671db3d4f689eed68b4d64be15b5 (4.1) */
+-#define IFLA_BRPORT_PROXYARP_WIFI       12
+-#endif
+-#if !HAVE_IFLA_BRPORT_MULTICAST_ROUTER /* linux@4ebc7660ab4559cad10b6595e05f70562bb26dc5..5d6ae479ab7ddf77bb22bdf739268581453ff886 (4.4) */
+-#define IFLA_BRPORT_ROOT_ID             13
+-#define IFLA_BRPORT_BRIDGE_ID           14
+-#define IFLA_BRPORT_DESIGNATED_PORT     15
+-#define IFLA_BRPORT_DESIGNATED_COST     16
+-#define IFLA_BRPORT_ID                  17
+-#define IFLA_BRPORT_NO                  18
+-#define IFLA_BRPORT_TOPOLOGY_CHANGE_ACK 19
+-#define IFLA_BRPORT_CONFIG_PENDING      20
+-#define IFLA_BRPORT_MESSAGE_AGE_TIMER   21
+-#define IFLA_BRPORT_FORWARD_DELAY_TIMER 22
+-#define IFLA_BRPORT_HOLD_TIMER          23
+-#define IFLA_BRPORT_FLUSH               24
+-#define IFLA_BRPORT_MULTICAST_ROUTER    25
+-#endif
+-#if !HAVE_IFLA_BRPORT_PAD /* linux@12a0faa3bd76157b9dc096758d6818ff535e4586 (4.7) */
+-#define IFLA_BRPORT_PAD                 26
+-#endif
+-#if !HAVE_IFLA_BRPORT_MCAST_FLOOD /* linux@b6cb5ac8331b6bcfe9ce38c7f7f58db6e1d6270a (4.9) */
+-#define IFLA_BRPORT_MCAST_FLOOD         27
+-#endif
+-#if !HAVE_IFLA_BRPORT_VLAN_TUNNEL /* linux@6db6f0eae6052b70885562e1733896647ec1d807, b3c7ef0adadc5768e0baa786213c6bd1ce521a77 (4.11) */
+-#define IFLA_BRPORT_MCAST_TO_UCAST      28
+-#define IFLA_BRPORT_VLAN_TUNNEL         29
+-#endif
+-#if !HAVE_IFLA_BRPORT_BCAST_FLOOD /* linux@99f906e9ad7b6e79ffeda30f45906a8448b9d6a2 (4.12) */
+-#define IFLA_BRPORT_BCAST_FLOOD         30
+-#endif
+-#if !HAVE_IFLA_BRPORT_NEIGH_SUPPRESS /* linux@5af48b59f35cf712793badabe1a574a0d0ce3bd3, 821f1b21cabb46827ce39ddf82e2789680b5042a (4.15) */
+-#define IFLA_BRPORT_GROUP_FWD_MASK      31
+-#define IFLA_BRPORT_NEIGH_SUPPRESS      32
+-#endif
+-#if !HAVE_IFLA_BRPORT_ISOLATED /* linux@7d850abd5f4edb1b1ca4b4141a4453305736f564 (4.18) */
+-#define IFLA_BRPORT_ISOLATED            33
+-#endif
+-#if !HAVE_IFLA_BRPORT_BACKUP_PORT /* linux@2756f68c314917d03eb348084edb08bb929139d9 (4.19) */
+-#define IFLA_BRPORT_BACKUP_PORT         34
+-
+-#undef  IFLA_BRPORT_MAX
+-#define IFLA_BRPORT_MAX                 34
+-#endif
+-
+-#if !HAVE_IFLA_VRF_TABLE /* linux@4e3c89920cd3a6cfce22c6f537690747c26128dd (4.3) */
+-enum {
+-        IFLA_VRF_UNSPEC,
+-        IFLA_VRF_TABLE,
+-        __IFLA_VRF_MAX
+-};
+-#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+-#endif
+diff --git a/src/basic/missing_if_tunnel.h b/src/basic/missing_if_tunnel.h
+deleted file mode 100644
+index f51fdd1ed7..0000000000
+--- a/src/basic/missing_if_tunnel.h
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#if !HAVE_IFLA_VTI_FWMARK /* linux@0a473b82cb23e7a35c4be6e9765c8487a65e8f55 (4.12) */
+-#define IFLA_VTI_FWMARK 6
+-
+-#undef  IFLA_VTI_MAX
+-#define IFLA_VTI_MAX    6
+-#endif
+-
+-#if !HAVE_IFLA_IPTUN_ENCAP_DPORT /* linux@56328486539ddd07cbaafec7a542a2c8a3043623 (3.18)*/
+-#define IFLA_IPTUN_ENCAP_TYPE       15
+-#define IFLA_IPTUN_ENCAP_FLAGS      16
+-#define IFLA_IPTUN_ENCAP_SPORT      17
+-#define IFLA_IPTUN_ENCAP_DPORT      18
+-#endif
+-
+-#if !HAVE_IFLA_IPTUN_COLLECT_METADATA /* linux@cfc7381b3002756b1dcada32979e942aa3126e31 (4.9) */
+-#define IFLA_IPTUN_COLLECT_METADATA 19
+-#endif
+-
+-#if !HAVE_IFLA_IPTUN_FWMARK /* linux@0a473b82cb23e7a35c4be6e9765c8487a65e8f55 (4.12) */
+-#define IFLA_IPTUN_FWMARK           20
+-
+-#undef  IFLA_IPTUN_MAX
+-#define IFLA_IPTUN_MAX              20
+-#endif
+-
+-#if !HAVE_IFLA_GRE_ENCAP_DPORT /* linux@4565e9919cda747815547e2e5d7b78f15efbffdf (3.18) */
+-#define IFLA_GRE_ENCAP_TYPE       14
+-#define IFLA_GRE_ENCAP_FLAGS      15
+-#define IFLA_GRE_ENCAP_SPORT      16
+-#define IFLA_GRE_ENCAP_DPORT      17
+-#endif
+-
+-#if !HAVE_IFLA_GRE_COLLECT_METADATA /* linux@2e15ea390e6f4466655066d97e22ec66870a042c (4.3) */
+-#define IFLA_GRE_COLLECT_METADATA 18
+-#endif
+-
+-#if !HAVE_IFLA_GRE_IGNORE_DF /* linux@22a59be8b7693eb2d0897a9638f5991f2f8e4ddd (4.8) */
+-#define IFLA_GRE_IGNORE_DF        19
+-#endif
+-
+-#if !HAVE_IFLA_GRE_FWMARK /* linux@0a473b82cb23e7a35c4be6e9765c8487a65e8f55 (4.12) */
+-#define IFLA_GRE_FWMARK           20
+-#endif
+-
+-#if !HAVE_IFLA_GRE_ERSPAN_INDEX /* linux@84e54fe0a5eaed696dee4019c396f8396f5a908b (4.14) */
+-#define IFLA_GRE_ERSPAN_INDEX     21
+-#endif
+-
+-#if !HAVE_IFLA_GRE_ERSPAN_HWID /* linux@f551c91de262ba36b20c3ac19538afb4f4507441 (4.16) */
+-#define IFLA_GRE_ERSPAN_VER       22
+-#define IFLA_GRE_ERSPAN_DIR       23
+-#define IFLA_GRE_ERSPAN_HWID      24
+-
+-#undef  IFLA_GRE_MAX
+-#define IFLA_GRE_MAX              24
+-#endif
+diff --git a/src/basic/missing_network.h b/src/basic/missing_network.h
+index 80ef13fd3e..257879405c 100644
+--- a/src/basic/missing_network.h
++++ b/src/basic/missing_network.h
+@@ -1,158 +1,22 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ #pragma once
+ 
+-#include <linux/loop.h>
+-#include <linux/rtnetlink.h>
+-#include <net/ethernet.h>
+-
+-#include "missing_ethtool.h"
+-#include "missing_fib_rules.h"
+-#include "missing_fou.h"
+-#include "missing_if_bridge.h"
+-#include "missing_if_link.h"
+-#include "missing_if_tunnel.h"
+-#include "missing_vxcan.h"
+-
+-/* if.h */
+-/* The following two defines are actually available in the kernel headers for longer, but we define them here anyway,
+- * since that makes it easier to use them in conjunction with the glibc net/if.h header which conflicts with
+- * linux/if.h. */
+-#ifndef IF_OPER_UNKNOWN
+-#define IF_OPER_UNKNOWN 0
+-#endif
+-
+-#ifndef IF_OPER_UP
+-#define IF_OPER_UP 6
+-#endif
+-
+-#ifndef IFF_LOWER_UP
+-#define IFF_LOWER_UP 0x10000
+-#endif
+-
+-#ifndef IFF_DORMANT
+-#define IFF_DORMANT 0x20000
+-#endif
+-
+-/* if_addr.h */
+-#if !HAVE_IFA_FLAGS
+-#define IFA_FLAGS 8
+-#endif
+-
+-#ifndef IFA_F_MANAGETEMPADDR
+-#define IFA_F_MANAGETEMPADDR 0x100
+-#endif
+-
+-#ifndef IFA_F_NOPREFIXROUTE
+-#define IFA_F_NOPREFIXROUTE 0x200
+-#endif
+-
+-#ifndef IFA_F_MCAUTOJOIN
+-#define IFA_F_MCAUTOJOIN 0x400
+-#endif
+-
+-/* if_arp.h */
+-#ifndef ARPHRD_IP6GRE
+-#define ARPHRD_IP6GRE 823
+-#endif
+-
+-/* if_bonding.h */
+-#ifndef BOND_XMIT_POLICY_ENCAP23
+-#define BOND_XMIT_POLICY_ENCAP23 3
+-#endif
+-
+-#ifndef BOND_XMIT_POLICY_ENCAP34
+-#define BOND_XMIT_POLICY_ENCAP34 4
+-#endif
+-
+-/* if_tun.h */
+-#ifndef IFF_MULTI_QUEUE
+-#define IFF_MULTI_QUEUE 0x100
+-#endif
+-
+-/* in6.h */
++/* linux/in6.h or netinet/in.h */
+ #ifndef IPV6_UNICAST_IF
+ #define IPV6_UNICAST_IF 76
+ #endif
+ 
+-/* ip.h */
++/* Not exposed but defined at include/net/ip.h */
+ #ifndef IPV4_MIN_MTU
+ #define IPV4_MIN_MTU 68
+ #endif
+ 
+-/* ipv6.h */
++/* linux/ipv6.h */
+ #ifndef IPV6_MIN_MTU
+ #define IPV6_MIN_MTU 1280
+ #endif
+ 
+-/* loop.h */
+-#if !HAVE_LO_FLAGS_PARTSCAN
+-#define LO_FLAGS_PARTSCAN 8
+-#endif
+-
+-#ifndef LOOP_CTL_REMOVE
+-#define LOOP_CTL_REMOVE 0x4C81
+-#endif
+-
+-#ifndef LOOP_CTL_GET_FREE
+-#define LOOP_CTL_GET_FREE 0x4C82
+-#endif
+-
+-/* netdevice.h */
+-#ifndef NET_ADDR_PERM
+-#define NET_ADDR_PERM 0
+-#endif
+-
+-#ifndef NET_ADDR_RANDOM
+-#define NET_ADDR_RANDOM 1
+-#endif
+-
+-#ifndef NET_ADDR_STOLEN
+-#define NET_ADDR_STOLEN 2
+-#endif
+-
+-#ifndef NET_ADDR_SET
+-#define NET_ADDR_SET 3
+-#endif
+-
+-#ifndef NET_NAME_UNKNOWN
+-#define NET_NAME_UNKNOWN 0
+-#endif
+-
+-#ifndef NET_NAME_ENUM
+-#define NET_NAME_ENUM 1
+-#endif
+-
+-#ifndef NET_NAME_PREDICTABLE
+-#define NET_NAME_PREDICTABLE 2
+-#endif
+-
+-#ifndef NET_NAME_USER
+-#define NET_NAME_USER 3
+-#endif
+-
+-#ifndef NET_NAME_RENAMED
+-#define NET_NAME_RENAMED 4
+-#endif
+-
+-/* netlink.h */
+-#ifndef NETLINK_LIST_MEMBERSHIPS /* b42be38b2778eda2237fc759e55e3b698b05b315 (4.2) */
+-#define NETLINK_LIST_MEMBERSHIPS 9
+-#endif
+-
+-/* rtnetlink.h */
+-#ifndef RTA_PREF
+-#define RTA_PREF 20
+-#endif
+-
+-#ifndef RTAX_QUICKACK
+-#define RTAX_QUICKACK 15
+-#endif
+-
+-#ifndef RTA_EXPIRES
+-#define RTA_EXPIRES 23
+-#endif
+-
+-/* Note that LOOPBACK_IFINDEX is currently not exported by the
++/* Note that LOOPBACK_IFINDEX is currently not exposed by the
+  * kernel/glibc, but hardcoded internally by the kernel.  However, as
+  * it is exported to userspace indirectly via rtnetlink and the
+  * ioctls, and made use of widely we define it here too, in a way that
+diff --git a/src/basic/missing_vxcan.h b/src/basic/missing_vxcan.h
+deleted file mode 100644
+index be430f708d..0000000000
+--- a/src/basic/missing_vxcan.h
++++ /dev/null
+@@ -1,12 +0,0 @@
+-/* SPDX-License-Identifier: LGPL-2.1+ */
+-#pragma once
+-
+-#if !HAVE_LINUX_CAN_VXCAN_H /* linux@a8f820a380a2a06fc4fe1a54159067958f800929 (4.12) */
+-enum {
+-        VXCAN_INFO_UNSPEC,
+-        VXCAN_INFO_PEER,
+-
+-        __VXCAN_INFO_MAX
+-#define VXCAN_INFO_MAX        (__VXCAN_INFO_MAX - 1)
+-};
+-#endif
+diff --git a/src/core/bpf-devices.c b/src/core/bpf-devices.c
+index 81e91fcb36..9750c4c682 100644
+--- a/src/core/bpf-devices.c
++++ b/src/core/bpf-devices.c
+@@ -1,5 +1,5 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+-#include <linux/libbpf.h>
++#include <linux/bpf_insn.h>
+ 
+ #include "bpf-devices.h"
+ #include "bpf-program.h"
+diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
+index 2ecce300da..723c7b4b4e 100644
+--- a/src/core/bpf-firewall.c
++++ b/src/core/bpf-firewall.c
+@@ -4,7 +4,7 @@
+ #include <assert.h>
+ #include <errno.h>
+ #include <fcntl.h>
+-#include <linux/libbpf.h>
++#include <linux/bpf_insn.h>
+ #include <net/ethernet.h>
+ #include <net/if.h>
+ #include <netinet/ip.h>
+diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
+index 8248ac0f5a..0c67d1c68f 100644
+--- a/src/libsystemd/sd-netlink/netlink-types.c
++++ b/src/libsystemd/sd-netlink/netlink-types.c
+@@ -3,6 +3,7 @@
+ #include <netinet/in.h>
+ #include <stdint.h>
+ #include <sys/socket.h>
++#include <linux/can/vxcan.h>
+ #include <linux/netlink.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/genetlink.h>
+@@ -10,6 +11,7 @@
+ #include <linux/if.h>
+ #include <linux/can/netlink.h>
+ #include <linux/fib_rules.h>
++#include <linux/fou.h>
+ #include <linux/if_addr.h>
+ #include <linux/if_addrlabel.h>
+ #include <linux/if_bridge.h>
+@@ -17,14 +19,7 @@
+ #include <linux/if_tunnel.h>
+ #include <linux/l2tp.h>
+ #include <linux/veth.h>
+-
+-#if HAVE_LINUX_FOU_H
+-#include <linux/fou.h>
+-#endif
+-
+-#if HAVE_LINUX_CAN_VXCAN_H
+-#include <linux/can/vxcan.h>
+-#endif
++#include <linux/wireguard.h>
+ 
+ #include "macro.h"
+ #include "missing.h"
+@@ -32,7 +27,6 @@
+ #include "sd-netlink.h"
+ #include "string-table.h"
+ #include "util.h"
+-#include "wireguard-netlink.h"
+ 
+ /* Maximum ARP IP target defined in kernel */
+ #define BOND_MAX_ARP_TARGETS    16
+diff --git a/src/network/netdev/fou-tunnel.h b/src/network/netdev/fou-tunnel.h
+index 0e3fd7dd76..51eeac41bd 100644
+--- a/src/network/netdev/fou-tunnel.h
++++ b/src/network/netdev/fou-tunnel.h
+@@ -1,12 +1,9 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ #pragma once
+ 
+-#if HAVE_LINUX_FOU_H
+ #include <linux/fou.h>
+-#endif
+ 
+ #include "in-addr-util.h"
+-#include "missing_fou.h"
+ #include "netdev/netdev.h"
+ 
+ typedef enum FooOverUDPEncapType {
+diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h
+index fb426d37e5..78f09dbb2d 100644
+--- a/src/network/netdev/ipvlan.h
++++ b/src/network/netdev/ipvlan.h
+@@ -3,7 +3,6 @@
+ 
+ #include <linux/if_link.h>
+ 
+-#include "missing_if_link.h"
+ #include "netdev/netdev.h"
+ 
+ typedef enum IPVlanMode {
+diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c
+index 719b5e4add..84f6af8578 100644
+--- a/src/network/netdev/tunnel.c
++++ b/src/network/netdev/tunnel.c
+@@ -1,15 +1,11 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include <arpa/inet.h>
+-#include <net/if.h>
++#include <linux/fou.h>
+ #include <linux/ip.h>
+ #include <linux/if_tunnel.h>
+ #include <linux/ip6_tunnel.h>
+ 
+-#if HAVE_LINUX_FOU_H
+-#include <linux/fou.h>
+-#endif
+-
+ #include "sd-netlink.h"
+ 
+ #include "conf-parser.h"
+diff --git a/src/network/netdev/vxcan.c b/src/network/netdev/vxcan.c
+index e8ea70a1ed..c5dd5df51c 100644
+--- a/src/network/netdev/vxcan.c
++++ b/src/network/netdev/vxcan.c
+@@ -1,10 +1,7 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+-#if HAVE_LINUX_CAN_VXCAN_H
+ #include <linux/can/vxcan.h>
+-#endif
+ 
+-#include "missing.h"
+ #include "netdev/vxcan.h"
+ 
+ static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c
+index 7959c1c01f..f3084c0773 100644
+--- a/src/network/netdev/wireguard.c
++++ b/src/network/netdev/wireguard.c
+@@ -23,7 +23,6 @@
+ #include "resolve-private.h"
+ #include "string-util.h"
+ #include "strv.h"
+-#include "wireguard-netlink.h"
+ #include "wireguard.h"
+ 
+ static void resolve_endpoints(NetDev *netdev);
+diff --git a/src/network/netdev/wireguard.h b/src/network/netdev/wireguard.h
+index 4ae520c52b..862f2a99c4 100644
+--- a/src/network/netdev/wireguard.h
++++ b/src/network/netdev/wireguard.h
+@@ -2,10 +2,11 @@
+ 
+ typedef struct Wireguard Wireguard;
+ 
++#include <linux/wireguard.h>
++
+ #include "in-addr-util.h"
+ #include "netdev.h"
+ #include "socket-util.h"
+-#include "wireguard-netlink.h"
+ 
+ typedef struct WireguardIPmask {
+         uint16_t family;
+diff --git a/src/network/networkd-brvlan.c b/src/network/networkd-brvlan.c
+index 8377623da4..8f9103f146 100644
+--- a/src/network/networkd-brvlan.c
++++ b/src/network/networkd-brvlan.c
+@@ -9,7 +9,6 @@
+ 
+ #include "alloc-util.h"
+ #include "conf-parser.h"
+-#include "missing_if_bridge.h"
+ #include "netlink-util.h"
+ #include "networkd-brvlan.h"
+ #include "networkd-link.h"
+diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
+index 836776ae84..2c8896530a 100644
+--- a/src/network/networkd-network.c
++++ b/src/network/networkd-network.c
+@@ -1,7 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+-#include <ctype.h>
+-#include <net/if.h>
++#include <linux/netdevice.h>
+ 
+ #include "alloc-util.h"
+ #include "conf-files.h"
+@@ -10,7 +9,6 @@
+ #include "fd-util.h"
+ #include "hostname-util.h"
+ #include "in-addr-util.h"
+-#include "missing_network.h"
+ #include "network-internal.h"
+ #include "networkd-manager.h"
+ #include "networkd-network.h"
+diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
+index e1bd78f809..28699ba236 100644
+--- a/src/network/networkd-routing-policy-rule.h
++++ b/src/network/networkd-routing-policy-rule.h
+@@ -7,7 +7,6 @@
+ 
+ #include "in-addr-util.h"
+ #include "conf-parser.h"
+-#include "missing_fib_rules.h"
+ 
+ typedef struct RoutingPolicyRule RoutingPolicyRule;
+ 
+diff --git a/src/partition/growfs.c b/src/partition/growfs.c
+index 60a310946d..ce86f96e13 100644
+--- a/src/partition/growfs.c
++++ b/src/partition/growfs.c
+@@ -3,6 +3,7 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <getopt.h>
++#include <linux/btrfs.h>
+ #include <linux/magic.h>
+ #include <sys/ioctl.h>
+ #include <sys/mount.h>
+diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
+index 44f70aceaa..50f9309f10 100644
+--- a/src/resolve/resolved-link.c
++++ b/src/resolve/resolved-link.c
+@@ -1,7 +1,9 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include <net/if.h>
++#include <linux/if.h>
+ #include <stdio_ext.h>
++#include <unistd.h>
+ 
+ #include "sd-network.h"
+ 
+@@ -9,7 +11,6 @@
+ #include "env-file.h"
+ #include "fd-util.h"
+ #include "fileio.h"
+-#include "missing.h"
+ #include "mkdir.h"
+ #include "parse-util.h"
+ #include "resolved-link.h"
+diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
+index ce210bfd43..ac2f7ceaf8 100644
+--- a/src/shared/dissect-image.c
++++ b/src/shared/dissect-image.c
+@@ -1,5 +1,7 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
++#include <linux/dm-ioctl.h>
++#include <linux/loop.h>
+ #include <sys/mount.h>
+ #include <sys/prctl.h>
+ #include <sys/wait.h>
+@@ -25,7 +27,6 @@
+ #include "hexdecoct.h"
+ #include "hostname-util.h"
+ #include "id128-util.h"
+-#include "linux-3.13/dm-ioctl.h"
+ #include "missing.h"
+ #include "mount-util.h"
+ #include "mountpoint-util.h"
+diff --git a/src/shared/linux-3.13/dm-ioctl.h b/src/shared/linux-3.13/dm-ioctl.h
+deleted file mode 100644
+index c8a4302093..0000000000
+--- a/src/shared/linux-3.13/dm-ioctl.h
++++ /dev/null
+@@ -1,355 +0,0 @@
+-/*
+- * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
+- * Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved.
+- *
+- * This file is released under the LGPL.
+- */
+-
+-#ifndef _LINUX_DM_IOCTL_V4_H
+-#define _LINUX_DM_IOCTL_V4_H
+-
+-#include <linux/types.h>
+-
+-#define DM_DIR "mapper"		/* Slashes not supported */
+-#define DM_CONTROL_NODE "control"
+-#define DM_MAX_TYPE_NAME 16
+-#define DM_NAME_LEN 128
+-#define DM_UUID_LEN 129
+-
+-/*
+- * A traditional ioctl interface for the device mapper.
+- *
+- * Each device can have two tables associated with it, an
+- * 'active' table which is the one currently used by io passing
+- * through the device, and an 'inactive' one which is a table
+- * that is being prepared as a replacement for the 'active' one.
+- *
+- * DM_VERSION:
+- * Just get the version information for the ioctl interface.
+- *
+- * DM_REMOVE_ALL:
+- * Remove all dm devices, destroy all tables.  Only really used
+- * for debug.
+- *
+- * DM_LIST_DEVICES:
+- * Get a list of all the dm device names.
+- *
+- * DM_DEV_CREATE:
+- * Create a new device, neither the 'active' or 'inactive' table
+- * slots will be filled.  The device will be in suspended state
+- * after creation, however any io to the device will get errored
+- * since it will be out-of-bounds.
+- *
+- * DM_DEV_REMOVE:
+- * Remove a device, destroy any tables.
+- *
+- * DM_DEV_RENAME:
+- * Rename a device or set its uuid if none was previously supplied.
+- *
+- * DM_SUSPEND:
+- * This performs both suspend and resume, depending which flag is
+- * passed in.
+- * Suspend: This command will not return until all pending io to
+- * the device has completed.  Further io will be deferred until
+- * the device is resumed.
+- * Resume: It is no longer an error to issue this command on an
+- * unsuspended device.  If a table is present in the 'inactive'
+- * slot, it will be moved to the active slot, then the old table
+- * from the active slot will be _destroyed_.  Finally the device
+- * is resumed.
+- *
+- * DM_DEV_STATUS:
+- * Retrieves the status for the table in the 'active' slot.
+- *
+- * DM_DEV_WAIT:
+- * Wait for a significant event to occur to the device.  This
+- * could either be caused by an event triggered by one of the
+- * targets of the table in the 'active' slot, or a table change.
+- *
+- * DM_TABLE_LOAD:
+- * Load a table into the 'inactive' slot for the device.  The
+- * device does _not_ need to be suspended prior to this command.
+- *
+- * DM_TABLE_CLEAR:
+- * Destroy any table in the 'inactive' slot (ie. abort).
+- *
+- * DM_TABLE_DEPS:
+- * Return a set of device dependencies for the 'active' table.
+- *
+- * DM_TABLE_STATUS:
+- * Return the targets status for the 'active' table.
+- *
+- * DM_TARGET_MSG:
+- * Pass a message string to the target at a specific offset of a device.
+- *
+- * DM_DEV_SET_GEOMETRY:
+- * Set the geometry of a device by passing in a string in this format:
+- *
+- * "cylinders heads sectors_per_track start_sector"
+- *
+- * Beware that CHS geometry is nearly obsolete and only provided
+- * for compatibility with dm devices that can be booted by a PC
+- * BIOS.  See struct hd_geometry for range limits.  Also note that
+- * the geometry is erased if the device size changes.
+- */
+-
+-/*
+- * All ioctl arguments consist of a single chunk of memory, with
+- * this structure at the start.  If a uuid is specified any
+- * lookup (eg. for a DM_INFO) will be done on that, *not* the
+- * name.
+- */
+-struct dm_ioctl {
+-	/*
+-	 * The version number is made up of three parts:
+-	 * major - no backward or forward compatibility,
+-	 * minor - only backwards compatible,
+-	 * patch - both backwards and forwards compatible.
+-	 *
+-	 * All clients of the ioctl interface should fill in the
+-	 * version number of the interface that they were
+-	 * compiled with.
+-	 *
+-	 * All recognised ioctl commands (ie. those that don't
+-	 * return -ENOTTY) fill out this field, even if the
+-	 * command failed.
+-	 */
+-	__u32 version[3];	/* in/out */
+-	__u32 data_size;	/* total size of data passed in
+-				 * including this struct */
+-
+-	__u32 data_start;	/* offset to start of data
+-				 * relative to start of this struct */
+-
+-	__u32 target_count;	/* in/out */
+-	__s32 open_count;	/* out */
+-	__u32 flags;		/* in/out */
+-
+-	/*
+-	 * event_nr holds either the event number (input and output) or the
+-	 * udev cookie value (input only).
+-	 * The DM_DEV_WAIT ioctl takes an event number as input.
+-	 * The DM_SUSPEND, DM_DEV_REMOVE and DM_DEV_RENAME ioctls
+-	 * use the field as a cookie to return in the DM_COOKIE
+-	 * variable with the uevents they issue.
+-	 * For output, the ioctls return the event number, not the cookie.
+-	 */
+-	__u32 event_nr;      	/* in/out */
+-	__u32 padding;
+-
+-	__u64 dev;		/* in/out */
+-
+-	char name[DM_NAME_LEN];	/* device name */
+-	char uuid[DM_UUID_LEN];	/* unique identifier for
+-				 * the block device */
+-	char data[7];		/* padding or data */
+-};
+-
+-/*
+- * Used to specify tables.  These structures appear after the
+- * dm_ioctl.
+- */
+-struct dm_target_spec {
+-	__u64 sector_start;
+-	__u64 length;
+-	__s32 status;		/* used when reading from kernel only */
+-
+-	/*
+-	 * Location of the next dm_target_spec.
+-	 * - When specifying targets on a DM_TABLE_LOAD command, this value is
+-	 *   the number of bytes from the start of the "current" dm_target_spec
+-	 *   to the start of the "next" dm_target_spec.
+-	 * - When retrieving targets on a DM_TABLE_STATUS command, this value
+-	 *   is the number of bytes from the start of the first dm_target_spec
+-	 *   (that follows the dm_ioctl struct) to the start of the "next"
+-	 *   dm_target_spec.
+-	 */
+-	__u32 next;
+-
+-	char target_type[DM_MAX_TYPE_NAME];
+-
+-	/*
+-	 * Parameter string starts immediately after this object.
+-	 * Be careful to add padding after string to ensure correct
+-	 * alignment of subsequent dm_target_spec.
+-	 */
+-};
+-
+-/*
+- * Used to retrieve the target dependencies.
+- */
+-struct dm_target_deps {
+-	__u32 count;	/* Array size */
+-	__u32 padding;	/* unused */
+-	__u64 dev[0];	/* out */
+-};
+-
+-/*
+- * Used to get a list of all dm devices.
+- */
+-struct dm_name_list {
+-	__u64 dev;
+-	__u32 next;		/* offset to the next record from
+-				   the _start_ of this */
+-	char name[0];
+-};
+-
+-/*
+- * Used to retrieve the target versions
+- */
+-struct dm_target_versions {
+-        __u32 next;
+-        __u32 version[3];
+-
+-        char name[0];
+-};
+-
+-/*
+- * Used to pass message to a target
+- */
+-struct dm_target_msg {
+-	__u64 sector;	/* Device sector */
+-
+-	char message[0];
+-};
+-
+-/*
+- * If you change this make sure you make the corresponding change
+- * to dm-ioctl.c:lookup_ioctl()
+- */
+-enum {
+-	/* Top level cmds */
+-	DM_VERSION_CMD = 0,
+-	DM_REMOVE_ALL_CMD,
+-	DM_LIST_DEVICES_CMD,
+-
+-	/* device level cmds */
+-	DM_DEV_CREATE_CMD,
+-	DM_DEV_REMOVE_CMD,
+-	DM_DEV_RENAME_CMD,
+-	DM_DEV_SUSPEND_CMD,
+-	DM_DEV_STATUS_CMD,
+-	DM_DEV_WAIT_CMD,
+-
+-	/* Table level cmds */
+-	DM_TABLE_LOAD_CMD,
+-	DM_TABLE_CLEAR_CMD,
+-	DM_TABLE_DEPS_CMD,
+-	DM_TABLE_STATUS_CMD,
+-
+-	/* Added later */
+-	DM_LIST_VERSIONS_CMD,
+-	DM_TARGET_MSG_CMD,
+-	DM_DEV_SET_GEOMETRY_CMD
+-};
+-
+-#define DM_IOCTL 0xfd
+-
+-#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
+-#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
+-#define DM_LIST_DEVICES  _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
+-
+-#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
+-#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
+-#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
+-#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
+-#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
+-#define DM_DEV_WAIT      _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+-
+-#define DM_TABLE_LOAD    _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
+-#define DM_TABLE_CLEAR   _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
+-#define DM_TABLE_DEPS    _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
+-#define DM_TABLE_STATUS  _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
+-
+-#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
+-
+-#define DM_TARGET_MSG	 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
+-#define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+-
+-#define DM_VERSION_MAJOR	4
+-#define DM_VERSION_MINOR	27
+-#define DM_VERSION_PATCHLEVEL	0
+-#define DM_VERSION_EXTRA	"-ioctl (2013-10-30)"
+-
+-/* Status bits */
+-#define DM_READONLY_FLAG	(1 << 0) /* In/Out */
+-#define DM_SUSPEND_FLAG		(1 << 1) /* In/Out */
+-#define DM_PERSISTENT_DEV_FLAG	(1 << 3) /* In */
+-
+-/*
+- * Flag passed into ioctl STATUS command to get table information
+- * rather than current status.
+- */
+-#define DM_STATUS_TABLE_FLAG	(1 << 4) /* In */
+-
+-/*
+- * Flags that indicate whether a table is present in either of
+- * the two table slots that a device has.
+- */
+-#define DM_ACTIVE_PRESENT_FLAG   (1 << 5) /* Out */
+-#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
+-
+-/*
+- * Indicates that the buffer passed in wasn't big enough for the
+- * results.
+- */
+-#define DM_BUFFER_FULL_FLAG	(1 << 8) /* Out */
+-
+-/*
+- * This flag is now ignored.
+- */
+-#define DM_SKIP_BDGET_FLAG	(1 << 9) /* In */
+-
+-/*
+- * Set this to avoid attempting to freeze any filesystem when suspending.
+- */
+-#define DM_SKIP_LOCKFS_FLAG	(1 << 10) /* In */
+-
+-/*
+- * Set this to suspend without flushing queued ios.
+- * Also disables flushing uncommitted changes in the thin target before
+- * generating statistics for DM_TABLE_STATUS and DM_DEV_WAIT.
+- */
+-#define DM_NOFLUSH_FLAG		(1 << 11) /* In */
+-
+-/*
+- * If set, any table information returned will relate to the inactive
+- * table instead of the live one.  Always check DM_INACTIVE_PRESENT_FLAG
+- * is set before using the data returned.
+- */
+-#define DM_QUERY_INACTIVE_TABLE_FLAG	(1 << 12) /* In */
+-
+-/*
+- * If set, a uevent was generated for which the caller may need to wait.
+- */
+-#define DM_UEVENT_GENERATED_FLAG	(1 << 13) /* Out */
+-
+-/*
+- * If set, rename changes the uuid not the name.  Only permitted
+- * if no uuid was previously supplied: an existing uuid cannot be changed.
+- */
+-#define DM_UUID_FLAG			(1 << 14) /* In */
+-
+-/*
+- * If set, all buffers are wiped after use. Use when sending
+- * or requesting sensitive data such as an encryption key.
+- */
+-#define DM_SECURE_DATA_FLAG		(1 << 15) /* In */
+-
+-/*
+- * If set, a message generated output data.
+- */
+-#define DM_DATA_OUT_FLAG		(1 << 16) /* Out */
+-
+-/*
+- * If set with DM_DEV_REMOVE or DM_REMOVE_ALL this indicates that if
+- * the device cannot be removed immediately because it is still in use
+- * it should instead be scheduled for removal when it gets closed.
+- *
+- * On return from DM_DEV_REMOVE, DM_DEV_STATUS or other ioctls, this
+- * flag indicates that the device is scheduled to be removed when it
+- * gets closed.
+- */
+-#define DM_DEFERRED_REMOVE		(1 << 17) /* In/Out */
+-
+-#endif				/* _LINUX_DM_IOCTL_H */
+diff --git a/src/shared/linux/README b/src/shared/linux/README
+new file mode 100644
+index 0000000000..34f90486bb
+--- /dev/null
++++ b/src/shared/linux/README
+@@ -0,0 +1,8 @@
++The files in this directory are copied from kernel-5.0, and the following modifications are applied:
++- auto_dev-ioctl.h: set AUTOFS_DEV_IOCTL_VERSION_MINOR to 0
++- auto_dev-ioctl.h: define AUTOFS_IOCTL if not defined
++- bpf_insn.h: This is imported from samples/bpf/bpf_insn.h
++- bpf_insn.h: BPF_JMP_A() macro is also imported from include/linux/filter.h
++- dm-ioctl.h: set DM_VERSION_MINOR to 27
++- ethtool.h: add a type cast to SPEED_UNKNOWN
++- ethtool.h: define __KERNEL_DIV_ROUND_UP if not defined
+diff --git a/src/shared/linux/auto_dev-ioctl.h b/src/shared/linux/auto_dev-ioctl.h
+index d9838eba49..261546c667 100644
+--- a/src/shared/linux/auto_dev-ioctl.h
++++ b/src/shared/linux/auto_dev-ioctl.h
+@@ -1,31 +1,24 @@
+-/* SPDX-License-Identifier: GPL-2.0+ */
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+ /*
+- * Copyright © 2008 Red Hat, Inc. All rights reserved.
+- * Copyright © 2008 Ian Kent <raven@themaw.net>
++ * Copyright 2008 Red Hat, Inc. All rights reserved.
++ * Copyright 2008 Ian Kent <raven@themaw.net>
+  *
+  * This file is part of the Linux kernel and is made available under
+  * the terms of the GNU General Public License, version 2, or at your
+  * option, any later version, incorporated herein by reference.
+  */
+ 
+-#ifndef _LINUX_AUTO_DEV_IOCTL_H
+-#define _LINUX_AUTO_DEV_IOCTL_H
++#ifndef _UAPI_LINUX_AUTO_DEV_IOCTL_H
++#define _UAPI_LINUX_AUTO_DEV_IOCTL_H
+ 
+ #include <linux/auto_fs.h>
+-
+-#ifdef __KERNEL__
+ #include <linux/string.h>
+-#else
+-#include <string.h>
+-#endif /* __KERNEL__ */
+ 
+ #define AUTOFS_DEVICE_NAME		"autofs"
+ 
+ #define AUTOFS_DEV_IOCTL_VERSION_MAJOR	1
+ #define AUTOFS_DEV_IOCTL_VERSION_MINOR	0
+ 
+-#define AUTOFS_DEVID_LEN		16
+-
+ #define AUTOFS_DEV_IOCTL_SIZE		sizeof(struct autofs_dev_ioctl)
+ 
+ /*
+@@ -119,19 +112,15 @@ struct autofs_dev_ioctl {
+ 	char path[0];
+ };
+ 
+-static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) {
+-	memset(in, 0, sizeof(struct autofs_dev_ioctl));
++static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
++{
++	memset(in, 0, AUTOFS_DEV_IOCTL_SIZE);
+ 	in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+ 	in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+-	in->size = sizeof(struct autofs_dev_ioctl);
++	in->size = AUTOFS_DEV_IOCTL_SIZE;
+ 	in->ioctlfd = -1;
+-	return;
+ }
+ 
+-/*
+- * If you change this make sure you make the corresponding change
+- * to autofs-dev-ioctl.c:lookup_ioctl()
+- */
+ enum {
+ 	/* Get various version info */
+ 	AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
+@@ -168,7 +157,9 @@ enum {
+ 	AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
+ };
+ 
++#ifndef AUTOFS_IOCTL
+ #define AUTOFS_IOCTL 0x93
++#endif
+ 
+ #define AUTOFS_DEV_IOCTL_VERSION \
+ 	_IOWR(AUTOFS_IOCTL, \
+@@ -226,4 +217,4 @@ enum {
+ 	_IOWR(AUTOFS_IOCTL, \
+ 	      AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
+ 
+-#endif	/* _LINUX_AUTO_DEV_IOCTL_H */
++#endif	/* _UAPI_LINUX_AUTO_DEV_IOCTL_H */
+diff --git a/src/shared/linux/bpf.h b/src/shared/linux/bpf.h
+index 1df9e7e3d0..91c43884f2 100644
+--- a/src/shared/linux/bpf.h
++++ b/src/shared/linux/bpf.h
+@@ -44,106 +44,149 @@
+ 
+ /* Register numbers */
+ enum {
+-        BPF_REG_0 = 0,
+-        BPF_REG_1,
+-        BPF_REG_2,
+-        BPF_REG_3,
+-        BPF_REG_4,
+-        BPF_REG_5,
+-        BPF_REG_6,
+-        BPF_REG_7,
+-        BPF_REG_8,
+-        BPF_REG_9,
+-        BPF_REG_10,
+-        __MAX_BPF_REG,
++	BPF_REG_0 = 0,
++	BPF_REG_1,
++	BPF_REG_2,
++	BPF_REG_3,
++	BPF_REG_4,
++	BPF_REG_5,
++	BPF_REG_6,
++	BPF_REG_7,
++	BPF_REG_8,
++	BPF_REG_9,
++	BPF_REG_10,
++	__MAX_BPF_REG,
+ };
+ 
+ /* BPF has 10 general purpose 64-bit registers and stack frame. */
+ #define MAX_BPF_REG	__MAX_BPF_REG
+ 
+ struct bpf_insn {
+-        __u8	code;		/* opcode */
+-        __u8	dst_reg:4;	/* dest register */
+-        __u8	src_reg:4;	/* source register */
+-        __s16	off;		/* signed offset */
+-        __s32	imm;		/* signed immediate constant */
++	__u8	code;		/* opcode */
++	__u8	dst_reg:4;	/* dest register */
++	__u8	src_reg:4;	/* source register */
++	__s16	off;		/* signed offset */
++	__s32	imm;		/* signed immediate constant */
+ };
+ 
+ /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
+ struct bpf_lpm_trie_key {
+-        __u32	prefixlen;	/* up to 32 for AF_INET, 128 for AF_INET6 */
+-        __u8	data[0];	/* Arbitrary size */
++	__u32	prefixlen;	/* up to 32 for AF_INET, 128 for AF_INET6 */
++	__u8	data[0];	/* Arbitrary size */
++};
++
++struct bpf_cgroup_storage_key {
++	__u64	cgroup_inode_id;	/* cgroup inode id */
++	__u32	attach_type;		/* program attach type */
+ };
+ 
+ /* BPF syscall commands, see bpf(2) man-page for details. */
+ enum bpf_cmd {
+-        BPF_MAP_CREATE,
+-        BPF_MAP_LOOKUP_ELEM,
+-        BPF_MAP_UPDATE_ELEM,
+-        BPF_MAP_DELETE_ELEM,
+-        BPF_MAP_GET_NEXT_KEY,
+-        BPF_PROG_LOAD,
+-        BPF_OBJ_PIN,
+-        BPF_OBJ_GET,
+-        BPF_PROG_ATTACH,
+-        BPF_PROG_DETACH,
+-        BPF_PROG_TEST_RUN,
+-        BPF_PROG_GET_NEXT_ID,
+-        BPF_MAP_GET_NEXT_ID,
+-        BPF_PROG_GET_FD_BY_ID,
+-        BPF_MAP_GET_FD_BY_ID,
+-        BPF_OBJ_GET_INFO_BY_FD,
+-        BPF_PROG_QUERY,
++	BPF_MAP_CREATE,
++	BPF_MAP_LOOKUP_ELEM,
++	BPF_MAP_UPDATE_ELEM,
++	BPF_MAP_DELETE_ELEM,
++	BPF_MAP_GET_NEXT_KEY,
++	BPF_PROG_LOAD,
++	BPF_OBJ_PIN,
++	BPF_OBJ_GET,
++	BPF_PROG_ATTACH,
++	BPF_PROG_DETACH,
++	BPF_PROG_TEST_RUN,
++	BPF_PROG_GET_NEXT_ID,
++	BPF_MAP_GET_NEXT_ID,
++	BPF_PROG_GET_FD_BY_ID,
++	BPF_MAP_GET_FD_BY_ID,
++	BPF_OBJ_GET_INFO_BY_FD,
++	BPF_PROG_QUERY,
++	BPF_RAW_TRACEPOINT_OPEN,
++	BPF_BTF_LOAD,
++	BPF_BTF_GET_FD_BY_ID,
++	BPF_TASK_FD_QUERY,
++	BPF_MAP_LOOKUP_AND_DELETE_ELEM,
+ };
+ 
+ enum bpf_map_type {
+-        BPF_MAP_TYPE_UNSPEC,
+-        BPF_MAP_TYPE_HASH,
+-        BPF_MAP_TYPE_ARRAY,
+-        BPF_MAP_TYPE_PROG_ARRAY,
+-        BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+-        BPF_MAP_TYPE_PERCPU_HASH,
+-        BPF_MAP_TYPE_PERCPU_ARRAY,
+-        BPF_MAP_TYPE_STACK_TRACE,
+-        BPF_MAP_TYPE_CGROUP_ARRAY,
+-        BPF_MAP_TYPE_LRU_HASH,
+-        BPF_MAP_TYPE_LRU_PERCPU_HASH,
+-        BPF_MAP_TYPE_LPM_TRIE,
+-        BPF_MAP_TYPE_ARRAY_OF_MAPS,
+-        BPF_MAP_TYPE_HASH_OF_MAPS,
+-        BPF_MAP_TYPE_DEVMAP,
+-        BPF_MAP_TYPE_SOCKMAP,
+-        BPF_MAP_TYPE_CPUMAP,
++	BPF_MAP_TYPE_UNSPEC,
++	BPF_MAP_TYPE_HASH,
++	BPF_MAP_TYPE_ARRAY,
++	BPF_MAP_TYPE_PROG_ARRAY,
++	BPF_MAP_TYPE_PERF_EVENT_ARRAY,
++	BPF_MAP_TYPE_PERCPU_HASH,
++	BPF_MAP_TYPE_PERCPU_ARRAY,
++	BPF_MAP_TYPE_STACK_TRACE,
++	BPF_MAP_TYPE_CGROUP_ARRAY,
++	BPF_MAP_TYPE_LRU_HASH,
++	BPF_MAP_TYPE_LRU_PERCPU_HASH,
++	BPF_MAP_TYPE_LPM_TRIE,
++	BPF_MAP_TYPE_ARRAY_OF_MAPS,
++	BPF_MAP_TYPE_HASH_OF_MAPS,
++	BPF_MAP_TYPE_DEVMAP,
++	BPF_MAP_TYPE_SOCKMAP,
++	BPF_MAP_TYPE_CPUMAP,
++	BPF_MAP_TYPE_XSKMAP,
++	BPF_MAP_TYPE_SOCKHASH,
++	BPF_MAP_TYPE_CGROUP_STORAGE,
++	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
++	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
++	BPF_MAP_TYPE_QUEUE,
++	BPF_MAP_TYPE_STACK,
+ };
+ 
++/* Note that tracing related programs such as
++ * BPF_PROG_TYPE_{KPROBE,TRACEPOINT,PERF_EVENT,RAW_TRACEPOINT}
++ * are not subject to a stable API since kernel internal data
++ * structures can change from release to release and may
++ * therefore break existing tracing BPF programs. Tracing BPF
++ * programs correspond to /a/ specific kernel which is to be
++ * analyzed, and not /a/ specific kernel /and/ all future ones.
++ */
+ enum bpf_prog_type {
+-        BPF_PROG_TYPE_UNSPEC,
+-        BPF_PROG_TYPE_SOCKET_FILTER,
+-        BPF_PROG_TYPE_KPROBE,
+-        BPF_PROG_TYPE_SCHED_CLS,
+-        BPF_PROG_TYPE_SCHED_ACT,
+-        BPF_PROG_TYPE_TRACEPOINT,
+-        BPF_PROG_TYPE_XDP,
+-        BPF_PROG_TYPE_PERF_EVENT,
+-        BPF_PROG_TYPE_CGROUP_SKB,
+-        BPF_PROG_TYPE_CGROUP_SOCK,
+-        BPF_PROG_TYPE_LWT_IN,
+-        BPF_PROG_TYPE_LWT_OUT,
+-        BPF_PROG_TYPE_LWT_XMIT,
+-        BPF_PROG_TYPE_SOCK_OPS,
+-        BPF_PROG_TYPE_SK_SKB,
+-        BPF_PROG_TYPE_CGROUP_DEVICE,
++	BPF_PROG_TYPE_UNSPEC,
++	BPF_PROG_TYPE_SOCKET_FILTER,
++	BPF_PROG_TYPE_KPROBE,
++	BPF_PROG_TYPE_SCHED_CLS,
++	BPF_PROG_TYPE_SCHED_ACT,
++	BPF_PROG_TYPE_TRACEPOINT,
++	BPF_PROG_TYPE_XDP,
++	BPF_PROG_TYPE_PERF_EVENT,
++	BPF_PROG_TYPE_CGROUP_SKB,
++	BPF_PROG_TYPE_CGROUP_SOCK,
++	BPF_PROG_TYPE_LWT_IN,
++	BPF_PROG_TYPE_LWT_OUT,
++	BPF_PROG_TYPE_LWT_XMIT,
++	BPF_PROG_TYPE_SOCK_OPS,
++	BPF_PROG_TYPE_SK_SKB,
++	BPF_PROG_TYPE_CGROUP_DEVICE,
++	BPF_PROG_TYPE_SK_MSG,
++	BPF_PROG_TYPE_RAW_TRACEPOINT,
++	BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
++	BPF_PROG_TYPE_LWT_SEG6LOCAL,
++	BPF_PROG_TYPE_LIRC_MODE2,
++	BPF_PROG_TYPE_SK_REUSEPORT,
++	BPF_PROG_TYPE_FLOW_DISSECTOR,
+ };
+ 
+ enum bpf_attach_type {
+-        BPF_CGROUP_INET_INGRESS,
+-        BPF_CGROUP_INET_EGRESS,
+-        BPF_CGROUP_INET_SOCK_CREATE,
+-        BPF_CGROUP_SOCK_OPS,
+-        BPF_SK_SKB_STREAM_PARSER,
+-        BPF_SK_SKB_STREAM_VERDICT,
+-        BPF_CGROUP_DEVICE,
+-        __MAX_BPF_ATTACH_TYPE
++	BPF_CGROUP_INET_INGRESS,
++	BPF_CGROUP_INET_EGRESS,
++	BPF_CGROUP_INET_SOCK_CREATE,
++	BPF_CGROUP_SOCK_OPS,
++	BPF_SK_SKB_STREAM_PARSER,
++	BPF_SK_SKB_STREAM_VERDICT,
++	BPF_CGROUP_DEVICE,
++	BPF_SK_MSG_VERDICT,
++	BPF_CGROUP_INET4_BIND,
++	BPF_CGROUP_INET6_BIND,
++	BPF_CGROUP_INET4_CONNECT,
++	BPF_CGROUP_INET6_CONNECT,
++	BPF_CGROUP_INET4_POST_BIND,
++	BPF_CGROUP_INET6_POST_BIND,
++	BPF_CGROUP_UDP4_SENDMSG,
++	BPF_CGROUP_UDP6_SENDMSG,
++	BPF_LIRC_MODE2,
++	BPF_FLOW_DISSECTOR,
++	__MAX_BPF_ATTACH_TYPE
+ };
+ 
+ #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
+@@ -197,6 +240,20 @@ enum bpf_attach_type {
+  */
+ #define BPF_F_STRICT_ALIGNMENT	(1U << 0)
+ 
++/* If BPF_F_ANY_ALIGNMENT is used in BPF_PROF_LOAD command, the
++ * verifier will allow any alignment whatsoever.  On platforms
++ * with strict alignment requirements for loads ands stores (such
++ * as sparc and mips) the verifier validates that all loads and
++ * stores provably follow this requirement.  This flag turns that
++ * checking and enforcement off.
++ *
++ * It is mostly used for testing when we want to validate the
++ * context and memory access aspects of the verifier, but because
++ * of an unaligned access the alignment check would trigger before
++ * the one we are interested in.
++ */
++#define BPF_F_ANY_ALIGNMENT	(1U << 1)
++
+ /* when bpf_ldimm64->src_reg == BPF_PSEUDO_MAP_FD, bpf_ldimm64->imm == fd */
+ #define BPF_PSEUDO_MAP_FD	1
+ 
+@@ -222,550 +279,2157 @@ enum bpf_attach_type {
+ /* Specify numa node during map creation */
+ #define BPF_F_NUMA_NODE		(1U << 2)
+ 
+-/* flags for BPF_PROG_QUERY */
+-#define BPF_F_QUERY_EFFECTIVE	(1U << 0)
+-
+ #define BPF_OBJ_NAME_LEN 16U
+ 
+ /* Flags for accessing BPF object */
+ #define BPF_F_RDONLY		(1U << 3)
+ #define BPF_F_WRONLY		(1U << 4)
+ 
++/* Flag for stack_map, store build_id+offset instead of pointer */
++#define BPF_F_STACK_BUILD_ID	(1U << 5)
++
++/* Zero-initialize hash function seed. This should only be used for testing. */
++#define BPF_F_ZERO_SEED		(1U << 6)
++
++/* flags for BPF_PROG_QUERY */
++#define BPF_F_QUERY_EFFECTIVE	(1U << 0)
++
++enum bpf_stack_build_id_status {
++	/* user space need an empty entry to identify end of a trace */
++	BPF_STACK_BUILD_ID_EMPTY = 0,
++	/* with valid build_id and offset */
++	BPF_STACK_BUILD_ID_VALID = 1,
++	/* couldn't get build_id, fallback to ip */
++	BPF_STACK_BUILD_ID_IP = 2,
++};
++
++#define BPF_BUILD_ID_SIZE 20
++struct bpf_stack_build_id {
++	__s32		status;
++	unsigned char	build_id[BPF_BUILD_ID_SIZE];
++	union {
++		__u64	offset;
++		__u64	ip;
++	};
++};
++
+ union bpf_attr {
+-        struct { /* anonymous struct used by BPF_MAP_CREATE command */
+-                __u32	map_type;	/* one of enum bpf_map_type */
+-                __u32	key_size;	/* size of key in bytes */
+-                __u32	value_size;	/* size of value in bytes */
+-                __u32	max_entries;	/* max number of entries in a map */
+-                __u32	map_flags;	/* BPF_MAP_CREATE related
+-                                         * flags defined above.
+-                                         */
+-                __u32	inner_map_fd;	/* fd pointing to the inner map */
+-                __u32	numa_node;	/* numa node (effective only if
+-                                         * BPF_F_NUMA_NODE is set).
+-                                         */
+-                char	map_name[BPF_OBJ_NAME_LEN];
+-                __u32	map_ifindex;	/* ifindex of netdev to create on */
+-        };
+-
+-        struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
+-                __u32		map_fd;
+-                __aligned_u64	key;
+-                union {
+-                        __aligned_u64 value;
+-                        __aligned_u64 next_key;
+-                };
+-                __u64		flags;
+-        };
+-
+-        struct { /* anonymous struct used by BPF_PROG_LOAD command */
+-                __u32		prog_type;	/* one of enum bpf_prog_type */
+-                __u32		insn_cnt;
+-                __aligned_u64	insns;
+-                __aligned_u64	license;
+-                __u32		log_level;	/* verbosity level of verifier */
+-                __u32		log_size;	/* size of user buffer */
+-                __aligned_u64	log_buf;	/* user supplied buffer */
+-                __u32		kern_version;	/* checked when prog_type=kprobe */
+-                __u32		prog_flags;
+-                char		prog_name[BPF_OBJ_NAME_LEN];
+-                __u32		prog_ifindex;	/* ifindex of netdev to prep for */
+-        };
+-
+-        struct { /* anonymous struct used by BPF_OBJ_* commands */
+-                __aligned_u64	pathname;
+-                __u32		bpf_fd;
+-                __u32		file_flags;
+-        };
+-
+-        struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */
+-                __u32		target_fd;	/* container object to attach to */
+-                __u32		attach_bpf_fd;	/* eBPF program to attach */
+-                __u32		attach_type;
+-                __u32		attach_flags;
+-        };
+-
+-        struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */
+-                __u32		prog_fd;
+-                __u32		retval;
+-                __u32		data_size_in;
+-                __u32		data_size_out;
+-                __aligned_u64	data_in;
+-                __aligned_u64	data_out;
+-                __u32		repeat;
+-                __u32		duration;
+-        } test;
+-
+-        struct { /* anonymous struct used by BPF_*_GET_*_ID */
+-                union {
+-                        __u32		start_id;
+-                        __u32		prog_id;
+-                        __u32		map_id;
+-                };
+-                __u32		next_id;
+-                __u32		open_flags;
+-        };
+-
+-        struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */
+-                __u32		bpf_fd;
+-                __u32		info_len;
+-                __aligned_u64	info;
+-        } info;
+-
+-        struct { /* anonymous struct used by BPF_PROG_QUERY command */
+-                __u32		target_fd;	/* container object to query */
+-                __u32		attach_type;
+-                __u32		query_flags;
+-                __u32		attach_flags;
+-                __aligned_u64	prog_ids;
+-                __u32		prog_cnt;
+-        } query;
++	struct { /* anonymous struct used by BPF_MAP_CREATE command */
++		__u32	map_type;	/* one of enum bpf_map_type */
++		__u32	key_size;	/* size of key in bytes */
++		__u32	value_size;	/* size of value in bytes */
++		__u32	max_entries;	/* max number of entries in a map */
++		__u32	map_flags;	/* BPF_MAP_CREATE related
++					 * flags defined above.
++					 */
++		__u32	inner_map_fd;	/* fd pointing to the inner map */
++		__u32	numa_node;	/* numa node (effective only if
++					 * BPF_F_NUMA_NODE is set).
++					 */
++		char	map_name[BPF_OBJ_NAME_LEN];
++		__u32	map_ifindex;	/* ifindex of netdev to create on */
++		__u32	btf_fd;		/* fd pointing to a BTF type data */
++		__u32	btf_key_type_id;	/* BTF type_id of the key */
++		__u32	btf_value_type_id;	/* BTF type_id of the value */
++	};
++
++	struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
++		__u32		map_fd;
++		__aligned_u64	key;
++		union {
++			__aligned_u64 value;
++			__aligned_u64 next_key;
++		};
++		__u64		flags;
++	};
++
++	struct { /* anonymous struct used by BPF_PROG_LOAD command */
++		__u32		prog_type;	/* one of enum bpf_prog_type */
++		__u32		insn_cnt;
++		__aligned_u64	insns;
++		__aligned_u64	license;
++		__u32		log_level;	/* verbosity level of verifier */
++		__u32		log_size;	/* size of user buffer */
++		__aligned_u64	log_buf;	/* user supplied buffer */
++		__u32		kern_version;	/* not used */
++		__u32		prog_flags;
++		char		prog_name[BPF_OBJ_NAME_LEN];
++		__u32		prog_ifindex;	/* ifindex of netdev to prep for */
++		/* For some prog types expected attach type must be known at
++		 * load time to verify attach type specific parts of prog
++		 * (context accesses, allowed helpers, etc).
++		 */
++		__u32		expected_attach_type;
++		__u32		prog_btf_fd;	/* fd pointing to BTF type data */
++		__u32		func_info_rec_size;	/* userspace bpf_func_info size */
++		__aligned_u64	func_info;	/* func info */
++		__u32		func_info_cnt;	/* number of bpf_func_info records */
++		__u32		line_info_rec_size;	/* userspace bpf_line_info size */
++		__aligned_u64	line_info;	/* line info */
++		__u32		line_info_cnt;	/* number of bpf_line_info records */
++	};
++
++	struct { /* anonymous struct used by BPF_OBJ_* commands */
++		__aligned_u64	pathname;
++		__u32		bpf_fd;
++		__u32		file_flags;
++	};
++
++	struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */
++		__u32		target_fd;	/* container object to attach to */
++		__u32		attach_bpf_fd;	/* eBPF program to attach */
++		__u32		attach_type;
++		__u32		attach_flags;
++	};
++
++	struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */
++		__u32		prog_fd;
++		__u32		retval;
++		__u32		data_size_in;	/* input: len of data_in */
++		__u32		data_size_out;	/* input/output: len of data_out
++						 *   returns ENOSPC if data_out
++						 *   is too small.
++						 */
++		__aligned_u64	data_in;
++		__aligned_u64	data_out;
++		__u32		repeat;
++		__u32		duration;
++	} test;
++
++	struct { /* anonymous struct used by BPF_*_GET_*_ID */
++		union {
++			__u32		start_id;
++			__u32		prog_id;
++			__u32		map_id;
++			__u32		btf_id;
++		};
++		__u32		next_id;
++		__u32		open_flags;
++	};
++
++	struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */
++		__u32		bpf_fd;
++		__u32		info_len;
++		__aligned_u64	info;
++	} info;
++
++	struct { /* anonymous struct used by BPF_PROG_QUERY command */
++		__u32		target_fd;	/* container object to query */
++		__u32		attach_type;
++		__u32		query_flags;
++		__u32		attach_flags;
++		__aligned_u64	prog_ids;
++		__u32		prog_cnt;
++	} query;
++
++	struct {
++		__u64 name;
++		__u32 prog_fd;
++	} raw_tracepoint;
++
++	struct { /* anonymous struct for BPF_BTF_LOAD */
++		__aligned_u64	btf;
++		__aligned_u64	btf_log_buf;
++		__u32		btf_size;
++		__u32		btf_log_size;
++		__u32		btf_log_level;
++	};
++
++	struct {
++		__u32		pid;		/* input: pid */
++		__u32		fd;		/* input: fd */
++		__u32		flags;		/* input: flags */
++		__u32		buf_len;	/* input/output: buf len */
++		__aligned_u64	buf;		/* input/output:
++						 *   tp_name for tracepoint
++						 *   symbol for kprobe
++						 *   filename for uprobe
++						 */
++		__u32		prog_id;	/* output: prod_id */
++		__u32		fd_type;	/* output: BPF_FD_TYPE_* */
++		__u64		probe_offset;	/* output: probe_offset */
++		__u64		probe_addr;	/* output: probe_addr */
++	} task_fd_query;
+ } __attribute__((aligned(8)));
+ 
+-/* BPF helper function descriptions:
+- *
+- * void *bpf_map_lookup_elem(&map, &key)
+- *     Return: Map value or NULL
+- *
+- * int bpf_map_update_elem(&map, &key, &value, flags)
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_map_delete_elem(&map, &key)
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_probe_read(void *dst, int size, void *src)
+- *     Return: 0 on success or negative error
++/* The description below is an attempt at providing documentation to eBPF
++ * developers about the multiple available eBPF helper functions. It can be
++ * parsed and used to produce a manual page. The workflow is the following,
++ * and requires the rst2man utility:
++ *
++ *     $ ./scripts/bpf_helpers_doc.py \
++ *             --filename include/uapi/linux/bpf.h > /tmp/bpf-helpers.rst
++ *     $ rst2man /tmp/bpf-helpers.rst > /tmp/bpf-helpers.7
++ *     $ man /tmp/bpf-helpers.7
++ *
++ * Note that in order to produce this external documentation, some RST
++ * formatting is used in the descriptions to get "bold" and "italics" in
++ * manual pages. Also note that the few trailing white spaces are
++ * intentional, removing them would break paragraphs for rst2man.
++ *
++ * Start of BPF helper function descriptions:
++ *
++ * void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
++ * 	Description
++ * 		Perform a lookup in *map* for an entry associated to *key*.
++ * 	Return
++ * 		Map value associated to *key*, or **NULL** if no entry was
++ * 		found.
++ *
++ * int bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
++ * 	Description
++ * 		Add or update the value of the entry associated to *key* in
++ * 		*map* with *value*. *flags* is one of:
++ *
++ * 		**BPF_NOEXIST**
++ * 			The entry for *key* must not exist in the map.
++ * 		**BPF_EXIST**
++ * 			The entry for *key* must already exist in the map.
++ * 		**BPF_ANY**
++ * 			No condition on the existence of the entry for *key*.
++ *
++ * 		Flag value **BPF_NOEXIST** cannot be used for maps of types
++ * 		**BPF_MAP_TYPE_ARRAY** or **BPF_MAP_TYPE_PERCPU_ARRAY**  (all
++ * 		elements always exist), the helper would return an error.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_map_delete_elem(struct bpf_map *map, const void *key)
++ * 	Description
++ * 		Delete entry with *key* from *map*.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
++ * 	Description
++ * 		Push an element *value* in *map*. *flags* is one of:
++ *
++ * 		**BPF_EXIST**
++ * 		If the queue/stack is full, the oldest element is removed to
++ * 		make room for this.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_probe_read(void *dst, u32 size, const void *src)
++ * 	Description
++ * 		For tracing programs, safely attempt to read *size* bytes from
++ * 		address *src* and store the data in *dst*.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
+  *
+  * u64 bpf_ktime_get_ns(void)
+- *     Return: current ktime
+- *
+- * int bpf_trace_printk(const char *fmt, int fmt_size, ...)
+- *     Return: length of buffer written or negative error
+- *
+- * u32 bpf_prandom_u32(void)
+- *     Return: random value
+- *
+- * u32 bpf_raw_smp_processor_id(void)
+- *     Return: SMP processor ID
+- *
+- * int bpf_skb_store_bytes(skb, offset, from, len, flags)
+- *     store bytes into packet
+- *     @skb: pointer to skb
+- *     @offset: offset within packet from skb->mac_header
+- *     @from: pointer where to copy bytes from
+- *     @len: number of bytes to store into packet
+- *     @flags: bit 0 - if true, recompute skb->csum
+- *             other bits - reserved
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_l3_csum_replace(skb, offset, from, to, flags)
+- *     recompute IP checksum
+- *     @skb: pointer to skb
+- *     @offset: offset within packet where IP checksum is located
+- *     @from: old value of header field
+- *     @to: new value of header field
+- *     @flags: bits 0-3 - size of header field
+- *             other bits - reserved
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_l4_csum_replace(skb, offset, from, to, flags)
+- *     recompute TCP/UDP checksum
+- *     @skb: pointer to skb
+- *     @offset: offset within packet where TCP/UDP checksum is located
+- *     @from: old value of header field
+- *     @to: new value of header field
+- *     @flags: bits 0-3 - size of header field
+- *             bit 4 - is pseudo header
+- *             other bits - reserved
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_tail_call(ctx, prog_array_map, index)
+- *     jump into another BPF program
+- *     @ctx: context pointer passed to next program
+- *     @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY
+- *     @index: 32-bit index inside array that selects specific program to run
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_clone_redirect(skb, ifindex, flags)
+- *     redirect to another netdev
+- *     @skb: pointer to skb
+- *     @ifindex: ifindex of the net device
+- *     @flags: bit 0 - if set, redirect to ingress instead of egress
+- *             other bits - reserved
+- *     Return: 0 on success or negative error
++ * 	Description
++ * 		Return the time elapsed since system boot, in nanoseconds.
++ * 	Return
++ * 		Current *ktime*.
++ *
++ * int bpf_trace_printk(const char *fmt, u32 fmt_size, ...)
++ * 	Description
++ * 		This helper is a "printk()-like" facility for debugging. It
++ * 		prints a message defined by format *fmt* (of size *fmt_size*)
++ * 		to file *\/sys/kernel/debug/tracing/trace* from DebugFS, if
++ * 		available. It can take up to three additional **u64**
++ * 		arguments (as an eBPF helpers, the total number of arguments is
++ * 		limited to five).
++ *
++ * 		Each time the helper is called, it appends a line to the trace.
++ * 		The format of the trace is customizable, and the exact output
++ * 		one will get depends on the options set in
++ * 		*\/sys/kernel/debug/tracing/trace_options* (see also the
++ * 		*README* file under the same directory). However, it usually
++ * 		defaults to something like:
++ *
++ * 		::
++ *
++ * 			telnet-470   [001] .N.. 419421.045894: 0x00000001: <formatted msg>
++ *
++ * 		In the above:
++ *
++ * 			* ``telnet`` is the name of the current task.
++ * 			* ``470`` is the PID of the current task.
++ * 			* ``001`` is the CPU number on which the task is
++ * 			  running.
++ * 			* In ``.N..``, each character refers to a set of
++ * 			  options (whether irqs are enabled, scheduling
++ * 			  options, whether hard/softirqs are running, level of
++ * 			  preempt_disabled respectively). **N** means that
++ * 			  **TIF_NEED_RESCHED** and **PREEMPT_NEED_RESCHED**
++ * 			  are set.
++ * 			* ``419421.045894`` is a timestamp.
++ * 			* ``0x00000001`` is a fake value used by BPF for the
++ * 			  instruction pointer register.
++ * 			* ``<formatted msg>`` is the message formatted with
++ * 			  *fmt*.
++ *
++ * 		The conversion specifiers supported by *fmt* are similar, but
++ * 		more limited than for printk(). They are **%d**, **%i**,
++ * 		**%u**, **%x**, **%ld**, **%li**, **%lu**, **%lx**, **%lld**,
++ * 		**%lli**, **%llu**, **%llx**, **%p**, **%s**. No modifier (size
++ * 		of field, padding with zeroes, etc.) is available, and the
++ * 		helper will return **-EINVAL** (but print nothing) if it
++ * 		encounters an unknown specifier.
++ *
++ * 		Also, note that **bpf_trace_printk**\ () is slow, and should
++ * 		only be used for debugging purposes. For this reason, a notice
++ * 		bloc (spanning several lines) is printed to kernel logs and
++ * 		states that the helper should not be used "for production use"
++ * 		the first time this helper is used (or more precisely, when
++ * 		**trace_printk**\ () buffers are allocated). For passing values
++ * 		to user space, perf events should be preferred.
++ * 	Return
++ * 		The number of bytes written to the buffer, or a negative error
++ * 		in case of failure.
++ *
++ * u32 bpf_get_prandom_u32(void)
++ * 	Description
++ * 		Get a pseudo-random number.
++ *
++ * 		From a security point of view, this helper uses its own
++ * 		pseudo-random internal state, and cannot be used to infer the
++ * 		seed of other random functions in the kernel. However, it is
++ * 		essential to note that the generator used by the helper is not
++ * 		cryptographically secure.
++ * 	Return
++ * 		A random 32-bit unsigned value.
++ *
++ * u32 bpf_get_smp_processor_id(void)
++ * 	Description
++ * 		Get the SMP (symmetric multiprocessing) processor id. Note that
++ * 		all programs run with preemption disabled, which means that the
++ * 		SMP processor id is stable during all the execution of the
++ * 		program.
++ * 	Return
++ * 		The SMP id of the processor running the program.
++ *
++ * int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags)
++ * 	Description
++ * 		Store *len* bytes from address *from* into the packet
++ * 		associated to *skb*, at *offset*. *flags* are a combination of
++ * 		**BPF_F_RECOMPUTE_CSUM** (automatically recompute the
++ * 		checksum for the packet after storing the bytes) and
++ * 		**BPF_F_INVALIDATE_HASH** (set *skb*\ **->hash**, *skb*\
++ * 		**->swhash** and *skb*\ **->l4hash** to 0).
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_l3_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 size)
++ * 	Description
++ * 		Recompute the layer 3 (e.g. IP) checksum for the packet
++ * 		associated to *skb*. Computation is incremental, so the helper
++ * 		must know the former value of the header field that was
++ * 		modified (*from*), the new value of this field (*to*), and the
++ * 		number of bytes (2 or 4) for this field, stored in *size*.
++ * 		Alternatively, it is possible to store the difference between
++ * 		the previous and the new values of the header field in *to*, by
++ * 		setting *from* and *size* to 0. For both methods, *offset*
++ * 		indicates the location of the IP checksum within the packet.
++ *
++ * 		This helper works in combination with **bpf_csum_diff**\ (),
++ * 		which does not update the checksum in-place, but offers more
++ * 		flexibility and can handle sizes larger than 2 or 4 for the
++ * 		checksum to update.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_l4_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 flags)
++ * 	Description
++ * 		Recompute the layer 4 (e.g. TCP, UDP or ICMP) checksum for the
++ * 		packet associated to *skb*. Computation is incremental, so the
++ * 		helper must know the former value of the header field that was
++ * 		modified (*from*), the new value of this field (*to*), and the
++ * 		number of bytes (2 or 4) for this field, stored on the lowest
++ * 		four bits of *flags*. Alternatively, it is possible to store
++ * 		the difference between the previous and the new values of the
++ * 		header field in *to*, by setting *from* and the four lowest
++ * 		bits of *flags* to 0. For both methods, *offset* indicates the
++ * 		location of the IP checksum within the packet. In addition to
++ * 		the size of the field, *flags* can be added (bitwise OR) actual
++ * 		flags. With **BPF_F_MARK_MANGLED_0**, a null checksum is left
++ * 		untouched (unless **BPF_F_MARK_ENFORCE** is added as well), and
++ * 		for updates resulting in a null checksum the value is set to
++ * 		**CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
++ * 		the checksum is to be computed against a pseudo-header.
++ *
++ * 		This helper works in combination with **bpf_csum_diff**\ (),
++ * 		which does not update the checksum in-place, but offers more
++ * 		flexibility and can handle sizes larger than 2 or 4 for the
++ * 		checksum to update.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_tail_call(void *ctx, struct bpf_map *prog_array_map, u32 index)
++ * 	Description
++ * 		This special helper is used to trigger a "tail call", or in
++ * 		other words, to jump into another eBPF program. The same stack
++ * 		frame is used (but values on stack and in registers for the
++ * 		caller are not accessible to the callee). This mechanism allows
++ * 		for program chaining, either for raising the maximum number of
++ * 		available eBPF instructions, or to execute given programs in
++ * 		conditional blocks. For security reasons, there is an upper
++ * 		limit to the number of successive tail calls that can be
++ * 		performed.
++ *
++ * 		Upon call of this helper, the program attempts to jump into a
++ * 		program referenced at index *index* in *prog_array_map*, a
++ * 		special map of type **BPF_MAP_TYPE_PROG_ARRAY**, and passes
++ * 		*ctx*, a pointer to the context.
++ *
++ * 		If the call succeeds, the kernel immediately runs the first
++ * 		instruction of the new program. This is not a function call,
++ * 		and it never returns to the previous program. If the call
++ * 		fails, then the helper has no effect, and the caller continues
++ * 		to run its subsequent instructions. A call can fail if the
++ * 		destination program for the jump does not exist (i.e. *index*
++ * 		is superior to the number of entries in *prog_array_map*), or
++ * 		if the maximum number of tail calls has been reached for this
++ * 		chain of programs. This limit is defined in the kernel by the
++ * 		macro **MAX_TAIL_CALL_CNT** (not accessible to user space),
++ * 		which is currently set to 32.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_clone_redirect(struct sk_buff *skb, u32 ifindex, u64 flags)
++ * 	Description
++ * 		Clone and redirect the packet associated to *skb* to another
++ * 		net device of index *ifindex*. Both ingress and egress
++ * 		interfaces can be used for redirection. The **BPF_F_INGRESS**
++ * 		value in *flags* is used to make the distinction (ingress path
++ * 		is selected if the flag is present, egress path otherwise).
++ * 		This is the only flag supported for now.
++ *
++ * 		In comparison with **bpf_redirect**\ () helper,
++ * 		**bpf_clone_redirect**\ () has the associated cost of
++ * 		duplicating the packet buffer, but this can be executed out of
++ * 		the eBPF program. Conversely, **bpf_redirect**\ () is more
++ * 		efficient, but it is handled through an action code where the
++ * 		redirection happens only after the eBPF program has returned.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
+  *
+  * u64 bpf_get_current_pid_tgid(void)
+- *     Return: current->tgid << 32 | current->pid
++ * 	Return
++ * 		A 64-bit integer containing the current tgid and pid, and
++ * 		created as such:
++ * 		*current_task*\ **->tgid << 32 \|**
++ * 		*current_task*\ **->pid**.
+  *
+  * u64 bpf_get_current_uid_gid(void)
+- *     Return: current_gid << 32 | current_uid
+- *
+- * int bpf_get_current_comm(char *buf, int size_of_buf)
+- *     stores current->comm into buf
+- *     Return: 0 on success or negative error
+- *
+- * u32 bpf_get_cgroup_classid(skb)
+- *     retrieve a proc's classid
+- *     @skb: pointer to skb
+- *     Return: classid if != 0
+- *
+- * int bpf_skb_vlan_push(skb, vlan_proto, vlan_tci)
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_vlan_pop(skb)
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_get_tunnel_key(skb, key, size, flags)
+- * int bpf_skb_set_tunnel_key(skb, key, size, flags)
+- *     retrieve or populate tunnel metadata
+- *     @skb: pointer to skb
+- *     @key: pointer to 'struct bpf_tunnel_key'
+- *     @size: size of 'struct bpf_tunnel_key'
+- *     @flags: room for future extensions
+- *     Return: 0 on success or negative error
+- *
+- * u64 bpf_perf_event_read(map, flags)
+- *     read perf event counter value
+- *     @map: pointer to perf_event_array map
+- *     @flags: index of event in the map or bitmask flags
+- *     Return: value of perf event counter read or error code
+- *
+- * int bpf_redirect(ifindex, flags)
+- *     redirect to another netdev
+- *     @ifindex: ifindex of the net device
+- *     @flags:
+- *	  cls_bpf:
+- *          bit 0 - if set, redirect to ingress instead of egress
+- *          other bits - reserved
+- *	  xdp_bpf:
+- *	    all bits - reserved
+- *     Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error
+- *	       xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error
+- * int bpf_redirect_map(map, key, flags)
+- *     redirect to endpoint in map
+- *     @map: pointer to dev map
+- *     @key: index in map to lookup
+- *     @flags: --
+- *     Return: XDP_REDIRECT on success or XDP_ABORT on error
+- *
+- * u32 bpf_get_route_realm(skb)
+- *     retrieve a dst's tclassid
+- *     @skb: pointer to skb
+- *     Return: realm if != 0
+- *
+- * int bpf_perf_event_output(ctx, map, flags, data, size)
+- *     output perf raw sample
+- *     @ctx: struct pt_regs*
+- *     @map: pointer to perf_event_array map
+- *     @flags: index of event in the map or bitmask flags
+- *     @data: data on stack to be output as raw data
+- *     @size: size of data
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_get_stackid(ctx, map, flags)
+- *     walk user or kernel stack and return id
+- *     @ctx: struct pt_regs*
+- *     @map: pointer to stack_trace map
+- *     @flags: bits 0-7 - numer of stack frames to skip
+- *             bit 8 - collect user stack instead of kernel
+- *             bit 9 - compare stacks by hash only
+- *             bit 10 - if two different stacks hash into the same stackid
+- *                      discard old
+- *             other bits - reserved
+- *     Return: >= 0 stackid on success or negative error
+- *
+- * s64 bpf_csum_diff(from, from_size, to, to_size, seed)
+- *     calculate csum diff
+- *     @from: raw from buffer
+- *     @from_size: length of from buffer
+- *     @to: raw to buffer
+- *     @to_size: length of to buffer
+- *     @seed: optional seed
+- *     Return: csum result or negative error code
+- *
+- * int bpf_skb_get_tunnel_opt(skb, opt, size)
+- *     retrieve tunnel options metadata
+- *     @skb: pointer to skb
+- *     @opt: pointer to raw tunnel option data
+- *     @size: size of @opt
+- *     Return: option size
+- *
+- * int bpf_skb_set_tunnel_opt(skb, opt, size)
+- *     populate tunnel options metadata
+- *     @skb: pointer to skb
+- *     @opt: pointer to raw tunnel option data
+- *     @size: size of @opt
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_change_proto(skb, proto, flags)
+- *     Change protocol of the skb. Currently supported is v4 -> v6,
+- *     v6 -> v4 transitions. The helper will also resize the skb. eBPF
+- *     program is expected to fill the new headers via skb_store_bytes
+- *     and lX_csum_replace.
+- *     @skb: pointer to skb
+- *     @proto: new skb->protocol type
+- *     @flags: reserved
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_change_type(skb, type)
+- *     Change packet type of skb.
+- *     @skb: pointer to skb
+- *     @type: new skb->pkt_type type
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_under_cgroup(skb, map, index)
+- *     Check cgroup2 membership of skb
+- *     @skb: pointer to skb
+- *     @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
+- *     @index: index of the cgroup in the bpf_map
+- *     Return:
+- *       == 0 skb failed the cgroup2 descendant test
+- *       == 1 skb succeeded the cgroup2 descendant test
+- *        < 0 error
+- *
+- * u32 bpf_get_hash_recalc(skb)
+- *     Retrieve and possibly recalculate skb->hash.
+- *     @skb: pointer to skb
+- *     Return: hash
++ * 	Return
++ * 		A 64-bit integer containing the current GID and UID, and
++ * 		created as such: *current_gid* **<< 32 \|** *current_uid*.
++ *
++ * int bpf_get_current_comm(char *buf, u32 size_of_buf)
++ * 	Description
++ * 		Copy the **comm** attribute of the current task into *buf* of
++ * 		*size_of_buf*. The **comm** attribute contains the name of
++ * 		the executable (excluding the path) for the current task. The
++ * 		*size_of_buf* must be strictly positive. On success, the
++ * 		helper makes sure that the *buf* is NUL-terminated. On failure,
++ * 		it is filled with zeroes.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * u32 bpf_get_cgroup_classid(struct sk_buff *skb)
++ * 	Description
++ * 		Retrieve the classid for the current task, i.e. for the net_cls
++ * 		cgroup to which *skb* belongs.
++ *
++ * 		This helper can be used on TC egress path, but not on ingress.
++ *
++ * 		The net_cls cgroup provides an interface to tag network packets
++ * 		based on a user-provided identifier for all traffic coming from
++ * 		the tasks belonging to the related cgroup. See also the related
++ * 		kernel documentation, available from the Linux sources in file
++ * 		*Documentation/cgroup-v1/net_cls.txt*.
++ *
++ * 		The Linux kernel has two versions for cgroups: there are
++ * 		cgroups v1 and cgroups v2. Both are available to users, who can
++ * 		use a mixture of them, but note that the net_cls cgroup is for
++ * 		cgroup v1 only. This makes it incompatible with BPF programs
++ * 		run on cgroups, which is a cgroup-v2-only feature (a socket can
++ * 		only hold data for one version of cgroups at a time).
++ *
++ * 		This helper is only available is the kernel was compiled with
++ * 		the **CONFIG_CGROUP_NET_CLASSID** configuration option set to
++ * 		"**y**" or to "**m**".
++ * 	Return
++ * 		The classid, or 0 for the default unconfigured classid.
++ *
++ * int bpf_skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci)
++ * 	Description
++ * 		Push a *vlan_tci* (VLAN tag control information) of protocol
++ * 		*vlan_proto* to the packet associated to *skb*, then update
++ * 		the checksum. Note that if *vlan_proto* is different from
++ * 		**ETH_P_8021Q** and **ETH_P_8021AD**, it is considered to
++ * 		be **ETH_P_8021Q**.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_vlan_pop(struct sk_buff *skb)
++ * 	Description
++ * 		Pop a VLAN header from the packet associated to *skb*.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_get_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags)
++ * 	Description
++ * 		Get tunnel metadata. This helper takes a pointer *key* to an
++ * 		empty **struct bpf_tunnel_key** of **size**, that will be
++ * 		filled with tunnel metadata for the packet associated to *skb*.
++ * 		The *flags* can be set to **BPF_F_TUNINFO_IPV6**, which
++ * 		indicates that the tunnel is based on IPv6 protocol instead of
++ * 		IPv4.
++ *
++ * 		The **struct bpf_tunnel_key** is an object that generalizes the
++ * 		principal parameters used by various tunneling protocols into a
++ * 		single struct. This way, it can be used to easily make a
++ * 		decision based on the contents of the encapsulation header,
++ * 		"summarized" in this struct. In particular, it holds the IP
++ * 		address of the remote end (IPv4 or IPv6, depending on the case)
++ * 		in *key*\ **->remote_ipv4** or *key*\ **->remote_ipv6**. Also,
++ * 		this struct exposes the *key*\ **->tunnel_id**, which is
++ * 		generally mapped to a VNI (Virtual Network Identifier), making
++ * 		it programmable together with the **bpf_skb_set_tunnel_key**\
++ * 		() helper.
++ *
++ * 		Let's imagine that the following code is part of a program
++ * 		attached to the TC ingress interface, on one end of a GRE
++ * 		tunnel, and is supposed to filter out all messages coming from
++ * 		remote ends with IPv4 address other than 10.0.0.1:
++ *
++ * 		::
++ *
++ * 			int ret;
++ * 			struct bpf_tunnel_key key = {};
++ * 			
++ * 			ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
++ * 			if (ret < 0)
++ * 				return TC_ACT_SHOT;	// drop packet
++ * 			
++ * 			if (key.remote_ipv4 != 0x0a000001)
++ * 				return TC_ACT_SHOT;	// drop packet
++ * 			
++ * 			return TC_ACT_OK;		// accept packet
++ *
++ * 		This interface can also be used with all encapsulation devices
++ * 		that can operate in "collect metadata" mode: instead of having
++ * 		one network device per specific configuration, the "collect
++ * 		metadata" mode only requires a single device where the
++ * 		configuration can be extracted from this helper.
++ *
++ * 		This can be used together with various tunnels such as VXLan,
++ * 		Geneve, GRE or IP in IP (IPIP).
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_set_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags)
++ * 	Description
++ * 		Populate tunnel metadata for packet associated to *skb.* The
++ * 		tunnel metadata is set to the contents of *key*, of *size*. The
++ * 		*flags* can be set to a combination of the following values:
++ *
++ * 		**BPF_F_TUNINFO_IPV6**
++ * 			Indicate that the tunnel is based on IPv6 protocol
++ * 			instead of IPv4.
++ * 		**BPF_F_ZERO_CSUM_TX**
++ * 			For IPv4 packets, add a flag to tunnel metadata
++ * 			indicating that checksum computation should be skipped
++ * 			and checksum set to zeroes.
++ * 		**BPF_F_DONT_FRAGMENT**
++ * 			Add a flag to tunnel metadata indicating that the
++ * 			packet should not be fragmented.
++ * 		**BPF_F_SEQ_NUMBER**
++ * 			Add a flag to tunnel metadata indicating that a
++ * 			sequence number should be added to tunnel header before
++ * 			sending the packet. This flag was added for GRE
++ * 			encapsulation, but might be used with other protocols
++ * 			as well in the future.
++ *
++ * 		Here is a typical usage on the transmit path:
++ *
++ * 		::
++ *
++ * 			struct bpf_tunnel_key key;
++ * 			     populate key ...
++ * 			bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
++ * 			bpf_clone_redirect(skb, vxlan_dev_ifindex, 0);
++ *
++ * 		See also the description of the **bpf_skb_get_tunnel_key**\ ()
++ * 		helper for additional information.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * u64 bpf_perf_event_read(struct bpf_map *map, u64 flags)
++ * 	Description
++ * 		Read the value of a perf event counter. This helper relies on a
++ * 		*map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. The nature of
++ * 		the perf event counter is selected when *map* is updated with
++ * 		perf event file descriptors. The *map* is an array whose size
++ * 		is the number of available CPUs, and each cell contains a value
++ * 		relative to one CPU. The value to retrieve is indicated by
++ * 		*flags*, that contains the index of the CPU to look up, masked
++ * 		with **BPF_F_INDEX_MASK**. Alternatively, *flags* can be set to
++ * 		**BPF_F_CURRENT_CPU** to indicate that the value for the
++ * 		current CPU should be retrieved.
++ *
++ * 		Note that before Linux 4.13, only hardware perf event can be
++ * 		retrieved.
++ *
++ * 		Also, be aware that the newer helper
++ * 		**bpf_perf_event_read_value**\ () is recommended over
++ * 		**bpf_perf_event_read**\ () in general. The latter has some ABI
++ * 		quirks where error and counter value are used as a return code
++ * 		(which is wrong to do since ranges may overlap). This issue is
++ * 		fixed with **bpf_perf_event_read_value**\ (), which at the same
++ * 		time provides more features over the **bpf_perf_event_read**\
++ * 		() interface. Please refer to the description of
++ * 		**bpf_perf_event_read_value**\ () for details.
++ * 	Return
++ * 		The value of the perf event counter read from the map, or a
++ * 		negative error code in case of failure.
++ *
++ * int bpf_redirect(u32 ifindex, u64 flags)
++ * 	Description
++ * 		Redirect the packet to another net device of index *ifindex*.
++ * 		This helper is somewhat similar to **bpf_clone_redirect**\
++ * 		(), except that the packet is not cloned, which provides
++ * 		increased performance.
++ *
++ * 		Except for XDP, both ingress and egress interfaces can be used
++ * 		for redirection. The **BPF_F_INGRESS** value in *flags* is used
++ * 		to make the distinction (ingress path is selected if the flag
++ * 		is present, egress path otherwise). Currently, XDP only
++ * 		supports redirection to the egress interface, and accepts no
++ * 		flag at all.
++ *
++ * 		The same effect can be attained with the more generic
++ * 		**bpf_redirect_map**\ (), which requires specific maps to be
++ * 		used but offers better performance.
++ * 	Return
++ * 		For XDP, the helper returns **XDP_REDIRECT** on success or
++ * 		**XDP_ABORTED** on error. For other program types, the values
++ * 		are **TC_ACT_REDIRECT** on success or **TC_ACT_SHOT** on
++ * 		error.
++ *
++ * u32 bpf_get_route_realm(struct sk_buff *skb)
++ * 	Description
++ * 		Retrieve the realm or the route, that is to say the
++ * 		**tclassid** field of the destination for the *skb*. The
++ * 		indentifier retrieved is a user-provided tag, similar to the
++ * 		one used with the net_cls cgroup (see description for
++ * 		**bpf_get_cgroup_classid**\ () helper), but here this tag is
++ * 		held by a route (a destination entry), not by a task.
++ *
++ * 		Retrieving this identifier works with the clsact TC egress hook
++ * 		(see also **tc-bpf(8)**), or alternatively on conventional
++ * 		classful egress qdiscs, but not on TC ingress path. In case of
++ * 		clsact TC egress hook, this has the advantage that, internally,
++ * 		the destination entry has not been dropped yet in the transmit
++ * 		path. Therefore, the destination entry does not need to be
++ * 		artificially held via **netif_keep_dst**\ () for a classful
++ * 		qdisc until the *skb* is freed.
++ *
++ * 		This helper is available only if the kernel was compiled with
++ * 		**CONFIG_IP_ROUTE_CLASSID** configuration option.
++ * 	Return
++ * 		The realm of the route for the packet associated to *skb*, or 0
++ * 		if none was found.
++ *
++ * int bpf_perf_event_output(struct pt_reg *ctx, struct bpf_map *map, u64 flags, void *data, u64 size)
++ * 	Description
++ * 		Write raw *data* blob into a special BPF perf event held by
++ * 		*map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. This perf
++ * 		event must have the following attributes: **PERF_SAMPLE_RAW**
++ * 		as **sample_type**, **PERF_TYPE_SOFTWARE** as **type**, and
++ * 		**PERF_COUNT_SW_BPF_OUTPUT** as **config**.
++ *
++ * 		The *flags* are used to indicate the index in *map* for which
++ * 		the value must be put, masked with **BPF_F_INDEX_MASK**.
++ * 		Alternatively, *flags* can be set to **BPF_F_CURRENT_CPU**
++ * 		to indicate that the index of the current CPU core should be
++ * 		used.
++ *
++ * 		The value to write, of *size*, is passed through eBPF stack and
++ * 		pointed by *data*.
++ *
++ * 		The context of the program *ctx* needs also be passed to the
++ * 		helper.
++ *
++ * 		On user space, a program willing to read the values needs to
++ * 		call **perf_event_open**\ () on the perf event (either for
++ * 		one or for all CPUs) and to store the file descriptor into the
++ * 		*map*. This must be done before the eBPF program can send data
++ * 		into it. An example is available in file
++ * 		*samples/bpf/trace_output_user.c* in the Linux kernel source
++ * 		tree (the eBPF program counterpart is in
++ * 		*samples/bpf/trace_output_kern.c*).
++ *
++ * 		**bpf_perf_event_output**\ () achieves better performance
++ * 		than **bpf_trace_printk**\ () for sharing data with user
++ * 		space, and is much better suitable for streaming data from eBPF
++ * 		programs.
++ *
++ * 		Note that this helper is not restricted to tracing use cases
++ * 		and can be used with programs attached to TC or XDP as well,
++ * 		where it allows for passing data to user space listeners. Data
++ * 		can be:
++ *
++ * 		* Only custom structs,
++ * 		* Only the packet payload, or
++ * 		* A combination of both.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset, void *to, u32 len)
++ * 	Description
++ * 		This helper was provided as an easy way to load data from a
++ * 		packet. It can be used to load *len* bytes from *offset* from
++ * 		the packet associated to *skb*, into the buffer pointed by
++ * 		*to*.
++ *
++ * 		Since Linux 4.7, usage of this helper has mostly been replaced
++ * 		by "direct packet access", enabling packet data to be
++ * 		manipulated with *skb*\ **->data** and *skb*\ **->data_end**
++ * 		pointing respectively to the first byte of packet data and to
++ * 		the byte after the last byte of packet data. However, it
++ * 		remains useful if one wishes to read large quantities of data
++ * 		at once from a packet into the eBPF stack.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_get_stackid(struct pt_reg *ctx, struct bpf_map *map, u64 flags)
++ * 	Description
++ * 		Walk a user or a kernel stack and return its id. To achieve
++ * 		this, the helper needs *ctx*, which is a pointer to the context
++ * 		on which the tracing program is executed, and a pointer to a
++ * 		*map* of type **BPF_MAP_TYPE_STACK_TRACE**.
++ *
++ * 		The last argument, *flags*, holds the number of stack frames to
++ * 		skip (from 0 to 255), masked with
++ * 		**BPF_F_SKIP_FIELD_MASK**. The next bits can be used to set
++ * 		a combination of the following flags:
++ *
++ * 		**BPF_F_USER_STACK**
++ * 			Collect a user space stack instead of a kernel stack.
++ * 		**BPF_F_FAST_STACK_CMP**
++ * 			Compare stacks by hash only.
++ * 		**BPF_F_REUSE_STACKID**
++ * 			If two different stacks hash into the same *stackid*,
++ * 			discard the old one.
++ *
++ * 		The stack id retrieved is a 32 bit long integer handle which
++ * 		can be further combined with other data (including other stack
++ * 		ids) and used as a key into maps. This can be useful for
++ * 		generating a variety of graphs (such as flame graphs or off-cpu
++ * 		graphs).
++ *
++ * 		For walking a stack, this helper is an improvement over
++ * 		**bpf_probe_read**\ (), which can be used with unrolled loops
++ * 		but is not efficient and consumes a lot of eBPF instructions.
++ * 		Instead, **bpf_get_stackid**\ () can collect up to
++ * 		**PERF_MAX_STACK_DEPTH** both kernel and user frames. Note that
++ * 		this limit can be controlled with the **sysctl** program, and
++ * 		that it should be manually increased in order to profile long
++ * 		user stacks (such as stacks for Java programs). To do so, use:
++ *
++ * 		::
++ *
++ * 			# sysctl kernel.perf_event_max_stack=<new value>
++ * 	Return
++ * 		The positive or null stack id on success, or a negative error
++ * 		in case of failure.
++ *
++ * s64 bpf_csum_diff(__be32 *from, u32 from_size, __be32 *to, u32 to_size, __wsum seed)
++ * 	Description
++ * 		Compute a checksum difference, from the raw buffer pointed by
++ * 		*from*, of length *from_size* (that must be a multiple of 4),
++ * 		towards the raw buffer pointed by *to*, of size *to_size*
++ * 		(same remark). An optional *seed* can be added to the value
++ * 		(this can be cascaded, the seed may come from a previous call
++ * 		to the helper).
++ *
++ * 		This is flexible enough to be used in several ways:
++ *
++ * 		* With *from_size* == 0, *to_size* > 0 and *seed* set to
++ * 		  checksum, it can be used when pushing new data.
++ * 		* With *from_size* > 0, *to_size* == 0 and *seed* set to
++ * 		  checksum, it can be used when removing data from a packet.
++ * 		* With *from_size* > 0, *to_size* > 0 and *seed* set to 0, it
++ * 		  can be used to compute a diff. Note that *from_size* and
++ * 		  *to_size* do not need to be equal.
++ *
++ * 		This helper can be used in combination with
++ * 		**bpf_l3_csum_replace**\ () and **bpf_l4_csum_replace**\ (), to
++ * 		which one can feed in the difference computed with
++ * 		**bpf_csum_diff**\ ().
++ * 	Return
++ * 		The checksum result, or a negative error code in case of
++ * 		failure.
++ *
++ * int bpf_skb_get_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size)
++ * 	Description
++ * 		Retrieve tunnel options metadata for the packet associated to
++ * 		*skb*, and store the raw tunnel option data to the buffer *opt*
++ * 		of *size*.
++ *
++ * 		This helper can be used with encapsulation devices that can
++ * 		operate in "collect metadata" mode (please refer to the related
++ * 		note in the description of **bpf_skb_get_tunnel_key**\ () for
++ * 		more details). A particular example where this can be used is
++ * 		in combination with the Geneve encapsulation protocol, where it
++ * 		allows for pushing (with **bpf_skb_get_tunnel_opt**\ () helper)
++ * 		and retrieving arbitrary TLVs (Type-Length-Value headers) from
++ * 		the eBPF program. This allows for full customization of these
++ * 		headers.
++ * 	Return
++ * 		The size of the option data retrieved.
++ *
++ * int bpf_skb_set_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size)
++ * 	Description
++ * 		Set tunnel options metadata for the packet associated to *skb*
++ * 		to the option data contained in the raw buffer *opt* of *size*.
++ *
++ * 		See also the description of the **bpf_skb_get_tunnel_opt**\ ()
++ * 		helper for additional information.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_change_proto(struct sk_buff *skb, __be16 proto, u64 flags)
++ * 	Description
++ * 		Change the protocol of the *skb* to *proto*. Currently
++ * 		supported are transition from IPv4 to IPv6, and from IPv6 to
++ * 		IPv4. The helper takes care of the groundwork for the
++ * 		transition, including resizing the socket buffer. The eBPF
++ * 		program is expected to fill the new headers, if any, via
++ * 		**skb_store_bytes**\ () and to recompute the checksums with
++ * 		**bpf_l3_csum_replace**\ () and **bpf_l4_csum_replace**\
++ * 		(). The main case for this helper is to perform NAT64
++ * 		operations out of an eBPF program.
++ *
++ * 		Internally, the GSO type is marked as dodgy so that headers are
++ * 		checked and segments are recalculated by the GSO/GRO engine.
++ * 		The size for GSO target is adapted as well.
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_change_type(struct sk_buff *skb, u32 type)
++ * 	Description
++ * 		Change the packet type for the packet associated to *skb*. This
++ * 		comes down to setting *skb*\ **->pkt_type** to *type*, except
++ * 		the eBPF program does not have a write access to *skb*\
++ * 		**->pkt_type** beside this helper. Using a helper here allows
++ * 		for graceful handling of errors.
++ *
++ * 		The major use case is to change incoming *skb*s to
++ * 		**PACKET_HOST** in a programmatic way instead of having to
++ * 		recirculate via **redirect**\ (..., **BPF_F_INGRESS**), for
++ * 		example.
++ *
++ * 		Note that *type* only allows certain values. At this time, they
++ * 		are:
++ *
++ * 		**PACKET_HOST**
++ * 			Packet is for us.
++ * 		**PACKET_BROADCAST**
++ * 			Send packet to all.
++ * 		**PACKET_MULTICAST**
++ * 			Send packet to group.
++ * 		**PACKET_OTHERHOST**
++ * 			Send packet to someone else.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_under_cgroup(struct sk_buff *skb, struct bpf_map *map, u32 index)
++ * 	Description
++ * 		Check whether *skb* is a descendant of the cgroup2 held by
++ * 		*map* of type **BPF_MAP_TYPE_CGROUP_ARRAY**, at *index*.
++ * 	Return
++ * 		The return value depends on the result of the test, and can be:
++ *
++ * 		* 0, if the *skb* failed the cgroup2 descendant test.
++ * 		* 1, if the *skb* succeeded the cgroup2 descendant test.
++ * 		* A negative error code, if an error occurred.
++ *
++ * u32 bpf_get_hash_recalc(struct sk_buff *skb)
++ * 	Description
++ * 		Retrieve the hash of the packet, *skb*\ **->hash**. If it is
++ * 		not set, in particular if the hash was cleared due to mangling,
++ * 		recompute this hash. Later accesses to the hash can be done
++ * 		directly with *skb*\ **->hash**.
++ *
++ * 		Calling **bpf_set_hash_invalid**\ (), changing a packet
++ * 		prototype with **bpf_skb_change_proto**\ (), or calling
++ * 		**bpf_skb_store_bytes**\ () with the
++ * 		**BPF_F_INVALIDATE_HASH** are actions susceptible to clear
++ * 		the hash and to trigger a new computation for the next call to
++ * 		**bpf_get_hash_recalc**\ ().
++ * 	Return
++ * 		The 32-bit hash.
+  *
+  * u64 bpf_get_current_task(void)
+- *     Returns current task_struct
+- *     Return: current
+- *
+- * int bpf_probe_write_user(void *dst, void *src, int len)
+- *     safely attempt to write to a location
+- *     @dst: destination address in userspace
+- *     @src: source address on stack
+- *     @len: number of bytes to copy
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_current_task_under_cgroup(map, index)
+- *     Check cgroup2 membership of current task
+- *     @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
+- *     @index: index of the cgroup in the bpf_map
+- *     Return:
+- *       == 0 current failed the cgroup2 descendant test
+- *       == 1 current succeeded the cgroup2 descendant test
+- *        < 0 error
+- *
+- * int bpf_skb_change_tail(skb, len, flags)
+- *     The helper will resize the skb to the given new size, to be used f.e.
+- *     with control messages.
+- *     @skb: pointer to skb
+- *     @len: new skb length
+- *     @flags: reserved
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_skb_pull_data(skb, len)
+- *     The helper will pull in non-linear data in case the skb is non-linear
+- *     and not all of len are part of the linear section. Only needed for
+- *     read/write with direct packet access.
+- *     @skb: pointer to skb
+- *     @len: len to make read/writeable
+- *     Return: 0 on success or negative error
+- *
+- * s64 bpf_csum_update(skb, csum)
+- *     Adds csum into skb->csum in case of CHECKSUM_COMPLETE.
+- *     @skb: pointer to skb
+- *     @csum: csum to add
+- *     Return: csum on success or negative error
+- *
+- * void bpf_set_hash_invalid(skb)
+- *     Invalidate current skb->hash.
+- *     @skb: pointer to skb
+- *
+- * int bpf_get_numa_node_id()
+- *     Return: Id of current NUMA node.
+- *
+- * int bpf_skb_change_head()
+- *     Grows headroom of skb and adjusts MAC header offset accordingly.
+- *     Will extends/reallocae as required automatically.
+- *     May change skb data pointer and will thus invalidate any check
+- *     performed for direct packet access.
+- *     @skb: pointer to skb
+- *     @len: length of header to be pushed in front
+- *     @flags: Flags (unused for now)
+- *     Return: 0 on success or negative error
+- *
+- * int bpf_xdp_adjust_head(xdp_md, delta)
+- *     Adjust the xdp_md.data by delta
+- *     @xdp_md: pointer to xdp_md
+- *     @delta: An positive/negative integer to be added to xdp_md.data
+- *     Return: 0 on success or negative on error
++ * 	Return
++ * 		A pointer to the current task struct.
++ *
++ * int bpf_probe_write_user(void *dst, const void *src, u32 len)
++ * 	Description
++ * 		Attempt in a safe way to write *len* bytes from the buffer
++ * 		*src* to *dst* in memory. It only works for threads that are in
++ * 		user context, and *dst* must be a valid user space address.
++ *
++ * 		This helper should not be used to implement any kind of
++ * 		security mechanism because of TOC-TOU attacks, but rather to
++ * 		debug, divert, and manipulate execution of semi-cooperative
++ * 		processes.
++ *
++ * 		Keep in mind that this feature is meant for experiments, and it
++ * 		has a risk of crashing the system and running programs.
++ * 		Therefore, when an eBPF program using this helper is attached,
++ * 		a warning including PID and process name is printed to kernel
++ * 		logs.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_current_task_under_cgroup(struct bpf_map *map, u32 index)
++ * 	Description
++ * 		Check whether the probe is being run is the context of a given
++ * 		subset of the cgroup2 hierarchy. The cgroup2 to test is held by
++ * 		*map* of type **BPF_MAP_TYPE_CGROUP_ARRAY**, at *index*.
++ * 	Return
++ * 		The return value depends on the result of the test, and can be:
++ *
++ * 		* 0, if the *skb* task belongs to the cgroup2.
++ * 		* 1, if the *skb* task does not belong to the cgroup2.
++ * 		* A negative error code, if an error occurred.
++ *
++ * int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags)
++ * 	Description
++ * 		Resize (trim or grow) the packet associated to *skb* to the
++ * 		new *len*. The *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		The basic idea is that the helper performs the needed work to
++ * 		change the size of the packet, then the eBPF program rewrites
++ * 		the rest via helpers like **bpf_skb_store_bytes**\ (),
++ * 		**bpf_l3_csum_replace**\ (), **bpf_l3_csum_replace**\ ()
++ * 		and others. This helper is a slow path utility intended for
++ * 		replies with control messages. And because it is targeted for
++ * 		slow path, the helper itself can afford to be slow: it
++ * 		implicitly linearizes, unclones and drops offloads from the
++ * 		*skb*.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_pull_data(struct sk_buff *skb, u32 len)
++ * 	Description
++ * 		Pull in non-linear data in case the *skb* is non-linear and not
++ * 		all of *len* are part of the linear section. Make *len* bytes
++ * 		from *skb* readable and writable. If a zero value is passed for
++ * 		*len*, then the whole length of the *skb* is pulled.
++ *
++ * 		This helper is only needed for reading and writing with direct
++ * 		packet access.
++ *
++ * 		For direct packet access, testing that offsets to access
++ * 		are within packet boundaries (test on *skb*\ **->data_end**) is
++ * 		susceptible to fail if offsets are invalid, or if the requested
++ * 		data is in non-linear parts of the *skb*. On failure the
++ * 		program can just bail out, or in the case of a non-linear
++ * 		buffer, use a helper to make the data available. The
++ * 		**bpf_skb_load_bytes**\ () helper is a first solution to access
++ * 		the data. Another one consists in using **bpf_skb_pull_data**
++ * 		to pull in once the non-linear parts, then retesting and
++ * 		eventually access the data.
++ *
++ * 		At the same time, this also makes sure the *skb* is uncloned,
++ * 		which is a necessary condition for direct write. As this needs
++ * 		to be an invariant for the write part only, the verifier
++ * 		detects writes and adds a prologue that is calling
++ * 		**bpf_skb_pull_data()** to effectively unclone the *skb* from
++ * 		the very beginning in case it is indeed cloned.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * s64 bpf_csum_update(struct sk_buff *skb, __wsum csum)
++ * 	Description
++ * 		Add the checksum *csum* into *skb*\ **->csum** in case the
++ * 		driver has supplied a checksum for the entire packet into that
++ * 		field. Return an error otherwise. This helper is intended to be
++ * 		used in combination with **bpf_csum_diff**\ (), in particular
++ * 		when the checksum needs to be updated after data has been
++ * 		written into the packet through direct packet access.
++ * 	Return
++ * 		The checksum on success, or a negative error code in case of
++ * 		failure.
++ *
++ * void bpf_set_hash_invalid(struct sk_buff *skb)
++ * 	Description
++ * 		Invalidate the current *skb*\ **->hash**. It can be used after
++ * 		mangling on headers through direct packet access, in order to
++ * 		indicate that the hash is outdated and to trigger a
++ * 		recalculation the next time the kernel tries to access this
++ * 		hash or when the **bpf_get_hash_recalc**\ () helper is called.
++ *
++ * int bpf_get_numa_node_id(void)
++ * 	Description
++ * 		Return the id of the current NUMA node. The primary use case
++ * 		for this helper is the selection of sockets for the local NUMA
++ * 		node, when the program is attached to sockets using the
++ * 		**SO_ATTACH_REUSEPORT_EBPF** option (see also **socket(7)**),
++ * 		but the helper is also available to other eBPF program types,
++ * 		similarly to **bpf_get_smp_processor_id**\ ().
++ * 	Return
++ * 		The id of current NUMA node.
++ *
++ * int bpf_skb_change_head(struct sk_buff *skb, u32 len, u64 flags)
++ * 	Description
++ * 		Grows headroom of packet associated to *skb* and adjusts the
++ * 		offset of the MAC header accordingly, adding *len* bytes of
++ * 		space. It automatically extends and reallocates memory as
++ * 		required.
++ *
++ * 		This helper can be used on a layer 3 *skb* to push a MAC header
++ * 		for redirection into a layer 2 device.
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_xdp_adjust_head(struct xdp_buff *xdp_md, int delta)
++ * 	Description
++ * 		Adjust (move) *xdp_md*\ **->data** by *delta* bytes. Note that
++ * 		it is possible to use a negative value for *delta*. This helper
++ * 		can be used to prepare the packet for pushing or popping
++ * 		headers.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
+  *
+  * int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr)
+- *     Copy a NUL terminated string from unsafe address. In case the string
+- *     length is smaller than size, the target is not padded with further NUL
+- *     bytes. In case the string length is larger than size, just count-1
+- *     bytes are copied and the last byte is set to NUL.
+- *     @dst: destination address
+- *     @size: maximum number of bytes to copy, including the trailing NUL
+- *     @unsafe_ptr: unsafe address
+- *     Return:
+- *       > 0 length of the string including the trailing NUL on success
+- *       < 0 error
+- *
+- * u64 bpf_get_socket_cookie(skb)
+- *     Get the cookie for the socket stored inside sk_buff.
+- *     @skb: pointer to skb
+- *     Return: 8 Bytes non-decreasing number on success or 0 if the socket
+- *     field is missing inside sk_buff
+- *
+- * u32 bpf_get_socket_uid(skb)
+- *     Get the owner uid of the socket stored inside sk_buff.
+- *     @skb: pointer to skb
+- *     Return: uid of the socket owner on success or overflowuid if failed.
+- *
+- * u32 bpf_set_hash(skb, hash)
+- *     Set full skb->hash.
+- *     @skb: pointer to skb
+- *     @hash: hash to set
+- *
+- * int bpf_setsockopt(bpf_socket, level, optname, optval, optlen)
+- *     Calls setsockopt. Not all opts are available, only those with
+- *     integer optvals plus TCP_CONGESTION.
+- *     Supported levels: SOL_SOCKET and IPPROTO_TCP
+- *     @bpf_socket: pointer to bpf_socket
+- *     @level: SOL_SOCKET or IPPROTO_TCP
+- *     @optname: option name
+- *     @optval: pointer to option value
+- *     @optlen: length of optval in bytes
+- *     Return: 0 or negative error
+- *
+- * int bpf_getsockopt(bpf_socket, level, optname, optval, optlen)
+- *     Calls getsockopt. Not all opts are available.
+- *     Supported levels: IPPROTO_TCP
+- *     @bpf_socket: pointer to bpf_socket
+- *     @level: IPPROTO_TCP
+- *     @optname: option name
+- *     @optval: pointer to option value
+- *     @optlen: length of optval in bytes
+- *     Return: 0 or negative error
+- *
+- * int bpf_sock_ops_cb_flags_set(bpf_sock_ops, flags)
+- *     Set callback flags for sock_ops
+- *     @bpf_sock_ops: pointer to bpf_sock_ops_kern struct
+- *     @flags: flags value
+- *     Return: 0 for no error
+- *             -EINVAL if there is no full tcp socket
+- *             bits in flags that are not supported by current kernel
+- *
+- * int bpf_skb_adjust_room(skb, len_diff, mode, flags)
+- *     Grow or shrink room in sk_buff.
+- *     @skb: pointer to skb
+- *     @len_diff: (signed) amount of room to grow/shrink
+- *     @mode: operation mode (enum bpf_adj_room_mode)
+- *     @flags: reserved for future use
+- *     Return: 0 on success or negative error code
+- *
+- * int bpf_sk_redirect_map(map, key, flags)
+- *     Redirect skb to a sock in map using key as a lookup key for the
+- *     sock in map.
+- *     @map: pointer to sockmap
+- *     @key: key to lookup sock in map
+- *     @flags: reserved for future use
+- *     Return: SK_PASS
+- *
+- * int bpf_sock_map_update(skops, map, key, flags)
+- *	@skops: pointer to bpf_sock_ops
+- *	@map: pointer to sockmap to update
+- *	@key: key to insert/update sock in map
+- *	@flags: same flags as map update elem
+- *
+- * int bpf_xdp_adjust_meta(xdp_md, delta)
+- *     Adjust the xdp_md.data_meta by delta
+- *     @xdp_md: pointer to xdp_md
+- *     @delta: An positive/negative integer to be added to xdp_md.data_meta
+- *     Return: 0 on success or negative on error
+- *
+- * int bpf_perf_event_read_value(map, flags, buf, buf_size)
+- *     read perf event counter value and perf event enabled/running time
+- *     @map: pointer to perf_event_array map
+- *     @flags: index of event in the map or bitmask flags
+- *     @buf: buf to fill
+- *     @buf_size: size of the buf
+- *     Return: 0 on success or negative error code
+- *
+- * int bpf_perf_prog_read_value(ctx, buf, buf_size)
+- *     read perf prog attached perf event counter and enabled/running time
+- *     @ctx: pointer to ctx
+- *     @buf: buf to fill
+- *     @buf_size: size of the buf
+- *     Return : 0 on success or negative error code
+- *
+- * int bpf_override_return(pt_regs, rc)
+- *	@pt_regs: pointer to struct pt_regs
+- *	@rc: the return value to set
++ * 	Description
++ * 		Copy a NUL terminated string from an unsafe address
++ * 		*unsafe_ptr* to *dst*. The *size* should include the
++ * 		terminating NUL byte. In case the string length is smaller than
++ * 		*size*, the target is not padded with further NUL bytes. If the
++ * 		string length is larger than *size*, just *size*-1 bytes are
++ * 		copied and the last byte is set to NUL.
++ *
++ * 		On success, the length of the copied string is returned. This
++ * 		makes this helper useful in tracing programs for reading
++ * 		strings, and more importantly to get its length at runtime. See
++ * 		the following snippet:
++ *
++ * 		::
++ *
++ * 			SEC("kprobe/sys_open")
++ * 			void bpf_sys_open(struct pt_regs *ctx)
++ * 			{
++ * 			        char buf[PATHLEN]; // PATHLEN is defined to 256
++ * 			        int res = bpf_probe_read_str(buf, sizeof(buf),
++ * 				                             ctx->di);
++ *
++ * 				// Consume buf, for example push it to
++ * 				// userspace via bpf_perf_event_output(); we
++ * 				// can use res (the string length) as event
++ * 				// size, after checking its boundaries.
++ * 			}
++ *
++ * 		In comparison, using **bpf_probe_read()** helper here instead
++ * 		to read the string would require to estimate the length at
++ * 		compile time, and would often result in copying more memory
++ * 		than necessary.
++ *
++ * 		Another useful use case is when parsing individual process
++ * 		arguments or individual environment variables navigating
++ * 		*current*\ **->mm->arg_start** and *current*\
++ * 		**->mm->env_start**: using this helper and the return value,
++ * 		one can quickly iterate at the right offset of the memory area.
++ * 	Return
++ * 		On success, the strictly positive length of the string,
++ * 		including the trailing NUL character. On error, a negative
++ * 		value.
++ *
++ * u64 bpf_get_socket_cookie(struct sk_buff *skb)
++ * 	Description
++ * 		If the **struct sk_buff** pointed by *skb* has a known socket,
++ * 		retrieve the cookie (generated by the kernel) of this socket.
++ * 		If no cookie has been set yet, generate a new cookie. Once
++ * 		generated, the socket cookie remains stable for the life of the
++ * 		socket. This helper can be useful for monitoring per socket
++ * 		networking traffic statistics as it provides a unique socket
++ * 		identifier per namespace.
++ * 	Return
++ * 		A 8-byte long non-decreasing number on success, or 0 if the
++ * 		socket field is missing inside *skb*.
++ *
++ * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
++ * 	Description
++ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
++ * 		*skb*, but gets socket from **struct bpf_sock_addr** contex.
++ * 	Return
++ * 		A 8-byte long non-decreasing number.
++ *
++ * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
++ * 	Description
++ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
++ * 		*skb*, but gets socket from **struct bpf_sock_ops** contex.
++ * 	Return
++ * 		A 8-byte long non-decreasing number.
++ *
++ * u32 bpf_get_socket_uid(struct sk_buff *skb)
++ * 	Return
++ * 		The owner UID of the socket associated to *skb*. If the socket
++ * 		is **NULL**, or if it is not a full socket (i.e. if it is a
++ * 		time-wait or a request socket instead), **overflowuid** value
++ * 		is returned (note that **overflowuid** might also be the actual
++ * 		UID value for the socket).
++ *
++ * u32 bpf_set_hash(struct sk_buff *skb, u32 hash)
++ * 	Description
++ * 		Set the full hash for *skb* (set the field *skb*\ **->hash**)
++ * 		to value *hash*.
++ * 	Return
++ * 		0
++ *
++ * int bpf_setsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, char *optval, int optlen)
++ * 	Description
++ * 		Emulate a call to **setsockopt()** on the socket associated to
++ * 		*bpf_socket*, which must be a full socket. The *level* at
++ * 		which the option resides and the name *optname* of the option
++ * 		must be specified, see **setsockopt(2)** for more information.
++ * 		The option value of length *optlen* is pointed by *optval*.
++ *
++ * 		This helper actually implements a subset of **setsockopt()**.
++ * 		It supports the following *level*\ s:
++ *
++ * 		* **SOL_SOCKET**, which supports the following *optname*\ s:
++ * 		  **SO_RCVBUF**, **SO_SNDBUF**, **SO_MAX_PACING_RATE**,
++ * 		  **SO_PRIORITY**, **SO_RCVLOWAT**, **SO_MARK**.
++ * 		* **IPPROTO_TCP**, which supports the following *optname*\ s:
++ * 		  **TCP_CONGESTION**, **TCP_BPF_IW**,
++ * 		  **TCP_BPF_SNDCWND_CLAMP**.
++ * 		* **IPPROTO_IP**, which supports *optname* **IP_TOS**.
++ * 		* **IPPROTO_IPV6**, which supports *optname* **IPV6_TCLASS**.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_adjust_room(struct sk_buff *skb, s32 len_diff, u32 mode, u64 flags)
++ * 	Description
++ * 		Grow or shrink the room for data in the packet associated to
++ * 		*skb* by *len_diff*, and according to the selected *mode*.
++ *
++ * 		There is a single supported mode at this time:
++ *
++ * 		* **BPF_ADJ_ROOM_NET**: Adjust room at the network layer
++ * 		  (room space is added or removed below the layer 3 header).
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags)
++ * 	Description
++ * 		Redirect the packet to the endpoint referenced by *map* at
++ * 		index *key*. Depending on its type, this *map* can contain
++ * 		references to net devices (for forwarding packets through other
++ * 		ports), or to CPUs (for redirecting XDP frames to another CPU;
++ * 		but this is only implemented for native XDP (with driver
++ * 		support) as of this writing).
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		When used to redirect packets to net devices, this helper
++ * 		provides a high performance increase over **bpf_redirect**\ ().
++ * 		This is due to various implementation details of the underlying
++ * 		mechanisms, one of which is the fact that **bpf_redirect_map**\
++ * 		() tries to send packet as a "bulk" to the device.
++ * 	Return
++ * 		**XDP_REDIRECT** on success, or **XDP_ABORTED** on error.
++ *
++ * int bpf_sk_redirect_map(struct bpf_map *map, u32 key, u64 flags)
++ * 	Description
++ * 		Redirect the packet to the socket referenced by *map* (of type
++ * 		**BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and
++ * 		egress interfaces can be used for redirection. The
++ * 		**BPF_F_INGRESS** value in *flags* is used to make the
++ * 		distinction (ingress path is selected if the flag is present,
++ * 		egress path otherwise). This is the only flag supported for now.
++ * 	Return
++ * 		**SK_PASS** on success, or **SK_DROP** on error.
++ *
++ * int bpf_sock_map_update(struct bpf_sock_ops *skops, struct bpf_map *map, void *key, u64 flags)
++ * 	Description
++ * 		Add an entry to, or update a *map* referencing sockets. The
++ * 		*skops* is used as a new value for the entry associated to
++ * 		*key*. *flags* is one of:
++ *
++ * 		**BPF_NOEXIST**
++ * 			The entry for *key* must not exist in the map.
++ * 		**BPF_EXIST**
++ * 			The entry for *key* must already exist in the map.
++ * 		**BPF_ANY**
++ * 			No condition on the existence of the entry for *key*.
++ *
++ * 		If the *map* has eBPF programs (parser and verdict), those will
++ * 		be inherited by the socket being added. If the socket is
++ * 		already attached to eBPF programs, this results in an error.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_xdp_adjust_meta(struct xdp_buff *xdp_md, int delta)
++ * 	Description
++ * 		Adjust the address pointed by *xdp_md*\ **->data_meta** by
++ * 		*delta* (which can be positive or negative). Note that this
++ * 		operation modifies the address stored in *xdp_md*\ **->data**,
++ * 		so the latter must be loaded only after the helper has been
++ * 		called.
++ *
++ * 		The use of *xdp_md*\ **->data_meta** is optional and programs
++ * 		are not required to use it. The rationale is that when the
++ * 		packet is processed with XDP (e.g. as DoS filter), it is
++ * 		possible to push further meta data along with it before passing
++ * 		to the stack, and to give the guarantee that an ingress eBPF
++ * 		program attached as a TC classifier on the same device can pick
++ * 		this up for further post-processing. Since TC works with socket
++ * 		buffers, it remains possible to set from XDP the **mark** or
++ * 		**priority** pointers, or other pointers for the socket buffer.
++ * 		Having this scratch space generic and programmable allows for
++ * 		more flexibility as the user is free to store whatever meta
++ * 		data they need.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_perf_event_read_value(struct bpf_map *map, u64 flags, struct bpf_perf_event_value *buf, u32 buf_size)
++ * 	Description
++ * 		Read the value of a perf event counter, and store it into *buf*
++ * 		of size *buf_size*. This helper relies on a *map* of type
++ * 		**BPF_MAP_TYPE_PERF_EVENT_ARRAY**. The nature of the perf event
++ * 		counter is selected when *map* is updated with perf event file
++ * 		descriptors. The *map* is an array whose size is the number of
++ * 		available CPUs, and each cell contains a value relative to one
++ * 		CPU. The value to retrieve is indicated by *flags*, that
++ * 		contains the index of the CPU to look up, masked with
++ * 		**BPF_F_INDEX_MASK**. Alternatively, *flags* can be set to
++ * 		**BPF_F_CURRENT_CPU** to indicate that the value for the
++ * 		current CPU should be retrieved.
++ *
++ * 		This helper behaves in a way close to
++ * 		**bpf_perf_event_read**\ () helper, save that instead of
++ * 		just returning the value observed, it fills the *buf*
++ * 		structure. This allows for additional data to be retrieved: in
++ * 		particular, the enabled and running times (in *buf*\
++ * 		**->enabled** and *buf*\ **->running**, respectively) are
++ * 		copied. In general, **bpf_perf_event_read_value**\ () is
++ * 		recommended over **bpf_perf_event_read**\ (), which has some
++ * 		ABI issues and provides fewer functionalities.
++ *
++ * 		These values are interesting, because hardware PMU (Performance
++ * 		Monitoring Unit) counters are limited resources. When there are
++ * 		more PMU based perf events opened than available counters,
++ * 		kernel will multiplex these events so each event gets certain
++ * 		percentage (but not all) of the PMU time. In case that
++ * 		multiplexing happens, the number of samples or counter value
++ * 		will not reflect the case compared to when no multiplexing
++ * 		occurs. This makes comparison between different runs difficult.
++ * 		Typically, the counter value should be normalized before
++ * 		comparing to other experiments. The usual normalization is done
++ * 		as follows.
++ *
++ * 		::
++ *
++ * 			normalized_counter = counter * t_enabled / t_running
++ *
++ * 		Where t_enabled is the time enabled for event and t_running is
++ * 		the time running for event since last normalization. The
++ * 		enabled and running times are accumulated since the perf event
++ * 		open. To achieve scaling factor between two invocations of an
++ * 		eBPF program, users can can use CPU id as the key (which is
++ * 		typical for perf array usage model) to remember the previous
++ * 		value and do the calculation inside the eBPF program.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_perf_prog_read_value(struct bpf_perf_event_data *ctx, struct bpf_perf_event_value *buf, u32 buf_size)
++ * 	Description
++ * 		For en eBPF program attached to a perf event, retrieve the
++ * 		value of the event counter associated to *ctx* and store it in
++ * 		the structure pointed by *buf* and of size *buf_size*. Enabled
++ * 		and running times are also stored in the structure (see
++ * 		description of helper **bpf_perf_event_read_value**\ () for
++ * 		more details).
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_getsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, char *optval, int optlen)
++ * 	Description
++ * 		Emulate a call to **getsockopt()** on the socket associated to
++ * 		*bpf_socket*, which must be a full socket. The *level* at
++ * 		which the option resides and the name *optname* of the option
++ * 		must be specified, see **getsockopt(2)** for more information.
++ * 		The retrieved value is stored in the structure pointed by
++ * 		*opval* and of length *optlen*.
++ *
++ * 		This helper actually implements a subset of **getsockopt()**.
++ * 		It supports the following *level*\ s:
++ *
++ * 		* **IPPROTO_TCP**, which supports *optname*
++ * 		  **TCP_CONGESTION**.
++ * 		* **IPPROTO_IP**, which supports *optname* **IP_TOS**.
++ * 		* **IPPROTO_IPV6**, which supports *optname* **IPV6_TCLASS**.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_override_return(struct pt_reg *regs, u64 rc)
++ * 	Description
++ * 		Used for error injection, this helper uses kprobes to override
++ * 		the return value of the probed function, and to set it to *rc*.
++ * 		The first argument is the context *regs* on which the kprobe
++ * 		works.
++ *
++ * 		This helper works by setting setting the PC (program counter)
++ * 		to an override function which is run in place of the original
++ * 		probed function. This means the probed function is not run at
++ * 		all. The replacement function just returns with the required
++ * 		value.
++ *
++ * 		This helper has security implications, and thus is subject to
++ * 		restrictions. It is only available if the kernel was compiled
++ * 		with the **CONFIG_BPF_KPROBE_OVERRIDE** configuration
++ * 		option, and in this case it only works on functions tagged with
++ * 		**ALLOW_ERROR_INJECTION** in the kernel code.
++ *
++ * 		Also, the helper is only available for the architectures having
++ * 		the CONFIG_FUNCTION_ERROR_INJECTION option. As of this writing,
++ * 		x86 architecture is the only one to support this feature.
++ * 	Return
++ * 		0
++ *
++ * int bpf_sock_ops_cb_flags_set(struct bpf_sock_ops *bpf_sock, int argval)
++ * 	Description
++ * 		Attempt to set the value of the **bpf_sock_ops_cb_flags** field
++ * 		for the full TCP socket associated to *bpf_sock_ops* to
++ * 		*argval*.
++ *
++ * 		The primary use of this field is to determine if there should
++ * 		be calls to eBPF programs of type
++ * 		**BPF_PROG_TYPE_SOCK_OPS** at various points in the TCP
++ * 		code. A program of the same type can change its value, per
++ * 		connection and as necessary, when the connection is
++ * 		established. This field is directly accessible for reading, but
++ * 		this helper must be used for updates in order to return an
++ * 		error if an eBPF program tries to set a callback that is not
++ * 		supported in the current kernel.
++ *
++ * 		The supported callback values that *argval* can combine are:
++ *
++ * 		* **BPF_SOCK_OPS_RTO_CB_FLAG** (retransmission time out)
++ * 		* **BPF_SOCK_OPS_RETRANS_CB_FLAG** (retransmission)
++ * 		* **BPF_SOCK_OPS_STATE_CB_FLAG** (TCP state change)
++ *
++ * 		Here are some examples of where one could call such eBPF
++ * 		program:
++ *
++ * 		* When RTO fires.
++ * 		* When a packet is retransmitted.
++ * 		* When the connection terminates.
++ * 		* When a packet is sent.
++ * 		* When a packet is received.
++ * 	Return
++ * 		Code **-EINVAL** if the socket is not a full TCP socket;
++ * 		otherwise, a positive number containing the bits that could not
++ * 		be set is returned (which comes down to 0 if all bits were set
++ * 		as required).
++ *
++ * int bpf_msg_redirect_map(struct sk_msg_buff *msg, struct bpf_map *map, u32 key, u64 flags)
++ * 	Description
++ * 		This helper is used in programs implementing policies at the
++ * 		socket level. If the message *msg* is allowed to pass (i.e. if
++ * 		the verdict eBPF program returns **SK_PASS**), redirect it to
++ * 		the socket referenced by *map* (of type
++ * 		**BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and
++ * 		egress interfaces can be used for redirection. The
++ * 		**BPF_F_INGRESS** value in *flags* is used to make the
++ * 		distinction (ingress path is selected if the flag is present,
++ * 		egress path otherwise). This is the only flag supported for now.
++ * 	Return
++ * 		**SK_PASS** on success, or **SK_DROP** on error.
++ *
++ * int bpf_msg_apply_bytes(struct sk_msg_buff *msg, u32 bytes)
++ * 	Description
++ * 		For socket policies, apply the verdict of the eBPF program to
++ * 		the next *bytes* (number of bytes) of message *msg*.
++ *
++ * 		For example, this helper can be used in the following cases:
++ *
++ * 		* A single **sendmsg**\ () or **sendfile**\ () system call
++ * 		  contains multiple logical messages that the eBPF program is
++ * 		  supposed to read and for which it should apply a verdict.
++ * 		* An eBPF program only cares to read the first *bytes* of a
++ * 		  *msg*. If the message has a large payload, then setting up
++ * 		  and calling the eBPF program repeatedly for all bytes, even
++ * 		  though the verdict is already known, would create unnecessary
++ * 		  overhead.
++ *
++ * 		When called from within an eBPF program, the helper sets a
++ * 		counter internal to the BPF infrastructure, that is used to
++ * 		apply the last verdict to the next *bytes*. If *bytes* is
++ * 		smaller than the current data being processed from a
++ * 		**sendmsg**\ () or **sendfile**\ () system call, the first
++ * 		*bytes* will be sent and the eBPF program will be re-run with
++ * 		the pointer for start of data pointing to byte number *bytes*
++ * 		**+ 1**. If *bytes* is larger than the current data being
++ * 		processed, then the eBPF verdict will be applied to multiple
++ * 		**sendmsg**\ () or **sendfile**\ () calls until *bytes* are
++ * 		consumed.
++ *
++ * 		Note that if a socket closes with the internal counter holding
++ * 		a non-zero value, this is not a problem because data is not
++ * 		being buffered for *bytes* and is sent as it is received.
++ * 	Return
++ * 		0
++ *
++ * int bpf_msg_cork_bytes(struct sk_msg_buff *msg, u32 bytes)
++ * 	Description
++ * 		For socket policies, prevent the execution of the verdict eBPF
++ * 		program for message *msg* until *bytes* (byte number) have been
++ * 		accumulated.
++ *
++ * 		This can be used when one needs a specific number of bytes
++ * 		before a verdict can be assigned, even if the data spans
++ * 		multiple **sendmsg**\ () or **sendfile**\ () calls. The extreme
++ * 		case would be a user calling **sendmsg**\ () repeatedly with
++ * 		1-byte long message segments. Obviously, this is bad for
++ * 		performance, but it is still valid. If the eBPF program needs
++ * 		*bytes* bytes to validate a header, this helper can be used to
++ * 		prevent the eBPF program to be called again until *bytes* have
++ * 		been accumulated.
++ * 	Return
++ * 		0
++ *
++ * int bpf_msg_pull_data(struct sk_msg_buff *msg, u32 start, u32 end, u64 flags)
++ * 	Description
++ * 		For socket policies, pull in non-linear data from user space
++ * 		for *msg* and set pointers *msg*\ **->data** and *msg*\
++ * 		**->data_end** to *start* and *end* bytes offsets into *msg*,
++ * 		respectively.
++ *
++ * 		If a program of type **BPF_PROG_TYPE_SK_MSG** is run on a
++ * 		*msg* it can only parse data that the (**data**, **data_end**)
++ * 		pointers have already consumed. For **sendmsg**\ () hooks this
++ * 		is likely the first scatterlist element. But for calls relying
++ * 		on the **sendpage** handler (e.g. **sendfile**\ ()) this will
++ * 		be the range (**0**, **0**) because the data is shared with
++ * 		user space and by default the objective is to avoid allowing
++ * 		user space to modify data while (or after) eBPF verdict is
++ * 		being decided. This helper can be used to pull in data and to
++ * 		set the start and end pointer to given values. Data will be
++ * 		copied if necessary (i.e. if data was not linear and if start
++ * 		and end pointers do not point to the same chunk).
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_bind(struct bpf_sock_addr *ctx, struct sockaddr *addr, int addr_len)
++ * 	Description
++ * 		Bind the socket associated to *ctx* to the address pointed by
++ * 		*addr*, of length *addr_len*. This allows for making outgoing
++ * 		connection from the desired IP address, which can be useful for
++ * 		example when all processes inside a cgroup should use one
++ * 		single IP address on a host that has multiple IP configured.
++ *
++ * 		This helper works for IPv4 and IPv6, TCP and UDP sockets. The
++ * 		domain (*addr*\ **->sa_family**) must be **AF_INET** (or
++ * 		**AF_INET6**). Looking for a free port to bind to can be
++ * 		expensive, therefore binding to port is not permitted by the
++ * 		helper: *addr*\ **->sin_port** (or **sin6_port**, respectively)
++ * 		must be set to zero.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_xdp_adjust_tail(struct xdp_buff *xdp_md, int delta)
++ * 	Description
++ * 		Adjust (move) *xdp_md*\ **->data_end** by *delta* bytes. It is
++ * 		only possible to shrink the packet as of this writing,
++ * 		therefore *delta* must be a negative integer.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_skb_get_xfrm_state(struct sk_buff *skb, u32 index, struct bpf_xfrm_state *xfrm_state, u32 size, u64 flags)
++ * 	Description
++ * 		Retrieve the XFRM state (IP transform framework, see also
++ * 		**ip-xfrm(8)**) at *index* in XFRM "security path" for *skb*.
++ *
++ * 		The retrieved value is stored in the **struct bpf_xfrm_state**
++ * 		pointed by *xfrm_state* and of length *size*.
++ *
++ * 		All values for *flags* are reserved for future usage, and must
++ * 		be left at zero.
++ *
++ * 		This helper is available only if the kernel was compiled with
++ * 		**CONFIG_XFRM** configuration option.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_get_stack(struct pt_regs *regs, void *buf, u32 size, u64 flags)
++ * 	Description
++ * 		Return a user or a kernel stack in bpf program provided buffer.
++ * 		To achieve this, the helper needs *ctx*, which is a pointer
++ * 		to the context on which the tracing program is executed.
++ * 		To store the stacktrace, the bpf program provides *buf* with
++ * 		a nonnegative *size*.
++ *
++ * 		The last argument, *flags*, holds the number of stack frames to
++ * 		skip (from 0 to 255), masked with
++ * 		**BPF_F_SKIP_FIELD_MASK**. The next bits can be used to set
++ * 		the following flags:
++ *
++ * 		**BPF_F_USER_STACK**
++ * 			Collect a user space stack instead of a kernel stack.
++ * 		**BPF_F_USER_BUILD_ID**
++ * 			Collect buildid+offset instead of ips for user stack,
++ * 			only valid if **BPF_F_USER_STACK** is also specified.
++ *
++ * 		**bpf_get_stack**\ () can collect up to
++ * 		**PERF_MAX_STACK_DEPTH** both kernel and user frames, subject
++ * 		to sufficient large buffer size. Note that
++ * 		this limit can be controlled with the **sysctl** program, and
++ * 		that it should be manually increased in order to profile long
++ * 		user stacks (such as stacks for Java programs). To do so, use:
++ *
++ * 		::
++ *
++ * 			# sysctl kernel.perf_event_max_stack=<new value>
++ * 	Return
++ * 		A non-negative value equal to or less than *size* on success,
++ * 		or a negative error in case of failure.
++ *
++ * int bpf_skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header)
++ * 	Description
++ * 		This helper is similar to **bpf_skb_load_bytes**\ () in that
++ * 		it provides an easy way to load *len* bytes from *offset*
++ * 		from the packet associated to *skb*, into the buffer pointed
++ * 		by *to*. The difference to **bpf_skb_load_bytes**\ () is that
++ * 		a fifth argument *start_header* exists in order to select a
++ * 		base offset to start from. *start_header* can be one of:
++ *
++ * 		**BPF_HDR_START_MAC**
++ * 			Base offset to load data from is *skb*'s mac header.
++ * 		**BPF_HDR_START_NET**
++ * 			Base offset to load data from is *skb*'s network header.
++ *
++ * 		In general, "direct packet access" is the preferred method to
++ * 		access packet data, however, this helper is in particular useful
++ * 		in socket filters where *skb*\ **->data** does not always point
++ * 		to the start of the mac header and where "direct packet access"
++ * 		is not available.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_fib_lookup(void *ctx, struct bpf_fib_lookup *params, int plen, u32 flags)
++ *	Description
++ *		Do FIB lookup in kernel tables using parameters in *params*.
++ *		If lookup is successful and result shows packet is to be
++ *		forwarded, the neighbor tables are searched for the nexthop.
++ *		If successful (ie., FIB lookup shows forwarding and nexthop
++ *		is resolved), the nexthop address is returned in ipv4_dst
++ *		or ipv6_dst based on family, smac is set to mac address of
++ *		egress device, dmac is set to nexthop mac address, rt_metric
++ *		is set to metric from route (IPv4/IPv6 only), and ifindex
++ *		is set to the device index of the nexthop from the FIB lookup.
++ *
++ *		*plen* argument is the size of the passed in struct.
++ *		*flags* argument can be a combination of one or more of the
++ *		following values:
++ *
++ *		**BPF_FIB_LOOKUP_DIRECT**
++ *			Do a direct table lookup vs full lookup using FIB
++ *			rules.
++ *		**BPF_FIB_LOOKUP_OUTPUT**
++ *			Perform lookup from an egress perspective (default is
++ *			ingress).
++ *
++ *		*ctx* is either **struct xdp_md** for XDP programs or
++ *		**struct sk_buff** tc cls_act programs.
++ *	Return
++ *		* < 0 if any input argument is invalid
++ *		*   0 on success (packet is forwarded, nexthop neighbor exists)
++ *		* > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
++ *		  packet is not forwarded or needs assist from full stack
++ *
++ * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
++ *	Description
++ *		Add an entry to, or update a sockhash *map* referencing sockets.
++ *		The *skops* is used as a new value for the entry associated to
++ *		*key*. *flags* is one of:
++ *
++ *		**BPF_NOEXIST**
++ *			The entry for *key* must not exist in the map.
++ *		**BPF_EXIST**
++ *			The entry for *key* must already exist in the map.
++ *		**BPF_ANY**
++ *			No condition on the existence of the entry for *key*.
++ *
++ *		If the *map* has eBPF programs (parser and verdict), those will
++ *		be inherited by the socket being added. If the socket is
++ *		already attached to eBPF programs, this results in an error.
++ *	Return
++ *		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_msg_redirect_hash(struct sk_msg_buff *msg, struct bpf_map *map, void *key, u64 flags)
++ *	Description
++ *		This helper is used in programs implementing policies at the
++ *		socket level. If the message *msg* is allowed to pass (i.e. if
++ *		the verdict eBPF program returns **SK_PASS**), redirect it to
++ *		the socket referenced by *map* (of type
++ *		**BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and
++ *		egress interfaces can be used for redirection. The
++ *		**BPF_F_INGRESS** value in *flags* is used to make the
++ *		distinction (ingress path is selected if the flag is present,
++ *		egress path otherwise). This is the only flag supported for now.
++ *	Return
++ *		**SK_PASS** on success, or **SK_DROP** on error.
++ *
++ * int bpf_sk_redirect_hash(struct sk_buff *skb, struct bpf_map *map, void *key, u64 flags)
++ *	Description
++ *		This helper is used in programs implementing policies at the
++ *		skb socket level. If the sk_buff *skb* is allowed to pass (i.e.
++ *		if the verdeict eBPF program returns **SK_PASS**), redirect it
++ *		to the socket referenced by *map* (of type
++ *		**BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and
++ *		egress interfaces can be used for redirection. The
++ *		**BPF_F_INGRESS** value in *flags* is used to make the
++ *		distinction (ingress path is selected if the flag is present,
++ *		egress otherwise). This is the only flag supported for now.
++ *	Return
++ *		**SK_PASS** on success, or **SK_DROP** on error.
++ *
++ * int bpf_lwt_push_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len)
++ *	Description
++ *		Encapsulate the packet associated to *skb* within a Layer 3
++ *		protocol header. This header is provided in the buffer at
++ *		address *hdr*, with *len* its size in bytes. *type* indicates
++ *		the protocol of the header and can be one of:
++ *
++ *		**BPF_LWT_ENCAP_SEG6**
++ *			IPv6 encapsulation with Segment Routing Header
++ *			(**struct ipv6_sr_hdr**). *hdr* only contains the SRH,
++ *			the IPv6 header is computed by the kernel.
++ *		**BPF_LWT_ENCAP_SEG6_INLINE**
++ *			Only works if *skb* contains an IPv6 packet. Insert a
++ *			Segment Routing Header (**struct ipv6_sr_hdr**) inside
++ *			the IPv6 header.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ *	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_lwt_seg6_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len)
++ *	Description
++ *		Store *len* bytes from address *from* into the packet
++ *		associated to *skb*, at *offset*. Only the flags, tag and TLVs
++ *		inside the outermost IPv6 Segment Routing Header can be
++ *		modified through this helper.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ *	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_lwt_seg6_adjust_srh(struct sk_buff *skb, u32 offset, s32 delta)
++ *	Description
++ *		Adjust the size allocated to TLVs in the outermost IPv6
++ *		Segment Routing Header contained in the packet associated to
++ *		*skb*, at position *offset* by *delta* bytes. Only offsets
++ *		after the segments are accepted. *delta* can be as well
++ *		positive (growing) as negative (shrinking).
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ *	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_lwt_seg6_action(struct sk_buff *skb, u32 action, void *param, u32 param_len)
++ *	Description
++ *		Apply an IPv6 Segment Routing action of type *action* to the
++ *		packet associated to *skb*. Each action takes a parameter
++ *		contained at address *param*, and of length *param_len* bytes.
++ *		*action* can be one of:
++ *
++ *		**SEG6_LOCAL_ACTION_END_X**
++ *			End.X action: Endpoint with Layer-3 cross-connect.
++ *			Type of *param*: **struct in6_addr**.
++ *		**SEG6_LOCAL_ACTION_END_T**
++ *			End.T action: Endpoint with specific IPv6 table lookup.
++ *			Type of *param*: **int**.
++ *		**SEG6_LOCAL_ACTION_END_B6**
++ *			End.B6 action: Endpoint bound to an SRv6 policy.
++ *			Type of param: **struct ipv6_sr_hdr**.
++ *		**SEG6_LOCAL_ACTION_END_B6_ENCAP**
++ *			End.B6.Encap action: Endpoint bound to an SRv6
++ *			encapsulation policy.
++ *			Type of param: **struct ipv6_sr_hdr**.
++ *
++ * 		A call to this helper is susceptible to change the underlaying
++ * 		packet buffer. Therefore, at load time, all checks on pointers
++ * 		previously done by the verifier are invalidated and must be
++ * 		performed again, if the helper is used in combination with
++ * 		direct packet access.
++ *	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_rc_keydown(void *ctx, u32 protocol, u64 scancode, u32 toggle)
++ *	Description
++ *		This helper is used in programs implementing IR decoding, to
++ *		report a successfully decoded key press with *scancode*,
++ *		*toggle* value in the given *protocol*. The scancode will be
++ *		translated to a keycode using the rc keymap, and reported as
++ *		an input key down event. After a period a key up event is
++ *		generated. This period can be extended by calling either
++ *		**bpf_rc_keydown**\ () again with the same values, or calling
++ *		**bpf_rc_repeat**\ ().
++ *
++ *		Some protocols include a toggle bit, in case the button	was
++ *		released and pressed again between consecutive scancodes.
++ *
++ *		The *ctx* should point to the lirc sample as passed into
++ *		the program.
++ *
++ *		The *protocol* is the decoded protocol number (see
++ *		**enum rc_proto** for some predefined values).
++ *
++ *		This helper is only available is the kernel was compiled with
++ *		the **CONFIG_BPF_LIRC_MODE2** configuration option set to
++ *		"**y**".
++ *	Return
++ *		0
++ *
++ * int bpf_rc_repeat(void *ctx)
++ *	Description
++ *		This helper is used in programs implementing IR decoding, to
++ *		report a successfully decoded repeat key message. This delays
++ *		the generation of a key up event for previously generated
++ *		key down event.
++ *
++ *		Some IR protocols like NEC have a special IR message for
++ *		repeating last button, for when a button is held down.
++ *
++ *		The *ctx* should point to the lirc sample as passed into
++ *		the program.
++ *
++ *		This helper is only available is the kernel was compiled with
++ *		the **CONFIG_BPF_LIRC_MODE2** configuration option set to
++ *		"**y**".
++ *	Return
++ *		0
++ *
++ * 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,
++ * 		and is available only if the kernel was compiled with the
++ * 		**CONFIG_SOCK_CGROUP_DATA** configuration option.
++ * 	Return
++ * 		The id is returned or 0 in case the id could not be retrieved.
++ *
++ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
++ *	Description
++ *		Return id of cgroup v2 that is ancestor of cgroup associated
++ *		with the *skb* at the *ancestor_level*.  The root cgroup is at
++ *		*ancestor_level* zero and each step down the hierarchy
++ *		increments the level. If *ancestor_level* == level of cgroup
++ *		associated with *skb*, then return value will be same as that
++ *		of **bpf_skb_cgroup_id**\ ().
++ *
++ *		The helper is useful to implement policies based on cgroups
++ *		that are upper in hierarchy than immediate cgroup associated
++ *		with *skb*.
++ *
++ *		The format of returned id and helper limitations are same as in
++ *		**bpf_skb_cgroup_id**\ ().
++ *	Return
++ *		The id is returned or 0 in case the id could not be retrieved.
++ *
++ * u64 bpf_get_current_cgroup_id(void)
++ * 	Return
++ * 		A 64-bit integer containing the current cgroup id based
++ * 		on the cgroup within which the current task is running.
++ *
++ * void* get_local_storage(void *map, u64 flags)
++ *	Description
++ *		Get the pointer to the local storage area.
++ *		The type and the size of the local storage is defined
++ *		by the *map* argument.
++ *		The *flags* meaning is specific for each map type,
++ *		and has to be 0 for cgroup local storage.
++ *
++ *		Depending on the BPF program type, a local storage area
++ *		can be shared between multiple instances of the BPF program,
++ *		running simultaneously.
++ *
++ *		A user should care about the synchronization by himself.
++ *		For example, by using the **BPF_STX_XADD** instruction to alter
++ *		the shared data.
++ *	Return
++ *		A pointer to the local storage area.
++ *
++ * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
++ *	Description
++ *		Select a **SO_REUSEPORT** socket from a
++ *		**BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*.
++ *		It checks the selected socket is matching the incoming
++ *		request in the socket buffer.
++ *	Return
++ *		0 on success, or a negative error in case of failure.
++ *
++ * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
++ *	Description
++ *		Look for TCP socket matching *tuple*, optionally in a child
++ *		network namespace *netns*. The return value must be checked,
++ *		and if non-**NULL**, released via **bpf_sk_release**\ ().
++ *
++ *		The *ctx* should point to the context of the program, such as
++ *		the skb or socket (depending on the hook in use). This is used
++ *		to determine the base network namespace for the lookup.
++ *
++ *		*tuple_size* must be one of:
++ *
++ *		**sizeof**\ (*tuple*\ **->ipv4**)
++ *			Look for an IPv4 socket.
++ *		**sizeof**\ (*tuple*\ **->ipv6**)
++ *			Look for an IPv6 socket.
++ *
++ *		If the *netns* is a negative signed 32-bit integer, then the
++ *		socket lookup table in the netns associated with the *ctx* will
++ *		will be used. For the TC hooks, this is the netns of the device
++ *		in the skb. For socket hooks, this is the netns of the socket.
++ *		If *netns* is any other signed 32-bit value greater than or
++ *		equal to zero then it specifies the ID of the netns relative to
++ *		the netns associated with the *ctx*. *netns* values beyond the
++ *		range of 32-bit integers are reserved for future use.
++ *
++ *		All values for *flags* are reserved for future usage, and must
++ *		be left at zero.
++ *
++ *		This helper is available only if the kernel was compiled with
++ *		**CONFIG_NET** configuration option.
++ *	Return
++ *		Pointer to **struct bpf_sock**, or **NULL** in case of failure.
++ *		For sockets with reuseport option, the **struct bpf_sock**
++ *		result is from **reuse->socks**\ [] using the hash of the tuple.
++ *
++ * struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
++ *	Description
++ *		Look for UDP socket matching *tuple*, optionally in a child
++ *		network namespace *netns*. The return value must be checked,
++ *		and if non-**NULL**, released via **bpf_sk_release**\ ().
++ *
++ *		The *ctx* should point to the context of the program, such as
++ *		the skb or socket (depending on the hook in use). This is used
++ *		to determine the base network namespace for the lookup.
++ *
++ *		*tuple_size* must be one of:
++ *
++ *		**sizeof**\ (*tuple*\ **->ipv4**)
++ *			Look for an IPv4 socket.
++ *		**sizeof**\ (*tuple*\ **->ipv6**)
++ *			Look for an IPv6 socket.
++ *
++ *		If the *netns* is a negative signed 32-bit integer, then the
++ *		socket lookup table in the netns associated with the *ctx* will
++ *		will be used. For the TC hooks, this is the netns of the device
++ *		in the skb. For socket hooks, this is the netns of the socket.
++ *		If *netns* is any other signed 32-bit value greater than or
++ *		equal to zero then it specifies the ID of the netns relative to
++ *		the netns associated with the *ctx*. *netns* values beyond the
++ *		range of 32-bit integers are reserved for future use.
++ *
++ *		All values for *flags* are reserved for future usage, and must
++ *		be left at zero.
++ *
++ *		This helper is available only if the kernel was compiled with
++ *		**CONFIG_NET** configuration option.
++ *	Return
++ *		Pointer to **struct bpf_sock**, or **NULL** in case of failure.
++ *		For sockets with reuseport option, the **struct bpf_sock**
++ *		result is from **reuse->socks**\ [] using the hash of the tuple.
++ *
++ * int bpf_sk_release(struct bpf_sock *sock)
++ *	Description
++ *		Release the reference held by *sock*. *sock* must be a
++ *		non-**NULL** pointer that was returned from
++ *		**bpf_sk_lookup_xxx**\ ().
++ *	Return
++ *		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_map_pop_elem(struct bpf_map *map, void *value)
++ * 	Description
++ * 		Pop an element from *map*.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_map_peek_elem(struct bpf_map *map, void *value)
++ * 	Description
++ * 		Get an element from *map* without removing it.
++ * 	Return
++ * 		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_msg_push_data(struct sk_buff *skb, u32 start, u32 len, u64 flags)
++ *	Description
++ *		For socket policies, insert *len* bytes into *msg* at offset
++ *		*start*.
++ *
++ *		If a program of type **BPF_PROG_TYPE_SK_MSG** is run on a
++ *		*msg* it may want to insert metadata or options into the *msg*.
++ *		This can later be read and used by any of the lower layer BPF
++ *		hooks.
++ *
++ *		This helper may fail if under memory pressure (a malloc
++ *		fails) in these cases BPF programs will get an appropriate
++ *		error and BPF programs will need to handle them.
++ *	Return
++ *		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_msg_pop_data(struct sk_msg_buff *msg, u32 start, u32 pop, u64 flags)
++ *	Description
++ *		Will remove *pop* bytes from a *msg* starting at byte *start*.
++ *		This may result in **ENOMEM** errors under certain situations if
++ *		an allocation and copy are required due to a full ring buffer.
++ *		However, the helper will try to avoid doing the allocation
++ *		if possible. Other errors can occur if input parameters are
++ *		invalid either due to *start* byte not being valid part of *msg*
++ *		payload and/or *pop* value being to large.
++ *	Return
++ *		0 on success, or a negative error in case of failure.
++ *
++ * int bpf_rc_pointer_rel(void *ctx, s32 rel_x, s32 rel_y)
++ *	Description
++ *		This helper is used in programs implementing IR decoding, to
++ *		report a successfully decoded pointer movement.
++ *
++ *		The *ctx* should point to the lirc sample as passed into
++ *		the program.
++ *
++ *		This helper is only available is the kernel was compiled with
++ *		the **CONFIG_BPF_LIRC_MODE2** configuration option set to
++ *		"**y**".
++ *	Return
++ *		0
+  */
+ #define __BPF_FUNC_MAPPER(FN)		\
+-        FN(unspec),			\
+-        FN(map_lookup_elem),		\
+-        FN(map_update_elem),		\
+-        FN(map_delete_elem),		\
+-        FN(probe_read),			\
+-        FN(ktime_get_ns),		\
+-        FN(trace_printk),		\
+-        FN(get_prandom_u32),		\
+-        FN(get_smp_processor_id),	\
+-        FN(skb_store_bytes),		\
+-        FN(l3_csum_replace),		\
+-        FN(l4_csum_replace),		\
+-        FN(tail_call),			\
+-        FN(clone_redirect),		\
+-        FN(get_current_pid_tgid),	\
+-        FN(get_current_uid_gid),	\
+-        FN(get_current_comm),		\
+-        FN(get_cgroup_classid),		\
+-        FN(skb_vlan_push),		\
+-        FN(skb_vlan_pop),		\
+-        FN(skb_get_tunnel_key),		\
+-        FN(skb_set_tunnel_key),		\
+-        FN(perf_event_read),		\
+-        FN(redirect),			\
+-        FN(get_route_realm),		\
+-        FN(perf_event_output),		\
+-        FN(skb_load_bytes),		\
+-        FN(get_stackid),		\
+-        FN(csum_diff),			\
+-        FN(skb_get_tunnel_opt),		\
+-        FN(skb_set_tunnel_opt),		\
+-        FN(skb_change_proto),		\
+-        FN(skb_change_type),		\
+-        FN(skb_under_cgroup),		\
+-        FN(get_hash_recalc),		\
+-        FN(get_current_task),		\
+-        FN(probe_write_user),		\
+-        FN(current_task_under_cgroup),	\
+-        FN(skb_change_tail),		\
+-        FN(skb_pull_data),		\
+-        FN(csum_update),		\
+-        FN(set_hash_invalid),		\
+-        FN(get_numa_node_id),		\
+-        FN(skb_change_head),		\
+-        FN(xdp_adjust_head),		\
+-        FN(probe_read_str),		\
+-        FN(get_socket_cookie),		\
+-        FN(get_socket_uid),		\
+-        FN(set_hash),			\
+-        FN(setsockopt),			\
+-        FN(skb_adjust_room),		\
+-        FN(redirect_map),		\
+-        FN(sk_redirect_map),		\
+-        FN(sock_map_update),		\
+-        FN(xdp_adjust_meta),		\
+-        FN(perf_event_read_value),	\
+-        FN(perf_prog_read_value),	\
+-        FN(getsockopt),			\
+-        FN(override_return),		\
+-        FN(sock_ops_cb_flags_set),
++	FN(unspec),			\
++	FN(map_lookup_elem),		\
++	FN(map_update_elem),		\
++	FN(map_delete_elem),		\
++	FN(probe_read),			\
++	FN(ktime_get_ns),		\
++	FN(trace_printk),		\
++	FN(get_prandom_u32),		\
++	FN(get_smp_processor_id),	\
++	FN(skb_store_bytes),		\
++	FN(l3_csum_replace),		\
++	FN(l4_csum_replace),		\
++	FN(tail_call),			\
++	FN(clone_redirect),		\
++	FN(get_current_pid_tgid),	\
++	FN(get_current_uid_gid),	\
++	FN(get_current_comm),		\
++	FN(get_cgroup_classid),		\
++	FN(skb_vlan_push),		\
++	FN(skb_vlan_pop),		\
++	FN(skb_get_tunnel_key),		\
++	FN(skb_set_tunnel_key),		\
++	FN(perf_event_read),		\
++	FN(redirect),			\
++	FN(get_route_realm),		\
++	FN(perf_event_output),		\
++	FN(skb_load_bytes),		\
++	FN(get_stackid),		\
++	FN(csum_diff),			\
++	FN(skb_get_tunnel_opt),		\
++	FN(skb_set_tunnel_opt),		\
++	FN(skb_change_proto),		\
++	FN(skb_change_type),		\
++	FN(skb_under_cgroup),		\
++	FN(get_hash_recalc),		\
++	FN(get_current_task),		\
++	FN(probe_write_user),		\
++	FN(current_task_under_cgroup),	\
++	FN(skb_change_tail),		\
++	FN(skb_pull_data),		\
++	FN(csum_update),		\
++	FN(set_hash_invalid),		\
++	FN(get_numa_node_id),		\
++	FN(skb_change_head),		\
++	FN(xdp_adjust_head),		\
++	FN(probe_read_str),		\
++	FN(get_socket_cookie),		\
++	FN(get_socket_uid),		\
++	FN(set_hash),			\
++	FN(setsockopt),			\
++	FN(skb_adjust_room),		\
++	FN(redirect_map),		\
++	FN(sk_redirect_map),		\
++	FN(sock_map_update),		\
++	FN(xdp_adjust_meta),		\
++	FN(perf_event_read_value),	\
++	FN(perf_prog_read_value),	\
++	FN(getsockopt),			\
++	FN(override_return),		\
++	FN(sock_ops_cb_flags_set),	\
++	FN(msg_redirect_map),		\
++	FN(msg_apply_bytes),		\
++	FN(msg_cork_bytes),		\
++	FN(msg_pull_data),		\
++	FN(bind),			\
++	FN(xdp_adjust_tail),		\
++	FN(skb_get_xfrm_state),		\
++	FN(get_stack),			\
++	FN(skb_load_bytes_relative),	\
++	FN(fib_lookup),			\
++	FN(sock_hash_update),		\
++	FN(msg_redirect_hash),		\
++	FN(sk_redirect_hash),		\
++	FN(lwt_push_encap),		\
++	FN(lwt_seg6_store_bytes),	\
++	FN(lwt_seg6_adjust_srh),	\
++	FN(lwt_seg6_action),		\
++	FN(rc_repeat),			\
++	FN(rc_keydown),			\
++	FN(skb_cgroup_id),		\
++	FN(get_current_cgroup_id),	\
++	FN(get_local_storage),		\
++	FN(sk_select_reuseport),	\
++	FN(skb_ancestor_cgroup_id),	\
++	FN(sk_lookup_tcp),		\
++	FN(sk_lookup_udp),		\
++	FN(sk_release),			\
++	FN(map_push_elem),		\
++	FN(map_pop_elem),		\
++	FN(map_peek_elem),		\
++	FN(msg_push_data),		\
++	FN(msg_pop_data),		\
++	FN(rc_pointer_rel),
+ 
+ /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+  * function eBPF program intends to call
+  */
+ #define __BPF_ENUM_FN(x) BPF_FUNC_ ## x
+ enum bpf_func_id {
+-        __BPF_FUNC_MAPPER(__BPF_ENUM_FN)
+-        __BPF_FUNC_MAX_ID,
++	__BPF_FUNC_MAPPER(__BPF_ENUM_FN)
++	__BPF_FUNC_MAX_ID,
+ };
+ #undef __BPF_ENUM_FN
+ 
+@@ -791,15 +2455,19 @@ enum bpf_func_id {
+ /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
+ #define BPF_F_TUNINFO_IPV6		(1ULL << 0)
+ 
+-/* BPF_FUNC_get_stackid flags. */
++/* flags for both BPF_FUNC_get_stackid and BPF_FUNC_get_stack. */
+ #define BPF_F_SKIP_FIELD_MASK		0xffULL
+ #define BPF_F_USER_STACK		(1ULL << 8)
++/* flags used by BPF_FUNC_get_stackid only. */
+ #define BPF_F_FAST_STACK_CMP		(1ULL << 9)
+ #define BPF_F_REUSE_STACKID		(1ULL << 10)
++/* flags used by BPF_FUNC_get_stack only. */
++#define BPF_F_USER_BUILD_ID		(1ULL << 11)
+ 
+ /* BPF_FUNC_skb_set_tunnel_key flags. */
+ #define BPF_F_ZERO_CSUM_TX		(1ULL << 1)
+ #define BPF_F_DONT_FRAGMENT		(1ULL << 2)
++#define BPF_F_SEQ_NUMBER		(1ULL << 3)
+ 
+ /* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
+  * BPF_FUNC_perf_event_read_value flags.
+@@ -809,57 +2477,95 @@ enum bpf_func_id {
+ /* BPF_FUNC_perf_event_output for sk_buff input context. */
+ #define BPF_F_CTXLEN_MASK		(0xfffffULL << 32)
+ 
++/* Current network namespace */
++#define BPF_F_CURRENT_NETNS		(-1L)
++
+ /* Mode for BPF_FUNC_skb_adjust_room helper. */
+ enum bpf_adj_room_mode {
+-        BPF_ADJ_ROOM_NET,
++	BPF_ADJ_ROOM_NET,
++};
++
++/* Mode for BPF_FUNC_skb_load_bytes_relative helper. */
++enum bpf_hdr_start_off {
++	BPF_HDR_START_MAC,
++	BPF_HDR_START_NET,
+ };
+ 
++/* Encapsulation type for BPF_FUNC_lwt_push_encap helper. */
++enum bpf_lwt_encap_mode {
++	BPF_LWT_ENCAP_SEG6,
++	BPF_LWT_ENCAP_SEG6_INLINE
++};
++
++#define __bpf_md_ptr(type, name)	\
++union {					\
++	type name;			\
++	__u64 :64;			\
++} __attribute__((aligned(8)))
++
+ /* user accessible mirror of in-kernel sk_buff.
+  * new fields can only be added to the end of this structure
+  */
+ struct __sk_buff {
+-        __u32 len;
+-        __u32 pkt_type;
+-        __u32 mark;
+-        __u32 queue_mapping;
+-        __u32 protocol;
+-        __u32 vlan_present;
+-        __u32 vlan_tci;
+-        __u32 vlan_proto;
+-        __u32 priority;
+-        __u32 ingress_ifindex;
+-        __u32 ifindex;
+-        __u32 tc_index;
+-        __u32 cb[5];
+-        __u32 hash;
+-        __u32 tc_classid;
+-        __u32 data;
+-        __u32 data_end;
+-        __u32 napi_id;
+-
+-        /* Accessed by BPF_PROG_TYPE_sk_skb types from here to ... */
+-        __u32 family;
+-        __u32 remote_ip4;	/* Stored in network byte order */
+-        __u32 local_ip4;	/* Stored in network byte order */
+-        __u32 remote_ip6[4];	/* Stored in network byte order */
+-        __u32 local_ip6[4];	/* Stored in network byte order */
+-        __u32 remote_port;	/* Stored in network byte order */
+-        __u32 local_port;	/* stored in host byte order */
+-        /* ... here. */
+-
+-        __u32 data_meta;
++	__u32 len;
++	__u32 pkt_type;
++	__u32 mark;
++	__u32 queue_mapping;
++	__u32 protocol;
++	__u32 vlan_present;
++	__u32 vlan_tci;
++	__u32 vlan_proto;
++	__u32 priority;
++	__u32 ingress_ifindex;
++	__u32 ifindex;
++	__u32 tc_index;
++	__u32 cb[5];
++	__u32 hash;
++	__u32 tc_classid;
++	__u32 data;
++	__u32 data_end;
++	__u32 napi_id;
++
++	/* Accessed by BPF_PROG_TYPE_sk_skb types from here to ... */
++	__u32 family;
++	__u32 remote_ip4;	/* Stored in network byte order */
++	__u32 local_ip4;	/* Stored in network byte order */
++	__u32 remote_ip6[4];	/* Stored in network byte order */
++	__u32 local_ip6[4];	/* Stored in network byte order */
++	__u32 remote_port;	/* Stored in network byte order */
++	__u32 local_port;	/* stored in host byte order */
++	/* ... here. */
++
++	__u32 data_meta;
++	__bpf_md_ptr(struct bpf_flow_keys *, flow_keys);
++	__u64 tstamp;
++	__u32 wire_len;
+ };
+ 
+ struct bpf_tunnel_key {
+-        __u32 tunnel_id;
+-        union {
+-                __u32 remote_ipv4;
+-                __u32 remote_ipv6[4];
+-        };
+-        __u8 tunnel_tos;
+-        __u8 tunnel_ttl;
+-        __u16 tunnel_ext;
+-        __u32 tunnel_label;
++	__u32 tunnel_id;
++	union {
++		__u32 remote_ipv4;
++		__u32 remote_ipv6[4];
++	};
++	__u8 tunnel_tos;
++	__u8 tunnel_ttl;
++	__u16 tunnel_ext;	/* Padding, future use. */
++	__u32 tunnel_label;
++};
++
++/* user accessible mirror of in-kernel xfrm_state.
++ * new fields can only be added to the end of this structure
++ */
++struct bpf_xfrm_state {
++	__u32 reqid;
++	__u32 spi;	/* Stored in network byte order */
++	__u16 family;
++	__u16 ext;	/* Padding, future use. */
++	union {
++		__u32 remote_ipv4;	/* Stored in network byte order */
++		__u32 remote_ipv6[4];	/* Stored in network byte order */
++	};
+ };
+ 
+ /* Generic BPF return codes which all BPF program types may support.
+@@ -870,21 +2576,47 @@ struct bpf_tunnel_key {
+  * XDP is handled seprately, see XDP_*.
+  */
+ enum bpf_ret_code {
+-        BPF_OK = 0,
+-        /* 1 reserved */
+-        BPF_DROP = 2,
+-        /* 3-6 reserved */
+-        BPF_REDIRECT = 7,
+-        /* >127 are reserved for prog type specific return codes */
++	BPF_OK = 0,
++	/* 1 reserved */
++	BPF_DROP = 2,
++	/* 3-6 reserved */
++	BPF_REDIRECT = 7,
++	/* >127 are reserved for prog type specific return codes */
+ };
+ 
+ struct bpf_sock {
+-        __u32 bound_dev_if;
+-        __u32 family;
+-        __u32 type;
+-        __u32 protocol;
+-        __u32 mark;
+-        __u32 priority;
++	__u32 bound_dev_if;
++	__u32 family;
++	__u32 type;
++	__u32 protocol;
++	__u32 mark;
++	__u32 priority;
++	__u32 src_ip4;		/* Allows 1,2,4-byte read.
++				 * Stored in network byte order.
++				 */
++	__u32 src_ip6[4];	/* Allows 1,2,4-byte read.
++				 * Stored in network byte order.
++				 */
++	__u32 src_port;		/* Allows 4-byte read.
++				 * Stored in host byte order
++				 */
++};
++
++struct bpf_sock_tuple {
++	union {
++		struct {
++			__be32 saddr;
++			__be32 daddr;
++			__be16 sport;
++			__be16 dport;
++		} ipv4;
++		struct {
++			__be32 saddr[4];
++			__be32 daddr[4];
++			__be16 sport;
++			__be16 dport;
++		} ipv6;
++	};
+ };
+ 
+ #define XDP_PACKET_HEADROOM 256
+@@ -895,63 +2627,158 @@ struct bpf_sock {
+  * result in packet drops and a warning via bpf_warn_invalid_xdp_action().
+  */
+ enum xdp_action {
+-        XDP_ABORTED = 0,
+-        XDP_DROP,
+-        XDP_PASS,
+-        XDP_TX,
+-        XDP_REDIRECT,
++	XDP_ABORTED = 0,
++	XDP_DROP,
++	XDP_PASS,
++	XDP_TX,
++	XDP_REDIRECT,
+ };
+ 
+ /* user accessible metadata for XDP packet hook
+  * new fields must be added to the end of this structure
+  */
+ struct xdp_md {
+-        __u32 data;
+-        __u32 data_end;
+-        __u32 data_meta;
+-        /* Below access go through struct xdp_rxq_info */
+-        __u32 ingress_ifindex; /* rxq->dev->ifindex */
+-        __u32 rx_queue_index;  /* rxq->queue_index  */
++	__u32 data;
++	__u32 data_end;
++	__u32 data_meta;
++	/* Below access go through struct xdp_rxq_info */
++	__u32 ingress_ifindex; /* rxq->dev->ifindex */
++	__u32 rx_queue_index;  /* rxq->queue_index  */
+ };
+ 
+ enum sk_action {
+-        SK_DROP = 0,
+-        SK_PASS,
++	SK_DROP = 0,
++	SK_PASS,
++};
++
++/* user accessible metadata for SK_MSG packet hook, new fields must
++ * be added to the end of this structure
++ */
++struct sk_msg_md {
++	__bpf_md_ptr(void *, data);
++	__bpf_md_ptr(void *, data_end);
++
++	__u32 family;
++	__u32 remote_ip4;	/* Stored in network byte order */
++	__u32 local_ip4;	/* Stored in network byte order */
++	__u32 remote_ip6[4];	/* Stored in network byte order */
++	__u32 local_ip6[4];	/* Stored in network byte order */
++	__u32 remote_port;	/* Stored in network byte order */
++	__u32 local_port;	/* stored in host byte order */
++	__u32 size;		/* Total size of sk_msg */
++};
++
++struct sk_reuseport_md {
++	/*
++	 * Start of directly accessible data. It begins from
++	 * the tcp/udp header.
++	 */
++	__bpf_md_ptr(void *, data);
++	/* End of directly accessible data */
++	__bpf_md_ptr(void *, data_end);
++	/*
++	 * Total length of packet (starting from the tcp/udp header).
++	 * Note that the directly accessible bytes (data_end - data)
++	 * could be less than this "len".  Those bytes could be
++	 * indirectly read by a helper "bpf_skb_load_bytes()".
++	 */
++	__u32 len;
++	/*
++	 * Eth protocol in the mac header (network byte order). e.g.
++	 * ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD)
++	 */
++	__u32 eth_protocol;
++	__u32 ip_protocol;	/* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */
++	__u32 bind_inany;	/* Is sock bound to an INANY address? */
++	__u32 hash;		/* A hash of the packet 4 tuples */
+ };
+ 
+ #define BPF_TAG_SIZE	8
+ 
+ struct bpf_prog_info {
+-        __u32 type;
+-        __u32 id;
+-        __u8  tag[BPF_TAG_SIZE];
+-        __u32 jited_prog_len;
+-        __u32 xlated_prog_len;
+-        __aligned_u64 jited_prog_insns;
+-        __aligned_u64 xlated_prog_insns;
+-        __u64 load_time;	/* ns since boottime */
+-        __u32 created_by_uid;
+-        __u32 nr_map_ids;
+-        __aligned_u64 map_ids;
+-        char name[BPF_OBJ_NAME_LEN];
+-        __u32 ifindex;
+-        __u64 netns_dev;
+-        __u64 netns_ino;
++	__u32 type;
++	__u32 id;
++	__u8  tag[BPF_TAG_SIZE];
++	__u32 jited_prog_len;
++	__u32 xlated_prog_len;
++	__aligned_u64 jited_prog_insns;
++	__aligned_u64 xlated_prog_insns;
++	__u64 load_time;	/* ns since boottime */
++	__u32 created_by_uid;
++	__u32 nr_map_ids;
++	__aligned_u64 map_ids;
++	char name[BPF_OBJ_NAME_LEN];
++	__u32 ifindex;
++	__u32 gpl_compatible:1;
++	__u64 netns_dev;
++	__u64 netns_ino;
++	__u32 nr_jited_ksyms;
++	__u32 nr_jited_func_lens;
++	__aligned_u64 jited_ksyms;
++	__aligned_u64 jited_func_lens;
++	__u32 btf_id;
++	__u32 func_info_rec_size;
++	__aligned_u64 func_info;
++	__u32 nr_func_info;
++	__u32 nr_line_info;
++	__aligned_u64 line_info;
++	__aligned_u64 jited_line_info;
++	__u32 nr_jited_line_info;
++	__u32 line_info_rec_size;
++	__u32 jited_line_info_rec_size;
++	__u32 nr_prog_tags;
++	__aligned_u64 prog_tags;
+ } __attribute__((aligned(8)));
+ 
+ struct bpf_map_info {
+-        __u32 type;
+-        __u32 id;
+-        __u32 key_size;
+-        __u32 value_size;
+-        __u32 max_entries;
+-        __u32 map_flags;
+-        char  name[BPF_OBJ_NAME_LEN];
+-        __u32 ifindex;
+-        __u64 netns_dev;
+-        __u64 netns_ino;
++	__u32 type;
++	__u32 id;
++	__u32 key_size;
++	__u32 value_size;
++	__u32 max_entries;
++	__u32 map_flags;
++	char  name[BPF_OBJ_NAME_LEN];
++	__u32 ifindex;
++	__u32 :32;
++	__u64 netns_dev;
++	__u64 netns_ino;
++	__u32 btf_id;
++	__u32 btf_key_type_id;
++	__u32 btf_value_type_id;
+ } __attribute__((aligned(8)));
+ 
++struct bpf_btf_info {
++	__aligned_u64 btf;
++	__u32 btf_size;
++	__u32 id;
++} __attribute__((aligned(8)));
++
++/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed
++ * by user and intended to be used by socket (e.g. to bind to, depends on
++ * attach attach type).
++ */
++struct bpf_sock_addr {
++	__u32 user_family;	/* Allows 4-byte read, but no write. */
++	__u32 user_ip4;		/* Allows 1,2,4-byte read and 4-byte write.
++				 * Stored in network byte order.
++				 */
++	__u32 user_ip6[4];	/* Allows 1,2,4-byte read an 4-byte write.
++				 * Stored in network byte order.
++				 */
++	__u32 user_port;	/* Allows 4-byte read and write.
++				 * Stored in network byte order
++				 */
++	__u32 family;		/* Allows 4-byte read, but no write */
++	__u32 type;		/* Allows 4-byte read, but no write */
++	__u32 protocol;		/* Allows 4-byte read, but no write */
++	__u32 msg_src_ip4;	/* Allows 1,2,4-byte read an 4-byte write.
++				 * Stored in network byte order.
++				 */
++	__u32 msg_src_ip6[4];	/* Allows 1,2,4-byte read an 4-byte write.
++				 * Stored in network byte order.
++				 */
++};
++
+ /* User bpf_sock_ops struct to access socket values and specify request ops
+  * and their replies.
+  * Some of this fields are in network (bigendian) byte order and may need
+@@ -959,48 +2786,48 @@ struct bpf_map_info {
+  * New fields can only be added at the end of this structure
+  */
+ struct bpf_sock_ops {
+-        __u32 op;
+-        union {
+-                __u32 args[4];		/* Optionally passed to bpf program */
+-                __u32 reply;		/* Returned by bpf program	    */
+-                __u32 replylong[4];	/* Optionally returned by bpf prog  */
+-        };
+-        __u32 family;
+-        __u32 remote_ip4;	/* Stored in network byte order */
+-        __u32 local_ip4;	/* Stored in network byte order */
+-        __u32 remote_ip6[4];	/* Stored in network byte order */
+-        __u32 local_ip6[4];	/* Stored in network byte order */
+-        __u32 remote_port;	/* Stored in network byte order */
+-        __u32 local_port;	/* stored in host byte order */
+-        __u32 is_fullsock;	/* Some TCP fields are only valid if
+-                                 * there is a full socket. If not, the
+-                                 * fields read as zero.
+-                                 */
+-        __u32 snd_cwnd;
+-        __u32 srtt_us;		/* Averaged RTT << 3 in usecs */
+-        __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */
+-        __u32 state;
+-        __u32 rtt_min;
+-        __u32 snd_ssthresh;
+-        __u32 rcv_nxt;
+-        __u32 snd_nxt;
+-        __u32 snd_una;
+-        __u32 mss_cache;
+-        __u32 ecn_flags;
+-        __u32 rate_delivered;
+-        __u32 rate_interval_us;
+-        __u32 packets_out;
+-        __u32 retrans_out;
+-        __u32 total_retrans;
+-        __u32 segs_in;
+-        __u32 data_segs_in;
+-        __u32 segs_out;
+-        __u32 data_segs_out;
+-        __u32 lost_out;
+-        __u32 sacked_out;
+-        __u32 sk_txhash;
+-        __u64 bytes_received;
+-        __u64 bytes_acked;
++	__u32 op;
++	union {
++		__u32 args[4];		/* Optionally passed to bpf program */
++		__u32 reply;		/* Returned by bpf program	    */
++		__u32 replylong[4];	/* Optionally returned by bpf prog  */
++	};
++	__u32 family;
++	__u32 remote_ip4;	/* Stored in network byte order */
++	__u32 local_ip4;	/* Stored in network byte order */
++	__u32 remote_ip6[4];	/* Stored in network byte order */
++	__u32 local_ip6[4];	/* Stored in network byte order */
++	__u32 remote_port;	/* Stored in network byte order */
++	__u32 local_port;	/* stored in host byte order */
++	__u32 is_fullsock;	/* Some TCP fields are only valid if
++				 * there is a full socket. If not, the
++				 * fields read as zero.
++				 */
++	__u32 snd_cwnd;
++	__u32 srtt_us;		/* Averaged RTT << 3 in usecs */
++	__u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */
++	__u32 state;
++	__u32 rtt_min;
++	__u32 snd_ssthresh;
++	__u32 rcv_nxt;
++	__u32 snd_nxt;
++	__u32 snd_una;
++	__u32 mss_cache;
++	__u32 ecn_flags;
++	__u32 rate_delivered;
++	__u32 rate_interval_us;
++	__u32 packets_out;
++	__u32 retrans_out;
++	__u32 total_retrans;
++	__u32 segs_in;
++	__u32 data_segs_in;
++	__u32 segs_out;
++	__u32 data_segs_out;
++	__u32 lost_out;
++	__u32 sacked_out;
++	__u32 sk_txhash;
++	__u64 bytes_received;
++	__u64 bytes_acked;
+ };
+ 
+ /* Definitions for bpf_sock_ops_cb_flags */
+@@ -1008,57 +2835,60 @@ struct bpf_sock_ops {
+ #define BPF_SOCK_OPS_RETRANS_CB_FLAG	(1<<1)
+ #define BPF_SOCK_OPS_STATE_CB_FLAG	(1<<2)
+ #define BPF_SOCK_OPS_ALL_CB_FLAGS       0x7		/* Mask of all currently
+-                                                         * supported cb flags
+-                                                         */
++							 * supported cb flags
++							 */
+ 
+ /* List of known BPF sock_ops operators.
+  * New entries can only be added at the end
+  */
+ enum {
+-        BPF_SOCK_OPS_VOID,
+-        BPF_SOCK_OPS_TIMEOUT_INIT,	/* Should return SYN-RTO value to use or
+-                                         * -1 if default value should be used
+-                                         */
+-        BPF_SOCK_OPS_RWND_INIT,		/* Should return initial advertized
+-                                         * window (in packets) or -1 if default
+-                                         * value should be used
+-                                         */
+-        BPF_SOCK_OPS_TCP_CONNECT_CB,	/* Calls BPF program right before an
+-                                         * active connection is initialized
+-                                         */
+-        BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,	/* Calls BPF program when an
+-                                                 * active connection is
+-                                                 * established
+-                                                 */
+-        BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,	/* Calls BPF program when a
+-                                                 * passive connection is
+-                                                 * established
+-                                                 */
+-        BPF_SOCK_OPS_NEEDS_ECN,		/* If connection's congestion control
+-                                         * needs ECN
+-                                         */
+-        BPF_SOCK_OPS_BASE_RTT,		/* Get base RTT. The correct value is
+-                                         * based on the path and may be
+-                                         * dependent on the congestion control
+-                                         * algorithm. In general it indicates
+-                                         * a congestion threshold. RTTs above
+-                                         * this indicate congestion
+-                                         */
+-        BPF_SOCK_OPS_RTO_CB,		/* Called when an RTO has triggered.
+-                                         * Arg1: value of icsk_retransmits
+-                                         * Arg2: value of icsk_rto
+-                                         * Arg3: whether RTO has expired
+-                                         */
+-        BPF_SOCK_OPS_RETRANS_CB,	/* Called when skb is retransmitted.
+-                                         * Arg1: sequence number of 1st byte
+-                                         * Arg2: # segments
+-                                         * Arg3: return value of
+-                                         *       tcp_transmit_skb (0 => success)
+-                                         */
+-        BPF_SOCK_OPS_STATE_CB,		/* Called when TCP changes state.
+-                                         * Arg1: old_state
+-                                         * Arg2: new_state
+-                                         */
++	BPF_SOCK_OPS_VOID,
++	BPF_SOCK_OPS_TIMEOUT_INIT,	/* Should return SYN-RTO value to use or
++					 * -1 if default value should be used
++					 */
++	BPF_SOCK_OPS_RWND_INIT,		/* Should return initial advertized
++					 * window (in packets) or -1 if default
++					 * value should be used
++					 */
++	BPF_SOCK_OPS_TCP_CONNECT_CB,	/* Calls BPF program right before an
++					 * active connection is initialized
++					 */
++	BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,	/* Calls BPF program when an
++						 * active connection is
++						 * established
++						 */
++	BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,	/* Calls BPF program when a
++						 * passive connection is
++						 * established
++						 */
++	BPF_SOCK_OPS_NEEDS_ECN,		/* If connection's congestion control
++					 * needs ECN
++					 */
++	BPF_SOCK_OPS_BASE_RTT,		/* Get base RTT. The correct value is
++					 * based on the path and may be
++					 * dependent on the congestion control
++					 * algorithm. In general it indicates
++					 * a congestion threshold. RTTs above
++					 * this indicate congestion
++					 */
++	BPF_SOCK_OPS_RTO_CB,		/* Called when an RTO has triggered.
++					 * Arg1: value of icsk_retransmits
++					 * Arg2: value of icsk_rto
++					 * Arg3: whether RTO has expired
++					 */
++	BPF_SOCK_OPS_RETRANS_CB,	/* Called when skb is retransmitted.
++					 * Arg1: sequence number of 1st byte
++					 * Arg2: # segments
++					 * Arg3: return value of
++					 *       tcp_transmit_skb (0 => success)
++					 */
++	BPF_SOCK_OPS_STATE_CB,		/* Called when TCP changes state.
++					 * Arg1: old_state
++					 * Arg2: new_state
++					 */
++	BPF_SOCK_OPS_TCP_LISTEN_CB,	/* Called on listen(2), right after
++					 * socket transition to LISTEN state.
++					 */
+ };
+ 
+ /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
+@@ -1067,29 +2897,29 @@ enum {
+  * the BPF sock_ops function.
+  */
+ enum {
+-        BPF_TCP_ESTABLISHED = 1,
+-        BPF_TCP_SYN_SENT,
+-        BPF_TCP_SYN_RECV,
+-        BPF_TCP_FIN_WAIT1,
+-        BPF_TCP_FIN_WAIT2,
+-        BPF_TCP_TIME_WAIT,
+-        BPF_TCP_CLOSE,
+-        BPF_TCP_CLOSE_WAIT,
+-        BPF_TCP_LAST_ACK,
+-        BPF_TCP_LISTEN,
+-        BPF_TCP_CLOSING,	/* Now a valid state */
+-        BPF_TCP_NEW_SYN_RECV,
+-
+-        BPF_TCP_MAX_STATES	/* Leave at the end! */
++	BPF_TCP_ESTABLISHED = 1,
++	BPF_TCP_SYN_SENT,
++	BPF_TCP_SYN_RECV,
++	BPF_TCP_FIN_WAIT1,
++	BPF_TCP_FIN_WAIT2,
++	BPF_TCP_TIME_WAIT,
++	BPF_TCP_CLOSE,
++	BPF_TCP_CLOSE_WAIT,
++	BPF_TCP_LAST_ACK,
++	BPF_TCP_LISTEN,
++	BPF_TCP_CLOSING,	/* Now a valid state */
++	BPF_TCP_NEW_SYN_RECV,
++
++	BPF_TCP_MAX_STATES	/* Leave at the end! */
+ };
+ 
+ #define TCP_BPF_IW		1001	/* Set TCP initial congestion window */
+ #define TCP_BPF_SNDCWND_CLAMP	1002	/* Set sndcwnd_clamp */
+ 
+ struct bpf_perf_event_value {
+-        __u64 counter;
+-        __u64 enabled;
+-        __u64 running;
++	__u64 counter;
++	__u64 enabled;
++	__u64 running;
+ };
+ 
+ #define BPF_DEVCG_ACC_MKNOD	(1ULL << 0)
+@@ -1100,10 +2930,128 @@ struct bpf_perf_event_value {
+ #define BPF_DEVCG_DEV_CHAR	(1ULL << 1)
+ 
+ struct bpf_cgroup_dev_ctx {
+-        /* access_type encoded as (BPF_DEVCG_ACC_* << 16) | BPF_DEVCG_DEV_* */
+-        __u32 access_type;
+-        __u32 major;
+-        __u32 minor;
++	/* access_type encoded as (BPF_DEVCG_ACC_* << 16) | BPF_DEVCG_DEV_* */
++	__u32 access_type;
++	__u32 major;
++	__u32 minor;
++};
++
++struct bpf_raw_tracepoint_args {
++	__u64 args[0];
++};
++
++/* DIRECT:  Skip the FIB rules and go to FIB table associated with device
++ * OUTPUT:  Do lookup from egress perspective; default is ingress
++ */
++#define BPF_FIB_LOOKUP_DIRECT  BIT(0)
++#define BPF_FIB_LOOKUP_OUTPUT  BIT(1)
++
++enum {
++	BPF_FIB_LKUP_RET_SUCCESS,      /* lookup successful */
++	BPF_FIB_LKUP_RET_BLACKHOLE,    /* dest is blackholed; can be dropped */
++	BPF_FIB_LKUP_RET_UNREACHABLE,  /* dest is unreachable; can be dropped */
++	BPF_FIB_LKUP_RET_PROHIBIT,     /* dest not allowed; can be dropped */
++	BPF_FIB_LKUP_RET_NOT_FWDED,    /* packet is not forwarded */
++	BPF_FIB_LKUP_RET_FWD_DISABLED, /* fwding is not enabled on ingress */
++	BPF_FIB_LKUP_RET_UNSUPP_LWT,   /* fwd requires encapsulation */
++	BPF_FIB_LKUP_RET_NO_NEIGH,     /* no neighbor entry for nh */
++	BPF_FIB_LKUP_RET_FRAG_NEEDED,  /* fragmentation required to fwd */
++};
++
++struct bpf_fib_lookup {
++	/* input:  network family for lookup (AF_INET, AF_INET6)
++	 * output: network family of egress nexthop
++	 */
++	__u8	family;
++
++	/* set if lookup is to consider L4 data - e.g., FIB rules */
++	__u8	l4_protocol;
++	__be16	sport;
++	__be16	dport;
++
++	/* total length of packet from network header - used for MTU check */
++	__u16	tot_len;
++
++	/* input: L3 device index for lookup
++	 * output: device index from FIB lookup
++	 */
++	__u32	ifindex;
++
++	union {
++		/* inputs to lookup */
++		__u8	tos;		/* AF_INET  */
++		__be32	flowinfo;	/* AF_INET6, flow_label + priority */
++
++		/* output: metric of fib result (IPv4/IPv6 only) */
++		__u32	rt_metric;
++	};
++
++	union {
++		__be32		ipv4_src;
++		__u32		ipv6_src[4];  /* in6_addr; network order */
++	};
++
++	/* input to bpf_fib_lookup, ipv{4,6}_dst is destination address in
++	 * network header. output: bpf_fib_lookup sets to gateway address
++	 * if FIB lookup returns gateway route
++	 */
++	union {
++		__be32		ipv4_dst;
++		__u32		ipv6_dst[4];  /* in6_addr; network order */
++	};
++
++	/* output */
++	__be16	h_vlan_proto;
++	__be16	h_vlan_TCI;
++	__u8	smac[6];     /* ETH_ALEN */
++	__u8	dmac[6];     /* ETH_ALEN */
++};
++
++enum bpf_task_fd_type {
++	BPF_FD_TYPE_RAW_TRACEPOINT,	/* tp name */
++	BPF_FD_TYPE_TRACEPOINT,		/* tp name */
++	BPF_FD_TYPE_KPROBE,		/* (symbol + offset) or addr */
++	BPF_FD_TYPE_KRETPROBE,		/* (symbol + offset) or addr */
++	BPF_FD_TYPE_UPROBE,		/* filename + offset */
++	BPF_FD_TYPE_URETPROBE,		/* filename + offset */
++};
++
++struct bpf_flow_keys {
++	__u16	nhoff;
++	__u16	thoff;
++	__u16	addr_proto;			/* ETH_P_* of valid addrs */
++	__u8	is_frag;
++	__u8	is_first_frag;
++	__u8	is_encap;
++	__u8	ip_proto;
++	__be16	n_proto;
++	__be16	sport;
++	__be16	dport;
++	union {
++		struct {
++			__be32	ipv4_src;
++			__be32	ipv4_dst;
++		};
++		struct {
++			__u32	ipv6_src[4];	/* in6_addr; network order */
++			__u32	ipv6_dst[4];	/* in6_addr; network order */
++		};
++	};
++};
++
++struct bpf_func_info {
++	__u32	insn_off;
++	__u32	type_id;
++};
++
++#define BPF_LINE_INFO_LINE_NUM(line_col)	((line_col) >> 10)
++#define BPF_LINE_INFO_LINE_COL(line_col)	((line_col) & 0x3ff)
++
++struct bpf_line_info {
++	__u32	insn_off;
++	__u32	file_name_off;
++	__u32	line_off;
++	__u32	line_col;
+ };
+ 
+ #endif /* _UAPI__LINUX_BPF_H__ */
+diff --git a/src/shared/linux/bpf_common.h b/src/shared/linux/bpf_common.h
+index afe7433b98..ee97668bda 100644
+--- a/src/shared/linux/bpf_common.h
++++ b/src/shared/linux/bpf_common.h
+@@ -1,5 +1,6 @@
+-#ifndef __LINUX_BPF_COMMON_H__
+-#define __LINUX_BPF_COMMON_H__
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _UAPI__LINUX_BPF_COMMON_H__
++#define _UAPI__LINUX_BPF_COMMON_H__
+ 
+ /* Instruction classes */
+ #define BPF_CLASS(code) ((code) & 0x07)
+@@ -14,9 +15,10 @@
+ 
+ /* ld/ldx fields */
+ #define BPF_SIZE(code)  ((code) & 0x18)
+-#define		BPF_W		0x00
+-#define		BPF_H		0x08
+-#define		BPF_B		0x10
++#define		BPF_W		0x00 /* 32-bit */
++#define		BPF_H		0x08 /* 16-bit */
++#define		BPF_B		0x10 /*  8-bit */
++/* eBPF		BPF_DW		0x18    64-bit */
+ #define BPF_MODE(code)  ((code) & 0xe0)
+ #define		BPF_IMM		0x00
+ #define		BPF_ABS		0x20
+@@ -52,4 +54,4 @@
+ #define BPF_MAXINSNS 4096
+ #endif
+ 
+-#endif /* __LINUX_BPF_COMMON_H__ */
++#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
+diff --git a/src/shared/linux/bpf_insn.h b/src/shared/linux/bpf_insn.h
+new file mode 100644
+index 0000000000..e88459fdaa
+--- /dev/null
++++ b/src/shared/linux/bpf_insn.h
+@@ -0,0 +1,205 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* eBPF instruction mini library */
++#ifndef __BPF_INSN_H
++#define __BPF_INSN_H
++
++struct bpf_insn;
++
++/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
++
++#define BPF_ALU64_REG(OP, DST, SRC)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = 0,					\
++		.imm   = 0 })
++
++#define BPF_ALU32_REG(OP, DST, SRC)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = 0,					\
++		.imm   = 0 })
++
++/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
++
++#define BPF_ALU64_IMM(OP, DST, IMM)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = IMM })
++
++#define BPF_ALU32_IMM(OP, DST, IMM)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = IMM })
++
++/* Short form of mov, dst_reg = src_reg */
++
++#define BPF_MOV64_REG(DST, SRC)					\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = 0,					\
++		.imm   = 0 })
++
++#define BPF_MOV32_REG(DST, SRC)					\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU | BPF_MOV | BPF_X,		\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = 0,					\
++		.imm   = 0 })
++
++/* Short form of mov, dst_reg = imm32 */
++
++#define BPF_MOV64_IMM(DST, IMM)					\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = IMM })
++
++#define BPF_MOV32_IMM(DST, IMM)					\
++	((struct bpf_insn) {					\
++		.code  = BPF_ALU | BPF_MOV | BPF_K,		\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = IMM })
++
++/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
++#define BPF_LD_IMM64(DST, IMM)					\
++	BPF_LD_IMM64_RAW(DST, 0, IMM)
++
++#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_LD | BPF_DW | BPF_IMM,		\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = 0,					\
++		.imm   = (__u32) (IMM) }),			\
++	((struct bpf_insn) {					\
++		.code  = 0, /* zero is reserved opcode */	\
++		.dst_reg = 0,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = ((__u64) (IMM)) >> 32 })
++
++#ifndef BPF_PSEUDO_MAP_FD
++# define BPF_PSEUDO_MAP_FD	1
++#endif
++
++/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
++#define BPF_LD_MAP_FD(DST, MAP_FD)				\
++	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
++
++
++/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
++
++#define BPF_LD_ABS(SIZE, IMM)					\
++	((struct bpf_insn) {					\
++		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
++		.dst_reg = 0,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = IMM })
++
++/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
++
++#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
++	((struct bpf_insn) {					\
++		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = OFF,					\
++		.imm   = 0 })
++
++/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
++
++#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
++	((struct bpf_insn) {					\
++		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = OFF,					\
++		.imm   = 0 })
++
++/* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */
++
++#define BPF_STX_XADD(SIZE, DST, SRC, OFF)			\
++	((struct bpf_insn) {					\
++		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD,	\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = OFF,					\
++		.imm   = 0 })
++
++/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
++
++#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = OFF,					\
++		.imm   = IMM })
++
++/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
++
++#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = OFF,					\
++		.imm   = 0 })
++
++/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
++
++#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
++	((struct bpf_insn) {					\
++		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
++		.dst_reg = DST,					\
++		.src_reg = 0,					\
++		.off   = OFF,					\
++		.imm   = IMM })
++
++#define BPF_JMP_A(OFF)						\
++	((struct bpf_insn) {					\
++		.code  = BPF_JMP | BPF_JA,			\
++		.dst_reg = 0,					\
++		.src_reg = 0,					\
++		.off   = OFF,					\
++		.imm   = 0 })
++
++/* Raw code statement block */
++
++#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
++	((struct bpf_insn) {					\
++		.code  = CODE,					\
++		.dst_reg = DST,					\
++		.src_reg = SRC,					\
++		.off   = OFF,					\
++		.imm   = IMM })
++
++/* Program exit */
++
++#define BPF_EXIT_INSN()						\
++	((struct bpf_insn) {					\
++		.code  = BPF_JMP | BPF_EXIT,			\
++		.dst_reg = 0,					\
++		.src_reg = 0,					\
++		.off   = 0,					\
++		.imm   = 0 })
++
++#endif
+diff --git a/src/shared/linux/dm-ioctl.h b/src/shared/linux/dm-ioctl.h
+new file mode 100644
+index 0000000000..8faa188c35
+--- /dev/null
++++ b/src/shared/linux/dm-ioctl.h
+@@ -0,0 +1,363 @@
++/* SPDX-License-Identifier: LGPL-2.0+ WITH Linux-syscall-note */
++/*
++ * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
++ * Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved.
++ *
++ * This file is released under the LGPL.
++ */
++
++#ifndef _LINUX_DM_IOCTL_V4_H
++#define _LINUX_DM_IOCTL_V4_H
++
++#include <linux/types.h>
++
++#define DM_DIR "mapper"		/* Slashes not supported */
++#define DM_CONTROL_NODE "control"
++#define DM_MAX_TYPE_NAME 16
++#define DM_NAME_LEN 128
++#define DM_UUID_LEN 129
++
++/*
++ * A traditional ioctl interface for the device mapper.
++ *
++ * Each device can have two tables associated with it, an
++ * 'active' table which is the one currently used by io passing
++ * through the device, and an 'inactive' one which is a table
++ * that is being prepared as a replacement for the 'active' one.
++ *
++ * DM_VERSION:
++ * Just get the version information for the ioctl interface.
++ *
++ * DM_REMOVE_ALL:
++ * Remove all dm devices, destroy all tables.  Only really used
++ * for debug.
++ *
++ * DM_LIST_DEVICES:
++ * Get a list of all the dm device names.
++ *
++ * DM_DEV_CREATE:
++ * Create a new device, neither the 'active' or 'inactive' table
++ * slots will be filled.  The device will be in suspended state
++ * after creation, however any io to the device will get errored
++ * since it will be out-of-bounds.
++ *
++ * DM_DEV_REMOVE:
++ * Remove a device, destroy any tables.
++ *
++ * DM_DEV_RENAME:
++ * Rename a device or set its uuid if none was previously supplied.
++ *
++ * DM_SUSPEND:
++ * This performs both suspend and resume, depending which flag is
++ * passed in.
++ * Suspend: This command will not return until all pending io to
++ * the device has completed.  Further io will be deferred until
++ * the device is resumed.
++ * Resume: It is no longer an error to issue this command on an
++ * unsuspended device.  If a table is present in the 'inactive'
++ * slot, it will be moved to the active slot, then the old table
++ * from the active slot will be _destroyed_.  Finally the device
++ * is resumed.
++ *
++ * DM_DEV_STATUS:
++ * Retrieves the status for the table in the 'active' slot.
++ *
++ * DM_DEV_WAIT:
++ * Wait for a significant event to occur to the device.  This
++ * could either be caused by an event triggered by one of the
++ * targets of the table in the 'active' slot, or a table change.
++ *
++ * DM_TABLE_LOAD:
++ * Load a table into the 'inactive' slot for the device.  The
++ * device does _not_ need to be suspended prior to this command.
++ *
++ * DM_TABLE_CLEAR:
++ * Destroy any table in the 'inactive' slot (ie. abort).
++ *
++ * DM_TABLE_DEPS:
++ * Return a set of device dependencies for the 'active' table.
++ *
++ * DM_TABLE_STATUS:
++ * Return the targets status for the 'active' table.
++ *
++ * DM_TARGET_MSG:
++ * Pass a message string to the target at a specific offset of a device.
++ *
++ * DM_DEV_SET_GEOMETRY:
++ * Set the geometry of a device by passing in a string in this format:
++ *
++ * "cylinders heads sectors_per_track start_sector"
++ *
++ * Beware that CHS geometry is nearly obsolete and only provided
++ * for compatibility with dm devices that can be booted by a PC
++ * BIOS.  See struct hd_geometry for range limits.  Also note that
++ * the geometry is erased if the device size changes.
++ */
++
++/*
++ * All ioctl arguments consist of a single chunk of memory, with
++ * this structure at the start.  If a uuid is specified any
++ * lookup (eg. for a DM_INFO) will be done on that, *not* the
++ * name.
++ */
++struct dm_ioctl {
++	/*
++	 * The version number is made up of three parts:
++	 * major - no backward or forward compatibility,
++	 * minor - only backwards compatible,
++	 * patch - both backwards and forwards compatible.
++	 *
++	 * All clients of the ioctl interface should fill in the
++	 * version number of the interface that they were
++	 * compiled with.
++	 *
++	 * All recognised ioctl commands (ie. those that don't
++	 * return -ENOTTY) fill out this field, even if the
++	 * command failed.
++	 */
++	__u32 version[3];	/* in/out */
++	__u32 data_size;	/* total size of data passed in
++				 * including this struct */
++
++	__u32 data_start;	/* offset to start of data
++				 * relative to start of this struct */
++
++	__u32 target_count;	/* in/out */
++	__s32 open_count;	/* out */
++	__u32 flags;		/* in/out */
++
++	/*
++	 * event_nr holds either the event number (input and output) or the
++	 * udev cookie value (input only).
++	 * The DM_DEV_WAIT ioctl takes an event number as input.
++	 * The DM_SUSPEND, DM_DEV_REMOVE and DM_DEV_RENAME ioctls
++	 * use the field as a cookie to return in the DM_COOKIE
++	 * variable with the uevents they issue.
++	 * For output, the ioctls return the event number, not the cookie.
++	 */
++	__u32 event_nr;      	/* in/out */
++	__u32 padding;
++
++	__u64 dev;		/* in/out */
++
++	char name[DM_NAME_LEN];	/* device name */
++	char uuid[DM_UUID_LEN];	/* unique identifier for
++				 * the block device */
++	char data[7];		/* padding or data */
++};
++
++/*
++ * Used to specify tables.  These structures appear after the
++ * dm_ioctl.
++ */
++struct dm_target_spec {
++	__u64 sector_start;
++	__u64 length;
++	__s32 status;		/* used when reading from kernel only */
++
++	/*
++	 * Location of the next dm_target_spec.
++	 * - When specifying targets on a DM_TABLE_LOAD command, this value is
++	 *   the number of bytes from the start of the "current" dm_target_spec
++	 *   to the start of the "next" dm_target_spec.
++	 * - When retrieving targets on a DM_TABLE_STATUS command, this value
++	 *   is the number of bytes from the start of the first dm_target_spec
++	 *   (that follows the dm_ioctl struct) to the start of the "next"
++	 *   dm_target_spec.
++	 */
++	__u32 next;
++
++	char target_type[DM_MAX_TYPE_NAME];
++
++	/*
++	 * Parameter string starts immediately after this object.
++	 * Be careful to add padding after string to ensure correct
++	 * alignment of subsequent dm_target_spec.
++	 */
++};
++
++/*
++ * Used to retrieve the target dependencies.
++ */
++struct dm_target_deps {
++	__u32 count;	/* Array size */
++	__u32 padding;	/* unused */
++	__u64 dev[0];	/* out */
++};
++
++/*
++ * Used to get a list of all dm devices.
++ */
++struct dm_name_list {
++	__u64 dev;
++	__u32 next;		/* offset to the next record from
++				   the _start_ of this */
++	char name[0];
++};
++
++/*
++ * Used to retrieve the target versions
++ */
++struct dm_target_versions {
++        __u32 next;
++        __u32 version[3];
++
++        char name[0];
++};
++
++/*
++ * Used to pass message to a target
++ */
++struct dm_target_msg {
++	__u64 sector;	/* Device sector */
++
++	char message[0];
++};
++
++/*
++ * If you change this make sure you make the corresponding change
++ * to dm-ioctl.c:lookup_ioctl()
++ */
++enum {
++	/* Top level cmds */
++	DM_VERSION_CMD = 0,
++	DM_REMOVE_ALL_CMD,
++	DM_LIST_DEVICES_CMD,
++
++	/* device level cmds */
++	DM_DEV_CREATE_CMD,
++	DM_DEV_REMOVE_CMD,
++	DM_DEV_RENAME_CMD,
++	DM_DEV_SUSPEND_CMD,
++	DM_DEV_STATUS_CMD,
++	DM_DEV_WAIT_CMD,
++
++	/* Table level cmds */
++	DM_TABLE_LOAD_CMD,
++	DM_TABLE_CLEAR_CMD,
++	DM_TABLE_DEPS_CMD,
++	DM_TABLE_STATUS_CMD,
++
++	/* Added later */
++	DM_LIST_VERSIONS_CMD,
++	DM_TARGET_MSG_CMD,
++	DM_DEV_SET_GEOMETRY_CMD,
++	DM_DEV_ARM_POLL_CMD,
++};
++
++#define DM_IOCTL 0xfd
++
++#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
++#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
++#define DM_LIST_DEVICES  _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
++
++#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
++#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
++#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
++#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
++#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
++#define DM_DEV_WAIT      _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
++#define DM_DEV_ARM_POLL  _IOWR(DM_IOCTL, DM_DEV_ARM_POLL_CMD, struct dm_ioctl)
++
++#define DM_TABLE_LOAD    _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
++#define DM_TABLE_CLEAR   _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
++#define DM_TABLE_DEPS    _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
++#define DM_TABLE_STATUS  _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
++
++#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
++
++#define DM_TARGET_MSG	 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
++#define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
++
++#define DM_VERSION_MAJOR	4
++#define DM_VERSION_MINOR	27
++#define DM_VERSION_PATCHLEVEL	0
++#define DM_VERSION_EXTRA	"-ioctl (2018-04-03)"
++
++/* Status bits */
++#define DM_READONLY_FLAG	(1 << 0) /* In/Out */
++#define DM_SUSPEND_FLAG		(1 << 1) /* In/Out */
++#define DM_PERSISTENT_DEV_FLAG	(1 << 3) /* In */
++
++/*
++ * Flag passed into ioctl STATUS command to get table information
++ * rather than current status.
++ */
++#define DM_STATUS_TABLE_FLAG	(1 << 4) /* In */
++
++/*
++ * Flags that indicate whether a table is present in either of
++ * the two table slots that a device has.
++ */
++#define DM_ACTIVE_PRESENT_FLAG   (1 << 5) /* Out */
++#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
++
++/*
++ * Indicates that the buffer passed in wasn't big enough for the
++ * results.
++ */
++#define DM_BUFFER_FULL_FLAG	(1 << 8) /* Out */
++
++/*
++ * This flag is now ignored.
++ */
++#define DM_SKIP_BDGET_FLAG	(1 << 9) /* In */
++
++/*
++ * Set this to avoid attempting to freeze any filesystem when suspending.
++ */
++#define DM_SKIP_LOCKFS_FLAG	(1 << 10) /* In */
++
++/*
++ * Set this to suspend without flushing queued ios.
++ * Also disables flushing uncommitted changes in the thin target before
++ * generating statistics for DM_TABLE_STATUS and DM_DEV_WAIT.
++ */
++#define DM_NOFLUSH_FLAG		(1 << 11) /* In */
++
++/*
++ * If set, any table information returned will relate to the inactive
++ * table instead of the live one.  Always check DM_INACTIVE_PRESENT_FLAG
++ * is set before using the data returned.
++ */
++#define DM_QUERY_INACTIVE_TABLE_FLAG	(1 << 12) /* In */
++
++/*
++ * If set, a uevent was generated for which the caller may need to wait.
++ */
++#define DM_UEVENT_GENERATED_FLAG	(1 << 13) /* Out */
++
++/*
++ * If set, rename changes the uuid not the name.  Only permitted
++ * if no uuid was previously supplied: an existing uuid cannot be changed.
++ */
++#define DM_UUID_FLAG			(1 << 14) /* In */
++
++/*
++ * If set, all buffers are wiped after use. Use when sending
++ * or requesting sensitive data such as an encryption key.
++ */
++#define DM_SECURE_DATA_FLAG		(1 << 15) /* In */
++
++/*
++ * If set, a message generated output data.
++ */
++#define DM_DATA_OUT_FLAG		(1 << 16) /* Out */
++
++/*
++ * If set with DM_DEV_REMOVE or DM_REMOVE_ALL this indicates that if
++ * the device cannot be removed immediately because it is still in use
++ * it should instead be scheduled for removal when it gets closed.
++ *
++ * On return from DM_DEV_REMOVE, DM_DEV_STATUS or other ioctls, this
++ * flag indicates that the device is scheduled to be removed when it
++ * gets closed.
++ */
++#define DM_DEFERRED_REMOVE		(1 << 17) /* In/Out */
++
++/*
++ * If set, the device is suspended internally.
++ */
++#define DM_INTERNAL_SUSPEND_FLAG	(1 << 18) /* Out */
++
++#endif				/* _LINUX_DM_IOCTL_H */
+diff --git a/src/shared/linux/ethtool.h b/src/shared/linux/ethtool.h
+new file mode 100644
+index 0000000000..f6c45a36c9
+--- /dev/null
++++ b/src/shared/linux/ethtool.h
+@@ -0,0 +1,1843 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/*
++ * ethtool.h: Defines for Linux ethtool.
++ *
++ * Copyright (C) 1998 David S. Miller (davem@redhat.com)
++ * Copyright 2001 Jeff Garzik <jgarzik@pobox.com>
++ * Portions Copyright 2001 Sun Microsystems (thockin@sun.com)
++ * Portions Copyright 2002 Intel (eli.kupermann@intel.com,
++ *                                christopher.leech@intel.com,
++ *                                scott.feldman@intel.com)
++ * Portions Copyright (C) Sun Microsystems 2008
++ */
++
++#ifndef _UAPI_LINUX_ETHTOOL_H
++#define _UAPI_LINUX_ETHTOOL_H
++
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/if_ether.h>
++
++#ifndef __KERNEL__
++#include <limits.h> /* for INT_MAX */
++#endif
++
++#ifndef __KERNEL_DIV_ROUND_UP
++#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
++#endif
++
++/* All structures exposed to userland should be defined such that they
++ * have the same layout for 32-bit and 64-bit userland.
++ */
++
++/**
++ * struct ethtool_cmd - DEPRECATED, link control and status
++ * This structure is DEPRECATED, please use struct ethtool_link_settings.
++ * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
++ * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
++ *	physical connectors and other link features for which the
++ *	interface supports autonegotiation or auto-detection.
++ *	Read-only.
++ * @advertising: Bitmask of %ADVERTISED_* flags for the link modes,
++ *	physical connectors and other link features that are
++ *	advertised through autonegotiation or enabled for
++ *	auto-detection.
++ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
++ * @duplex: Duplex mode; one of %DUPLEX_*
++ * @port: Physical connector type; one of %PORT_*
++ * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
++ *	applicable.  For clause 45 PHYs this is the PRTAD.
++ * @transceiver: Historically used to distinguish different possible
++ *	PHY types, but not in a consistent way.  Deprecated.
++ * @autoneg: Enable/disable autonegotiation and auto-detection;
++ *	either %AUTONEG_DISABLE or %AUTONEG_ENABLE
++ * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO
++ *	protocols supported by the interface; 0 if unknown.
++ *	Read-only.
++ * @maxtxpkt: Historically used to report TX IRQ coalescing; now
++ *	obsoleted by &struct ethtool_coalesce.  Read-only; deprecated.
++ * @maxrxpkt: Historically used to report RX IRQ coalescing; now
++ *	obsoleted by &struct ethtool_coalesce.  Read-only; deprecated.
++ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
++ * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
++ *	%ETH_TP_MDI_*.  If the status is unknown or not applicable, the
++ *	value will be %ETH_TP_MDI_INVALID.  Read-only.
++ * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of
++ *	%ETH_TP_MDI_*.  If MDI(-X) control is not implemented, reads
++ *	yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected.
++ *	When written successfully, the link should be renegotiated if
++ *	necessary.
++ * @lp_advertising: Bitmask of %ADVERTISED_* flags for the link modes
++ *	and other link features that the link partner advertised
++ *	through autonegotiation; 0 if unknown or not applicable.
++ *	Read-only.
++ *
++ * The link speed in Mbps is split between @speed and @speed_hi.  Use
++ * the ethtool_cmd_speed() and ethtool_cmd_speed_set() functions to
++ * access it.
++ *
++ * If autonegotiation is disabled, the speed and @duplex represent the
++ * fixed link mode and are writable if the driver supports multiple
++ * link modes.  If it is enabled then they are read-only; if the link
++ * is up they represent the negotiated link mode; if the link is down,
++ * the speed is 0, %SPEED_UNKNOWN or the highest enabled speed and
++ * @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
++ *
++ * Some hardware interfaces may have multiple PHYs and/or physical
++ * connectors fitted or do not allow the driver to detect which are
++ * fitted.  For these interfaces @port and/or @phy_address may be
++ * writable, possibly dependent on @autoneg being %AUTONEG_DISABLE.
++ * Otherwise, attempts to write different values may be ignored or
++ * rejected.
++ *
++ * Users should assume that all fields not marked read-only are
++ * writable and subject to validation by the driver.  They should use
++ * %ETHTOOL_GSET to get the current values before making specific
++ * changes and then applying them with %ETHTOOL_SSET.
++ *
++ * Deprecated fields should be ignored by both users and drivers.
++ */
++struct ethtool_cmd {
++	__u32	cmd;
++	__u32	supported;
++	__u32	advertising;
++	__u16	speed;
++	__u8	duplex;
++	__u8	port;
++	__u8	phy_address;
++	__u8	transceiver;
++	__u8	autoneg;
++	__u8	mdio_support;
++	__u32	maxtxpkt;
++	__u32	maxrxpkt;
++	__u16	speed_hi;
++	__u8	eth_tp_mdix;
++	__u8	eth_tp_mdix_ctrl;
++	__u32	lp_advertising;
++	__u32	reserved[2];
++};
++
++static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
++					 __u32 speed)
++{
++	ep->speed = (__u16)(speed & 0xFFFF);
++	ep->speed_hi = (__u16)(speed >> 16);
++}
++
++static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
++{
++	return (ep->speed_hi << 16) | ep->speed;
++}
++
++/* Device supports clause 22 register access to PHY or peripherals
++ * using the interface defined in <linux/mii.h>.  This should not be
++ * set if there are known to be no such peripherals present or if
++ * the driver only emulates clause 22 registers for compatibility.
++ */
++#define ETH_MDIO_SUPPORTS_C22	1
++
++/* Device supports clause 45 register access to PHY or peripherals
++ * using the interface defined in <linux/mii.h> and <linux/mdio.h>.
++ * This should not be set if there are known to be no such peripherals
++ * present.
++ */
++#define ETH_MDIO_SUPPORTS_C45	2
++
++#define ETHTOOL_FWVERS_LEN	32
++#define ETHTOOL_BUSINFO_LEN	32
++#define ETHTOOL_EROMVERS_LEN	32
++
++/**
++ * struct ethtool_drvinfo - general driver and device information
++ * @cmd: Command number = %ETHTOOL_GDRVINFO
++ * @driver: Driver short name.  This should normally match the name
++ *	in its bus driver structure (e.g. pci_driver::name).  Must
++ *	not be an empty string.
++ * @version: Driver version string; may be an empty string
++ * @fw_version: Firmware version string; may be an empty string
++ * @erom_version: Expansion ROM version string; may be an empty string
++ * @bus_info: Device bus address.  This should match the dev_name()
++ *	string for the underlying bus device, if there is one.  May be
++ *	an empty string.
++ * @n_priv_flags: Number of flags valid for %ETHTOOL_GPFLAGS and
++ *	%ETHTOOL_SPFLAGS commands; also the number of strings in the
++ *	%ETH_SS_PRIV_FLAGS set
++ * @n_stats: Number of u64 statistics returned by the %ETHTOOL_GSTATS
++ *	command; also the number of strings in the %ETH_SS_STATS set
++ * @testinfo_len: Number of results returned by the %ETHTOOL_TEST
++ *	command; also the number of strings in the %ETH_SS_TEST set
++ * @eedump_len: Size of EEPROM accessible through the %ETHTOOL_GEEPROM
++ *	and %ETHTOOL_SEEPROM commands, in bytes
++ * @regdump_len: Size of register dump returned by the %ETHTOOL_GREGS
++ *	command, in bytes
++ *
++ * Users can use the %ETHTOOL_GSSET_INFO command to get the number of
++ * strings in any string set (from Linux 2.6.34).
++ *
++ * Drivers should set at most @driver, @version, @fw_version and
++ * @bus_info in their get_drvinfo() implementation.  The ethtool
++ * core fills in the other fields using other driver operations.
++ */
++struct ethtool_drvinfo {
++	__u32	cmd;
++	char	driver[32];
++	char	version[32];
++	char	fw_version[ETHTOOL_FWVERS_LEN];
++	char	bus_info[ETHTOOL_BUSINFO_LEN];
++	char	erom_version[ETHTOOL_EROMVERS_LEN];
++	char	reserved2[12];
++	__u32	n_priv_flags;
++	__u32	n_stats;
++	__u32	testinfo_len;
++	__u32	eedump_len;
++	__u32	regdump_len;
++};
++
++#define SOPASS_MAX	6
++
++/**
++ * struct ethtool_wolinfo - Wake-On-Lan configuration
++ * @cmd: Command number = %ETHTOOL_GWOL or %ETHTOOL_SWOL
++ * @supported: Bitmask of %WAKE_* flags for supported Wake-On-Lan modes.
++ *	Read-only.
++ * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes.
++ * @sopass: SecureOn(tm) password; meaningful only if %WAKE_MAGICSECURE
++ *	is set in @wolopts.
++ */
++struct ethtool_wolinfo {
++	__u32	cmd;
++	__u32	supported;
++	__u32	wolopts;
++	__u8	sopass[SOPASS_MAX];
++};
++
++/* for passing single values */
++struct ethtool_value {
++	__u32	cmd;
++	__u32	data;
++};
++
++#define PFC_STORM_PREVENTION_AUTO	0xffff
++#define PFC_STORM_PREVENTION_DISABLE	0
++
++enum tunable_id {
++	ETHTOOL_ID_UNSPEC,
++	ETHTOOL_RX_COPYBREAK,
++	ETHTOOL_TX_COPYBREAK,
++	ETHTOOL_PFC_PREVENTION_TOUT, /* timeout in msecs */
++	/*
++	 * Add your fresh new tunable attribute above and remember to update
++	 * tunable_strings[] in net/core/ethtool.c
++	 */
++	__ETHTOOL_TUNABLE_COUNT,
++};
++
++enum tunable_type_id {
++	ETHTOOL_TUNABLE_UNSPEC,
++	ETHTOOL_TUNABLE_U8,
++	ETHTOOL_TUNABLE_U16,
++	ETHTOOL_TUNABLE_U32,
++	ETHTOOL_TUNABLE_U64,
++	ETHTOOL_TUNABLE_STRING,
++	ETHTOOL_TUNABLE_S8,
++	ETHTOOL_TUNABLE_S16,
++	ETHTOOL_TUNABLE_S32,
++	ETHTOOL_TUNABLE_S64,
++};
++
++struct ethtool_tunable {
++	__u32	cmd;
++	__u32	id;
++	__u32	type_id;
++	__u32	len;
++	void	*data[0];
++};
++
++#define DOWNSHIFT_DEV_DEFAULT_COUNT	0xff
++#define DOWNSHIFT_DEV_DISABLE		0
++
++enum phy_tunable_id {
++	ETHTOOL_PHY_ID_UNSPEC,
++	ETHTOOL_PHY_DOWNSHIFT,
++	/*
++	 * Add your fresh new phy tunable attribute above and remember to update
++	 * phy_tunable_strings[] in net/core/ethtool.c
++	 */
++	__ETHTOOL_PHY_TUNABLE_COUNT,
++};
++
++/**
++ * struct ethtool_regs - hardware register dump
++ * @cmd: Command number = %ETHTOOL_GREGS
++ * @version: Dump format version.  This is driver-specific and may
++ *	distinguish different chips/revisions.  Drivers must use new
++ *	version numbers whenever the dump format changes in an
++ *	incompatible way.
++ * @len: On entry, the real length of @data.  On return, the number of
++ *	bytes used.
++ * @data: Buffer for the register dump
++ *
++ * Users should use %ETHTOOL_GDRVINFO to find the maximum length of
++ * a register dump for the interface.  They must allocate the buffer
++ * immediately following this structure.
++ */
++struct ethtool_regs {
++	__u32	cmd;
++	__u32	version;
++	__u32	len;
++	__u8	data[0];
++};
++
++/**
++ * struct ethtool_eeprom - EEPROM dump
++ * @cmd: Command number = %ETHTOOL_GEEPROM, %ETHTOOL_GMODULEEEPROM or
++ *	%ETHTOOL_SEEPROM
++ * @magic: A 'magic cookie' value to guard against accidental changes.
++ *	The value passed in to %ETHTOOL_SEEPROM must match the value
++ *	returned by %ETHTOOL_GEEPROM for the same device.  This is
++ *	unused when @cmd is %ETHTOOL_GMODULEEEPROM.
++ * @offset: Offset within the EEPROM to begin reading/writing, in bytes
++ * @len: On entry, number of bytes to read/write.  On successful
++ *	return, number of bytes actually read/written.  In case of
++ *	error, this may indicate at what point the error occurred.
++ * @data: Buffer to read/write from
++ *
++ * Users may use %ETHTOOL_GDRVINFO or %ETHTOOL_GMODULEINFO to find
++ * the length of an on-board or module EEPROM, respectively.  They
++ * must allocate the buffer immediately following this structure.
++ */
++struct ethtool_eeprom {
++	__u32	cmd;
++	__u32	magic;
++	__u32	offset;
++	__u32	len;
++	__u8	data[0];
++};
++
++/**
++ * struct ethtool_eee - Energy Efficient Ethernet information
++ * @cmd: ETHTOOL_{G,S}EEE
++ * @supported: Mask of %SUPPORTED_* flags for the speed/duplex combinations
++ *	for which there is EEE support.
++ * @advertised: Mask of %ADVERTISED_* flags for the speed/duplex combinations
++ *	advertised as eee capable.
++ * @lp_advertised: Mask of %ADVERTISED_* flags for the speed/duplex
++ *	combinations advertised by the link partner as eee capable.
++ * @eee_active: Result of the eee auto negotiation.
++ * @eee_enabled: EEE configured mode (enabled/disabled).
++ * @tx_lpi_enabled: Whether the interface should assert its tx lpi, given
++ *	that eee was negotiated.
++ * @tx_lpi_timer: Time in microseconds the interface delays prior to asserting
++ *	its tx lpi (after reaching 'idle' state). Effective only when eee
++ *	was negotiated and tx_lpi_enabled was set.
++ */
++struct ethtool_eee {
++	__u32	cmd;
++	__u32	supported;
++	__u32	advertised;
++	__u32	lp_advertised;
++	__u32	eee_active;
++	__u32	eee_enabled;
++	__u32	tx_lpi_enabled;
++	__u32	tx_lpi_timer;
++	__u32	reserved[2];
++};
++
++/**
++ * struct ethtool_modinfo - plugin module eeprom information
++ * @cmd: %ETHTOOL_GMODULEINFO
++ * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx
++ * @eeprom_len: Length of the eeprom
++ *
++ * This structure is used to return the information to
++ * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM.
++ * The type code indicates the eeprom data format
++ */
++struct ethtool_modinfo {
++	__u32   cmd;
++	__u32   type;
++	__u32   eeprom_len;
++	__u32   reserved[8];
++};
++
++/**
++ * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates
++ * @cmd: ETHTOOL_{G,S}COALESCE
++ * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after
++ *	a packet arrives.
++ * @rx_max_coalesced_frames: Maximum number of packets to receive
++ *	before an RX interrupt.
++ * @rx_coalesce_usecs_irq: Same as @rx_coalesce_usecs, except that
++ *	this value applies while an IRQ is being serviced by the host.
++ * @rx_max_coalesced_frames_irq: Same as @rx_max_coalesced_frames,
++ *	except that this value applies while an IRQ is being serviced
++ *	by the host.
++ * @tx_coalesce_usecs: How many usecs to delay a TX interrupt after
++ *	a packet is sent.
++ * @tx_max_coalesced_frames: Maximum number of packets to be sent
++ *	before a TX interrupt.
++ * @tx_coalesce_usecs_irq: Same as @tx_coalesce_usecs, except that
++ *	this value applies while an IRQ is being serviced by the host.
++ * @tx_max_coalesced_frames_irq: Same as @tx_max_coalesced_frames,
++ *	except that this value applies while an IRQ is being serviced
++ *	by the host.
++ * @stats_block_coalesce_usecs: How many usecs to delay in-memory
++ *	statistics block updates.  Some drivers do not have an
++ *	in-memory statistic block, and in such cases this value is
++ *	ignored.  This value must not be zero.
++ * @use_adaptive_rx_coalesce: Enable adaptive RX coalescing.
++ * @use_adaptive_tx_coalesce: Enable adaptive TX coalescing.
++ * @pkt_rate_low: Threshold for low packet rate (packets per second).
++ * @rx_coalesce_usecs_low: How many usecs to delay an RX interrupt after
++ *	a packet arrives, when the packet rate is below @pkt_rate_low.
++ * @rx_max_coalesced_frames_low: Maximum number of packets to be received
++ *	before an RX interrupt, when the packet rate is below @pkt_rate_low.
++ * @tx_coalesce_usecs_low: How many usecs to delay a TX interrupt after
++ *	a packet is sent, when the packet rate is below @pkt_rate_low.
++ * @tx_max_coalesced_frames_low: Maximum nuumber of packets to be sent before
++ *	a TX interrupt, when the packet rate is below @pkt_rate_low.
++ * @pkt_rate_high: Threshold for high packet rate (packets per second).
++ * @rx_coalesce_usecs_high: How many usecs to delay an RX interrupt after
++ *	a packet arrives, when the packet rate is above @pkt_rate_high.
++ * @rx_max_coalesced_frames_high: Maximum number of packets to be received
++ *	before an RX interrupt, when the packet rate is above @pkt_rate_high.
++ * @tx_coalesce_usecs_high: How many usecs to delay a TX interrupt after
++ *	a packet is sent, when the packet rate is above @pkt_rate_high.
++ * @tx_max_coalesced_frames_high: Maximum number of packets to be sent before
++ *	a TX interrupt, when the packet rate is above @pkt_rate_high.
++ * @rate_sample_interval: How often to do adaptive coalescing packet rate
++ *	sampling, measured in seconds.  Must not be zero.
++ *
++ * Each pair of (usecs, max_frames) fields specifies that interrupts
++ * should be coalesced until
++ *	(usecs > 0 && time_since_first_completion >= usecs) ||
++ *	(max_frames > 0 && completed_frames >= max_frames)
++ *
++ * It is illegal to set both usecs and max_frames to zero as this
++ * would cause interrupts to never be generated.  To disable
++ * coalescing, set usecs = 0 and max_frames = 1.
++ *
++ * Some implementations ignore the value of max_frames and use the
++ * condition time_since_first_completion >= usecs
++ *
++ * This is deprecated.  Drivers for hardware that does not support
++ * counting completions should validate that max_frames == !rx_usecs.
++ *
++ * Adaptive RX/TX coalescing is an algorithm implemented by some
++ * drivers to improve latency under low packet rates and improve
++ * throughput under high packet rates.  Some drivers only implement
++ * one of RX or TX adaptive coalescing.  Anything not implemented by
++ * the driver causes these values to be silently ignored.
++ *
++ * When the packet rate is below @pkt_rate_high but above
++ * @pkt_rate_low (both measured in packets per second) the
++ * normal {rx,tx}_* coalescing parameters are used.
++ */
++struct ethtool_coalesce {
++	__u32	cmd;
++	__u32	rx_coalesce_usecs;
++	__u32	rx_max_coalesced_frames;
++	__u32	rx_coalesce_usecs_irq;
++	__u32	rx_max_coalesced_frames_irq;
++	__u32	tx_coalesce_usecs;
++	__u32	tx_max_coalesced_frames;
++	__u32	tx_coalesce_usecs_irq;
++	__u32	tx_max_coalesced_frames_irq;
++	__u32	stats_block_coalesce_usecs;
++	__u32	use_adaptive_rx_coalesce;
++	__u32	use_adaptive_tx_coalesce;
++	__u32	pkt_rate_low;
++	__u32	rx_coalesce_usecs_low;
++	__u32	rx_max_coalesced_frames_low;
++	__u32	tx_coalesce_usecs_low;
++	__u32	tx_max_coalesced_frames_low;
++	__u32	pkt_rate_high;
++	__u32	rx_coalesce_usecs_high;
++	__u32	rx_max_coalesced_frames_high;
++	__u32	tx_coalesce_usecs_high;
++	__u32	tx_max_coalesced_frames_high;
++	__u32	rate_sample_interval;
++};
++
++/**
++ * struct ethtool_ringparam - RX/TX ring parameters
++ * @cmd: Command number = %ETHTOOL_GRINGPARAM or %ETHTOOL_SRINGPARAM
++ * @rx_max_pending: Maximum supported number of pending entries per
++ *	RX ring.  Read-only.
++ * @rx_mini_max_pending: Maximum supported number of pending entries
++ *	per RX mini ring.  Read-only.
++ * @rx_jumbo_max_pending: Maximum supported number of pending entries
++ *	per RX jumbo ring.  Read-only.
++ * @tx_max_pending: Maximum supported number of pending entries per
++ *	TX ring.  Read-only.
++ * @rx_pending: Current maximum number of pending entries per RX ring
++ * @rx_mini_pending: Current maximum number of pending entries per RX
++ *	mini ring
++ * @rx_jumbo_pending: Current maximum number of pending entries per RX
++ *	jumbo ring
++ * @tx_pending: Current maximum supported number of pending entries
++ *	per TX ring
++ *
++ * If the interface does not have separate RX mini and/or jumbo rings,
++ * @rx_mini_max_pending and/or @rx_jumbo_max_pending will be 0.
++ *
++ * There may also be driver-dependent minimum values for the number
++ * of entries per ring.
++ */
++struct ethtool_ringparam {
++	__u32	cmd;
++	__u32	rx_max_pending;
++	__u32	rx_mini_max_pending;
++	__u32	rx_jumbo_max_pending;
++	__u32	tx_max_pending;
++	__u32	rx_pending;
++	__u32	rx_mini_pending;
++	__u32	rx_jumbo_pending;
++	__u32	tx_pending;
++};
++
++/**
++ * struct ethtool_channels - configuring number of network channel
++ * @cmd: ETHTOOL_{G,S}CHANNELS
++ * @max_rx: Read only. Maximum number of receive channel the driver support.
++ * @max_tx: Read only. Maximum number of transmit channel the driver support.
++ * @max_other: Read only. Maximum number of other channel the driver support.
++ * @max_combined: Read only. Maximum number of combined channel the driver
++ *	support. Set of queues RX, TX or other.
++ * @rx_count: Valid values are in the range 1 to the max_rx.
++ * @tx_count: Valid values are in the range 1 to the max_tx.
++ * @other_count: Valid values are in the range 1 to the max_other.
++ * @combined_count: Valid values are in the range 1 to the max_combined.
++ *
++ * This can be used to configure RX, TX and other channels.
++ */
++
++struct ethtool_channels {
++	__u32	cmd;
++	__u32	max_rx;
++	__u32	max_tx;
++	__u32	max_other;
++	__u32	max_combined;
++	__u32	rx_count;
++	__u32	tx_count;
++	__u32	other_count;
++	__u32	combined_count;
++};
++
++/**
++ * struct ethtool_pauseparam - Ethernet pause (flow control) parameters
++ * @cmd: Command number = %ETHTOOL_GPAUSEPARAM or %ETHTOOL_SPAUSEPARAM
++ * @autoneg: Flag to enable autonegotiation of pause frame use
++ * @rx_pause: Flag to enable reception of pause frames
++ * @tx_pause: Flag to enable transmission of pause frames
++ *
++ * Drivers should reject a non-zero setting of @autoneg when
++ * autoneogotiation is disabled (or not supported) for the link.
++ *
++ * If the link is autonegotiated, drivers should use
++ * mii_advertise_flowctrl() or similar code to set the advertised
++ * pause frame capabilities based on the @rx_pause and @tx_pause flags,
++ * even if @autoneg is zero.  They should also allow the advertised
++ * pause frame capabilities to be controlled directly through the
++ * advertising field of &struct ethtool_cmd.
++ *
++ * If @autoneg is non-zero, the MAC is configured to send and/or
++ * receive pause frames according to the result of autonegotiation.
++ * Otherwise, it is configured directly based on the @rx_pause and
++ * @tx_pause flags.
++ */
++struct ethtool_pauseparam {
++	__u32	cmd;
++	__u32	autoneg;
++	__u32	rx_pause;
++	__u32	tx_pause;
++};
++
++#define ETH_GSTRING_LEN		32
++
++/**
++ * enum ethtool_stringset - string set ID
++ * @ETH_SS_TEST: Self-test result names, for use with %ETHTOOL_TEST
++ * @ETH_SS_STATS: Statistic names, for use with %ETHTOOL_GSTATS
++ * @ETH_SS_PRIV_FLAGS: Driver private flag names, for use with
++ *	%ETHTOOL_GPFLAGS and %ETHTOOL_SPFLAGS
++ * @ETH_SS_NTUPLE_FILTERS: Previously used with %ETHTOOL_GRXNTUPLE;
++ *	now deprecated
++ * @ETH_SS_FEATURES: Device feature names
++ * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
++ * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
++ * @ETH_SS_PHY_TUNABLES: PHY tunable names
++ */
++enum ethtool_stringset {
++	ETH_SS_TEST		= 0,
++	ETH_SS_STATS,
++	ETH_SS_PRIV_FLAGS,
++	ETH_SS_NTUPLE_FILTERS,
++	ETH_SS_FEATURES,
++	ETH_SS_RSS_HASH_FUNCS,
++	ETH_SS_TUNABLES,
++	ETH_SS_PHY_STATS,
++	ETH_SS_PHY_TUNABLES,
++};
++
++/**
++ * struct ethtool_gstrings - string set for data tagging
++ * @cmd: Command number = %ETHTOOL_GSTRINGS
++ * @string_set: String set ID; one of &enum ethtool_stringset
++ * @len: On return, the number of strings in the string set
++ * @data: Buffer for strings.  Each string is null-padded to a size of
++ *	%ETH_GSTRING_LEN.
++ *
++ * Users must use %ETHTOOL_GSSET_INFO to find the number of strings in
++ * the string set.  They must allocate a buffer of the appropriate
++ * size immediately following this structure.
++ */
++struct ethtool_gstrings {
++	__u32	cmd;
++	__u32	string_set;
++	__u32	len;
++	__u8	data[0];
++};
++
++/**
++ * struct ethtool_sset_info - string set information
++ * @cmd: Command number = %ETHTOOL_GSSET_INFO
++ * @sset_mask: On entry, a bitmask of string sets to query, with bits
++ *	numbered according to &enum ethtool_stringset.  On return, a
++ *	bitmask of those string sets queried that are supported.
++ * @data: Buffer for string set sizes.  On return, this contains the
++ *	size of each string set that was queried and supported, in
++ *	order of ID.
++ *
++ * Example: The user passes in @sset_mask = 0x7 (sets 0, 1, 2) and on
++ * return @sset_mask == 0x6 (sets 1, 2).  Then @data[0] contains the
++ * size of set 1 and @data[1] contains the size of set 2.
++ *
++ * Users must allocate a buffer of the appropriate size (4 * number of
++ * sets queried) immediately following this structure.
++ */
++struct ethtool_sset_info {
++	__u32	cmd;
++	__u32	reserved;
++	__u64	sset_mask;
++	__u32	data[0];
++};
++
++/**
++ * enum ethtool_test_flags - flags definition of ethtool_test
++ * @ETH_TEST_FL_OFFLINE: if set perform online and offline tests, otherwise
++ *	only online tests.
++ * @ETH_TEST_FL_FAILED: Driver set this flag if test fails.
++ * @ETH_TEST_FL_EXTERNAL_LB: Application request to perform external loopback
++ *	test.
++ * @ETH_TEST_FL_EXTERNAL_LB_DONE: Driver performed the external loopback test
++ */
++
++enum ethtool_test_flags {
++	ETH_TEST_FL_OFFLINE	= (1 << 0),
++	ETH_TEST_FL_FAILED	= (1 << 1),
++	ETH_TEST_FL_EXTERNAL_LB	= (1 << 2),
++	ETH_TEST_FL_EXTERNAL_LB_DONE	= (1 << 3),
++};
++
++/**
++ * struct ethtool_test - device self-test invocation
++ * @cmd: Command number = %ETHTOOL_TEST
++ * @flags: A bitmask of flags from &enum ethtool_test_flags.  Some
++ *	flags may be set by the user on entry; others may be set by
++ *	the driver on return.
++ * @len: On return, the number of test results
++ * @data: Array of test results
++ *
++ * Users must use %ETHTOOL_GSSET_INFO or %ETHTOOL_GDRVINFO to find the
++ * number of test results that will be returned.  They must allocate a
++ * buffer of the appropriate size (8 * number of results) immediately
++ * following this structure.
++ */
++struct ethtool_test {
++	__u32	cmd;
++	__u32	flags;
++	__u32	reserved;
++	__u32	len;
++	__u64	data[0];
++};
++
++/**
++ * struct ethtool_stats - device-specific statistics
++ * @cmd: Command number = %ETHTOOL_GSTATS
++ * @n_stats: On return, the number of statistics
++ * @data: Array of statistics
++ *
++ * Users must use %ETHTOOL_GSSET_INFO or %ETHTOOL_GDRVINFO to find the
++ * number of statistics that will be returned.  They must allocate a
++ * buffer of the appropriate size (8 * number of statistics)
++ * immediately following this structure.
++ */
++struct ethtool_stats {
++	__u32	cmd;
++	__u32	n_stats;
++	__u64	data[0];
++};
++
++/**
++ * struct ethtool_perm_addr - permanent hardware address
++ * @cmd: Command number = %ETHTOOL_GPERMADDR
++ * @size: On entry, the size of the buffer.  On return, the size of the
++ *	address.  The command fails if the buffer is too small.
++ * @data: Buffer for the address
++ *
++ * Users must allocate the buffer immediately following this structure.
++ * A buffer size of %MAX_ADDR_LEN should be sufficient for any address
++ * type.
++ */
++struct ethtool_perm_addr {
++	__u32	cmd;
++	__u32	size;
++	__u8	data[0];
++};
++
++/* boolean flags controlling per-interface behavior characteristics.
++ * When reading, the flag indicates whether or not a certain behavior
++ * is enabled/present.  When writing, the flag indicates whether
++ * or not the driver should turn on (set) or off (clear) a behavior.
++ *
++ * Some behaviors may read-only (unconditionally absent or present).
++ * If such is the case, return EINVAL in the set-flags operation if the
++ * flag differs from the read-only value.
++ */
++enum ethtool_flags {
++	ETH_FLAG_TXVLAN		= (1 << 7),	/* TX VLAN offload enabled */
++	ETH_FLAG_RXVLAN		= (1 << 8),	/* RX VLAN offload enabled */
++	ETH_FLAG_LRO		= (1 << 15),	/* LRO is enabled */
++	ETH_FLAG_NTUPLE		= (1 << 27),	/* N-tuple filters enabled */
++	ETH_FLAG_RXHASH		= (1 << 28),
++};
++
++/* The following structures are for supporting RX network flow
++ * classification and RX n-tuple configuration. Note, all multibyte
++ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
++ * be in network byte order.
++ */
++
++/**
++ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
++ * @ip4src: Source host
++ * @ip4dst: Destination host
++ * @psrc: Source port
++ * @pdst: Destination port
++ * @tos: Type-of-service
++ *
++ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
++ */
++struct ethtool_tcpip4_spec {
++	__be32	ip4src;
++	__be32	ip4dst;
++	__be16	psrc;
++	__be16	pdst;
++	__u8    tos;
++};
++
++/**
++ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
++ * @ip4src: Source host
++ * @ip4dst: Destination host
++ * @spi: Security parameters index
++ * @tos: Type-of-service
++ *
++ * This can be used to specify an IPsec transport or tunnel over IPv4.
++ */
++struct ethtool_ah_espip4_spec {
++	__be32	ip4src;
++	__be32	ip4dst;
++	__be32	spi;
++	__u8    tos;
++};
++
++#define	ETH_RX_NFC_IP4	1
++
++/**
++ * struct ethtool_usrip4_spec - general flow specification for IPv4
++ * @ip4src: Source host
++ * @ip4dst: Destination host
++ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
++ * @tos: Type-of-service
++ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
++ * @proto: Transport protocol number; mask must be 0
++ */
++struct ethtool_usrip4_spec {
++	__be32	ip4src;
++	__be32	ip4dst;
++	__be32	l4_4_bytes;
++	__u8    tos;
++	__u8    ip_ver;
++	__u8    proto;
++};
++
++/**
++ * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
++ * @ip6src: Source host
++ * @ip6dst: Destination host
++ * @psrc: Source port
++ * @pdst: Destination port
++ * @tclass: Traffic Class
++ *
++ * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow.
++ */
++struct ethtool_tcpip6_spec {
++	__be32	ip6src[4];
++	__be32	ip6dst[4];
++	__be16	psrc;
++	__be16	pdst;
++	__u8    tclass;
++};
++
++/**
++ * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6
++ * @ip6src: Source host
++ * @ip6dst: Destination host
++ * @spi: Security parameters index
++ * @tclass: Traffic Class
++ *
++ * This can be used to specify an IPsec transport or tunnel over IPv6.
++ */
++struct ethtool_ah_espip6_spec {
++	__be32	ip6src[4];
++	__be32	ip6dst[4];
++	__be32	spi;
++	__u8    tclass;
++};
++
++/**
++ * struct ethtool_usrip6_spec - general flow specification for IPv6
++ * @ip6src: Source host
++ * @ip6dst: Destination host
++ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
++ * @tclass: Traffic Class
++ * @l4_proto: Transport protocol number (nexthdr after any Extension Headers)
++ */
++struct ethtool_usrip6_spec {
++	__be32	ip6src[4];
++	__be32	ip6dst[4];
++	__be32	l4_4_bytes;
++	__u8    tclass;
++	__u8    l4_proto;
++};
++
++union ethtool_flow_union {
++	struct ethtool_tcpip4_spec		tcp_ip4_spec;
++	struct ethtool_tcpip4_spec		udp_ip4_spec;
++	struct ethtool_tcpip4_spec		sctp_ip4_spec;
++	struct ethtool_ah_espip4_spec		ah_ip4_spec;
++	struct ethtool_ah_espip4_spec		esp_ip4_spec;
++	struct ethtool_usrip4_spec		usr_ip4_spec;
++	struct ethtool_tcpip6_spec		tcp_ip6_spec;
++	struct ethtool_tcpip6_spec		udp_ip6_spec;
++	struct ethtool_tcpip6_spec		sctp_ip6_spec;
++	struct ethtool_ah_espip6_spec		ah_ip6_spec;
++	struct ethtool_ah_espip6_spec		esp_ip6_spec;
++	struct ethtool_usrip6_spec		usr_ip6_spec;
++	struct ethhdr				ether_spec;
++	__u8					hdata[52];
++};
++
++/**
++ * struct ethtool_flow_ext - additional RX flow fields
++ * @h_dest: destination MAC address
++ * @vlan_etype: VLAN EtherType
++ * @vlan_tci: VLAN tag control information
++ * @data: user defined data
++ *
++ * Note, @vlan_etype, @vlan_tci, and @data are only valid if %FLOW_EXT
++ * is set in &struct ethtool_rx_flow_spec @flow_type.
++ * @h_dest is valid if %FLOW_MAC_EXT is set.
++ */
++struct ethtool_flow_ext {
++	__u8		padding[2];
++	unsigned char	h_dest[ETH_ALEN];
++	__be16		vlan_etype;
++	__be16		vlan_tci;
++	__be32		data[2];
++};
++
++/**
++ * struct ethtool_rx_flow_spec - classification rule for RX flows
++ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
++ * @h_u: Flow fields to match (dependent on @flow_type)
++ * @h_ext: Additional fields to match
++ * @m_u: Masks for flow field bits to be matched
++ * @m_ext: Masks for additional field bits to be matched
++ *	Note, all additional fields must be ignored unless @flow_type
++ *	includes the %FLOW_EXT or %FLOW_MAC_EXT flag
++ *	(see &struct ethtool_flow_ext description).
++ * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
++ *	if packets should be discarded, or %RX_CLS_FLOW_WAKE if the
++ *	packets should be used for Wake-on-LAN with %WAKE_FILTER
++ * @location: Location of rule in the table.  Locations must be
++ *	numbered such that a flow matching multiple rules will be
++ *	classified according to the first (lowest numbered) rule.
++ */
++struct ethtool_rx_flow_spec {
++	__u32		flow_type;
++	union ethtool_flow_union h_u;
++	struct ethtool_flow_ext h_ext;
++	union ethtool_flow_union m_u;
++	struct ethtool_flow_ext m_ext;
++	__u64		ring_cookie;
++	__u32		location;
++};
++
++/* How rings are laid out when accessing virtual functions or
++ * offloaded queues is device specific. To allow users to do flow
++ * steering and specify these queues the ring cookie is partitioned
++ * into a 32bit queue index with an 8 bit virtual function id.
++ * This also leaves the 3bytes for further specifiers. It is possible
++ * future devices may support more than 256 virtual functions if
++ * devices start supporting PCIe w/ARI. However at the moment I
++ * do not know of any devices that support this so I do not reserve
++ * space for this at this time. If a future patch consumes the next
++ * byte it should be aware of this possibility.
++ */
++#define ETHTOOL_RX_FLOW_SPEC_RING	0x00000000FFFFFFFFLL
++#define ETHTOOL_RX_FLOW_SPEC_RING_VF	0x000000FF00000000LL
++#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32
++static inline __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
++{
++	return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie;
++}
++
++static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
++{
++	return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >>
++				ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
++}
++
++/**
++ * struct ethtool_rxnfc - command to get or set RX flow classification rules
++ * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
++ *	%ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
++ *	%ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
++ * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
++ * @data: Command-dependent value
++ * @fs: Flow classification rule
++ * @rss_context: RSS context to be affected
++ * @rule_cnt: Number of rules to be affected
++ * @rule_locs: Array of used rule locations
++ *
++ * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
++ * the fields included in the flow hash, e.g. %RXH_IP_SRC.  The following
++ * structure fields must not be used, except that if @flow_type includes
++ * the %FLOW_RSS flag, then @rss_context determines which RSS context to
++ * act on.
++ *
++ * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
++ * on return.
++ *
++ * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
++ * rules on return.  If @data is non-zero on return then it is the
++ * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the
++ * driver supports any special location values.  If that flag is not
++ * set in @data then special location values should not be used.
++ *
++ * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
++ * existing rule on entry and @fs contains the rule on return; if
++ * @fs.@flow_type includes the %FLOW_RSS flag, then @rss_context is
++ * filled with the RSS context ID associated with the rule.
++ *
++ * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
++ * user buffer for @rule_locs on entry.  On return, @data is the size
++ * of the rule table, @rule_cnt is the number of defined rules, and
++ * @rule_locs contains the locations of the defined rules.  Drivers
++ * must use the second parameter to get_rxnfc() instead of @rule_locs.
++ *
++ * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
++ * @fs.@location either specifies the location to use or is a special
++ * location value with %RX_CLS_LOC_SPECIAL flag set.  On return,
++ * @fs.@location is the actual rule location.  If @fs.@flow_type
++ * includes the %FLOW_RSS flag, @rss_context is the RSS context ID to
++ * use for flow spreading traffic which matches this rule.  The value
++ * from the rxfh indirection table will be added to @fs.@ring_cookie
++ * to choose which ring to deliver to.
++ *
++ * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
++ * existing rule on entry.
++ *
++ * A driver supporting the special location values for
++ * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused
++ * location, and may remove a rule at a later location (lower
++ * priority) that matches exactly the same set of flows.  The special
++ * values are %RX_CLS_LOC_ANY, selecting any location;
++ * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum
++ * priority); and %RX_CLS_LOC_LAST, selecting the last suitable
++ * location (minimum priority).  Additional special values may be
++ * defined in future and drivers must return -%EINVAL for any
++ * unrecognised value.
++ */
++struct ethtool_rxnfc {
++	__u32				cmd;
++	__u32				flow_type;
++	__u64				data;
++	struct ethtool_rx_flow_spec	fs;
++	union {
++		__u32			rule_cnt;
++		__u32			rss_context;
++	};
++	__u32				rule_locs[0];
++};
++
++
++/**
++ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
++ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
++ * @size: On entry, the array size of the user buffer, which may be zero.
++ *	On return from %ETHTOOL_GRXFHINDIR, the array size of the hardware
++ *	indirection table.
++ * @ring_index: RX ring/queue index for each hash value
++ *
++ * For %ETHTOOL_GRXFHINDIR, a @size of zero means that only the size
++ * should be returned.  For %ETHTOOL_SRXFHINDIR, a @size of zero means
++ * the table should be reset to default values.  This last feature
++ * is not supported by the original implementations.
++ */
++struct ethtool_rxfh_indir {
++	__u32	cmd;
++	__u32	size;
++	__u32	ring_index[0];
++};
++
++/**
++ * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
++ * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
++ * @rss_context: RSS context identifier.  Context 0 is the default for normal
++ *	traffic; other contexts can be referenced as the destination for RX flow
++ *	classification rules.  %ETH_RXFH_CONTEXT_ALLOC is used with command
++ *	%ETHTOOL_SRSSH to allocate a new RSS context; on return this field will
++ *	contain the ID of the newly allocated context.
++ * @indir_size: On entry, the array size of the user buffer for the
++ *	indirection table, which may be zero, or (for %ETHTOOL_SRSSH),
++ *	%ETH_RXFH_INDIR_NO_CHANGE.  On return from %ETHTOOL_GRSSH,
++ *	the array size of the hardware indirection table.
++ * @key_size: On entry, the array size of the user buffer for the hash key,
++ *	which may be zero.  On return from %ETHTOOL_GRSSH, the size of the
++ *	hardware hash key.
++ * @hfunc: Defines the current RSS hash function used by HW (or to be set to).
++ *	Valid values are one of the %ETH_RSS_HASH_*.
++ * @rsvd:	Reserved for future extensions.
++ * @rss_config: RX ring/queue index for each hash value i.e., indirection table
++ *	of @indir_size __u32 elements, followed by hash key of @key_size
++ *	bytes.
++ *
++ * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the
++ * size should be returned.  For %ETHTOOL_SRSSH, an @indir_size of
++ * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested
++ * and a @indir_size of zero means the indir table should be reset to default
++ * values (if @rss_context == 0) or that the RSS context should be deleted.
++ * An hfunc of zero means that hash function setting is not requested.
++ */
++struct ethtool_rxfh {
++	__u32   cmd;
++	__u32	rss_context;
++	__u32   indir_size;
++	__u32   key_size;
++	__u8	hfunc;
++	__u8	rsvd8[3];
++	__u32	rsvd32;
++	__u32   rss_config[0];
++};
++#define ETH_RXFH_CONTEXT_ALLOC		0xffffffff
++#define ETH_RXFH_INDIR_NO_CHANGE	0xffffffff
++
++/**
++ * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
++ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
++ * @h_u: Flow field values to match (dependent on @flow_type)
++ * @m_u: Masks for flow field value bits to be ignored
++ * @vlan_tag: VLAN tag to match
++ * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
++ * @data: Driver-dependent data to match
++ * @data_mask: Mask for driver-dependent data bits to be ignored
++ * @action: RX ring/queue index to deliver to (non-negative) or other action
++ *	(negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
++ *
++ * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
++ * a field value and mask are both zero this is treated as if all mask
++ * bits are set i.e. the field is ignored.
++ */
++struct ethtool_rx_ntuple_flow_spec {
++	__u32		 flow_type;
++	union {
++		struct ethtool_tcpip4_spec		tcp_ip4_spec;
++		struct ethtool_tcpip4_spec		udp_ip4_spec;
++		struct ethtool_tcpip4_spec		sctp_ip4_spec;
++		struct ethtool_ah_espip4_spec		ah_ip4_spec;
++		struct ethtool_ah_espip4_spec		esp_ip4_spec;
++		struct ethtool_usrip4_spec		usr_ip4_spec;
++		struct ethhdr				ether_spec;
++		__u8					hdata[72];
++	} h_u, m_u;
++
++	__u16	        vlan_tag;
++	__u16	        vlan_tag_mask;
++	__u64		data;
++	__u64		data_mask;
++
++	__s32		action;
++#define ETHTOOL_RXNTUPLE_ACTION_DROP	(-1)	/* drop packet */
++#define ETHTOOL_RXNTUPLE_ACTION_CLEAR	(-2)	/* clear filter */
++};
++
++/**
++ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
++ * @cmd: Command number - %ETHTOOL_SRXNTUPLE
++ * @fs: Flow filter specification
++ */
++struct ethtool_rx_ntuple {
++	__u32					cmd;
++	struct ethtool_rx_ntuple_flow_spec	fs;
++};
++
++#define ETHTOOL_FLASH_MAX_FILENAME	128
++enum ethtool_flash_op_type {
++	ETHTOOL_FLASH_ALL_REGIONS	= 0,
++};
++
++/* for passing firmware flashing related parameters */
++struct ethtool_flash {
++	__u32	cmd;
++	__u32	region;
++	char	data[ETHTOOL_FLASH_MAX_FILENAME];
++};
++
++/**
++ * struct ethtool_dump - used for retrieving, setting device dump
++ * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or
++ * 	%ETHTOOL_SET_DUMP
++ * @version: FW version of the dump, filled in by driver
++ * @flag: driver dependent flag for dump setting, filled in by driver during
++ *        get and filled in by ethtool for set operation.
++ *        flag must be initialized by macro ETH_FW_DUMP_DISABLE value when
++ *        firmware dump is disabled.
++ * @len: length of dump data, used as the length of the user buffer on entry to
++ * 	 %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver
++ * 	 for %ETHTOOL_GET_DUMP_FLAG command
++ * @data: data collected for get dump data operation
++ */
++struct ethtool_dump {
++	__u32	cmd;
++	__u32	version;
++	__u32	flag;
++	__u32	len;
++	__u8	data[0];
++};
++
++#define ETH_FW_DUMP_DISABLE 0
++
++/* for returning and changing feature sets */
++
++/**
++ * struct ethtool_get_features_block - block with state of 32 features
++ * @available: mask of changeable features
++ * @requested: mask of features requested to be enabled if possible
++ * @active: mask of currently enabled features
++ * @never_changed: mask of features not changeable for any device
++ */
++struct ethtool_get_features_block {
++	__u32	available;
++	__u32	requested;
++	__u32	active;
++	__u32	never_changed;
++};
++
++/**
++ * struct ethtool_gfeatures - command to get state of device's features
++ * @cmd: command number = %ETHTOOL_GFEATURES
++ * @size: On entry, the number of elements in the features[] array;
++ *	on return, the number of elements in features[] needed to hold
++ *	all features
++ * @features: state of features
++ */
++struct ethtool_gfeatures {
++	__u32	cmd;
++	__u32	size;
++	struct ethtool_get_features_block features[0];
++};
++
++/**
++ * struct ethtool_set_features_block - block with request for 32 features
++ * @valid: mask of features to be changed
++ * @requested: values of features to be changed
++ */
++struct ethtool_set_features_block {
++	__u32	valid;
++	__u32	requested;
++};
++
++/**
++ * struct ethtool_sfeatures - command to request change in device's features
++ * @cmd: command number = %ETHTOOL_SFEATURES
++ * @size: array size of the features[] array
++ * @features: feature change masks
++ */
++struct ethtool_sfeatures {
++	__u32	cmd;
++	__u32	size;
++	struct ethtool_set_features_block features[0];
++};
++
++/**
++ * struct ethtool_ts_info - holds a device's timestamping and PHC association
++ * @cmd: command number = %ETHTOOL_GET_TS_INFO
++ * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING flags
++ * @phc_index: device index of the associated PHC, or -1 if there is none
++ * @tx_types: bit mask of the supported hwtstamp_tx_types enumeration values
++ * @rx_filters: bit mask of the supported hwtstamp_rx_filters enumeration values
++ *
++ * The bits in the 'tx_types' and 'rx_filters' fields correspond to
++ * the 'hwtstamp_tx_types' and 'hwtstamp_rx_filters' enumeration values,
++ * respectively.  For example, if the device supports HWTSTAMP_TX_ON,
++ * then (1 << HWTSTAMP_TX_ON) in 'tx_types' will be set.
++ *
++ * Drivers should only report the filters they actually support without
++ * upscaling in the SIOCSHWTSTAMP ioctl. If the SIOCSHWSTAMP request for
++ * HWTSTAMP_FILTER_V1_SYNC is supported by HWTSTAMP_FILTER_V1_EVENT, then the
++ * driver should only report HWTSTAMP_FILTER_V1_EVENT in this op.
++ */
++struct ethtool_ts_info {
++	__u32	cmd;
++	__u32	so_timestamping;
++	__s32	phc_index;
++	__u32	tx_types;
++	__u32	tx_reserved[3];
++	__u32	rx_filters;
++	__u32	rx_reserved[3];
++};
++
++/*
++ * %ETHTOOL_SFEATURES changes features present in features[].valid to the
++ * values of corresponding bits in features[].requested. Bits in .requested
++ * not set in .valid or not changeable are ignored.
++ *
++ * Returns %EINVAL when .valid contains undefined or never-changeable bits
++ * or size is not equal to required number of features words (32-bit blocks).
++ * Returns >= 0 if request was completed; bits set in the value mean:
++ *   %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not
++ *	changeable (not present in %ETHTOOL_GFEATURES' features[].available)
++ *	those bits were ignored.
++ *   %ETHTOOL_F_WISH - some or all changes requested were recorded but the
++ *      resulting state of bits masked by .valid is not equal to .requested.
++ *      Probably there are other device-specific constraints on some features
++ *      in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered
++ *      here as though ignored bits were cleared.
++ *   %ETHTOOL_F_COMPAT - some or all changes requested were made by calling
++ *      compatibility functions. Requested offload state cannot be properly
++ *      managed by kernel.
++ *
++ * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of
++ * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands
++ * for ETH_SS_FEATURES string set. First entry in the table corresponds to least
++ * significant bit in features[0] fields. Empty strings mark undefined features.
++ */
++enum ethtool_sfeatures_retval_bits {
++	ETHTOOL_F_UNSUPPORTED__BIT,
++	ETHTOOL_F_WISH__BIT,
++	ETHTOOL_F_COMPAT__BIT,
++};
++
++#define ETHTOOL_F_UNSUPPORTED   (1 << ETHTOOL_F_UNSUPPORTED__BIT)
++#define ETHTOOL_F_WISH          (1 << ETHTOOL_F_WISH__BIT)
++#define ETHTOOL_F_COMPAT        (1 << ETHTOOL_F_COMPAT__BIT)
++
++#define MAX_NUM_QUEUE		4096
++
++/**
++ * struct ethtool_per_queue_op - apply sub command to the queues in mask.
++ * @cmd: ETHTOOL_PERQUEUE
++ * @sub_command: the sub command which apply to each queues
++ * @queue_mask: Bitmap of the queues which sub command apply to
++ * @data: A complete command structure following for each of the queues addressed
++ */
++struct ethtool_per_queue_op {
++	__u32	cmd;
++	__u32	sub_command;
++	__u32	queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)];
++	char	data[];
++};
++
++/**
++ * struct ethtool_fecparam - Ethernet forward error correction(fec) parameters
++ * @cmd: Command number = %ETHTOOL_GFECPARAM or %ETHTOOL_SFECPARAM
++ * @active_fec: FEC mode which is active on porte
++ * @fec: Bitmask of supported/configured FEC modes
++ * @rsvd: Reserved for future extensions. i.e FEC bypass feature.
++ *
++ * Drivers should reject a non-zero setting of @autoneg when
++ * autoneogotiation is disabled (or not supported) for the link.
++ *
++ */
++struct ethtool_fecparam {
++	__u32   cmd;
++	/* bitmask of FEC modes */
++	__u32   active_fec;
++	__u32   fec;
++	__u32   reserved;
++};
++
++/**
++ * enum ethtool_fec_config_bits - flags definition of ethtool_fec_configuration
++ * @ETHTOOL_FEC_NONE: FEC mode configuration is not supported
++ * @ETHTOOL_FEC_AUTO: Default/Best FEC mode provided by driver
++ * @ETHTOOL_FEC_OFF: No FEC Mode
++ * @ETHTOOL_FEC_RS: Reed-Solomon Forward Error Detection mode
++ * @ETHTOOL_FEC_BASER: Base-R/Reed-Solomon Forward Error Detection mode
++ */
++enum ethtool_fec_config_bits {
++	ETHTOOL_FEC_NONE_BIT,
++	ETHTOOL_FEC_AUTO_BIT,
++	ETHTOOL_FEC_OFF_BIT,
++	ETHTOOL_FEC_RS_BIT,
++	ETHTOOL_FEC_BASER_BIT,
++};
++
++#define ETHTOOL_FEC_NONE		(1 << ETHTOOL_FEC_NONE_BIT)
++#define ETHTOOL_FEC_AUTO		(1 << ETHTOOL_FEC_AUTO_BIT)
++#define ETHTOOL_FEC_OFF			(1 << ETHTOOL_FEC_OFF_BIT)
++#define ETHTOOL_FEC_RS			(1 << ETHTOOL_FEC_RS_BIT)
++#define ETHTOOL_FEC_BASER		(1 << ETHTOOL_FEC_BASER_BIT)
++
++/* CMDs currently supported */
++#define ETHTOOL_GSET		0x00000001 /* DEPRECATED, Get settings.
++					    * Please use ETHTOOL_GLINKSETTINGS
++					    */
++#define ETHTOOL_SSET		0x00000002 /* DEPRECATED, Set settings.
++					    * Please use ETHTOOL_SLINKSETTINGS
++					    */
++#define ETHTOOL_GDRVINFO	0x00000003 /* Get driver info. */
++#define ETHTOOL_GREGS		0x00000004 /* Get NIC registers. */
++#define ETHTOOL_GWOL		0x00000005 /* Get wake-on-lan options. */
++#define ETHTOOL_SWOL		0x00000006 /* Set wake-on-lan options. */
++#define ETHTOOL_GMSGLVL		0x00000007 /* Get driver message level */
++#define ETHTOOL_SMSGLVL		0x00000008 /* Set driver msg level. */
++#define ETHTOOL_NWAY_RST	0x00000009 /* Restart autonegotiation. */
++/* Get link status for host, i.e. whether the interface *and* the
++ * physical port (if there is one) are up (ethtool_value). */
++#define ETHTOOL_GLINK		0x0000000a
++#define ETHTOOL_GEEPROM		0x0000000b /* Get EEPROM data */
++#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data. */
++#define ETHTOOL_GCOALESCE	0x0000000e /* Get coalesce config */
++#define ETHTOOL_SCOALESCE	0x0000000f /* Set coalesce config. */
++#define ETHTOOL_GRINGPARAM	0x00000010 /* Get ring parameters */
++#define ETHTOOL_SRINGPARAM	0x00000011 /* Set ring parameters. */
++#define ETHTOOL_GPAUSEPARAM	0x00000012 /* Get pause parameters */
++#define ETHTOOL_SPAUSEPARAM	0x00000013 /* Set pause parameters. */
++#define ETHTOOL_GRXCSUM		0x00000014 /* Get RX hw csum enable (ethtool_value) */
++#define ETHTOOL_SRXCSUM		0x00000015 /* Set RX hw csum enable (ethtool_value) */
++#define ETHTOOL_GTXCSUM		0x00000016 /* Get TX hw csum enable (ethtool_value) */
++#define ETHTOOL_STXCSUM		0x00000017 /* Set TX hw csum enable (ethtool_value) */
++#define ETHTOOL_GSG		0x00000018 /* Get scatter-gather enable
++					    * (ethtool_value) */
++#define ETHTOOL_SSG		0x00000019 /* Set scatter-gather enable
++					    * (ethtool_value). */
++#define ETHTOOL_TEST		0x0000001a /* execute NIC self-test. */
++#define ETHTOOL_GSTRINGS	0x0000001b /* get specified string set */
++#define ETHTOOL_PHYS_ID		0x0000001c /* identify the NIC */
++#define ETHTOOL_GSTATS		0x0000001d /* get NIC-specific statistics */
++#define ETHTOOL_GTSO		0x0000001e /* Get TSO enable (ethtool_value) */
++#define ETHTOOL_STSO		0x0000001f /* Set TSO enable (ethtool_value) */
++#define ETHTOOL_GPERMADDR	0x00000020 /* Get permanent hardware address */
++#define ETHTOOL_GUFO		0x00000021 /* Get UFO enable (ethtool_value) */
++#define ETHTOOL_SUFO		0x00000022 /* Set UFO enable (ethtool_value) */
++#define ETHTOOL_GGSO		0x00000023 /* Get GSO enable (ethtool_value) */
++#define ETHTOOL_SGSO		0x00000024 /* Set GSO enable (ethtool_value) */
++#define ETHTOOL_GFLAGS		0x00000025 /* Get flags bitmap(ethtool_value) */
++#define ETHTOOL_SFLAGS		0x00000026 /* Set flags bitmap(ethtool_value) */
++#define ETHTOOL_GPFLAGS		0x00000027 /* Get driver-private flags bitmap */
++#define ETHTOOL_SPFLAGS		0x00000028 /* Set driver-private flags bitmap */
++
++#define ETHTOOL_GRXFH		0x00000029 /* Get RX flow hash configuration */
++#define ETHTOOL_SRXFH		0x0000002a /* Set RX flow hash configuration */
++#define ETHTOOL_GGRO		0x0000002b /* Get GRO enable (ethtool_value) */
++#define ETHTOOL_SGRO		0x0000002c /* Set GRO enable (ethtool_value) */
++#define ETHTOOL_GRXRINGS	0x0000002d /* Get RX rings available for LB */
++#define ETHTOOL_GRXCLSRLCNT	0x0000002e /* Get RX class rule count */
++#define ETHTOOL_GRXCLSRULE	0x0000002f /* Get RX classification rule */
++#define ETHTOOL_GRXCLSRLALL	0x00000030 /* Get all RX classification rule */
++#define ETHTOOL_SRXCLSRLDEL	0x00000031 /* Delete RX classification rule */
++#define ETHTOOL_SRXCLSRLINS	0x00000032 /* Insert RX classification rule */
++#define ETHTOOL_FLASHDEV	0x00000033 /* Flash firmware to device */
++#define ETHTOOL_RESET		0x00000034 /* Reset hardware */
++#define ETHTOOL_SRXNTUPLE	0x00000035 /* Add an n-tuple filter to device */
++#define ETHTOOL_GRXNTUPLE	0x00000036 /* deprecated */
++#define ETHTOOL_GSSET_INFO	0x00000037 /* Get string set info */
++#define ETHTOOL_GRXFHINDIR	0x00000038 /* Get RX flow hash indir'n table */
++#define ETHTOOL_SRXFHINDIR	0x00000039 /* Set RX flow hash indir'n table */
++
++#define ETHTOOL_GFEATURES	0x0000003a /* Get device offload settings */
++#define ETHTOOL_SFEATURES	0x0000003b /* Change device offload settings */
++#define ETHTOOL_GCHANNELS	0x0000003c /* Get no of channels */
++#define ETHTOOL_SCHANNELS	0x0000003d /* Set no of channels */
++#define ETHTOOL_SET_DUMP	0x0000003e /* Set dump settings */
++#define ETHTOOL_GET_DUMP_FLAG	0x0000003f /* Get dump settings */
++#define ETHTOOL_GET_DUMP_DATA	0x00000040 /* Get dump data */
++#define ETHTOOL_GET_TS_INFO	0x00000041 /* Get time stamping and PHC info */
++#define ETHTOOL_GMODULEINFO	0x00000042 /* Get plug-in module information */
++#define ETHTOOL_GMODULEEEPROM	0x00000043 /* Get plug-in module eeprom */
++#define ETHTOOL_GEEE		0x00000044 /* Get EEE settings */
++#define ETHTOOL_SEEE		0x00000045 /* Set EEE settings */
++
++#define ETHTOOL_GRSSH		0x00000046 /* Get RX flow hash configuration */
++#define ETHTOOL_SRSSH		0x00000047 /* Set RX flow hash configuration */
++#define ETHTOOL_GTUNABLE	0x00000048 /* Get tunable configuration */
++#define ETHTOOL_STUNABLE	0x00000049 /* Set tunable configuration */
++#define ETHTOOL_GPHYSTATS	0x0000004a /* get PHY-specific statistics */
++
++#define ETHTOOL_PERQUEUE	0x0000004b /* Set per queue options */
++
++#define ETHTOOL_GLINKSETTINGS	0x0000004c /* Get ethtool_link_settings */
++#define ETHTOOL_SLINKSETTINGS	0x0000004d /* Set ethtool_link_settings */
++#define ETHTOOL_PHY_GTUNABLE	0x0000004e /* Get PHY tunable configuration */
++#define ETHTOOL_PHY_STUNABLE	0x0000004f /* Set PHY tunable configuration */
++#define ETHTOOL_GFECPARAM	0x00000050 /* Get FEC settings */
++#define ETHTOOL_SFECPARAM	0x00000051 /* Set FEC settings */
++
++/* compatibility with older code */
++#define SPARC_ETH_GSET		ETHTOOL_GSET
++#define SPARC_ETH_SSET		ETHTOOL_SSET
++
++/* Link mode bit indices */
++enum ethtool_link_mode_bit_indices {
++	ETHTOOL_LINK_MODE_10baseT_Half_BIT	= 0,
++	ETHTOOL_LINK_MODE_10baseT_Full_BIT	= 1,
++	ETHTOOL_LINK_MODE_100baseT_Half_BIT	= 2,
++	ETHTOOL_LINK_MODE_100baseT_Full_BIT	= 3,
++	ETHTOOL_LINK_MODE_1000baseT_Half_BIT	= 4,
++	ETHTOOL_LINK_MODE_1000baseT_Full_BIT	= 5,
++	ETHTOOL_LINK_MODE_Autoneg_BIT		= 6,
++	ETHTOOL_LINK_MODE_TP_BIT		= 7,
++	ETHTOOL_LINK_MODE_AUI_BIT		= 8,
++	ETHTOOL_LINK_MODE_MII_BIT		= 9,
++	ETHTOOL_LINK_MODE_FIBRE_BIT		= 10,
++	ETHTOOL_LINK_MODE_BNC_BIT		= 11,
++	ETHTOOL_LINK_MODE_10000baseT_Full_BIT	= 12,
++	ETHTOOL_LINK_MODE_Pause_BIT		= 13,
++	ETHTOOL_LINK_MODE_Asym_Pause_BIT	= 14,
++	ETHTOOL_LINK_MODE_2500baseX_Full_BIT	= 15,
++	ETHTOOL_LINK_MODE_Backplane_BIT		= 16,
++	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT	= 17,
++	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT	= 18,
++	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT	= 19,
++	ETHTOOL_LINK_MODE_10000baseR_FEC_BIT	= 20,
++	ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT = 21,
++	ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT	= 22,
++	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT	= 23,
++	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT	= 24,
++	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT	= 25,
++	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT	= 26,
++	ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT	= 27,
++	ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT	= 28,
++	ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT	= 29,
++	ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT	= 30,
++	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT	= 31,
++	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT	= 32,
++	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT	= 33,
++	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT	= 34,
++	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT	= 35,
++	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT	= 36,
++	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT	= 37,
++	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT	= 38,
++	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT	= 39,
++	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT		= 40,
++	ETHTOOL_LINK_MODE_1000baseX_Full_BIT	= 41,
++	ETHTOOL_LINK_MODE_10000baseCR_Full_BIT	= 42,
++	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT	= 43,
++	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT	= 44,
++	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT	= 45,
++	ETHTOOL_LINK_MODE_10000baseER_Full_BIT	= 46,
++	ETHTOOL_LINK_MODE_2500baseT_Full_BIT	= 47,
++	ETHTOOL_LINK_MODE_5000baseT_Full_BIT	= 48,
++
++	ETHTOOL_LINK_MODE_FEC_NONE_BIT	= 49,
++	ETHTOOL_LINK_MODE_FEC_RS_BIT	= 50,
++	ETHTOOL_LINK_MODE_FEC_BASER_BIT	= 51,
++
++	/* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
++	 * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
++	 * macro for bits > 31. The only way to use indices > 31 is to
++	 * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API.
++	 */
++
++	__ETHTOOL_LINK_MODE_LAST
++	  = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
++};
++
++#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name)	\
++	(1UL << (ETHTOOL_LINK_MODE_ ## base_name ## _BIT))
++
++/* DEPRECATED macros. Please migrate to
++ * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT
++ * define any new SUPPORTED_* macro for bits > 31.
++ */
++#define SUPPORTED_10baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
++#define SUPPORTED_10baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full)
++#define SUPPORTED_100baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half)
++#define SUPPORTED_100baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full)
++#define SUPPORTED_1000baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half)
++#define SUPPORTED_1000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full)
++#define SUPPORTED_Autoneg		__ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg)
++#define SUPPORTED_TP			__ETHTOOL_LINK_MODE_LEGACY_MASK(TP)
++#define SUPPORTED_AUI			__ETHTOOL_LINK_MODE_LEGACY_MASK(AUI)
++#define SUPPORTED_MII			__ETHTOOL_LINK_MODE_LEGACY_MASK(MII)
++#define SUPPORTED_FIBRE			__ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE)
++#define SUPPORTED_BNC			__ETHTOOL_LINK_MODE_LEGACY_MASK(BNC)
++#define SUPPORTED_10000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full)
++#define SUPPORTED_Pause			__ETHTOOL_LINK_MODE_LEGACY_MASK(Pause)
++#define SUPPORTED_Asym_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause)
++#define SUPPORTED_2500baseX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full)
++#define SUPPORTED_Backplane		__ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane)
++#define SUPPORTED_1000baseKX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full)
++#define SUPPORTED_10000baseKX4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full)
++#define SUPPORTED_10000baseKR_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full)
++#define SUPPORTED_10000baseR_FEC	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC)
++#define SUPPORTED_20000baseMLD2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full)
++#define SUPPORTED_20000baseKR2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full)
++#define SUPPORTED_40000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full)
++#define SUPPORTED_40000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full)
++#define SUPPORTED_40000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full)
++#define SUPPORTED_40000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full)
++#define SUPPORTED_56000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full)
++#define SUPPORTED_56000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full)
++#define SUPPORTED_56000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full)
++#define SUPPORTED_56000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full)
++/* Please do not define any new SUPPORTED_* macro for bits > 31, see
++ * notice above.
++ */
++
++/*
++ * DEPRECATED macros. Please migrate to
++ * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT
++ * define any new ADERTISE_* macro for bits > 31.
++ */
++#define ADVERTISED_10baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
++#define ADVERTISED_10baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full)
++#define ADVERTISED_100baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half)
++#define ADVERTISED_100baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full)
++#define ADVERTISED_1000baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half)
++#define ADVERTISED_1000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full)
++#define ADVERTISED_Autoneg		__ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg)
++#define ADVERTISED_TP			__ETHTOOL_LINK_MODE_LEGACY_MASK(TP)
++#define ADVERTISED_AUI			__ETHTOOL_LINK_MODE_LEGACY_MASK(AUI)
++#define ADVERTISED_MII			__ETHTOOL_LINK_MODE_LEGACY_MASK(MII)
++#define ADVERTISED_FIBRE		__ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE)
++#define ADVERTISED_BNC			__ETHTOOL_LINK_MODE_LEGACY_MASK(BNC)
++#define ADVERTISED_10000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full)
++#define ADVERTISED_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Pause)
++#define ADVERTISED_Asym_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause)
++#define ADVERTISED_2500baseX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full)
++#define ADVERTISED_Backplane		__ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane)
++#define ADVERTISED_1000baseKX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full)
++#define ADVERTISED_10000baseKX4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full)
++#define ADVERTISED_10000baseKR_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full)
++#define ADVERTISED_10000baseR_FEC	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC)
++#define ADVERTISED_20000baseMLD2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full)
++#define ADVERTISED_20000baseKR2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full)
++#define ADVERTISED_40000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full)
++#define ADVERTISED_40000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full)
++#define ADVERTISED_40000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full)
++#define ADVERTISED_40000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full)
++#define ADVERTISED_56000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full)
++#define ADVERTISED_56000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full)
++#define ADVERTISED_56000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full)
++#define ADVERTISED_56000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full)
++/* Please do not define any new ADVERTISED_* macro for bits > 31, see
++ * notice above.
++ */
++
++/* The following are all involved in forcing a particular link
++ * mode for the device for setting things.  When getting the
++ * devices settings, these indicate the current mode and whether
++ * it was forced up into this mode or autonegotiated.
++ */
++
++/* The forced speed, in units of 1Mb. All values 0 to INT_MAX are legal.
++ * Update drivers/net/phy/phy.c:phy_speed_to_str() and
++ * drivers/net/bonding/bond_3ad.c:__get_link_speed() when adding new values.
++ */
++#define SPEED_10		10
++#define SPEED_100		100
++#define SPEED_1000		1000
++#define SPEED_2500		2500
++#define SPEED_5000		5000
++#define SPEED_10000		10000
++#define SPEED_14000		14000
++#define SPEED_20000		20000
++#define SPEED_25000		25000
++#define SPEED_40000		40000
++#define SPEED_50000		50000
++#define SPEED_56000		56000
++#define SPEED_100000		100000
++
++#define SPEED_UNKNOWN		((__u32) -1)
++
++static inline int ethtool_validate_speed(__u32 speed)
++{
++	return speed <= INT_MAX || speed == SPEED_UNKNOWN;
++}
++
++/* Duplex, half or full. */
++#define DUPLEX_HALF		0x00
++#define DUPLEX_FULL		0x01
++#define DUPLEX_UNKNOWN		0xff
++
++static inline int ethtool_validate_duplex(__u8 duplex)
++{
++	switch (duplex) {
++	case DUPLEX_HALF:
++	case DUPLEX_FULL:
++	case DUPLEX_UNKNOWN:
++		return 1;
++	}
++
++	return 0;
++}
++
++/* Which connector port. */
++#define PORT_TP			0x00
++#define PORT_AUI		0x01
++#define PORT_MII		0x02
++#define PORT_FIBRE		0x03
++#define PORT_BNC		0x04
++#define PORT_DA			0x05
++#define PORT_NONE		0xef
++#define PORT_OTHER		0xff
++
++/* Which transceiver to use. */
++#define XCVR_INTERNAL		0x00 /* PHY and MAC are in the same package */
++#define XCVR_EXTERNAL		0x01 /* PHY and MAC are in different packages */
++#define XCVR_DUMMY1		0x02
++#define XCVR_DUMMY2		0x03
++#define XCVR_DUMMY3		0x04
++
++/* Enable or disable autonegotiation. */
++#define AUTONEG_DISABLE		0x00
++#define AUTONEG_ENABLE		0x01
++
++/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then
++ * the driver is required to renegotiate link
++ */
++#define ETH_TP_MDI_INVALID	0x00 /* status: unknown; control: unsupported */
++#define ETH_TP_MDI		0x01 /* status: MDI;     control: force MDI */
++#define ETH_TP_MDI_X		0x02 /* status: MDI-X;   control: force MDI-X */
++#define ETH_TP_MDI_AUTO		0x03 /*                  control: auto-select */
++
++/* Wake-On-Lan options. */
++#define WAKE_PHY		(1 << 0)
++#define WAKE_UCAST		(1 << 1)
++#define WAKE_MCAST		(1 << 2)
++#define WAKE_BCAST		(1 << 3)
++#define WAKE_ARP		(1 << 4)
++#define WAKE_MAGIC		(1 << 5)
++#define WAKE_MAGICSECURE	(1 << 6) /* only meaningful if WAKE_MAGIC */
++#define WAKE_FILTER		(1 << 7)
++
++/* L2-L4 network traffic flow types */
++#define	TCP_V4_FLOW	0x01	/* hash or spec (tcp_ip4_spec) */
++#define	UDP_V4_FLOW	0x02	/* hash or spec (udp_ip4_spec) */
++#define	SCTP_V4_FLOW	0x03	/* hash or spec (sctp_ip4_spec) */
++#define	AH_ESP_V4_FLOW	0x04	/* hash only */
++#define	TCP_V6_FLOW	0x05	/* hash or spec (tcp_ip6_spec; nfc only) */
++#define	UDP_V6_FLOW	0x06	/* hash or spec (udp_ip6_spec; nfc only) */
++#define	SCTP_V6_FLOW	0x07	/* hash or spec (sctp_ip6_spec; nfc only) */
++#define	AH_ESP_V6_FLOW	0x08	/* hash only */
++#define	AH_V4_FLOW	0x09	/* hash or spec (ah_ip4_spec) */
++#define	ESP_V4_FLOW	0x0a	/* hash or spec (esp_ip4_spec) */
++#define	AH_V6_FLOW	0x0b	/* hash or spec (ah_ip6_spec; nfc only) */
++#define	ESP_V6_FLOW	0x0c	/* hash or spec (esp_ip6_spec; nfc only) */
++#define	IPV4_USER_FLOW	0x0d	/* spec only (usr_ip4_spec) */
++#define	IP_USER_FLOW	IPV4_USER_FLOW
++#define	IPV6_USER_FLOW	0x0e	/* spec only (usr_ip6_spec; nfc only) */
++#define	IPV4_FLOW	0x10	/* hash only */
++#define	IPV6_FLOW	0x11	/* hash only */
++#define	ETHER_FLOW	0x12	/* spec only (ether_spec) */
++/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
++#define	FLOW_EXT	0x80000000
++#define	FLOW_MAC_EXT	0x40000000
++/* Flag to enable RSS spreading of traffic matching rule (nfc only) */
++#define	FLOW_RSS	0x20000000
++
++/* L3-L4 network traffic flow hash options */
++#define	RXH_L2DA	(1 << 1)
++#define	RXH_VLAN	(1 << 2)
++#define	RXH_L3_PROTO	(1 << 3)
++#define	RXH_IP_SRC	(1 << 4)
++#define	RXH_IP_DST	(1 << 5)
++#define	RXH_L4_B_0_1	(1 << 6) /* src port in case of TCP/UDP/SCTP */
++#define	RXH_L4_B_2_3	(1 << 7) /* dst port in case of TCP/UDP/SCTP */
++#define	RXH_DISCARD	(1 << 31)
++
++#define	RX_CLS_FLOW_DISC	0xffffffffffffffffULL
++#define RX_CLS_FLOW_WAKE	0xfffffffffffffffeULL
++
++/* Special RX classification rule insert location values */
++#define RX_CLS_LOC_SPECIAL	0x80000000	/* flag */
++#define RX_CLS_LOC_ANY		0xffffffff
++#define RX_CLS_LOC_FIRST	0xfffffffe
++#define RX_CLS_LOC_LAST		0xfffffffd
++
++/* EEPROM Standards for plug in modules */
++#define ETH_MODULE_SFF_8079		0x1
++#define ETH_MODULE_SFF_8079_LEN		256
++#define ETH_MODULE_SFF_8472		0x2
++#define ETH_MODULE_SFF_8472_LEN		512
++#define ETH_MODULE_SFF_8636		0x3
++#define ETH_MODULE_SFF_8636_LEN		256
++#define ETH_MODULE_SFF_8436		0x4
++#define ETH_MODULE_SFF_8436_LEN		256
++
++/* Reset flags */
++/* The reset() operation must clear the flags for the components which
++ * were actually reset.  On successful return, the flags indicate the
++ * components which were not reset, either because they do not exist
++ * in the hardware or because they cannot be reset independently.  The
++ * driver must never reset any components that were not requested.
++ */
++enum ethtool_reset_flags {
++	/* These flags represent components dedicated to the interface
++	 * the command is addressed to.  Shift any flag left by
++	 * ETH_RESET_SHARED_SHIFT to reset a shared component of the
++	 * same type.
++	 */
++	ETH_RESET_MGMT		= 1 << 0,	/* Management processor */
++	ETH_RESET_IRQ		= 1 << 1,	/* Interrupt requester */
++	ETH_RESET_DMA		= 1 << 2,	/* DMA engine */
++	ETH_RESET_FILTER	= 1 << 3,	/* Filtering/flow direction */
++	ETH_RESET_OFFLOAD	= 1 << 4,	/* Protocol offload */
++	ETH_RESET_MAC		= 1 << 5,	/* Media access controller */
++	ETH_RESET_PHY		= 1 << 6,	/* Transceiver/PHY */
++	ETH_RESET_RAM		= 1 << 7,	/* RAM shared between
++						 * multiple components */
++	ETH_RESET_AP		= 1 << 8,	/* Application processor */
++
++	ETH_RESET_DEDICATED	= 0x0000ffff,	/* All components dedicated to
++						 * this interface */
++	ETH_RESET_ALL		= 0xffffffff,	/* All components used by this
++						 * interface, even if shared */
++};
++#define ETH_RESET_SHARED_SHIFT	16
++
++
++/**
++ * struct ethtool_link_settings - link control and status
++ *
++ * IMPORTANT, Backward compatibility notice: When implementing new
++ *	user-space tools, please first try %ETHTOOL_GLINKSETTINGS, and
++ *	if it succeeds use %ETHTOOL_SLINKSETTINGS to change link
++ *	settings; do not use %ETHTOOL_SSET if %ETHTOOL_GLINKSETTINGS
++ *	succeeded: stick to %ETHTOOL_GLINKSETTINGS/%SLINKSETTINGS in
++ *	that case.  Conversely, if %ETHTOOL_GLINKSETTINGS fails, use
++ *	%ETHTOOL_GSET to query and %ETHTOOL_SSET to change link
++ *	settings; do not use %ETHTOOL_SLINKSETTINGS if
++ *	%ETHTOOL_GLINKSETTINGS failed: stick to
++ *	%ETHTOOL_GSET/%ETHTOOL_SSET in that case.
++ *
++ * @cmd: Command number = %ETHTOOL_GLINKSETTINGS or %ETHTOOL_SLINKSETTINGS
++ * @speed: Link speed (Mbps)
++ * @duplex: Duplex mode; one of %DUPLEX_*
++ * @port: Physical connector type; one of %PORT_*
++ * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
++ *	applicable.  For clause 45 PHYs this is the PRTAD.
++ * @autoneg: Enable/disable autonegotiation and auto-detection;
++ *	either %AUTONEG_DISABLE or %AUTONEG_ENABLE
++ * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO
++ *	protocols supported by the interface; 0 if unknown.
++ *	Read-only.
++ * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
++ *	%ETH_TP_MDI_*.  If the status is unknown or not applicable, the
++ *	value will be %ETH_TP_MDI_INVALID.  Read-only.
++ * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of
++ *	%ETH_TP_MDI_*.  If MDI(-X) control is not implemented, reads
++ *	yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected.
++ *	When written successfully, the link should be renegotiated if
++ *	necessary.
++ * @link_mode_masks_nwords: Number of 32-bit words for each of the
++ *	supported, advertising, lp_advertising link mode bitmaps. For
++ *	%ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user
++ *	(>= 0); on return, if handshake in progress, negative if
++ *	request size unsupported by kernel: absolute value indicates
++ *	kernel expected size and all the other fields but cmd
++ *	are 0; otherwise (handshake completed), strictly positive
++ *	to indicate size used by kernel and cmd field stays
++ *	%ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For
++ *	%ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive
++ *	value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise
++ *	refused. For drivers: ignore this field (use kernel's
++ *	__ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will
++ *	be overwritten by kernel.
++ * @supported: Bitmap with each bit meaning given by
++ *	%ethtool_link_mode_bit_indices for the link modes, physical
++ *	connectors and other link features for which the interface
++ *	supports autonegotiation or auto-detection.  Read-only.
++ * @advertising: Bitmap with each bit meaning given by
++ *	%ethtool_link_mode_bit_indices for the link modes, physical
++ *	connectors and other link features that are advertised through
++ *	autonegotiation or enabled for auto-detection.
++ * @lp_advertising: Bitmap with each bit meaning given by
++ *	%ethtool_link_mode_bit_indices for the link modes, and other
++ *	link features that the link partner advertised through
++ *	autonegotiation; 0 if unknown or not applicable.  Read-only.
++ * @transceiver: Used to distinguish different possible PHY types,
++ *	reported consistently by PHYLIB.  Read-only.
++ *
++ * If autonegotiation is disabled, the speed and @duplex represent the
++ * fixed link mode and are writable if the driver supports multiple
++ * link modes.  If it is enabled then they are read-only; if the link
++ * is up they represent the negotiated link mode; if the link is down,
++ * the speed is 0, %SPEED_UNKNOWN or the highest enabled speed and
++ * @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
++ *
++ * Some hardware interfaces may have multiple PHYs and/or physical
++ * connectors fitted or do not allow the driver to detect which are
++ * fitted.  For these interfaces @port and/or @phy_address may be
++ * writable, possibly dependent on @autoneg being %AUTONEG_DISABLE.
++ * Otherwise, attempts to write different values may be ignored or
++ * rejected.
++ *
++ * Deprecated %ethtool_cmd fields transceiver, maxtxpkt and maxrxpkt
++ * are not available in %ethtool_link_settings. These fields will be
++ * always set to zero in %ETHTOOL_GSET reply and %ETHTOOL_SSET will
++ * fail if any of them is set to non-zero value.
++ *
++ * Users should assume that all fields not marked read-only are
++ * writable and subject to validation by the driver.  They should use
++ * %ETHTOOL_GLINKSETTINGS to get the current values before making specific
++ * changes and then applying them with %ETHTOOL_SLINKSETTINGS.
++ *
++ * Drivers that implement %get_link_ksettings and/or
++ * %set_link_ksettings should ignore the @cmd
++ * and @link_mode_masks_nwords fields (any change to them overwritten
++ * by kernel), and rely only on kernel's internal
++ * %__ETHTOOL_LINK_MODE_MASK_NBITS and
++ * %ethtool_link_mode_mask_t. Drivers that implement
++ * %set_link_ksettings() should validate all fields other than @cmd
++ * and @link_mode_masks_nwords that are not described as read-only or
++ * deprecated, and must ignore all fields described as read-only.
++ */
++struct ethtool_link_settings {
++	__u32	cmd;
++	__u32	speed;
++	__u8	duplex;
++	__u8	port;
++	__u8	phy_address;
++	__u8	autoneg;
++	__u8	mdio_support;
++	__u8	eth_tp_mdix;
++	__u8	eth_tp_mdix_ctrl;
++	__s8	link_mode_masks_nwords;
++	__u8	transceiver;
++	__u8	reserved1[3];
++	__u32	reserved[7];
++	__u32	link_mode_masks[0];
++	/* layout of link_mode_masks fields:
++	 * __u32 map_supported[link_mode_masks_nwords];
++	 * __u32 map_advertising[link_mode_masks_nwords];
++	 * __u32 map_lp_advertising[link_mode_masks_nwords];
++	 */
++};
++#endif /* _UAPI_LINUX_ETHTOOL_H */
+diff --git a/src/shared/linux/libbpf.h b/src/shared/linux/libbpf.h
+deleted file mode 100644
+index 391eee5a4e..0000000000
+--- a/src/shared/linux/libbpf.h
++++ /dev/null
+@@ -1,207 +0,0 @@
+-/* eBPF mini library */
+-#ifndef __LIBBPF_H
+-#define __LIBBPF_H
+-
+-#include <linux/bpf.h>
+-
+-struct bpf_insn;
+-
+-/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
+-
+-#define BPF_ALU64_REG(OP, DST, SRC)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = 0,					\
+-                .imm   = 0 })
+-
+-#define BPF_ALU32_REG(OP, DST, SRC)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = 0,					\
+-                .imm   = 0 })
+-
+-/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
+-
+-#define BPF_ALU64_IMM(OP, DST, IMM)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = IMM })
+-
+-#define BPF_ALU32_IMM(OP, DST, IMM)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = IMM })
+-
+-/* Short form of mov, dst_reg = src_reg */
+-
+-#define BPF_MOV64_REG(DST, SRC)					\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = 0,					\
+-                .imm   = 0 })
+-
+-#define BPF_MOV32_REG(DST, SRC)					\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU | BPF_MOV | BPF_X,		\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = 0,					\
+-                .imm   = 0 })
+-
+-/* Short form of mov, dst_reg = imm32 */
+-
+-#define BPF_MOV64_IMM(DST, IMM)					\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = IMM })
+-
+-#define BPF_MOV32_IMM(DST, IMM)					\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ALU | BPF_MOV | BPF_K,		\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = IMM })
+-
+-/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
+-#define BPF_LD_IMM64(DST, IMM)					\
+-        BPF_LD_IMM64_RAW(DST, 0, IMM)
+-
+-#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_LD | BPF_DW | BPF_IMM,		\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = 0,					\
+-                .imm   = (__u32) (IMM) }),			\
+-        ((struct bpf_insn) {					\
+-                .code  = 0, /* zero is reserved opcode */	\
+-                .dst_reg = 0,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = ((__u64) (IMM)) >> 32 })
+-
+-#ifndef BPF_PSEUDO_MAP_FD
+-# define BPF_PSEUDO_MAP_FD	1
+-#endif
+-
+-/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
+-#define BPF_LD_MAP_FD(DST, MAP_FD)				\
+-        BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
+-
+-/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
+-
+-#define BPF_LD_ABS(SIZE, IMM)					\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
+-                .dst_reg = 0,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = IMM })
+-
+-/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
+-
+-#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = OFF,					\
+-                .imm   = 0 })
+-
+-/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
+-
+-#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = OFF,					\
+-                .imm   = 0 })
+-
+-/* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */
+-
+-#define BPF_STX_XADD(SIZE, DST, SRC, OFF)			\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD,	\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = OFF,					\
+-                .imm   = 0 })
+-
+-/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
+-
+-#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = OFF,					\
+-                .imm   = IMM })
+-
+-/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
+-
+-#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = OFF,					\
+-                .imm   = 0 })
+-
+-/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
+-
+-#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
+-                .dst_reg = DST,					\
+-                .src_reg = 0,					\
+-                .off   = OFF,					\
+-                .imm   = IMM })
+-
+-/* Unconditional jumps */
+-
+-#define BPF_JMP_A(OFF)						\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_JMP | BPF_JA,			\
+-                .dst_reg = 0,					\
+-                .src_reg = 0,					\
+-                .off   = OFF,					\
+-                .imm   = 0 })
+-
+-/* Raw code statement block */
+-
+-#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
+-        ((struct bpf_insn) {					\
+-                .code  = CODE,					\
+-                .dst_reg = DST,					\
+-                .src_reg = SRC,					\
+-                .off   = OFF,					\
+-                .imm   = IMM })
+-
+-/* Program exit */
+-
+-#define BPF_EXIT_INSN()						\
+-        ((struct bpf_insn) {					\
+-                .code  = BPF_JMP | BPF_EXIT,			\
+-                .dst_reg = 0,					\
+-                .src_reg = 0,					\
+-                .off   = 0,					\
+-                .imm   = 0 })
+-
+-#endif
+diff --git a/src/shared/linux/netdevice.h b/src/shared/linux/netdevice.h
+new file mode 100644
+index 0000000000..f3770c5b0f
+--- /dev/null
++++ b/src/shared/linux/netdevice.h
+@@ -0,0 +1,66 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET		An implementation of the TCP/IP protocol suite for the LINUX
++ *		operating system.  INET is implemented using the  BSD Socket
++ *		interface as the means of communication with the user level.
++ *
++ *		Definitions for the Interfaces handler.
++ *
++ * Version:	@(#)dev.h	1.0.10	08/12/93
++ *
++ * Authors:	Ross Biro
++ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *		Corey Minyard <wf-rch!minyard@relay.EU.net>
++ *		Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
++ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
++ *		Bjorn Ekwall. <bj0rn@blox.se>
++ *              Pekka Riikonen <priikone@poseidon.pspt.fi>
++ *
++ *		This program is free software; you can redistribute it and/or
++ *		modify it under the terms of the GNU General Public License
++ *		as published by the Free Software Foundation; either version
++ *		2 of the License, or (at your option) any later version.
++ *
++ *		Moved to /usr/include/linux for NET3
++ */
++#ifndef _UAPI_LINUX_NETDEVICE_H
++#define _UAPI_LINUX_NETDEVICE_H
++
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/if_packet.h>
++#include <linux/if_link.h>
++
++
++#define MAX_ADDR_LEN	32		/* Largest hardware address length */
++
++/* Initial net device group. All devices belong to group 0 by default. */
++#define INIT_NETDEV_GROUP	0
++
++
++/* interface name assignment types (sysfs name_assign_type attribute) */
++#define NET_NAME_UNKNOWN	0	/* unknown origin (not exposed to userspace) */
++#define NET_NAME_ENUM		1	/* enumerated by kernel */
++#define NET_NAME_PREDICTABLE	2	/* predictably named by the kernel */
++#define NET_NAME_USER		3	/* provided by user-space */
++#define NET_NAME_RENAMED	4	/* renamed by user-space */
++
++/* Media selection options. */
++enum {
++        IF_PORT_UNKNOWN = 0,
++        IF_PORT_10BASE2,
++        IF_PORT_10BASET,
++        IF_PORT_AUI,
++        IF_PORT_100BASET,
++        IF_PORT_100BASETX,
++        IF_PORT_100BASEFX
++};
++
++/* hardware address assignment types */
++#define NET_ADDR_PERM		0	/* address is permanent (default) */
++#define NET_ADDR_RANDOM		1	/* address is generated randomly */
++#define NET_ADDR_STOLEN		2	/* address is stolen from other device */
++#define NET_ADDR_SET		3	/* address is set using
++					 * dev_set_mac_address() */
++
++#endif /* _UAPI_LINUX_NETDEVICE_H */
+diff --git a/src/shared/meson.build b/src/shared/meson.build
+index e05fbce30f..15466bcaf1 100644
+--- a/src/shared/meson.build
++++ b/src/shared/meson.build
+@@ -96,6 +96,13 @@ shared_sources = files('''
+         json.c
+         json.h
+         libmount-util.h
++        linux/auto_dev-ioctl.h
++        linux/bpf.h
++        linux/bpf_common.h
++        linux/bpf_insn.h
++        linux/dm-ioctl.h
++        linux/ethtool.h
++        linux/netdevice.h
+         lockfile-util.c
+         lockfile-util.h
+         log-link.h
+@@ -168,7 +175,6 @@ shared_sources = files('''
+         watchdog.h
+         web-util.c
+         web-util.h
+-        wireguard-netlink.h
+         xml.c
+         xml.h
+ '''.split())
+diff --git a/src/shared/wireguard-netlink.h b/src/shared/wireguard-netlink.h
+deleted file mode 100644
+index eb170915a6..0000000000
+--- a/src/shared/wireguard-netlink.h
++++ /dev/null
+@@ -1,179 +0,0 @@
+-#pragma once
+-
+-/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR MIT)
+- *
+- * Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+- *
+- * Documentation
+- * =============
+- *
+- * The below enums and macros are for interfacing with WireGuard, using generic
+- * netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two
+- * methods: get and set. Note that while they share many common attributes, these
+- * two functions actually accept a slightly different set of inputs and outputs.
+- *
+- * WG_CMD_GET_DEVICE
+- * -----------------
+- *
+- * May only be called via NLM_F_REQUEST | NLM_F_DUMP. The command should contain
+- * one but not both of:
+- *
+- *	WGDEVICE_A_IFINDEX: NLA_U32
+- *	WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+- *
+- * The kernel will then return several messages (NLM_F_MULTI) containing the following
+- * tree of nested items:
+- *
+- *	WGDEVICE_A_IFINDEX: NLA_U32
+- *	WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+- *	WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN
+- *	WGDEVICE_A_PUBLIC_KEY: len WG_KEY_LEN
+- *	WGDEVICE_A_LISTEN_PORT: NLA_U16
+- *	WGDEVICE_A_FWMARK: NLA_U32
+- *	WGDEVICE_A_PEERS: NLA_NESTED
+- *		0: NLA_NESTED
+- *			WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
+- *			WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN
+- *			WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
+- *			WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16
+- *			WGPEER_A_LAST_HANDSHAKE_TIME: struct timespec
+- *			WGPEER_A_RX_BYTES: NLA_U64
+- *			WGPEER_A_TX_BYTES: NLA_U64
+- *			WGPEER_A_ALLOWEDIPS: NLA_NESTED
+- *				0: NLA_NESTED
+- *					WGALLOWEDIP_A_FAMILY: NLA_U16
+- *					WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
+- *					WGALLOWEDIP_A_CIDR_MASK: NLA_U8
+- *				1: NLA_NESTED
+- *					...
+- *				2: NLA_NESTED
+- *					...
+- *				...
+- *		1: NLA_NESTED
+- *			...
+- *		...
+- *
+- * It is possible that all of the allowed IPs of a single peer will not
+- * fit within a single netlink message. In that case, the same peer will
+- * be written in the following message, except it will only contain
+- * WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several
+- * times in a row for the same peer. It is then up to the receiver to
+- * coalesce adjacent peers. Likewise, it is possible that all peers will
+- * not fit within a single message. So, subsequent peers will be sent
+- * in following messages, except those will only contain WGDEVICE_A_IFNAME
+- * and WGDEVICE_A_PEERS. It is then up to the receiver to coalesce these
+- * messages to form the complete list of peers.
+- *
+- * Since this is an NLA_F_DUMP command, the final message will always be
+- * NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message
+- * contains an integer error code. It is either zero or a negative error
+- * code corresponding to the errno.
+- *
+- * WG_CMD_SET_DEVICE
+- * -----------------
+- *
+- * May only be called via NLM_F_REQUEST. The command should contain the following
+- * tree of nested items, containing one but not both of WGDEVICE_A_IFINDEX
+- * and WGDEVICE_A_IFNAME:
+- *
+- *	WGDEVICE_A_IFINDEX: NLA_U32
+- *	WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+- *	WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
+- *			  peers should be removed prior to adding the list below.
+- *	WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
+- *	WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly
+- *	WGDEVICE_A_FWMARK: NLA_U32, 0 to disable
+- *	WGDEVICE_A_PEERS: NLA_NESTED
+- *		0: NLA_NESTED
+- *			WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
+- *			WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the specified peer
+- *					should be removed rather than added/updated and/or
+- *					WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed IPs of
+- *					this peer should be removed prior to adding the list below.
+- *			WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove
+- *			WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
+- *			WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable
+- *			WGPEER_A_ALLOWEDIPS: NLA_NESTED
+- *				0: NLA_NESTED
+- *					WGALLOWEDIP_A_FAMILY: NLA_U16
+- *					WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
+- *					WGALLOWEDIP_A_CIDR_MASK: NLA_U8
+- *				1: NLA_NESTED
+- *					...
+- *				2: NLA_NESTED
+- *					...
+- *				...
+- *		1: NLA_NESTED
+- *			...
+- *		...
+- *
+- * It is possible that the amount of configuration data exceeds that of
+- * the maximum message length accepted by the kernel. In that case,
+- * several messages should be sent one after another, with each
+- * successive one filling in information not contained in the prior. Note
+- * that if WGDEVICE_F_REPLACE_PEERS is specified in the first message, it
+- * probably should not be specified in fragments that come after, so that
+- * the list of peers is only cleared the first time but appened after.
+- * Likewise for peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the
+- * first message of a peer, it likely should not be specified in subsequent
+- * fragments.
+- *
+- * If an error occurs, NLMSG_ERROR will reply containing an errno.
+- */
+-
+-#define WG_GENL_NAME "wireguard"
+-#define WG_GENL_VERSION 1
+-
+-#define WG_KEY_LEN 32
+-
+-enum wg_cmd {
+-        WG_CMD_GET_DEVICE,
+-        WG_CMD_SET_DEVICE,
+-        __WG_CMD_MAX
+-};
+-#define WG_CMD_MAX (__WG_CMD_MAX - 1)
+-
+-enum wgdevice_flag {
+- WGDEVICE_F_REPLACE_PEERS = 1U << 0
+-};
+-enum wgdevice_attribute {
+-        WGDEVICE_A_UNSPEC,
+-        WGDEVICE_A_IFINDEX,
+-        WGDEVICE_A_IFNAME,
+-        WGDEVICE_A_PRIVATE_KEY,
+-        WGDEVICE_A_PUBLIC_KEY,
+-        WGDEVICE_A_FLAGS,
+-        WGDEVICE_A_LISTEN_PORT,
+-        WGDEVICE_A_FWMARK,
+-        WGDEVICE_A_PEERS,
+-        __WGDEVICE_A_LAST
+-};
+-#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
+-
+-enum wgpeer_flag {
+-        WGPEER_F_REMOVE_ME = 1U << 0,
+-        WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
+-};
+-enum wgpeer_attribute {
+-        WGPEER_A_UNSPEC,
+-        WGPEER_A_PUBLIC_KEY,
+-        WGPEER_A_PRESHARED_KEY,
+-        WGPEER_A_FLAGS,
+-        WGPEER_A_ENDPOINT,
+-        WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+-        WGPEER_A_LAST_HANDSHAKE_TIME,
+-        WGPEER_A_RX_BYTES,
+-        WGPEER_A_TX_BYTES,
+-        WGPEER_A_ALLOWEDIPS,
+-        __WGPEER_A_LAST
+-};
+-#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)
+-
+-enum wgallowedip_attribute {
+-        WGALLOWEDIP_A_UNSPEC,
+-        WGALLOWEDIP_A_FAMILY,
+-        WGALLOWEDIP_A_IPADDR,
+-        WGALLOWEDIP_A_CIDR_MASK,
+-        __WGALLOWEDIP_A_LAST
+-};
+-#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1)
+diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
+index 928bae6ab1..6afa512bff 100644
+--- a/src/shutdown/umount.c
++++ b/src/shutdown/umount.c
+@@ -5,6 +5,7 @@
+ 
+ #include <errno.h>
+ #include <fcntl.h>
++#include <linux/dm-ioctl.h>
+ #include <linux/loop.h>
+ #include <string.h>
+ #include <sys/mount.h>
+@@ -23,7 +24,6 @@
+ #include "fd-util.h"
+ #include "fstab-util.h"
+ #include "libmount-util.h"
+-#include "linux-3.13/dm-ioctl.h"
+ #include "mount-setup.h"
+ #include "mount-util.h"
+ #include "mountpoint-util.h"
+diff --git a/src/test/test-arphrd-list.c b/src/test/test-arphrd-list.c
+index 3005fc1b69..02bb25b695 100644
+--- a/src/test/test-arphrd-list.c
++++ b/src/test/test-arphrd-list.c
+@@ -1,10 +1,9 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+-#include <net/if_arp.h>
++#include <linux/if_arp.h>
+ #include <string.h>
+ 
+ #include "macro.h"
+-#include "missing_network.h"
+ #include "string-util.h"
+ 
+ _unused_ \
+diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c
+index cd8d68f215..6a0bf1462f 100644
+--- a/src/test/test-bpf.c
++++ b/src/test/test-bpf.c
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+-#include <linux/libbpf.h>
++#include <linux/bpf_insn.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <unistd.h>
+diff --git a/src/test/test-netlink-manual.c b/src/test/test-netlink-manual.c
+index a1a5eb4778..031a47605e 100644
+--- a/src/test/test-netlink-manual.c
++++ b/src/test/test-netlink-manual.c
+@@ -2,9 +2,8 @@
+ 
+ #include <arpa/inet.h>
+ #include <libkmod.h>
+-#include <linux/ip.h>
+-#include <net/if.h>
+ #include <linux/if_tunnel.h>
++#include <linux/ip.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ 
+diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
+index 618b26bf59..7ca703d22c 100644
+--- a/src/udev/net/ethtool-util.h
++++ b/src/udev/net/ethtool-util.h
+@@ -5,7 +5,6 @@
+ #include <linux/ethtool.h>
+ 
+ #include "conf-parser.h"
+-#include "missing_network.h"
+ 
+ struct link_config;
+ 
+diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
+index 14690e364b..a26c4cefa8 100644
+--- a/src/udev/net/link-config.c
++++ b/src/udev/net/link-config.c
+@@ -1,5 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
++#include <linux/netdevice.h>
+ #include <netinet/ether.h>
+ 
+ #include "sd-device.h"
+@@ -15,7 +16,6 @@
+ #include "link-config.h"
+ #include "log.h"
+ #include "memory-util.h"
+-#include "missing_network.h"
+ #include "naming-scheme.h"
+ #include "netlink-util.h"
+ #include "network-internal.h"
+diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
+index 956be59afb..6a69dae3af 100644
+--- a/src/udev/udev-builtin-btrfs.c
++++ b/src/udev/udev-builtin-btrfs.c
+@@ -1,12 +1,12 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include <fcntl.h>
++#include <linux/btrfs.h>
+ #include <stdlib.h>
+ #include <sys/ioctl.h>
+ 
+ #include "device-util.h"
+ #include "fd-util.h"
+-#include "missing.h"
+ #include "string-util.h"
+ #include "strxcpyx.h"
+ #include "udev-builtin.h"
+-- 
+2.20.1
+
diff --git a/package/systemd/0003-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch b/package/systemd/0003-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch
deleted file mode 100644
index 007b806c09..0000000000
--- a/package/systemd/0003-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch
+++ /dev/null
@@ -1,194 +0,0 @@ 
-From 9e3f5a77226d5320270c92df001f6c79be735af3 Mon Sep 17 00:00:00 2001
-From: Riccardo Schirone <rschiron@redhat.com>
-Date: Mon, 4 Feb 2019 14:29:28 +0100
-Subject: [PATCH] Allocate temporary strings to hold dbus paths on the heap
-
-Paths are limited to BUS_PATH_SIZE_MAX but the maximum size is anyway too big
-to be allocated on the stack, so let's switch to the heap where there is a
-clear way to understand if the allocation fails.
-
-(cherry picked from commit f519a19bcd5afe674a9b8fc462cd77d8bad403c1)
-[baruch: backport to v240]
-Signed-off-by: Baruch Siach <baruch@tkos.co.il>
-[Adam: Update for v241]
-Signed-off-by: Adam Duskett <aduskett@gmail.com>
----
- src/libsystemd/sd-bus/bus-objects.c | 68 +++++++++++++++++++++++------
- 1 file changed, 54 insertions(+), 14 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
-index 58329f3fe78..54b977418e0 100644
---- a/src/libsystemd/sd-bus/bus-objects.c
-+++ b/src/libsystemd/sd-bus/bus-objects.c
-@@ -1133,7 +1133,8 @@ static int object_manager_serialize_path_and_fallbacks(
-                 const char *path,
-                 sd_bus_error *error) {
- 
--        char *prefix;
-+        _cleanup_free_ char *prefix = NULL;
-+        size_t pl;
-         int r;
- 
-         assert(bus);
-@@ -1149,7 +1150,12 @@ static int object_manager_serialize_path_and_fallbacks(
-                 return 0;
- 
-         /* Second, add fallback vtables registered for any of the prefixes */
--        prefix = newa(char, strlen(path) + 1);
-+        pl = strlen(path);
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
-+
-         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                 r = object_manager_serialize_path(bus, reply, prefix, path, true, error);
-                 if (r < 0)
-@@ -1345,6 +1351,7 @@ static int object_find_and_run(
- }
- 
- int bus_process_object(sd_bus *bus, sd_bus_message *m) {
-+        _cleanup_free_ char *prefix = NULL;
-         int r;
-         size_t pl;
-         bool found_object = false;
-@@ -1369,9 +1376,12 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
-         assert(m->member);
- 
-         pl = strlen(m->path);
--        do {
--                char prefix[pl+1];
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
- 
-+        do {
-                 bus->nodes_modified = false;
- 
-                 r = object_find_and_run(bus, m, m->path, false, &found_object);
-@@ -1498,9 +1508,15 @@ static int bus_find_parent_object_manager(sd_bus *bus, struct node **out, const
- 
-         n = hashmap_get(bus->nodes, path);
-         if (!n) {
--                char *prefix;
-+                _cleanup_free_ char *prefix = NULL;
-+                size_t pl;
-+
-+                pl = strlen(path);
-+                assert(pl <= BUS_PATH_SIZE_MAX);
-+                prefix = new(char, pl + 1);
-+                if (!prefix)
-+                        return -ENOMEM;
- 
--                prefix = newa(char, strlen(path) + 1);
-                 OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                         n = hashmap_get(bus->nodes, prefix);
-                         if (n)
-@@ -2083,8 +2099,9 @@ _public_ int sd_bus_emit_properties_changed_strv(
-                 const char *interface,
-                 char **names) {
- 
-+        _cleanup_free_ char *prefix = NULL;
-         bool found_interface = false;
--        char *prefix;
-+        size_t pl;
-         int r;
- 
-         assert_return(bus, -EINVAL);
-@@ -2105,6 +2122,12 @@ _public_ int sd_bus_emit_properties_changed_strv(
- 
-         BUS_DONT_DESTROY(bus);
- 
-+        pl = strlen(path);
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
-+
-         do {
-                 bus->nodes_modified = false;
- 
-@@ -2114,7 +2137,6 @@ _public_ int sd_bus_emit_properties_changed_strv(
-                 if (bus->nodes_modified)
-                         continue;
- 
--                prefix = newa(char, strlen(path) + 1);
-                 OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                         r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names);
-                         if (r != 0)
-@@ -2246,7 +2268,8 @@ static int object_added_append_all_prefix(
- 
- static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *path) {
-         _cleanup_set_free_ Set *s = NULL;
--        char *prefix;
-+        _cleanup_free_ char *prefix = NULL;
-+        size_t pl;
-         int r;
- 
-         assert(bus);
-@@ -2291,7 +2314,12 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
-         if (bus->nodes_modified)
-                 return 0;
- 
--        prefix = newa(char, strlen(path) + 1);
-+        pl = strlen(path);
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
-+
-         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                 r = object_added_append_all_prefix(bus, m, s, prefix, path, true);
-                 if (r < 0)
-@@ -2430,7 +2458,8 @@ static int object_removed_append_all_prefix(
- 
- static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char *path) {
-         _cleanup_set_free_ Set *s = NULL;
--        char *prefix;
-+        _cleanup_free_ char *prefix = NULL;
-+        size_t pl;
-         int r;
- 
-         assert(bus);
-@@ -2462,7 +2491,12 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
-         if (bus->nodes_modified)
-                 return 0;
- 
--        prefix = newa(char, strlen(path) + 1);
-+        pl = strlen(path);
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
-+
-         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                 r = object_removed_append_all_prefix(bus, m, s, prefix, path, true);
-                 if (r < 0)
-@@ -2612,7 +2646,8 @@ static int interfaces_added_append_one(
-                 const char *path,
-                 const char *interface) {
- 
--        char *prefix;
-+        _cleanup_free_ char *prefix = NULL;
-+        size_t pl;
-         int r;
- 
-         assert(bus);
-@@ -2626,7 +2661,12 @@ static int interfaces_added_append_one(
-         if (bus->nodes_modified)
-                 return 0;
- 
--        prefix = newa(char, strlen(path) + 1);
-+        pl = strlen(path);
-+        assert(pl <= BUS_PATH_SIZE_MAX);
-+        prefix = new(char, pl + 1);
-+        if (!prefix)
-+                return -ENOMEM;
-+
-         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                 r = interfaces_added_append_one_prefix(bus, m, prefix, path, interface, true);
-                 if (r != 0)
--- 
-2.20.1
-
diff --git a/package/systemd/0003-linux-move-netdevice.h-from-shared-linux-to-basic-li.patch b/package/systemd/0003-linux-move-netdevice.h-from-shared-linux-to-basic-li.patch
new file mode 100644
index 0000000000..2fa3c62649
--- /dev/null
+++ b/package/systemd/0003-linux-move-netdevice.h-from-shared-linux-to-basic-li.patch
@@ -0,0 +1,190 @@ 
+From 76566792e33f054dd02df84db044f5ae747afe67 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Sat, 13 Apr 2019 18:33:34 +0900
+Subject: [PATCH] linux: move netdevice.h from shared/linux to basic/linux
+
+As the header linux/if_arp.h includes linux/netdevice.h.
+
+[james.hilliard1@gmail.com: backport from upstream commit
+76566792e33f054dd02df84db044f5ae747afe67]
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+---
+ src/basic/linux/netdevice.h  | 66 ++++++++++++++++++++++++++++++++++++
+ src/basic/meson.build        |  1 +
+ src/shared/linux/netdevice.h | 66 ------------------------------------
+ src/shared/meson.build       |  1 -
+ 4 files changed, 67 insertions(+), 67 deletions(-)
+ create mode 100644 src/basic/linux/netdevice.h
+ delete mode 100644 src/shared/linux/netdevice.h
+
+diff --git a/src/basic/linux/netdevice.h b/src/basic/linux/netdevice.h
+new file mode 100644
+index 0000000000..f3770c5b0f
+--- /dev/null
++++ b/src/basic/linux/netdevice.h
+@@ -0,0 +1,66 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET		An implementation of the TCP/IP protocol suite for the LINUX
++ *		operating system.  INET is implemented using the  BSD Socket
++ *		interface as the means of communication with the user level.
++ *
++ *		Definitions for the Interfaces handler.
++ *
++ * Version:	@(#)dev.h	1.0.10	08/12/93
++ *
++ * Authors:	Ross Biro
++ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *		Corey Minyard <wf-rch!minyard@relay.EU.net>
++ *		Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
++ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
++ *		Bjorn Ekwall. <bj0rn@blox.se>
++ *              Pekka Riikonen <priikone@poseidon.pspt.fi>
++ *
++ *		This program is free software; you can redistribute it and/or
++ *		modify it under the terms of the GNU General Public License
++ *		as published by the Free Software Foundation; either version
++ *		2 of the License, or (at your option) any later version.
++ *
++ *		Moved to /usr/include/linux for NET3
++ */
++#ifndef _UAPI_LINUX_NETDEVICE_H
++#define _UAPI_LINUX_NETDEVICE_H
++
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/if_packet.h>
++#include <linux/if_link.h>
++
++
++#define MAX_ADDR_LEN	32		/* Largest hardware address length */
++
++/* Initial net device group. All devices belong to group 0 by default. */
++#define INIT_NETDEV_GROUP	0
++
++
++/* interface name assignment types (sysfs name_assign_type attribute) */
++#define NET_NAME_UNKNOWN	0	/* unknown origin (not exposed to userspace) */
++#define NET_NAME_ENUM		1	/* enumerated by kernel */
++#define NET_NAME_PREDICTABLE	2	/* predictably named by the kernel */
++#define NET_NAME_USER		3	/* provided by user-space */
++#define NET_NAME_RENAMED	4	/* renamed by user-space */
++
++/* Media selection options. */
++enum {
++        IF_PORT_UNKNOWN = 0,
++        IF_PORT_10BASE2,
++        IF_PORT_10BASET,
++        IF_PORT_AUI,
++        IF_PORT_100BASET,
++        IF_PORT_100BASETX,
++        IF_PORT_100BASEFX
++};
++
++/* hardware address assignment types */
++#define NET_ADDR_PERM		0	/* address is permanent (default) */
++#define NET_ADDR_RANDOM		1	/* address is generated randomly */
++#define NET_ADDR_STOLEN		2	/* address is stolen from other device */
++#define NET_ADDR_SET		3	/* address is set using
++					 * dev_set_mac_address() */
++
++#endif /* _UAPI_LINUX_NETDEVICE_H */
+diff --git a/src/basic/meson.build b/src/basic/meson.build
+index 524f3785dc..81c3d0f3e8 100644
+--- a/src/basic/meson.build
++++ b/src/basic/meson.build
+@@ -99,6 +99,7 @@ basic_sources = files('''
+         linux/if_tun.h
+         linux/if_tunnel.h
+         linux/libc-compat.h
++        linux/netdevice.h
+         linux/netlink.h
+         linux/rtnetlink.h
+         linux/wireguard.h
+diff --git a/src/shared/linux/netdevice.h b/src/shared/linux/netdevice.h
+deleted file mode 100644
+index f3770c5b0f..0000000000
+--- a/src/shared/linux/netdevice.h
++++ /dev/null
+@@ -1,66 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+-/*
+- * INET		An implementation of the TCP/IP protocol suite for the LINUX
+- *		operating system.  INET is implemented using the  BSD Socket
+- *		interface as the means of communication with the user level.
+- *
+- *		Definitions for the Interfaces handler.
+- *
+- * Version:	@(#)dev.h	1.0.10	08/12/93
+- *
+- * Authors:	Ross Biro
+- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+- *		Corey Minyard <wf-rch!minyard@relay.EU.net>
+- *		Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
+- *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
+- *		Bjorn Ekwall. <bj0rn@blox.se>
+- *              Pekka Riikonen <priikone@poseidon.pspt.fi>
+- *
+- *		This program is free software; you can redistribute it and/or
+- *		modify it under the terms of the GNU General Public License
+- *		as published by the Free Software Foundation; either version
+- *		2 of the License, or (at your option) any later version.
+- *
+- *		Moved to /usr/include/linux for NET3
+- */
+-#ifndef _UAPI_LINUX_NETDEVICE_H
+-#define _UAPI_LINUX_NETDEVICE_H
+-
+-#include <linux/if.h>
+-#include <linux/if_ether.h>
+-#include <linux/if_packet.h>
+-#include <linux/if_link.h>
+-
+-
+-#define MAX_ADDR_LEN	32		/* Largest hardware address length */
+-
+-/* Initial net device group. All devices belong to group 0 by default. */
+-#define INIT_NETDEV_GROUP	0
+-
+-
+-/* interface name assignment types (sysfs name_assign_type attribute) */
+-#define NET_NAME_UNKNOWN	0	/* unknown origin (not exposed to userspace) */
+-#define NET_NAME_ENUM		1	/* enumerated by kernel */
+-#define NET_NAME_PREDICTABLE	2	/* predictably named by the kernel */
+-#define NET_NAME_USER		3	/* provided by user-space */
+-#define NET_NAME_RENAMED	4	/* renamed by user-space */
+-
+-/* Media selection options. */
+-enum {
+-        IF_PORT_UNKNOWN = 0,
+-        IF_PORT_10BASE2,
+-        IF_PORT_10BASET,
+-        IF_PORT_AUI,
+-        IF_PORT_100BASET,
+-        IF_PORT_100BASETX,
+-        IF_PORT_100BASEFX
+-};
+-
+-/* hardware address assignment types */
+-#define NET_ADDR_PERM		0	/* address is permanent (default) */
+-#define NET_ADDR_RANDOM		1	/* address is generated randomly */
+-#define NET_ADDR_STOLEN		2	/* address is stolen from other device */
+-#define NET_ADDR_SET		3	/* address is set using
+-					 * dev_set_mac_address() */
+-
+-#endif /* _UAPI_LINUX_NETDEVICE_H */
+diff --git a/src/shared/meson.build b/src/shared/meson.build
+index 15466bcaf1..c80a67cdde 100644
+--- a/src/shared/meson.build
++++ b/src/shared/meson.build
+@@ -102,7 +102,6 @@ shared_sources = files('''
+         linux/bpf_insn.h
+         linux/dm-ioctl.h
+         linux/ethtool.h
+-        linux/netdevice.h
+         lockfile-util.c
+         lockfile-util.h
+         log-link.h
+-- 
+2.20.1
+
diff --git a/package/systemd/0004-linux-also-import-linux-in.h-and-in6.h-from-kernel-5.patch b/package/systemd/0004-linux-also-import-linux-in.h-and-in6.h-from-kernel-5.patch
new file mode 100644
index 0000000000..3efd396dc5
--- /dev/null
+++ b/package/systemd/0004-linux-also-import-linux-in.h-and-in6.h-from-kernel-5.patch
@@ -0,0 +1,655 @@ 
+From 7057b6144f4c5cb7e284a409c7f24b84c16a3bb8 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Sat, 13 Apr 2019 18:46:40 +0900
+Subject: [PATCH] linux: also import linux/in.h and in6.h from kernel-5.0
+
+Now linux/in.h has better conflict detection with glibc's
+netinet/in.h. So, let's import the headers.
+
+Note that our code already have many workarounds for the conflict,
+but in this commit does not drop them. Let's do that in the later
+commits if this really helps.
+
+[james.hilliard1@gmail.com: backport from upstream commit
+7057b6144f4c5cb7e284a409c7f24b84c16a3bb8]
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+---
+ src/basic/linux/in.h  | 305 ++++++++++++++++++++++++++++++++++++++++++
+ src/basic/linux/in6.h | 299 +++++++++++++++++++++++++++++++++++++++++
+ src/basic/meson.build |   2 +
+ 3 files changed, 606 insertions(+)
+ create mode 100644 src/basic/linux/in.h
+ create mode 100644 src/basic/linux/in6.h
+
+diff --git a/src/basic/linux/in.h b/src/basic/linux/in.h
+new file mode 100644
+index 0000000000..a55cb8b101
+--- /dev/null
++++ b/src/basic/linux/in.h
+@@ -0,0 +1,305 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET		An implementation of the TCP/IP protocol suite for the LINUX
++ *		operating system.  INET is implemented using the  BSD Socket
++ *		interface as the means of communication with the user level.
++ *
++ *		Definitions of the Internet Protocol.
++ *
++ * Version:	@(#)in.h	1.0.1	04/21/93
++ *
++ * Authors:	Original taken from the GNU Project <netinet/in.h> file.
++ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *
++ *		This program is free software; you can redistribute it and/or
++ *		modify it under the terms of the GNU General Public License
++ *		as published by the Free Software Foundation; either version
++ *		2 of the License, or (at your option) any later version.
++ */
++#ifndef _UAPI_LINUX_IN_H
++#define _UAPI_LINUX_IN_H
++
++#include <linux/types.h>
++#include <linux/libc-compat.h>
++#include <linux/socket.h>
++
++#if __UAPI_DEF_IN_IPPROTO
++/* Standard well-defined IP protocols.  */
++enum {
++  IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/
++#define IPPROTO_IP		IPPROTO_IP
++  IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/
++#define IPPROTO_ICMP		IPPROTO_ICMP
++  IPPROTO_IGMP = 2,		/* Internet Group Management Protocol	*/
++#define IPPROTO_IGMP		IPPROTO_IGMP
++  IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */
++#define IPPROTO_IPIP		IPPROTO_IPIP
++  IPPROTO_TCP = 6,		/* Transmission Control Protocol	*/
++#define IPPROTO_TCP		IPPROTO_TCP
++  IPPROTO_EGP = 8,		/* Exterior Gateway Protocol		*/
++#define IPPROTO_EGP		IPPROTO_EGP
++  IPPROTO_PUP = 12,		/* PUP protocol				*/
++#define IPPROTO_PUP		IPPROTO_PUP
++  IPPROTO_UDP = 17,		/* User Datagram Protocol		*/
++#define IPPROTO_UDP		IPPROTO_UDP
++  IPPROTO_IDP = 22,		/* XNS IDP protocol			*/
++#define IPPROTO_IDP		IPPROTO_IDP
++  IPPROTO_TP = 29,		/* SO Transport Protocol Class 4	*/
++#define IPPROTO_TP		IPPROTO_TP
++  IPPROTO_DCCP = 33,		/* Datagram Congestion Control Protocol */
++#define IPPROTO_DCCP		IPPROTO_DCCP
++  IPPROTO_IPV6 = 41,		/* IPv6-in-IPv4 tunnelling		*/
++#define IPPROTO_IPV6		IPPROTO_IPV6
++  IPPROTO_RSVP = 46,		/* RSVP Protocol			*/
++#define IPPROTO_RSVP		IPPROTO_RSVP
++  IPPROTO_GRE = 47,		/* Cisco GRE tunnels (rfc 1701,1702)	*/
++#define IPPROTO_GRE		IPPROTO_GRE
++  IPPROTO_ESP = 50,		/* Encapsulation Security Payload protocol */
++#define IPPROTO_ESP		IPPROTO_ESP
++  IPPROTO_AH = 51,		/* Authentication Header protocol	*/
++#define IPPROTO_AH		IPPROTO_AH
++  IPPROTO_MTP = 92,		/* Multicast Transport Protocol		*/
++#define IPPROTO_MTP		IPPROTO_MTP
++  IPPROTO_BEETPH = 94,		/* IP option pseudo header for BEET	*/
++#define IPPROTO_BEETPH		IPPROTO_BEETPH
++  IPPROTO_ENCAP = 98,		/* Encapsulation Header			*/
++#define IPPROTO_ENCAP		IPPROTO_ENCAP
++  IPPROTO_PIM = 103,		/* Protocol Independent Multicast	*/
++#define IPPROTO_PIM		IPPROTO_PIM
++  IPPROTO_COMP = 108,		/* Compression Header Protocol		*/
++#define IPPROTO_COMP		IPPROTO_COMP
++  IPPROTO_SCTP = 132,		/* Stream Control Transport Protocol	*/
++#define IPPROTO_SCTP		IPPROTO_SCTP
++  IPPROTO_UDPLITE = 136,	/* UDP-Lite (RFC 3828)			*/
++#define IPPROTO_UDPLITE		IPPROTO_UDPLITE
++  IPPROTO_MPLS = 137,		/* MPLS in IP (RFC 4023)		*/
++#define IPPROTO_MPLS		IPPROTO_MPLS
++  IPPROTO_RAW = 255,		/* Raw IP packets			*/
++#define IPPROTO_RAW		IPPROTO_RAW
++  IPPROTO_MAX
++};
++#endif
++
++#if __UAPI_DEF_IN_ADDR
++/* Internet address. */
++struct in_addr {
++	__be32	s_addr;
++};
++#endif
++
++#define IP_TOS		1
++#define IP_TTL		2
++#define IP_HDRINCL	3
++#define IP_OPTIONS	4
++#define IP_ROUTER_ALERT	5
++#define IP_RECVOPTS	6
++#define IP_RETOPTS	7
++#define IP_PKTINFO	8
++#define IP_PKTOPTIONS	9
++#define IP_MTU_DISCOVER	10
++#define IP_RECVERR	11
++#define IP_RECVTTL	12
++#define	IP_RECVTOS	13
++#define IP_MTU		14
++#define IP_FREEBIND	15
++#define IP_IPSEC_POLICY	16
++#define IP_XFRM_POLICY	17
++#define IP_PASSSEC	18
++#define IP_TRANSPARENT	19
++
++/* BSD compatibility */
++#define IP_RECVRETOPTS	IP_RETOPTS
++
++/* TProxy original addresses */
++#define IP_ORIGDSTADDR       20
++#define IP_RECVORIGDSTADDR   IP_ORIGDSTADDR
++
++#define IP_MINTTL       21
++#define IP_NODEFRAG     22
++#define IP_CHECKSUM	23
++#define IP_BIND_ADDRESS_NO_PORT	24
++#define IP_RECVFRAGSIZE	25
++
++/* IP_MTU_DISCOVER values */
++#define IP_PMTUDISC_DONT		0	/* Never send DF frames */
++#define IP_PMTUDISC_WANT		1	/* Use per route hints	*/
++#define IP_PMTUDISC_DO			2	/* Always DF		*/
++#define IP_PMTUDISC_PROBE		3       /* Ignore dst pmtu      */
++/* Always use interface mtu (ignores dst pmtu) but don't set DF flag.
++ * Also incoming ICMP frag_needed notifications will be ignored on
++ * this socket to prevent accepting spoofed ones.
++ */
++#define IP_PMTUDISC_INTERFACE		4
++/* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get
++ * fragmented if they exeed the interface mtu
++ */
++#define IP_PMTUDISC_OMIT		5
++
++#define IP_MULTICAST_IF			32
++#define IP_MULTICAST_TTL 		33
++#define IP_MULTICAST_LOOP 		34
++#define IP_ADD_MEMBERSHIP		35
++#define IP_DROP_MEMBERSHIP		36
++#define IP_UNBLOCK_SOURCE		37
++#define IP_BLOCK_SOURCE			38
++#define IP_ADD_SOURCE_MEMBERSHIP	39
++#define IP_DROP_SOURCE_MEMBERSHIP	40
++#define IP_MSFILTER			41
++#define MCAST_JOIN_GROUP		42
++#define MCAST_BLOCK_SOURCE		43
++#define MCAST_UNBLOCK_SOURCE		44
++#define MCAST_LEAVE_GROUP		45
++#define MCAST_JOIN_SOURCE_GROUP		46
++#define MCAST_LEAVE_SOURCE_GROUP	47
++#define MCAST_MSFILTER			48
++#define IP_MULTICAST_ALL		49
++#define IP_UNICAST_IF			50
++
++#define MCAST_EXCLUDE	0
++#define MCAST_INCLUDE	1
++
++/* These need to appear somewhere around here */
++#define IP_DEFAULT_MULTICAST_TTL        1
++#define IP_DEFAULT_MULTICAST_LOOP       1
++
++/* Request struct for multicast socket ops */
++
++#if __UAPI_DEF_IP_MREQ
++struct ip_mreq  {
++	struct in_addr imr_multiaddr;	/* IP multicast address of group */
++	struct in_addr imr_interface;	/* local IP address of interface */
++};
++
++struct ip_mreqn {
++	struct in_addr	imr_multiaddr;		/* IP multicast address of group */
++	struct in_addr	imr_address;		/* local IP address of interface */
++	int		imr_ifindex;		/* Interface index */
++};
++
++struct ip_mreq_source {
++	__be32		imr_multiaddr;
++	__be32		imr_interface;
++	__be32		imr_sourceaddr;
++};
++
++struct ip_msfilter {
++	__be32		imsf_multiaddr;
++	__be32		imsf_interface;
++	__u32		imsf_fmode;
++	__u32		imsf_numsrc;
++	__be32		imsf_slist[1];
++};
++
++#define IP_MSFILTER_SIZE(numsrc) \
++	(sizeof(struct ip_msfilter) - sizeof(__u32) \
++	+ (numsrc) * sizeof(__u32))
++
++struct group_req {
++	__u32				 gr_interface;	/* interface index */
++	struct __kernel_sockaddr_storage gr_group;	/* group address */
++};
++
++struct group_source_req {
++	__u32				 gsr_interface;	/* interface index */
++	struct __kernel_sockaddr_storage gsr_group;	/* group address */
++	struct __kernel_sockaddr_storage gsr_source;	/* source address */
++};
++
++struct group_filter {
++	__u32				 gf_interface;	/* interface index */
++	struct __kernel_sockaddr_storage gf_group;	/* multicast address */
++	__u32				 gf_fmode;	/* filter mode */
++	__u32				 gf_numsrc;	/* number of sources */
++	struct __kernel_sockaddr_storage gf_slist[1];	/* interface index */
++};
++
++#define GROUP_FILTER_SIZE(numsrc) \
++	(sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
++	+ (numsrc) * sizeof(struct __kernel_sockaddr_storage))
++#endif
++
++#if __UAPI_DEF_IN_PKTINFO
++struct in_pktinfo {
++	int		ipi_ifindex;
++	struct in_addr	ipi_spec_dst;
++	struct in_addr	ipi_addr;
++};
++#endif
++
++/* Structure describing an Internet (IP) socket address. */
++#if  __UAPI_DEF_SOCKADDR_IN
++#define __SOCK_SIZE__	16		/* sizeof(struct sockaddr)	*/
++struct sockaddr_in {
++  __kernel_sa_family_t	sin_family;	/* Address family		*/
++  __be16		sin_port;	/* Port number			*/
++  struct in_addr	sin_addr;	/* Internet address		*/
++
++  /* Pad to size of `struct sockaddr'. */
++  unsigned char		__pad[__SOCK_SIZE__ - sizeof(short int) -
++			sizeof(unsigned short int) - sizeof(struct in_addr)];
++};
++#define sin_zero	__pad		/* for BSD UNIX comp. -FvK	*/
++#endif
++
++#if __UAPI_DEF_IN_CLASS
++/*
++ * Definitions of the bits in an Internet address integer.
++ * On subnets, host and network parts are found according
++ * to the subnet mask, not these masks.
++ */
++#define	IN_CLASSA(a)		((((long int) (a)) & 0x80000000) == 0)
++#define	IN_CLASSA_NET		0xff000000
++#define	IN_CLASSA_NSHIFT	24
++#define	IN_CLASSA_HOST		(0xffffffff & ~IN_CLASSA_NET)
++#define	IN_CLASSA_MAX		128
++
++#define	IN_CLASSB(a)		((((long int) (a)) & 0xc0000000) == 0x80000000)
++#define	IN_CLASSB_NET		0xffff0000
++#define	IN_CLASSB_NSHIFT	16
++#define	IN_CLASSB_HOST		(0xffffffff & ~IN_CLASSB_NET)
++#define	IN_CLASSB_MAX		65536
++
++#define	IN_CLASSC(a)		((((long int) (a)) & 0xe0000000) == 0xc0000000)
++#define	IN_CLASSC_NET		0xffffff00
++#define	IN_CLASSC_NSHIFT	8
++#define	IN_CLASSC_HOST		(0xffffffff & ~IN_CLASSC_NET)
++
++#define	IN_CLASSD(a)		((((long int) (a)) & 0xf0000000) == 0xe0000000)
++#define	IN_MULTICAST(a)		IN_CLASSD(a)
++#define	IN_MULTICAST_NET	0xe0000000
++
++#define	IN_BADCLASS(a)		(((long int) (a) ) == (long int)0xffffffff)
++#define	IN_EXPERIMENTAL(a)	IN_BADCLASS((a))
++
++#define	IN_CLASSE(a)		((((long int) (a)) & 0xf0000000) == 0xf0000000)
++#define	IN_CLASSE_NET		0xffffffff
++#define	IN_CLASSE_NSHIFT	0
++
++/* Address to accept any incoming messages. */
++#define	INADDR_ANY		((unsigned long int) 0x00000000)
++
++/* Address to send to all hosts. */
++#define	INADDR_BROADCAST	((unsigned long int) 0xffffffff)
++
++/* Address indicating an error return. */
++#define	INADDR_NONE		((unsigned long int) 0xffffffff)
++
++/* Network number for local host loopback. */
++#define	IN_LOOPBACKNET		127
++
++/* Address to loopback in software to local host.  */
++#define	INADDR_LOOPBACK		0x7f000001	/* 127.0.0.1   */
++#define	IN_LOOPBACK(a)		((((long int) (a)) & 0xff000000) == 0x7f000000)
++
++/* Defines for Multicast INADDR */
++#define INADDR_UNSPEC_GROUP   	0xe0000000U	/* 224.0.0.0   */
++#define INADDR_ALLHOSTS_GROUP 	0xe0000001U	/* 224.0.0.1   */
++#define INADDR_ALLRTRS_GROUP    0xe0000002U	/* 224.0.0.2 */
++#define INADDR_MAX_LOCAL_GROUP  0xe00000ffU	/* 224.0.0.255 */
++#endif
++
++/* <asm/byteorder.h> contains the htonl type stuff.. */
++#include <asm/byteorder.h> 
++
++
++#endif /* _UAPI_LINUX_IN_H */
+diff --git a/src/basic/linux/in6.h b/src/basic/linux/in6.h
+new file mode 100644
+index 0000000000..71d82fe15b
+--- /dev/null
++++ b/src/basic/linux/in6.h
+@@ -0,0 +1,299 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ *	Types and definitions for AF_INET6 
++ *	Linux INET6 implementation 
++ *
++ *	Authors:
++ *	Pedro Roque		<roque@di.fc.ul.pt>	
++ *
++ *	Sources:
++ *	IPv6 Program Interfaces for BSD Systems
++ *      <draft-ietf-ipngwg-bsd-api-05.txt>
++ *
++ *	Advanced Sockets API for IPv6
++ *	<draft-stevens-advanced-api-00.txt>
++ *
++ *	This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++
++#ifndef _UAPI_LINUX_IN6_H
++#define _UAPI_LINUX_IN6_H
++
++#include <linux/types.h>
++#include <linux/libc-compat.h>
++
++/*
++ *	IPv6 address structure
++ */
++
++#if __UAPI_DEF_IN6_ADDR
++struct in6_addr {
++	union {
++		__u8		u6_addr8[16];
++#if __UAPI_DEF_IN6_ADDR_ALT
++		__be16		u6_addr16[8];
++		__be32		u6_addr32[4];
++#endif
++	} in6_u;
++#define s6_addr			in6_u.u6_addr8
++#if __UAPI_DEF_IN6_ADDR_ALT
++#define s6_addr16		in6_u.u6_addr16
++#define s6_addr32		in6_u.u6_addr32
++#endif
++};
++#endif /* __UAPI_DEF_IN6_ADDR */
++
++#if __UAPI_DEF_SOCKADDR_IN6
++struct sockaddr_in6 {
++	unsigned short int	sin6_family;    /* AF_INET6 */
++	__be16			sin6_port;      /* Transport layer port # */
++	__be32			sin6_flowinfo;  /* IPv6 flow information */
++	struct in6_addr		sin6_addr;      /* IPv6 address */
++	__u32			sin6_scope_id;  /* scope id (new in RFC2553) */
++};
++#endif /* __UAPI_DEF_SOCKADDR_IN6 */
++
++#if __UAPI_DEF_IPV6_MREQ
++struct ipv6_mreq {
++	/* IPv6 multicast address of group */
++	struct in6_addr ipv6mr_multiaddr;
++
++	/* local IPv6 address of interface */
++	int		ipv6mr_ifindex;
++};
++#endif /* __UAPI_DEF_IVP6_MREQ */
++
++#define ipv6mr_acaddr	ipv6mr_multiaddr
++
++struct in6_flowlabel_req {
++	struct in6_addr	flr_dst;
++	__be32	flr_label;
++	__u8	flr_action;
++	__u8	flr_share;
++	__u16	flr_flags;
++	__u16 	flr_expires;
++	__u16	flr_linger;
++	__u32	__flr_pad;
++	/* Options in format of IPV6_PKTOPTIONS */
++};
++
++#define IPV6_FL_A_GET	0
++#define IPV6_FL_A_PUT	1
++#define IPV6_FL_A_RENEW	2
++
++#define IPV6_FL_F_CREATE	1
++#define IPV6_FL_F_EXCL		2
++#define IPV6_FL_F_REFLECT	4
++#define IPV6_FL_F_REMOTE	8
++
++#define IPV6_FL_S_NONE		0
++#define IPV6_FL_S_EXCL		1
++#define IPV6_FL_S_PROCESS	2
++#define IPV6_FL_S_USER		3
++#define IPV6_FL_S_ANY		255
++
++
++/*
++ *	Bitmask constant declarations to help applications select out the 
++ *	flow label and priority fields.
++ *
++ *	Note that this are in host byte order while the flowinfo field of
++ *	sockaddr_in6 is in network byte order.
++ */
++
++#define IPV6_FLOWINFO_FLOWLABEL		0x000fffff
++#define IPV6_FLOWINFO_PRIORITY		0x0ff00000
++
++/* These definitions are obsolete */
++#define IPV6_PRIORITY_UNCHARACTERIZED	0x0000
++#define IPV6_PRIORITY_FILLER		0x0100
++#define IPV6_PRIORITY_UNATTENDED	0x0200
++#define IPV6_PRIORITY_RESERVED1		0x0300
++#define IPV6_PRIORITY_BULK		0x0400
++#define IPV6_PRIORITY_RESERVED2		0x0500
++#define IPV6_PRIORITY_INTERACTIVE	0x0600
++#define IPV6_PRIORITY_CONTROL		0x0700
++#define IPV6_PRIORITY_8			0x0800
++#define IPV6_PRIORITY_9			0x0900
++#define IPV6_PRIORITY_10		0x0a00
++#define IPV6_PRIORITY_11		0x0b00
++#define IPV6_PRIORITY_12		0x0c00
++#define IPV6_PRIORITY_13		0x0d00
++#define IPV6_PRIORITY_14		0x0e00
++#define IPV6_PRIORITY_15		0x0f00
++
++/*
++ *	IPV6 extension headers
++ */
++#if __UAPI_DEF_IPPROTO_V6
++#define IPPROTO_HOPOPTS		0	/* IPv6 hop-by-hop options	*/
++#define IPPROTO_ROUTING		43	/* IPv6 routing header		*/
++#define IPPROTO_FRAGMENT	44	/* IPv6 fragmentation header	*/
++#define IPPROTO_ICMPV6		58	/* ICMPv6			*/
++#define IPPROTO_NONE		59	/* IPv6 no next header		*/
++#define IPPROTO_DSTOPTS		60	/* IPv6 destination options	*/
++#define IPPROTO_MH		135	/* IPv6 mobility header		*/
++#endif /* __UAPI_DEF_IPPROTO_V6 */
++
++/*
++ *	IPv6 TLV options.
++ */
++#define IPV6_TLV_PAD1		0
++#define IPV6_TLV_PADN		1
++#define IPV6_TLV_ROUTERALERT	5
++#define IPV6_TLV_CALIPSO	7	/* RFC 5570 */
++#define IPV6_TLV_JUMBO		194
++#define IPV6_TLV_HAO		201	/* home address option */
++
++/*
++ *	IPV6 socket options
++ */
++#if __UAPI_DEF_IPV6_OPTIONS
++#define IPV6_ADDRFORM		1
++#define IPV6_2292PKTINFO	2
++#define IPV6_2292HOPOPTS	3
++#define IPV6_2292DSTOPTS	4
++#define IPV6_2292RTHDR		5
++#define IPV6_2292PKTOPTIONS	6
++#define IPV6_CHECKSUM		7
++#define IPV6_2292HOPLIMIT	8
++#define IPV6_NEXTHOP		9
++#define IPV6_AUTHHDR		10	/* obsolete */
++#define IPV6_FLOWINFO		11
++
++#define IPV6_UNICAST_HOPS	16
++#define IPV6_MULTICAST_IF	17
++#define IPV6_MULTICAST_HOPS	18
++#define IPV6_MULTICAST_LOOP	19
++#define IPV6_ADD_MEMBERSHIP	20
++#define IPV6_DROP_MEMBERSHIP	21
++#define IPV6_ROUTER_ALERT	22
++#define IPV6_MTU_DISCOVER	23
++#define IPV6_MTU		24
++#define IPV6_RECVERR		25
++#define IPV6_V6ONLY		26
++#define IPV6_JOIN_ANYCAST	27
++#define IPV6_LEAVE_ANYCAST	28
++#define IPV6_MULTICAST_ALL	29
++
++/* IPV6_MTU_DISCOVER values */
++#define IPV6_PMTUDISC_DONT		0
++#define IPV6_PMTUDISC_WANT		1
++#define IPV6_PMTUDISC_DO		2
++#define IPV6_PMTUDISC_PROBE		3
++/* same as IPV6_PMTUDISC_PROBE, provided for symetry with IPv4
++ * also see comments on IP_PMTUDISC_INTERFACE
++ */
++#define IPV6_PMTUDISC_INTERFACE		4
++/* weaker version of IPV6_PMTUDISC_INTERFACE, which allows packets to
++ * get fragmented if they exceed the interface mtu
++ */
++#define IPV6_PMTUDISC_OMIT		5
++
++/* Flowlabel */
++#define IPV6_FLOWLABEL_MGR	32
++#define IPV6_FLOWINFO_SEND	33
++
++#define IPV6_IPSEC_POLICY	34
++#define IPV6_XFRM_POLICY	35
++#define IPV6_HDRINCL		36
++#endif
++
++/*
++ * Multicast:
++ * Following socket options are shared between IPv4 and IPv6.
++ *
++ * MCAST_JOIN_GROUP		42
++ * MCAST_BLOCK_SOURCE		43
++ * MCAST_UNBLOCK_SOURCE		44
++ * MCAST_LEAVE_GROUP		45
++ * MCAST_JOIN_SOURCE_GROUP	46
++ * MCAST_LEAVE_SOURCE_GROUP	47
++ * MCAST_MSFILTER		48
++ */
++
++/*
++ * Advanced API (RFC3542) (1)
++ *
++ * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c.
++ */
++
++#define IPV6_RECVPKTINFO	49
++#define IPV6_PKTINFO		50
++#define IPV6_RECVHOPLIMIT	51
++#define IPV6_HOPLIMIT		52
++#define IPV6_RECVHOPOPTS	53
++#define IPV6_HOPOPTS		54
++#define IPV6_RTHDRDSTOPTS	55
++#define IPV6_RECVRTHDR		56
++#define IPV6_RTHDR		57
++#define IPV6_RECVDSTOPTS	58
++#define IPV6_DSTOPTS		59
++#define IPV6_RECVPATHMTU	60
++#define IPV6_PATHMTU		61
++#define IPV6_DONTFRAG		62
++#if 0	/* not yet */
++#define IPV6_USE_MIN_MTU	63
++#endif
++
++/*
++ * Netfilter (1)
++ *
++ * Following socket options are used in ip6_tables;
++ * see include/linux/netfilter_ipv6/ip6_tables.h.
++ *
++ * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO		64
++ * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES	65
++ */
++
++/*
++ * Advanced API (RFC3542) (2)
++ */
++#define IPV6_RECVTCLASS		66
++#define IPV6_TCLASS		67
++
++/*
++ * Netfilter (2)
++ *
++ * Following socket options are used in ip6_tables;
++ * see include/linux/netfilter_ipv6/ip6_tables.h.
++ *
++ * IP6T_SO_GET_REVISION_MATCH	68
++ * IP6T_SO_GET_REVISION_TARGET	69
++ * IP6T_SO_ORIGINAL_DST		80
++ */
++
++#define IPV6_AUTOFLOWLABEL	70
++/* RFC5014: Source address selection */
++#define IPV6_ADDR_PREFERENCES	72
++
++#define IPV6_PREFER_SRC_TMP		0x0001
++#define IPV6_PREFER_SRC_PUBLIC		0x0002
++#define IPV6_PREFER_SRC_PUBTMP_DEFAULT	0x0100
++#define IPV6_PREFER_SRC_COA		0x0004
++#define IPV6_PREFER_SRC_HOME		0x0400
++#define IPV6_PREFER_SRC_CGA		0x0008
++#define IPV6_PREFER_SRC_NONCGA		0x0800
++
++/* RFC5082: Generalized Ttl Security Mechanism */
++#define IPV6_MINHOPCOUNT		73
++
++#define IPV6_ORIGDSTADDR        74
++#define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR
++#define IPV6_TRANSPARENT        75
++#define IPV6_UNICAST_IF         76
++#define IPV6_RECVFRAGSIZE	77
++#define IPV6_FREEBIND		78
++
++/*
++ * Multicast Routing:
++ * see include/uapi/linux/mroute6.h.
++ *
++ * MRT6_BASE			200
++ * ...
++ * MRT6_MAX
++ */
++#endif /* _UAPI_LINUX_IN6_H */
+diff --git a/src/basic/meson.build b/src/basic/meson.build
+index 81c3d0f3e8..26c7fc42c7 100644
+--- a/src/basic/meson.build
++++ b/src/basic/meson.build
+@@ -98,6 +98,8 @@ basic_sources = files('''
+         linux/if_macsec.h
+         linux/if_tun.h
+         linux/if_tunnel.h
++        linux/in.h
++        linux/in6.h
+         linux/libc-compat.h
+         linux/netdevice.h
+         linux/netlink.h
+-- 
+2.20.1
+
diff --git a/package/systemd/0004-meson-drop-misplaced-Wl-undefined-argument.patch b/package/systemd/0004-meson-drop-misplaced-Wl-undefined-argument.patch
deleted file mode 100644
index 52ef811494..0000000000
--- a/package/systemd/0004-meson-drop-misplaced-Wl-undefined-argument.patch
+++ /dev/null
@@ -1,51 +0,0 @@ 
-From 700805f6c546f2adb79059614f3747f7b5474325 Mon Sep 17 00:00:00 2001
-From: Jussi Pakkanen <jpakkane@gmail.com>
-Date: Sat, 6 Apr 2019 21:59:06 +0200
-Subject: [PATCH] meson: drop misplaced -Wl,--undefined argument
-
-Ld's man page says the following:
-
-  -u symbol
-  --undefined=symbol
-
-  Force symbol to be entered in the output file as an undefined symbol. Doing
-  this may, for example, trigger linking of additional modules from standard
-  libraries. -u may be repeated with different option arguments to enter
-  additional undefined symbols. This option is equivalent to the "EXTERN"
-  linker script command.
-
-  If this option is being used to force additional modules to be pulled into
-  the link, and if it is an error for the symbol to remain undefined, then the
-  option --require-defined should be used instead.
-
-This would imply that it always requires an argument, which this does not
-pass. Thus it will grab the next argument on the command line as its
-argument. Before it took one of the many -lrt args (presumably) and now it
-grabs something other random linker argument and things break.
-
-[zj: this line was added in the first version of the meson configuration back
-in 5c23128daba7236a6080383b2a5649033cfef85c. AFAICT, this was a mistake. No
-such flag appeared in Makefile.am at the time.]
-
-https://github.com/mesonbuild/meson/issues/5113
-Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
-[Retrieved from:
-https://github.com/systemd/systemd/commit/700805f6c546f2adb79059614f3747f7b5474325]
----
- meson.build | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/meson.build b/meson.build
-index 287125f0107..79195c97484 100644
---- a/meson.build
-+++ b/meson.build
-@@ -1606,8 +1606,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
-                         # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
-                         link_args : ['-Wl,-z,nodelete',
-                                      '-shared',
--                                     '-Wl,--version-script=' + version_script_arg,
--                                     '-Wl,--undefined'],
-+                                     '-Wl,--version-script=' + version_script_arg],
-                         link_with : [libsystemd_static,
-                                      libbasic],
-                         dependencies : [threads,
diff --git a/package/systemd/0005-linux-also-import-l2tp.h-from-kernel-5.0.patch b/package/systemd/0005-linux-also-import-l2tp.h-from-kernel-5.0.patch
new file mode 100644
index 0000000000..934029cf58
--- /dev/null
+++ b/package/systemd/0005-linux-also-import-l2tp.h-from-kernel-5.0.patch
@@ -0,0 +1,242 @@ 
+From aa8129049564627fd9eb7866fa58c9bc9f47c672 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Sat, 13 Apr 2019 18:35:15 +0900
+Subject: [PATCH] linux: also import l2tp.h from kernel-5.0
+
+The L2TP_ATTR_UDP_ZERO_CSUM6_{TX,RX} attributes are introduced by
+6b649feafe10b293f4bd5a74aca95faf625ae525, which is included in
+kernel-3.16. To support older kernel, let's import the header.
+
+Fixes #12300.
+
+[james.hilliard1@gmail.com: backport from upstream commit
+aa8129049564627fd9eb7866fa58c9bc9f47c672]
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+---
+ src/basic/linux/l2tp.h | 201 +++++++++++++++++++++++++++++++++++++++++
+ src/basic/meson.build  |   1 +
+ 2 files changed, 202 insertions(+)
+ create mode 100644 src/basic/linux/l2tp.h
+
+diff --git a/src/basic/linux/l2tp.h b/src/basic/linux/l2tp.h
+new file mode 100644
+index 0000000000..61158f5a1a
+--- /dev/null
++++ b/src/basic/linux/l2tp.h
+@@ -0,0 +1,201 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/*
++ * L2TP-over-IP socket for L2TPv3.
++ *
++ * Author: James Chapman <jchapman@katalix.com>
++ */
++
++#ifndef _UAPI_LINUX_L2TP_H_
++#define _UAPI_LINUX_L2TP_H_
++
++#include <linux/types.h>
++#include <linux/socket.h>
++#include <linux/in.h>
++#include <linux/in6.h>
++
++#define IPPROTO_L2TP		115
++
++/**
++ * struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets
++ * @l2tp_family:  address family number AF_L2TPIP.
++ * @l2tp_addr:    protocol specific address information
++ * @l2tp_conn_id: connection id of tunnel
++ */
++#define __SOCK_SIZE__	16		/* sizeof(struct sockaddr)	*/
++struct sockaddr_l2tpip {
++	/* The first fields must match struct sockaddr_in */
++	__kernel_sa_family_t l2tp_family; /* AF_INET */
++	__be16		l2tp_unused;	/* INET port number (unused) */
++	struct in_addr	l2tp_addr;	/* Internet address */
++
++	__u32		l2tp_conn_id;	/* Connection ID of tunnel */
++
++	/* Pad to size of `struct sockaddr'. */
++	unsigned char	__pad[__SOCK_SIZE__ -
++			      sizeof(__kernel_sa_family_t) -
++			      sizeof(__be16) - sizeof(struct in_addr) -
++			      sizeof(__u32)];
++};
++
++/**
++ * struct sockaddr_l2tpip6 - the sockaddr structure for L2TP-over-IPv6 sockets
++ * @l2tp_family:  address family number AF_L2TPIP.
++ * @l2tp_addr:    protocol specific address information
++ * @l2tp_conn_id: connection id of tunnel
++ */
++struct sockaddr_l2tpip6 {
++	/* The first fields must match struct sockaddr_in6 */
++	__kernel_sa_family_t l2tp_family; /* AF_INET6 */
++	__be16		l2tp_unused;	/* INET port number (unused) */
++	__be32		l2tp_flowinfo;	/* IPv6 flow information */
++	struct in6_addr	l2tp_addr;	/* IPv6 address */
++	__u32		l2tp_scope_id;	/* scope id (new in RFC2553) */
++	__u32		l2tp_conn_id;	/* Connection ID of tunnel */
++};
++
++/*****************************************************************************
++ *  NETLINK_GENERIC netlink family.
++ *****************************************************************************/
++
++/*
++ * Commands.
++ * Valid TLVs of each command are:-
++ * TUNNEL_CREATE	- CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum
++ * TUNNEL_DELETE	- CONN_ID
++ * TUNNEL_MODIFY	- CONN_ID, udpcsum
++ * TUNNEL_GETSTATS	- CONN_ID, (stats)
++ * TUNNEL_GET		- CONN_ID, (...)
++ * SESSION_CREATE	- SESSION_ID, PW_TYPE, cookie, peer_cookie, l2spec
++ * SESSION_DELETE	- SESSION_ID
++ * SESSION_MODIFY	- SESSION_ID
++ * SESSION_GET		- SESSION_ID, (...)
++ * SESSION_GETSTATS	- SESSION_ID, (stats)
++ *
++ */
++enum {
++	L2TP_CMD_NOOP,
++	L2TP_CMD_TUNNEL_CREATE,
++	L2TP_CMD_TUNNEL_DELETE,
++	L2TP_CMD_TUNNEL_MODIFY,
++	L2TP_CMD_TUNNEL_GET,
++	L2TP_CMD_SESSION_CREATE,
++	L2TP_CMD_SESSION_DELETE,
++	L2TP_CMD_SESSION_MODIFY,
++	L2TP_CMD_SESSION_GET,
++	__L2TP_CMD_MAX,
++};
++
++#define L2TP_CMD_MAX			(__L2TP_CMD_MAX - 1)
++
++/*
++ * ATTR types defined for L2TP
++ */
++enum {
++	L2TP_ATTR_NONE,			/* no data */
++	L2TP_ATTR_PW_TYPE,		/* u16, enum l2tp_pwtype */
++	L2TP_ATTR_ENCAP_TYPE,		/* u16, enum l2tp_encap_type */
++	L2TP_ATTR_OFFSET,		/* u16 (not used) */
++	L2TP_ATTR_DATA_SEQ,		/* u16 (not used) */
++	L2TP_ATTR_L2SPEC_TYPE,		/* u8, enum l2tp_l2spec_type */
++	L2TP_ATTR_L2SPEC_LEN,		/* u8 (not used) */
++	L2TP_ATTR_PROTO_VERSION,	/* u8 */
++	L2TP_ATTR_IFNAME,		/* string */
++	L2TP_ATTR_CONN_ID,		/* u32 */
++	L2TP_ATTR_PEER_CONN_ID,		/* u32 */
++	L2TP_ATTR_SESSION_ID,		/* u32 */
++	L2TP_ATTR_PEER_SESSION_ID,	/* u32 */
++	L2TP_ATTR_UDP_CSUM,		/* u8 */
++	L2TP_ATTR_VLAN_ID,		/* u16 (not used) */
++	L2TP_ATTR_COOKIE,		/* 0, 4 or 8 bytes */
++	L2TP_ATTR_PEER_COOKIE,		/* 0, 4 or 8 bytes */
++	L2TP_ATTR_DEBUG,		/* u32, enum l2tp_debug_flags */
++	L2TP_ATTR_RECV_SEQ,		/* u8 */
++	L2TP_ATTR_SEND_SEQ,		/* u8 */
++	L2TP_ATTR_LNS_MODE,		/* u8 */
++	L2TP_ATTR_USING_IPSEC,		/* u8 */
++	L2TP_ATTR_RECV_TIMEOUT,		/* msec */
++	L2TP_ATTR_FD,			/* int */
++	L2TP_ATTR_IP_SADDR,		/* u32 */
++	L2TP_ATTR_IP_DADDR,		/* u32 */
++	L2TP_ATTR_UDP_SPORT,		/* u16 */
++	L2TP_ATTR_UDP_DPORT,		/* u16 */
++	L2TP_ATTR_MTU,			/* u16 (not used) */
++	L2TP_ATTR_MRU,			/* u16 (not used) */
++	L2TP_ATTR_STATS,		/* nested */
++	L2TP_ATTR_IP6_SADDR,		/* struct in6_addr */
++	L2TP_ATTR_IP6_DADDR,		/* struct in6_addr */
++	L2TP_ATTR_UDP_ZERO_CSUM6_TX,	/* flag */
++	L2TP_ATTR_UDP_ZERO_CSUM6_RX,	/* flag */
++	L2TP_ATTR_PAD,
++	__L2TP_ATTR_MAX,
++};
++
++#define L2TP_ATTR_MAX			(__L2TP_ATTR_MAX - 1)
++
++/* Nested in L2TP_ATTR_STATS */
++enum {
++	L2TP_ATTR_STATS_NONE,		/* no data */
++	L2TP_ATTR_TX_PACKETS,		/* u64 */
++	L2TP_ATTR_TX_BYTES,		/* u64 */
++	L2TP_ATTR_TX_ERRORS,		/* u64 */
++	L2TP_ATTR_RX_PACKETS,		/* u64 */
++	L2TP_ATTR_RX_BYTES,		/* u64 */
++	L2TP_ATTR_RX_SEQ_DISCARDS,	/* u64 */
++	L2TP_ATTR_RX_OOS_PACKETS,	/* u64 */
++	L2TP_ATTR_RX_ERRORS,		/* u64 */
++	L2TP_ATTR_STATS_PAD,
++	__L2TP_ATTR_STATS_MAX,
++};
++
++#define L2TP_ATTR_STATS_MAX		(__L2TP_ATTR_STATS_MAX - 1)
++
++enum l2tp_pwtype {
++	L2TP_PWTYPE_NONE = 0x0000,
++	L2TP_PWTYPE_ETH_VLAN = 0x0004,
++	L2TP_PWTYPE_ETH = 0x0005,
++	L2TP_PWTYPE_PPP = 0x0007,
++	L2TP_PWTYPE_PPP_AC = 0x0008,
++	L2TP_PWTYPE_IP = 0x000b,
++	__L2TP_PWTYPE_MAX
++};
++
++enum l2tp_l2spec_type {
++	L2TP_L2SPECTYPE_NONE,
++	L2TP_L2SPECTYPE_DEFAULT,
++};
++
++enum l2tp_encap_type {
++	L2TP_ENCAPTYPE_UDP,
++	L2TP_ENCAPTYPE_IP,
++};
++
++/* For L2TP_ATTR_DATA_SEQ. Unused. */
++enum l2tp_seqmode {
++	L2TP_SEQ_NONE = 0,
++	L2TP_SEQ_IP = 1,
++	L2TP_SEQ_ALL = 2,
++};
++
++/**
++ * enum l2tp_debug_flags - debug message categories for L2TP tunnels/sessions
++ *
++ * @L2TP_MSG_DEBUG: verbose debug (if compiled in)
++ * @L2TP_MSG_CONTROL: userspace - kernel interface
++ * @L2TP_MSG_SEQ: sequence numbers
++ * @L2TP_MSG_DATA: data packets
++ */
++enum l2tp_debug_flags {
++	L2TP_MSG_DEBUG		= (1 << 0),
++	L2TP_MSG_CONTROL	= (1 << 1),
++	L2TP_MSG_SEQ		= (1 << 2),
++	L2TP_MSG_DATA		= (1 << 3),
++};
++
++/*
++ * NETLINK_GENERIC related info
++ */
++#define L2TP_GENL_NAME		"l2tp"
++#define L2TP_GENL_VERSION	0x1
++#define L2TP_GENL_MCGROUP       "l2tp"
++
++#endif /* _UAPI_LINUX_L2TP_H_ */
+diff --git a/src/basic/meson.build b/src/basic/meson.build
+index 26c7fc42c7..67f04bcbc4 100644
+--- a/src/basic/meson.build
++++ b/src/basic/meson.build
+@@ -100,6 +100,7 @@ basic_sources = files('''
+         linux/if_tunnel.h
+         linux/in.h
+         linux/in6.h
++        linux/l2tp.h
+         linux/libc-compat.h
+         linux/netdevice.h
+         linux/netlink.h
+-- 
+2.20.1
+
diff --git a/package/systemd/systemd.hash b/package/systemd/systemd.hash
index c769d48959..b3c5e4c64f 100644
--- a/package/systemd/systemd.hash
+++ b/package/systemd/systemd.hash
@@ -1,5 +1,5 @@ 
 # sha256 locally computed
-sha256	b2561a8e1d10a2c248253f0dda31a85dd6d69f2b54177de55e02cd1d2778316e  	systemd-241.tar.gz
+sha256	ec22be9a5dd94c9640e6348ed8391d1499af8ca2c2f01109198a414cff6c6cba  	systemd-242.tar.gz
 sha256	ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6	LICENSE.GPL2
 sha256	dc626520dcd53a22f727af3ee42c770e56c97a64fe3adb063799d8ab032fe551	LICENSE.LGPL2.1
 sha256	d9356b277440f21730426592c27170d034a39954ab5154dfba1cc3cbf7b22935	README
diff --git a/package/systemd/systemd.mk b/package/systemd/systemd.mk
index e8fd7967bd..8efb7f192b 100644
--- a/package/systemd/systemd.mk
+++ b/package/systemd/systemd.mk
@@ -4,7 +4,7 @@ 
 #
 ################################################################################
 
-SYSTEMD_VERSION = 241
+SYSTEMD_VERSION = 242
 SYSTEMD_SITE = $(call github,systemd,systemd,v$(SYSTEMD_VERSION))
 SYSTEMD_LICENSE = LGPL-2.1+, GPL-2.0+ (udev), Public Domain (few source files, see README)
 SYSTEMD_LICENSE_FILES = LICENSE.GPL2 LICENSE.LGPL2.1 README
@@ -24,7 +24,6 @@  SYSTEMD_CONF_OPTS += \
 	-Dblkid=true \
 	-Dman=false \
 	-Dima=false \
-	-Dlibcryptsetup=false \
 	-Dldconfig=false \
 	-Ddefault-dnssec=no \
 	-Dtests=false \
@@ -52,6 +51,12 @@  endif
 ifeq ($(BR2_PACKAGE_AUDIT),y)
 SYSTEMD_DEPENDENCIES += audit
 SYSTEMD_CONF_OPTS += -Daudit=true
+define SYSTEMD_INSTALL_SERVICE_AUDIT
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../../usr/lib/systemd/system/auditd.service \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/auditd.service
+endef
+
 else
 SYSTEMD_CONF_OPTS += -Daudit=false
 endif
@@ -59,6 +64,11 @@  endif
 ifeq ($(BR2_PACKAGE_CRYPTSETUP),y)
 SYSTEMD_DEPENDENCIES += cryptsetup
 SYSTEMD_CONF_OPTS += -Dlibcryptsetup=true
+define SYSTEMD_INSTALL_TARGET_CRYPTSETUP
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../../usr/lib/systemd/system/remote-cryptsetup.target \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/remote-cryptsetup.target
+endef
 else
 SYSTEMD_CONF_OPTS += -Dlibcryptsetup=false
 endif
@@ -259,6 +269,11 @@  endif
 
 ifeq ($(BR2_PACKAGE_SYSTEMD_MACHINED),y)
 SYSTEMD_CONF_OPTS += -Dmachined=true
+define SYSTEMD_INSTALL_TARGET_MACHINED
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../../lib/systemd/system/machines.target \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/machines.target
+endef
 else
 SYSTEMD_CONF_OPTS += -Dmachined=false
 endif
@@ -310,6 +325,21 @@  endif
 ifeq ($(BR2_PACKAGE_SYSTEMD_NETWORKD),y)
 SYSTEMD_CONF_OPTS += -Dnetworkd=true
 SYSTEMD_NETWORKD_USER = systemd-network -1 systemd-network -1 * - - - Network Manager
+define SYSTEMD_INSTALL_SOCKET_NETWORKD
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/sockets.target.wants
+	ln -sf ../../../../lib/systemd/system/systemd-networkd.socket \
+		$(TARGET_DIR)/etc/systemd/system/sockets.target.wants/systemd-networkd.socket
+endef
+define SYSTEMD_INSTALL_SERVICE_NETWORKD
+	ln -sf ../../../lib/systemd/system/systemd-networkd.service \
+		$(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.network1.service
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../../lib/systemd/system/systemd-networkd.service \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/systemd-networkd.service
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/network-online.target.wants
+	ln -sf ../../../../lib/systemd/system/systemd-networkd-wait-online.service \
+		$(TARGET_DIR)/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service
+endef
 define SYSTEMD_INSTALL_RESOLVCONF_HOOK
 	ln -sf ../run/systemd/resolve/resolv.conf \
 		$(TARGET_DIR)/etc/resolv.conf
@@ -329,6 +359,13 @@  endif
 ifeq ($(BR2_PACKAGE_SYSTEMD_RESOLVED),y)
 SYSTEMD_CONF_OPTS += -Dresolve=true
 SYSTEMD_RESOLVED_USER = systemd-resolve -1 systemd-resolve -1 * - - - Network Name Resolution Manager
+define SYSTEMD_INSTALL_SERVICE_RESOLVED
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../lib/systemd/system/systemd-resolved.service \
+		$(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.resolve1.service
+	ln -sf ../../../../lib/systemd/system/systemd-resolved.service \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/systemd-resolved.service
+endef
 else
 SYSTEMD_CONF_OPTS += -Dresolve=false
 endif
@@ -336,10 +373,14 @@  endif
 ifeq ($(BR2_PACKAGE_SYSTEMD_TIMESYNCD),y)
 SYSTEMD_CONF_OPTS += -Dtimesyncd=true
 SYSTEMD_TIMESYNCD_USER = systemd-timesync -1 systemd-timesync -1 * - - - Network Time Synchronization
-define SYSTEMD_INSTALL_SERVICE_TIMESYNC
+define SYSTEMD_INSTALL_SERVICE_TIMESYNCD
 	mkdir -p $(TARGET_DIR)/etc/systemd/system/sysinit.target.wants
 	ln -sf ../../../../lib/systemd/system/systemd-timesyncd.service \
 		$(TARGET_DIR)/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service
+	ln -sf ../../../../lib/systemd/system/systemd-time-wait-sync.service \
+		$(TARGET_DIR)/etc/systemd/system/sysinit.target.wants/systemd-time-wait-sync.service
+	ln -sf ../../../lib/systemd/system/systemd-timesyncd.service \
+		$(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.timesync1.service
 endef
 else
 SYSTEMD_CONF_OPTS += -Dtimesyncd=false
@@ -398,6 +439,11 @@  define SYSTEMD_INSTALL_INIT_HOOK
 	ln -fs ../bin/systemctl $(TARGET_DIR)/sbin/shutdown
 	ln -fs ../../../lib/systemd/system/multi-user.target \
 		$(TARGET_DIR)/etc/systemd/system/default.target
+	ln -fs ../../../lib/systemd/system/reboot.target \
+		$(TARGET_DIR)/etc/systemd/system/ctrl-alt-del.target
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
+	ln -sf ../../../../lib/systemd/system/remote-fs.target \
+		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/remote-fs.target
 endef
 
 define SYSTEMD_INSTALL_MACHINEID_HOOK
@@ -405,6 +451,9 @@  define SYSTEMD_INSTALL_MACHINEID_HOOK
 endef
 
 SYSTEMD_POST_INSTALL_TARGET_HOOKS += \
+	SYSTEMD_INSTALL_TARGET_CRYPTSETUP \
+	SYSTEMD_INSTALL_TARGET_MACHINED \
+	SYSTEMD_INSTALL_SOCKET_NETWORKD \
 	SYSTEMD_INSTALL_INIT_HOOK \
 	SYSTEMD_INSTALL_MACHINEID_HOOK \
 	SYSTEMD_INSTALL_RESOLVCONF_HOOK
@@ -458,11 +507,27 @@  define SYSTEMD_INSTALL_SERVICE_TTY
 endef
 endif
 
+define SYSTEMD_INSTALL_SERVICE_AUTOVT
+	ln -sf ../../../lib/systemd/system/getty@.service \
+		$(TARGET_DIR)/lib/systemd/system/autovt@.service
+endef
+
+define SYSTEMD_INSTALL_SERVICE_BOOT_CHECK
+	mkdir -p $(TARGET_DIR)/etc/systemd/system/boot-complete.target.requires
+	ln -sf ../../../../lib/systemd/system/systemd-boot-check-no-failures.service \
+		$(TARGET_DIR)/etc/systemd/system/boot-complete.target.requires/systemd-boot-check-no-failures.service
+endef
+
 define SYSTEMD_INSTALL_INIT_SYSTEMD
 	$(SYSTEMD_DISABLE_SERVICE_TTY1)
 	$(SYSTEMD_INSTALL_SERVICE_TTY)
-	$(SYSTEMD_INSTALL_SERVICE_TIMESYNC)
+	$(SYSTEMD_INSTALL_SERVICE_AUTOVT)
+	$(SYSTEMD_INSTALL_SERVICE_RESOLVED)
+	$(SYSTEMD_INSTALL_SERVICE_TIMESYNCD)
 	$(SYSTEMD_INSTALL_NETWORK_CONFS)
+	$(SYSTEMD_INSTALL_SERVICE_NETWORKD)
+	$(SYSTEMD_INSTALL_SERVICE_AUDIT)
+	$(SYSTEMD_INSTALL_SERVICE_BOOT_CHECK)
 endef
 
 SYSTEMD_CONF_ENV = $(HOST_UTF8_LOCALE_ENV)