From patchwork Tue Apr 2 15:35:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Manning X-Patchwork-Id: 1074662 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vyatta.att-mail.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44YZ4d0r7vz9sTV for ; Wed, 3 Apr 2019 03:13:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729721AbfDBQND (ORCPT ); Tue, 2 Apr 2019 12:13:03 -0400 Received: from mx0a-00191d01.pphosted.com ([67.231.149.140]:44026 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728741AbfDBQND (ORCPT ); Tue, 2 Apr 2019 12:13:03 -0400 X-Greylist: delayed 2208 seconds by postgrey-1.27 at vger.kernel.org; Tue, 02 Apr 2019 12:13:02 EDT Received: from pps.filterd (m0049287.ppops.net [127.0.0.1]) by m0049287.ppops.net-00191d01. (8.16.0.27/8.16.0.27) with SMTP id x32FFpjt003941 for ; Tue, 2 Apr 2019 11:36:13 -0400 Received: from tlpd255.enaf.dadc.sbc.com (sbcsmtp3.sbc.com [144.160.112.28]) by m0049287.ppops.net-00191d01. with ESMTP id 2rm9yx9cme-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 02 Apr 2019 11:36:12 -0400 Received: from enaf.dadc.sbc.com (localhost [127.0.0.1]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32FaBfE027159 for ; Tue, 2 Apr 2019 10:36:12 -0500 Received: from zlp30495.vci.att.com (zlp30495.vci.att.com [135.46.181.158]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa7Pe026895 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 2 Apr 2019 10:36:07 -0500 Received: from zlp30495.vci.att.com (zlp30495.vci.att.com [127.0.0.1]) by zlp30495.vci.att.com (Service) with ESMTP id DDAAB4009E6F for ; Tue, 2 Apr 2019 15:36:07 +0000 (GMT) Received: from clpi183.sldc.sbc.com (unknown [135.41.1.46]) by zlp30495.vci.att.com (Service) with ESMTP id BB6114009E68 for ; Tue, 2 Apr 2019 15:36:07 +0000 (GMT) Received: from sldc.sbc.com (localhost [127.0.0.1]) by clpi183.sldc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa7Ll029141 for ; Tue, 2 Apr 2019 10:36:07 -0500 Received: from mail.eng.vyatta.net (mail.eng.vyatta.net [10.156.50.82]) by clpi183.sldc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa2fG028761 for ; Tue, 2 Apr 2019 10:36:02 -0500 Received: from MM-7520.eng.vyatta.net (unknown [10.156.47.86]) by mail.eng.vyatta.net (Postfix) with ESMTPA id 8ED6B3603E4 for ; Tue, 2 Apr 2019 08:36:01 -0700 (PDT) From: Mike Manning To: netdev@vger.kernel.org Subject: [PATCH net-next 1/4] vlan: support binding link state to vlan member bridge ports Date: Tue, 2 Apr 2019 16:35:40 +0100 Message-Id: <20190402153543.6277-2-mmanning@vyatta.att-mail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> References: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-02_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=877 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904020103 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the case of vlan filtering on bridges, the bridge may also have the corresponding vlan devices as upper devices. Currently the link state of vlan devices is transferred from the lower device. So this is up if the bridge is in admin up state and there is at least one bridge port that is up, regardless of the vlan that the port is a member of. The link state of the vlan device may need to track only the state of the subset of ports that are also members of the corresponding vlan, rather than that of all ports. Add a flag to specify a vlan bridge binding mode, by which the link state is no longer automatically transferred from the lower device, but is instead determined by the bridge ports that are members of the vlan. Signed-off-by: Mike Manning --- include/uapi/linux/if_vlan.h | 9 +++++---- net/8021q/vlan_dev.c | 3 ++- net/8021q/vlan_netlink.c | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/if_vlan.h b/include/uapi/linux/if_vlan.h index 7a0e8bd65b6b..601931ac8002 100644 --- a/include/uapi/linux/if_vlan.h +++ b/include/uapi/linux/if_vlan.h @@ -32,10 +32,11 @@ enum vlan_ioctl_cmds { }; enum vlan_flags { - VLAN_FLAG_REORDER_HDR = 0x1, - VLAN_FLAG_GVRP = 0x2, - VLAN_FLAG_LOOSE_BINDING = 0x4, - VLAN_FLAG_MVRP = 0x8, + VLAN_FLAG_REORDER_HDR = 0x1, + VLAN_FLAG_GVRP = 0x2, + VLAN_FLAG_LOOSE_BINDING = 0x4, + VLAN_FLAG_MVRP = 0x8, + VLAN_FLAG_BRIDGE_BINDING = 0x16, }; enum vlan_name_types { diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 15293c2a5dd8..86b38bb87f9a 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -223,7 +223,8 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) u32 old_flags = vlan->flags; if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | - VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) + VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP | + VLAN_FLAG_BRIDGE_BINDING)) return -EINVAL; vlan->flags = (old_flags & ~mask) | (flags & mask); diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 9b60c1e399e2..a624dccf68fd 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c @@ -84,7 +84,8 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[], flags = nla_data(data[IFLA_VLAN_FLAGS]); if ((flags->flags & flags->mask) & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | - VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) { + VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP | + VLAN_FLAG_BRIDGE_BINDING)) { NL_SET_ERR_MSG_MOD(extack, "Invalid VLAN flags"); return -EINVAL; } From patchwork Tue Apr 2 15:35:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Manning X-Patchwork-Id: 1074863 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vyatta.att-mail.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44YfCy5f18z9sPF for ; Wed, 3 Apr 2019 06:19:42 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730626AbfDBTTl (ORCPT ); Tue, 2 Apr 2019 15:19:41 -0400 Received: from mx0a-00191d01.pphosted.com ([67.231.149.140]:47044 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726083AbfDBTTl (ORCPT ); Tue, 2 Apr 2019 15:19:41 -0400 Received: from pps.filterd (m0053301.ppops.net [127.0.0.1]) by mx0a-00191d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x32FFoHV047858 for ; Tue, 2 Apr 2019 11:36:18 -0400 Received: from tlpd255.enaf.dadc.sbc.com (sbcsmtp3.sbc.com [144.160.112.28]) by mx0a-00191d01.pphosted.com with ESMTP id 2rm9xwsghw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 02 Apr 2019 11:36:18 -0400 Received: from enaf.dadc.sbc.com (localhost [127.0.0.1]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32FaFu5027430 for ; Tue, 2 Apr 2019 10:36:17 -0500 Received: from zlp30497.vci.att.com (zlp30497.vci.att.com [135.46.181.156]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa8Yv026965 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 2 Apr 2019 10:36:09 -0500 Received: from zlp30497.vci.att.com (zlp30497.vci.att.com [127.0.0.1]) by zlp30497.vci.att.com (Service) with ESMTP id EB2B24009E88 for ; Tue, 2 Apr 2019 15:36:08 +0000 (GMT) Received: from tlpd252.dadc.sbc.com (unknown [135.31.184.157]) by zlp30497.vci.att.com (Service) with ESMTP id D47E44009E87 for ; Tue, 2 Apr 2019 15:36:08 +0000 (GMT) Received: from dadc.sbc.com (localhost [127.0.0.1]) by tlpd252.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa7LL052570 for ; Tue, 2 Apr 2019 10:36:08 -0500 Received: from mail.eng.vyatta.net (mail.eng.vyatta.net [10.156.50.82]) by tlpd252.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa2J0052267 for ; Tue, 2 Apr 2019 10:36:03 -0500 Received: from MM-7520.eng.vyatta.net (unknown [10.156.47.86]) by mail.eng.vyatta.net (Postfix) with ESMTPA id 4B9AF3600F5 for ; Tue, 2 Apr 2019 08:36:02 -0700 (PDT) From: Mike Manning To: netdev@vger.kernel.org Subject: [PATCH net-next 2/4] vlan: do not transfer link state in vlan bridge binding mode Date: Tue, 2 Apr 2019 16:35:41 +0100 Message-Id: <20190402153543.6277-3-mmanning@vyatta.att-mail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> References: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-02_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904020103 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In vlan bridge binding mode, the link state is no longer transferred from the lower device. Instead it is set by the bridge module according to the state of bridge ports that are members of the vlan. Signed-off-by: Mike Manning --- net/8021q/vlan.c | 18 ++++++++++++++---- net/8021q/vlan_dev.c | 19 ++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index dc4411165e43..1f99678751df 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -75,6 +75,14 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, return 0; } +static void vlan_stacked_transfer_operstate(const struct net_device *rootdev, + struct net_device *dev, + struct vlan_dev_priv *vlan) +{ + if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING)) + netif_stacked_transfer_operstate(rootdev, dev); +} + void unregister_vlan_dev(struct net_device *dev, struct list_head *head) { struct vlan_dev_priv *vlan = vlan_dev_priv(dev); @@ -180,7 +188,7 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack) /* Account for reference in struct vlan_dev_priv */ dev_hold(real_dev); - netif_stacked_transfer_operstate(real_dev, dev); + vlan_stacked_transfer_operstate(real_dev, dev, vlan); linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ /* So, got the sucker initialized, now lets place @@ -399,7 +407,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_CHANGE: /* Propagate real device state to vlan devices */ vlan_group_for_each_dev(grp, i, vlandev) - netif_stacked_transfer_operstate(dev, vlandev); + vlan_stacked_transfer_operstate(dev, vlandev, + vlan_dev_priv(vlandev)); break; case NETDEV_CHANGEADDR: @@ -446,7 +455,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, dev_close_many(&close_list, false); list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) { - netif_stacked_transfer_operstate(dev, vlandev); + vlan_stacked_transfer_operstate(dev, vlandev, + vlan_dev_priv(vlandev)); list_del_init(&vlandev->close_list); } list_del(&close_list); @@ -463,7 +473,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) dev_change_flags(vlandev, flgs | IFF_UP, extack); - netif_stacked_transfer_operstate(dev, vlandev); + vlan_stacked_transfer_operstate(dev, vlandev, vlan); } break; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 86b38bb87f9a..270df9f0dfea 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -297,7 +297,8 @@ static int vlan_dev_open(struct net_device *dev) if (vlan->flags & VLAN_FLAG_MVRP) vlan_mvrp_request_join(dev); - if (netif_carrier_ok(real_dev)) + if (netif_carrier_ok(real_dev) && + !(vlan->flags & VLAN_FLAG_BRIDGE_BINDING)) netif_carrier_on(dev); return 0; @@ -327,7 +328,8 @@ static int vlan_dev_stop(struct net_device *dev) if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); - netif_carrier_off(dev); + if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING)) + netif_carrier_off(dev); return 0; } @@ -549,7 +551,8 @@ static const struct net_device_ops vlan_netdev_ops; static int vlan_dev_init(struct net_device *dev) { - struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + struct vlan_dev_priv *vlan = vlan_dev_priv(dev); + struct net_device *real_dev = vlan->real_dev; netif_carrier_off(dev); @@ -560,6 +563,9 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); + if (vlan->flags & VLAN_FLAG_BRIDGE_BINDING) + dev->state |= (1 << __LINK_STATE_NOCARRIER); + dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | @@ -590,8 +596,7 @@ static int vlan_dev_init(struct net_device *dev) #endif dev->needed_headroom = real_dev->needed_headroom; - if (vlan_hw_offload_capable(real_dev->features, - vlan_dev_priv(dev)->vlan_proto)) { + if (vlan_hw_offload_capable(real_dev->features, vlan->vlan_proto)) { dev->header_ops = &vlan_passthru_header_ops; dev->hard_header_len = real_dev->hard_header_len; } else { @@ -605,8 +610,8 @@ static int vlan_dev_init(struct net_device *dev) vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); - vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); - if (!vlan_dev_priv(dev)->vlan_pcpu_stats) + vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); + if (!vlan->vlan_pcpu_stats) return -ENOMEM; return 0; From patchwork Tue Apr 2 15:35:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Manning X-Patchwork-Id: 1074765 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vyatta.att-mail.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44YcCJ3WTxz9sSL for ; Wed, 3 Apr 2019 04:49:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730227AbfDBRs6 (ORCPT ); Tue, 2 Apr 2019 13:48:58 -0400 Received: from mx0b-00191d01.pphosted.com ([67.231.157.136]:39014 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729927AbfDBRs6 (ORCPT ); Tue, 2 Apr 2019 13:48:58 -0400 Received: from pps.filterd (m0083689.ppops.net [127.0.0.1]) by m0083689.ppops.net-00191d01. (8.16.0.27/8.16.0.27) with SMTP id x32FFpIW035200 for ; Tue, 2 Apr 2019 11:36:16 -0400 Received: from alpi155.enaf.aldc.att.com (sbcsmtp7.sbc.com [144.160.229.24]) by m0083689.ppops.net-00191d01. with ESMTP id 2rm9pdt322-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 02 Apr 2019 11:36:16 -0400 Received: from enaf.aldc.att.com (localhost [127.0.0.1]) by alpi155.enaf.aldc.att.com (8.14.5/8.14.5) with ESMTP id x32FaF5A008050 for ; Tue, 2 Apr 2019 11:36:15 -0400 Received: from zlp27129.vci.att.com (zlp27129.vci.att.com [135.66.87.42]) by alpi155.enaf.aldc.att.com (8.14.5/8.14.5) with ESMTP id x32Fa9b5007920 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 2 Apr 2019 11:36:09 -0400 Received: from zlp27129.vci.att.com (zlp27129.vci.att.com [127.0.0.1]) by zlp27129.vci.att.com (Service) with ESMTP id 081E34039286 for ; Tue, 2 Apr 2019 15:36:09 +0000 (GMT) Received: from mlpi432.sfdc.sbc.com (unknown [144.151.223.11]) by zlp27129.vci.att.com (Service) with ESMTP id E19F54039284 for ; Tue, 2 Apr 2019 15:36:08 +0000 (GMT) Received: from sfdc.sbc.com (localhost [127.0.0.1]) by mlpi432.sfdc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa8Yr023968 for ; Tue, 2 Apr 2019 11:36:08 -0400 Received: from mail.eng.vyatta.net (mail.eng.vyatta.net [10.156.50.82]) by mlpi432.sfdc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa3fB023824 for ; Tue, 2 Apr 2019 11:36:03 -0400 Received: from MM-7520.eng.vyatta.net (unknown [10.156.47.86]) by mail.eng.vyatta.net (Postfix) with ESMTPA id 074983603E4 for ; Tue, 2 Apr 2019 08:36:02 -0700 (PDT) From: Mike Manning To: netdev@vger.kernel.org Subject: [PATCH net-next 3/4] bridge: support binding vlan dev link state to vlan member bridge ports Date: Tue, 2 Apr 2019 16:35:42 +0100 Message-Id: <20190402153543.6277-4-mmanning@vyatta.att-mail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> References: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-02_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904020103 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the case of vlan filtering on bridges, the bridge may also have the corresponding vlan devices as upper devices. A vlan bridge binding mode is added to allow the link state of the vlan device to track only the state of the subset of bridge ports that are also members of the vlan, rather than that of all bridge ports. This mode is set with a vlan flag rather than a bridge sysfs so that the 8021q module is aware that it should not set the link state for the vlan device. If bridge vlan is configured, the bridge device event handling results in the link state for an upper device being set, if it is a vlan device with the vlan bridge binding mode enabled. This also sets a vlan_bridge_binding flag so that subsequent UP/DOWN/CHANGE events for the ports in that bridge result in a link state update of the vlan device if required. The link state of the vlan device is up if there is at least one bridge port that is a vlan member that is admin & oper up, otherwise its oper state is IF_OPER_LOWERLAYERDOWN. Signed-off-by: Mike Manning --- net/bridge/br.c | 23 ++++++-- net/bridge/br_private.h | 17 ++++++ net/bridge/br_vlan.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 4 deletions(-) diff --git a/net/bridge/br.c b/net/bridge/br.c index a5174e5001d8..b80cd5ccd590 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -40,10 +40,21 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v bool changed_addr; int err; - /* register of bridge completed, add sysfs entries */ - if ((dev->priv_flags & IFF_EBRIDGE) && event == NETDEV_REGISTER) { - br_sysfs_addbr(dev); - return NOTIFY_DONE; + if (dev->priv_flags & IFF_EBRIDGE) { + if (event == NETDEV_REGISTER) { + /* register of bridge completed, add sysfs entries */ + br_sysfs_addbr(dev); + return NOTIFY_DONE; + } +#ifdef CONFIG_BRIDGE_VLAN_FILTERING + if (event == NETDEV_CHANGEUPPER) { + struct netdev_notifier_changeupper_info *info = ptr; + + br_vlan_upper_change(dev, info->upper_dev, + info->linking); + return NOTIFY_DONE; + } +#endif } /* not a port of a bridge */ @@ -126,6 +137,10 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v break; } +#ifdef CONFIG_BRIDGE_VLAN_FILTERING + br_vlan_port_event(p, br, event); +#endif + /* Events that may cause spanning tree to refresh */ if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP || event == NETDEV_CHANGE || event == NETDEV_DOWN)) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 00deef7fc1f3..604de174abe0 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -336,6 +336,7 @@ struct net_bridge { #ifdef CONFIG_BRIDGE_VLAN_FILTERING __be16 vlan_proto; u16 default_pvid; + u8 vlan_bridge_binding; struct net_bridge_vlan_group __rcu *vlgrp; #endif @@ -896,6 +897,10 @@ int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack); int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); void br_vlan_get_stats(const struct net_bridge_vlan *v, struct br_vlan_stats *stats); +void br_vlan_port_event(struct net_bridge_port *p, struct net_bridge *br, + unsigned long event); +void br_vlan_upper_change(struct net_device *dev, struct net_device *upper_dev, + bool linking); static inline struct net_bridge_vlan_group *br_vlan_group( const struct net_bridge *br) @@ -1079,6 +1084,18 @@ static inline void br_vlan_get_stats(const struct net_bridge_vlan *v, struct br_vlan_stats *stats) { } + +static inline void br_vlan_port_event(struct net_bridge_port *p, + struct net_bridge *br, + unsigned long event) +{ +} + +static inline void br_vlan_upper_change(struct net_device *dev, + struct net_device *upper_dev, + bool linking) +{ +} #endif struct nf_br_ops { diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 96abf8feb9dc..642373231386 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -1265,3 +1265,146 @@ int br_vlan_get_info(const struct net_device *dev, u16 vid, return 0; } EXPORT_SYMBOL_GPL(br_vlan_get_info); + +static int br_vlan_is_bind_vlan_dev(struct net_device *dev) +{ + return is_vlan_dev(dev) && + !!(vlan_dev_priv(dev)->flags & VLAN_FLAG_BRIDGE_BINDING); +} + +static int br_vlan_is_bind_vlan_dev_fn(struct net_device *dev, + __always_unused void *data) +{ + return br_vlan_is_bind_vlan_dev(dev); +} + +static int br_vlan_has_upper_bind_vlan_dev(struct net_device *dev) +{ + int found; + + rcu_read_lock(); + found = netdev_walk_all_upper_dev_rcu(dev, br_vlan_is_bind_vlan_dev_fn, + NULL); + rcu_read_unlock(); + + return found; +} + +struct br_vlan_bind_walk_data { + u16 vid; + struct net_device *result; +}; + +static int br_vlan_match_bind_vlan_dev_fn(struct net_device *dev, void *data_in) +{ + struct br_vlan_bind_walk_data *data = data_in; + int found = 0; + + if (br_vlan_is_bind_vlan_dev(dev) && + vlan_dev_priv(dev)->vlan_id == data->vid) { + dev_hold(dev); + data->result = dev; + found = 1; + } + + return found; +} + +/* If found, returns the vlan device with a reference held, else returns NULL. + */ +static struct net_device * +br_vlan_get_upper_bind_vlan_dev(struct net_device *dev, u16 vid) +{ + struct br_vlan_bind_walk_data data = { + .vid = vid, + }; + + rcu_read_lock(); + netdev_walk_all_upper_dev_rcu(dev, br_vlan_match_bind_vlan_dev_fn, + &data); + rcu_read_unlock(); + + return data.result; +} + +static bool br_vlan_is_dev_up(struct net_device *dev) +{ + return !!(dev->flags & IFF_UP) && netif_oper_up(dev); +} + +static void br_vlan_set_vlan_dev_state(struct net_bridge *br, + struct net_device *vlan_dev) +{ + u16 vid = vlan_dev_priv(vlan_dev)->vlan_id; + struct net_bridge_vlan_group *vg; + struct net_bridge_port *p; + bool has_carrier = false; + + list_for_each_entry(p, &br->port_list, list) { + vg = nbp_vlan_group(p); + if (br_vlan_find(vg, vid) && br_vlan_is_dev_up(p->dev)) { + has_carrier = true; + break; + } + } + + if (netif_carrier_ok(vlan_dev)) { + if (!has_carrier) + netif_carrier_off(vlan_dev); + } else { + if (has_carrier) + netif_carrier_on(vlan_dev); + } +} + +static void br_vlan_set_all_vlan_dev_state(struct net_bridge_port *p, + struct net_bridge *br) +{ + struct net_bridge_vlan_group *vg = nbp_vlan_group(p); + struct net_bridge_vlan *vlan; + struct net_device *vlan_dev; + + list_for_each_entry(vlan, &vg->vlan_list, vlist) { + vlan_dev = br_vlan_get_upper_bind_vlan_dev(br->dev, vlan->vid); + if (vlan_dev) { + if (br_vlan_is_dev_up(p->dev)) { + if (!netif_carrier_ok(vlan_dev)) + netif_carrier_on(vlan_dev); + } else { + br_vlan_set_vlan_dev_state(br, vlan_dev); + } + dev_put(vlan_dev); + } + } +} + +void br_vlan_upper_change(struct net_device *dev, struct net_device *upper_dev, + bool linking) +{ + struct net_bridge *br = netdev_priv(dev); + + if (!br_vlan_is_bind_vlan_dev(upper_dev)) + return; + + if (linking) { + br_vlan_set_vlan_dev_state(br, upper_dev); + br->vlan_bridge_binding = 1; + } else { + br->vlan_bridge_binding = br_vlan_has_upper_bind_vlan_dev(dev); + } +} + +void br_vlan_port_event(struct net_bridge_port *p, struct net_bridge *br, + unsigned long event) +{ + if (!br->vlan_bridge_binding) + return; + + switch (event) { + case NETDEV_CHANGE: + case NETDEV_DOWN: + case NETDEV_UP: + br_vlan_set_all_vlan_dev_state(p, br); + break; + } +} From patchwork Tue Apr 2 15:35:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Manning X-Patchwork-Id: 1074777 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vyatta.att-mail.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44YcZT2bswz9sQr for ; Wed, 3 Apr 2019 05:05:37 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729616AbfDBSFe (ORCPT ); Tue, 2 Apr 2019 14:05:34 -0400 Received: from mx0a-00191d01.pphosted.com ([67.231.149.140]:50544 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726582AbfDBSFe (ORCPT ); Tue, 2 Apr 2019 14:05:34 -0400 Received: from pps.filterd (m0049295.ppops.net [127.0.0.1]) by m0049295.ppops.net-00191d01. (8.16.0.27/8.16.0.27) with SMTP id x32FFsqD027022 for ; Tue, 2 Apr 2019 11:36:18 -0400 Received: from tlpd255.enaf.dadc.sbc.com (sbcsmtp3.sbc.com [144.160.112.28]) by m0049295.ppops.net-00191d01. with ESMTP id 2rm9tgsvkx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 02 Apr 2019 11:36:17 -0400 Received: from enaf.dadc.sbc.com (localhost [127.0.0.1]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32FaFtF027430 for ; Tue, 2 Apr 2019 10:36:16 -0500 Received: from zlp30493.vci.att.com (zlp30493.vci.att.com [135.46.181.176]) by tlpd255.enaf.dadc.sbc.com (8.14.5/8.14.5) with ESMTP id x32FaAjo027103 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 2 Apr 2019 10:36:10 -0500 Received: from zlp30493.vci.att.com (zlp30493.vci.att.com [127.0.0.1]) by zlp30493.vci.att.com (Service) with ESMTP id D9302400B57F for ; Tue, 2 Apr 2019 15:36:10 +0000 (GMT) Received: from clpi183.sldc.sbc.com (unknown [135.41.1.46]) by zlp30493.vci.att.com (Service) with ESMTP id BB78E400B579 for ; Tue, 2 Apr 2019 15:36:10 +0000 (GMT) Received: from sldc.sbc.com (localhost [127.0.0.1]) by clpi183.sldc.sbc.com (8.14.5/8.14.5) with ESMTP id x32FaABW029345 for ; Tue, 2 Apr 2019 10:36:10 -0500 Received: from mail.eng.vyatta.net (mail.eng.vyatta.net [10.156.50.82]) by clpi183.sldc.sbc.com (8.14.5/8.14.5) with ESMTP id x32Fa4IM028906 for ; Tue, 2 Apr 2019 10:36:04 -0500 Received: from MM-7520.eng.vyatta.net (unknown [10.156.47.86]) by mail.eng.vyatta.net (Postfix) with ESMTPA id B71E23600F5 for ; Tue, 2 Apr 2019 08:36:03 -0700 (PDT) From: Mike Manning To: netdev@vger.kernel.org Subject: [PATCH net-next 4/4] bridge: update vlan dev state when port added to or deleted from vlan Date: Tue, 2 Apr 2019 16:35:43 +0100 Message-Id: <20190402153543.6277-5-mmanning@vyatta.att-mail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> References: <20190402153543.6277-1-mmanning@vyatta.att-mail.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-02_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904020103 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If vlan bridge binding is enabled, then the link state of a vlan device that is an upper device of the bridge should track the state of bridge ports that are members of that vlan. So if a bridge port becomes or stops being a member of a vlan, then update the link state of the vlan device if necessary. Signed-off-by: Mike Manning --- net/bridge/br_vlan.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 642373231386..7c11607cf1f4 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -7,6 +7,9 @@ #include "br_private.h" #include "br_private_tunnel.h" +static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, + struct net_bridge *br, u16 vid); + static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg, const void *ptr) { @@ -294,6 +297,9 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, __vlan_add_list(v); __vlan_add_flags(v, flags); + + if (p) + nbp_vlan_set_vlan_dev_state(p, br, v->vid); out: return err; @@ -358,6 +364,8 @@ static int __vlan_del(struct net_bridge_vlan *v) rhashtable_remove_fast(&vg->vlan_hash, &v->vnode, br_vlan_rht_params); __vlan_del_list(v); + if (p) + nbp_vlan_set_vlan_dev_state(p, p->br, v->vid); call_rcu(&v->rcu, nbp_vlan_rcu_free); } @@ -1357,6 +1365,21 @@ static void br_vlan_set_vlan_dev_state(struct net_bridge *br, } } +static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, + struct net_bridge *br, u16 vid) +{ + struct net_device *vlan_dev; + + if (!br->vlan_bridge_binding) + return; + + vlan_dev = br_vlan_get_upper_bind_vlan_dev(br->dev, vid); + if (vlan_dev) { + br_vlan_set_vlan_dev_state(br, vlan_dev); + dev_put(vlan_dev); + } +} + static void br_vlan_set_all_vlan_dev_state(struct net_bridge_port *p, struct net_bridge *br) {