* [PATCHv2 net-next 3/8] sctp: implement validate_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-14 16:41 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513269224.git.lucien.xin@gmail.com>
validate_ftsn is added as a member of sctp_stream_interleave, used to
validate ssn/chunk type for fwdtsn or mid (message id)/chunk type for
ifwdtsn, called in sctp_sf_eat_fwd_tsn, just as validate_data.
If this check fails, an abort packet will be sent, as said in section
2.3.1 of RFC8260.
As ifwdtsn and fwdtsn chunks have different length, it also defines
ftsn_chunk_len for sctp_stream_interleave to describe the chunk size.
Then it replaces all sizeof(struct sctp_fwdtsn_chunk) with
sctp_ftsnchk_len.
It also adds the process for ifwdtsn in rx path. As Marcelo pointed
out, there's no need to add event table for ifwdtsn, but just share
prsctp_chunk_event_table with fwdtsn's. It would drop fwdtsn chunk
for ifwdtsn and drop ifwdtsn chunk for fwdtsn by calling validate_ftsn
in sctp_sf_eat_fwd_tsn.
After this patch, the ifwdtsn can be accepted.
Note that this patch also removes the sctp.intl_enable check for
idata chunks in sctp_chunk_event_lookup, as it will do this check
in validate_data later.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 2 ++
include/net/sctp/structs.h | 10 ++++++++
net/sctp/sm_statefuns.c | 24 +++++++-------------
net/sctp/sm_statetable.c | 4 ++--
net/sctp/stream_interleave.c | 44 ++++++++++++++++++++++++++++++++++++
5 files changed, 66 insertions(+), 18 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 66267db..0db15b5 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -33,6 +33,7 @@
struct sctp_stream_interleave {
__u16 data_chunk_len;
+ __u16 ftsn_chunk_len;
/* (I-)DATA process */
struct sctp_chunk *(*make_datafrag)(const struct sctp_association *asoc,
const struct sctp_sndrcvinfo *sinfo,
@@ -49,6 +50,7 @@ struct sctp_stream_interleave {
void (*abort_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
/* (I-)FORWARD-TSN process */
void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
+ bool (*validate_ftsn)(struct sctp_chunk *chunk);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index b7720d6..8ac4d5c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1443,6 +1443,16 @@ static inline __u16 sctp_datahdr_len(const struct sctp_stream *stream)
return stream->si->data_chunk_len - sizeof(struct sctp_chunkhdr);
}
+static inline __u16 sctp_ftsnchk_len(const struct sctp_stream *stream)
+{
+ return stream->si->ftsn_chunk_len;
+}
+
+static inline __u16 sctp_ftsnhdr_len(const struct sctp_stream *stream)
+{
+ return stream->si->ftsn_chunk_len - sizeof(struct sctp_chunkhdr);
+}
+
/* SCTP_GET_ASSOC_STATS counters */
struct sctp_priv_assoc_stats {
/* Maximum observed rto in the association during subsequent
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index c609c54..541f347 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3957,7 +3957,6 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
{
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_chunk *chunk = arg;
- struct sctp_fwdtsn_skip *skip;
__u16 len;
__u32 tsn;
@@ -3971,7 +3970,7 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
/* Make sure that the FORWARD_TSN chunk has valid length. */
- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+ if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
@@ -3990,14 +3989,11 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
goto discard_noforce;
- /* Silently discard the chunk if stream-id is not valid */
- sctp_walk_fwdtsn(skip, chunk) {
- if (ntohs(skip->stream) >= asoc->stream.incnt)
- goto discard_noforce;
- }
+ if (!asoc->stream.si->validate_ftsn(chunk))
+ goto discard_noforce;
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
- if (len > sizeof(struct sctp_fwdtsn_hdr))
+ if (len > sctp_ftsnhdr_len(&asoc->stream))
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
@@ -4028,7 +4024,6 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
{
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_chunk *chunk = arg;
- struct sctp_fwdtsn_skip *skip;
__u16 len;
__u32 tsn;
@@ -4042,7 +4037,7 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
/* Make sure that the FORWARD_TSN chunk has a valid length. */
- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+ if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
@@ -4061,14 +4056,11 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
goto gen_shutdown;
- /* Silently discard the chunk if stream-id is not valid */
- sctp_walk_fwdtsn(skip, chunk) {
- if (ntohs(skip->stream) >= asoc->stream.incnt)
- goto gen_shutdown;
- }
+ if (!asoc->stream.si->validate_ftsn(chunk))
+ goto gen_shutdown;
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
- if (len > sizeof(struct sctp_fwdtsn_hdr))
+ if (len > sctp_ftsnhdr_len(&asoc->stream))
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 8c9bb41..691d9dc 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -985,14 +985,14 @@ static const struct sctp_sm_table_entry *sctp_chunk_event_lookup(
if (state > SCTP_STATE_MAX)
return &bug;
- if (net->sctp.intl_enable && cid == SCTP_CID_I_DATA)
+ if (cid == SCTP_CID_I_DATA)
cid = SCTP_CID_DATA;
if (cid <= SCTP_CID_BASE_MAX)
return &chunk_event_table[cid][state];
if (net->sctp.prsctp_enable) {
- if (cid == SCTP_CID_FWD_TSN)
+ if (cid == SCTP_CID_FWD_TSN || cid == SCTP_CID_I_FWD_TSN)
return &prsctp_chunk_event_table[0][state];
}
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index 2ead372..cc4a5e3 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1153,8 +1153,49 @@ static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
}
}
+#define _sctp_walk_ifwdtsn(pos, chunk, end) \
+ for (pos = chunk->subh.ifwdtsn_hdr->skip; \
+ (void *)pos < (void *)chunk->subh.ifwdtsn_hdr->skip + (end); pos++)
+
+#define sctp_walk_ifwdtsn(pos, ch) \
+ _sctp_walk_ifwdtsn((pos), (ch), ntohs((ch)->chunk_hdr->length) - \
+ sizeof(struct sctp_ifwdtsn_chunk))
+
+static bool sctp_validate_fwdtsn(struct sctp_chunk *chunk)
+{
+ struct sctp_fwdtsn_skip *skip;
+ __u16 incnt;
+
+ if (chunk->chunk_hdr->type != SCTP_CID_FWD_TSN)
+ return false;
+
+ incnt = chunk->asoc->stream.incnt;
+ sctp_walk_fwdtsn(skip, chunk)
+ if (ntohs(skip->stream) >= incnt)
+ return false;
+
+ return true;
+}
+
+static bool sctp_validate_iftsn(struct sctp_chunk *chunk)
+{
+ struct sctp_ifwdtsn_skip *skip;
+ __u16 incnt;
+
+ if (chunk->chunk_hdr->type != SCTP_CID_I_FWD_TSN)
+ return false;
+
+ incnt = chunk->asoc->stream.incnt;
+ sctp_walk_ifwdtsn(skip, chunk)
+ if (ntohs(skip->stream) >= incnt)
+ return false;
+
+ return true;
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
+ .ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk),
/* DATA process functions */
.make_datafrag = sctp_make_datafrag_empty,
.assign_number = sctp_chunk_assign_ssn,
@@ -1166,10 +1207,12 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.abort_pd = sctp_ulpq_abort_pd,
/* FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_fwdtsn,
+ .validate_ftsn = sctp_validate_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.data_chunk_len = sizeof(struct sctp_idata_chunk),
+ .ftsn_chunk_len = sizeof(struct sctp_ifwdtsn_chunk),
/* I-DATA process functions */
.make_datafrag = sctp_make_idatafrag_empty,
.assign_number = sctp_chunk_assign_mid,
@@ -1181,6 +1224,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.abort_pd = sctp_intl_abort_pd,
/* I-FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_iftsn,
+ .validate_ftsn = sctp_validate_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCHv2 net-next 2/8] sctp: implement generate_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-14 16:41 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513269224.git.lucien.xin@gmail.com>
generate_ftsn is added as a member of sctp_stream_interleave, used to
create fwdtsn or ifwdtsn chunk according to abandoned chunks, called
in sctp_retransmit and sctp_outq_sack.
sctp_generate_iftsn works for ifwdtsn, and sctp_generate_fwdtsn is
still used for making fwdtsn.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 2 +
include/net/sctp/structs.h | 1 +
net/sctp/outqueue.c | 12 +++---
net/sctp/stream_interleave.c | 75 ++++++++++++++++++++++++++++++++++++
4 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 501b2be..66267db 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -47,6 +47,8 @@ struct sctp_stream_interleave {
struct sctp_chunk *chunk, gfp_t gfp);
void (*start_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
void (*abort_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
+ /* (I-)FORWARD-TSN process */
+ void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index a5c3cf4..b7720d6 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1100,6 +1100,7 @@ void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
void sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
void sctp_prsctp_prune(struct sctp_association *asoc,
struct sctp_sndrcvinfo *sinfo, int msg_len);
+void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
/* Uncork and flush an outqueue. */
static inline void sctp_outq_cork(struct sctp_outq *q)
{
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 7d67fee..af9b5eb 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -67,8 +67,6 @@ static void sctp_mark_missing(struct sctp_outq *q,
__u32 highest_new_tsn,
int count_of_newacks);
-static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
-
static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp);
/* Add data to the front of the queue. */
@@ -591,7 +589,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
* following the procedures outlined in C1 - C5.
*/
if (reason == SCTP_RTXR_T3_RTX)
- sctp_generate_fwdtsn(q, q->asoc->ctsn_ack_point);
+ q->asoc->stream.si->generate_ftsn(q, q->asoc->ctsn_ack_point);
/* Flush the queues only on timeout, since fast_rtx is only
* triggered during sack processing and the queue
@@ -942,6 +940,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
case SCTP_CID_ECN_ECNE:
case SCTP_CID_ASCONF:
case SCTP_CID_FWD_TSN:
+ case SCTP_CID_I_FWD_TSN:
case SCTP_CID_RECONF:
status = sctp_packet_transmit_chunk(packet, chunk,
one_packet, gfp);
@@ -956,7 +955,8 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
* sender MUST assure that at least one T3-rtx
* timer is running.
*/
- if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) {
+ if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN ||
+ chunk->chunk_hdr->type == SCTP_CID_I_FWD_TSN) {
sctp_transport_reset_t3_rtx(transport);
transport->last_time_sent = jiffies;
}
@@ -1372,7 +1372,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
asoc->peer.rwnd = sack_a_rwnd;
- sctp_generate_fwdtsn(q, sack_ctsn);
+ asoc->stream.si->generate_ftsn(q, sack_ctsn);
pr_debug("%s: sack cumulative tsn ack:0x%x\n", __func__, sack_ctsn);
pr_debug("%s: cumulative tsn ack of assoc:%p is 0x%x, "
@@ -1795,7 +1795,7 @@ static inline int sctp_get_skip_pos(struct sctp_fwdtsn_skip *skiplist,
}
/* Create and add a fwdtsn chunk to the outq's control queue if needed. */
-static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
+void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
{
struct sctp_association *asoc = q->asoc;
struct sctp_chunk *ftsn_chunk = NULL;
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index 87b9417..2ead372 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1082,6 +1082,77 @@ static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
sctp_ulpq_flush(ulpq);
}
+static inline int sctp_get_skip_pos(struct sctp_ifwdtsn_skip *skiplist,
+ int nskips, __be16 stream, __u8 flags)
+{
+ int i;
+
+ for (i = 0; i < nskips; i++)
+ if (skiplist[i].stream == stream &&
+ skiplist[i].flags == flags)
+ return i;
+
+ return i;
+}
+
+#define SCTP_FTSN_U_BIT 0x1
+static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
+{
+ struct sctp_ifwdtsn_skip ftsn_skip_arr[10];
+ struct sctp_association *asoc = q->asoc;
+ struct sctp_chunk *ftsn_chunk = NULL;
+ struct list_head *lchunk, *temp;
+ int nskips = 0, skip_pos;
+ struct sctp_chunk *chunk;
+ __u32 tsn;
+
+ if (!asoc->peer.prsctp_capable)
+ return;
+
+ if (TSN_lt(asoc->adv_peer_ack_point, ctsn))
+ asoc->adv_peer_ack_point = ctsn;
+
+ list_for_each_safe(lchunk, temp, &q->abandoned) {
+ chunk = list_entry(lchunk, struct sctp_chunk, transmitted_list);
+ tsn = ntohl(chunk->subh.data_hdr->tsn);
+
+ if (TSN_lte(tsn, ctsn)) {
+ list_del_init(lchunk);
+ sctp_chunk_free(chunk);
+ } else if (TSN_lte(tsn, asoc->adv_peer_ack_point + 1)) {
+ __be16 sid = chunk->subh.idata_hdr->stream;
+ __be32 mid = chunk->subh.idata_hdr->mid;
+ __u8 flags = 0;
+
+ if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+ flags |= SCTP_FTSN_U_BIT;
+
+ asoc->adv_peer_ack_point = tsn;
+ skip_pos = sctp_get_skip_pos(&ftsn_skip_arr[0], nskips,
+ sid, flags);
+ ftsn_skip_arr[skip_pos].stream = sid;
+ ftsn_skip_arr[skip_pos].reserved = 0;
+ ftsn_skip_arr[skip_pos].flags = flags;
+ ftsn_skip_arr[skip_pos].mid = mid;
+ if (skip_pos == nskips)
+ nskips++;
+ if (nskips == 10)
+ break;
+ } else {
+ break;
+ }
+ }
+
+ if (asoc->adv_peer_ack_point > ctsn)
+ ftsn_chunk = sctp_make_ifwdtsn(asoc, asoc->adv_peer_ack_point,
+ nskips, &ftsn_skip_arr[0]);
+
+ if (ftsn_chunk) {
+ list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
+ SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_OUTCTRLCHUNKS);
+ }
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
/* DATA process functions */
@@ -1093,6 +1164,8 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.renege_events = sctp_ulpq_renege,
.start_pd = sctp_ulpq_partial_delivery,
.abort_pd = sctp_ulpq_abort_pd,
+ /* FORWARD-TSN process functions */
+ .generate_ftsn = sctp_generate_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
@@ -1106,6 +1179,8 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.renege_events = sctp_renege_events,
.start_pd = sctp_intl_start_pd,
.abort_pd = sctp_intl_abort_pd,
+ /* I-FORWARD-TSN process functions */
+ .generate_ftsn = sctp_generate_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCHv2 net-next 1/8] sctp: add basic structures and make chunk function for ifwdtsn
From: Xin Long @ 2017-12-14 16:41 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513269224.git.lucien.xin@gmail.com>
sctp_ifwdtsn_skip, sctp_ifwdtsn_hdr and sctp_ifwdtsn_chunk are used to
define and parse I-FWD TSN chunk format, and sctp_make_ifwdtsn is a
function to build the chunk.
The I-FORWARD-TSN Chunk Format is defined in section 2.3.1 of RFC8260.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/sctp.h | 17 +++++++++++++++++
include/net/sctp/sm.h | 3 +++
include/net/sctp/structs.h | 1 +
net/sctp/sm_make_chunk.c | 24 ++++++++++++++++++++++++
4 files changed, 45 insertions(+)
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 38e2cf6..b36c766 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -110,6 +110,7 @@ enum sctp_cid {
/* Use hex, as defined in ADDIP sec. 3.1 */
SCTP_CID_ASCONF = 0xC1,
+ SCTP_CID_I_FWD_TSN = 0xC2,
SCTP_CID_ASCONF_ACK = 0x80,
SCTP_CID_RECONF = 0x82,
}; /* enum */
@@ -616,6 +617,22 @@ struct sctp_fwdtsn_chunk {
struct sctp_fwdtsn_hdr fwdtsn_hdr;
};
+struct sctp_ifwdtsn_skip {
+ __be16 stream;
+ __u8 reserved;
+ __u8 flags;
+ __be32 mid;
+};
+
+struct sctp_ifwdtsn_hdr {
+ __be32 new_cum_tsn;
+ struct sctp_ifwdtsn_skip skip[0];
+};
+
+struct sctp_ifwdtsn_chunk {
+ struct sctp_chunkhdr chunk_hdr;
+ struct sctp_ifwdtsn_hdr fwdtsn_hdr;
+};
/* ADDIP
* Section 3.1.1 Address Configuration Change Chunk (ASCONF)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 0993b49..2883c43 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -199,6 +199,9 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
const struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_idata(const struct sctp_association *asoc,
__u8 flags, int paylen, gfp_t gfp);
+struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
+ __u32 new_cum_tsn, size_t nstreams,
+ struct sctp_ifwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_datafrag_empty(const struct sctp_association *asoc,
const struct sctp_sndrcvinfo *sinfo,
int len, __u8 flags, gfp_t gfp);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 8ef638d..a5c3cf4 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -599,6 +599,7 @@ struct sctp_chunk {
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_authhdr *auth_hdr;
struct sctp_idatahdr *idata_hdr;
+ struct sctp_ifwdtsn_hdr *ifwdtsn_hdr;
} subh;
__u8 *chunk_end;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 23a7313..b9b269c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3536,6 +3536,30 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
return retval;
}
+struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
+ __u32 new_cum_tsn, size_t nstreams,
+ struct sctp_ifwdtsn_skip *skiplist)
+{
+ struct sctp_chunk *retval = NULL;
+ struct sctp_ifwdtsn_hdr ftsn_hdr;
+ size_t hint;
+
+ hint = (nstreams + 1) * sizeof(__u32);
+
+ retval = sctp_make_control(asoc, SCTP_CID_I_FWD_TSN, 0, hint,
+ GFP_ATOMIC);
+ if (!retval)
+ return NULL;
+
+ ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
+ retval->subh.ifwdtsn_hdr =
+ sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);
+
+ sctp_addto_chunk(retval, nstreams * sizeof(skiplist[0]), skiplist);
+
+ return retval;
+}
+
/* RE-CONFIG 3.1 (RE-CONFIG chunk)
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
--
2.1.0
^ permalink raw reply related
* [PATCHv2 net-next 0/8] sctp: Implement Stream Interleave: Interaction with Other SCTP Extensions
From: Xin Long @ 2017-12-14 16:41 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
Stream Interleave would be implemented in two Parts:
1. The I-DATA Chunk Supporting User Message Interleaving
2. Interaction with Other SCTP Extensions
Overview in section 2.3 of RFC8260 for Part 2:
The usage of the I-DATA chunk might interfere with other SCTP
extensions. Future SCTP extensions MUST describe if and how they
interfere with the usage of I-DATA chunks. For the SCTP extensions
already defined when this document was published, the details are
given in the following subsections.
As the 2nd part of Stream Interleave Implementation, this patchset mostly
adds the support for SCTP Partial Reliability Extension with I-FORWARD-TSN
chunk. Then adjusts stream scheduler and stream reconfig to make them work
properly with I-DATA chunks.
In the last patch, all stream interleave codes will be enabled by adding
sysctl to allow users to use this feature.
v1 -> v2:
- removed the intl_enable check from sctp_chunk_event_lookup, as Marcelo's
suggestion.
- fixed a typo in changelog.
Xin Long (8):
sctp: add basic structures and make chunk function for ifwdtsn
sctp: implement generate_ftsn for sctp_stream_interleave
sctp: implement validate_ftsn for sctp_stream_interleave
sctp: implement report_ftsn for sctp_stream_interleave
sctp: implement handle_ftsn for sctp_stream_interleave
sctp: add stream interleave support in stream scheduler
sctp: update mid instead of ssn when doing stream and asoc reset
sctp: support sysctl to allow users to use stream interleave
include/linux/sctp.h | 17 +++
include/net/sctp/sm.h | 3 +
include/net/sctp/stream_interleave.h | 7 ++
include/net/sctp/structs.h | 12 ++
net/sctp/outqueue.c | 12 +-
net/sctp/sm_make_chunk.c | 24 ++++
net/sctp/sm_sideeffect.c | 24 +---
net/sctp/sm_statefuns.c | 24 ++--
net/sctp/sm_statetable.c | 4 +-
net/sctp/stream.c | 46 +++++---
net/sctp/stream_interleave.c | 216 +++++++++++++++++++++++++++++++++++
net/sctp/stream_sched.c | 3 +-
net/sctp/sysctl.c | 7 ++
13 files changed, 334 insertions(+), 65 deletions(-)
--
2.1.0
^ permalink raw reply
* Re: [PATCH net-next v4 0/5] Introduce NETIF_F_GRO_HW
From: Or Gerlitz @ 2017-12-14 16:34 UTC (permalink / raw)
To: Michael Chan
Cc: David Miller, Linux Netdev List, Andy Gospodarek, Gal Pressman
In-Reply-To: <1512992470-28861-1-git-send-email-michael.chan@broadcom.com>
On Mon, Dec 11, 2017 at 1:41 PM, Michael Chan <michael.chan@broadcom.com> wrote:
> Introduce NETIF_F_GRO_HW feature flag and convert drivers that support
> hardware GRO to use the new flag.
Hi Michael,
Could you add more performance motivations/results? looking on your
netconf slides [1]
I see (much) better CPU utilization (slide 5) -- do you have more
numbers to share?
Or.
[1] http://vger.kernel.org/netconf2017_files/hardware_gro.pdf
^ permalink raw reply
* Re: Linux 4.14 - regression: broken tun/tap / bridge network with virtio - bisected
From: Andreas Hartmann @ 2017-12-14 16:31 UTC (permalink / raw)
To: Willem de Bruijn, Michal Kubecek
Cc: Jason Wang, David Miller, Network Development
In-Reply-To: <d71df64e-e65f-4db4-6f2e-c002c15fcbe4@01019freenet.de>
On 12/11/2017 at 04:54 PM Andreas Hartmann wrote:
> On 12/08/2017 at 09:44 PM Andreas Hartmann wrote:
>> On 12/08/2017 at 09:11 PM Andreas Hartmann wrote:
>>> On 12/08/2017 at 05:04 PM Willem de Bruijn wrote:
>>>> On Fri, Dec 8, 2017 at 6:40 AM, Michal Kubecek <mkubecek@suse.cz> wrote:
>>>>> On Fri, Dec 08, 2017 at 11:31:50AM +0100, Andreas Hartmann wrote:
>>>>>> On 12/08/2017 at 09:47 AM Michal Kubecek wrote:
>>>>>>> On Fri, Dec 08, 2017 at 08:21:16AM +0100, Andreas Hartmann wrote:
>>>>>>>>
>>>>>>>> All my VMs are using virtio_net. BTW: I couldn't see the problems
>>>>>>>> (sometimes, the VM couldn't be stopped at all) if all my VMs are using
>>>>>>>> e1000 as interface instead.
>>>>>>>>
>>>>>>>> This finding now matches pretty much the responsible UDP-package which
>>>>>>>> caused the stall. I already mentioned it here [2].
>>>>>>>>
>>>>>>>> To prove it, I reverted from the patch series "[PATCH v2 RFC 0/13]
>>>>>>>> Remove UDP Fragmentation Offload support" [3]
>>>>>>>>
>>>>>>>> 11/13 [v2,RFC,11/13] net: Remove all references to SKB_GSO_UDP. [4]
>>>>>>>> 12/13 [v2,RFC,12/13] inet: Remove software UFO fragmenting code. [5]
>>>>>>>> 13/13 [v2,RFC,13/13] net: Kill NETIF_F_UFO and SKB_GSO_UDP. [6]
>>>>>>>>
>>>>>>>> and applied it to Linux 4.14.4. It compiled fine and is running fine.
>>>>>>>> The vnet doesn't die anymore. Yet, I can't say if the qemu stop hangs
>>>>>>>> are gone, too.
>>>>>>>>
>>>>>>>> Obviously, there is something broken with the new UDP handling. Could
>>>>>>>> you please analyze this problem? I could test some more patches ... .
>>>>>>>
>>>>>>> Any chance your VMs were live migrated from pre-4.14 host kernel?
>>>>>>
>>>>>> No - the VMs are not live migrated. They are always running on the same
>>>>>> host - either with kernel < 4.14 or with kernel 4.14.x.
>>>>>
>>>>> This is disturbing... unless I'm mistaken, it shouldn't be possible to
>>>>> have UFO enabled on a virtio device in a VM booted on a host with 4.14
>>>>> kernel.
>>>>
>>>> Indeed. When working on that revert patch I verified that UFO in
>>>> the guest virtio_net was off before the revert patch, on after.
>>>>
>>>> Qemu should check host support with tap_probe_has_ufo
>>>> before advertising support to the guest. Indeed, this is exactly
>>>> what broke live migration in virtio_net_load_device at
>>>>
>>>> if (qemu_get_byte(f) && !peer_has_ufo(n)) {
>>>> error_report("virtio-net: saved image requires TUN_F_UFO support");
>>>> return -1;
>>>> }
>>>>
>>>> Which follows
>>>>
>>>> peer_has_ufo
>>>> qemu_has_ufo
>>>> tap_has_ufo
>>>> s->has_ufo
>>>>
>>>> where s->has_ufo was set by tap_probe_has_ufo in net_tap_fd_init.
>>>>
>>>> Now, checking my qemu git branch, I ran pretty old 2.7.0-rc3. But this
>>>> codepath does not seem to have changed between then and 2.10.1.
>>>>
>>>> I cherry-picked the revert onto 4.14.3. It did not apply cleanly, but the
>>>> fix-up wasn't too hard. Compiled and booted, but untested otherwise. At
>>>>
>>>> https://github.com/wdebruij/linux/commits/v4.14.3-aargh-ufo
>>>
>>> I'm just running it at the moment. I didn't face any network hang until
>>> now - although the critical UDP packages have been gone through.
>>> Therefore: looks nice.
>>
>> Well, the patch does not fix hanging VMs, which have been shutdown and
>> can't be killed any more.
>> Because of the stack trace
>>
>> [<ffffffffc0d0e3c5>] vhost_net_ubuf_put_and_wait+0x35/0x60 [vhost_net]
>> [<ffffffffc0d0f264>] vhost_net_ioctl+0x304/0x870 [vhost_net]
>> [<ffffffff9b25460f>] do_vfs_ioctl+0x8f/0x5c0
>> [<ffffffff9b254bb4>] SyS_ioctl+0x74/0x80
>> [<ffffffff9b00365b>] do_syscall_64+0x5b/0x100
>> [<ffffffff9b78e7ab>] entry_SYSCALL64_slow_path+0x25/0x25
>> [<ffffffffffffffff>] 0xffffffffffffffff
>>
>> I was hoping, that the problems could be related - but that seems not to
>> be true.
>
> However, it turned out, that reverting the complete patchset "Remove UDP
> Fragmentation Offload support" prevent hanging qemu processes. I tested
> today and the whole weekend - I didn't face any problem. Before that, I
> could see nearly immediately hanging qemu processes after shutdown w/
> libvirt.
>
> Tested w/ 4.14.4, qemu 2.6.2 and libvirt 2.0.0 and 4 VMs.
>
> I'll be back if the problem comes up again while the patchset is reverted.
After reversion of "Remove UDP Fragmentation Offload support" I didn't
see any problem any more so far.
Thanks,
Andreas
^ permalink raw reply
* Re: [PATCH ipsec-next] xfrm: check for xdo_dev_state_free
From: Shannon Nelson @ 2017-12-14 16:28 UTC (permalink / raw)
To: Steffen Klassert; +Cc: netdev
In-Reply-To: <20171214062020.wj6iglgcfpu2b7kh@gauss3.secunet.de>
On 12/13/2017 10:20 PM, Steffen Klassert wrote:
> On Mon, Dec 11, 2017 at 12:57:22PM -0800, Shannon Nelson wrote:
>> The current XFRM code assumes that we've implemented the
>> xdo_dev_state_free() callback, even if it is meaningless to the driver.
<snip>
>> + if (dev->features & NETIF_F_HW_ESP_TX_CSUM) {
>> + netdev_err(dev, "NETIF_F_HW_ESP_TX_CSUM without NETIF_F_HW_ESP\n");
>> + return NOTIFY_BAD;
>> + } else {
>> + return NOTIFY_DONE;
>> + }
>> + }
>> +
>> + if (!(dev->xfrmdev_ops &&
>> + dev->xfrmdev_ops->xdo_dev_state_add &&
>> + dev->xfrmdev_ops->xdo_dev_state_delete)) {
>> + netdev_err(dev, "add or delete function missing from xfrmdev_ops\n");
>
> Please remove these error printings, this is not relevant for normal
> users.
>
Okay.
After I posted this I realized this really should be two patches, so
I'll split this up as well before resending.
sln
^ permalink raw reply
* Re: [PATCH net] vxlan: Restore initial MTU setting based on lower device
From: Alexey Kodanev @ 2017-12-14 16:26 UTC (permalink / raw)
To: Stefano Brivio
Cc: Matthias Schiffer, David S . Miller, netdev, Junhan Yan,
Jiri Benc, Hangbin Liu
In-Reply-To: <20171214133647.1c1b82d1@elisabeth>
On 12/14/2017 03:36 PM, Stefano Brivio wrote:
> On Thu, 14 Dec 2017 14:23:36 +0300
> Alexey Kodanev <alexey.kodanev@oracle.com> wrote:
>
>> On 12/14/2017 03:31 AM, Stefano Brivio wrote:
...
>>
>> if we move it up in "if (lowerdev) { ..." branch we will be checking the presence
>> of "lowerdev" and also not calculating it again. Also I would check max_mtu for
>> minimum as it might happen to be negative, though unlikely corner case...
>
> Indeed it might happen to be negative (only for IPv6, down to -2), good
> catch.
>
> For the benefit of others: it took me a few minutes to see how this is
> *not* unrelated, because we are introducing a direct assignment of
> dev->mtu to set max_mtu, whereas earlier it was just used in
> comparisons, so it didn't matter whether it was negative.
>
>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>> index 19b9cc5..1000b0e 100644
>> --- a/drivers/net/vxlan.c
>> +++ b/drivers/net/vxlan.c
>> @@ -3103,6 +3103,11 @@ static void vxlan_config_apply(struct net_device *dev,
>>
>> max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM :
>> VXLAN_HEADROOM);
>> + if (max_mtu < ETH_MIN_MTU)
>> + max_mtu = ETH_MIN_MTU;
>> +
>> + if (!changelink && !conf->mtu)
>> + dev->mtu = max_mtu;
>
> I don't really have a strong preference here. On one hand, you're
> hiding this a bit from the "device creation" path. On the other hand,
> it's a bit more compact. So I'm also fine with this.
>
> Can you perhaps submit a formal patch?
>
OK, I'll send a patch.
Thanks,
Alexey
^ permalink raw reply
* Fw: [Bug 198163] New: vpn pptp protocol did not working properly in new kernel release
From: Stephen Hemminger @ 2017-12-14 16:05 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Thu, 14 Dec 2017 09:41:42 +0000
From: bugzilla-daemon@bugzilla.kernel.org
To: stephen@networkplumber.org
Subject: [Bug 198163] New: vpn pptp protocol did not working properly in new kernel release
https://bugzilla.kernel.org/show_bug.cgi?id=198163
Bug ID: 198163
Summary: vpn pptp protocol did not working properly in new
kernel release
Product: Networking
Version: 2.5
Kernel Version: 4.14.3-300.fc27.x86_64
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: high
Priority: P1
Component: Other
Assignee: stephen@networkplumber.org
Reporter: mohammed.okasha.ps@gmail.com
Regression: No
I have VPN network (PPTP protocol), When established connection to VPN server I
can see VPN network tunnel in output ip command and table route with netstat
command but I cannot access to internet and VPN network unless I disconnect VPN
network in Fedora 27
How reproducible:
Just add new VPN (PPTP) network
Steps to Reproduce:
1.add gateway
2.add username and password
3.keep another default settings
Note:firewalld off and routing table same and SELinux disabled
When I downgraded kernel to 4.8.6-300.fc25 version everything works fine
this report that i was created contain logs:
https://bugzilla.redhat.com/show_bug.cgi?id=1524212
also see this screenshot:
https://imgur.com/fCDE8U1
https://imgur.com/zUBrdmP
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [PATCH 2/2] ip6_gre: fix error path when ip6erspan_rcv failed
From: Haishuang Yan @ 2017-12-14 16:05 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan, William Tu
In-Reply-To: <1513267513-11562-1-git-send-email-yanhaishuang@cmss.chinamobile.com>
Same as ipv4 code, when ip6erspan_rcv call return PACKET_REJECT, we
should call icmpv6_send to send icmp unreachable message in error path.
Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv6/ip6_gre.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index b8b0e4b..68e7eef 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -580,12 +580,13 @@ static int gre_rcv(struct sk_buff *skb)
if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) {
if (ip6erspan_rcv(skb, hdr_len, &tpi) == PACKET_RCVD)
return 0;
- goto drop;
+ goto out;
}
if (ip6gre_rcv(skb, &tpi) == PACKET_RCVD)
return 0;
+out:
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
drop:
kfree_skb(skb);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2] ip_gre: fix error path when erspan_rcv failed
From: Haishuang Yan @ 2017-12-14 16:05 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan, William Tu
When erspan_rcv call return PACKET_REJECT, we shoudn't call ipgre_rcv to
process packets again, instead send icmp unreachable message in error
path.
Fixes: 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv4/ip_gre.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 9253d6f..61ee014 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -411,11 +411,13 @@ static int gre_rcv(struct sk_buff *skb)
if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) {
if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
return 0;
+ goto out;
}
if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
return 0;
+out:
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
drop:
kfree_skb(skb);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/1] net: usb: qmi_wwan: add Telit ME910 PID 0x1101 support
From: Daniele Palmas @ 2017-12-14 15:56 UTC (permalink / raw)
To: Bjørn Mork; +Cc: netdev, Daniele Palmas
This patch adds support for Telit ME910 PID 0x1101.
Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
---
Following lsusb output for 0x1101 composition
tty, tty, tty, rmnet
Bus 003 Device 015: ID 1bc7:1101 Telit Wireless Solutions
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1bc7 Telit Wireless Solutions
idProduct 0x1101
bcdDevice 0.00
iManufacturer 3 Telit
iProduct 2 Telit ME910
iSerial 4 5f97073d
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 122
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 1 Telit Configuration
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 254
bInterfaceProtocol 255
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0000
(Bus Powered)
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index d2ca5a2..3000ddd 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1211,6 +1211,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
+ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
{QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */
--
2.7.4
^ permalink raw reply related
* Re: wcn36xx: Reduce spinlock in indication handler
From: Kalle Valo @ 2017-12-14 15:32 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Eugene Krasnikov, Kalle Valo, Loic Poulain, wcn36xx,
linux-wireless, netdev, linux-kernel
In-Reply-To: <20171209003508.3507-1-bjorn.andersson@linaro.org>
Bjorn Andersson <bjorn.andersson@linaro.org> wrote:
> The purpose of pushing indication on a list and handle these in a
> separate worker is to allow the handlers to sleep. It does therefor not
> make much sense to hold the queue spinlock through the entire indication
> worker function.
>
> By removing items from the queue early we don't need to hold the lock
> throughout the indication worker, allowing the individual handlers to
> sleep.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Patch applied to ath-next branch of ath.git, thanks.
6d1f37323f5b wcn36xx: Reduce spinlock in indication handler
--
https://patchwork.kernel.org/patch/10103469/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH net-next v3] ip6_vti: adjust vti mtu according to mtu of output device
From: Alexey Kodanev @ 2017-12-14 15:37 UTC (permalink / raw)
To: netdev
Cc: Steffen Klassert, David Miller, Petr Vorel, Shannon Nelson,
Alexey Kodanev
LTP/udp6_ipsec_vti tests fail when sending large UDP datagrams that
require fragmentation and the underlying device has MTU <= 1500. This
happens because ip6_vti sets mtu to ETH_DATA_LEN and not updating it
depending on a destination address or link parameter.
Further attempts to send UDP packets may succeed because pmtu gets
updated on ICMPV6_PKT_TOOBIG in vti6_err().
Here is the example when the output device MTU is set to 9000:
# ip a sh ltp_ns_veth2
ltp_ns_veth2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 ...
inet 10.0.0.2/24 scope global ltp_ns_veth2
inet6 fd00::2/64 scope global
# ip li add vti6 type vti6 local fd00::2 remote fd00::1
# ip li show vti6
vti6@NONE: <POINTOPOINT,NOARP> mtu 1500 ...
link/tunnel6 fd00::2 peer fd00::1
After the patch:
# ip li add vti6 type vti6 local fd00::2 remote fd00::1
# ip li show vti6
vti6@NONE: <POINTOPOINT,NOARP> mtu 8832 ...
link/tunnel6 fd00::2 peer fd00::1
Regarding ip_vti, it already tunes MTU with ip_tunnel_bind_dev().
Reported-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
Acked-by: Shannon Nelson <shannon.nelson@oracle.com>
---
v3: * fix style issue with curly braces around single-statement if block
v2: * cleanup commit message issues (thanks to Shannon)
* handle the case when we don't have route but have device parameter
* cast new MTU to int and then check the maximum (tdev->mtu can be
less than dev->hard_header_len)
net/ipv6/ip6_vti.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index dbb74f3..5404443 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -626,6 +626,7 @@ static void vti6_link_config(struct ip6_tnl *t)
{
struct net_device *dev = t->dev;
struct __ip6_tnl_parm *p = &t->parms;
+ struct net_device *tdev = NULL;
memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -638,6 +639,26 @@ static void vti6_link_config(struct ip6_tnl *t)
dev->flags |= IFF_POINTOPOINT;
else
dev->flags &= ~IFF_POINTOPOINT;
+
+ if (p->flags & IP6_TNL_F_CAP_XMIT) {
+ int strict = (ipv6_addr_type(&p->raddr) &
+ (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
+
+ struct rt6_info *rt = rt6_lookup(t->net,
+ &p->raddr, &p->laddr,
+ p->link, strict);
+
+ if (rt)
+ tdev = rt->dst.dev;
+ ip6_rt_put(rt);
+ }
+
+ if (!tdev && p->link)
+ tdev = __dev_get_by_index(t->net, p->link);
+
+ if (tdev)
+ dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
+ IPV6_MIN_MTU);
}
/**
--
1.7.1
^ permalink raw reply related
* [PATCH 2/2] ip6_gre: fix potential memory leak in ip6erspan_rcv
From: Haishuang Yan @ 2017-12-14 15:15 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan, William Tu
In-Reply-To: <1513264507-26199-1-git-send-email-yanhaishuang@cmss.chinamobile.com>
If md is NULL, tun_dst must be freed, otherwise it will cause memory
leak
Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv6/ip6_gre.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 4562579..b8b0e4b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -542,8 +542,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
info = &tun_dst->u.tun_info;
md = ip_tunnel_info_opts(info);
- if (!md)
+ if (!md) {
+ dst_release((struct dst_entry *)tun_dst);
return PACKET_REJECT;
+ }
md->index = index;
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2] ip_gre: fix potential memory leak in erspan_rcv
From: Haishuang Yan @ 2017-12-14 15:15 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan, William Tu
If md is NULL, tun_dst must be freed, otherwise it will cause memory
leak.
Fixes: 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv4/ip_gre.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index d828821..9253d6f 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -304,8 +304,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
return PACKET_REJECT;
md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
- if (!md)
+ if (!md) {
+ dst_release((struct dst_entry *)tun_dst);
return PACKET_REJECT;
+ }
md->index = index;
info = &tun_dst->u.tun_info;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v2] ARM64: dts: meson-axg: add ethernet mac controller
From: Jerome Brunet @ 2017-12-14 14:52 UTC (permalink / raw)
To: Yixun Lan, devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman
Cc: Neil Armstrong, Giuseppe Cavallaro, Alexandre Torgue,
Carlo Caione, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171214030242.113152-1-yixun.lan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org>
On Thu, 2017-12-14 at 11:02 +0800, Yixun Lan wrote:
> Add DT info for the stmmac ethernet MAC which found in
> the Amlogic's Meson-AXG SoC, also describe the ethernet
> pinctrl & clock information here.
>
> This is tested in the S400 dev board which use a RTL8211F PHY,
> and the pins connect to the 'eth_rgmii_y_pins' group.
>
> Reviewed-by: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Yixun Lan <yixun.lan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org>
I think it would have been better to split this into 2 patches.
One adding the controller for axg, the other using it in the s400, but maybe
Kevin is OK with it...
>
> ---
> Changes in v2 since [1]:
> - rebase to kevin's v4.16/dt64 branch
> - add Neil's Reviewed-by
> - move clock info to board.dts instead of in soc.dtsi
> - drop "meson-axg-dwmac" compatible string, since we didn't use this
> we could re-add it later when we really need.
> - note: to make ethernet work properly,it depend on clock & pinctrl[2],
> to compile the DTS, the patch [3] is required.
> the code part will be taken via clock & pinctrl subsystem tree.
>
> [1]
> http://lists.infradead.org/pipermail/linux-amlogic/2017-November/005301.html
>
> [2]
> http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005735.html
> http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005694.html
>
> [3]
> http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005738.html
> ---
> arch/arm64/boot/dts/amlogic/meson-axg-s400.dts | 11 ++++++
> arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 50 ++++++++++++++++++++++++++
> 2 files changed, 61 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> index 70eca1f8736a..138de3bc7cc8 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> @@ -20,3 +20,14 @@
> &uart_AO {
> status = "okay";
> };
> +
> +ðmac {
We try to keep nodes alphabetically ordered.
Please put ethmac before uart_A0
thx
>
>
With all the dependencies sorted out, it works
Tested-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
--
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] Fix handling of verdicts after NF_QUEUE
From: Pablo Neira Ayuso @ 2017-12-14 12:30 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Debabrata Banerjee, David S . Miller, netfilter-devel, coreteam,
netdev, stable
In-Reply-To: <20171213203337.314-1-dbanerje@akamai.com>
Hi Greg,
I'd appreciate if you can take this patch into 4.9-stable. There is no
similar patch in tree, so this is not a backport.
On Wed, Dec 13, 2017 at 03:33:37PM -0500, Debabrata Banerjee wrote:
> A verdict of NF_STOLEN after NF_QUEUE will cause an incorrect return value
> and a potential kernel panic via double free of skb's
>
> This was broken by commit 7034b566a4e7 ("netfilter: fix nf_queue handling")
> and subsequently fixed in v4.10 by commit c63cbc460419 ("netfilter:
> use switch() to handle verdict cases from nf_hook_slow()"). However that
> commit cannot be cleanly cherry-picked to v4.9
>
> Signed-off-by: Debabrata Banerjee <dbanerje@akamai.com>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Thanks a lot!
> ---
>
> This fix is only needed for v4.9 stable since v4.10+ does not have the
> issue
> ---
> net/netfilter/core.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/net/netfilter/core.c b/net/netfilter/core.c
> index 004af030ef1a..d869ea50623e 100644
> --- a/net/netfilter/core.c
> +++ b/net/netfilter/core.c
> @@ -364,6 +364,11 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state)
> ret = nf_queue(skb, state, &entry, verdict);
> if (ret == 1 && entry)
> goto next_hook;
> + } else {
> + /* Implicit handling for NF_STOLEN, as well as any other
> + * non conventional verdicts.
> + */
> + ret = 0;
> }
> return ret;
> }
> --
> 2.15.1
>
^ permalink raw reply
* Re: net-next libbpf broken on prev kernel release
From: Arnaldo Carvalho de Melo @ 2017-12-14 14:28 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Eric Leblond, Martin KaFai Lau, ast, netdev
In-Reply-To: <91dc11ff-0bf8-2db3-a933-27fb60869082@iogearbox.net>
Em Thu, Dec 14, 2017 at 10:52:19AM +0100, Daniel Borkmann escreveu:
> [ +acme, +ast ]
>
> On 12/14/2017 10:16 AM, Eric Leblond wrote:
> > Hello,
> >
> > It seems that the following patch did break libbpf (in net-next
> > version) which is not able to load anymore a program on a 4.14:
> >
> > tree 5096ddd73981e33a2164606461a45b56a189889c
> > parent ad5b177bd73f5107d97c36f56395c4281fb6f089
> > author Martin KaFai Lau <kafai@fb.com> Wed Sep 27 14:37:54 2017 -0700
> > committer David S. Miller <davem@davemloft.net> Fri Sep 29 06:17:05 2017 +0100
> >
> > bpf: libbpf: Provide basic API support to specify BPF obj name
> >
> > The problem comes from
> >
> > -int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
> > - size_t insns_cnt, const char *license,
> > - __u32 kern_version, char *log_buf, size_t log_buf_sz)
> > +int bpf_load_program_name(enum bpf_prog_type type, const char *name,
> > + const struct bpf_insn *insns,
> > + size_t insns_cnt, const char *license,
> > + __u32 kern_version, char *log_buf,
> > + size_t log_buf_sz)
> > {
> > int fd;
> > union bpf_attr attr;
> > + __u32 name_len = name ? strlen(name) : 0;
> >
> > bzero(&attr, sizeof(attr));
> > attr.prog_type = type;
> > @@ -130,6 +151,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
> > attr.log_size = 0;
> > attr.log_level = 0;
> > attr.kern_version = kern_version;
> > + memcpy(attr.prog_name, name, min(name_len, BPF_OBJ_NAME_LEN - 1));
> >
> > If I comment the memcpy then the eBPF program is loading correctly.
> >
> > Is this a wanted behavior to have libbpf that needs to be in sync with
> > kernel ? or should it be fixed ?
> Yeah, this was reported recently here: https://lkml.org/lkml/2017/11/28/1246
> I agree that given the policy of perf tool is to try to use new features
> but if they fail on older kernels, then we should try to fallback whenever
> that is feasible. I think for this specific case, we should in-fact fallback
> and try w/o map/prog name in order to fix this regression for perf (or
> other lib users).
> Also agree that this cannot be done for every possible case like the mentioned
> prog_ifindex field for offloading to NIC in the thread above, but I imho
> the prog_ifindex is a slightly different situation given that a user needs
> to specifically ask to offload via some provided API.
> I think the fix should be: if a user *specifically* calls bpf_load_program_name()
> or bpf_create_map_name() API from the lib, then the intention is very clear
> that the bpf object should be created *with* name and otherwise fail. So a
> fallback for these APIs to load w/o name would be inappropriate! But for the
> existing code that used to load objects before, e.g. bpf_object__create_maps()
> or bpf_program__load() it should try to use either mentioned bpf_*_name() APIs
> and *iff* they fail, fall-back to the normal ones w/o name attribute. Meaning,
> this kind of fall-back should be done, but not on a sys_bpf() layer but from
> a higher PoV in the lib instead. I guess it would make sense to probe the
> underlying kernel at startup and then based on its capabilities use one out
> of the two APIs when we get there, such that we don't need to uselessly retry
> APIs for each prog load.
tools/perf/ has:
static struct {
bool sample_id_all;
bool exclude_guest;
bool mmap2;
bool cloexec;
bool clockid;
bool clockid_wrong;
bool lbr_flags;
bool write_backward;
bool group_read;
} perf_missing_features;
When the user request something that needs some of these features we try
using it, failing it will mark it as missing and then other events will
not needlessly try using it, i.e. we don't do it at program start, we
leave that to when we actually need it, to avoid uselessly probing at
startup.
> Arnaldo, will there be a rework of your fix that we could route to bpf tree?
I'm resuming work on it after I get my current batch tested and
submitted, will reboot with an older kernel and follow your suggestions,
that seems to match Alexei's and Martin's, my patch was just a RFC to
show that we need a fallback for older kernels.
I needed to move on, so I updated my machine to a kernel where interlock
of tools/ with the kernel happens and it worked, so I left this to see
if someone else complained or if I was being too picky. :-)
- Arnaldo
^ permalink raw reply
* [PATCH net-next] net: tap: fix POLLOUT condition in tap_poll()
From: yuan linyu @ 2017-12-14 14:22 UTC (permalink / raw)
To: netdev; +Cc: David S . Miller, yuan linyu
From: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
from logical view, if sock_writeable(&q->sk) return false,
original second condition will return false too,
change it and make second condition can return true.
Signed-off-by: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
---
drivers/net/tap.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 0a886fda..72212bf 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -587,8 +587,7 @@ static unsigned int tap_poll(struct file *file, poll_table *wait)
mask |= POLLIN | POLLRDNORM;
if (sock_writeable(&q->sk) ||
- (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &q->sock.flags) &&
- sock_writeable(&q->sk)))
+ !test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &q->sock.flags))
mask |= POLLOUT | POLLWRNORM;
out:
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net 3/3] pkt_sched: Remove TC_RED_OFFLOADED from uapi
From: Jiri Pirko @ 2017-12-14 14:07 UTC (permalink / raw)
To: Yuval Mintz; +Cc: davem, netdev, mlxsw
In-Reply-To: <1513259671-1183-4-git-send-email-yuvalm@mellanox.com>
Thu, Dec 14, 2017 at 02:54:31PM CET, yuvalm@mellanox.com wrote:
>Following the previous patch, RED is now using the new uniform uapi
>for indicating it's offloaded. As a result, TC_RED_OFFLOADED is no
>longer utilized by kernel and can be removed [as it's still not
>part of any stable release].
>
>Fixes: 602f3baf2218 ("net_sch: red: Add offload ability to RED qdisc")
>Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* Re: [PATCH net 2/3] net: sched: Move to new offload indication in RED
From: Jiri Pirko @ 2017-12-14 14:07 UTC (permalink / raw)
To: Yuval Mintz; +Cc: davem, netdev, mlxsw
In-Reply-To: <1513259671-1183-3-git-send-email-yuvalm@mellanox.com>
Thu, Dec 14, 2017 at 02:54:30PM CET, yuvalm@mellanox.com wrote:
>Let RED utilize the new internal flag, TCQ_F_OFFLOADED,
>to mark a given qdisc as offloaded instead of using a dedicated
>indication.
>
>Also, change internal logic into looking at said flag when possible.
>
>Fixes: 602f3baf2218 ("net_sch: red: Add offload ability to RED qdisc")
>Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Note that it would be good to add red offload presence in drivers
(mlxsw) and forbid to disable tc offload feature in that case.
^ permalink raw reply
* Re: [PATCH net 1/3] net: sched: Add TCA_HW_OFFLOAD
From: Jiri Pirko @ 2017-12-14 14:04 UTC (permalink / raw)
To: Yuval Mintz; +Cc: davem, netdev, mlxsw
In-Reply-To: <1513259671-1183-2-git-send-email-yuvalm@mellanox.com>
Thu, Dec 14, 2017 at 02:54:29PM CET, yuvalm@mellanox.com wrote:
>Qdiscs can be offloaded to HW, but current implementation isn't uniform.
>Instead, qdiscs either pass information about offload status via their
>TCA_OPTIONS or omit it altogether.
>
>Introduce a new attribute - TCA_HW_OFFLOAD that would form a uniform
>uAPI for the offloading status of qdiscs.
>
>Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* [PATCH net 2/3] net: sched: Move to new offload indication in RED
From: Yuval Mintz @ 2017-12-14 13:54 UTC (permalink / raw)
To: davem, netdev; +Cc: mlxsw, Yuval Mintz
In-Reply-To: <1513259671-1183-1-git-send-email-yuvalm@mellanox.com>
Let RED utilize the new internal flag, TCQ_F_OFFLOADED,
to mark a given qdisc as offloaded instead of using a dedicated
indication.
Also, change internal logic into looking at said flag when possible.
Fixes: 602f3baf2218 ("net_sch: red: Add offload ability to RED qdisc")
Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
---
net/sched/sch_red.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 9d874e6..f0747eb 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
.handle = sch->handle,
.parent = sch->parent,
};
+ int err;
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return -EOPNOTSUPP;
@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable)
opt.command = TC_RED_DESTROY;
}
- return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
+ err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
+
+ if (!err && enable)
+ sch->flags |= TCQ_F_OFFLOADED;
+ else
+ sch->flags &= ~TCQ_F_OFFLOADED;
+
+ return err;
}
static void red_destroy(struct Qdisc *sch)
@@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt)
return red_change(sch, opt);
}
-static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
+static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt)
{
struct net_device *dev = qdisc_dev(sch);
struct tc_red_qopt_offload hw_stats = {
@@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
.stats.qstats = &sch->qstats,
},
};
- int err;
- opt->flags &= ~TC_RED_OFFLOADED;
- if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
- return 0;
-
- err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
- &hw_stats);
- if (err == -EOPNOTSUPP)
+ if (!(sch->flags & TCQ_F_OFFLOADED))
return 0;
- if (!err)
- opt->flags |= TC_RED_OFFLOADED;
-
- return err;
+ return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
+ &hw_stats);
}
static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
@@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
int err;
sch->qstats.backlog = q->qdisc->qstats.backlog;
- err = red_dump_offload(sch, &opt);
+ err = red_dump_offload_stats(sch, &opt);
if (err)
goto nla_put_failure;
@@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
.marked = q->stats.prob_mark + q->stats.forced_mark,
};
- if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) {
+ if (sch->flags & TCQ_F_OFFLOADED) {
struct red_stats hw_stats = {0};
struct tc_red_qopt_offload hw_stats_request = {
.command = TC_RED_XSTATS,
--
2.4.3
^ permalink raw reply related
* [PATCH net 1/3] net: sched: Add TCA_HW_OFFLOAD
From: Yuval Mintz @ 2017-12-14 13:54 UTC (permalink / raw)
To: davem, netdev; +Cc: mlxsw, Yuval Mintz
In-Reply-To: <1513259671-1183-1-git-send-email-yuvalm@mellanox.com>
Qdiscs can be offloaded to HW, but current implementation isn't uniform.
Instead, qdiscs either pass information about offload status via their
TCA_OPTIONS or omit it altogether.
Introduce a new attribute - TCA_HW_OFFLOAD that would form a uniform
uAPI for the offloading status of qdiscs.
Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
---
Do Notice this is going to create [easy-to-solve-]conflicts with net-next,
Due to 6b3ba9146fe6 ("net: sched: allow qdiscs to handle locking").
That's also why the numbering here are apparently inconsistent [skipping
0x100].
---
include/net/sch_generic.h | 1 +
include/uapi/linux/rtnetlink.h | 1 +
net/sched/sch_api.c | 2 ++
3 files changed, 4 insertions(+)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 65d0d25..83a3e47 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -71,6 +71,7 @@ struct Qdisc {
* qdisc_tree_decrease_qlen() should stop.
*/
#define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */
+#define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */
u32 limit;
const struct Qdisc_ops *ops;
struct qdisc_size_table __rcu *stab;
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index d8b5f80..843e29a 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -557,6 +557,7 @@ enum {
TCA_PAD,
TCA_DUMP_INVISIBLE,
TCA_CHAIN,
+ TCA_HW_OFFLOAD,
__TCA_MAX
};
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index b6c4f53..0f1eab9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
tcm->tcm_info = refcount_read(&q->refcnt);
if (nla_put_string(skb, TCA_KIND, q->ops->id))
goto nla_put_failure;
+ if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED)))
+ goto nla_put_failure;
if (q->ops->dump && q->ops->dump(q, skb) < 0)
goto nla_put_failure;
qlen = q->q.qlen;
--
2.4.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