Re: [PATCH netifd] team: add simple bonding/teaming module

2021-01-16 Thread Pavel Šimerda

On 1/16/21 1:55 PM, Petr Štetiar wrote:

Pavel Šimerda  [2021-01-12 04:36:36]:

Hi,


The module requires libteam's teamd and teamdctl commands.


This looks like an alien to the OpenWrt ecosystem, basically you're using
netifd just as a launcher for teamd, teamdctl without any proper error
handling instead of ubus for configuration etc.


Hey Petr,

this is what I'm using right now to enable the hardware features that were 
*absent* in OpenWRT. Would you suggest that we keep a local fork for the time 
being, until someone is willing to invest their time into building a ubus 
wrapper for libteam?

Cheers,

Pavel Šimerda




Signed-off-by: Pavel Šimerda 
---
  CMakeLists.txt |   2 +-
  team.c | 178 +
  2 files changed, 179 insertions(+), 1 deletion(-)
  create mode 100644 team.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d19817..351e303 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ SET(SOURCES
main.c utils.c system.c tunnel.c handler.c
interface.c interface-ip.c interface-event.c
iprule.c proto.c proto-static.c proto-shell.c
-   config.c device.c bridge.c veth.c vlan.c alias.c
+   config.c device.c bridge.c team.c veth.c vlan.c alias.c
macvlan.c ubus.c vlandev.c wireless.c)
  
  
diff --git a/team.c b/team.c

new file mode 100644
index 000..9b67566
--- /dev/null
+++ b/team.c
@@ -0,0 +1,178 @@
+/*
+ * netifd - network interface daemon
+ * Copyright (C) 2021 Pavel Šimerda 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * 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.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "netifd.h"
+#include "device.h"
+#include "interface.h"
+#include "system.h"
+
+enum {
+   TEAM_ATTR_IFNAME,
+   __TEAM_ATTR_MAX
+};
+
+static const struct blobmsg_policy team_attrs[__TEAM_ATTR_MAX] = {
+   [TEAM_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_ARRAY },
+};
+
+static const struct uci_blob_param_info team_attr_info[__TEAM_ATTR_MAX] = {
+   [TEAM_ATTR_IFNAME] = { .type = BLOBMSG_TYPE_STRING },
+};
+
+static const struct uci_blob_param_list team_attr_list = {
+   .n_params = __TEAM_ATTR_MAX,
+   .params = team_attrs,
+   .info = team_attr_info,
+
+   .n_next = 1,
+   .next = { &device_attr_list },
+};
+
+struct team_device {
+   struct device dev;
+   device_state_cb set_state;
+
+   struct blob_attr *config_data;
+   struct blob_attr *ifnames;
+
+   int pid;
+};
+
+static int
+team_set_state(struct device *dev, bool up)
+{
+   struct team_device *teamdev = container_of(dev, struct team_device, 
dev);
+
+   if (up) {
+   int pid;
+   struct blob_attr *cur;
+   int rem;
+   char buffer[64];
+
+   printf("TEAM start teamd\n");


if this is needed at all, take a look around and use proper debug logging


+   pid = fork();
+   if (pid == -1)
+   return -errno;
+   if (pid == 0)
+   execlp("teamd", "teamd", "-t", dev->ifname, NULL);


this is external dependency and you lack any check for that


+   teamdev->pid = pid;
+   // TODO: Better handling of newly created devices.


better? there is no handling of anything


+   sleep(1);
+   if (teamdev->ifnames) {
+   printf("TEAM port init\n");
+   blobmsg_for_each_attr(cur, teamdev->ifnames, rem) {
+   printf("TEAM one port init\n");
+   snprintf(buffer, sizeof buffer,
+   "teamdctl %s port add %s",
+   dev->ifname,
+   blobmsg_get_string(cur));
+   system(buffer);


puting aside usage of system() for service configuration this smells, you're
passing possibly malicious input directly to system() in the service running
as root, what could go wrong?


+   }
+   }
+   teamdev->set_state(dev, up);
+   return 0;
+   } else {
+   printf("TEAM: killing %d\n", teamdev->pid);
+   if (teamdev->pid) {
+   kill(teamdev->pid, SIGTERM);
+   waitpid(teamdev->

Re: [PATCH 2/2] libteam: add library to control team devices

2021-01-16 Thread Pavel Šimerda

On 1/16/21 12:54 PM, Petr Štetiar wrote:

Pavel Šimerda  [2021-01-14 03:38:48]:

Hi,


+++ b/package/network/services/libteam/Makefile
@@ -0,0 +1,30 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME := libteam
+PKG_FIXUP := autoreconf
+PKG_BUILD_DEPENDS := libdaemon jansson


libdaemon is not in the main tree, it's in the packages tree, so this package
should go there as well.


+Subject: [PATCH] fix build on OpenWRT/musl-libc


this should be upstreamed


Sure. This has been submitted to upstream but there seems to be a communication 
issue.

https://github.com/jpirko/libteam/pull/31



-- ynezz



___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


Re: [PATCH 1/2] libnl: add libnl-cli library

2021-01-16 Thread Pavel Šimerda

On 1/16/21 12:50 PM, Petr Štetiar wrote:

Pavel Šimerda  [2021-01-16 00:23:01]:

Hi,


My perspective is that we are working on *hardware enablement* here. At
least some switch chips support Link Aggregation in addition to hardware
switching and VLAN filtering. This will be handled by offloading the LAG
configuration from the kernel team driver.


we're trying to keep the main tree minimal for details see following link:

  https://lists.infradead.org/pipermail/openwrt-devel/2019-August/024109.html


Hey Petr,

is this an idea in progress or is OpenWRT already heading towards that goal?




   * The libteam package to support the team module (new package)
   - Submitted in PATCH 2/2.


This one looks like material for packages feed.


So what is the correct approach? Please see my questions below.

1) Is it okay to modify libnl to build and distribute the libnl-cli package so 
that I can base the libteam package on it?

2) How should I handle the netifd team module dependency on libteam to get it 
accepted to netifd code base?

Cheers,

Pavel Šimerda



-- ynezz



___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


Re: [PATCH 1/2] libnl: add libnl-cli library

2021-01-16 Thread Pavel Šimerda

On 1/16/21 12:25 PM, Petr Štetiar wrote:

Pavel Šimerda  [2021-01-14 03:38:47]:

Hi,


---
  package/libs/libnl/Makefile | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/package/libs/libnl/Makefile b/package/libs/libnl/Makefile
index db0c65c7a7..3b9bad4533 100644
--- a/package/libs/libnl/Makefile
+++ b/package/libs/libnl/Makefile
@@ -52,16 +52,26 @@ $(call Package/libnl/default)
DEPENDS:=+libnl-route
  endef
  
+define Package/libnl-cli

+$(call Package/libnl/default)
+  TITLE:=Netlink Library CLI
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf
+endef
+
  define Package/libnl
  $(call Package/libnl/default)
TITLE:=Full Netlink Library
-  DEPENDS:=+libnl-genl +libnl-route +libnl-nf
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf +libnl-cli


Why is this dependency needed?


Hey,

would you suggest that libnl-cli stays left out of libnl deps as an “extra” 
package? I have no strong opinion about that one.




  endef
  
  define Package/libnl-core/description

   Common code for all netlink libraries
  endef
  
+define Package/libnl-cli/description

+ CLI Netlink Library Functions
+endef
+
  define Package/libnl-genl/description
   Generic Netlink Library Functions
  endef
@@ -92,6 +102,7 @@ define Build/InstallDev
  
  	# Copy symlinks

$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so $(1)/usr/lib/libnl.so
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so $(1)/usr/lib/libnl.so


This seems like copy&pasta issue.


Thanks.

Pavel Šimerda


$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so 
$(1)/usr/lib/libnl-genl.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so $(1)/usr/lib/libnl-nf.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-route-3.so 
$(1)/usr/lib/libnl-route.so
@@ -102,6 +113,11 @@ define Package/libnl-core/install
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so.* $(1)/usr/lib/
  endef
  
+define Package/libnl-cli/install

+   $(INSTALL_DIR) $(1)/usr/lib
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so.* $(1)/usr/lib/
+endef
+
  define Package/libnl-genl/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so.* $(1)/usr/lib/
@@ -122,6 +138,7 @@ define Package/libnl/install
  endef
  
  $(eval $(call BuildPackage,libnl-core))

+$(eval $(call BuildPackage,libnl-cli))
  $(eval $(call BuildPackage,libnl-genl))
  $(eval $(call BuildPackage,libnl-route))
  $(eval $(call BuildPackage,libnl-nf))
--
2.29.2


___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel





___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


Re: [PATCH 1/2] libnl: add libnl-cli library

2021-01-15 Thread Pavel Šimerda



On 1/14/21 1:10 PM, Adrian Schmutzler wrote:

-Original Message-
From: openwrt-devel [mailto:openwrt-devel-boun...@lists.openwrt.org]
On Behalf Of Pavel Šimerda
Sent: Donnerstag, 14. Januar 2021 03:39
To: openwrt-devel@lists.openwrt.org
Cc: Pavel Šimerda 
Subject: [PATCH 1/2] libnl: add libnl-cli library


Hi,

this has formal issues (like entirely missing commit message, missing SoB, 
...). Please have another look at https://openwrt.org/submitting-patches

Hey,


thanks for your quick response to my first submission. I'll fix that.


Apart from that, do we need this in the main repo or could it also go into 
packages?


Whether libteam belongs to the main repo or package may be subject to point of 
view.



My perspective is that we are working on *hardware enablement* here. At least 
some switch chips support Link Aggregation in addition to hardware switching 
and VLAN filtering. This will be handled by offloading the LAG configuration 
from the kernel team driver.



The intended functionality consists of:



  * Team module for netifd
 (package already in main)
  - Submitted: 
https://lists.openwrt.org/pipermail/openwrt-devel/2021-January/033269.html

  * The libteam package to support the team module (new package)
  - Submitted in PATCH 2/2.

  * A change in libnl to support the libteam package (package already in main)
  - Submitted in PATCH 1/2.

  * The kernel team driver (already in kernel)
  - Works as expected.

  * Offloaded LAG confugration to a switch driver (to be done in kernel)
  - This is of course hardware specific.

I would rather see all support protocols for switch chip features (like RSTP 
and LACP) ready in the main repo and supported by netifd and the network UCI 
configuration. What is the motivation to keep these networking features 
separate?

Cheers

Pavel Šimerda


Best

Adrian



---
  package/libs/libnl/Makefile | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/package/libs/libnl/Makefile b/package/libs/libnl/Makefile index
db0c65c7a7..3b9bad4533 100644
--- a/package/libs/libnl/Makefile
+++ b/package/libs/libnl/Makefile
@@ -52,16 +52,26 @@ $(call Package/libnl/default)
DEPENDS:=+libnl-route
  endef

+define Package/libnl-cli
+$(call Package/libnl/default)
+  TITLE:=Netlink Library CLI
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf endef
+
  define Package/libnl
  $(call Package/libnl/default)
TITLE:=Full Netlink Library
-  DEPENDS:=+libnl-genl +libnl-route +libnl-nf
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf +libnl-cli
  endef

  define Package/libnl-core/description
   Common code for all netlink libraries
  endef

+define Package/libnl-cli/description
+ CLI Netlink Library Functions
+endef
+
  define Package/libnl-genl/description
   Generic Netlink Library Functions
  endef
@@ -92,6 +102,7 @@ define Build/InstallDev

# Copy symlinks
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so $(1)/usr/lib/libnl.so
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so $(1)/usr/lib/libnl.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so $(1)/usr/lib/libnl-
genl.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so $(1)/usr/lib/libnl-
nf.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-route-3.so $(1)/usr/lib/libnl-
route.so @@ -102,6 +113,11 @@ define Package/libnl-core/install
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so.* $(1)/usr/lib/  endef

+define Package/libnl-cli/install
+   $(INSTALL_DIR) $(1)/usr/lib
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so.* $(1)/usr/lib/ endef
+
  define Package/libnl-genl/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so.* $(1)/usr/lib/ @@
-122,6 +138,7 @@ define Package/libnl/install  endef

  $(eval $(call BuildPackage,libnl-core))
+$(eval $(call BuildPackage,libnl-cli))
  $(eval $(call BuildPackage,libnl-genl))  $(eval $(call 
BuildPackage,libnl-route))
$(eval $(call BuildPackage,libnl-nf))
--
2.29.2


___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


[PATCH 1/2] libnl: add libnl-cli library

2021-01-13 Thread Pavel Šimerda
---
 package/libs/libnl/Makefile | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/package/libs/libnl/Makefile b/package/libs/libnl/Makefile
index db0c65c7a7..3b9bad4533 100644
--- a/package/libs/libnl/Makefile
+++ b/package/libs/libnl/Makefile
@@ -52,16 +52,26 @@ $(call Package/libnl/default)
   DEPENDS:=+libnl-route
 endef
 
+define Package/libnl-cli
+$(call Package/libnl/default)
+  TITLE:=Netlink Library CLI
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf
+endef
+
 define Package/libnl
 $(call Package/libnl/default)
   TITLE:=Full Netlink Library
-  DEPENDS:=+libnl-genl +libnl-route +libnl-nf
+  DEPENDS:=+libnl-genl +libnl-route +libnl-nf +libnl-cli
 endef
 
 define Package/libnl-core/description
  Common code for all netlink libraries
 endef
 
+define Package/libnl-cli/description
+ CLI Netlink Library Functions
+endef
+
 define Package/libnl-genl/description
  Generic Netlink Library Functions
 endef
@@ -92,6 +102,7 @@ define Build/InstallDev
 
# Copy symlinks
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so $(1)/usr/lib/libnl.so
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so $(1)/usr/lib/libnl.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so 
$(1)/usr/lib/libnl-genl.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so $(1)/usr/lib/libnl-nf.so
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-route-3.so 
$(1)/usr/lib/libnl-route.so
@@ -102,6 +113,11 @@ define Package/libnl-core/install
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-3.so.* $(1)/usr/lib/
 endef
 
+define Package/libnl-cli/install
+   $(INSTALL_DIR) $(1)/usr/lib
+   $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so.* $(1)/usr/lib/
+endef
+
 define Package/libnl-genl/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so.* $(1)/usr/lib/
@@ -122,6 +138,7 @@ define Package/libnl/install
 endef
 
 $(eval $(call BuildPackage,libnl-core))
+$(eval $(call BuildPackage,libnl-cli))
 $(eval $(call BuildPackage,libnl-genl))
 $(eval $(call BuildPackage,libnl-route))
 $(eval $(call BuildPackage,libnl-nf))
-- 
2.29.2


___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


[PATCH 2/2] libteam: add library to control team devices

2021-01-13 Thread Pavel Šimerda
---
 package/network/services/libteam/Makefile | 30 +
 .../0001-fix-build-on-OpenWRT-musl-libc.patch | 43 +++
 2 files changed, 73 insertions(+)
 create mode 100644 package/network/services/libteam/Makefile
 create mode 100644 
package/network/services/libteam/patches/0001-fix-build-on-OpenWRT-musl-libc.patch

diff --git a/package/network/services/libteam/Makefile 
b/package/network/services/libteam/Makefile
new file mode 100644
index 00..367134656b
--- /dev/null
+++ b/package/network/services/libteam/Makefile
@@ -0,0 +1,30 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME := libteam
+PKG_FIXUP := autoreconf
+PKG_BUILD_DEPENDS := libdaemon jansson
+PKG_INSTALL := 1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/jpirko/libteam.git
+PKG_SOURCE_DATE:=2021-01-12
+PKG_SOURCE_VERSION:=61efd6de2fbb8ee077863ee5a355ac3dfd9365b9
+
+PKG_LICENSE:=LGPL-2.1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libteam
+  SECTION := base
+  CATEGORY := Network
+  DEPENDS := +libnl +libnl-cli +libnl-core +libnl-genl +libnl-nf +libnl-route 
+libdaemon +jansson
+  TITLE := Library for controlling team network device
+  URL := http://libteam.org/
+endef
+
+define Package/libteam/install
+   $(INSTALL_DIR) $(1)/
+   $(CP) $(PKG_INSTALL_DIR)/. $(1)/
+endef
+
+$(eval $(call BuildPackage,libteam))
diff --git 
a/package/network/services/libteam/patches/0001-fix-build-on-OpenWRT-musl-libc.patch
 
b/package/network/services/libteam/patches/0001-fix-build-on-OpenWRT-musl-libc.patch
new file mode 100644
index 00..71b2b8abba
--- /dev/null
+++ 
b/package/network/services/libteam/patches/0001-fix-build-on-OpenWRT-musl-libc.patch
@@ -0,0 +1,43 @@
+From 5a5825708ba0bfcb7700a9fba4ea9f8c41c1ae6c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20=C5=A0imerda?= 
+Date: Tue, 5 Jan 2021 22:13:06 +0100
+Subject: [PATCH] fix build on OpenWRT/musl-libc
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Pavel Šimerda 
+---
+ teamd/teamd_runner_lacp.c | 2 --
+ utils/teamnl.c| 1 +
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
+index 9437f05..f524be2 100644
+--- a/teamd/teamd_runner_lacp.c
 b/teamd/teamd_runner_lacp.c
+@@ -23,9 +23,7 @@
+ #include 
+ #include 
+ #include 
+-#include 
+ #include 
+-#include 
+ #include 
+ #include 
+ #include 
+diff --git a/utils/teamnl.c b/utils/teamnl.c
+index c53345d..ec2b435 100644
+--- a/utils/teamnl.c
 b/utils/teamnl.c
+@@ -24,6 +24,7 @@
+ #include 
+ #include 
+ #include 
++#include 
+ #include 
+ #include 
+ #include 
+-- 
+2.29.2
+
-- 
2.29.2


___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


[PATCH netifd] team: add simple bonding/teaming module

2021-01-11 Thread Pavel Šimerda
An initial version of a bonding/teaming module based on libteam and the
kernel team driver. It is capable of creating a team device and add
member ports. The ultimate goal is to support LAG offloaded to DSA
switch hardware with teamd handling the LACP management.

config interface teamdev
option ifname "lan1 lan2"
option type team

The module requires libteam's teamd and teamdctl commands.

Signed-off-by: Pavel Šimerda 
---
 CMakeLists.txt |   2 +-
 team.c | 178 +
 2 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 team.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d19817..351e303 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ SET(SOURCES
main.c utils.c system.c tunnel.c handler.c
interface.c interface-ip.c interface-event.c
iprule.c proto.c proto-static.c proto-shell.c
-   config.c device.c bridge.c veth.c vlan.c alias.c
+   config.c device.c bridge.c team.c veth.c vlan.c alias.c
macvlan.c ubus.c vlandev.c wireless.c)
 
 
diff --git a/team.c b/team.c
new file mode 100644
index 000..9b67566
--- /dev/null
+++ b/team.c
@@ -0,0 +1,178 @@
+/*
+ * netifd - network interface daemon
+ * Copyright (C) 2021 Pavel Šimerda 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * 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.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "netifd.h"
+#include "device.h"
+#include "interface.h"
+#include "system.h"
+
+enum {
+   TEAM_ATTR_IFNAME,
+   __TEAM_ATTR_MAX
+};
+
+static const struct blobmsg_policy team_attrs[__TEAM_ATTR_MAX] = {
+   [TEAM_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_ARRAY },
+};
+
+static const struct uci_blob_param_info team_attr_info[__TEAM_ATTR_MAX] = {
+   [TEAM_ATTR_IFNAME] = { .type = BLOBMSG_TYPE_STRING },
+};
+
+static const struct uci_blob_param_list team_attr_list = {
+   .n_params = __TEAM_ATTR_MAX,
+   .params = team_attrs,
+   .info = team_attr_info,
+
+   .n_next = 1,
+   .next = { &device_attr_list },
+};
+
+struct team_device {
+   struct device dev;
+   device_state_cb set_state;
+
+   struct blob_attr *config_data;
+   struct blob_attr *ifnames;
+
+   int pid;
+};
+
+static int
+team_set_state(struct device *dev, bool up)
+{
+   struct team_device *teamdev = container_of(dev, struct team_device, 
dev);
+
+   if (up) {
+   int pid;
+   struct blob_attr *cur;
+   int rem;
+   char buffer[64];
+
+   printf("TEAM start teamd\n");
+
+   pid = fork();
+   if (pid == -1)
+   return -errno;
+   if (pid == 0)
+   execlp("teamd", "teamd", "-t", dev->ifname, NULL);
+   teamdev->pid = pid;
+   // TODO: Better handling of newly created devices.
+   sleep(1);
+   if (teamdev->ifnames) {
+   printf("TEAM port init\n");
+   blobmsg_for_each_attr(cur, teamdev->ifnames, rem) {
+   printf("TEAM one port init\n");
+   snprintf(buffer, sizeof buffer,
+   "teamdctl %s port add %s",
+   dev->ifname,
+   blobmsg_get_string(cur));
+   system(buffer);
+   }
+   }
+   teamdev->set_state(dev, up);
+   return 0;
+   } else {
+   printf("TEAM: killing %d\n", teamdev->pid);
+   if (teamdev->pid) {
+   kill(teamdev->pid, SIGTERM);
+   waitpid(teamdev->pid, NULL, 0);
+   teamdev->pid = 0;
+   }
+   return 0;
+   }
+}
+
+static enum dev_change_type
+team_reload(struct device *dev, struct blob_attr *attr)
+{
+   struct team_device *teamdev = container_of(dev, struct team_device, 
dev);
+   struct blob_attr *tb_tm[__TEAM_ATTR_MAX];
+
+   attr = blob_memdup(attr);
+
+   blobmsg_parse(team_attrs, __TEAM_ATTR_MAX, tb_tm, blob_data(attr), 
blob_len(attr));
+   teamdev->ifnames = tb_tm[TEAM_ATTR_IFNAME];
+
+   if (teamdev->pid) {
+   // TODO: More fine-graine