* Re: [PATCH] virtio-net: drop legacy features in virtio 1 mode
From: Cornelia Huck @ 2016-11-04 11:15 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: netdev, linux-kernel, stable, virtualization
In-Reply-To: <1478256865-29003-1-git-send-email-mst@redhat.com>
On Fri, 4 Nov 2016 12:55:36 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> Virtio 1.0 spec says VIRTIO_F_ANY_LAYOUT and VIRTIO_NET_F_GSO are
> legacy-only feature bits. Do not negotiate them in virtio 1 mode. Note
> this is a spec violation so we need to backport it to stable/downstream
> kernels.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/net/virtio_net.c | 30 ++++++++++++++++++++----------
> 1 file changed, 20 insertions(+), 10 deletions(-)
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH net] sctp: assign assoc_id earlier in __sctp_connect
From: Marcelo Ricardo Leitner @ 2016-11-04 11:10 UTC (permalink / raw)
To: David Laight, netdev@vger.kernel.org
Cc: linux-sctp@vger.kernel.org, Vlad Yasevich, Neil Horman,
syzkaller@googlegroups.com, kcc@google.com, glider@google.com,
edumazet@google.com, dvyukov@google.com, andreyknvl@google.com
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6DB0215215@AcuExch.aculab.com>
Em 04-11-2016 08:55, David Laight escreveu:
> From: Of Marcelo Ricardo Leitner
>> Sent: 03 November 2016 19:04
>> sctp_wait_for_connect() currently already holds the asoc to keep it
>> alive during the sleep, in case another thread release it. But Andrey
>> Konovalov and Dmitry Vyukov reported an use-after-free in such
>> situation.
>>
>> Problem is that __sctp_connect() doesn't get a ref on the asoc and will
>> do a read on the asoc after calling sctp_wait_for_connect(), but by then
>> another thread may have closed it and the _put on sctp_wait_for_connect
>> will actually release it, causing the use-after-free.
>>
>> Fix is, instead of doing the read after waiting for the connect, do it
>> before so, and avoid this issue as the socket is still locked by then.
>> There should be no issue on returning the asoc id in case of failure as
>> the application shouldn't trust on that number in such situations
>> anyway.
>>
>> This issue doesn't exist in sctp_sendmsg() path.
>>
>> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>> Tested-by: Andrey Konovalov <andreyknvl@google.com>
>> Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
>> ---
>> net/sctp/socket.c | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
>> index 6cdc61c21438aa9b6dbdad93e70759071a4d6789..be1d9bb98230c9d77f676949db773b2dacd801a4 100644
>> --- a/net/sctp/socket.c
>> +++ b/net/sctp/socket.c
>> @@ -1214,9 +1214,12 @@ static int __sctp_connect(struct sock *sk,
>>
>> timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
>>
>> - err = sctp_wait_for_connect(asoc, &timeo);
>> - if ((err == 0 || err == -EINPROGRESS) && assoc_id)
>> + if (assoc_id)
>> *assoc_id = asoc->assoc_id;
>> + err = sctp_wait_for_connect(asoc, &timeo);
>> + /* Note: the asoc may be freed after the return of
>> + * sctp_wait_for_connect.
>> + */
>
> Is it worth ensuring that *assoc_id is NULL on error?
I don't think so. An error was returned, the value shouldn't be trusted
anyway and it's not leaking any sort of critical data.
Note that original code doesn't touch assoc_id in case of error. It's
different than zeroing it out.
> Maybe change the code to:
> assoc_id_val = asoc->assoc_id;
> rval = sctp_wait_for_connect(asoc, &timeo);
> if (err != 0 && err != -EINPROGRESS)
> assoc_id_val = 0;
> if (assoc_id)
> *assoc_id = assoc_id_val;
Or just clear it in case of error..
if (assoc_id && (err != 0 && err != -EINPROGRESS))
*assoc_id = 0;
Amount of code is probably the same but avoids a temporary var.
Marcelo
^ permalink raw reply
* From Amir A. K
From: Amir A. K @ 2016-11-04 10:42 UTC (permalink / raw)
To: 013
--
Thanks for your last email response to me.
The information required should include the following-:
Your full names
Your address
Telephone number
Your private email
Occupation
Age
This is to enable my further discussion with you in confidence.
Best regards and wishes to you.
Amir A. Khanmammadov
REPLY TO
khanmammadov@vera.com.uy
amir2016@vera.com.uy
^ permalink raw reply
* [PATCH net-next 4/5] ethtool: Core impl for ETHTOOL_PHY_DOWNSHIFT tunable
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255742-25693-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Adding validation support for the ETHTOOL_PHY_DOWNSHIFT. Functional
implementation needs to be done in the individual PHY drivers.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
net/core/ethtool.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 75f19ab..1a66faa 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -2425,6 +2425,11 @@ static int ethtool_set_per_queue(struct net_device *dev, void __user *useraddr)
static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
{
switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ if (tuna->len != sizeof(u8) ||
+ tuna->type_id != ETHTOOL_TUNABLE_U8)
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
--
2.7.3
^ permalink raw reply related
* [PATCH net-next 5/5] net: phy: Add downshift get/set support in Microsemi PHYs driver
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255742-25693-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Implements the phy tunable function pointers and implement downshift
functionality for MSCC PHYs.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
drivers/net/phy/mscc.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index d0026ab..7edd32d 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -46,8 +46,15 @@ enum rgmii_rx_clock_delay {
#define MSCC_EXT_PAGE_ACCESS 31
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
+#define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
+/* Extended Page 1 Registers */
+#define MSCC_PHY_ACTIPHY_CNTL 20
+#define DOWNSHIFT_CNTL_MASK 0x001C
+#define DOWNSHIFT_EN 0x0010
+#define DOWNSHIFT_CNTL_POS 2
+
/* Extended Page 2 Registers */
#define MSCC_PHY_RGMII_CNTL 20
#define RGMII_RX_CLK_DELAY_MASK 0x0070
@@ -75,6 +82,8 @@ enum rgmii_rx_clock_delay {
#define MSCC_VDDMAC_2500 2500
#define MSCC_VDDMAC_3300 3300
+#define DOWNSHIFT_COUNT_MAX 5
+
struct vsc8531_private {
int rate_magic;
};
@@ -101,6 +110,66 @@ static int vsc85xx_phy_page_set(struct phy_device *phydev, u8 page)
return rc;
}
+static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
+{
+ int rc;
+ u16 reg_val;
+
+ mutex_lock(&phydev->lock);
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED);
+ if (rc != 0)
+ goto out_unlock;
+
+ reg_val = phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
+ reg_val &= DOWNSHIFT_CNTL_MASK;
+ if (!(reg_val & DOWNSHIFT_EN))
+ *count = 0;
+ else
+ *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_STANDARD);
+
+out_unlock:
+ mutex_unlock(&phydev->lock);
+
+ return rc;
+}
+
+static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
+{
+ int rc;
+ u16 reg_val;
+
+ if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
+ /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
+ count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
+ } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
+ phydev_err(phydev, "Invalid downshift count\n");
+ return -EINVAL;
+ } else if (count) {
+ /* Downshift count is either 2,3,4 or 5 */
+ count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
+ }
+
+ mutex_lock(&phydev->lock);
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED);
+ if (rc != 0)
+ goto out_unlock;
+
+ reg_val = phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
+ reg_val &= ~(DOWNSHIFT_CNTL_MASK);
+ reg_val |= count;
+ rc = phy_write(phydev, MSCC_PHY_ACTIPHY_CNTL, reg_val);
+ if (rc != 0)
+ goto out_unlock;
+
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_STANDARD);
+
+out_unlock:
+ mutex_unlock(&phydev->lock);
+
+ return rc;
+}
+
static int vsc85xx_wol_set(struct phy_device *phydev,
struct ethtool_wolinfo *wol)
{
@@ -329,6 +398,31 @@ static int vsc85xx_default_config(struct phy_device *phydev)
return rc;
}
+static int vsc85xx_get_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna, void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return vsc85xx_downshift_get(phydev, (u8 *)data);
+ default:
+ phydev_err(phydev, "Unsupported PHY tunable id\n");
+ return -EINVAL;
+ }
+}
+
+static int vsc85xx_set_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna,
+ const void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return vsc85xx_downshift_set(phydev, *(u8 *)data);
+ default:
+ phydev_err(phydev, "Unsupported PHY tunable id\n");
+ return -EINVAL;
+ }
+}
+
static int vsc85xx_config_init(struct phy_device *phydev)
{
int rc;
@@ -418,6 +512,8 @@ static struct phy_driver vsc85xx_driver[] = {
.probe = &vsc85xx_probe,
.set_wol = &vsc85xx_wol_set,
.get_wol = &vsc85xx_wol_get,
+ .get_tunable = &vsc85xx_get_tunable,
+ .set_tunable = &vsc85xx_set_tunable,
},
{
.phy_id = PHY_ID_VSC8531,
@@ -437,6 +533,8 @@ static struct phy_driver vsc85xx_driver[] = {
.probe = &vsc85xx_probe,
.set_wol = &vsc85xx_wol_set,
.get_wol = &vsc85xx_wol_get,
+ .get_tunable = &vsc85xx_get_tunable,
+ .set_tunable = &vsc85xx_set_tunable,
},
{
.phy_id = PHY_ID_VSC8540,
@@ -456,6 +554,8 @@ static struct phy_driver vsc85xx_driver[] = {
.probe = &vsc85xx_probe,
.set_wol = &vsc85xx_wol_set,
.get_wol = &vsc85xx_wol_get,
+ .get_tunable = &vsc85xx_get_tunable,
+ .set_tunable = &vsc85xx_set_tunable,
},
{
.phy_id = PHY_ID_VSC8541,
@@ -475,6 +575,8 @@ static struct phy_driver vsc85xx_driver[] = {
.probe = &vsc85xx_probe,
.set_wol = &vsc85xx_wol_set,
.get_wol = &vsc85xx_wol_get,
+ .get_tunable = &vsc85xx_get_tunable,
+ .set_tunable = &vsc85xx_set_tunable,
}
};
--
2.7.3
^ permalink raw reply related
* Re: Coding Style: Reverse XMAS tree declarations ? (was Re: [PATCH net-next v6 02/10] dpaa_eth: add support for DPAA Ethernet)
From: Lino Sanfilippo @ 2016-11-04 11:01 UTC (permalink / raw)
To: Joe Perches, David Miller, madalin.bucur, Andrew Morton,
Jonathan Corbet
Cc: netdev, linuxppc-dev, linux-kernel, oss, ppc, pebolle,
joakim.tjernlund
In-Reply-To: <1478242438.1924.31.camel@perches.com>
Hi,
On 04.11.2016 07:53, Joe Perches wrote:
>
> CHECK:REVERSE_XMAS_TREE: Prefer ordering declarations longest to shortest
> #446: FILE: drivers/net/ethernet/ethoc.c:446:
> + int size = bd.stat >> 16;
> + struct sk_buff *skb;
>
should not this case be valid? Optically the longer line is already before the shorter.
I think that the whole point in using this reverse xmas tree ordering is to have
the code optically tidied up and not to enforce ordering between variable name lengths.
Regards,
Lino
^ permalink raw reply
* Re: [net-next PATCH 3/3] qdisc: catch misconfig of attaching qdisc to tx_queue_len zero device
From: Phil Sutter @ 2016-11-04 10:59 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netdev, Robert Olsson, Jamal Hadi Salim
In-Reply-To: <20161104111042.12a361ca@redhat.com>
On Fri, Nov 04, 2016 at 11:10:42AM +0100, Jesper Dangaard Brouer wrote:
>
> On Fri, 4 Nov 2016 10:35:26 +0100 Phil Sutter <phil@nwl.cc> wrote:
>
> > Hi,
> >
> > On Thu, Nov 03, 2016 at 02:56:11PM +0100, Jesper Dangaard Brouer wrote:
> > [...]
> > > diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> > > index 206dc24add3a..f337f1bdd1d4 100644
> > > --- a/net/sched/sch_api.c
> > > +++ b/net/sched/sch_api.c
> > > @@ -960,6 +960,17 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
> > >
> > > sch->handle = handle;
> > >
> > > + /* This exist to keep backward compatible with a userspace
> > > + * loophole, what allowed userspace to get IFF_NO_QUEUE
> > > + * facility on older kernels by setting tx_queue_len=0 (prior
> > > + * to qdisc init), and then forgot to reinit tx_queue_len
> > > + * before again attaching a qdisc.
> > > + */
> > > + if ((dev->priv_flags & IFF_NO_QUEUE) && (dev->tx_queue_len == 0)) {
> > > + dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
> > > + netdev_info(dev, "Caught tx_queue_len zero misconfig\n");
> > > + }
> >
> > I wonder why this is limited to IFF_NO_QUEUE devices. Do you think there
> > is a valid use case for physical ones?
>
> Hmmm, I cannot come up with a useful use-case for physical devices, but
> I cannot see why we should save users that had used the loophole on
> physical devices, as that is clearly a faulty config to begin with.
> See net_crit_ratelimited warning here:
> https://github.com/torvalds/linux/blob/v4.9-rc3/net/core/dev.c#L3403
I really feel like nit-picking again, but what differs in between
loophole users of virtual devices (whose broken scripts stopped working)
and loophole users of physical devices (whose broken scripts stopped
working as well)?
I we really take exposing broken userspace scripts as kernel bugs, don't
we have to take this one for the same as well?
> > Also, if we sanitize here, couldn't we then just get rid of the
> > sanitization you're fixing in patch 2?
>
> Without patch 2, then some IFF_NO_QUEUE devices would have a visible
> tx_queue_len 0 (e.g. the ones not calling ether_setup()), and that
> would be inconsistent (visible from userspace).
Ah, indeed. Although there's no functional difference, I guess it might
confuse people seeing an interface with 0 qlen performing properly.
Thanks, Phil
^ permalink raw reply
* RE: [PATCH net] sctp: assign assoc_id earlier in __sctp_connect
From: David Laight @ 2016-11-04 10:55 UTC (permalink / raw)
To: 'Marcelo Ricardo Leitner', netdev@vger.kernel.org
Cc: linux-sctp@vger.kernel.org, Vlad Yasevich, Neil Horman,
syzkaller@googlegroups.com, kcc@google.com, glider@google.com,
edumazet@google.com, dvyukov@google.com, andreyknvl@google.com
In-Reply-To: <9df38dcd0323ad92386eb6851a60dc128dd00b4e.1478199530.git.marcelo.leitner@gmail.com>
From: Of Marcelo Ricardo Leitner
> Sent: 03 November 2016 19:04
> sctp_wait_for_connect() currently already holds the asoc to keep it
> alive during the sleep, in case another thread release it. But Andrey
> Konovalov and Dmitry Vyukov reported an use-after-free in such
> situation.
>
> Problem is that __sctp_connect() doesn't get a ref on the asoc and will
> do a read on the asoc after calling sctp_wait_for_connect(), but by then
> another thread may have closed it and the _put on sctp_wait_for_connect
> will actually release it, causing the use-after-free.
>
> Fix is, instead of doing the read after waiting for the connect, do it
> before so, and avoid this issue as the socket is still locked by then.
> There should be no issue on returning the asoc id in case of failure as
> the application shouldn't trust on that number in such situations
> anyway.
>
> This issue doesn't exist in sctp_sendmsg() path.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Tested-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
> ---
> net/sctp/socket.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 6cdc61c21438aa9b6dbdad93e70759071a4d6789..be1d9bb98230c9d77f676949db773b2dacd801a4 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1214,9 +1214,12 @@ static int __sctp_connect(struct sock *sk,
>
> timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
>
> - err = sctp_wait_for_connect(asoc, &timeo);
> - if ((err == 0 || err == -EINPROGRESS) && assoc_id)
> + if (assoc_id)
> *assoc_id = asoc->assoc_id;
> + err = sctp_wait_for_connect(asoc, &timeo);
> + /* Note: the asoc may be freed after the return of
> + * sctp_wait_for_connect.
> + */
Is it worth ensuring that *assoc_id is NULL on error?
Maybe change the code to:
assoc_id_val = asoc->assoc_id;
rval = sctp_wait_for_connect(asoc, &timeo);
if (err != 0 && err != -EINPROGRESS)
assoc_id_val = 0;
if (assoc_id)
*assoc_id = assoc_id_val;
David
^ permalink raw reply
* Re: [Patch net] ipvs: use IPVS_CMD_ATTR_MAX for family.maxattr
From: Simon Horman @ 2016-11-04 10:58 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, netfilter-devel, andreyknvl, Pablo Neira Ayuso
In-Reply-To: <1478218443-11616-1-git-send-email-xiyou.wangcong@gmail.com>
On Thu, Nov 03, 2016 at 05:14:03PM -0700, Cong Wang wrote:
> family.maxattr is the max index for policy[], the size of
> ops[] is determined with ARRAY_SIZE().
>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Tested-by: Andrey Konovalov <andreyknvl@google.com>
> Cc: Pablo Neira Ayuso <pablo@netfilter.org>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Pablo, can you take this one into nf?
> ---
> net/netfilter/ipvs/ip_vs_ctl.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> index c3c809b..a6e44ef 100644
> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
> @@ -2845,7 +2845,7 @@ static struct genl_family ip_vs_genl_family = {
> .hdrsize = 0,
> .name = IPVS_GENL_NAME,
> .version = IPVS_GENL_VERSION,
> - .maxattr = IPVS_CMD_MAX,
> + .maxattr = IPVS_CMD_ATTR_MAX,
> .netnsok = true, /* Make ipvsadm to work on netns */
> };
>
> --
> 2.1.0
>
^ permalink raw reply
* Re: [net-next PATCH 2/3] net/qdisc: IFF_NO_QUEUE drivers should use consistent TX queue len
From: Jesper Dangaard Brouer @ 2016-11-04 10:56 UTC (permalink / raw)
To: Krister Johansen
Cc: netdev, Phil Sutter, Robert Olsson, Jamal Hadi Salim, brouer
In-Reply-To: <20161103205440.GB2940@templeofstupid.com>
On Thu, 3 Nov 2016 13:54:40 -0700
Krister Johansen <kjlx@templeofstupid.com> wrote:
> On Thu, Nov 03, 2016 at 02:56:06PM +0100, Jesper Dangaard Brouer wrote:
> > The flag IFF_NO_QUEUE marks virtual device drivers that doesn't need a
> > default qdisc attached, given they will be backed by physical device,
> > that already have a qdisc attached for pushback.
> >
> > It is still supported to attach a qdisc to a IFF_NO_QUEUE device, as
> > this can be useful for difference policy reasons (e.g. bandwidth
> > limiting containers). For this to work, the tx_queue_len need to have
> > a sane value, because some qdiscs inherit/copy the tx_queue_len
> > (namely, pfifo, bfifo, gred, htb, plug and sfb).
> >
> > Commit a813104d9233 ("IFF_NO_QUEUE: Fix for drivers not calling
> > ether_setup()") caught situations where some drivers didn't initialize
> > tx_queue_len. The problem with the commit was choosing 1 as the
> > fallback value.
> >
> > A qdisc queue length of 1 causes more harm than good, because it
> > creates hard to debug situations for userspace. It gives userspace a
> > false sense of a working config after attaching a qdisc. As low
> > volume traffic (that doesn't activate the qdisc policy) works,
> > like ping, while traffic that e.g. needs shaping cannot reach the
> > configured policy levels, given the queue length is too small.
>
> Thanks for fixing this. I've run into this in the exact scenario you
> describe -- bandwith limiting containers. I'm pretty sure my vote
> doesn't count, but I'm in favor of this change.
Thanks for confirming the problem. You voice is actually very important
in matters like this. It is important to know if people were actually
hit by this.
My own story is that I was hit by this subtle queue length 1 problem
approx 11 years ago without noticing. An ISP were doing qdisc shaping
(with HTB) on VLAN devices. The original guy who developed the system
were fired because Internet customers were not getting the bandwidth
they paid for. I were hired to fix the problem, and unknowingly fixed
it (and bufferbloat) by using SFQ instead of pfifo_fast as leaf qdisc.
I actually didn't realize the root-cause until Oct 2014, see[1].
(I also ended-up fixing other scalability issues in iptables[2])
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1152231
[2] http://people.netfilter.org/hawk/presentations/osd2008/
^ permalink raw reply
* [PATCH] virtio-net: drop legacy features in virtio 1 mode
From: Michael S. Tsirkin @ 2016-11-04 10:55 UTC (permalink / raw)
To: linux-kernel; +Cc: stable, Jason Wang, virtualization, netdev
Virtio 1.0 spec says VIRTIO_F_ANY_LAYOUT and VIRTIO_NET_F_GSO are
legacy-only feature bits. Do not negotiate them in virtio 1 mode. Note
this is a spec violation so we need to backport it to stable/downstream
kernels.
Cc: stable@vger.kernel.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7a00365..b19fb4d 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2089,23 +2089,33 @@ static struct virtio_device_id id_table[] = {
{ 0 },
};
+#define VIRTNET_FEATURES \
+ VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, \
+ VIRTIO_NET_F_MAC, \
+ VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
+ VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
+ VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \
+ VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \
+ VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
+ VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
+ VIRTIO_NET_F_CTRL_MAC_ADDR, \
+ VIRTIO_NET_F_MTU
+
static unsigned int features[] = {
- VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
- VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
- VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
- VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
- VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
- VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
- VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
- VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
- VIRTIO_NET_F_CTRL_MAC_ADDR,
+ VIRTNET_FEATURES,
+};
+
+static unsigned int features_legacy[] = {
+ VIRTNET_FEATURES,
+ VIRTIO_NET_F_GSO,
VIRTIO_F_ANY_LAYOUT,
- VIRTIO_NET_F_MTU,
};
static struct virtio_driver virtio_net_driver = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
+ .feature_table_legacy = features_legacy,
+ .feature_table_size_legacy = ARRAY_SIZE(features_legacy),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,
--
MST
^ permalink raw reply related
* Re: [RFC PATCH v2 0/5] ARM64: Add Internal PHY support for Meson GXL
From: Neil Armstrong @ 2016-11-04 10:55 UTC (permalink / raw)
To: f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, khilman-rdvid1DuHRBWk0Htik3J/w,
carlo-KA+7E9HrN00dnm+yROfE0A, andrew-g2DYL2Zd6BY
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/31/2016 05:56 PM, Neil Armstrong wrote:
> The Amlogic Meson GXL SoCs have an internal RMII PHY that is muxed with the
> external RGMII pins.
>
> In order to support switching between the two PHYs links, extended registers
> size for mdio-mux-mmioreg must be added.
>
> Finally, the internal PHY is added in the GXL dtsi and support for each
> board is added in intermediate board family dtsi or final dts.
>
> This patchset depends on ARM64 dts patch at [1]
>
> Changes since original RFC patchset at : [2]
> - Remove meson8b experimental phy switching
> - Switch to mdio-mux-mmioreg with extennded size support
> - Add internal phy support for S905x and p231
> - Add external PHY support for p230
>
> [1] http://lkml.kernel.org/r/1477932286-27482-1-git-send-email-narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org
> [2] http://lkml.kernel.org/r/1477060838-14164-1-git-send-email-narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org
>
> Neil Armstrong (5):
> net: mdio-mux-mmioreg: Add support for 16bit and 32bit register sizes
> net: phy: Add Meson GXL Internal PHY driver
> ARM64: dts: meson-gxl: Add ethernet nodes with internal PHY
> ARM64: dts: meson-gxl-p23x: Enable ethernet
> ARM64: dts: meson-gxl-s905x: Enable internal ethernet PHY
>
> .../devicetree/bindings/net/mdio-mux-mmioreg.txt | 4 +-
> .../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 16 +++++
> .../boot/dts/amlogic/meson-gxl-s905d-p231.dts | 6 ++
> .../boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi | 4 ++
> arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi | 6 ++
> arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 45 ++++++++++++
> drivers/net/phy/Kconfig | 5 ++
> drivers/net/phy/Makefile | 1 +
> drivers/net/phy/mdio-mux-mmioreg.c | 60 ++++++++++++----
> drivers/net/phy/meson-gxl.c | 81 ++++++++++++++++++++++
> 10 files changed, 213 insertions(+), 15 deletions(-)
> create mode 100644 drivers/net/phy/meson-gxl.c
>
Hi Florian, Andrew, Sergei,
Thanks for reviews,
Since the meson-gxl dtsi has a lot of changes pending, the patches 3, 4 & 5 will be sent in a separate patchset,
and patches 1 & 2 will be send to netdev -next.
Neil
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net] sctp: assign assoc_id earlier in __sctp_connect
From: Xin Long @ 2016-11-04 10:45 UTC (permalink / raw)
To: Marcelo Ricardo Leitner
Cc: network dev, linux-sctp, Vlad Yasevich, Neil Horman, syzkaller,
Kostya Serebryany, Alexander Potapenko, Eric Dumazet,
Dmitry Vyukov, Andrey Konovalov
In-Reply-To: <9df38dcd0323ad92386eb6851a60dc128dd00b4e.1478199530.git.marcelo.leitner@gmail.com>
On Fri, Nov 4, 2016 at 3:03 AM, Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
> sctp_wait_for_connect() currently already holds the asoc to keep it
> alive during the sleep, in case another thread release it. But Andrey
> Konovalov and Dmitry Vyukov reported an use-after-free in such
> situation.
>
> Problem is that __sctp_connect() doesn't get a ref on the asoc and will
> do a read on the asoc after calling sctp_wait_for_connect(), but by then
> another thread may have closed it and the _put on sctp_wait_for_connect
> will actually release it, causing the use-after-free.
>
> Fix is, instead of doing the read after waiting for the connect, do it
> before so, and avoid this issue as the socket is still locked by then.
> There should be no issue on returning the asoc id in case of failure as
> the application shouldn't trust on that number in such situations
> anyway.
>
> This issue doesn't exist in sctp_sendmsg() path.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Tested-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Reviewed-by: Xin Long <lucien.xin@gmail.com>
^ permalink raw reply
* [PATCH ethtool 2/2] Ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE and PHY downshift
From: Allan W. Nielsen @ 2016-11-04 10:36 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255805-25823-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Add ethtool get and set tunable to access PHY drivers.
Ethtool Help: ethtool -h for PHY tunables
ethtool --set-phy-tunable DEVNAME Set PHY tunable
[ downshift on|off|%d ]
ethtool --get-phy-tunable DEVNAME Get PHY tunable
[ downshift ]
Ethtool ex:
ethtool --set-phy-tuanble eth0 downshift on
ethtool --set-phy-tuanble eth0 downshift off
ethtool --set-phy-tuanble eth0 downshift 2
ethtool --get-phy-tunable eth0 downshift
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
ethtool.8.in | 27 ++++++++++++++++++
ethtool.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+)
diff --git a/ethtool.8.in b/ethtool.8.in
index 9631847..e1fd51f 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -340,6 +340,14 @@ ethtool \- query or control network driver and hardware settings
.B2 tx-lpi on off
.BN tx-timer
.BN advertise
+.HP
+.B ethtool \-\-set\-phy\-tunable
+.I devname
+.B3 downshift on off N
+.HP
+.B ethtool \-\-get\-phy\-tunable
+.I devname
+.RB [ downshift ]
.
.\" Adjust lines (i.e. full justification) and hyphenate.
.ad
@@ -947,6 +955,25 @@ Values are as for
Sets the amount of time the device should stay in idle mode prior to asserting
its Tx LPI (in microseconds). This has meaning only when Tx LPI is enabled.
.RE
+.TP
+.B \-\-set\-phy\-tunable
+Sets the PHY tunable parameters.
+.RS 4
+.TP
+.A2 downshift on off
+Specifies whether downshift should be enabled
+.TP
+.BI downshift \ N
+Sets the PHY downshift count.
+.RE
+.TP
+.B \-\-get\-phy\-tunable
+Gets the PHY tunable parameters.
+.RS 4
+.TP
+.B downshift
+Gets the PHY downshift count/status.
+.RE
.SH BUGS
Not supported (in part or whole) on all network drivers.
.SH AUTHOR
diff --git a/ethtool.c b/ethtool.c
index 49ac94e..c9a0a1d 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4520,6 +4520,94 @@ static int do_seee(struct cmd_context *ctx)
return 0;
}
+static int do_get_phy_tunable(struct cmd_context *ctx)
+{
+ int argc = ctx->argc;
+ char **argp = ctx->argp;
+ int err, i;
+ u8 downshift_changed;
+
+ if (argc < 1)
+ exit_bad_args();
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argp[i], "downshift")) {
+ downshift_changed = 1;
+ i += 1;
+ } else {
+ exit_bad_args();
+ }
+ }
+
+ if (downshift_changed) {
+ struct ethtool_tunable ds;
+ u8 count = 0;
+
+ ds.cmd = ETHTOOL_PHY_GTUNABLE;
+ ds.id = ETHTOOL_PHY_DOWNSHIFT;
+ ds.type_id = ETHTOOL_TUNABLE_U8;
+ ds.len = 1;
+ ds.data[0] = &count;
+ err = send_ioctl(ctx, &ds);
+ if (err < 0) {
+ perror("Cannot Get PHY downshift count");
+ err = 87;
+ }
+ count = *((u8 *)&ds.data[0]);
+ if (count)
+ fprintf(stdout, " Downshift count: %d\n",
+ count);
+ else
+ fprintf(stdout, " Downshift disabled\n");
+ }
+
+ return err;
+}
+
+static int do_set_phy_tunable(struct cmd_context *ctx)
+{
+ int argc = ctx->argc;
+ char **argp = ctx->argp;
+ int err, i;
+ u8 downshift_changed, downshift_wanted = 0;
+
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argp[i], "downshift")) {
+ downshift_changed = 1;
+ i += 1;
+ if (i >= argc)
+ exit_bad_args();
+ if (!strcmp(argp[i], "on"))
+ downshift_wanted = DOWNSHIFT_DEV_DEFAULT_COUNT;
+ else if (!strcmp(argp[i], "off"))
+ downshift_wanted = DOWNSHIFT_DEV_DISABLE;
+ else
+ downshift_wanted =
+ get_uint_range(argp[i], 0, 0xff);
+ } else {
+ exit_bad_args();
+ }
+ }
+
+ if (downshift_changed) {
+ struct ethtool_tunable ds;
+ u8 count;
+
+ ds.cmd = ETHTOOL_PHY_STUNABLE;
+ ds.id = ETHTOOL_PHY_DOWNSHIFT;
+ ds.type_id = ETHTOOL_TUNABLE_U8;
+ ds.len = 1;
+ ds.data[0] = &count;
+ *((u8 *)&ds.data[0]) = downshift_wanted;
+ err = send_ioctl(ctx, &ds);
+ if (err < 0) {
+ perror("Cannot Set PHY downshift count");
+ err = 87;
+ }
+ }
+
+ return err;
+}
+
#ifndef TEST_ETHTOOL
int send_ioctl(struct cmd_context *ctx, void *cmd)
{
@@ -4681,6 +4769,10 @@ static const struct option {
" [ advertise %x ]\n"
" [ tx-lpi on|off ]\n"
" [ tx-timer %d ]\n"},
+ { "--set-phy-tunable", 1, do_set_phy_tunable, "Set PHY tunable",
+ " [ downshift on|off|%d ]\n"},
+ { "--get-phy-tunable", 1, do_get_phy_tunable, "Get PHY tunable",
+ " [ downshift ]\n"},
{ "-h|--help", 0, show_usage, "Show this help" },
{ "--version", 0, do_version, "Show version number" },
{}
--
2.7.3
^ permalink raw reply related
* [PATCH ethtool 1/2] ethtool-copy.h:sync with net
From: Allan W. Nielsen @ 2016-11-04 10:36 UTC (permalink / raw)
To: netdev; +Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh
In-Reply-To: <1478255805-25823-1-git-send-email-allan.nielsen@microsemi.com>
This covers kernel changes upto:
commit 67168af82f30bacbd734a4472670cba6b3d6fd36
Author: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Date: Wed Nov 2 11:35:12 2016 +0530
ethtool: (uapi) Add ETHTOOL_PHY_DOWNSHIFT to PHY tunables
For operation in cabling environments that are incompatible with 1000BAST-T, PHY
device may provide an automatic link speed downshift operation. When enabled,
the device automatically changes its 1000BAST-T auto-negotiation to the next
slower speed after a configured number of failed attempts at 1000BAST-T. This
feature is useful in setting up in networks using older cable installations that
include only pairs A and B, and not pairs C and D.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
ethtool-copy.h | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index 70748f5..040c5b5 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -10,14 +10,16 @@
* Portions Copyright (C) Sun Microsystems 2008
*/
-#ifndef _LINUX_ETHTOOL_H
-#define _LINUX_ETHTOOL_H
+#ifndef _UAPI_LINUX_ETHTOOL_H
+#define _UAPI_LINUX_ETHTOOL_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/if_ether.h>
+#ifndef __KERNEL__
#include <limits.h> /* for INT_MAX */
+#endif
/* All structures exposed to userland should be defined such that they
* have the same layout for 32-bit and 64-bit userland.
@@ -114,15 +116,14 @@ struct ethtool_cmd {
__u32 reserved[2];
};
-static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
+static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
__u32 speed)
{
-
- ep->speed = (__u16)speed;
+ ep->speed = (__u16)(speed & 0xFFFF);
ep->speed_hi = (__u16)(speed >> 16);
}
-static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
{
return (ep->speed_hi << 16) | ep->speed;
}
@@ -247,6 +248,14 @@ struct ethtool_tunable {
void *data[0];
};
+#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
+#define DOWNSHIFT_DEV_DISABLE 0
+
+enum phy_tunable_id {
+ ETHTOOL_PHY_ID_UNSPEC,
+ ETHTOOL_PHY_DOWNSHIFT,
+};
+
/**
* struct ethtool_regs - hardware register dump
* @cmd: Command number = %ETHTOOL_GREGS
@@ -878,12 +887,12 @@ struct ethtool_rx_flow_spec {
#define ETHTOOL_RX_FLOW_SPEC_RING 0x00000000FFFFFFFFLL
#define ETHTOOL_RX_FLOW_SPEC_RING_VF 0x000000FF00000000LL
#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32
-static __inline__ __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
+static inline __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
{
return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie;
};
-static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
+static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
{
return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >>
ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
@@ -1312,7 +1321,8 @@ struct ethtool_per_queue_op {
#define ETHTOOL_GLINKSETTINGS 0x0000004c /* Get ethtool_link_settings */
#define ETHTOOL_SLINKSETTINGS 0x0000004d /* Set ethtool_link_settings */
-
+#define ETHTOOL_PHY_GTUNABLE 0x0000004e /* Get PHY tunable configuration */
+#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -1483,7 +1493,7 @@ enum ethtool_link_mode_bit_indices {
#define SPEED_UNKNOWN -1
-static __inline__ int ethtool_validate_speed(__u32 speed)
+static inline int ethtool_validate_speed(__u32 speed)
{
return speed <= INT_MAX || speed == SPEED_UNKNOWN;
}
@@ -1493,7 +1503,7 @@ static __inline__ int ethtool_validate_speed(__u32 speed)
#define DUPLEX_FULL 0x01
#define DUPLEX_UNKNOWN 0xff
-static __inline__ int ethtool_validate_duplex(__u8 duplex)
+static inline int ethtool_validate_duplex(__u8 duplex)
{
switch (duplex) {
case DUPLEX_HALF:
@@ -1743,4 +1753,4 @@ struct ethtool_link_settings {
* __u32 map_lp_advertising[link_mode_masks_nwords];
*/
};
-#endif /* _LINUX_ETHTOOL_H */
+#endif /* _UAPI_LINUX_ETHTOOL_H */
--
2.7.3
^ permalink raw reply related
* [PATCH ethtool 0/2] Adding downshift support to ethtool
From: Allan W. Nielsen @ 2016-11-04 10:36 UTC (permalink / raw)
To: netdev; +Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh
Hi All,
This patch implements for set/get downshifting.
Downshifting can either be turned on/off, or it can be configured to a
specifc count.
If no "count" are provided, then it is up to the individual PHY driver to
configure a default count.
Best regards
Allan and Raju
Allan W. Nielsen (1):
ethtool-copy.h:sync with net
Raju Lakkaraju (1):
Ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE and PHY
downshift
ethtool-copy.h | 34 ++++++++++++++--------
ethtool.8.in | 27 +++++++++++++++++
ethtool.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+), 12 deletions(-)
--
2.7.3
^ permalink raw reply
* [PATCH net-next 2/5] ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255742-25693-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Adding get_tunable/set_tunable function pointer to the phy_driver
structure, and uses these function pointers to implement the
ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE ioctls.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
include/linux/phy.h | 7 +++++
net/core/ethtool.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e7e1fd3..d30daf8 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -611,6 +611,13 @@ struct phy_driver {
void (*get_strings)(struct phy_device *dev, u8 *data);
void (*get_stats)(struct phy_device *dev,
struct ethtool_stats *stats, u64 *data);
+
+ /* Get and Set PHY tunables */
+ int (*get_tunable)(struct phy_device *dev,
+ struct ethtool_tunable *tuna, void *data);
+ int (*set_tunable)(struct phy_device *dev,
+ struct ethtool_tunable *tuna,
+ const void *data);
};
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
struct phy_driver, mdiodrv)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 9774898..75f19ab 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -2422,6 +2422,76 @@ static int ethtool_set_per_queue(struct net_device *dev, void __user *useraddr)
};
}
+static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
+{
+ switch (tuna->id) {
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
+{
+ int ret;
+ struct ethtool_tunable tuna;
+ struct phy_device *phydev = dev->phydev;
+ void *data;
+
+ if (!(phydev && phydev->drv && phydev->drv->get_tunable))
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
+ return -EFAULT;
+ ret = ethtool_phy_tunable_valid(&tuna);
+ if (ret)
+ return ret;
+ data = kmalloc(tuna.len, GFP_USER);
+ if (!data)
+ return -ENOMEM;
+ ret = phydev->drv->get_tunable(phydev, &tuna, data);
+ if (ret)
+ goto out;
+ useraddr += sizeof(tuna);
+ ret = -EFAULT;
+ if (copy_to_user(useraddr, data, tuna.len))
+ goto out;
+ ret = 0;
+
+out:
+ kfree(data);
+ return ret;
+}
+
+static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
+{
+ int ret;
+ struct ethtool_tunable tuna;
+ struct phy_device *phydev = dev->phydev;
+ void *data;
+
+ if (!(phydev && phydev->drv && phydev->drv->set_tunable))
+ return -EOPNOTSUPP;
+ if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
+ return -EFAULT;
+ ret = ethtool_phy_tunable_valid(&tuna);
+ if (ret)
+ return ret;
+ data = kmalloc(tuna.len, GFP_USER);
+ if (!data)
+ return -ENOMEM;
+ useraddr += sizeof(tuna);
+ ret = -EFAULT;
+ if (copy_from_user(data, useraddr, tuna.len))
+ goto out;
+ ret = phydev->drv->set_tunable(phydev, &tuna, data);
+
+out:
+ kfree(data);
+ return ret;
+}
+
/* The main entry point in this file. Called from net/core/dev_ioctl.c */
int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -2479,6 +2549,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GET_TS_INFO:
case ETHTOOL_GEEE:
case ETHTOOL_GTUNABLE:
+ case ETHTOOL_PHY_GTUNABLE:
break;
default:
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -2684,6 +2755,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_SLINKSETTINGS:
rc = ethtool_set_link_ksettings(dev, useraddr);
break;
+ case ETHTOOL_PHY_GTUNABLE:
+ rc = get_phy_tunable(dev, useraddr);
+ break;
+ case ETHTOOL_PHY_STUNABLE:
+ rc = set_phy_tunable(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
--
2.7.3
^ permalink raw reply related
* [PATCH net-next 3/5] ethtool: (uapi) Add ETHTOOL_PHY_DOWNSHIFT to PHY tunables
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255742-25693-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
For operation in cabling environments that are incompatible with
1000BAST-T, PHY device may provide an automatic link speed downshift
operation. When enabled, the device automatically changes its 1000BAST-T
auto-negotiation to the next slower speed after a configured number of
failed attempts at 1000BAST-T. This feature is useful in setting up in
networks using older cable installations that include only pairs A and B,
and not pairs C and D.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
include/uapi/linux/ethtool.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index fd0bd36..040c5b5 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -248,8 +248,12 @@ struct ethtool_tunable {
void *data[0];
};
+#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
+#define DOWNSHIFT_DEV_DISABLE 0
+
enum phy_tunable_id {
ETHTOOL_PHY_ID_UNSPEC,
+ ETHTOOL_PHY_DOWNSHIFT,
};
/**
--
2.7.3
^ permalink raw reply related
* [PATCH net-next 1/5] ethtool: (uapi) Add ETHTOOL_PHY_GTUNABLE and ETHTOOL_PHY_STUNABLE
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh,
Raju Lakkaraju
In-Reply-To: <1478255742-25693-1-git-send-email-allan.nielsen@microsemi.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Defines a generic API to get/set phy tunables. The API is using the
existing ethtool_tunable/tunable_type_id types which is already being used
for mac level tunables.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
---
include/uapi/linux/ethtool.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 8e54723..fd0bd36 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -248,6 +248,10 @@ struct ethtool_tunable {
void *data[0];
};
+enum phy_tunable_id {
+ ETHTOOL_PHY_ID_UNSPEC,
+};
+
/**
* struct ethtool_regs - hardware register dump
* @cmd: Command number = %ETHTOOL_GREGS
@@ -1313,7 +1317,8 @@ struct ethtool_per_queue_op {
#define ETHTOOL_GLINKSETTINGS 0x0000004c /* Get ethtool_link_settings */
#define ETHTOOL_SLINKSETTINGS 0x0000004d /* Set ethtool_link_settings */
-
+#define ETHTOOL_PHY_GTUNABLE 0x0000004e /* Get PHY tunable configuration */
+#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
--
2.7.3
^ permalink raw reply related
* [PATCH net-next 0/5] Adding PHY-Tunables and downshift support
From: Allan W. Nielsen @ 2016-11-04 10:35 UTC (permalink / raw)
To: netdev; +Cc: andrew, f.fainelli, raju.lakkaraju, allan.nielsen, cphealy, robh
Hi All,
This series add support for PHY tunables, and uses this facility to configure
downshifting. The downshifting mechanism is implemented for MSCC phys.
This series tries to address the comments provided back in mid October when this
feature was posted along with fast-link-failure. Fast-link-failure has been
separated out, but we would like to pick continue on that if/when we agree on
how the phy-tunables and downshifting should be done.
The proposed generic interface is similar to ETHTOOL_GTUNABLE/ETHTOOL_STUNABLE,
it uses the same type (ethtool_tunable/tunable_type_id) but a new enum
(phy_tunable_id) is added to reflect the PHY tunable.
The implementation just call the newly added function pointers in
get_tunable/set_tunable phy_device structure.
To configure downshifting, the ethtool_tunable structure is used. 'id' must be
set to 'ETHTOOL_PHY_DOWNSHIFT', 'type_id' must be set to 'ETHTOOL_TUNABLE_U8'
and 'data' value configure the amount of downshift re-tries.
If configured to DOWNSHIFT_DEV_DISABLE, then downshift is disabled
If configured to DOWNSHIFT_DEV_DEFAULT_COUNT, then it is up to the device to
choose a device-specific re-try count.
Patches to implement this in ethtool will follow in a few minutes.
Please review.
Best regards
Allan and Raju
Raju Lakkaraju (5):
ethtool: (uapi) Add ETHTOOL_PHY_GTUNABLE and ETHTOOL_PHY_STUNABLE
ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE
ethtool: (uapi) Add ETHTOOL_PHY_DOWNSHIFT to PHY tunables
ethtool: Core impl for ETHTOOL_PHY_DOWNSHIFT tunable
net: phy: Add downshift get/set support in Microsemi PHYs driver
drivers/net/phy/mscc.c | 102 +++++++++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 7 +++
include/uapi/linux/ethtool.h | 11 ++++-
net/core/ethtool.c | 82 ++++++++++++++++++++++++++++++++++
4 files changed, 201 insertions(+), 1 deletion(-)
--
2.7.3
^ permalink raw reply
* [PATCH net-next v4 6/9] ipv6: sr: add calls to verify and insert HMAC signatures
From: David Lebrun @ 2016-11-04 10:32 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1478255388-32213-1-git-send-email-david.lebrun@uclouvain.be>
This patch enables the verification of the HMAC signature for transiting
SR-enabled packets, and its insertion on encapsulated/injected SRH.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/exthdrs.c | 10 ++++++++++
net/ipv6/seg6_iptunnel.c | 21 +++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 21a86cf..973a128e 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -49,6 +49,9 @@
#endif
#include <linux/seg6.h>
#include <net/seg6.h>
+#ifdef CONFIG_IPV6_SEG6_HMAC
+#include <net/seg6_hmac.h>
+#endif
#include <linux/uaccess.h>
@@ -340,6 +343,13 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
return -1;
}
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ if (!seg6_hmac_validate_skb(skb)) {
+ kfree_skb(skb);
+ return -1;
+ }
+#endif
+
looped_back:
if (hdr->segments_left > 0) {
if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 &&
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 9abeb45..4a3f1ba 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -29,6 +29,9 @@
#ifdef CONFIG_DST_CACHE
#include <net/dst_cache.h>
#endif
+#ifdef CONFIG_IPV6_SEG6_HMAC
+#include <net/seg6_hmac.h>
+#endif
struct seg6_lwt {
#ifdef CONFIG_DST_CACHE
@@ -130,6 +133,14 @@ static int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
hdr->daddr = isrh->segments[isrh->first_segment];
set_tun_src(net, skb->dev, &hdr->daddr, &hdr->saddr);
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ if (sr_has_hmac(isrh)) {
+ err = seg6_push_hmac(net, &hdr->saddr, isrh);
+ if (unlikely(err))
+ return err;
+ }
+#endif
+
skb_postpush_rcsum(skb, hdr, tot_len);
return 0;
@@ -171,6 +182,16 @@ static int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
isrh->segments[0] = hdr->daddr;
hdr->daddr = isrh->segments[isrh->first_segment];
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ if (sr_has_hmac(isrh)) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ err = seg6_push_hmac(net, &hdr->saddr, isrh);
+ if (unlikely(err))
+ return err;
+ }
+#endif
+
skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);
return 0;
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v4 5/9] ipv6: sr: implement API to control SR HMAC structure
From: David Lebrun @ 2016-11-04 10:32 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1478255388-32213-1-git-send-email-david.lebrun@uclouvain.be>
This patch provides an implementation of the genetlink commands
to associate a given HMAC key identifier with an hashing algorithm
and a secret.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/seg6.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 229 insertions(+)
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 8114ece..7e44c12 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -25,6 +25,9 @@
#include <net/genetlink.h>
#include <linux/seg6.h>
#include <linux/seg6_genl.h>
+#ifdef CONFIG_IPV6_SEG6_HMAC
+#include <net/seg6_hmac.h>
+#endif
static struct genl_family seg6_genl_family;
@@ -39,11 +42,90 @@ static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {
[SEG6_ATTR_HMACINFO] = { .type = NLA_NESTED, },
};
+#ifdef CONFIG_IPV6_SEG6_HMAC
+
+static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
+{
+ struct net *net = genl_info_net(info);
+ struct seg6_pernet_data *sdata;
+ struct seg6_hmac_info *hinfo;
+ u32 hmackeyid;
+ char *secret;
+ int err = 0;
+ u8 algid;
+ u8 slen;
+
+ sdata = seg6_pernet(net);
+
+ if (!info->attrs[SEG6_ATTR_HMACKEYID] ||
+ !info->attrs[SEG6_ATTR_SECRETLEN] ||
+ !info->attrs[SEG6_ATTR_ALGID])
+ return -EINVAL;
+
+ hmackeyid = nla_get_u32(info->attrs[SEG6_ATTR_HMACKEYID]);
+ slen = nla_get_u8(info->attrs[SEG6_ATTR_SECRETLEN]);
+ algid = nla_get_u8(info->attrs[SEG6_ATTR_ALGID]);
+
+ if (hmackeyid == 0)
+ return -EINVAL;
+
+ if (slen > SEG6_HMAC_SECRET_LEN)
+ return -EINVAL;
+
+ mutex_lock(&sdata->lock);
+ hinfo = seg6_hmac_info_lookup(net, hmackeyid);
+
+ if (!slen) {
+ if (!hinfo)
+ err = -ENOENT;
+
+ err = seg6_hmac_info_del(net, hmackeyid);
+
+ goto out_unlock;
+ }
+
+ if (!info->attrs[SEG6_ATTR_SECRET]) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (hinfo) {
+ err = seg6_hmac_info_del(net, hmackeyid);
+ if (err)
+ goto out_unlock;
+ }
+
+ secret = (char *)nla_data(info->attrs[SEG6_ATTR_SECRET]);
+
+ hinfo = kzalloc(sizeof(*hinfo), GFP_KERNEL);
+ if (!hinfo) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ memcpy(hinfo->secret, secret, slen);
+ hinfo->slen = slen;
+ hinfo->alg_id = algid;
+ hinfo->hmackeyid = hmackeyid;
+
+ err = seg6_hmac_info_add(net, hmackeyid, hinfo);
+ if (err)
+ kfree(hinfo);
+
+out_unlock:
+ mutex_unlock(&sdata->lock);
+ return err;
+}
+
+#else
+
static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
{
return -ENOTSUPP;
}
+#endif
+
static int seg6_genl_set_tunsrc(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
@@ -108,11 +190,135 @@ static int seg6_genl_get_tunsrc(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
}
+#ifdef CONFIG_IPV6_SEG6_HMAC
+
+static int __seg6_hmac_fill_info(struct seg6_hmac_info *hinfo,
+ struct sk_buff *msg)
+{
+ if (nla_put_u32(msg, SEG6_ATTR_HMACKEYID, hinfo->hmackeyid) ||
+ nla_put_u8(msg, SEG6_ATTR_SECRETLEN, hinfo->slen) ||
+ nla_put(msg, SEG6_ATTR_SECRET, hinfo->slen, hinfo->secret) ||
+ nla_put_u8(msg, SEG6_ATTR_ALGID, hinfo->alg_id))
+ return -1;
+
+ return 0;
+}
+
+static int __seg6_genl_dumphmac_element(struct seg6_hmac_info *hinfo,
+ u32 portid, u32 seq, u32 flags,
+ struct sk_buff *skb, u8 cmd)
+{
+ void *hdr;
+
+ hdr = genlmsg_put(skb, portid, seq, &seg6_genl_family, flags, cmd);
+ if (!hdr)
+ return -ENOMEM;
+
+ if (__seg6_hmac_fill_info(hinfo, skb) < 0)
+ goto nla_put_failure;
+
+ genlmsg_end(skb, hdr);
+ return 0;
+
+nla_put_failure:
+ genlmsg_cancel(skb, hdr);
+ return -EMSGSIZE;
+}
+
+static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
+{
+ struct net *net = sock_net(cb->skb->sk);
+ struct seg6_pernet_data *sdata;
+ struct rhashtable_iter *iter;
+
+ sdata = seg6_pernet(net);
+ iter = (struct rhashtable_iter *)cb->args[0];
+
+ if (!iter) {
+ iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+ if (!iter)
+ return -ENOMEM;
+
+ cb->args[0] = (long)iter;
+ }
+
+ rhashtable_walk_enter(&sdata->hmac_infos, iter);
+
+ return 0;
+}
+
+static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
+{
+ struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
+
+ rhashtable_walk_exit(iter);
+
+ kfree(iter);
+
+ return 0;
+}
+
+static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
+ struct net *net = sock_net(skb->sk);
+ struct seg6_pernet_data *sdata;
+ struct seg6_hmac_info *hinfo;
+ int ret;
+
+ sdata = seg6_pernet(net);
+
+ ret = rhashtable_walk_start(iter);
+ if (ret && ret != -EAGAIN)
+ goto done;
+
+ for (;;) {
+ hinfo = rhashtable_walk_next(iter);
+
+ if (IS_ERR(hinfo)) {
+ if (PTR_ERR(hinfo) == -EAGAIN)
+ continue;
+ ret = PTR_ERR(hinfo);
+ goto done;
+ } else if (!hinfo) {
+ break;
+ }
+
+ ret = __seg6_genl_dumphmac_element(hinfo,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ skb, SEG6_CMD_DUMPHMAC);
+ if (ret)
+ goto done;
+ }
+
+ ret = skb->len;
+
+done:
+ rhashtable_walk_stop(iter);
+ return ret;
+}
+
+#else
+
+static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
+{
+ return 0;
+}
+
+static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
+{
+ return 0;
+}
+
static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
{
return -ENOTSUPP;
}
+#endif
+
static int __net_init seg6_net_init(struct net *net)
{
struct seg6_pernet_data *sdata;
@@ -131,6 +337,10 @@ static int __net_init seg6_net_init(struct net *net)
net->ipv6.seg6_data = sdata;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_net_init(net);
+#endif
+
return 0;
}
@@ -138,6 +348,10 @@ static void __net_exit seg6_net_exit(struct net *net)
{
struct seg6_pernet_data *sdata = seg6_pernet(net);
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_net_exit(net);
+#endif
+
kfree(sdata->tun_src);
kfree(sdata);
}
@@ -156,7 +370,9 @@ static const struct genl_ops seg6_genl_ops[] = {
},
{
.cmd = SEG6_CMD_DUMPHMAC,
+ .start = seg6_genl_dumphmac_start,
.dumpit = seg6_genl_dumphmac,
+ .done = seg6_genl_dumphmac_done,
.policy = seg6_genl_policy,
.flags = GENL_ADMIN_PERM,
},
@@ -202,10 +418,20 @@ int __init seg6_init(void)
if (err)
goto out_unregister_pernet;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ err = seg6_hmac_init();
+ if (err)
+ goto out_unregister_iptun;
+#endif
+
pr_info("Segment Routing with IPv6\n");
out:
return err;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+out_unregister_iptun:
+ seg6_iptunnel_exit();
+#endif
out_unregister_pernet:
unregister_pernet_subsys(&ip6_segments_ops);
out_unregister_genl:
@@ -215,6 +441,9 @@ int __init seg6_init(void)
void seg6_exit(void)
{
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_exit();
+#endif
seg6_iptunnel_exit();
unregister_pernet_subsys(&ip6_segments_ops);
genl_unregister_family(&seg6_genl_family);
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v4 7/9] ipv6: add source address argument for ipv6_push_nfrag_opts
From: David Lebrun @ 2016-11-04 10:32 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1478255388-32213-1-git-send-email-david.lebrun@uclouvain.be>
This patch prepares for insertion of SRH through setsockopt().
The new source address argument is used when an HMAC field is
present in the SRH, which must be filled. The HMAC signature
process requires the source address as input text.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
include/net/ipv6.h | 3 ++-
net/ipv6/exthdrs.c | 6 +++---
net/ipv6/ip6_output.c | 5 +++--
net/ipv6/ip6_tunnel.c | 2 +-
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8fed1cd..0a3622b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -932,7 +932,8 @@ int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
*/
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
- u8 *proto, struct in6_addr **daddr_p);
+ u8 *proto, struct in6_addr **daddr_p,
+ struct in6_addr *saddr);
void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 973a128e..1690ace 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -856,7 +856,7 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
struct ipv6_rt_hdr *opt,
- struct in6_addr **addr_p)
+ struct in6_addr **addr_p, struct in6_addr *saddr)
{
struct rt0_hdr *phdr, *ihdr;
int hops;
@@ -890,10 +890,10 @@ static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto,
- struct in6_addr **daddr)
+ struct in6_addr **daddr, struct in6_addr *saddr)
{
if (opt->srcrt) {
- ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
+ ipv6_push_rthdr(skb, proto, opt->srcrt, daddr, saddr);
/*
* IPV6_RTHDRDSTOPTS is ignored
* unless IPV6_RTHDR is set (RFC3542).
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6001e78..ddc878d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -203,7 +203,8 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
if (opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt->opt_nflen)
- ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
+ ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop,
+ &fl6->saddr);
}
skb_push(skb, sizeof(struct ipv6hdr));
@@ -1672,7 +1673,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
if (opt && opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt && opt->opt_nflen)
- ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst);
+ ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 03e050d..d1561e7 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1157,7 +1157,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
if (encap_limit >= 0) {
init_tel_txopt(&opt, encap_limit);
- ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
+ ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL, NULL);
}
/* Calculate max headroom for all the headers and adjust
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v4 9/9] ipv6: sr: add documentation file for per-interface sysctls
From: David Lebrun @ 2016-11-04 10:32 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1478255388-32213-1-git-send-email-david.lebrun@uclouvain.be>
This patch adds documentation for some SR-related per-interface
sysctls.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
Documentation/networking/seg6-sysctl.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 Documentation/networking/seg6-sysctl.txt
diff --git a/Documentation/networking/seg6-sysctl.txt b/Documentation/networking/seg6-sysctl.txt
new file mode 100644
index 0000000..bdbde23
--- /dev/null
+++ b/Documentation/networking/seg6-sysctl.txt
@@ -0,0 +1,18 @@
+/proc/sys/net/conf/<iface>/seg6_* variables:
+
+seg6_enabled - BOOL
+ Accept or drop SR-enabled IPv6 packets on this interface.
+
+ Relevant packets are those with SRH present and DA = local.
+
+ 0 - disabled (default)
+ not 0 - enabled
+
+seg6_require_hmac - INTEGER
+ Define HMAC policy for ingress SR-enabled packets on this interface.
+
+ -1 - Ignore HMAC field
+ 0 - Accept SR packets without HMAC, validate SR packets with HMAC
+ 1 - Drop SR packets without HMAC, validate SR packets with HMAC
+
+ Default is 0.
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v4 8/9] ipv6: sr: add support for SRH injection through setsockopt
From: David Lebrun @ 2016-11-04 10:32 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1478255388-32213-1-git-send-email-david.lebrun@uclouvain.be>
This patch adds support for per-socket SRH injection with the setsockopt
system call through the IPPROTO_IPV6, IPV6_RTHDR options.
The SRH is pushed through the ipv6_push_nfrag_opts function.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/exthdrs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---
net/ipv6/ipv6_sockglue.c | 2 ++
2 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 1690ace..e7b46f8 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -854,9 +854,9 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
* for headers.
*/
-static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
- struct ipv6_rt_hdr *opt,
- struct in6_addr **addr_p, struct in6_addr *saddr)
+static void ipv6_push_rthdr0(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
{
struct rt0_hdr *phdr, *ihdr;
int hops;
@@ -879,6 +879,62 @@ static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
*proto = NEXTHDR_ROUTING;
}
+static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
+{
+ struct ipv6_sr_hdr *sr_phdr, *sr_ihdr;
+ int plen, hops;
+
+ sr_ihdr = (struct ipv6_sr_hdr *)opt;
+ plen = (sr_ihdr->hdrlen + 1) << 3;
+
+ sr_phdr = (struct ipv6_sr_hdr *)skb_push(skb, plen);
+ memcpy(sr_phdr, sr_ihdr, sizeof(struct ipv6_sr_hdr));
+
+ hops = sr_ihdr->first_segment + 1;
+ memcpy(sr_phdr->segments + 1, sr_ihdr->segments + 1,
+ (hops - 1) * sizeof(struct in6_addr));
+
+ sr_phdr->segments[0] = **addr_p;
+ *addr_p = &sr_ihdr->segments[hops - 1];
+
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ if (sr_has_hmac(sr_phdr)) {
+ struct net *net = NULL;
+
+ if (skb->dev)
+ net = dev_net(skb->dev);
+ else if (skb->sk)
+ net = sock_net(skb->sk);
+
+ WARN_ON(!net);
+
+ if (net)
+ seg6_push_hmac(net, saddr, sr_phdr);
+ }
+#endif
+
+ sr_phdr->nexthdr = *proto;
+ *proto = NEXTHDR_ROUTING;
+}
+
+static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
+{
+ switch (opt->type) {
+ case IPV6_SRCRT_TYPE_0:
+ ipv6_push_rthdr0(skb, proto, opt, addr_p, saddr);
+ break;
+ case IPV6_SRCRT_TYPE_4:
+ ipv6_push_rthdr4(skb, proto, opt, addr_p, saddr);
+ break;
+ default:
+ break;
+ }
+}
+
static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
{
struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
@@ -1120,7 +1176,22 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
return NULL;
*orig = fl6->daddr;
- fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
+
+ switch (opt->srcrt->type) {
+ case IPV6_SRCRT_TYPE_0:
+ fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
+ break;
+ case IPV6_SRCRT_TYPE_4:
+ {
+ struct ipv6_sr_hdr *srh = (struct ipv6_sr_hdr *)opt->srcrt;
+
+ fl6->daddr = srh->segments[srh->first_segment];
+ break;
+ }
+ default:
+ return NULL;
+ }
+
return orig;
}
EXPORT_SYMBOL_GPL(fl6_update_dst);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 6c12678..780fd6b 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -430,6 +430,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
break;
#endif
+ case IPV6_SRCRT_TYPE_4:
+ break;
default:
goto sticky_done;
}
--
2.7.3
^ permalink raw reply related
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