* Re: KASAN: use-after-free Read in tcf_block_find
From: Cong Wang @ 2018-09-26 21:44 UTC (permalink / raw)
To: syzbot+37b8770e6d5a8220a039
Cc: David Miller, Jamal Hadi Salim, Jiri Pirko, LKML,
Linux Kernel Network Developers, syzkaller-bugs
In-Reply-To: <00000000000084e2450576c817cc@google.com>
On Wed, Sep 26, 2018 at 8:44 AM syzbot
<syzbot+37b8770e6d5a8220a039@syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit: 4b1bd6976945 net: phy: marvell: Fix build.
> git tree: net-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=16f763fa400000
> kernel config: https://syzkaller.appspot.com/x/.config?x=443816db871edd66
> dashboard link: https://syzkaller.appspot.com/bug?extid=37b8770e6d5a8220a039
> compiler: gcc (GCC) 8.0.1 20180413 (experimental)
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=17a5614e400000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=141a532a400000
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+37b8770e6d5a8220a039@syzkaller.appspotmail.com
>
> IPv6: ADDRCONF(NETDEV_CHANGE): veth0: link becomes ready
> 8021q: adding VLAN 0 to HW filter on device team0
> ==================================================================
> BUG: KASAN: use-after-free in tcf_block_find+0x9d1/0xb90
> net/sched/cls_api.c:646
> Read of size 4 at addr ffff8801cc126978 by task syz-executor002/5646
>
> CPU: 1 PID: 5646 Comm: syz-executor002 Not tainted 4.19.0-rc5+ #232
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> Call Trace:
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113
> print_address_description.cold.8+0x9/0x1ff mm/kasan/report.c:256
> kasan_report_error mm/kasan/report.c:354 [inline]
> kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412
> __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:432
> tcf_block_find+0x9d1/0xb90 net/sched/cls_api.c:646
Hmm. looks like missing a rcu_dereference() here:
if (!*parent) {
*q = dev->qdisc;
*parent = (*q)->handle;
^ permalink raw reply
* Re: [PATCH net-next v3 09/11] dt-bindings: add constants for Microsemi Ocelot SerDes driver
From: Rob Herring @ 2018-09-26 21:36 UTC (permalink / raw)
To: Quentin Schulz
Cc: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, kishon, andrew, f.fainelli, allan.nielsen,
linux-mips, devicetree, linux-kernel, netdev, thomas.petazzoni,
Quentin Schulz
In-Reply-To: <73113ea4b3d8d34c05d88413b3d15cc1733cf25e.1536912834.git-series.quentin.schulz@bootlin.com>
On Fri, 14 Sep 2018 10:16:07 +0200, Quentin Schulz wrote:
> The Microsemi Ocelot has multiple SerDes and requires that the SerDes be
> muxed accordingly to the hardware representation.
>
> Let's add a constant for each SerDes available in the Microsemi Ocelot.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---
> include/dt-bindings/phy/phy-ocelot-serdes.h | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
> create mode 100644 include/dt-bindings/phy/phy-ocelot-serdes.h
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH net-next v3 07/11] dt-bindings: phy: add DT binding for Microsemi Ocelot SerDes muxing
From: Rob Herring @ 2018-09-26 21:35 UTC (permalink / raw)
To: Quentin Schulz
Cc: alexandre.belloni, ralf, paul.burton, jhogan, mark.rutland, davem,
kishon, andrew, f.fainelli, allan.nielsen, linux-mips, devicetree,
linux-kernel, netdev, thomas.petazzoni
In-Reply-To: <f392dafca9165800439fc09cd7d16e6a9506d457.1536912834.git-series.quentin.schulz@bootlin.com>
On Fri, Sep 14, 2018 at 10:16:05AM +0200, Quentin Schulz wrote:
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---
> Documentation/devicetree/bindings/phy/phy-ocelot-serdes.txt | 40 +++++++-
> 1 file changed, 40 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/phy-ocelot-serdes.txt
>
> diff --git a/Documentation/devicetree/bindings/phy/phy-ocelot-serdes.txt b/Documentation/devicetree/bindings/phy/phy-ocelot-serdes.txt
> new file mode 100644
> index 0000000..2a88cc3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/phy-ocelot-serdes.txt
> @@ -0,0 +1,40 @@
> +Microsemi Ocelot SerDes muxing driver
> +-------------------------------------
> +
> +On Microsemi Ocelot, there is a handful of registers in HSIO address
> +space for setting up the SerDes to switch port muxing.
> +
> +A SerDes X can be "muxed" to work with switch port Y or Z for example.
> +One specific SerDes can also be used as a PCIe interface.
> +
> +Hence, a SerDes represents an interface, be it an Ethernet or a PCIe one.
> +
> +There are two kinds of SerDes: SERDES1G supports 10/100Mbps in
> +half/full-duplex and 1000Mbps in full-duplex mode while SERDES6G supports
> +10/100Mbps in half/full-duplex and 1000/2500Mbps in full-duplex mode.
> +
> +Also, SERDES6G number (aka "macro") 0 is the only interface supporting
> +QSGMII.
> +
> +Required properties:
> +
> +- compatible: should be "mscc,vsc7514-serdes"
> +- #phy-cells : from the generic phy bindings, must be 2.
> + The first number defines the input port to use for a given
> + SerDes macro. The second defines the macro to use. They are
> + defined in dt-bindings/phy/phy-ocelot-serdes.h
You need to define what this is a child of.
> +
> +Example:
> +
> + serdes: serdes {
> + compatible = "mscc,vsc7514-serdes";
> + #phy-cells = <2>;
However, if there are no other resources associated with this, then you
don't even need this child node. The parent can be a phy provider and
provider of other functions too.
> + };
> +
> + ethernet {
> + port1 {
> + phy-handle = <&phy_foo>;
> + /* Link SERDES1G_5 to port1 */
> + phys = <&serdes 1 SERDES1G_5>;
> + };
> + };
> --
> git-series 0.9.1
^ permalink raw reply
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'.
From: Stephen Hemminger @ 2018-09-26 15:02 UTC (permalink / raw)
To: David Ahern
Cc: Jiri Benc, Christian Brauner, netdev@vger.kernel.org,
David Miller
In-Reply-To: <7ffc4951-0d2e-5bf1-8d64-62ae5d6bc477@gmail.com>
On Wed, 26 Sep 2018 08:54:43 -0600
David Ahern <dsahern@gmail.com> wrote:
> On 9/25/18 11:51 PM, Jiri Benc wrote:
> > On Tue, 25 Sep 2018 09:37:41 -0600, David Ahern wrote:
> >> For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side
> >> so this should be ok.
> >
> > Does the existing user space set ifi_type to anything? Does it zero out
> > the field?
> >
> > Are we able to find a flag value that is not going to be set by unaware
> > user space? I.e., a bit that is unused by the current ARPHRD values on
> > both little and big endian? (ARPHRD_NONE might be a problem, though...)
>
> The goal is for userpsace to pass something to the kernel to
> definitively state which header is used.
>
You can not safely assume anything about older code.
iproute2 is not the only thing using the API, others include Quagga, and other tools.
Sorry, this API is frozen.
^ permalink raw reply
* Re: [PATCH net-next 2/9] net: bridge: add bitfield for options and convert vlan opts
From: Andrew Lunn @ 2018-09-26 15:01 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, roopa, davem, stephen, bridge
In-Reply-To: <e5b4f87d-c665-9476-c9d3-a7254394c13f@cumulusnetworks.com>
On Wed, Sep 26, 2018 at 05:55:47PM +0300, Nikolay Aleksandrov wrote:
> On 26/09/18 17:48, Andrew Lunn wrote:
> > Hi Nikolay
> >
> >> struct net_bridge {
> >> spinlock_t lock;
> >> spinlock_t hash_lock;
> >> struct list_head port_list;
> >> struct net_device *dev;
> >> struct pcpu_sw_netstats __percpu *stats;
> >> + unsigned long options;
> >
> > Maybe a u32 would be better, so we run out of bits at the same time on
> > 32 and 64 bit systems?
> >
> > Andrew
> >
>
> Bitops operate on an unsigned long, I actually had a BUILD_BUG_ON() for
> 32 bits initially, but checked other places and they seem to be using it
> as-is without any checks so I decided to leave it as well (e.g.
> sock_flags).
O.K.
I assume we get compiler warnings anyway, when we use bit 32 on a
32bit system. The build-bots should let us know.
Andrew
^ permalink raw reply
* Re: [PATCH net-next 2/9] net: bridge: add bitfield for options and convert vlan opts
From: Nikolay Aleksandrov @ 2018-09-26 14:55 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, roopa, davem, stephen, bridge
In-Reply-To: <20180926144808.GM1676@lunn.ch>
On 26/09/18 17:48, Andrew Lunn wrote:
> Hi Nikolay
>
>> struct net_bridge {
>> spinlock_t lock;
>> spinlock_t hash_lock;
>> struct list_head port_list;
>> struct net_device *dev;
>> struct pcpu_sw_netstats __percpu *stats;
>> + unsigned long options;
>
> Maybe a u32 would be better, so we run out of bits at the same time on
> 32 and 64 bit systems?
>
> Andrew
>
Bitops operate on an unsigned long, I actually had a BUILD_BUG_ON() for
32 bits initially, but checked other places and they seem to be using it
as-is without any checks so I decided to leave it as well (e.g.
sock_flags).
^ permalink raw reply
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'.
From: David Ahern @ 2018-09-26 14:54 UTC (permalink / raw)
To: Jiri Benc; +Cc: Christian Brauner, netdev@vger.kernel.org, David Miller
In-Reply-To: <20180926075115.4ca7c527@redhat.com>
On 9/25/18 11:51 PM, Jiri Benc wrote:
> On Tue, 25 Sep 2018 09:37:41 -0600, David Ahern wrote:
>> For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side
>> so this should be ok.
>
> Does the existing user space set ifi_type to anything? Does it zero out
> the field?
>
> Are we able to find a flag value that is not going to be set by unaware
> user space? I.e., a bit that is unused by the current ARPHRD values on
> both little and big endian? (ARPHRD_NONE might be a problem, though...)
The goal is for userpsace to pass something to the kernel to
definitively state which header is used.
ifaddrmsg (proper header and one Christian's patch wants to use) is 8
bytes; ifinfomsg (legacy header from broken userspace) is 16. If you can
not trust that ifi_type is currently 0 on a dump request then you can
not trust ifi_flags to be correct or ifi_change to be correct and so you
can not move past the header and parse attributes. If that is the case
we are done - Christian's patches should be reverted as you can never
trust what is beyond the family entry.
But I do not believe that to be the case because of the route dump
analogy. As I mentioned route dumps have the same problem: sometimes
ifinfomsg is passed and sometimes rtmsg. Yet the kernel always looks at
rtm_flags.
In terms of which field to use the most logical to me is to pass in a
flag. Current address dumps have no reason to pass in a flag so it is
not like the field can be misinterpreted. ifa_flags is a single byte so
are there really endian issues to worry about?
^ permalink raw reply
* Re: [PATCH net-next 2/9] net: bridge: add bitfield for options and convert vlan opts
From: Andrew Lunn @ 2018-09-26 14:48 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, roopa, davem, stephen, bridge
In-Reply-To: <20180926121802.27851-3-nikolay@cumulusnetworks.com>
Hi Nikolay
> struct net_bridge {
> spinlock_t lock;
> spinlock_t hash_lock;
> struct list_head port_list;
> struct net_device *dev;
> struct pcpu_sw_netstats __percpu *stats;
> + unsigned long options;
Maybe a u32 would be better, so we run out of bits at the same time on
32 and 64 bit systems?
Andrew
^ permalink raw reply
* Re: [PATCH 3/5] ixgbe: add AF_XDP zero-copy Rx support
From: Björn Töpel @ 2018-09-26 14:29 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Jeff Kirsher, intel-wired-lan, Björn Töpel,
Karlsson, Magnus, Magnus Karlsson, ast, Daniel Borkmann, Netdev,
Jesper Dangaard Brouer, William Tu, tuc
In-Reply-To: <20180925075714.75db73ac@cakuba.netronome.com>
Den tis 25 sep. 2018 kl 16:57 skrev Jakub Kicinski
<jakub.kicinski@netronome.com>:
>
> On Mon, 24 Sep 2018 18:35:55 +0200, Björn Töpel wrote:
> > + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
> > + return -EINVAL;
> > +
> > + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
> > + return -EINVAL;
>
> Hm, should you add UMEM checks to all the places these may get
> enabled? Like fabf1bce103a ("ixgbe: Prevent unsupported configurations
> with XDP") did?
Actually, I can remove these checks, since it's already checked by the
XDP path. AF_XDP ZC is enabled only when XDP is enabled. So there's no
need to have the XDP checks in the AF_XDP path.
Björn
^ permalink raw reply
* KMSAN: uninit-value in __dev_mc_add
From: syzbot @ 2018-09-26 14:24 UTC (permalink / raw)
To: davem, edumazet, linux-kernel, netdev, sunlw.fnst, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: eb2e67596de2 kmsan: minor code cleanup
git tree: https://github.com/google/kmsan.git/master
console output: https://syzkaller.appspot.com/x/log.txt?x=136e3b11400000
kernel config: https://syzkaller.appspot.com/x/.config?x=94a9ed72288f7fef
dashboard link: https://syzkaller.appspot.com/bug?extid=001516d86dbe88862cec
compiler: clang version 8.0.0 (trunk 339414)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+001516d86dbe88862cec@syzkaller.appspotmail.com
==================================================================
BUG: KMSAN: uninit-value in memcmp+0x11d/0x180 lib/string.c:863
CPU: 0 PID: 14033 Comm: kworker/0:3 Not tainted 4.19.0-rc4+ #58
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: ipv6_addrconf addrconf_dad_work
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x2f6/0x430 lib/dump_stack.c:113
kmsan_report+0x183/0x2b0 mm/kmsan/kmsan.c:917
__msan_warning+0x70/0xc0 mm/kmsan/kmsan_instr.c:500
memcmp+0x11d/0x180 lib/string.c:863
__hw_addr_add_ex net/core/dev_addr_lists.c:61 [inline]
__dev_mc_add+0x215/0x8c0 net/core/dev_addr_lists.c:670
dev_mc_add+0x6d/0x80 net/core/dev_addr_lists.c:687
igmp6_group_added+0x2c8/0xaa0 net/ipv6/mcast.c:676
__ipv6_dev_mc_inc+0xf4b/0x1270 net/ipv6/mcast.c:934
ipv6_dev_mc_inc+0x70/0x80 net/ipv6/mcast.c:941
addrconf_join_solict net/ipv6/addrconf.c:2098 [inline]
addrconf_dad_begin net/ipv6/addrconf.c:3879 [inline]
addrconf_dad_work+0x437/0x29b0 net/ipv6/addrconf.c:4006
process_one_work+0x197f/0x2490 kernel/workqueue.c:2153
worker_thread+0x1f6a/0x2b00 kernel/workqueue.c:2296
kthread+0x59c/0x5d0 kernel/kthread.c:247
ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:416
Local variable description: ----buf@igmp6_group_added
Variable was created at:
igmp6_group_added+0x46/0xaa0 net/ipv6/mcast.c:664
__ipv6_dev_mc_inc+0xf4b/0x1270 net/ipv6/mcast.c:934
==================================================================
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with
syzbot.
^ permalink raw reply
* Re: [PATCH net-next] net: ti: fix return type of ndo_start_xmit function
From: Grygorii Strashko @ 2018-09-26 20:36 UTC (permalink / raw)
To: David Miller, yuehaibing
Cc: f.fainelli, w-kwok2, m-karicheri2, lukas, bgolaszewski,
ivan.khoronzhuk, dan.carpenter, linux-kernel, netdev, linux-omap
In-Reply-To: <20180926.101733.2070254569725987062.davem@davemloft.net>
Hi All,
On 09/26/2018 12:17 PM, David Miller wrote:
> From: YueHaibing <yuehaibing@huawei.com>
> Date: Wed, 26 Sep 2018 17:09:51 +0800
>
>> @@ -1290,7 +1291,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>> dev_warn(netcp->ndev_dev, "padding failed (%d), packet dropped\n",
>> ret);
>> tx_stats->tx_dropped++;
>> - return ret;
>> + return NETDEV_TX_BUSY;
>> }
>> skb->len = NETCP_MIN_PACKET_SIZE;
>> }
>> @@ -1298,7 +1299,6 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>> desc = netcp_tx_map_skb(skb, netcp);
>> if (unlikely(!desc)) {
>> netif_stop_subqueue(ndev, subqueue);
>> - ret = -ENOBUFS;
>> goto drop;
>> }
>>
>> @@ -1319,7 +1319,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>> if (desc)
>> netcp_free_tx_desc_chain(netcp, desc, sizeof(*desc));
>> dev_kfree_skb(skb);
>> - return ret;
>> + return NETDEV_TX_BUSY;
>> }
>
> These conversions are not correct.
>
> If the driver frees the SKB you must not return NETDEV_TX_BUSY.
>
> NETDEV_TX_BUSY tells the caller that the driver could not process the
> packet and that it should reqeueu up the SKB and try again later when
> there is more TX queue room.
>
Sry, but I still do not understand the reason for these changes (as I asked already [1])
May be there are some patches on the fly or long term decisions were made in this area.
According to the code include/linux/netdevice.h the .ndo_start_xmit() can return 3 type of values
1) enum netdev_tx, expected to be used by regular netdev drivers, but
2) "error while transmitting (rc < 0)" is also acceptable values
3) NET_XMIT_SUCCESS/DROP/CN (qdisc ->enqueue() return codes) for Virtual network devices
So, are there plans to move NET_XMIT_XXX in enum?
or any patches to change include/linux/netdevice.h "Transmit return codes:" section?
Not sure, that blindly following coccinelle recommendations is a good
choice in this particular case.
[1] https://lkml.org/lkml/2018/9/20/881
--
regards,
-grygorii
^ permalink raw reply
* Re: [PATCH] netlink: add policy attribute range validation
From: Johannes Berg @ 2018-09-26 20:35 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1537993066.28767.29.camel-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
On Wed, 2018-09-26 at 22:17 +0200, Johannes Berg wrote:
> On Wed, 2018-09-26 at 22:06 +0200, Johannes Berg wrote:
> > From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> >
> > Without further bloating the policy structs, we can overload
> > the `validation_data' pointer with a struct of s16 min, max
> > and use those to validate ranges in NLA_{U,S}{8,16,32,64}
> > attributes.
> >
> > It may sound strange to validate NLA_U32 with a s16 max, but
> > in many cases NLA_U32 is used for enums etc. since there's no
> > size benefit in using a smaller attribute width anyway, due
> > to netlink attribute alignment; in cases like that it's still
> > useful, particularly when the attribute really transports an
> > enum value.
>
> That said, I did find a few places where we could benefit from a larger
> type here - e.g. having a NLA_U16 that must be non-zero cannot be
> represented in the policy as is, since you can't set max to 65535.
We could also fix that, btw, by taking two bits out of the "type" field,
and letting those indicate "check_min" and "check_max". That would also
fix the other thing I noted regarding the union, I suppose.
I didn't really like that too much because it makes the whole thing far
more complex, but perhaps if we hide it behind macros like
#define NLA_POLICY_RANGE(tp, _min, _max) {
.type = tp,
.min = _min, .check_min = 1,
.max = _max, .check_max = 1,
}
#define NLA_POLICY_MIN(tp, _min) {
.type = tp,
.min = _min, .check_min = 1,
}
#define NLA_POLICY_MAX(tp, _max) {
.type = tp,
.max = _max, .check_max = 1,
}
it becomes more palatable?
johannes
^ permalink raw reply
* Re: [PATCH stable 4.4 V2 0/6] fix SegmentSmack in stable branch (CVE-2018-5390)
From: Greg KH @ 2018-09-26 20:21 UTC (permalink / raw)
To: maowenan; +Cc: netdev, dwmw2, eric.dumazet, davem, stable, linux-kernel
In-Reply-To: <83856420-af5a-e469-5b5b-e24634fc290f@huawei.com>
On Tue, Sep 25, 2018 at 10:10:15PM +0800, maowenan wrote:
> Hi Greg:
>
> can you review this patch set?
It is still in the queue, don't worry. It will take some more time to
properly review and test it.
Ideally you could get someone else to test this and provide a
"tested-by:" tag for it?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH net-next v2 0/9] net: bridge: convert bool options to bits
From: Nikolay Aleksandrov @ 2018-09-26 14:04 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
On 26/09/18 17:00, Nikolay Aleksandrov wrote:
> Hi,
> A lot of boolean bridge options have been added around the net_bridge
> structure resulting in holes and more importantly different cache lines
> that need to be fetched in the fast path. This set moves all of those
> to bits in a bitfield which resides in a hot cache line thus reducing
> the size of net_bridge, the number of holes and the number of cache
> lines needed for the fast path.
> The set is also sent in preparation for new boolean options to avoid
> spreading them in the structure and making new holes.
> One nice side-effect is that we avoid potential race conditions by using
> the bitops since some of the options were bits being directly set in
> parallel risking hard to debug issues (has_ipv6_addr).
>
> Before:
> size: 1184, holes: 8, sum holes: 30
> After:
> size: 1160, holes: 3, sum holes: 7
>
> Patch 01 is a trivial style fix
> Patch 02 adds the new options bitfield and converts the vlan boolean
> options to bits
> Patches 03-08 convert the rest of the boolean options to bits
> Patch 09 re-arranges a few fields in net_bridge to further reduce size
>
> v2: patch 09: remove the comment about offload_fwd_mark in net_bridge and
> leave it in the last 4 bytes, thanks to Ido for spotting it
And obviously it's not in the last 4 bytes, but that's fine. That
must've said just: "leave it where it is now".
>
> Stephen, I've added your reviewed-by in patches 01-08, only removed it
> from patch 09 as the patch has changed.
>
> Thanks,
> Nik
>
^ permalink raw reply
* Re: [PATCH net-next v6 07/23] zinc: ChaCha20 ARM and ARM64 implementations
From: Ard Biesheuvel @ 2018-09-26 14:02 UTC (permalink / raw)
To: Jason A. Donenfeld, Herbert Xu, Thomas Gleixner
Cc: Linux Kernel Mailing List, <netdev@vger.kernel.org>,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE, David S. Miller,
Greg Kroah-Hartman, Samuel Neves, Andy Lutomirski,
Jean-Philippe Aumasson, Russell King, linux-arm-kernel
In-Reply-To: <CAHmME9r9KppoFwwNVpzpYbU+9dCPzb7Pit+4iRa4MY_ouJBWrA@mail.gmail.com>
(+ Herbert, Thomas)
On Wed, 26 Sep 2018 at 15:33, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
>
> Hi Ard,
>
> On Wed, Sep 26, 2018 at 10:59 AM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
> > > +static inline bool chacha20_arch(struct chacha20_ctx *state, u8 *dst,
> > > + const u8 *src, size_t len,
> > > + simd_context_t *simd_context)
> > > +{
> > > +#if defined(CONFIG_KERNEL_MODE_NEON)
> > > + if (chacha20_use_neon && len >= CHACHA20_BLOCK_SIZE * 3 &&
> > > + simd_use(simd_context))
> > > + chacha20_neon(dst, src, len, state->key, state->counter);
> > > + else
> > > +#endif
> >
> > Better to use IS_ENABLED() here:
> >
> > > + if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON)) &&
> > > + chacha20_use_neon && len >= CHACHA20_BLOCK_SIZE * 3 &&
> > > + simd_use(simd_context))
>
> Good idea. I'll fix that up.
>
> >
> > Also, this still has unbounded worst case scheduling latency, given
> > that the outer library function passes its entire input straight into
> > the NEON routine.
>
> The vast majority of crypto routines in arch/*/crypto/ follow this
> same exact pattern, actually. I realize a few don't -- probably the
> ones you had a hand in :) -- but I think this is up to the caller to
> handle.
Anything that uses the scatterwalk API (AEADs and skciphers) will
handle at most a page at a time. Hashes are different, which is why
some of them have to handle it explicitly.
> I made a change so that in chacha20poly1305.c, it calls
> simd_relax after handling each scatter-gather element, so a
> "construction" will handle this gracefully. But I believe it's up to
> the caller to decide on what sizes of information it wants to pass to
> primitives. Put differently, this also hasn't ever been an issue
> before -- the existing state of the tree indicates this -- and so I
> don't anticipate this will be a real issue now.
The state of the tree does not capture all relevant context or
history. The scheduling latency issue was brought up very recently by
the -rt folks on the mailing lists.
> And if it becomes one,
> this is something we can address *later*, but certainly there's no use
> of adding additional complexity to the initial patchset to do this
> now.
>
You are introducing a very useful SIMD abstraction, but it lets code
run with preemption disabled for unbounded amounts of time, and so now
is the time to ensure we get it right.
Part of the [justified] criticism on the current state of the crypto
API is on its complexity, and so I don't think it makes sense to keep
it simple now and add the complexity later (and the same concern
applies to async support btw).
^ permalink raw reply
* [PATCH net-next v2 9/9] net: bridge: pack net_bridge better
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Further reduce the size of net_bridge with 8 bytes and reduce the number of
holes in it:
Before: holes: 5, sum holes: 15
After: holes: 3, sum holes: 7
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
v2: Remove the comment about offload_fwd_mark in net_bridge and
leave it, the change will be for net_bridge_port instead.
Thanks to Ido for spotting it.
net/bridge/br_private.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 92d08f8c7dd4..57229b9d800f 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -349,7 +349,6 @@ struct net_bridge {
/* STP */
bridge_id designated_root;
bridge_id bridge_id;
- u32 root_path_cost;
unsigned char topology_change;
unsigned char topology_change_detected;
u16 root_port;
@@ -361,6 +360,7 @@ struct net_bridge {
unsigned long bridge_hello_time;
unsigned long bridge_forward_delay;
unsigned long bridge_ageing_time;
+ u32 root_path_cost;
u8 group_addr[ETH_ALEN];
@@ -383,6 +383,7 @@ struct net_bridge {
#if IS_ENABLED(CONFIG_IPV6)
u8 multicast_mld_version;
#endif
+ spinlock_t multicast_lock;
unsigned long multicast_last_member_interval;
unsigned long multicast_membership_interval;
unsigned long multicast_querier_interval;
@@ -390,7 +391,6 @@ struct net_bridge {
unsigned long multicast_query_response_interval;
unsigned long multicast_startup_query_interval;
- spinlock_t multicast_lock;
struct net_bridge_mdb_htable __rcu *mdb;
struct hlist_head router_list;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 8/9] net: bridge: convert mtu_set_by_user to a bit
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Convert the last remaining bool option to a bit thus reducing the overall
net_bridge size further by 8 bytes.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_device.c | 2 +-
net/bridge/br_if.c | 4 ++--
net/bridge/br_private.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index a0afdca73d8f..e053a4e43758 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -228,7 +228,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
dev->mtu = new_mtu;
/* this flag will be cleared if the MTU was automatically adjusted */
- br->mtu_set_by_user = true;
+ br_opt_toggle(br, BROPT_MTU_SET_BY_USER, true);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
/* remember the MTU in the rtable for PMTU */
dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 3bb66508f07d..9b46d2dc4c22 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -508,14 +508,14 @@ void br_mtu_auto_adjust(struct net_bridge *br)
ASSERT_RTNL();
/* if the bridge MTU was manually configured don't mess with it */
- if (br->mtu_set_by_user)
+ if (br_opt_get(br, BROPT_MTU_SET_BY_USER))
return;
/* change to the minimum MTU and clear the flag which was set by
* the bridge ndo_change_mtu callback
*/
dev_set_mtu(br->dev, br_mtu_min(br));
- br->mtu_set_by_user = false;
+ br_opt_toggle(br, BROPT_MTU_SET_BY_USER, false);
}
static void br_set_gso_limits(struct net_bridge *br)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6bdcc701bc71..92d08f8c7dd4 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -319,6 +319,7 @@ enum net_bridge_opts {
BROPT_MULTICAST_STATS_ENABLED,
BROPT_HAS_IPV6_ADDR,
BROPT_NEIGH_SUPPRESS_ENABLED,
+ BROPT_MTU_SET_BY_USER,
};
struct net_bridge {
@@ -415,7 +416,6 @@ struct net_bridge {
#ifdef CONFIG_NET_SWITCHDEV
int offload_fwd_mark;
#endif
- bool mtu_set_by_user;
struct hlist_head fdb_list;
};
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 7/9] net: bridge: convert neigh_suppress_enabled option to a bit
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Convert the neigh_suppress_enabled option to a bit.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_arp_nd_proxy.c | 13 ++++++++-----
net/bridge/br_device.c | 4 ++--
net/bridge/br_input.c | 2 +-
net/bridge/br_private.h | 2 +-
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
index d42e3904b498..6b78e6351719 100644
--- a/net/bridge/br_arp_nd_proxy.c
+++ b/net/bridge/br_arp_nd_proxy.c
@@ -39,7 +39,7 @@ void br_recalculate_neigh_suppress_enabled(struct net_bridge *br)
}
}
- br->neigh_suppress_enabled = neigh_suppress;
+ br_opt_toggle(br, BROPT_NEIGH_SUPPRESS_ENABLED, neigh_suppress);
}
#if IS_ENABLED(CONFIG_INET)
@@ -155,7 +155,7 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
ipv4_is_multicast(tip))
return;
- if (br->neigh_suppress_enabled) {
+ if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
if (p && (p->flags & BR_NEIGH_SUPPRESS))
return;
if (ipv4_is_zeronet(sip) || sip == tip) {
@@ -175,7 +175,8 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
return;
}
- if (br->neigh_suppress_enabled && br_is_local_ip(vlandev, tip)) {
+ if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
+ br_is_local_ip(vlandev, tip)) {
/* its our local ip, so don't proxy reply
* and don't forward to neigh suppress ports
*/
@@ -213,7 +214,8 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
/* If we have replied or as long as we know the
* mac, indicate to arp replied
*/
- if (replied || br->neigh_suppress_enabled)
+ if (replied ||
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
}
@@ -460,7 +462,8 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
* mac, indicate to NEIGH_SUPPRESS ports that we
* have replied
*/
- if (replied || br->neigh_suppress_enabled)
+ if (replied ||
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
}
neigh_release(n);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index e682a668ce57..a0afdca73d8f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -67,11 +67,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
if (IS_ENABLED(CONFIG_INET) &&
(eth->h_proto == htons(ETH_P_ARP) ||
eth->h_proto == htons(ETH_P_RARP)) &&
- br->neigh_suppress_enabled) {
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
br_do_proxy_suppress_arp(skb, br, vid, NULL);
} else if (IS_ENABLED(CONFIG_IPV6) &&
skb->protocol == htons(ETH_P_IPV6) &&
- br->neigh_suppress_enabled &&
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
pskb_may_pull(skb, sizeof(struct ipv6hdr) +
sizeof(struct nd_msg)) &&
ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 72074276c088..3ddca11f44c2 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -122,7 +122,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
br_do_proxy_suppress_arp(skb, br, vid, p);
} else if (IS_ENABLED(CONFIG_IPV6) &&
skb->protocol == htons(ETH_P_IPV6) &&
- br->neigh_suppress_enabled &&
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
pskb_may_pull(skb, sizeof(struct ipv6hdr) +
sizeof(struct nd_msg)) &&
ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index e6bdb107fe04..6bdcc701bc71 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -318,6 +318,7 @@ enum net_bridge_opts {
BROPT_MULTICAST_QUERY_USE_IFADDR,
BROPT_MULTICAST_STATS_ENABLED,
BROPT_HAS_IPV6_ADDR,
+ BROPT_NEIGH_SUPPRESS_ENABLED,
};
struct net_bridge {
@@ -414,7 +415,6 @@ struct net_bridge {
#ifdef CONFIG_NET_SWITCHDEV
int offload_fwd_mark;
#endif
- bool neigh_suppress_enabled;
bool mtu_set_by_user;
struct hlist_head fdb_list;
};
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 6/9] net: bridge: convert mcast options to bits
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
This patch converts the rest of the mcast options to bits. It also packs
the mcast options a little better by moving multicast_mld_version to an
existing hole, reducing the net_bridge size by 8 bytes.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_multicast.c | 22 ++++++++++------------
net/bridge/br_netlink.c | 11 ++++++-----
net/bridge/br_private.h | 20 ++++++++++----------
net/bridge/br_sysfs_br.c | 12 +++++++-----
4 files changed, 33 insertions(+), 32 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index ed6c33adc747..928024d8360d 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -411,7 +411,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br,
iph->frag_off = htons(IP_DF);
iph->ttl = 1;
iph->protocol = IPPROTO_IGMP;
- iph->saddr = br->multicast_query_use_ifaddr ?
+ iph->saddr = br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR) ?
inet_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0;
iph->daddr = htonl(INADDR_ALLHOSTS_GROUP);
((u8 *)&iph[1])[0] = IPOPT_RA;
@@ -503,11 +503,11 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
&ip6h->saddr)) {
kfree_skb(skb);
- br->has_ipv6_addr = 0;
+ br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, false);
return NULL;
}
- br->has_ipv6_addr = 1;
+ br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true);
ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
hopopt = (u8 *)(ip6h + 1);
@@ -967,7 +967,7 @@ static void br_multicast_send_query(struct net_bridge *br,
if (!netif_running(br->dev) ||
!br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
- !br->multicast_querier)
+ !br_opt_get(br, BROPT_MULTICAST_QUERIER))
return;
memset(&br_group.u, 0, sizeof(br_group.u));
@@ -1636,7 +1636,7 @@ br_multicast_leave_group(struct net_bridge *br,
if (timer_pending(&other_query->timer))
goto out;
- if (br->multicast_querier) {
+ if (br_opt_get(br, BROPT_MULTICAST_QUERIER)) {
__br_multicast_send_query(br, port, &mp->addr);
time = jiffies + br->multicast_last_member_count *
@@ -1748,7 +1748,7 @@ static void br_multicast_err_count(const struct net_bridge *br,
struct bridge_mcast_stats __percpu *stats;
struct bridge_mcast_stats *pstats;
- if (!br->multicast_stats_enabled)
+ if (!br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED))
return;
if (p)
@@ -1958,8 +1958,6 @@ void br_multicast_init(struct net_bridge *br)
br->hash_max = 512;
br->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
- br->multicast_querier = 0;
- br->multicast_query_use_ifaddr = 0;
br->multicast_last_member_count = 2;
br->multicast_startup_query_count = 2;
@@ -1978,7 +1976,7 @@ void br_multicast_init(struct net_bridge *br)
br->ip6_other_query.delay_time = 0;
br->ip6_querier.port = NULL;
#endif
- br->has_ipv6_addr = 1;
+ br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true);
spin_lock_init(&br->multicast_lock);
timer_setup(&br->multicast_router_timer,
@@ -2238,10 +2236,10 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
val = !!val;
spin_lock_bh(&br->multicast_lock);
- if (br->multicast_querier == val)
+ if (br_opt_get(br, BROPT_MULTICAST_QUERIER) == val)
goto unlock;
- br->multicast_querier = val;
+ br_opt_toggle(br, BROPT_MULTICAST_QUERIER, !!val);
if (!val)
goto unlock;
@@ -2562,7 +2560,7 @@ void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p,
struct bridge_mcast_stats __percpu *stats;
/* if multicast_disabled is true then igmp type can't be set */
- if (!type || !br->multicast_stats_enabled)
+ if (!type || !br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED))
return;
if (p)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 1d276b7b27e0..e5a5bc5d5232 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1167,7 +1167,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
u8 val;
val = nla_get_u8(data[IFLA_BR_MCAST_QUERY_USE_IFADDR]);
- br->multicast_query_use_ifaddr = !!val;
+ br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val);
}
if (data[IFLA_BR_MCAST_QUERIER]) {
@@ -1244,7 +1244,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
__u8 mcast_stats;
mcast_stats = nla_get_u8(data[IFLA_BR_MCAST_STATS_ENABLED]);
- br->multicast_stats_enabled = !!mcast_stats;
+ br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!mcast_stats);
}
if (data[IFLA_BR_MCAST_IGMP_VERSION]) {
@@ -1425,10 +1425,11 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING,
br_opt_get(br, BROPT_MULTICAST_ENABLED)) ||
nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
- br->multicast_query_use_ifaddr) ||
- nla_put_u8(skb, IFLA_BR_MCAST_QUERIER, br->multicast_querier) ||
+ br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) ||
+ nla_put_u8(skb, IFLA_BR_MCAST_QUERIER,
+ br_opt_get(br, BROPT_MULTICAST_QUERIER)) ||
nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED,
- br->multicast_stats_enabled) ||
+ br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) ||
nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY,
br->hash_elasticity) ||
nla_put_u32(skb, IFLA_BR_MCAST_HASH_MAX, br->hash_max) ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index fb1a266cdac8..e6bdb107fe04 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -314,6 +314,10 @@ enum net_bridge_opts {
BROPT_NF_CALL_ARPTABLES,
BROPT_GROUP_ADDR_SET,
BROPT_MULTICAST_ENABLED,
+ BROPT_MULTICAST_QUERIER,
+ BROPT_MULTICAST_QUERY_USE_IFADDR,
+ BROPT_MULTICAST_STATS_ENABLED,
+ BROPT_HAS_IPV6_ADDR,
};
struct net_bridge {
@@ -365,12 +369,6 @@ struct net_bridge {
} stp_enabled;
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- unsigned char multicast_router;
-
- u8 multicast_querier:1;
- u8 multicast_query_use_ifaddr:1;
- u8 has_ipv6_addr:1;
- u8 multicast_stats_enabled:1;
u32 hash_elasticity;
u32 hash_max;
@@ -379,7 +377,10 @@ struct net_bridge {
u32 multicast_startup_query_count;
u8 multicast_igmp_version;
-
+ u8 multicast_router;
+#if IS_ENABLED(CONFIG_IPV6)
+ u8 multicast_mld_version;
+#endif
unsigned long multicast_last_member_interval;
unsigned long multicast_membership_interval;
unsigned long multicast_querier_interval;
@@ -400,7 +401,6 @@ struct net_bridge {
struct bridge_mcast_other_query ip6_other_query;
struct bridge_mcast_own_query ip6_own_query;
struct bridge_mcast_querier ip6_querier;
- u8 multicast_mld_version;
#endif /* IS_ENABLED(CONFIG_IPV6) */
#endif
@@ -707,8 +707,8 @@ __br_multicast_querier_exists(struct net_bridge *br,
{
bool own_querier_enabled;
- if (br->multicast_querier) {
- if (is_ipv6 && !br->has_ipv6_addr)
+ if (br_opt_get(br, BROPT_MULTICAST_QUERIER)) {
+ if (is_ipv6 && !br_opt_get(br, BROPT_HAS_IPV6_ADDR))
own_querier_enabled = false;
else
own_querier_enabled = true;
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index bf6f409a83e1..c93c5724609e 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -365,12 +365,13 @@ static ssize_t multicast_query_use_ifaddr_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%d\n", br->multicast_query_use_ifaddr);
+ return sprintf(buf, "%d\n",
+ br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR));
}
static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val)
{
- br->multicast_query_use_ifaddr = !!val;
+ br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val);
return 0;
}
@@ -388,7 +389,7 @@ static ssize_t multicast_querier_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%d\n", br->multicast_querier);
+ return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_QUERIER));
}
static ssize_t multicast_querier_store(struct device *d,
@@ -636,12 +637,13 @@ static ssize_t multicast_stats_enabled_show(struct device *d,
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%u\n", br->multicast_stats_enabled);
+ return sprintf(buf, "%d\n",
+ br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED));
}
static int set_stats_enabled(struct net_bridge *br, unsigned long val)
{
- br->multicast_stats_enabled = !!val;
+ br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!val);
return 0;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 5/9] net: bridge: convert and rename mcast disabled
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Convert mcast disabled to an option bit and while doing so convert the
logic to check if multicast is enabled instead. That is make the logic
follow the option value - if it's set then mcast is enabled and vice versa.
This avoids a few confusing places where we inverted the value that's being
set to follow the mcast_disabled logic.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_mdb.c | 6 +++---
net/bridge/br_multicast.c | 32 +++++++++++++++++---------------
net/bridge/br_netlink.c | 3 ++-
net/bridge/br_private.h | 2 +-
net/bridge/br_sysfs_br.c | 2 +-
5 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 6d9f48bd374a..a4a848bf827b 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -84,7 +84,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
int i, err = 0;
int idx = 0, s_idx = cb->args[1];
- if (br->multicast_disabled)
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
return 0;
mdb = rcu_dereference(br->mdb);
@@ -598,7 +598,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
struct net_bridge_port *p;
int ret;
- if (!netif_running(br->dev) || br->multicast_disabled)
+ if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
return -EINVAL;
dev = __dev_get_by_index(net, entry->ifindex);
@@ -673,7 +673,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
struct br_ip ip;
int err = -EINVAL;
- if (!netif_running(br->dev) || br->multicast_disabled)
+ if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
return -EINVAL;
__mdb_entry_to_br_ip(entry, &ip);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 20ed7adcf1cc..ed6c33adc747 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -158,7 +158,7 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
struct br_ip ip;
- if (br->multicast_disabled)
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
return NULL;
if (BR_INPUT_SKB_CB(skb)->igmp)
@@ -628,7 +628,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group(
port ? port->dev->name : br->dev->name);
err = -E2BIG;
disable:
- br->multicast_disabled = 1;
+ br_opt_toggle(br, BROPT_MULTICAST_ENABLED, false);
goto err;
}
}
@@ -894,7 +894,7 @@ static void br_multicast_querier_expired(struct net_bridge *br,
struct bridge_mcast_own_query *query)
{
spin_lock(&br->multicast_lock);
- if (!netif_running(br->dev) || br->multicast_disabled)
+ if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
goto out;
br_multicast_start_querier(br, query);
@@ -965,7 +965,8 @@ static void br_multicast_send_query(struct net_bridge *br,
struct br_ip br_group;
unsigned long time;
- if (!netif_running(br->dev) || br->multicast_disabled ||
+ if (!netif_running(br->dev) ||
+ !br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
!br->multicast_querier)
return;
@@ -1036,7 +1037,7 @@ static void br_mc_disabled_update(struct net_device *dev, bool value)
.orig_dev = dev,
.id = SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
.flags = SWITCHDEV_F_DEFER,
- .u.mc_disabled = value,
+ .u.mc_disabled = !value,
};
switchdev_port_attr_set(dev, &attr);
@@ -1054,7 +1055,8 @@ int br_multicast_add_port(struct net_bridge_port *port)
timer_setup(&port->ip6_own_query.timer,
br_ip6_multicast_port_query_expired, 0);
#endif
- br_mc_disabled_update(port->dev, port->br->multicast_disabled);
+ br_mc_disabled_update(port->dev,
+ br_opt_get(port->br, BROPT_MULTICAST_ENABLED));
port->mcast_stats = netdev_alloc_pcpu_stats(struct bridge_mcast_stats);
if (!port->mcast_stats)
@@ -1091,7 +1093,7 @@ static void __br_multicast_enable_port(struct net_bridge_port *port)
{
struct net_bridge *br = port->br;
- if (br->multicast_disabled || !netif_running(br->dev))
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED) || !netif_running(br->dev))
return;
br_multicast_enable(&port->ip4_own_query);
@@ -1904,7 +1906,7 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
BR_INPUT_SKB_CB(skb)->igmp = 0;
BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
- if (br->multicast_disabled)
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
return 0;
switch (skb->protocol) {
@@ -1998,7 +2000,7 @@ static void __br_multicast_open(struct net_bridge *br,
{
query->startup_sent = 0;
- if (br->multicast_disabled)
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
return;
mod_timer(&query->timer, jiffies);
@@ -2173,12 +2175,12 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
int err = 0;
spin_lock_bh(&br->multicast_lock);
- if (br->multicast_disabled == !val)
+ if (!!br_opt_get(br, BROPT_MULTICAST_ENABLED) == !!val)
goto unlock;
- br_mc_disabled_update(br->dev, !val);
- br->multicast_disabled = !val;
- if (br->multicast_disabled)
+ br_mc_disabled_update(br->dev, val);
+ br_opt_toggle(br, BROPT_MULTICAST_ENABLED, !!val);
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
goto unlock;
if (!netif_running(br->dev))
@@ -2189,7 +2191,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
if (mdb->old) {
err = -EEXIST;
rollback:
- br->multicast_disabled = !!val;
+ br_opt_toggle(br, BROPT_MULTICAST_ENABLED, false);
goto unlock;
}
@@ -2213,7 +2215,7 @@ bool br_multicast_enabled(const struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- return !br->multicast_disabled;
+ return !!br_opt_get(br, BROPT_MULTICAST_ENABLED);
}
EXPORT_SYMBOL_GPL(br_multicast_enabled);
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index b00ccf35c35d..1d276b7b27e0 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1422,7 +1422,8 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
#endif
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
if (nla_put_u8(skb, IFLA_BR_MCAST_ROUTER, br->multicast_router) ||
- nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING, !br->multicast_disabled) ||
+ nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING,
+ br_opt_get(br, BROPT_MULTICAST_ENABLED)) ||
nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
br->multicast_query_use_ifaddr) ||
nla_put_u8(skb, IFLA_BR_MCAST_QUERIER, br->multicast_querier) ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index dda117ce386e..fb1a266cdac8 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -313,6 +313,7 @@ enum net_bridge_opts {
BROPT_NF_CALL_IP6TABLES,
BROPT_NF_CALL_ARPTABLES,
BROPT_GROUP_ADDR_SET,
+ BROPT_MULTICAST_ENABLED,
};
struct net_bridge {
@@ -366,7 +367,6 @@ struct net_bridge {
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
unsigned char multicast_router;
- u8 multicast_disabled:1;
u8 multicast_querier:1;
u8 multicast_query_use_ifaddr:1;
u8 has_ipv6_addr:1;
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 4c2d56354d89..bf6f409a83e1 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -349,7 +349,7 @@ static ssize_t multicast_snooping_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%d\n", !br->multicast_disabled);
+ return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_ENABLED));
}
static ssize_t multicast_snooping_store(struct device *d,
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 4/9] net: bridge: convert group_addr_set option to a bit
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Convert group_addr_set internal bridge opt to a bit.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_netlink.c | 2 +-
net/bridge/br_private.h | 2 +-
net/bridge/br_sysfs_br.c | 2 +-
net/bridge/br_vlan.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 521893df0c2a..b00ccf35c35d 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1139,7 +1139,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
spin_lock_bh(&br->lock);
memcpy(br->group_addr, new_addr, sizeof(br->group_addr));
spin_unlock_bh(&br->lock);
- br->group_addr_set = true;
+ br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true);
br_recalculate_fwd_mask(br);
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d8eadab09d7d..dda117ce386e 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -312,6 +312,7 @@ enum net_bridge_opts {
BROPT_NF_CALL_IPTABLES,
BROPT_NF_CALL_IP6TABLES,
BROPT_NF_CALL_ARPTABLES,
+ BROPT_GROUP_ADDR_SET,
};
struct net_bridge {
@@ -355,7 +356,6 @@ struct net_bridge {
unsigned long bridge_ageing_time;
u8 group_addr[ETH_ALEN];
- bool group_addr_set;
enum {
BR_NO_STP, /* no spanning tree */
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 0f8545c94948..4c2d56354d89 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -303,7 +303,7 @@ static ssize_t group_addr_store(struct device *d,
ether_addr_copy(br->group_addr, new_addr);
spin_unlock_bh(&br->lock);
- br->group_addr_set = true;
+ br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true);
br_recalculate_fwd_mask(br);
netdev_state_change(br->dev);
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 61d698bfe2b7..5942e03dd845 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -695,7 +695,7 @@ struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid)
/* Must be protected by RTNL. */
static void recalculate_group_addr(struct net_bridge *br)
{
- if (br->group_addr_set)
+ if (br_opt_get(br, BROPT_GROUP_ADDR_SET))
return;
spin_lock_bh(&br->lock);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 3/9] net: bridge: convert nf call options to bits
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
No functional change, convert of nf_call_[ip|ip6|arp]tables to bits.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_netfilter_hooks.c | 7 ++++---
net/bridge/br_netlink.c | 12 ++++++------
net/bridge/br_private.h | 6 +++---
net/bridge/br_sysfs_br.c | 12 ++++++------
4 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index 6e0dc6bcd32a..e0a3b038d052 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -487,14 +487,15 @@ static unsigned int br_nf_pre_routing(void *priv,
br = p->br;
if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) {
- if (!brnf_call_ip6tables && !br->nf_call_ip6tables)
+ if (!brnf_call_ip6tables &&
+ !br_opt_get(br, BROPT_NF_CALL_IP6TABLES))
return NF_ACCEPT;
nf_bridge_pull_encap_header_rcsum(skb);
return br_nf_pre_routing_ipv6(priv, skb, state);
}
- if (!brnf_call_iptables && !br->nf_call_iptables)
+ if (!brnf_call_iptables && !br_opt_get(br, BROPT_NF_CALL_IPTABLES))
return NF_ACCEPT;
if (!IS_IP(skb) && !IS_VLAN_IP(skb) && !IS_PPPOE_IP(skb))
@@ -636,7 +637,7 @@ static unsigned int br_nf_forward_arp(void *priv,
return NF_ACCEPT;
br = p->br;
- if (!brnf_call_arptables && !br->nf_call_arptables)
+ if (!brnf_call_arptables && !br_opt_get(br, BROPT_NF_CALL_ARPTABLES))
return NF_ACCEPT;
if (!IS_ARP(skb)) {
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 6a53caff2d31..521893df0c2a 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1271,19 +1271,19 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
if (data[IFLA_BR_NF_CALL_IPTABLES]) {
u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IPTABLES]);
- br->nf_call_iptables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val);
}
if (data[IFLA_BR_NF_CALL_IP6TABLES]) {
u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IP6TABLES]);
- br->nf_call_ip6tables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val);
}
if (data[IFLA_BR_NF_CALL_ARPTABLES]) {
u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_ARPTABLES]);
- br->nf_call_arptables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val);
}
#endif
@@ -1470,11 +1470,11 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (nla_put_u8(skb, IFLA_BR_NF_CALL_IPTABLES,
- br->nf_call_iptables ? 1 : 0) ||
+ br_opt_get(br, BROPT_NF_CALL_IPTABLES) ? 1 : 0) ||
nla_put_u8(skb, IFLA_BR_NF_CALL_IP6TABLES,
- br->nf_call_ip6tables ? 1 : 0) ||
+ br_opt_get(br, BROPT_NF_CALL_IP6TABLES) ? 1 : 0) ||
nla_put_u8(skb, IFLA_BR_NF_CALL_ARPTABLES,
- br->nf_call_arptables ? 1 : 0))
+ br_opt_get(br, BROPT_NF_CALL_ARPTABLES) ? 1 : 0))
return -EMSGSIZE;
#endif
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 0abb632283ff..d8eadab09d7d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -309,6 +309,9 @@ static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_devi
enum net_bridge_opts {
BROPT_VLAN_ENABLED,
BROPT_VLAN_STATS_ENABLED,
+ BROPT_NF_CALL_IPTABLES,
+ BROPT_NF_CALL_IP6TABLES,
+ BROPT_NF_CALL_ARPTABLES,
};
struct net_bridge {
@@ -331,9 +334,6 @@ struct net_bridge {
struct rtable fake_rtable;
struct rt6_info fake_rt6_info;
};
- bool nf_call_iptables;
- bool nf_call_ip6tables;
- bool nf_call_arptables;
#endif
u16 group_fwd_mask;
u16 group_fwd_mask_required;
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 9f1f3866c833..0f8545c94948 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -678,12 +678,12 @@ static ssize_t nf_call_iptables_show(
struct device *d, struct device_attribute *attr, char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%u\n", br->nf_call_iptables);
+ return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IPTABLES));
}
static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
{
- br->nf_call_iptables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val);
return 0;
}
@@ -699,12 +699,12 @@ static ssize_t nf_call_ip6tables_show(
struct device *d, struct device_attribute *attr, char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%u\n", br->nf_call_ip6tables);
+ return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IP6TABLES));
}
static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
{
- br->nf_call_ip6tables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val);
return 0;
}
@@ -720,12 +720,12 @@ static ssize_t nf_call_arptables_show(
struct device *d, struct device_attribute *attr, char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%u\n", br->nf_call_arptables);
+ return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_ARPTABLES));
}
static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
{
- br->nf_call_arptables = val ? true : false;
+ br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val);
return 0;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 2/9] net: bridge: add bitfield for options and convert vlan opts
From: Nikolay Aleksandrov @ 2018-09-26 14:01 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Bridge options have usually been added as separate fields all over the
net_bridge struct taking up space and ending up in different cache lines.
Let's move them to a single bitfield to save up space and speedup lookups.
This patch adds a simple API for option modifying and retrieving using
bitops and converts the first user of the API - the bridge vlan options
(vlan_enabled and vlan_stats_enabled).
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br.c | 16 ++++++++++++++++
net/bridge/br_netlink.c | 3 ++-
net/bridge/br_private.h | 16 ++++++++++++++--
net/bridge/br_sysfs_br.c | 4 ++--
net/bridge/br_vlan.c | 28 +++++++++++++++-------------
5 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/net/bridge/br.c b/net/bridge/br.c
index b0a0b82e2d91..e411e40333e2 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -175,6 +175,22 @@ static struct notifier_block br_switchdev_notifier = {
.notifier_call = br_switchdev_event,
};
+void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on)
+{
+ bool cur = !!br_opt_get(br, opt);
+
+ br_debug(br, "toggle option: %d state: %d -> %d\n",
+ opt, cur, on);
+
+ if (cur == on)
+ return;
+
+ if (on)
+ set_bit(opt, &br->options);
+ else
+ clear_bit(opt, &br->options);
+}
+
static void __net_exit br_net_exit(struct net *net)
{
struct net_device *dev;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index ec2b58a09f76..6a53caff2d31 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1416,7 +1416,8 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
if (nla_put_be16(skb, IFLA_BR_VLAN_PROTOCOL, br->vlan_proto) ||
nla_put_u16(skb, IFLA_BR_VLAN_DEFAULT_PVID, br->default_pvid) ||
- nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED, br->vlan_stats_enabled))
+ nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED,
+ br_opt_get(br, BROPT_VLAN_STATS_ENABLED)))
return -EMSGSIZE;
#endif
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 522d707cc533..0abb632283ff 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -306,16 +306,20 @@ static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_devi
rcu_dereference_rtnl(dev->rx_handler_data) : NULL;
}
+enum net_bridge_opts {
+ BROPT_VLAN_ENABLED,
+ BROPT_VLAN_STATS_ENABLED,
+};
+
struct net_bridge {
spinlock_t lock;
spinlock_t hash_lock;
struct list_head port_list;
struct net_device *dev;
struct pcpu_sw_netstats __percpu *stats;
+ unsigned long options;
/* These fields are accessed on each packet */
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
- u8 vlan_enabled;
- u8 vlan_stats_enabled;
__be16 vlan_proto;
u16 default_pvid;
struct net_bridge_vlan_group __rcu *vlgrp;
@@ -489,6 +493,14 @@ static inline bool br_vlan_should_use(const struct net_bridge_vlan *v)
return true;
}
+static inline int br_opt_get(const struct net_bridge *br,
+ enum net_bridge_opts opt)
+{
+ return test_bit(opt, &br->options);
+}
+
+void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on);
+
/* br_device.c */
void br_dev_setup(struct net_device *dev);
void br_dev_delete(struct net_device *dev, struct list_head *list);
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 0318a69888d4..9f1f3866c833 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -743,7 +743,7 @@ static ssize_t vlan_filtering_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%d\n", br->vlan_enabled);
+ return sprintf(buf, "%d\n", br_opt_get(br, BROPT_VLAN_ENABLED));
}
static ssize_t vlan_filtering_store(struct device *d,
@@ -791,7 +791,7 @@ static ssize_t vlan_stats_enabled_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
- return sprintf(buf, "%u\n", br->vlan_stats_enabled);
+ return sprintf(buf, "%u\n", br_opt_get(br, BROPT_VLAN_STATS_ENABLED));
}
static ssize_t vlan_stats_enabled_store(struct device *d,
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index bb6ba794864f..61d698bfe2b7 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -386,7 +386,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
return NULL;
}
}
- if (br->vlan_stats_enabled) {
+ if (br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) {
stats = this_cpu_ptr(v->stats);
u64_stats_update_begin(&stats->syncp);
stats->tx_bytes += skb->len;
@@ -475,14 +475,14 @@ static bool __allowed_ingress(const struct net_bridge *br,
skb->vlan_tci |= pvid;
/* if stats are disabled we can avoid the lookup */
- if (!br->vlan_stats_enabled)
+ if (!br_opt_get(br, BROPT_VLAN_STATS_ENABLED))
return true;
}
v = br_vlan_find(vg, *vid);
if (!v || !br_vlan_should_use(v))
goto drop;
- if (br->vlan_stats_enabled) {
+ if (br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) {
stats = this_cpu_ptr(v->stats);
u64_stats_update_begin(&stats->syncp);
stats->rx_bytes += skb->len;
@@ -504,7 +504,7 @@ bool br_allowed_ingress(const struct net_bridge *br,
/* If VLAN filtering is disabled on the bridge, all packets are
* permitted.
*/
- if (!br->vlan_enabled) {
+ if (!br_opt_get(br, BROPT_VLAN_ENABLED)) {
BR_INPUT_SKB_CB(skb)->vlan_filtered = false;
return true;
}
@@ -538,7 +538,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
struct net_bridge *br = p->br;
/* If filtering was disabled at input, let it pass. */
- if (!br->vlan_enabled)
+ if (!br_opt_get(br, BROPT_VLAN_ENABLED))
return true;
vg = nbp_vlan_group_rcu(p);
@@ -699,7 +699,8 @@ static void recalculate_group_addr(struct net_bridge *br)
return;
spin_lock_bh(&br->lock);
- if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) {
+ if (!br_opt_get(br, BROPT_VLAN_ENABLED) ||
+ br->vlan_proto == htons(ETH_P_8021Q)) {
/* Bridge Group Address */
br->group_addr[5] = 0x00;
} else { /* vlan_enabled && ETH_P_8021AD */
@@ -712,7 +713,8 @@ static void recalculate_group_addr(struct net_bridge *br)
/* Must be protected by RTNL. */
void br_recalculate_fwd_mask(struct net_bridge *br)
{
- if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q))
+ if (!br_opt_get(br, BROPT_VLAN_ENABLED) ||
+ br->vlan_proto == htons(ETH_P_8021Q))
br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT;
else /* vlan_enabled && ETH_P_8021AD */
br->group_fwd_mask_required = BR_GROUPFWD_8021AD &
@@ -729,14 +731,14 @@ int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
};
int err;
- if (br->vlan_enabled == val)
+ if (br_opt_get(br, BROPT_VLAN_ENABLED) == !!val)
return 0;
err = switchdev_port_attr_set(br->dev, &attr);
if (err && err != -EOPNOTSUPP)
return err;
- br->vlan_enabled = val;
+ br_opt_toggle(br, BROPT_VLAN_ENABLED, !!val);
br_manage_promisc(br);
recalculate_group_addr(br);
br_recalculate_fwd_mask(br);
@@ -753,7 +755,7 @@ bool br_vlan_enabled(const struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- return !!br->vlan_enabled;
+ return br_opt_get(br, BROPT_VLAN_ENABLED);
}
EXPORT_SYMBOL_GPL(br_vlan_enabled);
@@ -819,7 +821,7 @@ int br_vlan_set_stats(struct net_bridge *br, unsigned long val)
switch (val) {
case 0:
case 1:
- br->vlan_stats_enabled = val;
+ br_opt_toggle(br, BROPT_VLAN_STATS_ENABLED, !!val);
break;
default:
return -EINVAL;
@@ -964,7 +966,7 @@ int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
goto out;
/* Only allow default pvid change when filtering is disabled */
- if (br->vlan_enabled) {
+ if (br_opt_get(br, BROPT_VLAN_ENABLED)) {
pr_info_once("Please disable vlan filtering to change default_pvid\n");
err = -EPERM;
goto out;
@@ -1018,7 +1020,7 @@ int nbp_vlan_init(struct net_bridge_port *p)
.orig_dev = p->br->dev,
.id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
.flags = SWITCHDEV_F_SKIP_EOPNOTSUPP,
- .u.vlan_filtering = p->br->vlan_enabled,
+ .u.vlan_filtering = br_opt_get(p->br, BROPT_VLAN_ENABLED),
};
struct net_bridge_vlan_group *vg;
int ret = -ENOMEM;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 1/9] net: bridge: make struct opening bracket consistent
From: Nikolay Aleksandrov @ 2018-09-26 14:00 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
In-Reply-To: <20180926140107.10218-1-nikolay@cumulusnetworks.com>
Currently we have a mix of opening brackets on new lines and on the same
line, let's move them all on the same line.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
---
net/bridge/br_private.h | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d21035a17f4c..522d707cc533 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -54,14 +54,12 @@ typedef struct bridge_id bridge_id;
typedef struct mac_addr mac_addr;
typedef __u16 port_id;
-struct bridge_id
-{
+struct bridge_id {
unsigned char prio[2];
unsigned char addr[ETH_ALEN];
};
-struct mac_addr
-{
+struct mac_addr {
unsigned char addr[ETH_ALEN];
};
@@ -207,8 +205,7 @@ struct net_bridge_port_group {
unsigned char eth_addr[ETH_ALEN];
};
-struct net_bridge_mdb_entry
-{
+struct net_bridge_mdb_entry {
struct hlist_node hlist[2];
struct net_bridge *br;
struct net_bridge_port_group __rcu *ports;
@@ -218,8 +215,7 @@ struct net_bridge_mdb_entry
bool host_joined;
};
-struct net_bridge_mdb_htable
-{
+struct net_bridge_mdb_htable {
struct hlist_head *mhash;
struct rcu_head rcu;
struct net_bridge_mdb_htable *old;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 0/9] net: bridge: convert bool options to bits
From: Nikolay Aleksandrov @ 2018-09-26 14:00 UTC (permalink / raw)
To: netdev; +Cc: roopa, davem, stephen, bridge, idosch, Nikolay Aleksandrov
Hi,
A lot of boolean bridge options have been added around the net_bridge
structure resulting in holes and more importantly different cache lines
that need to be fetched in the fast path. This set moves all of those
to bits in a bitfield which resides in a hot cache line thus reducing
the size of net_bridge, the number of holes and the number of cache
lines needed for the fast path.
The set is also sent in preparation for new boolean options to avoid
spreading them in the structure and making new holes.
One nice side-effect is that we avoid potential race conditions by using
the bitops since some of the options were bits being directly set in
parallel risking hard to debug issues (has_ipv6_addr).
Before:
size: 1184, holes: 8, sum holes: 30
After:
size: 1160, holes: 3, sum holes: 7
Patch 01 is a trivial style fix
Patch 02 adds the new options bitfield and converts the vlan boolean
options to bits
Patches 03-08 convert the rest of the boolean options to bits
Patch 09 re-arranges a few fields in net_bridge to further reduce size
v2: patch 09: remove the comment about offload_fwd_mark in net_bridge and
leave it in the last 4 bytes, thanks to Ido for spotting it
Stephen, I've added your reviewed-by in patches 01-08, only removed it
from patch 09 as the patch has changed.
Thanks,
Nik
Nikolay Aleksandrov (9):
net: bridge: make struct opening bracket consistent
net: bridge: add bitfield for options and convert vlan opts
net: bridge: convert nf call options to bits
net: bridge: convert group_addr_set option to a bit
net: bridge: convert and rename mcast disabled
net: bridge: convert mcast options to bits
net: bridge: convert neigh_suppress_enabled option to a bit
net: bridge: convert mtu_set_by_user to a bit
net: bridge: pack net_bridge better
net/bridge/br.c | 16 ++++++++++
net/bridge/br_arp_nd_proxy.c | 13 ++++----
net/bridge/br_device.c | 6 ++--
net/bridge/br_if.c | 4 +--
net/bridge/br_input.c | 2 +-
net/bridge/br_mdb.c | 6 ++--
net/bridge/br_multicast.c | 54 ++++++++++++++++-----------------
net/bridge/br_netfilter_hooks.c | 7 +++--
net/bridge/br_netlink.c | 31 ++++++++++---------
net/bridge/br_private.h | 66 +++++++++++++++++++++++------------------
net/bridge/br_sysfs_br.c | 32 ++++++++++----------
net/bridge/br_vlan.c | 30 ++++++++++---------
12 files changed, 151 insertions(+), 116 deletions(-)
--
2.11.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox