From patchwork Mon Dec 3 18:40:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 10710367 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0AFDA14BD for ; Mon, 3 Dec 2018 18:41:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F178F2B1B6 for ; Mon, 3 Dec 2018 18:41:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E58CE2B47F; Mon, 3 Dec 2018 18:41:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1822B2B1B6 for ; Mon, 3 Dec 2018 18:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726917AbeLCSkg (ORCPT ); Mon, 3 Dec 2018 13:40:36 -0500 Received: from mail-lj1-f195.google.com ([209.85.208.195]:40689 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726809AbeLCSkg (ORCPT ); Mon, 3 Dec 2018 13:40:36 -0500 Received: by mail-lj1-f195.google.com with SMTP id n18-v6so12391557lji.7 for ; Mon, 03 Dec 2018 10:40:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AMUy68ozbX3Wxgvgf/jAbwoq/KidBtnHdd2vBeUgHpA=; b=LQjm4358MjGTaaGg//Tuy/jwJ+OddA7BeHOLQ8fFAOX1ze4lUXIJIv4tU3EEqSSils N9vIzcTBnZ1SSsiMtHZAT4RPM9u2qUVc91TSXADw8AI/XLVDgzb5yBk8+bkI897OFAvb U9MV+A7+OpoeHtwnvfvNclTFr/4hfMYyWahEQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AMUy68ozbX3Wxgvgf/jAbwoq/KidBtnHdd2vBeUgHpA=; b=GRzFByFKH00N0SZMJDqnDa/bjxd5Aox7NPBQO7F6Eo68Gv4uyk0l9jZWrXFne2hFne 8mLfFQXoPKfUB6evtnvElEnGBwUeCmQlJ1t4c8v7FFGjKlxWzqpYPIHozZEeYSyVmGjq 9ZItkMCvFRI2XXPfOGjfKUpWEwyTILSqMv6ky0F4bWYvUqEXV+Ih7QVJ+xGE4UfOFPRx zFBswJLmKzgmBACu1AWvLCoW30orjbRAHVo8S5qUqiSAivyF+6w1AT4hsQwp73ZHvpMj tgZ9PDYLRoXWQ/95G5/6Ga/Dk89mecctRM1JsIQ+/ZT6vMYvwDGhhyCVMUWjh8Ie2H9G DkIQ== X-Gm-Message-State: AA+aEWblg59RyUJh/OEtBhqpRkSDvR240cC5HN7hkRqc7EhHOZ7dhjbn wozQcY2ftDwiaYxV9coC6295Gg== X-Google-Smtp-Source: AFSGD/U4vMd8Cmf2BwsYaRjQNLCQAA7f2Kbr1+VQV0mFCRi1BTEnY/4+oh1GRreoyAnU9BiFAzflGw== X-Received: by 2002:a2e:7801:: with SMTP id t1-v6mr169890ljc.84.1543862428988; Mon, 03 Dec 2018 10:40:28 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id d23sm2518513lfc.11.2018.12.03.10.40.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 10:40:28 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 1/5] net: core: dev_addr_lists: add VID to device address space Date: Mon, 3 Dec 2018 20:40:19 +0200 Message-Id: <20181203184023.3430-2-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> References: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds VID tag at the end of each address. For Ethernet addresses with 6 bytes long, when actual reserved address size is 32 bytes, that's possible to add tag w/o increasing maximum address length. Thus each address for the case has 32 - 6 = 26 bytes to hold additional info, say VID for virtual device address. Therefore, when addresses are synched to the address list of parent device the address list of latter can contain separate addresses for virtual devices. It allows contain separate address tables for virtual devices if they present and vlan be placed on any place of device chain as the address is propagated to to the end real device thru *_sync APIs. If parent device doesn't want to have virtual addresses in its address space the vid_len has to be 0, thus its address space is "shrunk" to the state as before this patch. The end real device, if it's allowed, can retrieve VID tag from an address and set it for given vlan only. By default vid 0 is used for real devices to distinguish it from virtual addresses (0xffff should be used, but for RFC is Ok). Similar approach can be used for passing additional information for virtual devices as allmulti flag or/and promisc flag, but this is separate story and could be added as a continuation. See next patches to see how it works. Signed-off-by: Ivan Khoronzhuk --- include/linux/netdevice.h | 5 ++ net/core/dev_addr_lists.c | 124 +++++++++++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 23 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 94fb2e12f117..1b0f9c322b01 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1635,6 +1635,8 @@ enum netdev_priv_flags { * @perm_addr: Permanent hw address * @addr_assign_type: Hw address assignment type * @addr_len: Hardware address length + * @vid_len: Virtual ID length, set only if virtual address + * filtering is supported * @neigh_priv_len: Used in neigh_alloc() * @dev_id: Used to differentiate devices that share * the same link layer address @@ -1864,6 +1866,7 @@ struct net_device { unsigned char perm_addr[MAX_ADDR_LEN]; unsigned char addr_assign_type; unsigned char addr_len; + unsigned char vid_len; unsigned short neigh_priv_len; unsigned short dev_id; unsigned short dev_port; @@ -4092,8 +4095,10 @@ int dev_addr_init(struct net_device *dev); /* Functions used for unicast addresses handling */ int dev_uc_add(struct net_device *dev, const unsigned char *addr); +int dev_vid_uc_add(struct net_device *dev, const unsigned char *addr); int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr); int dev_uc_del(struct net_device *dev, const unsigned char *addr); +int dev_vid_uc_del(struct net_device *dev, const unsigned char *addr); int dev_uc_sync(struct net_device *to, struct net_device *from); int dev_uc_sync_multiple(struct net_device *to, struct net_device *from); void dev_uc_unsync(struct net_device *to, struct net_device *from); diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 81a8cd4ea3bd..82c9c347f338 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -542,6 +542,26 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, } EXPORT_SYMBOL(dev_addr_del); +static int get_addr_len(struct net_device *dev) +{ + return dev->addr_len + dev->vid_len; +} + +static int set_vid_addr(struct net_device *dev, const unsigned char *addr, + unsigned char *naddr) +{ + int i; + + if (!dev->vid_len) + return dev->addr_len; + + memcpy(naddr, addr, dev->addr_len); + for (i = 0; i < dev->vid_len; i++) + naddr[dev->addr_len + i] = 0; + + return get_addr_len(dev); +} + /* * Unicast list handling functions */ @@ -553,18 +573,22 @@ EXPORT_SYMBOL(dev_addr_del); */ int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr) { + unsigned char naddr[MAX_ADDR_LEN]; struct netdev_hw_addr *ha; - int err; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); list_for_each_entry(ha, &dev->uc.list, list) { - if (!memcmp(ha->addr, addr, dev->addr_len) && + if (!memcmp(ha->addr, addr, addr_len) && ha->type == NETDEV_HW_ADDR_T_UNICAST) { err = -EEXIST; goto out; } } - err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len, + err = __hw_addr_create_ex(&dev->uc, addr, addr_len, NETDEV_HW_ADDR_T_UNICAST, true, false); if (!err) __dev_set_rx_mode(dev); @@ -575,47 +599,89 @@ int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr) EXPORT_SYMBOL(dev_uc_add_excl); /** - * dev_uc_add - Add a secondary unicast address + * dev_vid_uc_add - Add a secondary unicast address with tag * @dev: device - * @addr: address to add + * @addr: address to add, includes vid tag already * * Add a secondary unicast address to the device or increase * the reference count if it already exists. */ -int dev_uc_add(struct net_device *dev, const unsigned char *addr) +int dev_vid_uc_add(struct net_device *dev, const unsigned char *addr) { int err; netif_addr_lock_bh(dev); - err = __hw_addr_add(&dev->uc, addr, dev->addr_len, + err = __hw_addr_add(&dev->uc, addr, get_addr_len(dev), NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); netif_addr_unlock_bh(dev); return err; } +EXPORT_SYMBOL(dev_vid_uc_add); + +/** + * dev_uc_add - Add a secondary unicast address + * @dev: device + * @addr: address to add + * + * Add a secondary unicast address to the device or increase + * the reference count if it already exists. + */ +int dev_uc_add(struct net_device *dev, const unsigned char *addr) +{ + unsigned char naddr[MAX_ADDR_LEN]; + int err; + + set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; + + err = dev_vid_uc_add(dev, addr); + return err; +} EXPORT_SYMBOL(dev_uc_add); /** * dev_uc_del - Release secondary unicast address. * @dev: device - * @addr: address to delete + * @addr: address to delete, includes vid tag already * * Release reference to a secondary unicast address and remove it * from the device if the reference count drops to zero. */ -int dev_uc_del(struct net_device *dev, const unsigned char *addr) +int dev_vid_uc_del(struct net_device *dev, const unsigned char *addr) { int err; netif_addr_lock_bh(dev); - err = __hw_addr_del(&dev->uc, addr, dev->addr_len, + err = __hw_addr_del(&dev->uc, addr, get_addr_len(dev), NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); netif_addr_unlock_bh(dev); return err; } +EXPORT_SYMBOL(dev_vid_uc_del); + +/** + * dev_uc_del - Release secondary unicast address. + * @dev: device + * @addr: address to delete + * + * Release reference to a secondary unicast address and remove it + * from the device if the reference count drops to zero. + */ +int dev_uc_del(struct net_device *dev, const unsigned char *addr) +{ + unsigned char naddr[MAX_ADDR_LEN]; + int err; + + set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; + + err = dev_vid_uc_del(dev, addr); + return err; +} EXPORT_SYMBOL(dev_uc_del); /** @@ -639,7 +705,7 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); + err = __hw_addr_sync(&to->uc, &from->uc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -669,7 +735,7 @@ int dev_uc_sync_multiple(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len); + err = __hw_addr_sync_multiple(&to->uc, &from->uc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -693,7 +759,7 @@ void dev_uc_unsync(struct net_device *to, struct net_device *from) netif_addr_lock_bh(from); netif_addr_lock_nested(to); - __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); + __hw_addr_unsync(&to->uc, &from->uc, get_addr_len(to)); __dev_set_rx_mode(to); netif_addr_unlock(to); netif_addr_unlock_bh(from); @@ -737,18 +803,22 @@ EXPORT_SYMBOL(dev_uc_init); */ int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr) { + unsigned char naddr[MAX_ADDR_LEN]; struct netdev_hw_addr *ha; - int err; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); list_for_each_entry(ha, &dev->mc.list, list) { - if (!memcmp(ha->addr, addr, dev->addr_len) && + if (!memcmp(ha->addr, addr, addr_len) && ha->type == NETDEV_HW_ADDR_T_MULTICAST) { err = -EEXIST; goto out; } } - err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_create_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, true, false); if (!err) __dev_set_rx_mode(dev); @@ -761,10 +831,14 @@ EXPORT_SYMBOL(dev_mc_add_excl); static int __dev_mc_add(struct net_device *dev, const unsigned char *addr, bool global) { - int err; + unsigned char naddr[MAX_ADDR_LEN]; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); - err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_add_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, global, false, 0); if (!err) __dev_set_rx_mode(dev); @@ -801,10 +875,14 @@ EXPORT_SYMBOL(dev_mc_add_global); static int __dev_mc_del(struct net_device *dev, const unsigned char *addr, bool global) { - int err; + unsigned char naddr[MAX_ADDR_LEN]; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); - err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_del_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, global, false); if (!err) __dev_set_rx_mode(dev); @@ -860,7 +938,7 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); + err = __hw_addr_sync(&to->mc, &from->mc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -890,7 +968,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); + err = __hw_addr_sync_multiple(&to->mc, &from->mc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -914,7 +992,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) netif_addr_lock_bh(from); netif_addr_lock_nested(to); - __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); + __hw_addr_unsync(&to->mc, &from->mc, get_addr_len(to)); __dev_set_rx_mode(to); netif_addr_unlock(to); netif_addr_unlock_bh(from); From patchwork Mon Dec 3 18:40:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 10710359 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A664518A7 for ; Mon, 3 Dec 2018 18:40:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A5AE2B0D0 for ; Mon, 3 Dec 2018 18:40:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E6B62B13A; Mon, 3 Dec 2018 18:40:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C9132B0D0 for ; Mon, 3 Dec 2018 18:40:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726893AbeLCSkh (ORCPT ); Mon, 3 Dec 2018 13:40:37 -0500 Received: from mail-lf1-f66.google.com ([209.85.167.66]:32994 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726994AbeLCSkg (ORCPT ); Mon, 3 Dec 2018 13:40:36 -0500 Received: by mail-lf1-f66.google.com with SMTP id i26so9970204lfc.0 for ; Mon, 03 Dec 2018 10:40:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1E86stckhUJo7da4us/DFsrz1EGMsvbFJsbqAY8mK7A=; b=dl7feYKdeaM+O8AnqZ1Nb8PutI4XBUzUWe4OjNJU5cMiolmF+HMTsuIN1Uq31gspUz gPV/Biqk8jkzwkmvEY9Q3zx1bSs1akAQsFoxcBrJDyPZUpaJ+eUQHE34EY/q8Dr75G0L zz6r4pHOzUT6eYSKQkTQz61/xglQ8c13Wfb9E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1E86stckhUJo7da4us/DFsrz1EGMsvbFJsbqAY8mK7A=; b=P7D1n7bj93RFKArZFK6cuS4P90XpQMaqtIMCukGBrdSUFOK6OvGynNx/GDqTKY1XY9 t5vuHDIGy+gYxuhvkS8YXeN76CamkXDp9x741YqH4vc4gI0reAh+NgQ7oEcETizXD1g+ R3gOK5y2FtXF9y4YQTKAEK8Fdom5GW9CV3QVq2QyVZRUWgrk+3WsIaNzdcXZ1hWh6ifz jhmqfF55Hr63/PQf6Ofmwygrg63B8T9Ri2JoiebIuaMe1nweYOw/ZSHn0+/CicSZiPTX SnsYaTdeSncKcr9kwyn227sKEqjs+yOjZpR6KtFgvhWeD7Yz2O+dUDh1efEjc0LingYq zv7w== X-Gm-Message-State: AA+aEWYvVO05hLBHy7soB0es3aNR/Uk+ATsCrZ93YudUnCy2v4Rxaog+ Iw733HrxvSughZPCSC/91wGwRQ== X-Google-Smtp-Source: AFSGD/V9o/EnPu/jS21sRLzC9rVzv3Ae9fU+4D6Ndx+QLN4B5fnprorFaxpOIqfwIKVJdvRIR9dkNQ== X-Received: by 2002:a19:f510:: with SMTP id j16mr9345394lfb.35.1543862430451; Mon, 03 Dec 2018 10:40:30 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id d23sm2518513lfc.11.2018.12.03.10.40.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 10:40:29 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 2/5] net: 8021q: vlan_dev: add vid tag for uc and mc address lists Date: Mon, 3 Dec 2018 20:40:20 +0200 Message-Id: <20181203184023.3430-3-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> References: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Update vlan mc and uc addresses with VID tag while propagating address set to lower devices, do this only if address is not synched. It allows on end driver level to distinguish address belonging to vlans. Signed-off-by: Ivan Khoronzhuk --- include/linux/if_vlan.h | 1 + net/8021q/vlan_core.c | 10 ++++++++++ net/8021q/vlan_dev.c | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 4cca4da7a6de..94657f3c483a 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -136,6 +136,7 @@ extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev, extern int vlan_for_each(struct net_device *dev, int (*action)(struct net_device *dev, int vid, void *arg), void *arg); +extern u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index a313165e7a67..5d17947d6988 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -454,6 +454,16 @@ bool vlan_uses_dev(const struct net_device *dev) } EXPORT_SYMBOL(vlan_uses_dev); +u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr) +{ + u16 vid = 0; + + vid = addr[dev->addr_len]; + vid |= (addr[dev->addr_len + 1] & 0xf) << 8; + return vid; +} +EXPORT_SYMBOL(vlan_dev_get_addr_vid); + static struct sk_buff *vlan_gro_receive(struct list_head *head, struct sk_buff *skb) { diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b2d9c8f27cd7..c05b313314b7 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -250,6 +250,14 @@ void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23); } +static void vlan_dev_set_addr_vid(struct net_device *vlan_dev, u8 *addr) +{ + u16 vid = vlan_dev_vlan_id(vlan_dev); + + addr[vlan_dev->addr_len] = vid & 0xff; + addr[vlan_dev->addr_len + 1] = (vid >> 8) & 0xf; +} + bool vlan_dev_inherit_address(struct net_device *dev, struct net_device *real_dev) { @@ -481,8 +489,26 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) } } +static void vlan_dev_align_addr_vid(struct net_device *vlan_dev) +{ + struct net_device *real_dev = vlan_dev_real_dev(vlan_dev); + struct netdev_hw_addr *ha; + + if (!real_dev->vid_len) + return; + + netdev_for_each_mc_addr(ha, vlan_dev) + if (!ha->sync_cnt) + vlan_dev_set_addr_vid(vlan_dev, ha->addr); + + netdev_for_each_uc_addr(ha, vlan_dev) + if (!ha->sync_cnt) + vlan_dev_set_addr_vid(vlan_dev, ha->addr); +} + static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) { + vlan_dev_align_addr_vid(vlan_dev); dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); } From patchwork Mon Dec 3 18:40:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 10710365 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C123E14BD for ; Mon, 3 Dec 2018 18:40:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B51332B3C5 for ; Mon, 3 Dec 2018 18:40:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A9B1E2B3B0; Mon, 3 Dec 2018 18:40:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 285792B3B0 for ; Mon, 3 Dec 2018 18:40:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727019AbeLCSkj (ORCPT ); Mon, 3 Dec 2018 13:40:39 -0500 Received: from mail-lf1-f68.google.com ([209.85.167.68]:41509 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727013AbeLCSkj (ORCPT ); Mon, 3 Dec 2018 13:40:39 -0500 Received: by mail-lf1-f68.google.com with SMTP id c16so9948226lfj.8 for ; Mon, 03 Dec 2018 10:40:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TRbSa+zIScLn5oBfObhnQYA2lIlslwrx0Wo3p5ZDIKA=; b=Q+EZwnZZiafPJrwFa0oh3lW+9Qd0bw6m8FB0BDbO3og20JyPMHU2I95ndlot8anzji 97jIECbovDwjkX2vcrZxBcTG6iYnUTbIlhpqk8ErEkAVWYl6bGSDRC6QEJ1WIflFb22q Eu4fMTAMzPnpYmQMz/iIMFceHrQhbdqYfEFgg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TRbSa+zIScLn5oBfObhnQYA2lIlslwrx0Wo3p5ZDIKA=; b=LSFXHpPKQJT4PRkbJW2sw1bS64JD2bw0pfLONYdm5G9oZn7E2L8uzYZxGLTK39nKav 5Ty0SWBQEry/DDnIWvb/YaeuBQVLjduNv9sPcBwJMO61tiD+F3wWXsZ7mFWFiyhwwfOq FnlJxVreXglv1WcpWea5Rc9IYBGqHshL8GwArWzviGZC1cMgDQ/MJgDolOPITE1z8iCx ewV5Mn3WUIEQH0uCTO3ttHRLypecxqQZPWumEnVDKoKhLo2q70tzxgNrkImamzhSbgmn ZjYb9RPuCZi396PkFXIq4BUkkx052deNDcWVRAA0TvCwN1qw6RLlUPWabFXO2b5L3xy6 M10Q== X-Gm-Message-State: AA+aEWa1Cu4huiehqS8QugIqzOdw7eENKSaKUs/TDuX3I+HfkrBYTLqe hKl31/c2RDSWvhDTjPIAOsHIMw== X-Google-Smtp-Source: AFSGD/VthoZsaKZ1Wj9igPaBRFAOMxSWzOgzbF9w6Fs9TOpJtl3hWO3Nn2JDOhW7qzkwiJAMXdqdpQ== X-Received: by 2002:a19:5f1e:: with SMTP id t30mr9469772lfb.76.1543862432032; Mon, 03 Dec 2018 10:40:32 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id d23sm2518513lfc.11.2018.12.03.10.40.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 10:40:31 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 3/5] net: 8021q: vlan_dev: add vid tag for vlan device mac address Date: Mon, 3 Dec 2018 20:40:21 +0200 Message-Id: <20181203184023.3430-4-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> References: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The vlan device address is hold separately from uc/mc lists and is handled differently. With proposed change, the vlan dev address is bind with real device address only if's inherited, in all other cases it's separate address entry. Signed-off-by: Ivan Khoronzhuk --- include/linux/netdevice.h | 2 ++ net/8021q/vlan.c | 3 ++ net/8021q/vlan_dev.c | 76 +++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1b0f9c322b01..28c6da3583cf 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -76,6 +76,8 @@ void netdev_set_default_ethtool_ops(struct net_device *dev, #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ #define NET_RX_DROP 1 /* packet dropped */ +#define NET_802Q_VID_TSIZE 2 + /* * Transmit return codes: transmit return codes originate from three different * namespaces: diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index aef1a977279c..a1eae9d61284 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -295,6 +295,9 @@ static void vlan_sync_address(struct net_device *dev, if (vlan_dev_inherit_address(vlandev, dev)) goto out; + if (dev->vid_len) + goto out; + /* vlan address was different from the old address and is equal to * the new address */ if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index c05b313314b7..f6bcd847509e 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -258,12 +258,61 @@ static void vlan_dev_set_addr_vid(struct net_device *vlan_dev, u8 *addr) addr[vlan_dev->addr_len + 1] = (vid >> 8) & 0xf; } +static int vlan_dev_add_addr(struct net_device *dev, u8 *addr) +{ + struct net_device *real_dev = vlan_dev_real_dev(dev); + unsigned char naddr[ETH_ALEN + NET_802Q_VID_TSIZE]; + + if (real_dev->vid_len) { + memcpy(naddr, addr, dev->addr_len); + vlan_dev_set_addr_vid(dev, naddr); + return dev_vid_uc_add(real_dev, naddr); + } + + if (ether_addr_equal(addr, real_dev->dev_addr)) + return 0; + + return dev_uc_add(real_dev, addr); +} + +static void vlan_dev_del_addr(struct net_device *dev, u8 *addr) +{ + struct net_device *real_dev = vlan_dev_real_dev(dev); + unsigned char naddr[ETH_ALEN + NET_802Q_VID_TSIZE]; + + if (real_dev->vid_len) { + memcpy(naddr, addr, dev->addr_len); + vlan_dev_set_addr_vid(dev, naddr); + dev_vid_uc_del(real_dev, naddr); + return; + } + + if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) + dev_uc_del(real_dev, addr); +} + +int vlan_dev_subs_addr(struct net_device *dev, u8 *addr) +{ + int err; + + err = vlan_dev_add_addr(dev, addr); + if (err < 0) + return err; + + vlan_dev_del_addr(dev, dev->dev_addr); + return err; +} + bool vlan_dev_inherit_address(struct net_device *dev, struct net_device *real_dev) { if (dev->addr_assign_type != NET_ADDR_STOLEN) return false; + if (real_dev->vid_len) + if (vlan_dev_subs_addr(dev, real_dev->dev_addr)) + return false; + ether_addr_copy(dev->dev_addr, real_dev->dev_addr); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); return true; @@ -279,9 +328,10 @@ static int vlan_dev_open(struct net_device *dev) !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) return -ENETDOWN; - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr) && - !vlan_dev_inherit_address(dev, real_dev)) { - err = dev_uc_add(real_dev, dev->dev_addr); + if (ether_addr_equal(dev->dev_addr, real_dev->dev_addr) || + (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr) && + !vlan_dev_inherit_address(dev, real_dev))) { + err = vlan_dev_add_addr(dev, dev->dev_addr); if (err < 0) goto out; } @@ -313,8 +363,7 @@ static int vlan_dev_open(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); del_unicast: - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); + vlan_dev_del_addr(dev, dev->dev_addr); out: netif_carrier_off(dev); return err; @@ -332,18 +381,14 @@ static int vlan_dev_stop(struct net_device *dev) if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); - + vlan_dev_del_addr(dev, dev->dev_addr); netif_carrier_off(dev); return 0; } static int vlan_dev_set_mac_address(struct net_device *dev, void *p) { - struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; struct sockaddr *addr = p; - int err; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; @@ -351,15 +396,8 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) if (!(dev->flags & IFF_UP)) goto out; - if (!ether_addr_equal(addr->sa_data, real_dev->dev_addr)) { - err = dev_uc_add(real_dev, addr->sa_data); - if (err < 0) - return err; - } - - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); - + if (vlan_dev_subs_addr(dev, addr->sa_data)) + return true; out: ether_addr_copy(dev->dev_addr, addr->sa_data); return 0; From patchwork Mon Dec 3 18:40:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 10710361 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8F9A518A7 for ; Mon, 3 Dec 2018 18:40:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8324B2B0D0 for ; Mon, 3 Dec 2018 18:40:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 776C52B13A; Mon, 3 Dec 2018 18:40:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 120422B0D0 for ; Mon, 3 Dec 2018 18:40:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726870AbeLCSkl (ORCPT ); Mon, 3 Dec 2018 13:40:41 -0500 Received: from mail-lf1-f68.google.com ([209.85.167.68]:36009 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726925AbeLCSkk (ORCPT ); Mon, 3 Dec 2018 13:40:40 -0500 Received: by mail-lf1-f68.google.com with SMTP id a16so9966646lfg.3 for ; Mon, 03 Dec 2018 10:40:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AqR+/tdvN+T03MfMl2BZakLvSSDhyowAZhzj7me3ZY0=; b=YaD4BKzhs0h80iAS6DLry0wrLCOm+kNnEJBcvZO8qowRaipNimLGISvXZTTISIAQBd 4wgK7t6/ElreUMZowwv6K6eqM/v2dATuPJg9MaTdBYCC6fG68dEbhz7Vy/by4wgPjz28 Ayx7AiZ6U+wjM60HgTE8O7y6xOs9aXl/b76jY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AqR+/tdvN+T03MfMl2BZakLvSSDhyowAZhzj7me3ZY0=; b=KuKlN7tAnL5MVcMYch6QP0QM+U2GIyr4xAmgQ0NJwHxSV58B5m959fojKVrnxKEXh7 HJaYZusK/zzseoKZ+z5g1Prru34XyvN+MLalyP4SD2n8EMso0cm+5POpGT+inVZ6k3Pr caN7RH4qJDuLYb5NX3B+RGjvUctzoLOy1stDDskWofQk8Gc5vEACF+nj0JaXtDuitMTr Kd6RoZPt4TRGj/j0jJ5lz7JtlExpsVuQiS3N62gbfVCZKxm3wZP8p9VLb9bqRFL2yEPy O0TLCwzECT5h4Ug5ZPVW/YvagFpQw37hPwx1TFc+MryB67wFTH1d4BnX/1UV1Q7thn/0 i/RA== X-Gm-Message-State: AA+aEWblakgWDQRf+cARMGqco8uQTOGTmzTqS56Ux9aV3sPQD+JZn5JQ ZPPBcWYwt5Yp9USNjKcL2SLViQ== X-Google-Smtp-Source: AFSGD/WuA0Ki0SJfIvQBbk9ywQ8RcQEjitFRR+Gh0ivVr+aKQhOB0EyqkBXV6ldkFLi9yGuAWY8JZQ== X-Received: by 2002:a19:920a:: with SMTP id u10mr9678312lfd.122.1543862433315; Mon, 03 Dec 2018 10:40:33 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id d23sm2518513lfc.11.2018.12.03.10.40.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 10:40:32 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 4/5] net: ethernet: add default vid len for all ehternet kind devices Date: Mon, 3 Dec 2018 20:40:22 +0200 Message-Id: <20181203184023.3430-5-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> References: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP By default every ethernet netdev needs vid len = 2 bytes to be able to hold up to 4096 vids. So set it for every eth device to be correct, except vlan devs. In order to shrink all addresses of devices above vlan, the vid_len for vlan dev = 0, as result all suckers sync their addresses to common base not taking in to account vid part (vid_len of "to" devices is important only). And only vlan device is the source of addresses with actual its vid set, propagating it to parent devices while rx_mode(). Also, don't bother those devices that at this moment not moved to vlan addressing scheme, so while end ethernet device is created - set vid_len to 0, thus, while syncing, its address space is concatenated to one dimensional like usual, and who needs vlan addresses to be separate - set it to VLAN_VID_TYPE_SIZE. When number of devices supporting new vlan addressing scheme becomes more than simple ones, it can be reversed, disabling it for those who don't need. This vid_len should be placed under smth like CONFIG_8021Q_ADDR_FLT. There is another decision - is to inherit vid_len or some feature flag from end root device in order to all upper devices have vlan extended address space only if exact end real device have such capability. But I didn't, because it requires more changes and probably I'm not familiar with all places where it should be inherited, I would appreciate if someone can guid where it's applicable, then it could become a little bit more limited. Signed-off-by: Ivan Khoronzhuk --- net/8021q/vlan_dev.c | 1 + net/ethernet/eth.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f6bcd847509e..c2d934251e77 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -896,6 +896,7 @@ void vlan_setup(struct net_device *dev) dev->min_mtu = 0; dev->max_mtu = ETH_MAX_MTU; + dev->vid_len = 0; eth_zero_addr(dev->broadcast); } diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 58933fa50bb5..52f90cefb6de 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -363,6 +363,7 @@ void ether_setup(struct net_device *dev) dev->min_mtu = ETH_MIN_MTU; dev->max_mtu = ETH_DATA_LEN; dev->addr_len = ETH_ALEN; + dev->vid_len = NET_802Q_VID_TSIZE; dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; dev->flags = IFF_BROADCAST|IFF_MULTICAST; dev->priv_flags |= IFF_TX_SKB_SHARING; @@ -390,8 +391,18 @@ EXPORT_SYMBOL(ether_setup); struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs) { - return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, - ether_setup, txqs, rxqs); + struct net_device *dev; + + dev = alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, + ether_setup, txqs, rxqs); + + /* TODO: When number of real ehternet devices supporting vlan + * addressing scheme becomes more than simple ones, it should + * be removed, disabling it (by dev->vid_len = 0) for those + * who doesn't support it + */ + dev->vid_len = 0; + return dev; } EXPORT_SYMBOL(alloc_etherdev_mqs); From patchwork Mon Dec 3 18:40:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 10710363 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 308A61923 for ; Mon, 3 Dec 2018 18:40:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23A532B13A for ; Mon, 3 Dec 2018 18:40:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1834A2B166; Mon, 3 Dec 2018 18:40:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FBC92B13A for ; Mon, 3 Dec 2018 18:40:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726882AbeLCSkm (ORCPT ); Mon, 3 Dec 2018 13:40:42 -0500 Received: from mail-lf1-f68.google.com ([209.85.167.68]:46134 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727017AbeLCSkl (ORCPT ); Mon, 3 Dec 2018 13:40:41 -0500 Received: by mail-lf1-f68.google.com with SMTP id f23so9936329lfc.13 for ; Mon, 03 Dec 2018 10:40:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LQhVP2xTDiWvMET8FX8dZ7UeSj+rc4vD4kLYzBGpj+Q=; b=WAHxVwvXKFmdWCpyYPcvFNSunMdJ/C2M0OVQ+QS3pwoW2cNSpeHdirsztoll0UBisR xQNZPz12+bGdP1TVrbwnktJKZCAer/arLA6OXowvtSgniykZR461ek+4sKCmJIVBwuLG r9vfgi0nnPXFwZrPpZcaiHefM73a9rmFFv//0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LQhVP2xTDiWvMET8FX8dZ7UeSj+rc4vD4kLYzBGpj+Q=; b=Jk6Tcd/u+P6ARfc9rt407AMfkKBUffSuZiFiF/BzvKc3AWeKfuLAyOjuycIl1dpebf /PbxugH1zx+HNSCW2i/P90hCFEpv4l9foV5JRCyqGqS1sAs2KQj2GTGuWASK4Gi1/3kG hDI6FEuStsTDRWwiejpjc0GD8N2bAWOOB7wJukM4nuG37P/nY2ZE+YJ/oTI6T6yvyvff ySqEaMlkXl/TAwmH7KSeQH8JpFqCXX4+ZAY27qIliqvY/scq20a9CHW3f9srrFRHbUvE OVY1ZNpJNv1meHOoafv1TWTALCgAGDpPFGrdBbfMYQAQq/gN0UJvhnZKg2ck8PMdHTvy kbtQ== X-Gm-Message-State: AA+aEWZoCD9PqSX2hzFR91NdnLdz2BGM/iJ/NngfjeZewsCcKT/yfyM8 XBRLoto4KgQIcsxcAHxF3KZ4tA== X-Google-Smtp-Source: AFSGD/UPDpwFWsYoPlLLpddaMc31C4vTNj7cd2E3zUy50EpLl2TFKda1baFDlrI3svZHvSXemk+Cqw== X-Received: by 2002:a19:9e11:: with SMTP id h17mr10478905lfe.73.1543862434506; Mon, 03 Dec 2018 10:40:34 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id d23sm2518513lfc.11.2018.12.03.10.40.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 10:40:33 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 5/5] net: ethernet: ti: cpsw: update mc vlan and add uc vlan support based on addr vids Date: Mon, 3 Dec 2018 20:40:23 +0200 Message-Id: <20181203184023.3430-6-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> References: <20181203184023.3430-1-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Update multicast support for vlans and add uc vlan support using newly added net/core changes with vid tag. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/cpsw.c | 86 ++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index e4aa030f1726..49a223720335 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -796,6 +796,67 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num) return 0; } +static int cpsw_set_uc(struct net_device *ndev, const u8 *addr, + int vid, int add) +{ + struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; + int flags, port, ret; + + if (vid < 0) { + if (cpsw->data.dual_emac) + vid = cpsw->slaves[priv->emac_port].port_vlan; + else + vid = 0; + } + + port = HOST_PORT_NUM; + flags = vid ? ALE_VLAN : 0; + + if (add) + ret = cpsw_ale_add_ucast(cpsw->ale, addr, port, flags, vid); + else + ret = cpsw_ale_del_ucast(cpsw->ale, addr, port, flags, vid); + + return ret; +} + +static int _cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_mc(ndev, addr, vid ? vid : -1, 1); + return 0; +} + +static int _cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_mc(ndev, addr, vid ? vid : -1, 0); + return 0; +} + +static int _cpsw_add_uc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_uc(ndev, addr, vid ? vid : -1, 1); + return 0; +} + +static int _cpsw_del_uc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_uc(ndev, addr, vid ? vid : -1, 0); + return 0; +} + static void cpsw_ndo_set_rx_mode(struct net_device *ndev) { struct cpsw_common *cpsw = ndev_to_cpsw(ndev); @@ -814,8 +875,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI); /* add/remove mcast address either for real netdev or for vlan */ - __hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr, - cpsw_del_mc_addr); + __dev_mc_sync(ndev, _cpsw_add_mc_addr, _cpsw_del_mc_addr); + __dev_uc_sync(ndev, _cpsw_add_uc_addr, _cpsw_del_uc_addr); } static void cpsw_intr_enable(struct cpsw_common *cpsw) @@ -2092,7 +2153,8 @@ static int cpsw_ndo_stop(struct net_device *ndev) struct cpsw_common *cpsw = priv->cpsw; cpsw_info(priv, ifdown, "shutting down cpsw device\n"); - __hw_addr_ref_unsync_dev(&ndev->mc, ndev, cpsw_purge_all_mc); + __dev_mc_unsync(ndev, _cpsw_del_mc_addr); + __dev_uc_unsync(ndev, _cpsw_del_uc_addr); netif_tx_stop_all_queues(priv->ndev); netif_carrier_off(priv->ndev); @@ -2453,21 +2515,11 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, if (ret != 0) return ret; - ret = cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, - HOST_PORT_NUM, ALE_VLAN, vid); - if (ret != 0) - goto clean_vid; - ret = cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, mcast_mask, ALE_VLAN, vid, 0); - if (ret != 0) - goto clean_vlan_ucast; - return 0; + if (!ret) + return 0; -clean_vlan_ucast: - cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, - HOST_PORT_NUM, ALE_VLAN, vid); -clean_vid: cpsw_ale_del_vlan(cpsw->ale, vid, 0); return ret; } @@ -3418,6 +3470,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->emac_port = 1; cpsw->slaves[1].ndev = ndev; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + ndev->priv_flags |= IFF_UNICAST_FLT; + ndev->vid_len = NET_802Q_VID_TSIZE; ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; @@ -3679,6 +3733,8 @@ static int cpsw_probe(struct platform_device *pdev) } ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + ndev->priv_flags |= IFF_UNICAST_FLT; + ndev->vid_len = NET_802Q_VID_TSIZE; ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;