From patchwork Fri Aug 7 12:35:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 1342259 X-Patchwork-Delegate: nbd@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nbd.name Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=zuSyNvoY; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nbd.name header.i=@nbd.name header.a=rsa-sha256 header.s=20160729 header.b=k3FNr+au; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BNPyb0t3sz9sTQ for ; Fri, 7 Aug 2020 22:37:42 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe :List-Id:MIME-Version:Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Owner; bh=ZUyPLOVvjZoiBgukzjbm6Zm/FyrnSwvSVX2wkbEJ6x0=; b=zuSyNvoYoq26pesWz0rLpfuqLr NFRiaNJUmOwbJ/hD/KS+rD7Ko8PlQ0AG6S/IHYhBF1zqzA/zyGbk0dwKwa+CV78zFi57hbVzx4lks ruh2Cr+fx4EsAt4F2UWgzJSc3lx31YgWcl+hpy6FdiDBT/7xtJV+9Ohsq+vcou9vgPK9VFjSUL2Mc 5rGtg9CSoCYvDGD5Qd4+wnEBv4748tng2X2fHY3xCopWPLoce+kmV00zMyo3tZY0j9FOFFbBAwCwK aN6nSq7tssNf12/uhoR946Td8RElUc290UgvFIfwSfuhlqFUcMycclwDhjKj9tnpjzxJpGpk1zu9z T1X+nKOw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41bB-0003MJ-3n; Fri, 07 Aug 2020 12:35:49 +0000 Received: from nbd.name ([2a01:4f8:221:3d45::2]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41b6-0003Kl-B5 for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 12:35:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject :To:From:Sender:Reply-To:Cc:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=b0gmYd22Qff0YazD7pwe/L6yHjZSEgwbkoY98pXwNLU=; b=k3FNr+au55KhYHZSFA3XhDykQM Wo2VdZpAZDsDhmIaQiqW0VsOFHpNK0QHgG7WmWgFVsi/VN0G/qj/50nc23HKBwLVHzjypPH2m2mHj YVYDv6+zn0nGKQvPRAagQxKAUyFQaPA8xDGAA8EPjI2dmYPY5R76E8g/Ej3wr3ArVNFo=; Received: from p54ae996c.dip0.t-ipconnect.de ([84.174.153.108] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.89) (envelope-from ) id 1k41b2-0003po-Q9 for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 14:35:40 +0200 From: Felix Fietkau To: openwrt-devel@lists.openwrt.org Subject: [RFC netifd 1/3] bridge: add support for defining port member vlans via hotplug ops Date: Fri, 7 Aug 2020 14:35:31 +0200 Message-Id: <20200807123533.71916-1-nbd@nbd.name> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200807_083544_642660_F922C11B X-CRM114-Status: GOOD ( 21.03 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Signed-off-by: Felix Fietkau --- bridge.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++- config.c | 1 + device.h | 4 +- interface.c | 10 +++-- interface.h | 2 +- ubus.c | 5 ++- wireless.c | 4 +- 7 files changed, 120 insertions(+), 11 deletions(-) diff --git a/bridge.c b/bridge.c index 14d497298352..92eea9f7e22e 100644 --- a/bridge.c +++ b/bridge.c @@ -122,6 +122,11 @@ struct bridge_member { char name[]; }; +struct bridge_vlan_hotplug_port { + struct list_head list; + struct bridge_vlan_port port; +}; + static void bridge_reset_primary(struct bridge_state *bst) { @@ -153,6 +158,7 @@ bridge_reset_primary(struct bridge_state *bst) static struct bridge_vlan_port * bridge_find_vlan_member_port(struct bridge_member *bm, struct bridge_vlan *vlan) { + struct bridge_vlan_hotplug_port *port; const char *ifname = bm->dev.dev->ifname; int i; @@ -163,6 +169,13 @@ bridge_find_vlan_member_port(struct bridge_member *bm, struct bridge_vlan *vlan) return &vlan->ports[i]; } + list_for_each_entry(port, &vlan->hotplug_ports, list) { + if (strcmp(port->port.ifname, ifname) != 0) + continue; + + return &port->port; + } + return NULL; } @@ -415,9 +428,25 @@ bridge_remove_member(struct bridge_member *bm) static void bridge_free_member(struct bridge_member *bm) { + struct bridge_state *bst = bm->bst; struct device *dev = bm->dev.dev; + const char *ifname = dev->ifname; + struct bridge_vlan *vlan; bridge_remove_member(bm); + + vlist_for_each_element(&bst->dev.vlans, vlan, node) { + struct bridge_vlan_hotplug_port *port, *tmp; + + list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) { + if (strcmp(port->port.ifname, ifname) != 0) + continue; + + list_del(&port->list); + free(port); + } + } + device_remove_user(&bm->dev); /* @@ -616,11 +645,66 @@ bridge_add_member(struct bridge_state *bst, const char *name) bridge_create_member(bst, name, dev, false); } +static void +bridge_hotplug_create_member_vlans(struct bridge_state *bst, struct blob_attr *vlans, const char *ifname) +{ + struct bridge_vlan *vlan; + struct blob_attr *cur; + int rem; + + if (!vlans) + return; + + blobmsg_for_each_attr(cur, vlans, rem) { + struct bridge_vlan_hotplug_port *port; + uint16_t flags = BRVLAN_F_UNTAGGED; + char *name_buf; + unsigned int vid; + char *end; + + if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) + continue; + + vid = strtoul(blobmsg_get_string(cur), &end, 0); + if (!vid || vid > 4095) + continue; + + vlan = vlist_find(&bst->dev.vlans, &vid, vlan, node); + if (!vlan) + continue; + + if (end && *end) { + if (*end != ':') + continue; + + for (end++; *end; end++) { + switch (*end) { + case 't': + flags &= ~BRVLAN_F_UNTAGGED; + break; + case '*': + flags |= BRVLAN_F_PVID; + break; + } + } + } + + port = calloc_a(sizeof(*port), &name_buf, strlen(ifname) + 1); + if (!port) + continue; + + port->port.flags = flags; + port->port.ifname = strcpy(name_buf, ifname); + list_add_tail(&port->list, &vlan->hotplug_ports); + } +} + static int -bridge_hotplug_add(struct device *dev, struct device *member) +bridge_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan) { struct bridge_state *bst = container_of(dev, struct bridge_state, dev); + bridge_hotplug_create_member_vlans(bst, vlan, member->ifname); bridge_create_member(bst, member->ifname, member, true); return 0; @@ -899,6 +983,20 @@ bridge_vlan_equal(struct bridge_vlan *v1, struct bridge_vlan *v2) return true; } +static void +bridge_vlan_free(struct bridge_vlan *vlan) +{ + struct bridge_vlan_hotplug_port *port, *tmp; + + if (!vlan) + return; + + list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) + free(port); + + free(vlan); +} + static void bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old) @@ -920,13 +1018,16 @@ bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new, if (node_old) bridge_set_vlan_state(bst, vlan_old, false); + if (node_old && node_new) + list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports); + if (node_new) bridge_set_vlan_state(bst, vlan_new, true); bst->dev.config_pending = true; out: - free(vlan_old); + bridge_vlan_free(vlan_old); } static struct device * diff --git a/config.c b/config.c index 526a20f0d1ab..3546787e46f5 100644 --- a/config.c +++ b/config.c @@ -323,6 +323,7 @@ config_parse_vlan(struct device *dev, struct uci_section *s) vlan->n_ports = n_ports; vlan->ports = port = (struct bridge_vlan_port *)&vlan[1]; + INIT_LIST_HEAD(&vlan->hotplug_ports); name_buf = (char *)&port[n_ports]; blobmsg_for_each_attr(cur, tb[BRVLAN_ATTR_PORTS], rem) { diff --git a/device.h b/device.h index b25d2675e2fa..617a2724b1fd 100644 --- a/device.h +++ b/device.h @@ -227,7 +227,7 @@ struct device { struct device_hotplug_ops { int (*prepare)(struct device *dev); - int (*add)(struct device *main, struct device *member); + int (*add)(struct device *main, struct device *member, struct blob_attr *vlan); int (*del)(struct device *main, struct device *member); }; @@ -248,6 +248,8 @@ struct bridge_vlan { struct bridge_vlan_port *ports; int n_ports; + struct list_head hotplug_ports; + uint16_t vid; bool local; }; diff --git a/interface.c b/interface.c index 782174f3b365..c53c091c3232 100644 --- a/interface.c +++ b/interface.c @@ -1038,7 +1038,8 @@ interface_remove_link(struct interface *iface, struct device *dev) } static int -interface_add_link(struct interface *iface, struct device *dev, bool link_ext) +interface_add_link(struct interface *iface, struct device *dev, + struct blob_attr *vlan, bool link_ext) { struct device *mdev = iface->main_dev.dev; @@ -1050,7 +1051,7 @@ interface_add_link(struct interface *iface, struct device *dev, bool link_ext) if (mdev) { if (mdev->hotplug_ops) - return mdev->hotplug_ops->add(mdev, dev); + return mdev->hotplug_ops->add(mdev, dev, vlan); else return UBUS_STATUS_NOT_SUPPORTED; } @@ -1064,7 +1065,8 @@ interface_add_link(struct interface *iface, struct device *dev, bool link_ext) } int -interface_handle_link(struct interface *iface, const char *name, bool add, bool link_ext) +interface_handle_link(struct interface *iface, const char *name, + struct blob_attr *vlan, bool add, bool link_ext) { struct device *dev; int ret; @@ -1081,7 +1083,7 @@ interface_handle_link(struct interface *iface, const char *name, bool add, bool interface_set_device_config(iface, dev); device_set_present(dev, true); - ret = interface_add_link(iface, dev, link_ext); + ret = interface_add_link(iface, dev, vlan, link_ext); } else { ret = interface_remove_link(iface, dev); } diff --git a/interface.h b/interface.h index 3d58aa3dee40..9c136b63e377 100644 --- a/interface.h +++ b/interface.h @@ -196,7 +196,7 @@ void interface_set_l3_dev(struct interface *iface, struct device *dev); void interface_add_user(struct interface_user *dep, struct interface *iface); void interface_remove_user(struct interface_user *dep); -int interface_handle_link(struct interface *iface, const char *name, bool add, bool link_ext); +int interface_handle_link(struct interface *iface, const char *name, struct blob_attr *vlan, bool add, bool link_ext); void interface_add_error(struct interface *iface, const char *subsystem, const char *code, const char **data, int n_data); diff --git a/ubus.c b/ubus.c index 15c826b427d6..4f167641e3a1 100644 --- a/ubus.c +++ b/ubus.c @@ -903,12 +903,14 @@ netifd_handle_dump(struct ubus_context *ctx, struct ubus_object *obj, enum { DEV_LINK_NAME, DEV_LINK_EXT, + DEV_LINK_VLAN, __DEV_LINK_MAX, }; static const struct blobmsg_policy dev_link_policy[__DEV_LINK_MAX] = { [DEV_LINK_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, [DEV_LINK_EXT] = { .name = "link-ext", .type = BLOBMSG_TYPE_BOOL }, + [DEV_LINK_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY }, }; static int @@ -933,7 +935,8 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, if (cur) link_ext = blobmsg_get_bool(cur); - return interface_handle_link(iface, blobmsg_data(tb[DEV_LINK_NAME]), add, link_ext); + return interface_handle_link(iface, blobmsg_data(tb[DEV_LINK_NAME]), + tb[DEV_LINK_VLAN], add, link_ext); } diff --git a/wireless.c b/wireless.c index efb799204d76..6bf6b585bf73 100644 --- a/wireless.c +++ b/wireless.c @@ -319,7 +319,7 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, bool if (!iface) continue; - interface_handle_link(iface, vif->ifname, up, true); + interface_handle_link(iface, vif->ifname, NULL, up, true); } } @@ -349,7 +349,7 @@ static void wireless_vlan_handle_link(struct wireless_vlan *vlan, bool up) if (!iface) continue; - interface_handle_link(iface, vlan->ifname, up, true); + interface_handle_link(iface, vlan->ifname, NULL, up, true); } } From patchwork Fri Aug 7 12:35:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 1342258 X-Patchwork-Delegate: nbd@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nbd.name Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=J3rFcb0j; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nbd.name header.i=@nbd.name header.a=rsa-sha256 header.s=20160729 header.b=FR9P3CkQ; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BNPyb0sjjz9sPB for ; Fri, 7 Aug 2020 22:37:42 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe :List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:To:From: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=D54AU8QQ1HL7TAWPHFHMkEHHFaP0y5Ga5GdJhRtZmH0=; b=J3rFcb0jGioSS9C08Xvs1+BfCw bJ+n9+GQtuwVNMcDBoXM4WjWn+zkR/B+Icfi0Zg83HAK/9EoXfIpqmKSqcAKMGAJ5YQB/iDlGsTvt 2h/TBZbEtzT4R2lRTByg3JNajEcSutfU/EGl0n5/52SzkDt19QBBz+T57O1yCyMj0EBaD25S6VlRW rr14g587oN4ZnlEYV5O9D21fUFCGWEwK5QEwKufFxtrZhNia1rWcr4gwfHM+sRdwI7s51ZJ62mb63 YYzQ28cn55HHahkkC/jU50gMcInJpLsoRzjXCExmiIGSHaSqcmn0wOgIPbPo3wdSeI8tcCMYkYvi7 nRQw5pWw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41b9-0003Lp-05; Fri, 07 Aug 2020 12:35:47 +0000 Received: from nbd.name ([2a01:4f8:221:3d45::2]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41b6-0003Km-AO for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 12:35:45 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=IyjTydvaClGvtbiAZiRG2UhZFu0kLDp3F8o8eGBQrHc=; b=FR9P3CkQiRZf3hfJWEckQ8K/3f nOS5XO0HXaSZVZZbbqHOuuxfeLtwd/59m69UFXN1l6buqzvGnLTJU3RlTZDDeUgRJ+V0p/+CVLjDb xi0xtWa+P1ejaYZ+GgBOTzdW0uEGGL3glt9VXbITW2qLX7VBdXY+eVF366Lg2jOcjpds=; Received: from p54ae996c.dip0.t-ipconnect.de ([84.174.153.108] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.89) (envelope-from ) id 1k41b3-0003po-0z for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 14:35:41 +0200 From: Felix Fietkau To: openwrt-devel@lists.openwrt.org Subject: [RFC netifd 2/3] vlan: add pass-through hotplug ops that pass the VLAN info to the bridge Date: Fri, 7 Aug 2020 14:35:32 +0200 Message-Id: <20200807123533.71916-2-nbd@nbd.name> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200807123533.71916-1-nbd@nbd.name> References: <20200807123533.71916-1-nbd@nbd.name> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200807_083544_601498_8EF8B67C X-CRM114-Status: GOOD ( 14.10 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Signed-off-by: Felix Fietkau --- vlan.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/vlan.c b/vlan.c index 6270d95d755d..7d37fef33e2f 100644 --- a/vlan.c +++ b/vlan.c @@ -18,6 +18,8 @@ #include "netifd.h" #include "system.h" +static struct blob_buf b; + struct vlan_device { struct device dev; struct device_user dep; @@ -36,6 +38,66 @@ static void free_vlan_if(struct device *iface) free(vldev); } +static int +vlan_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan) +{ + struct vlan_device *vldev = container_of(dev, struct vlan_device, dev); + void *a; + + dev = vldev->dep.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + blob_buf_init(&b, 0); + a = blobmsg_open_array(&b, "vlans"); + blobmsg_printf(&b, NULL, "%d", vldev->id); + blobmsg_close_array(&b, a); + + return dev->hotplug_ops->add(dev, member, blobmsg_data(b.head)); +} + +static int +vlan_hotplug_del(struct device *dev, struct device *member) +{ + struct vlan_device *vldev = container_of(dev, struct vlan_device, dev); + + dev = vldev->dep.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + return dev->hotplug_ops->del(dev, member); +} + +static int +vlan_hotplug_prepare(struct device *dev) +{ + struct vlan_device *vldev = container_of(dev, struct vlan_device, dev); + + dev = vldev->dep.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + return dev->hotplug_ops->prepare(dev); +} + +static void vlan_hotplug_check(struct vlan_device *vldev) +{ + static const struct device_hotplug_ops hotplug_ops = { + .prepare = vlan_hotplug_prepare, + .add = vlan_hotplug_add, + .del = vlan_hotplug_del + }; + struct device *dev = vldev->dep.dev; + + if (!dev || !dev->hotplug_ops || avl_is_empty(&dev->vlans.avl)) { + vldev->dev.hotplug_ops = NULL; + return; + } + + vldev->dev.hotplug_ops = &hotplug_ops; +} + + static int vlan_set_device_state(struct device *dev, bool up) { struct vlan_device *vldev; @@ -75,6 +137,7 @@ static void vlan_dev_cb(struct device_user *dep, enum device_event ev) device_set_present(&vldev->dev, false); break; case DEV_EVENT_UPDATE_IFNAME: + vlan_hotplug_check(vldev); vldev->dev.hidden = dep->dev->hidden; if (snprintf(name, sizeof(name), "%s.%d", dep->dev->ifname, vldev->id) >= sizeof(name) - 1 || @@ -139,6 +202,7 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create) vldev->dep.cb = vlan_dev_cb; device_add_user(&vldev->dep, dev); + vlan_hotplug_check(vldev); return &vldev->dev; From patchwork Fri Aug 7 12:35:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 1342260 X-Patchwork-Delegate: nbd@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nbd.name Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=KCE+6X9K; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nbd.name header.i=@nbd.name header.a=rsa-sha256 header.s=20160729 header.b=lI3Opbd2; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BNPyc0mpsz9sTR for ; Fri, 7 Aug 2020 22:37:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe :List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:To:From: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cHP5TYgevE7vyA8BUjBiQ8jG5xjpZ+ZorzxBn6tHliQ=; b=KCE+6X9KZIMf1zJocLjgyMb2Mt SED4gohSI3iq6qm0/VWWabsu+3lcxQ0hw9RSXn0o+9ypZOqjFiXU+2ZLoN5W12jxFpRV1eM1sTkD0 uFk1a+z1YkAWh/TX5EVfn6Ojio8isglGmvHDlaBAVf43ZyX1BEwAsnr5dCUnVXjvDponvJIRDnRTr tZcYi/i9kaCYIw80tzq6S2BpjTE8BmxgRuYspeEbDOuEWs2/P5OJ+myXdOQz0Xxx3a1caVnPW/Q3h RbLa1cwGR9TeXKAtL7MgcFKCJ3B7P+gzmdZrgLkPXJrGMRBc3NcaVsTcAz3d0e4ndnak9BtvUkxs/ 7SmRQo8A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41b9-0003M1-Sm; Fri, 07 Aug 2020 12:35:47 +0000 Received: from nbd.name ([2a01:4f8:221:3d45::2]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k41b6-0003Ko-Bc for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 12:35:45 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=EBuVgj/rve2C8Zd9fMv03uC9nKyppp3Uj5Mxwv0aDkA=; b=lI3Opbd2GiItB7riybBIcb7QPH IM7aeyOLLiKwLgRBLdbIzsB8NR4IHa3or0Rn7YMRMM9xHSnefngE6p/vmZEIH/Yl3jJ+tdL6wWUcF /Uxg+qMzLKeRE+x50C627/QGbgmXMkPyoZRw1zOjcO+5ZibfnmR3zH/EzUQL3AgZlBY4=; Received: from p54ae996c.dip0.t-ipconnect.de ([84.174.153.108] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.89) (envelope-from ) id 1k41b3-0003po-6y for openwrt-devel@lists.openwrt.org; Fri, 07 Aug 2020 14:35:41 +0200 From: Felix Fietkau To: openwrt-devel@lists.openwrt.org Subject: [RFC netifd 3/3] vlandev: add pass-through hotplug ops that pass the VLAN info to the bridge Date: Fri, 7 Aug 2020 14:35:33 +0200 Message-Id: <20200807123533.71916-3-nbd@nbd.name> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200807123533.71916-1-nbd@nbd.name> References: <20200807123533.71916-1-nbd@nbd.name> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200807_083544_635312_E497A953 X-CRM114-Status: GOOD ( 14.02 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Only used for 802.1q devices Signed-off-by: Felix Fietkau --- vlandev.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/vlandev.c b/vlandev.c index 10b78e241576..7efb5f42b5c4 100644 --- a/vlandev.c +++ b/vlandev.c @@ -45,6 +45,7 @@ static const struct uci_blob_param_list vlandev_attr_list = { }; static struct device_type vlan8021q_device_type; +static struct blob_buf b; struct vlandev_device { struct device dev; @@ -57,6 +58,67 @@ struct vlandev_device { struct vlandev_config config; }; +static int +vlandev_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan) +{ + struct vlandev_device *mvdev = container_of(dev, struct vlandev_device, dev); + void *a; + + dev = mvdev->parent.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + blob_buf_init(&b, 0); + a = blobmsg_open_array(&b, "vlans"); + blobmsg_printf(&b, NULL, "%d", mvdev->config.vid); + blobmsg_close_array(&b, a); + + return dev->hotplug_ops->add(dev, member, blobmsg_data(b.head)); +} + +static int +vlandev_hotplug_del(struct device *dev, struct device *member) +{ + struct vlandev_device *mvdev = container_of(dev, struct vlandev_device, dev); + + dev = mvdev->parent.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + return dev->hotplug_ops->del(dev, member); +} + +static int +vlandev_hotplug_prepare(struct device *dev) +{ + struct vlandev_device *mvdev = container_of(dev, struct vlandev_device, dev); + + dev = mvdev->parent.dev; + if (!dev || !dev->hotplug_ops) + return UBUS_STATUS_NOT_SUPPORTED; + + return dev->hotplug_ops->prepare(dev); +} + +static void vlandev_hotplug_check(struct vlandev_device *mvdev) +{ + static const struct device_hotplug_ops hotplug_ops = { + .prepare = vlandev_hotplug_prepare, + .add = vlandev_hotplug_add, + .del = vlandev_hotplug_del + }; + struct device *dev = mvdev->parent.dev; + + if (!dev || !dev->hotplug_ops || avl_is_empty(&dev->vlans.avl) || + dev->type != &vlan8021q_device_type) { + mvdev->dev.hotplug_ops = NULL; + return; + } + + mvdev->dev.hotplug_ops = &hotplug_ops; +} + + static void vlandev_base_cb(struct device_user *dev, enum device_event ev) { @@ -69,6 +131,9 @@ vlandev_base_cb(struct device_user *dev, enum device_event ev) case DEV_EVENT_REMOVE: device_set_present(&mvdev->dev, false); break; + case DEV_EVENT_UPDATE_IFNAME: + vlandev_hotplug_check(mvdev); + break; default: return; } @@ -179,6 +244,7 @@ vlandev_config_init(struct device *dev) basedev = device_get(blobmsg_data(mvdev->ifname), true); device_add_user(&mvdev->parent, basedev); + vlandev_hotplug_check(mvdev); } static void vlandev_qos_mapping_list_apply(struct vlist_simple_tree *qos_mapping_li, struct blob_attr *list)