diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 8031bc0e0b..5703e4f53b 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -182,6 +182,9 @@
xfrm
A virtual tunnel interface like vti/vti6 but with several advantages.
+ ifb
+ The Intermediate Functional Block (ifb) pseudo network interface acts as a QoS concentrator for multiple different sources of traffic.
+
diff --git a/src/network/meson.build b/src/network/meson.build
index e2324a01b3..8a09078315 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -7,6 +7,8 @@ sources = files('''
netdev/bridge.h
netdev/dummy.c
netdev/dummy.h
+ netdev/ifb.c
+ netdev/ifb.h
netdev/ipvlan.c
netdev/ipvlan.h
netdev/macvlan.c
diff --git a/src/network/netdev/ifb.c b/src/network/netdev/ifb.c
new file mode 100644
index 0000000000..7736a162f9
--- /dev/null
+++ b/src/network/netdev/ifb.c
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2019 VMware, Inc. */
+
+#include "ifb.h"
+
+const NetDevVTable ifb_vtable = {
+ .object_size = sizeof(IntermediateFunctionalBlock),
+ .sections = NETDEV_COMMON_SECTIONS,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
+ .generate_mac = true,
+};
diff --git a/src/network/netdev/ifb.h b/src/network/netdev/ifb.h
new file mode 100644
index 0000000000..761d215894
--- /dev/null
+++ b/src/network/netdev/ifb.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2019 VMware, Inc. */
+
+#pragma once
+
+#include "netdev.h"
+
+typedef struct IntermediateFunctionalBlock {
+ NetDev meta;
+} IntermediateFunctionalBlock;
+
+DEFINE_NETDEV_CAST(IFB, IntermediateFunctionalBlock);
+extern const NetDevVTable ifb_vtable;
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 423750a6a0..f8121a48ed 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -12,6 +12,7 @@
#include "fd-util.h"
#include "fou-tunnel.h"
#include "geneve.h"
+#include "ifb.h"
#include "ipvlan.h"
#include "l2tp-tunnel.h"
#include "list.h"
@@ -73,6 +74,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_MACSEC] = &macsec_vtable,
[NETDEV_KIND_NLMON] = &nlmon_vtable,
[NETDEV_KIND_XFRM] = &xfrm_vtable,
+ [NETDEV_KIND_IFB] = &ifb_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -109,6 +111,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_MACSEC] = "macsec",
[NETDEV_KIND_NLMON] = "nlmon",
[NETDEV_KIND_XFRM] = "xfrm",
+ [NETDEV_KIND_IFB] = "ifb",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index 078d0aca4f..cc530022c1 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -80,6 +80,7 @@ typedef enum NetDevKind {
NETDEV_KIND_MACSEC,
NETDEV_KIND_NLMON,
NETDEV_KIND_XFRM,
+ NETDEV_KIND_IFB,
_NETDEV_KIND_MAX,
_NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */
_NETDEV_KIND_INVALID = -1