Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/806154/?format=api
{ "id": 806154, "url": "http://patchwork.ozlabs.org/api/1.2/patches/806154/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1503780970-10312-4-git-send-email-andrew@lunn.ch/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/1.2/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1503780970-10312-4-git-send-email-andrew@lunn.ch>", "list_archive_url": null, "date": "2017-08-26T20:56:08", "name": "[RFC,WIP,3/5] net: bridge: Make the brX interface a member of the bridge", "commit_ref": null, "pull_url": null, "state": "rfc", "archived": true, "hash": "b321929351b8a3043832478e1cb4df6e34747966", "submitter": { "id": 13608, "url": "http://patchwork.ozlabs.org/api/1.2/people/13608/?format=api", "name": "Andrew Lunn", "email": "andrew@lunn.ch" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/1.2/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1503780970-10312-4-git-send-email-andrew@lunn.ch/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/806154/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/806154/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xfr4C26Vmz9s8V\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSun, 27 Aug 2017 06:59:07 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751143AbdHZU7F (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tSat, 26 Aug 2017 16:59:05 -0400", "from vps0.lunn.ch ([178.209.37.122]:45158 \"EHLO vps0.lunn.ch\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751083AbdHZU7E (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tSat, 26 Aug 2017 16:59:04 -0400", "from andrew by vps0.lunn.ch with local (Exim 4.84_2)\n\t(envelope-from <andrew@lunn.ch>)\n\tid 1dli8H-0002hI-CT; Sat, 26 Aug 2017 22:56:41 +0200" ], "From": "Andrew Lunn <andrew@lunn.ch>", "To": "netdev <netdev@vger.kernel.org>", "Cc": "Vivien Didelot <vivien.didelot@savoirfairelinux.com>,\n\tFlorian Fainelli <f.fainelli@gmail.com>,\n\tnikolay@cumulusnetworks.com, jiri@mellanox.com,\n\troopa@cumulusnetworks.com, stephen@networkplumber.org,\n\tbridge@lists.linux-foundation.org, Andrew Lunn <andrew@lunn.ch>", "Subject": "[PATCH RFC WIP 3/5] net: bridge: Make the brX interface a member of\n\tthe bridge", "Date": "Sat, 26 Aug 2017 22:56:08 +0200", "Message-Id": "<1503780970-10312-4-git-send-email-andrew@lunn.ch>", "X-Mailer": "git-send-email 2.1.4", "In-Reply-To": "<1503780970-10312-1-git-send-email-andrew@lunn.ch>", "References": "<1503780970-10312-1-git-send-email-andrew@lunn.ch>", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "In order to perform IGMP snooping on the brX interface, it has to be\npart of the bridge, so that the code snooping on normal bridge ports\nkeeps track of IGMP joins and leaves.\n\nWhen the brX interface is opened, add the interface to the bridge.\nWhen the brX interface is closed, remove it from the bridge.\n\nThis port does however need some special handling. So add a bridge\nport flag, BR_SOFT_INTERFACE, indicating a port is the sort interface\nof the bridge.\n\nWhen the port is added to the bridge, the netdev for this port cannot\nbe linked to the master device, since it is the master device.\nSimilarly when removing the port, it cannot be unlinked from the\nmaster device.\n\nWith the brX interface now being a member of the bridge, and having\nall associated structures, we can process IGMP messages sent by the\ninterface. This is done by the br_multicast_rcv() function, which\ntakes the bridge_port structure as a parameter. This cannot be easily\nfound, so keep track of it in the net_bridge structure.\n---\n include/linux/if_bridge.h | 1 +\n net/bridge/br_device.c | 12 ++++++++++--\n net/bridge/br_if.c | 37 ++++++++++++++++++++++++-------------\n net/bridge/br_mdb.c | 2 --\n net/bridge/br_multicast.c | 7 ++++---\n net/bridge/br_private.h | 1 +\n 6 files changed, 40 insertions(+), 20 deletions(-)", "diff": "diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h\nindex 3cd18ac0697f..8a03821d1827 100644\n--- a/include/linux/if_bridge.h\n+++ b/include/linux/if_bridge.h\n@@ -49,6 +49,7 @@ struct br_ip_list {\n #define BR_MULTICAST_TO_UNICAST\tBIT(12)\n #define BR_VLAN_TUNNEL\t\tBIT(13)\n #define BR_BCAST_FLOOD\t\tBIT(14)\n+#define BR_SOFT_INTERFACE\tBIT(15)\n \n #define BR_DEFAULT_AGEING_TIME\t(300 * HZ)\n \ndiff --git a/net/bridge/br_device.c b/net/bridge/br_device.c\nindex 861ae2a165f4..f27ca62fd4a5 100644\n--- a/net/bridge/br_device.c\n+++ b/net/bridge/br_device.c\n@@ -69,7 +69,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)\n \t\t\tbr_flood(br, skb, BR_PKT_MULTICAST, false, true);\n \t\t\tgoto out;\n \t\t}\n-\t\tif (br_multicast_rcv(br, NULL, skb, vid)) {\n+\t\tif (br_multicast_rcv(br, br->local_port, skb, vid)) {\n \t\t\tkfree_skb(skb);\n \t\t\tgoto out;\n \t\t}\n@@ -133,6 +133,14 @@ static void br_dev_uninit(struct net_device *dev)\n static int br_dev_open(struct net_device *dev)\n {\n \tstruct net_bridge *br = netdev_priv(dev);\n+\tint err;\n+\n+\terr = br_add_if(br, br->dev);\n+\tif (err)\n+\t\treturn err;\n+\n+\tbr->local_port = list_first_or_null_rcu(&br->port_list,\n+\t\t\t\t\t\tstruct net_bridge_port, list);\n \n \tnetdev_update_features(dev);\n \tnetif_start_queue(dev);\n@@ -161,7 +169,7 @@ static int br_dev_stop(struct net_device *dev)\n \n \tnetif_stop_queue(dev);\n \n-\treturn 0;\n+\treturn br_del_if(br, br->dev);\n }\n \n static void br_get_stats64(struct net_device *dev,\ndiff --git a/net/bridge/br_if.c b/net/bridge/br_if.c\nindex f3aef22931ab..49208e774191 100644\n--- a/net/bridge/br_if.c\n+++ b/net/bridge/br_if.c\n@@ -284,7 +284,8 @@ static void del_nbp(struct net_bridge_port *p)\n \n \tnbp_update_port_count(br);\n \n-\tnetdev_upper_dev_unlink(dev, br->dev);\n+\tif (!(p->flags & BR_SOFT_INTERFACE))\n+\t\tnetdev_upper_dev_unlink(dev, br->dev);\n \n \tdev->priv_flags &= ~IFF_BRIDGE_PORT;\n \n@@ -362,6 +363,8 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,\n \tp->priority = 0x8000 >> BR_PORT_BITS;\n \tp->port_no = index;\n \tp->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;\n+\tif (br->dev == dev)\n+\t\tp->flags |= BR_SOFT_INTERFACE;\n \tbr_init_port(p);\n \tbr_set_state(p, BR_STATE_DISABLED);\n \tbr_stp_port_timer_init(p);\n@@ -500,8 +503,11 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)\n \t\treturn -EINVAL;\n \n \t/* No bridging of bridges */\n-\tif (dev->netdev_ops->ndo_start_xmit == br_dev_xmit)\n-\t\treturn -ELOOP;\n+\tif (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) {\n+\t\t/* Unless it is our own soft interface */\n+\t\tif (br->dev != dev)\n+\t\t\treturn -ELOOP;\n+\t}\n \n \t/* Device is already being bridged */\n \tif (br_port_exists(dev))\n@@ -540,9 +546,11 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)\n \n \tdev->priv_flags |= IFF_BRIDGE_PORT;\n \n-\terr = netdev_master_upper_dev_link(dev, br->dev, NULL, NULL);\n-\tif (err)\n-\t\tgoto err5;\n+\tif (!(p->flags & BR_SOFT_INTERFACE)) {\n+\t\terr = netdev_master_upper_dev_link(dev, br->dev, NULL, NULL);\n+\t\tif (err)\n+\t\t\tgoto err5;\n+\t}\n \n \terr = nbp_switchdev_mark_set(p);\n \tif (err)\n@@ -563,13 +571,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)\n \telse\n \t\tnetdev_set_rx_headroom(dev, br_hr);\n \n-\tif (br_fdb_insert(br, p, dev->dev_addr, 0))\n-\t\tnetdev_err(dev, \"failed insert local address bridge forwarding table\\n\");\n+\tif (!(p->flags & BR_SOFT_INTERFACE)) {\n+\t\tif (br_fdb_insert(br, p, dev->dev_addr, 0))\n+\t\t\tnetdev_err(dev, \"failed insert local address bridge forwarding table\\n\");\n \n-\terr = nbp_vlan_init(p);\n-\tif (err) {\n-\t\tnetdev_err(dev, \"failed to initialize vlan filtering on this port\\n\");\n-\t\tgoto err7;\n+\t\terr = nbp_vlan_init(p);\n+\t\tif (err) {\n+\t\t\tnetdev_err(dev, \"failed to initialize vlan filtering on this port\\n\");\n+\t\t\tgoto err7;\n+\t\t}\n \t}\n \n \tspin_lock_bh(&br->lock);\n@@ -597,7 +607,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)\n \tbr_fdb_delete_by_port(br, p, 0, 1);\n \tnbp_update_port_count(br);\n err6:\n-\tnetdev_upper_dev_unlink(dev, br->dev);\n+\tif (!(p->flags & BR_SOFT_INTERFACE))\n+\t\tnetdev_upper_dev_unlink(dev, br->dev);\n err5:\n \tdev->priv_flags &= ~IFF_BRIDGE_PORT;\n \tnetdev_rx_handler_unregister(dev);\ndiff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c\nindex a0b11e7d67d9..47f0d9b4221d 100644\n--- a/net/bridge/br_mdb.c\n+++ b/net/bridge/br_mdb.c\n@@ -117,8 +117,6 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,\n \t\t\t\tstruct br_mdb_entry e;\n \n \t\t\t\tport = p->port;\n-\t\t\t\tif (!port)\n-\t\t\t\t\tcontinue;\n \n \t\t\t\tmemset(&e, 0, sizeof(e));\n \t\t\t\te.ifindex = port->dev->ifindex;\ndiff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c\nindex dae3af1f531a..f1bf9ec15de8 100644\n--- a/net/bridge/br_multicast.c\n+++ b/net/bridge/br_multicast.c\n@@ -915,7 +915,7 @@ static void __br_multicast_send_query(struct net_bridge *br,\n \tif (!skb)\n \t\treturn;\n \n-\tif (port) {\n+\tif (port && !(port->flags & BR_SOFT_INTERFACE)) {\n \t\tskb->dev = port->dev;\n \t\tbr_multicast_count(br, port, skb, igmp_type,\n \t\t\t\t BR_MCAST_DIR_TX);\n@@ -944,8 +944,9 @@ static void br_multicast_send_query(struct net_bridge *br,\n \n \tmemset(&br_group.u, 0, sizeof(br_group.u));\n \n-\tif (port ? (own_query == &port->ip4_own_query) :\n-\t\t (own_query == &br->ip4_own_query)) {\n+\tif (port && !(port->flags & BR_SOFT_INTERFACE) ?\n+\t (own_query == &port->ip4_own_query) :\n+\t (own_query == &br->ip4_own_query)) {\n \t\tother_query = &br->ip4_other_query;\n \t\tbr_group.proto = htons(ETH_P_IP);\n #if IS_ENABLED(CONFIG_IPV6)\ndiff --git a/net/bridge/br_private.h b/net/bridge/br_private.h\nindex fd9ee73e0a6d..c4b99a35abb0 100644\n--- a/net/bridge/br_private.h\n+++ b/net/bridge/br_private.h\n@@ -296,6 +296,7 @@ struct net_bridge {\n \tspinlock_t\t\t\tlock;\n \tspinlock_t\t\t\thash_lock;\n \tstruct list_head\t\tport_list;\n+\tstruct net_bridge_port\t\t*local_port;\n \tstruct net_device\t\t*dev;\n \tstruct pcpu_sw_netstats\t\t__percpu *stats;\n \t/* These fields are accessed on each packet */\n", "prefixes": [ "RFC", "WIP", "3/5" ] }