This is a note to let you know that I've just added the patch titled
sctp: do not pr_err for the duplicated node in transport rhlist
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
sctp-do-not-pr_err-for-the-duplicated-node-in-transport-rhlist.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Xin Long <lucien.xin(a)gmail.com>
Date: Mon, 12 Feb 2018 18:29:06 +0800
Subject: sctp: do not pr_err for the duplicated node in transport rhlist
From: Xin Long <lucien.xin(a)gmail.com>
[ Upstream commit 27af86bb038d9c8b8066cd17854ddaf2ea92bce1 ]
The pr_err in sctp_hash_transport was supposed to report a sctp bug
for using rhashtable/rhlist.
The err '-EEXIST' introduced in Commit cd2b70875058 ("sctp: check
duplicate node before inserting a new transport") doesn't belong
to that case.
So just return -EEXIST back without pr_err any kmsg.
Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport")
Reported-by: Wei Chen <weichen(a)redhat.com>
Signed-off-by: Xin Long <lucien.xin(a)gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner(a)gmail.com>
Acked-by: Neil Horman <nhorman(a)tuxdriver.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
net/sctp/input.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -897,15 +897,12 @@ int sctp_hash_transport(struct sctp_tran
rhl_for_each_entry_rcu(transport, tmp, list, node)
if (transport->asoc->ep == t->asoc->ep) {
rcu_read_unlock();
- err = -EEXIST;
- goto out;
+ return -EEXIST;
}
rcu_read_unlock();
err = rhltable_insert_key(&sctp_transport_hashtable, &arg,
&t->node, sctp_hash_params);
-
-out:
if (err)
pr_err_once("insert transport fail, errno %d\n", err);
Patches currently in stable-queue which might be from lucien.xin(a)gmail.com are
queue-4.14/bridge-check-brport-attr-show-in-brport_show.patch
queue-4.14/sctp-do-not-pr_err-for-the-duplicated-node-in-transport-rhlist.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix overestimated count of buffer elements
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-overestimated-count-of-buffer-elements.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:12 +0100
Subject: s390/qeth: fix overestimated count of buffer elements
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit 12472af89632beb1ed8dea29d4efe208ca05b06a ]
qeth_get_elements_for_range() doesn't know how to handle a 0-length
range (ie. start == end), and returns 1 when it should return 0.
Such ranges occur on TSO skbs, where the L2/L3/L4 headers (and thus all
of the skb's linear data) are skipped when mapping the skb into regular
buffer elements.
This overestimation may cause several performance-related issues:
1. sub-optimal IO buffer selection, where the next buffer gets selected
even though the skb would actually still fit into the current buffer.
2. forced linearization, if the element count for a non-linear skb
exceeds QETH_MAX_BUFFER_ELEMENTS.
Rather than modifying qeth_get_elements_for_range() and adding overhead
to every caller, fix up those callers that are in risk of passing a
0-length range.
Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_core_main.c | 10 ++++++----
drivers/s390/net/qeth_l3_main.c | 11 ++++++-----
2 files changed, 12 insertions(+), 9 deletions(-)
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3861,10 +3861,12 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_
int qeth_get_elements_no(struct qeth_card *card,
struct sk_buff *skb, int extra_elems, int data_offset)
{
- int elements = qeth_get_elements_for_range(
- (addr_t)skb->data + data_offset,
- (addr_t)skb->data + skb_headlen(skb)) +
- qeth_get_elements_for_frags(skb);
+ addr_t end = (addr_t)skb->data + skb_headlen(skb);
+ int elements = qeth_get_elements_for_frags(skb);
+ addr_t start = (addr_t)skb->data + data_offset;
+
+ if (start != end)
+ elements += qeth_get_elements_for_range(start, end);
if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
QETH_DBF_MESSAGE(2, "Invalid size of IP packet "
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2633,11 +2633,12 @@ static void qeth_tso_fill_header(struct
static int qeth_l3_get_elements_no_tso(struct qeth_card *card,
struct sk_buff *skb, int extra_elems)
{
- addr_t tcpdptr = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
- int elements = qeth_get_elements_for_range(
- tcpdptr,
- (addr_t)skb->data + skb_headlen(skb)) +
- qeth_get_elements_for_frags(skb);
+ addr_t start = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
+ addr_t end = (addr_t)skb->data + skb_headlen(skb);
+ int elements = qeth_get_elements_for_frags(skb);
+
+ if (start != end)
+ elements += qeth_get_elements_for_range(start, end);
if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
QETH_DBF_MESSAGE(2,
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix SETIP command handling
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-setip-command-handling.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Fri, 9 Feb 2018 11:03:50 +0100
Subject: s390/qeth: fix SETIP command handling
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit 1c5b2216fbb973a9410e0b06389740b5c1289171 ]
send_control_data() applies some special handling to SETIP v4 IPA
commands. But current code parses *all* command types for the SETIP
command code. Limit the command code check to IPA commands.
Fixes: 5b54e16f1a54 ("qeth: do not spin for SETIP ip assist command")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_core.h | 5 +++++
drivers/s390/net/qeth_core_main.c | 14 ++++++++------
2 files changed, 13 insertions(+), 6 deletions(-)
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -580,6 +580,11 @@ struct qeth_cmd_buffer {
void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
};
+static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
+{
+ return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
+}
+
/**
* definition of a qeth channel, used for read and write
*/
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2073,7 +2073,7 @@ int qeth_send_control_data(struct qeth_c
unsigned long flags;
struct qeth_reply *reply = NULL;
unsigned long timeout, event_timeout;
- struct qeth_ipa_cmd *cmd;
+ struct qeth_ipa_cmd *cmd = NULL;
QETH_CARD_TEXT(card, 2, "sendctl");
@@ -2100,10 +2100,13 @@ int qeth_send_control_data(struct qeth_c
while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
qeth_prepare_control_data(card, len, iob);
- if (IS_IPA(iob->data))
+ if (IS_IPA(iob->data)) {
+ cmd = __ipa_cmd(iob);
event_timeout = QETH_IPA_TIMEOUT;
- else
+ } else {
event_timeout = QETH_TIMEOUT;
+ }
+
timeout = jiffies + event_timeout;
QETH_CARD_TEXT(card, 6, "noirqpnd");
@@ -2128,9 +2131,8 @@ int qeth_send_control_data(struct qeth_c
/* we have only one long running ipassist, since we can ensure
process context of this command we can sleep */
- cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
- if ((cmd->hdr.command == IPA_CMD_SETIP) &&
- (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
+ if (cmd && cmd->hdr.command == IPA_CMD_SETIP &&
+ cmd->hdr.prot_version == QETH_PROT_IPV4) {
if (!wait_event_timeout(reply->wait_q,
atomic_read(&reply->received), event_timeout))
goto time_err;
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix IP removal on offline cards
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-ip-removal-on-offline-cards.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:13 +0100
Subject: s390/qeth: fix IP removal on offline cards
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit 98d823ab1fbdcb13abc25b420f9bb71bade42056 ]
If the HW is not reachable, then none of the IPs in qeth's internal
table has been registered with the HW yet. So when deleting such an IP,
there's no need to stage it for deregistration - just drop it from
the table.
This fixes the "add-delete-add" scenario on an offline card, where the
the second "add" merely increments the IP's use count. But as the IP is
still set to DISP_ADDR_DELETE from the previous "delete" step,
l3_recover_ip() won't register it with the HW when the card goes online.
Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_l3_main.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -255,12 +255,8 @@ int qeth_l3_delete_ip(struct qeth_card *
if (addr->in_progress)
return -EINPROGRESS;
- if (!qeth_card_hw_is_reachable(card)) {
- addr->disp_flag = QETH_DISP_ADDR_DELETE;
- return 0;
- }
-
- rc = qeth_l3_deregister_addr_entry(card, addr);
+ if (qeth_card_hw_is_reachable(card))
+ rc = qeth_l3_deregister_addr_entry(card, addr);
hash_del(&addr->hnode);
kfree(addr);
@@ -403,11 +399,7 @@ static void qeth_l3_recover_ip(struct qe
spin_lock_bh(&card->ip_lock);
hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
- if (addr->disp_flag == QETH_DISP_ADDR_DELETE) {
- qeth_l3_deregister_addr_entry(card, addr);
- hash_del(&addr->hnode);
- kfree(addr);
- } else if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
+ if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
if (addr->proto == QETH_PROT_IPV4) {
addr->in_progress = 1;
spin_unlock_bh(&card->ip_lock);
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix IPA command submission race
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-ipa-command-submission-race.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:17 +0100
Subject: s390/qeth: fix IPA command submission race
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit d22ffb5a712f9211ffd104c38fc17cbfb1b5e2b0 ]
If multiple IPA commands are build & sent out concurrently,
fill_ipacmd_header() may assign a seqno value to a command that's
different from what send_control_data() later assigns to this command's
reply.
This is due to other commands passing through send_control_data(),
and incrementing card->seqno.ipa along the way.
So one IPA command has no reply that's waiting for its seqno, while some
other IPA command has multiple reply objects waiting for it.
Only one of those waiting replies wins, and the other(s) times out and
triggers a recovery via send_ipa_cmd().
Fix this by making sure that the same seqno value is assigned to
a command and its reply object.
Do so immediately before submitting the command & while holding the
irq_pending "lock", to produce nicely ascending seqnos.
As a side effect, *all* IPA commands now use a reply object that's
waiting for its actual seqno. Previously, early IPA commands that were
submitted while the card was still DOWN used the "catch-all" IDX seqno.
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_core_main.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2087,25 +2087,26 @@ int qeth_send_control_data(struct qeth_c
}
reply->callback = reply_cb;
reply->param = reply_param;
- if (card->state == CARD_STATE_DOWN)
- reply->seqno = QETH_IDX_COMMAND_SEQNO;
- else
- reply->seqno = card->seqno.ipa++;
+
init_waitqueue_head(&reply->wait_q);
- spin_lock_irqsave(&card->lock, flags);
- list_add_tail(&reply->list, &card->cmd_waiter_list);
- spin_unlock_irqrestore(&card->lock, flags);
QETH_DBF_HEX(CTRL, 2, iob->data, QETH_DBF_CTRL_LEN);
while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
- qeth_prepare_control_data(card, len, iob);
if (IS_IPA(iob->data)) {
cmd = __ipa_cmd(iob);
+ cmd->hdr.seqno = card->seqno.ipa++;
+ reply->seqno = cmd->hdr.seqno;
event_timeout = QETH_IPA_TIMEOUT;
} else {
+ reply->seqno = QETH_IDX_COMMAND_SEQNO;
event_timeout = QETH_TIMEOUT;
}
+ qeth_prepare_control_data(card, len, iob);
+
+ spin_lock_irqsave(&card->lock, flags);
+ list_add_tail(&reply->list, &card->cmd_waiter_list);
+ spin_unlock_irqrestore(&card->lock, flags);
timeout = jiffies + event_timeout;
@@ -2896,7 +2897,7 @@ static void qeth_fill_ipacmd_header(stru
memset(cmd, 0, sizeof(struct qeth_ipa_cmd));
cmd->hdr.command = command;
cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
- cmd->hdr.seqno = card->seqno.ipa;
+ /* cmd->hdr.seqno is set by qeth_send_control_data() */
cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
if (card->options.layer2)
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix IP address lookup for L3 devices
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:16 +0100
Subject: s390/qeth: fix IP address lookup for L3 devices
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit c5c48c58b259bb8f0482398370ee539d7a12df3e ]
Current code ("qeth_l3_ip_from_hash()") matches a queried address object
against objects in the IP table by IP address, Mask/Prefix Length and
MAC address ("qeth_l3_ipaddrs_is_equal()"). But what callers actually
require is either
a) "is this IP address registered" (ie. match by IP address only),
before adding a new address.
b) or "is this address object registered" (ie. match all relevant
attributes), before deleting an address.
Right now
1. the ADD path is too strict in its lookup, and eg. doesn't detect
conflicts between an existing NORMAL address and a new VIPA address
(because the NORMAL address will have mask != 0, while VIPA has
a mask == 0),
2. the DELETE path is not strict enough, and eg. allows del_rxip() to
delete a VIPA address as long as the IP address matches.
Fix all this by adding helpers (_addr_match_ip() and _addr_match_all())
that do the appropriate checking.
Note that the ADD path for NORMAL addresses is special, as qeth keeps
track of how many times such an address is in use (and there is no
immediate way of returning errors to the caller). So when a requested
NORMAL address _fully_ matches an existing one, it's not considered a
conflict and we merely increment the refcount.
Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_l3.h | 34 ++++++++++++++
drivers/s390/net/qeth_l3_main.c | 91 ++++++++++++++++++----------------------
2 files changed, 74 insertions(+), 51 deletions(-)
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -40,8 +40,40 @@ struct qeth_ipaddr {
unsigned int pfxlen;
} a6;
} u;
-
};
+
+static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1,
+ struct qeth_ipaddr *a2)
+{
+ if (a1->proto != a2->proto)
+ return false;
+ if (a1->proto == QETH_PROT_IPV6)
+ return ipv6_addr_equal(&a1->u.a6.addr, &a2->u.a6.addr);
+ return a1->u.a4.addr == a2->u.a4.addr;
+}
+
+static inline bool qeth_l3_addr_match_all(struct qeth_ipaddr *a1,
+ struct qeth_ipaddr *a2)
+{
+ /* Assumes that the pair was obtained via qeth_l3_addr_find_by_ip(),
+ * so 'proto' and 'addr' match for sure.
+ *
+ * For ucast:
+ * - 'mac' is always 0.
+ * - 'mask'/'pfxlen' for RXIP/VIPA is always 0. For NORMAL, matching
+ * values are required to avoid mixups in takeover eligibility.
+ *
+ * For mcast,
+ * - 'mac' is mapped from the IP, and thus always matches.
+ * - 'mask'/'pfxlen' is always 0.
+ */
+ if (a1->type != a2->type)
+ return false;
+ if (a1->proto == QETH_PROT_IPV6)
+ return a1->u.a6.pfxlen == a2->u.a6.pfxlen;
+ return a1->u.a4.mask == a2->u.a4.mask;
+}
+
static inline u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr)
{
u64 ret = 0;
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -149,6 +149,24 @@ int qeth_l3_string_to_ipaddr(const char
return -EINVAL;
}
+static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
+ struct qeth_ipaddr *query)
+{
+ u64 key = qeth_l3_ipaddr_hash(query);
+ struct qeth_ipaddr *addr;
+
+ if (query->is_multicast) {
+ hash_for_each_possible(card->ip_mc_htable, addr, hnode, key)
+ if (qeth_l3_addr_match_ip(addr, query))
+ return addr;
+ } else {
+ hash_for_each_possible(card->ip_htable, addr, hnode, key)
+ if (qeth_l3_addr_match_ip(addr, query))
+ return addr;
+ }
+ return NULL;
+}
+
static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
{
int i, j;
@@ -202,34 +220,6 @@ static bool qeth_l3_is_addr_covered_by_i
return rc;
}
-inline int
-qeth_l3_ipaddrs_is_equal(struct qeth_ipaddr *addr1, struct qeth_ipaddr *addr2)
-{
- return addr1->proto == addr2->proto &&
- !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) &&
- !memcmp(&addr1->mac, &addr2->mac, sizeof(addr1->mac));
-}
-
-static struct qeth_ipaddr *
-qeth_l3_ip_from_hash(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
-{
- struct qeth_ipaddr *addr;
-
- if (tmp_addr->is_multicast) {
- hash_for_each_possible(card->ip_mc_htable, addr,
- hnode, qeth_l3_ipaddr_hash(tmp_addr))
- if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr))
- return addr;
- } else {
- hash_for_each_possible(card->ip_htable, addr,
- hnode, qeth_l3_ipaddr_hash(tmp_addr))
- if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr))
- return addr;
- }
-
- return NULL;
-}
-
int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
{
int rc = 0;
@@ -244,8 +234,8 @@ int qeth_l3_delete_ip(struct qeth_card *
QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8);
}
- addr = qeth_l3_ip_from_hash(card, tmp_addr);
- if (!addr)
+ addr = qeth_l3_find_addr_by_ip(card, tmp_addr);
+ if (!addr || !qeth_l3_addr_match_all(addr, tmp_addr))
return -ENOENT;
addr->ref_counter--;
@@ -267,6 +257,7 @@ int qeth_l3_add_ip(struct qeth_card *car
{
int rc = 0;
struct qeth_ipaddr *addr;
+ char buf[40];
QETH_CARD_TEXT(card, 4, "addip");
@@ -277,8 +268,20 @@ int qeth_l3_add_ip(struct qeth_card *car
QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8);
}
- addr = qeth_l3_ip_from_hash(card, tmp_addr);
- if (!addr) {
+ addr = qeth_l3_find_addr_by_ip(card, tmp_addr);
+ if (addr) {
+ if (tmp_addr->type != QETH_IP_TYPE_NORMAL)
+ return -EADDRINUSE;
+ if (qeth_l3_addr_match_all(addr, tmp_addr)) {
+ addr->ref_counter++;
+ return 0;
+ }
+ qeth_l3_ipaddr_to_string(tmp_addr->proto, (u8 *)&tmp_addr->u,
+ buf);
+ dev_warn(&card->gdev->dev,
+ "Registering IP address %s failed\n", buf);
+ return -EADDRINUSE;
+ } else {
addr = qeth_l3_get_addr_buffer(tmp_addr->proto);
if (!addr)
return -ENOMEM;
@@ -326,11 +329,7 @@ int qeth_l3_add_ip(struct qeth_card *car
hash_del(&addr->hnode);
kfree(addr);
}
- } else {
- if (addr->type == QETH_IP_TYPE_NORMAL)
- addr->ref_counter++;
}
-
return rc;
}
@@ -714,12 +713,7 @@ int qeth_l3_add_vipa(struct qeth_card *c
return -ENOMEM;
spin_lock_bh(&card->ip_lock);
-
- if (qeth_l3_ip_from_hash(card, ipaddr))
- rc = -EEXIST;
- else
- qeth_l3_add_ip(card, ipaddr);
-
+ rc = qeth_l3_add_ip(card, ipaddr);
spin_unlock_bh(&card->ip_lock);
kfree(ipaddr);
@@ -782,12 +776,7 @@ int qeth_l3_add_rxip(struct qeth_card *c
return -ENOMEM;
spin_lock_bh(&card->ip_lock);
-
- if (qeth_l3_ip_from_hash(card, ipaddr))
- rc = -EEXIST;
- else
- qeth_l3_add_ip(card, ipaddr);
-
+ rc = qeth_l3_add_ip(card, ipaddr);
spin_unlock_bh(&card->ip_lock);
kfree(ipaddr);
@@ -1395,8 +1384,9 @@ qeth_l3_add_mc_to_hash(struct qeth_card
memcpy(tmp->mac, buf, sizeof(tmp->mac));
tmp->is_multicast = 1;
- ipm = qeth_l3_ip_from_hash(card, tmp);
+ ipm = qeth_l3_find_addr_by_ip(card, tmp);
if (ipm) {
+ /* for mcast, by-IP match means full match */
ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
} else {
ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
@@ -1479,8 +1469,9 @@ qeth_l3_add_mc6_to_hash(struct qeth_card
sizeof(struct in6_addr));
tmp->is_multicast = 1;
- ipm = qeth_l3_ip_from_hash(card, tmp);
+ ipm = qeth_l3_find_addr_by_ip(card, tmp);
if (ipm) {
+ /* for mcast, by-IP match means full match */
ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
continue;
}
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
s390/qeth: fix double-free on IP add/remove race
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
s390-qeth-fix-double-free-on-ip-add-remove-race.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:14 +0100
Subject: s390/qeth: fix double-free on IP add/remove race
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit 14d066c3531a87f727968cacd85bd95c75f59843 ]
Registering an IPv4 address with the HW takes quite a while, so we
temporarily drop the ip_htable lock. Any concurrent add/remove of the
same IP adjusts the IP's use count, and (on remove) is then blocked by
addr->in_progress.
After the register call has completed, we check the use count for
concurrently attempted add/remove calls - and possibly straight-away
deregister the IP again. This happens via l3_delete_ip(), which
1) looks up the queried IP in the htable (getting a reference to the
*same* queried object),
2) deregisters the IP from the HW, and
3) frees the IP object.
The caller in l3_add_ip() then does a second free on the same object.
For this case, skip all the extra checks and lookups in l3_delete_ip()
and just deregister & free the IP object ourselves.
Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_l3_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -319,7 +319,8 @@ int qeth_l3_add_ip(struct qeth_card *car
(rc == IPA_RC_LAN_OFFLINE)) {
addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
if (addr->ref_counter < 1) {
- qeth_l3_delete_ip(card, addr);
+ qeth_l3_deregister_addr_entry(card, addr);
+ hash_del(&addr->hnode);
kfree(addr);
}
} else {
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
Revert "s390/qeth: fix using of ref counter for rxip addresses"
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Date: Tue, 27 Feb 2018 18:58:15 +0100
Subject: Revert "s390/qeth: fix using of ref counter for rxip addresses"
From: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
[ Upstream commit 4964c66fd49b2e2342da35358f2ff74614bcbaee ]
This reverts commit cb816192d986f7596009dedcf2201fe2e5bc2aa7.
The issue this attempted to fix never actually occurs.
l3_add_rxip() checks (via l3_ip_from_hash()) if the requested address
was previously added to the card. If so, it returns -EEXIST and doesn't
call l3_add_ip().
As a result, the "address exists" path in l3_add_ip() is never taken
for rxip addresses, and this patch had no effect.
Fixes: cb816192d986 ("s390/qeth: fix using of ref counter for rxip addresses")
Signed-off-by: Julian Wiedmann <jwi(a)linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/s390/net/qeth_l3_main.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -249,8 +249,7 @@ int qeth_l3_delete_ip(struct qeth_card *
return -ENOENT;
addr->ref_counter--;
- if (addr->ref_counter > 0 && (addr->type == QETH_IP_TYPE_NORMAL ||
- addr->type == QETH_IP_TYPE_RXIP))
+ if (addr->type == QETH_IP_TYPE_NORMAL && addr->ref_counter > 0)
return rc;
if (addr->in_progress)
return -EINPROGRESS;
@@ -328,9 +327,8 @@ int qeth_l3_add_ip(struct qeth_card *car
kfree(addr);
}
} else {
- if (addr->type == QETH_IP_TYPE_NORMAL ||
- addr->type == QETH_IP_TYPE_RXIP)
- addr->ref_counter++;
+ if (addr->type == QETH_IP_TYPE_NORMAL)
+ addr->ref_counter++;
}
return rc;
Patches currently in stable-queue which might be from jwi(a)linux.vnet.ibm.com are
queue-4.14/s390-qeth-fix-setip-command-handling.patch
queue-4.14/s390-qeth-fix-ip-address-lookup-for-l3-devices.patch
queue-4.14/s390-qeth-fix-ipa-command-submission-race.patch
queue-4.14/revert-s390-qeth-fix-using-of-ref-counter-for-rxip-addresses.patch
queue-4.14/s390-qeth-fix-overestimated-count-of-buffer-elements.patch
queue-4.14/s390-qeth-fix-double-free-on-ip-add-remove-race.patch
queue-4.14/s390-qeth-fix-ip-removal-on-offline-cards.patch
queue-4.14/s390-qeth-fix-underestimated-count-of-buffer-elements.patch
This is a note to let you know that I've just added the patch titled
rxrpc: Fix send in rxrpc_send_data_packet()
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
rxrpc-fix-send-in-rxrpc_send_data_packet.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: David Howells <dhowells(a)redhat.com>
Date: Thu, 22 Feb 2018 14:38:14 +0000
Subject: rxrpc: Fix send in rxrpc_send_data_packet()
From: David Howells <dhowells(a)redhat.com>
[ Upstream commit 93c62c45ed5fad1b87e3a45835b251cd68de9c46 ]
All the kernel_sendmsg() calls in rxrpc_send_data_packet() need to send
both parts of the iov[] buffer, but one of them does not. Fix it so that
it does.
Without this, short IPv6 rxrpc DATA packets may be seen that have the rxrpc
header included, but no payload.
Fixes: 5a924b8951f8 ("rxrpc: Don't store the rxrpc header in the Tx queue sk_buffs")
Reported-by: Marc Dionne <marc.dionne(a)auristor.com>
Signed-off-by: David Howells <dhowells(a)redhat.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
net/rxrpc/output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -395,7 +395,7 @@ send_fragmentable:
(char *)&opt, sizeof(opt));
if (ret == 0) {
ret = kernel_sendmsg(conn->params.local->socket, &msg,
- iov, 1, iov[0].iov_len);
+ iov, 2, len);
opt = IPV6_PMTUDISC_DO;
kernel_setsockopt(conn->params.local->socket,
Patches currently in stable-queue which might be from dhowells(a)redhat.com are
queue-4.14/rxrpc-fix-send-in-rxrpc_send_data_packet.patch
This is a note to let you know that I've just added the patch titled
ppp: prevent unregistered channels from connecting to PPP units
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
ppp-prevent-unregistered-channels-from-connecting-to-ppp-units.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From foo@baz Tue Mar 6 19:02:12 PST 2018
From: Guillaume Nault <g.nault(a)alphalink.fr>
Date: Fri, 2 Mar 2018 18:41:16 +0100
Subject: ppp: prevent unregistered channels from connecting to PPP units
From: Guillaume Nault <g.nault(a)alphalink.fr>
[ Upstream commit 77f840e3e5f09c6d7d727e85e6e08276dd813d11 ]
PPP units don't hold any reference on the channels connected to it.
It is the channel's responsibility to ensure that it disconnects from
its unit before being destroyed.
In practice, this is ensured by ppp_unregister_channel() disconnecting
the channel from the unit before dropping a reference on the channel.
However, it is possible for an unregistered channel to connect to a PPP
unit: register a channel with ppp_register_net_channel(), attach a
/dev/ppp file to it with ioctl(PPPIOCATTCHAN), unregister the channel
with ppp_unregister_channel() and finally connect the /dev/ppp file to
a PPP unit with ioctl(PPPIOCCONNECT).
Once in this situation, the channel is only held by the /dev/ppp file,
which can be released at anytime and free the channel without letting
the parent PPP unit know. Then the ppp structure ends up with dangling
pointers in its ->channels list.
Prevent this scenario by forbidding unregistered channels from
connecting to PPP units. This maintains the code logic by keeping
ppp_unregister_channel() responsible from disconnecting the channel if
necessary and avoids modification on the reference counting mechanism.
This issue seems to predate git history (successfully reproduced on
Linux 2.6.26 and earlier PPP commits are unrelated).
Signed-off-by: Guillaume Nault <g.nault(a)alphalink.fr>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/net/ppp/ppp_generic.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -3158,6 +3158,15 @@ ppp_connect_channel(struct channel *pch,
goto outl;
ppp_lock(ppp);
+ spin_lock_bh(&pch->downl);
+ if (!pch->chan) {
+ /* Don't connect unregistered channels */
+ spin_unlock_bh(&pch->downl);
+ ppp_unlock(ppp);
+ ret = -ENOTCONN;
+ goto outl;
+ }
+ spin_unlock_bh(&pch->downl);
if (pch->file.hdrlen > ppp->file.hdrlen)
ppp->file.hdrlen = pch->file.hdrlen;
hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */
Patches currently in stable-queue which might be from g.nault(a)alphalink.fr are
queue-4.14/ppp-prevent-unregistered-channels-from-connecting-to-ppp-units.patch