* Re: [PATCH bpf-next] kbuild: replace BASH-specific ${@:2} with shift and ${@}
From: Yonghong Song @ 2019-09-05 23:59 UTC (permalink / raw)
To: Andrii Nakryiko, bpf@vger.kernel.org, netdev@vger.kernel.org,
Alexei Starovoitov, daniel@iogearbox.net
Cc: andrii.nakryiko@gmail.com, Kernel Team, Stephen Rothwell,
Masahiro Yamada
In-Reply-To: <20190905175938.599455-1-andriin@fb.com>
On 9/5/19 10:59 AM, Andrii Nakryiko wrote:
> ${@:2} is BASH-specific extension, which makes link-vmlinux.sh rely on
> BASH. Use shift and ${@} instead to fix this issue.
>
> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs")
> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested with bash/sh/csh, all works.
Acked-by: Yonghong Song <yhs@fb.com>
> ---
> scripts/link-vmlinux.sh | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> index 0d8f41db8cd6..8c59970a09dc 100755
> --- a/scripts/link-vmlinux.sh
> +++ b/scripts/link-vmlinux.sh
> @@ -57,12 +57,16 @@ modpost_link()
>
> # Link of vmlinux
> # ${1} - output file
> -# ${@:2} - optional extra .o files
> +# ${2}, ${3}, ... - optional extra .o files
> vmlinux_link()
> {
> local lds="${objtree}/${KBUILD_LDS}"
> + local output=${1}
> local objects
>
> + # skip output file argument
> + shift
> +
> if [ "${SRCARCH}" != "um" ]; then
> objects="--whole-archive \
> ${KBUILD_VMLINUX_OBJS} \
> @@ -70,9 +74,10 @@ vmlinux_link()
> --start-group \
> ${KBUILD_VMLINUX_LIBS} \
> --end-group \
> - ${@:2}"
> + ${@}"
>
> - ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${1} \
> + ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \
> + -o ${output} \
> -T ${lds} ${objects}
> else
> objects="-Wl,--whole-archive \
> @@ -81,9 +86,10 @@ vmlinux_link()
> -Wl,--start-group \
> ${KBUILD_VMLINUX_LIBS} \
> -Wl,--end-group \
> - ${@:2}"
> + ${@}"
>
> - ${CC} ${CFLAGS_vmlinux} -o ${1} \
> + ${CC} ${CFLAGS_vmlinux} \
> + -o ${output} \
> -Wl,-T,${lds} \
> ${objects} \
> -lutil -lrt -lpthread
>
^ permalink raw reply
* [PATCH net-next,v3 0/4] flow_offload: update mangle action representation
From: Pablo Neira Ayuso @ 2019-09-06 0:03 UTC (permalink / raw)
To: netfilter-devel
Cc: davem, netdev, jakub.kicinski, jiri, saeedm, vishal, vladbu
This patch updates the mangle action representation:
Patch 1) Undo bitwise NOT operation on the mangle mask (coming from tc
pedit userspace).
Patch 2) mangle value &= mask from the front-end side.
Patch 3) adjust offset, length and coalesce consecutive pedit keys into
one single action.
Patch 4) add support for payload mangling for netfilter.
After this patchset:
* Offset to payload does not need to be on the 32-bits boundaries anymore.
This patchset adds front-end code to adjust the offset and length coming
from the tc pedit representation, so drivers get an exact header field
offset and length.
* This new front-end code coalesces consecutive pedit actions into one
single action, so drivers can mangle IPv6 and ethernet address fields
in one go, instead once for each 32-bit word.
On the driver side, diffstat -t shows that drivers code to deal with
payload mangling gets simplified:
INSERTED,DELETED,MODIFIED,FILENAME
46,116,0,drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c (-70 LOC)
12,28,0,drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h (-16 LOC)
26,54,0,drivers/net/ethernet/mellanox/mlx5/core/en_tc.c (-27 LOC)
89,111,0,drivers/net/ethernet/netronome/nfp/flower/action.c (-17 LOC)
While, on the front-end side the balance is the following:
123,22,0,net/sched/cls_api.c (+101 LOC)
Changes since v2:
* Fix is_action_keys_supported() breakage in mlx5 reported by Vlad Buslov.
Pablo Neira Ayuso (4):
net: flow_offload: flip mangle action mask
net: flow_offload: bitwise AND on mangle action value field
net: flow_offload: mangle action at byte level
netfilter: nft_payload: packet mangling offload support
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 163 +++++-----------
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 40 ++--
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 80 +++-----
drivers/net/ethernet/netronome/nfp/flower/action.c | 204 ++++++++++-----------
include/net/flow_offload.h | 7 +-
net/netfilter/nft_payload.c | 73 ++++++++
net/sched/cls_api.c | 144 ++++++++++++---
7 files changed, 378 insertions(+), 333 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH net-next,v3 1/4] net: flow_offload: flip mangle action mask
From: Pablo Neira Ayuso @ 2019-09-06 0:04 UTC (permalink / raw)
To: netfilter-devel
Cc: davem, netdev, jakub.kicinski, jiri, saeedm, vishal, vladbu
In-Reply-To: <20190906000403.3701-1-pablo@netfilter.org>
Userspace tc pedit action performs a bitwise NOT operation on the mask.
All of the existing drivers in the tree undo this operation. Prepare the
mangle mask in the way the drivers expect from the
tc_setup_flow_action() function.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 12 ++++++------
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 6 +++---
drivers/net/ethernet/netronome/nfp/flower/action.c | 8 ++++----
net/sched/cls_api.c | 2 +-
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index e447976bdd3e..2d26dbca701d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -275,7 +275,7 @@ static int cxgb4_validate_flow_match(struct net_device *dev,
static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
u8 field)
{
- u32 set_val = val & ~mask;
+ u32 set_val = val & mask;
u32 offset = 0;
u8 size = 1;
int i;
@@ -301,7 +301,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
offload_pedit(fs, val, mask, ETH_DMAC_31_0);
break;
case PEDIT_ETH_DMAC_47_32_SMAC_15_0:
- if (~mask & PEDIT_ETH_DMAC_MASK)
+ if (mask & PEDIT_ETH_DMAC_MASK)
offload_pedit(fs, val, mask, ETH_DMAC_47_32);
else
offload_pedit(fs, val >> 16, mask >> 16,
@@ -353,7 +353,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) {
case PEDIT_TCP_SPORT_DPORT:
- if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
+ if (mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16,
cpu_to_be32(mask) >> 16,
TCP_SPORT);
@@ -366,7 +366,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) {
case PEDIT_UDP_SPORT_DPORT:
- if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
+ if (mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16,
cpu_to_be32(mask) >> 16,
UDP_SPORT);
@@ -510,7 +510,7 @@ static bool valid_pedit_action(struct net_device *dev,
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) {
case PEDIT_TCP_SPORT_DPORT:
- if (!valid_l4_mask(~mask)) {
+ if (!valid_l4_mask(mask)) {
netdev_err(dev, "%s: Unsupported mask for TCP L4 ports\n",
__func__);
return false;
@@ -525,7 +525,7 @@ static bool valid_pedit_action(struct net_device *dev,
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) {
case PEDIT_UDP_SPORT_DPORT:
- if (!valid_l4_mask(~mask)) {
+ if (!valid_l4_mask(mask)) {
netdev_err(dev, "%s: Unsupported mask for UDP L4 ports\n",
__func__);
return false;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 30d26eba75a3..3db63cf41ee5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2509,7 +2509,7 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
val = act->mangle.val;
offset = act->mangle.offset;
- err = set_pedit_val(htype, ~mask, val, offset, &hdrs[cmd]);
+ err = set_pedit_val(htype, mask, val, offset, &hdrs[cmd]);
if (err)
goto out_err;
@@ -2609,7 +2609,7 @@ static bool is_action_keys_supported(const struct flow_action_entry *act)
htype = act->mangle.htype;
offset = act->mangle.offset;
- mask = ~act->mangle.mask;
+ mask = act->mangle.mask;
/* For IPv4 & IPv6 header check 4 byte word,
* to determine that modified fields
* are NOT ttl & hop_limit only.
@@ -2733,7 +2733,7 @@ static int add_vlan_rewrite_action(struct mlx5e_priv *priv, int namespace,
.id = FLOW_ACTION_MANGLE,
.mangle.htype = FLOW_ACT_MANGLE_HDR_TYPE_ETH,
.mangle.offset = offsetof(struct vlan_ethhdr, h_vlan_TCI),
- .mangle.mask = ~(u32)be16_to_cpu(*(__be16 *)&mask16),
+ .mangle.mask = (u32)be16_to_cpu(*(__be16 *)&mask16),
.mangle.val = (u32)be16_to_cpu(*(__be16 *)&val16),
};
u8 match_prio_mask, match_prio_val;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index 1b019fdfcd97..ee0066a7ba87 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -495,7 +495,7 @@ nfp_fl_set_eth(const struct flow_action_entry *act, u32 off,
return -EOPNOTSUPP;
}
- mask = ~act->mangle.mask;
+ mask = act->mangle.mask;
exact = act->mangle.val;
if (exact & ~mask) {
@@ -532,7 +532,7 @@ nfp_fl_set_ip4(const struct flow_action_entry *act, u32 off,
__be32 exact, mask;
/* We are expecting tcf_pedit to return a big endian value */
- mask = (__force __be32)~act->mangle.mask;
+ mask = (__force __be32)act->mangle.mask;
exact = (__force __be32)act->mangle.val;
if (exact & ~mask) {
@@ -673,7 +673,7 @@ nfp_fl_set_ip6(const struct flow_action_entry *act, u32 off,
u8 word;
/* We are expecting tcf_pedit to return a big endian value */
- mask = (__force __be32)~act->mangle.mask;
+ mask = (__force __be32)act->mangle.mask;
exact = (__force __be32)act->mangle.val;
if (exact & ~mask) {
@@ -713,7 +713,7 @@ nfp_fl_set_tport(const struct flow_action_entry *act, u32 off,
return -EOPNOTSUPP;
}
- mask = ~act->mangle.mask;
+ mask = act->mangle.mask;
exact = act->mangle.val;
if (exact & ~mask) {
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 671ca905dbb5..fbab004d0075 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3379,7 +3379,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
goto err_out;
}
entry->mangle.htype = tcf_pedit_htype(act, k);
- entry->mangle.mask = tcf_pedit_mask(act, k);
+ entry->mangle.mask = ~tcf_pedit_mask(act, k);
entry->mangle.val = tcf_pedit_val(act, k);
entry->mangle.offset = tcf_pedit_offset(act, k);
entry = &flow_action->entries[++j];
--
2.11.0
^ permalink raw reply related
* [PATCH net-next,v3 2/4] net: flow_offload: bitwise AND on mangle action value field
From: Pablo Neira Ayuso @ 2019-09-06 0:04 UTC (permalink / raw)
To: netfilter-devel
Cc: davem, netdev, jakub.kicinski, jiri, saeedm, vishal, vladbu
In-Reply-To: <20190906000403.3701-1-pablo@netfilter.org>
Drivers perform a bitwise AND on the value and the mask. Update
tc_setup_flow_action() to perform this operation so drivers do not need
to do this.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 3 +--
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +-
drivers/net/ethernet/netronome/nfp/flower/action.c | 9 ++++-----
net/sched/cls_api.c | 3 ++-
4 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 2d26dbca701d..5afc15a60199 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -275,7 +275,6 @@ static int cxgb4_validate_flow_match(struct net_device *dev,
static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
u8 field)
{
- u32 set_val = val & mask;
u32 offset = 0;
u8 size = 1;
int i;
@@ -287,7 +286,7 @@ static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
break;
}
}
- memcpy((u8 *)fs + offset, &set_val, size);
+ memcpy((u8 *)fs + offset, &val, size);
}
static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 3db63cf41ee5..ec47e994b7e0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2214,7 +2214,7 @@ static int set_pedit_val(u8 hdr_type, u32 mask, u32 val, u32 offset,
goto out_err;
*curr_pmask |= mask;
- *curr_pval |= (val & mask);
+ *curr_pval |= val;
return 0;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index ee0066a7ba87..592c36ba9e3f 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -477,7 +477,6 @@ static void nfp_fl_set_helper32(u32 value, u32 mask, u8 *p_exact, u8 *p_mask)
u32 oldvalue = get_unaligned((u32 *)p_exact);
u32 oldmask = get_unaligned((u32 *)p_mask);
- value &= mask;
value |= oldvalue & ~mask;
put_unaligned(oldmask | mask, (u32 *)p_mask);
@@ -544,7 +543,7 @@ nfp_fl_set_ip4(const struct flow_action_entry *act, u32 off,
case offsetof(struct iphdr, daddr):
set_ip_addr->ipv4_dst_mask |= mask;
set_ip_addr->ipv4_dst &= ~mask;
- set_ip_addr->ipv4_dst |= exact & mask;
+ set_ip_addr->ipv4_dst |= exact;
set_ip_addr->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
set_ip_addr->head.len_lw = sizeof(*set_ip_addr) >>
NFP_FL_LW_SIZ;
@@ -552,7 +551,7 @@ nfp_fl_set_ip4(const struct flow_action_entry *act, u32 off,
case offsetof(struct iphdr, saddr):
set_ip_addr->ipv4_src_mask |= mask;
set_ip_addr->ipv4_src &= ~mask;
- set_ip_addr->ipv4_src |= exact & mask;
+ set_ip_addr->ipv4_src |= exact;
set_ip_addr->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
set_ip_addr->head.len_lw = sizeof(*set_ip_addr) >>
NFP_FL_LW_SIZ;
@@ -606,7 +605,7 @@ nfp_fl_set_ip6_helper(int opcode_tag, u8 word, __be32 exact, __be32 mask,
{
ip6->ipv6[word].mask |= mask;
ip6->ipv6[word].exact &= ~mask;
- ip6->ipv6[word].exact |= exact & mask;
+ ip6->ipv6[word].exact |= exact;
ip6->reserved = cpu_to_be16(0);
ip6->head.jump_id = opcode_tag;
@@ -651,7 +650,7 @@ nfp_fl_set_ip6_hop_limit_flow_label(u32 off, __be32 exact, __be32 mask,
ip_hl_fl->ipv6_label_mask |= mask;
ip_hl_fl->ipv6_label &= ~mask;
- ip_hl_fl->ipv6_label |= exact & mask;
+ ip_hl_fl->ipv6_label |= exact;
break;
}
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index fbab004d0075..e30a151d8527 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3380,7 +3380,8 @@ int tc_setup_flow_action(struct flow_action *flow_action,
}
entry->mangle.htype = tcf_pedit_htype(act, k);
entry->mangle.mask = ~tcf_pedit_mask(act, k);
- entry->mangle.val = tcf_pedit_val(act, k);
+ entry->mangle.val = tcf_pedit_val(act, k) &
+ entry->mangle.mask;
entry->mangle.offset = tcf_pedit_offset(act, k);
entry = &flow_action->entries[++j];
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next,v3 4/4] netfilter: nft_payload: packet mangling offload support
From: Pablo Neira Ayuso @ 2019-09-06 0:04 UTC (permalink / raw)
To: netfilter-devel
Cc: davem, netdev, jakub.kicinski, jiri, saeedm, vishal, vladbu
In-Reply-To: <20190906000403.3701-1-pablo@netfilter.org>
This patch allows for mangling packet fields using hardware offload
infrastructure.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_payload.c | 73 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 22a80eb60222..0efa8bfd2b51 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -562,12 +562,85 @@ static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr
return -1;
}
+static int nft_payload_offload_set_nh(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow,
+ const struct nft_payload_set *priv)
+{
+ int type = FLOW_ACT_MANGLE_UNSPEC;
+
+ switch (ctx->dep.l3num) {
+ case htons(ETH_P_IP):
+ type = FLOW_ACT_MANGLE_HDR_TYPE_IP4;
+ break;
+ case htons(ETH_P_IPV6):
+ type = FLOW_ACT_MANGLE_HDR_TYPE_IP6;
+ break;
+ }
+
+ return type;
+}
+
+static int nft_payload_offload_set_th(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow,
+ const struct nft_payload_set *priv)
+{
+ int type = FLOW_ACT_MANGLE_UNSPEC;
+
+ switch (ctx->dep.protonum) {
+ case IPPROTO_TCP:
+ type = FLOW_ACT_MANGLE_HDR_TYPE_TCP;
+ break;
+ case IPPROTO_UDP:
+ type = FLOW_ACT_MANGLE_HDR_TYPE_UDP;
+ break;
+ }
+
+ return type;
+}
+
+static int nft_payload_set_offload(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow,
+ const struct nft_expr *expr)
+{
+ const struct nft_payload_set *priv = nft_expr_priv(expr);
+ struct nft_offload_reg *sreg = &ctx->regs[priv->sreg];
+ int type = FLOW_ACT_MANGLE_UNSPEC;
+ struct flow_action_entry *entry;
+
+ switch (priv->base) {
+ case NFT_PAYLOAD_LL_HEADER:
+ type = FLOW_ACT_MANGLE_HDR_TYPE_ETH;
+ break;
+ case NFT_PAYLOAD_NETWORK_HEADER:
+ type = nft_payload_offload_set_nh(ctx, flow, priv);
+ break;
+ case NFT_PAYLOAD_TRANSPORT_HEADER:
+ type = nft_payload_offload_set_th(ctx, flow, priv);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+
+ entry = &flow->rule->action.entries[ctx->num_actions++];
+ entry->id = FLOW_ACTION_MANGLE;
+ entry->mangle.htype = type;
+ entry->mangle.offset = priv->offset;
+ entry->mangle.len = priv->len;
+
+ memcpy(entry->mangle.val, sreg->data.data, priv->len);
+ memset(entry->mangle.mask, 0xff, priv->len);
+
+ return type != FLOW_ACT_MANGLE_UNSPEC ? 0 : -EOPNOTSUPP;
+}
+
static const struct nft_expr_ops nft_payload_set_ops = {
.type = &nft_payload_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_payload_set)),
.eval = nft_payload_set_eval,
.init = nft_payload_set_init,
.dump = nft_payload_set_dump,
+ .offload = nft_payload_set_offload,
};
static const struct nft_expr_ops *
--
2.11.0
^ permalink raw reply related
* [PATCH net-next,v3 3/4] net: flow_offload: mangle action at byte level
From: Pablo Neira Ayuso @ 2019-09-06 0:04 UTC (permalink / raw)
To: netfilter-devel
Cc: davem, netdev, jakub.kicinski, jiri, saeedm, vishal, vladbu
In-Reply-To: <20190906000403.3701-1-pablo@netfilter.org>
The flow mangle action is originally modeled after the tc pedit action,
this has a number of shortcomings:
1) The tc pedit offset must be set on the 32-bits boundaries. Many
protocol header field offsets are not aligned to 32-bits, eg. port
destination, port source and ethernet destination. This patch adjusts
the offset accordingly and trim off length in these case, so drivers get
an exact offset and length to the header fields.
2) The maximum mangle length is one word of 32-bits, hence you need to
up to four actions to mangle an IPv6 address. This patch coalesces
consecutive tc pedit actions into one single action so drivers can
configure the IPv6 mangling in one go. Ethernet address fields now
require one single action instead of two too.
The following drivers have been updated accordingly to use this new
mangle action layout:
1) The cxgb4 driver does not need to split protocol field matching
larger than one 32-bit words into multiple definitions. Instead one
single definition per protocol field is enough. Checking for
transport protocol ports is also simplified.
2) The mlx5 driver logic to disallow IPv4 ttl and IPv6 hoplimit fields
becomes more simple too.
3) The nfp driver uses the nfp_fl_set_helper() function to configure the
payload mangling. The memchr_inv() function is used to check for
proper initialization of the value and mask. The driver has been
updated to refer to the exact protocol header offsets too.
As a result, this patch reduces code complexity on the driver side at
the cost of adding ~100 LOC at the core to perform offset and length
adjustment; and to coalesce consecutive actions.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 162 +++++-----------
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 40 ++--
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 80 +++-----
drivers/net/ethernet/netronome/nfp/flower/action.c | 203 ++++++++++-----------
include/net/flow_offload.h | 7 +-
net/sched/cls_api.c | 145 ++++++++++++---
6 files changed, 305 insertions(+), 332 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 5afc15a60199..ba1ced08e41c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -44,20 +44,12 @@
#define STATS_CHECK_PERIOD (HZ / 2)
static struct ch_tc_pedit_fields pedits[] = {
- PEDIT_FIELDS(ETH_, DMAC_31_0, 4, dmac, 0),
- PEDIT_FIELDS(ETH_, DMAC_47_32, 2, dmac, 4),
- PEDIT_FIELDS(ETH_, SMAC_15_0, 2, smac, 0),
- PEDIT_FIELDS(ETH_, SMAC_47_16, 4, smac, 2),
+ PEDIT_FIELDS(ETH_, DMAC, 6, dmac, 0),
+ PEDIT_FIELDS(ETH_, SMAC, 6, smac, 0),
PEDIT_FIELDS(IP4_, SRC, 4, nat_fip, 0),
PEDIT_FIELDS(IP4_, DST, 4, nat_lip, 0),
- PEDIT_FIELDS(IP6_, SRC_31_0, 4, nat_fip, 0),
- PEDIT_FIELDS(IP6_, SRC_63_32, 4, nat_fip, 4),
- PEDIT_FIELDS(IP6_, SRC_95_64, 4, nat_fip, 8),
- PEDIT_FIELDS(IP6_, SRC_127_96, 4, nat_fip, 12),
- PEDIT_FIELDS(IP6_, DST_31_0, 4, nat_lip, 0),
- PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4),
- PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8),
- PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12),
+ PEDIT_FIELDS(IP6_, SRC, 16, nat_fip, 0),
+ PEDIT_FIELDS(IP6_, DST, 16, nat_lip, 0),
PEDIT_FIELDS(TCP_, SPORT, 2, nat_fport, 0),
PEDIT_FIELDS(TCP_, DPORT, 2, nat_lport, 0),
PEDIT_FIELDS(UDP_, SPORT, 2, nat_fport, 0),
@@ -272,8 +264,8 @@ static int cxgb4_validate_flow_match(struct net_device *dev,
return 0;
}
-static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
- u8 field)
+static void offload_pedit(struct ch_filter_specification *fs,
+ struct flow_action_entry *act, u8 field)
{
u32 offset = 0;
u8 size = 1;
@@ -286,92 +278,68 @@ static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
break;
}
}
- memcpy((u8 *)fs + offset, &val, size);
+ memcpy((u8 *)fs + offset, act->mangle.val, size);
}
-static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
- u32 mask, u32 offset, u8 htype)
+static void process_pedit_field(struct ch_filter_specification *fs,
+ struct flow_action_entry *act)
{
+ u32 offset = act->mangle.offset;
+ u8 htype = act->mangle.htype;
+
switch (htype) {
case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
switch (offset) {
- case PEDIT_ETH_DMAC_31_0:
+ case PEDIT_ETH_DMAC:
fs->newdmac = 1;
- offload_pedit(fs, val, mask, ETH_DMAC_31_0);
- break;
- case PEDIT_ETH_DMAC_47_32_SMAC_15_0:
- if (mask & PEDIT_ETH_DMAC_MASK)
- offload_pedit(fs, val, mask, ETH_DMAC_47_32);
- else
- offload_pedit(fs, val >> 16, mask >> 16,
- ETH_SMAC_15_0);
+ offload_pedit(fs, act, ETH_DMAC);
break;
- case PEDIT_ETH_SMAC_47_16:
+ case PEDIT_ETH_SMAC:
fs->newsmac = 1;
- offload_pedit(fs, val, mask, ETH_SMAC_47_16);
+ offload_pedit(fs, act, ETH_SMAC);
+ break;
}
break;
case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
switch (offset) {
case PEDIT_IP4_SRC:
- offload_pedit(fs, val, mask, IP4_SRC);
+ offload_pedit(fs, act, IP4_SRC);
break;
case PEDIT_IP4_DST:
- offload_pedit(fs, val, mask, IP4_DST);
+ offload_pedit(fs, act, IP4_DST);
}
fs->nat_mode = NAT_MODE_ALL;
break;
case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
switch (offset) {
- case PEDIT_IP6_SRC_31_0:
- offload_pedit(fs, val, mask, IP6_SRC_31_0);
- break;
- case PEDIT_IP6_SRC_63_32:
- offload_pedit(fs, val, mask, IP6_SRC_63_32);
- break;
- case PEDIT_IP6_SRC_95_64:
- offload_pedit(fs, val, mask, IP6_SRC_95_64);
- break;
- case PEDIT_IP6_SRC_127_96:
- offload_pedit(fs, val, mask, IP6_SRC_127_96);
- break;
- case PEDIT_IP6_DST_31_0:
- offload_pedit(fs, val, mask, IP6_DST_31_0);
+ case PEDIT_IP6_SRC:
+ offload_pedit(fs, act, IP6_SRC);
break;
- case PEDIT_IP6_DST_63_32:
- offload_pedit(fs, val, mask, IP6_DST_63_32);
+ case PEDIT_IP6_DST:
+ offload_pedit(fs, act, IP6_DST);
break;
- case PEDIT_IP6_DST_95_64:
- offload_pedit(fs, val, mask, IP6_DST_95_64);
- break;
- case PEDIT_IP6_DST_127_96:
- offload_pedit(fs, val, mask, IP6_DST_127_96);
}
fs->nat_mode = NAT_MODE_ALL;
break;
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) {
- case PEDIT_TCP_SPORT_DPORT:
- if (mask & PEDIT_TCP_UDP_SPORT_MASK)
- offload_pedit(fs, cpu_to_be32(val) >> 16,
- cpu_to_be32(mask) >> 16,
- TCP_SPORT);
- else
- offload_pedit(fs, cpu_to_be32(val),
- cpu_to_be32(mask), TCP_DPORT);
+ case PEDIT_TCP_SPORT:
+ offload_pedit(fs, act, TCP_SPORT);
+ break;
+ case PEDIT_TCP_DPORT:
+ offload_pedit(fs, act, TCP_DPORT);
+ break;
}
fs->nat_mode = NAT_MODE_ALL;
break;
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) {
- case PEDIT_UDP_SPORT_DPORT:
- if (mask & PEDIT_TCP_UDP_SPORT_MASK)
- offload_pedit(fs, cpu_to_be32(val) >> 16,
- cpu_to_be32(mask) >> 16,
- UDP_SPORT);
- else
- offload_pedit(fs, cpu_to_be32(val),
- cpu_to_be32(mask), UDP_DPORT);
+ case PEDIT_UDP_SPORT:
+ offload_pedit(fs, act, UDP_SPORT);
+ break;
+ case PEDIT_UDP_DPORT:
+ offload_pedit(fs, act, UDP_DPORT);
+ break;
}
fs->nat_mode = NAT_MODE_ALL;
}
@@ -424,17 +392,8 @@ static void cxgb4_process_flow_actions(struct net_device *in,
}
}
break;
- case FLOW_ACTION_MANGLE: {
- u32 mask, val, offset;
- u8 htype;
-
- htype = act->mangle.htype;
- mask = act->mangle.mask;
- val = act->mangle.val;
- offset = act->mangle.offset;
-
- process_pedit_field(fs, val, mask, offset, htype);
- }
+ case FLOW_ACTION_MANGLE:
+ process_pedit_field(fs, act);
break;
default:
break;
@@ -442,35 +401,20 @@ static void cxgb4_process_flow_actions(struct net_device *in,
}
}
-static bool valid_l4_mask(u32 mask)
-{
- u16 hi, lo;
-
- /* Either the upper 16-bits (SPORT) OR the lower
- * 16-bits (DPORT) can be set, but NOT BOTH.
- */
- hi = (mask >> 16) & 0xFFFF;
- lo = mask & 0xFFFF;
-
- return hi && lo ? false : true;
-}
-
static bool valid_pedit_action(struct net_device *dev,
const struct flow_action_entry *act)
{
- u32 mask, offset;
+ u32 offset;
u8 htype;
htype = act->mangle.htype;
- mask = act->mangle.mask;
offset = act->mangle.offset;
switch (htype) {
case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
switch (offset) {
- case PEDIT_ETH_DMAC_31_0:
- case PEDIT_ETH_DMAC_47_32_SMAC_15_0:
- case PEDIT_ETH_SMAC_47_16:
+ case PEDIT_ETH_DMAC:
+ case PEDIT_ETH_SMAC:
break;
default:
netdev_err(dev, "%s: Unsupported pedit field\n",
@@ -491,14 +435,8 @@ static bool valid_pedit_action(struct net_device *dev,
break;
case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
switch (offset) {
- case PEDIT_IP6_SRC_31_0:
- case PEDIT_IP6_SRC_63_32:
- case PEDIT_IP6_SRC_95_64:
- case PEDIT_IP6_SRC_127_96:
- case PEDIT_IP6_DST_31_0:
- case PEDIT_IP6_DST_63_32:
- case PEDIT_IP6_DST_95_64:
- case PEDIT_IP6_DST_127_96:
+ case PEDIT_IP6_SRC:
+ case PEDIT_IP6_DST:
break;
default:
netdev_err(dev, "%s: Unsupported pedit field\n",
@@ -508,12 +446,8 @@ static bool valid_pedit_action(struct net_device *dev,
break;
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) {
- case PEDIT_TCP_SPORT_DPORT:
- if (!valid_l4_mask(mask)) {
- netdev_err(dev, "%s: Unsupported mask for TCP L4 ports\n",
- __func__);
- return false;
- }
+ case PEDIT_TCP_SPORT:
+ case PEDIT_TCP_DPORT:
break;
default:
netdev_err(dev, "%s: Unsupported pedit field\n",
@@ -523,12 +457,8 @@ static bool valid_pedit_action(struct net_device *dev,
break;
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) {
- case PEDIT_UDP_SPORT_DPORT:
- if (!valid_l4_mask(mask)) {
- netdev_err(dev, "%s: Unsupported mask for UDP L4 ports\n",
- __func__);
- return false;
- }
+ case PEDIT_UDP_SPORT:
+ case PEDIT_UDP_DPORT:
break;
default:
netdev_err(dev, "%s: Unsupported pedit field\n",
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
index eb4c95248baf..03892755a18f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
@@ -55,23 +55,14 @@ struct ch_tc_flower_entry {
};
enum {
- ETH_DMAC_31_0, /* dmac bits 0.. 31 */
- ETH_DMAC_47_32, /* dmac bits 32..47 */
- ETH_SMAC_15_0, /* smac bits 0.. 15 */
- ETH_SMAC_47_16, /* smac bits 16..47 */
+ ETH_DMAC, /* 48-bits dmac bits */
+ ETH_SMAC, /* 48-bits smac bits */
IP4_SRC, /* 32-bit IPv4 src */
IP4_DST, /* 32-bit IPv4 dst */
- IP6_SRC_31_0, /* src bits 0.. 31 */
- IP6_SRC_63_32, /* src bits 63.. 32 */
- IP6_SRC_95_64, /* src bits 95.. 64 */
- IP6_SRC_127_96, /* src bits 127..96 */
-
- IP6_DST_31_0, /* dst bits 0.. 31 */
- IP6_DST_63_32, /* dst bits 63.. 32 */
- IP6_DST_95_64, /* dst bits 95.. 64 */
- IP6_DST_127_96, /* dst bits 127..96 */
+ IP6_SRC, /* 128-bit IPv6 src */
+ IP6_DST, /* 128-bit IPv6 dst */
TCP_SPORT, /* 16-bit TCP sport */
TCP_DPORT, /* 16-bit TCP dport */
@@ -90,23 +81,16 @@ struct ch_tc_pedit_fields {
{ type## field, size, \
offsetof(struct ch_filter_specification, fs_field) + (offset) }
-#define PEDIT_ETH_DMAC_MASK 0xffff
-#define PEDIT_TCP_UDP_SPORT_MASK 0xffff
-#define PEDIT_ETH_DMAC_31_0 0x0
-#define PEDIT_ETH_DMAC_47_32_SMAC_15_0 0x4
-#define PEDIT_ETH_SMAC_47_16 0x8
+#define PEDIT_ETH_DMAC 0x0
+#define PEDIT_ETH_SMAC 0x6
+#define PEDIT_IP6_SRC 0x8
+#define PEDIT_IP6_DST 0x18
#define PEDIT_IP4_SRC 0xC
#define PEDIT_IP4_DST 0x10
-#define PEDIT_IP6_SRC_31_0 0x8
-#define PEDIT_IP6_SRC_63_32 0xC
-#define PEDIT_IP6_SRC_95_64 0x10
-#define PEDIT_IP6_SRC_127_96 0x14
-#define PEDIT_IP6_DST_31_0 0x18
-#define PEDIT_IP6_DST_63_32 0x1C
-#define PEDIT_IP6_DST_95_64 0x20
-#define PEDIT_IP6_DST_127_96 0x24
-#define PEDIT_TCP_SPORT_DPORT 0x0
-#define PEDIT_UDP_SPORT_DPORT 0x0
+#define PEDIT_TCP_SPORT 0x0
+#define PEDIT_TCP_DPORT 0x2
+#define PEDIT_UDP_SPORT 0x0
+#define PEDIT_UDP_DPORT 0x2
int cxgb4_tc_flower_replace(struct net_device *dev,
struct flow_cls_offload *cls);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index ec47e994b7e0..0b8e34fb8a0a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2202,19 +2202,24 @@ static int pedit_header_offsets[] = {
#define pedit_header(_ph, _htype) ((void *)(_ph) + pedit_header_offsets[_htype])
-static int set_pedit_val(u8 hdr_type, u32 mask, u32 val, u32 offset,
+static int set_pedit_val(u8 hdr_type, const struct flow_action_entry *act,
struct pedit_headers_action *hdrs)
{
- u32 *curr_pmask, *curr_pval;
+ u32 offset = act->mangle.offset;
+ u8 *curr_pmask, *curr_pval;
+ int i;
- curr_pmask = (u32 *)(pedit_header(&hdrs->masks, hdr_type) + offset);
- curr_pval = (u32 *)(pedit_header(&hdrs->vals, hdr_type) + offset);
+ curr_pmask = (u8 *)(pedit_header(&hdrs->masks, hdr_type) + offset);
+ curr_pval = (u8 *)(pedit_header(&hdrs->vals, hdr_type) + offset);
- if (*curr_pmask & mask) /* disallow acting twice on the same location */
- goto out_err;
+ for (i = 0; i < act->mangle.len; i++) {
+ /* disallow acting twice on the same location */
+ if (curr_pmask[i] & act->mangle.mask[i])
+ goto out_err;
- *curr_pmask |= mask;
- *curr_pval |= val;
+ curr_pmask[i] |= act->mangle.mask[i];
+ curr_pval[i] |= act->mangle.val[i];
+ }
return 0;
@@ -2488,7 +2493,6 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
{
u8 cmd = (act->id == FLOW_ACTION_MANGLE) ? 0 : 1;
int err = -EOPNOTSUPP;
- u32 mask, val, offset;
u8 htype;
htype = act->mangle.htype;
@@ -2505,11 +2509,7 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
goto out_err;
}
- mask = act->mangle.mask;
- val = act->mangle.val;
- offset = act->mangle.offset;
-
- err = set_pedit_val(htype, mask, val, offset, &hdrs[cmd]);
+ err = set_pedit_val(htype, act, &hdrs[cmd]);
if (err)
goto out_err;
@@ -2590,49 +2590,19 @@ static bool csum_offload_supported(struct mlx5e_priv *priv,
return true;
}
-struct ip_ttl_word {
- __u8 ttl;
- __u8 protocol;
- __sum16 check;
-};
-
-struct ipv6_hoplimit_word {
- __be16 payload_len;
- __u8 nexthdr;
- __u8 hop_limit;
-};
-
static bool is_action_keys_supported(const struct flow_action_entry *act)
{
- u32 mask, offset;
- u8 htype;
+ u32 offset = act->mangle.offset;
+ u8 htype = act->mangle.htype;
- htype = act->mangle.htype;
- offset = act->mangle.offset;
- mask = act->mangle.mask;
- /* For IPv4 & IPv6 header check 4 byte word,
- * to determine that modified fields
- * are NOT ttl & hop_limit only.
- */
if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP4) {
- struct ip_ttl_word *ttl_word =
- (struct ip_ttl_word *)&mask;
-
- if (offset != offsetof(struct iphdr, ttl) ||
- ttl_word->protocol ||
- ttl_word->check) {
+ if (offset != offsetof(struct iphdr, ttl))
return true;
- }
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) {
- struct ipv6_hoplimit_word *hoplimit_word =
- (struct ipv6_hoplimit_word *)&mask;
-
- if (offset != offsetof(struct ipv6hdr, payload_len) ||
- hoplimit_word->payload_len ||
- hoplimit_word->nexthdr) {
+ if (offset != offsetof(struct ipv6hdr, hop_limit))
return true;
- }
}
+
return false;
}
@@ -2727,19 +2697,21 @@ static int add_vlan_rewrite_action(struct mlx5e_priv *priv, int namespace,
struct pedit_headers_action *hdrs,
u32 *action, struct netlink_ext_ack *extack)
{
- u16 mask16 = VLAN_VID_MASK;
- u16 val16 = act->vlan.vid & VLAN_VID_MASK;
- const struct flow_action_entry pedit_act = {
+ __be16 mask16 = htons(VLAN_VID_MASK);
+ __be16 val16 = htons(act->vlan.vid & VLAN_VID_MASK);
+ struct flow_action_entry pedit_act = {
.id = FLOW_ACTION_MANGLE,
.mangle.htype = FLOW_ACT_MANGLE_HDR_TYPE_ETH,
.mangle.offset = offsetof(struct vlan_ethhdr, h_vlan_TCI),
- .mangle.mask = (u32)be16_to_cpu(*(__be16 *)&mask16),
- .mangle.val = (u32)be16_to_cpu(*(__be16 *)&val16),
+ .mangle.len = 2,
};
u8 match_prio_mask, match_prio_val;
void *headers_c, *headers_v;
int err;
+ memcpy(pedit_act.mangle.mask, &mask16, sizeof(__be16));
+ memcpy(pedit_act.mangle.val, &val16, sizeof(__be16));
+
headers_c = get_match_headers_criteria(*action, &parse_attr->spec);
headers_v = get_match_headers_value(*action, &parse_attr->spec);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index 592c36ba9e3f..a525ec244b79 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -472,38 +472,44 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun,
return 0;
}
-static void nfp_fl_set_helper32(u32 value, u32 mask, u8 *p_exact, u8 *p_mask)
+static void nfp_fl_set_helper(const u8 *value, const u8 *mask,
+ u8 *p_exact, u8 *p_mask, int len)
{
- u32 oldvalue = get_unaligned((u32 *)p_exact);
- u32 oldmask = get_unaligned((u32 *)p_mask);
+ int i;
- value |= oldvalue & ~mask;
-
- put_unaligned(oldmask | mask, (u32 *)p_mask);
- put_unaligned(value, (u32 *)p_exact);
+ for (i = 0; i < len; i++) {
+ p_exact[i] = (p_exact[i] & ~mask[i]) | value[i];
+ p_mask[i] |= mask[i];
+ }
}
static int
nfp_fl_set_eth(const struct flow_action_entry *act, u32 off,
struct nfp_fl_set_eth *set_eth, struct netlink_ext_ack *extack)
{
- u32 exact, mask;
+ int i;
- if (off + 4 > ETH_ALEN * 2) {
+ switch (off) {
+ case offsetof(struct ethhdr, h_dest):
+ i = 0;
+ break;
+ case offsetof(struct ethhdr, h_source):
+ i = ETH_ALEN;
+ break;
+ default:
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit ethernet action");
return -EOPNOTSUPP;
}
- mask = act->mangle.mask;
- exact = act->mangle.val;
-
- if (exact & ~mask) {
+ if (memchr_inv(&act->mangle.val, 0, act->mangle.len) &&
+ !memchr_inv(&act->mangle.mask, 0, act->mangle.len)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit ethernet action");
return -EOPNOTSUPP;
}
- nfp_fl_set_helper32(exact, mask, &set_eth->eth_addr_val[off],
- &set_eth->eth_addr_mask[off]);
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ &set_eth->eth_addr_val[i],
+ &set_eth->eth_addr_mask[i], act->mangle.len);
set_eth->reserved = cpu_to_be16(0);
set_eth->head.jump_id = NFP_FL_ACTION_OPCODE_SET_ETHERNET;
@@ -524,68 +530,46 @@ nfp_fl_set_ip4(const struct flow_action_entry *act, u32 off,
struct nfp_fl_set_ip4_ttl_tos *set_ip_ttl_tos,
struct netlink_ext_ack *extack)
{
- struct ipv4_ttl_word *ttl_word_mask;
- struct ipv4_ttl_word *ttl_word;
- struct iphdr *tos_word_mask;
- struct iphdr *tos_word;
- __be32 exact, mask;
-
- /* We are expecting tcf_pedit to return a big endian value */
- mask = (__force __be32)act->mangle.mask;
- exact = (__force __be32)act->mangle.val;
-
- if (exact & ~mask) {
+ if (memchr_inv(act->mangle.val, 0, act->mangle.len) &&
+ !memchr_inv(act->mangle.mask, 0, act->mangle.len)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv4 action");
return -EOPNOTSUPP;
}
switch (off) {
case offsetof(struct iphdr, daddr):
- set_ip_addr->ipv4_dst_mask |= mask;
- set_ip_addr->ipv4_dst &= ~mask;
- set_ip_addr->ipv4_dst |= exact;
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ (u8 *)&set_ip_addr->ipv4_dst,
+ (u8 *)&set_ip_addr->ipv4_dst_mask,
+ act->mangle.len);
set_ip_addr->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
set_ip_addr->head.len_lw = sizeof(*set_ip_addr) >>
NFP_FL_LW_SIZ;
break;
case offsetof(struct iphdr, saddr):
- set_ip_addr->ipv4_src_mask |= mask;
- set_ip_addr->ipv4_src &= ~mask;
- set_ip_addr->ipv4_src |= exact;
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ (u8 *)&set_ip_addr->ipv4_src,
+ (u8 *)&set_ip_addr->ipv4_src_mask,
+ act->mangle.len);
set_ip_addr->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
set_ip_addr->head.len_lw = sizeof(*set_ip_addr) >>
NFP_FL_LW_SIZ;
break;
case offsetof(struct iphdr, ttl):
- ttl_word_mask = (struct ipv4_ttl_word *)&mask;
- ttl_word = (struct ipv4_ttl_word *)&exact;
-
- if (ttl_word_mask->protocol || ttl_word_mask->check) {
- NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv4 ttl action");
- return -EOPNOTSUPP;
- }
-
- set_ip_ttl_tos->ipv4_ttl_mask |= ttl_word_mask->ttl;
- set_ip_ttl_tos->ipv4_ttl &= ~ttl_word_mask->ttl;
- set_ip_ttl_tos->ipv4_ttl |= ttl_word->ttl & ttl_word_mask->ttl;
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ (u8 *)&set_ip_ttl_tos->ipv4_ttl,
+ (u8 *)&set_ip_ttl_tos->ipv4_ttl_mask,
+ act->mangle.len);
set_ip_ttl_tos->head.jump_id =
NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
set_ip_ttl_tos->head.len_lw = sizeof(*set_ip_ttl_tos) >>
NFP_FL_LW_SIZ;
break;
- case round_down(offsetof(struct iphdr, tos), 4):
- tos_word_mask = (struct iphdr *)&mask;
- tos_word = (struct iphdr *)&exact;
-
- if (tos_word_mask->version || tos_word_mask->ihl ||
- tos_word_mask->tot_len) {
- NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv4 tos action");
- return -EOPNOTSUPP;
- }
-
- set_ip_ttl_tos->ipv4_tos_mask |= tos_word_mask->tos;
- set_ip_ttl_tos->ipv4_tos &= ~tos_word_mask->tos;
- set_ip_ttl_tos->ipv4_tos |= tos_word->tos & tos_word_mask->tos;
+ case offsetof(struct iphdr, tos):
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ (u8 *)&set_ip_ttl_tos->ipv4_tos,
+ (u8 *)&set_ip_ttl_tos->ipv4_tos_mask,
+ act->mangle.len);
set_ip_ttl_tos->head.jump_id =
NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
set_ip_ttl_tos->head.len_lw = sizeof(*set_ip_ttl_tos) >>
@@ -600,12 +584,17 @@ nfp_fl_set_ip4(const struct flow_action_entry *act, u32 off,
}
static void
-nfp_fl_set_ip6_helper(int opcode_tag, u8 word, __be32 exact, __be32 mask,
- struct nfp_fl_set_ipv6_addr *ip6)
+nfp_fl_set_ip6_helper(int opcode_tag, const struct flow_action_entry *act,
+ struct nfp_fl_set_ipv6_addr *ip6,
+ struct netlink_ext_ack *extack)
{
- ip6->ipv6[word].mask |= mask;
- ip6->ipv6[word].exact &= ~mask;
- ip6->ipv6[word].exact |= exact;
+ int i, j;
+
+ for (i = 0, j = 0; i < sizeof(struct in6_addr); i++, j += sizeof(u32)) {
+ nfp_fl_set_helper(&act->mangle.val[j], &act->mangle.mask[j],
+ (u8 *)&ip6->ipv6[i].exact,
+ (u8 *)&ip6->ipv6[i].mask, sizeof(u32));
+ }
ip6->reserved = cpu_to_be16(0);
ip6->head.jump_id = opcode_tag;
@@ -619,39 +608,34 @@ struct ipv6_hop_limit_word {
};
static int
-nfp_fl_set_ip6_hop_limit_flow_label(u32 off, __be32 exact, __be32 mask,
+nfp_fl_set_ip6_hop_limit_flow_label(u32 off,
+ const struct flow_action_entry *act,
struct nfp_fl_set_ipv6_tc_hl_fl *ip_hl_fl,
struct netlink_ext_ack *extack)
{
- struct ipv6_hop_limit_word *fl_hl_mask;
- struct ipv6_hop_limit_word *fl_hl;
-
switch (off) {
- case offsetof(struct ipv6hdr, payload_len):
- fl_hl_mask = (struct ipv6_hop_limit_word *)&mask;
- fl_hl = (struct ipv6_hop_limit_word *)&exact;
-
- if (fl_hl_mask->nexthdr || fl_hl_mask->payload_len) {
- NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv6 hop limit action");
- return -EOPNOTSUPP;
- }
-
- ip_hl_fl->ipv6_hop_limit_mask |= fl_hl_mask->hop_limit;
- ip_hl_fl->ipv6_hop_limit &= ~fl_hl_mask->hop_limit;
- ip_hl_fl->ipv6_hop_limit |= fl_hl->hop_limit &
- fl_hl_mask->hop_limit;
+ case offsetof(struct ipv6hdr, hop_limit):
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ &ip_hl_fl->ipv6_hop_limit,
+ &ip_hl_fl->ipv6_hop_limit_mask,
+ act->mangle.len);
break;
- case round_down(offsetof(struct ipv6hdr, flow_lbl), 4):
- if (mask & ~IPV6_FLOW_LABEL_MASK ||
- exact & ~IPV6_FLOW_LABEL_MASK) {
+ case 1: /* offsetof(struct ipv6hdr, flow_lbl) */
+ /* The initial 4-bits are part of the traffic class field. */
+ if (act->mangle.val[0] & 0xf0 ||
+ act->mangle.mask[0] & 0xf0) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv6 flow label action");
return -EOPNOTSUPP;
}
- ip_hl_fl->ipv6_label_mask |= mask;
- ip_hl_fl->ipv6_label &= ~mask;
- ip_hl_fl->ipv6_label |= exact;
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ (u8 *)&ip_hl_fl->ipv6_label,
+ (u8 *)&ip_hl_fl->ipv6_label_mask,
+ act->mangle.len);
break;
+ default:
+ NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv6 action");
+ return -EOPNOTSUPP;
}
ip_hl_fl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
@@ -667,31 +651,23 @@ nfp_fl_set_ip6(const struct flow_action_entry *act, u32 off,
struct nfp_fl_set_ipv6_tc_hl_fl *ip_hl_fl,
struct netlink_ext_ack *extack)
{
- __be32 exact, mask;
int err = 0;
- u8 word;
- /* We are expecting tcf_pedit to return a big endian value */
- mask = (__force __be32)act->mangle.mask;
- exact = (__force __be32)act->mangle.val;
-
- if (exact & ~mask) {
+ if (memchr_inv(act->mangle.val, 0, act->mangle.len) &&
+ !memchr_inv(act->mangle.mask, 0, act->mangle.len)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit IPv6 action");
return -EOPNOTSUPP;
}
if (off < offsetof(struct ipv6hdr, saddr)) {
- err = nfp_fl_set_ip6_hop_limit_flow_label(off, exact, mask,
- ip_hl_fl, extack);
- } else if (off < offsetof(struct ipv6hdr, daddr)) {
- word = (off - offsetof(struct ipv6hdr, saddr)) / sizeof(exact);
- nfp_fl_set_ip6_helper(NFP_FL_ACTION_OPCODE_SET_IPV6_SRC, word,
- exact, mask, ip_src);
- } else if (off < offsetof(struct ipv6hdr, daddr) +
- sizeof(struct in6_addr)) {
- word = (off - offsetof(struct ipv6hdr, daddr)) / sizeof(exact);
- nfp_fl_set_ip6_helper(NFP_FL_ACTION_OPCODE_SET_IPV6_DST, word,
- exact, mask, ip_dst);
+ err = nfp_fl_set_ip6_hop_limit_flow_label(off, act, ip_hl_fl,
+ extack);
+ } else if (off == offsetof(struct ipv6hdr, saddr)) {
+ nfp_fl_set_ip6_helper(NFP_FL_ACTION_OPCODE_SET_IPV6_SRC,
+ act, ip_src, extack);
+ } else if (off == offsetof(struct ipv6hdr, daddr)) {
+ nfp_fl_set_ip6_helper(NFP_FL_ACTION_OPCODE_SET_IPV6_DST,
+ act, ip_dst, extack);
} else {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: pedit on unsupported section of IPv6 header");
return -EOPNOTSUPP;
@@ -705,23 +681,30 @@ nfp_fl_set_tport(const struct flow_action_entry *act, u32 off,
struct nfp_fl_set_tport *set_tport, int opcode,
struct netlink_ext_ack *extack)
{
- u32 exact, mask;
+ int i;
- if (off) {
+ switch (off) {
+ case offsetof(struct tcphdr, source):
+ i = 0;
+ break;
+ case offsetof(struct tcphdr, dest):
+ i = sizeof(u16);
+ break;
+ default:
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: pedit on unsupported section of L4 header");
return -EOPNOTSUPP;
}
- mask = act->mangle.mask;
- exact = act->mangle.val;
-
- if (exact & ~mask) {
+ if (memchr_inv(act->mangle.val, 0, act->mangle.len) &&
+ !memchr_inv(act->mangle.mask, 0, act->mangle.len)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid pedit L4 action");
return -EOPNOTSUPP;
}
- nfp_fl_set_helper32(exact, mask, set_tport->tp_port_val,
- set_tport->tp_port_mask);
+ nfp_fl_set_helper(act->mangle.val, act->mangle.mask,
+ &set_tport->tp_port_val[i],
+ &set_tport->tp_port_mask[i],
+ act->mangle.len);
set_tport->reserved = cpu_to_be16(0);
set_tport->head.jump_id = opcode;
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index fc881875f856..a2853b37dded 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -154,6 +154,8 @@ enum flow_action_mangle_base {
FLOW_ACT_MANGLE_HDR_TYPE_UDP,
};
+#define FLOW_ACTION_MANGLE_MAXLEN 16
+
struct flow_action_entry {
enum flow_action_id id;
union {
@@ -167,8 +169,9 @@ struct flow_action_entry {
struct { /* FLOW_ACTION_PACKET_EDIT */
enum flow_action_mangle_base htype;
u32 offset;
- u32 mask;
- u32 val;
+ u8 mask[FLOW_ACTION_MANGLE_MAXLEN];
+ u8 val[FLOW_ACTION_MANGLE_MAXLEN];
+ u8 len;
} mangle;
const struct ip_tunnel_info *tunnel; /* FLOW_ACTION_TUNNEL_ENCAP */
u32 csum_flags; /* FLOW_ACTION_CSUM */
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index e30a151d8527..468db33292a9 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3289,11 +3289,128 @@ void tc_cleanup_flow_action(struct flow_action *flow_action)
}
EXPORT_SYMBOL(tc_cleanup_flow_action);
+static unsigned int flow_action_mangle_type(enum pedit_cmd cmd)
+{
+ switch (cmd) {
+ case TCA_PEDIT_KEY_EX_CMD_SET:
+ return FLOW_ACTION_MANGLE;
+ case TCA_PEDIT_KEY_EX_CMD_ADD:
+ return FLOW_ACTION_ADD;
+ default:
+ WARN_ON_ONCE(1);
+ }
+ return 0;
+}
+
+struct flow_action_mangle_ctx {
+ u8 cmd;
+ u8 offset;
+ u8 htype;
+ u8 idx;
+ u8 val[FLOW_ACTION_MANGLE_MAXLEN];
+ u8 mask[FLOW_ACTION_MANGLE_MAXLEN];
+ u32 first_word;
+ u32 last_word;
+};
+
+static void flow_action_mangle_entry(struct flow_action_entry *entry,
+ const struct flow_action_mangle_ctx *ctx)
+{
+ u32 delta;
+
+ entry->id = ctx->cmd;
+ entry->mangle.htype = ctx->htype;
+ entry->mangle.offset = ctx->offset;
+ entry->mangle.len = ctx->idx;
+
+ /* Adjust offset. */
+ delta = sizeof(u32) - (fls(ctx->first_word) / BITS_PER_BYTE);
+ entry->mangle.offset += delta;
+
+ /* Adjust length. */
+ entry->mangle.len -= ((ffs(ctx->last_word) / BITS_PER_BYTE) + delta);
+
+ /* Copy value and mask from offset using the adjusted length. */
+ memcpy(entry->mangle.val, &ctx->val[delta], entry->mangle.len);
+ memcpy(entry->mangle.mask, &ctx->mask[delta], entry->mangle.len);
+}
+
+static void flow_action_mangle_ctx_update(struct flow_action_mangle_ctx *ctx,
+ const struct tc_action *act, int k)
+{
+ u32 val, mask;
+
+ val = tcf_pedit_val(act, k);
+ mask = ~tcf_pedit_mask(act, k);
+
+ memcpy(&ctx->val[ctx->idx], &val, sizeof(u32));
+ memcpy(&ctx->mask[ctx->idx], &mask, sizeof(u32));
+ ctx->idx += sizeof(u32);
+}
+
+static void flow_action_mangle_ctx_init(struct flow_action_mangle_ctx *ctx,
+ const struct tc_action *act, int k)
+{
+ ctx->cmd = flow_action_mangle_type(tcf_pedit_cmd(act, k));
+ ctx->offset = tcf_pedit_offset(act, k);
+ ctx->htype = tcf_pedit_htype(act, k);
+ ctx->idx = 0;
+
+ ctx->first_word = ntohl(~tcf_pedit_mask(act, k));
+ ctx->last_word = ctx->first_word;
+
+ flow_action_mangle_ctx_update(ctx, act, k);
+}
+
+static int flow_action_mangle(struct flow_action *flow_action,
+ struct flow_action_entry *entry,
+ const struct tc_action *act, int j)
+{
+ struct flow_action_mangle_ctx ctx;
+ int k;
+
+ if (tcf_pedit_cmd(act, 0) > TCA_PEDIT_KEY_EX_CMD_ADD)
+ return -1;
+
+ flow_action_mangle_ctx_init(&ctx, act, 0);
+
+ /* Special case: one single 32-bits word. */
+ if (tcf_pedit_nkeys(act) == 1) {
+ flow_action_mangle_entry(entry, &ctx);
+ return j;
+ }
+
+ for (k = 1; k < tcf_pedit_nkeys(act); k++) {
+ if (tcf_pedit_cmd(act, k) > TCA_PEDIT_KEY_EX_CMD_ADD)
+ return -1;
+
+ /* Offset is contiguous and type is the same, coalesce. */
+ if (ctx.idx < FLOW_ACTION_MANGLE_MAXLEN &&
+ ctx.offset + ctx.idx == tcf_pedit_offset(act, k) &&
+ ctx.cmd == flow_action_mangle_type(tcf_pedit_cmd(act, k))) {
+ flow_action_mangle_ctx_update(&ctx, act, k);
+ continue;
+ }
+ ctx.last_word = ntohl(~tcf_pedit_mask(act, k - 1));
+
+ /* Cannot coalesce, set up this entry. */
+ flow_action_mangle_entry(entry, &ctx);
+
+ flow_action_mangle_ctx_init(&ctx, act, k);
+ entry = &flow_action->entries[++j];
+ }
+
+ ctx.last_word = ntohl(~tcf_pedit_mask(act, k - 1));
+ flow_action_mangle_entry(entry, &ctx);
+
+ return j;
+}
+
int tc_setup_flow_action(struct flow_action *flow_action,
const struct tcf_exts *exts, bool rtnl_held)
{
const struct tc_action *act;
- int i, j, k, err = 0;
+ int i, j, err = 0;
if (!exts)
return 0;
@@ -3366,25 +3483,9 @@ int tc_setup_flow_action(struct flow_action *flow_action,
} else if (is_tcf_tunnel_release(act)) {
entry->id = FLOW_ACTION_TUNNEL_DECAP;
} else if (is_tcf_pedit(act)) {
- for (k = 0; k < tcf_pedit_nkeys(act); k++) {
- switch (tcf_pedit_cmd(act, k)) {
- case TCA_PEDIT_KEY_EX_CMD_SET:
- entry->id = FLOW_ACTION_MANGLE;
- break;
- case TCA_PEDIT_KEY_EX_CMD_ADD:
- entry->id = FLOW_ACTION_ADD;
- break;
- default:
- err = -EOPNOTSUPP;
- goto err_out;
- }
- entry->mangle.htype = tcf_pedit_htype(act, k);
- entry->mangle.mask = ~tcf_pedit_mask(act, k);
- entry->mangle.val = tcf_pedit_val(act, k) &
- entry->mangle.mask;
- entry->mangle.offset = tcf_pedit_offset(act, k);
- entry = &flow_action->entries[++j];
- }
+ j = flow_action_mangle(flow_action, entry, act, j);
+ if (j < 0)
+ goto err_out;
} else if (is_tcf_csum(act)) {
entry->id = FLOW_ACTION_CSUM;
entry->csum_flags = tcf_csum_update_flags(act);
@@ -3439,9 +3540,9 @@ int tc_setup_flow_action(struct flow_action *flow_action,
goto err_out;
}
- if (!is_tcf_pedit(act))
- j++;
+ j++;
}
+ flow_action->num_entries = j;
err_out:
if (!rtnl_held)
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] kcm: use BPF_PROG_RUN
From: Yonghong Song @ 2019-09-06 0:07 UTC (permalink / raw)
To: Sami Tolvanen, David S. Miller, Tom Herbert
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20190905211528.97828-1-samitolvanen@google.com>
On 9/5/19 2:15 PM, Sami Tolvanen wrote:
> Instead of invoking struct bpf_prog::bpf_func directly, use the
> BPF_PROG_RUN macro.
>
> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Acked-by: Yonghong Song <yhs@fb.com>
> ---
> net/kcm/kcmsock.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
> index 5dbc0c48f8cb..f350c613bd7d 100644
> --- a/net/kcm/kcmsock.c
> +++ b/net/kcm/kcmsock.c
> @@ -379,7 +379,7 @@ static int kcm_parse_func_strparser(struct strparser *strp, struct sk_buff *skb)
> struct kcm_psock *psock = container_of(strp, struct kcm_psock, strp);
> struct bpf_prog *prog = psock->bpf_prog;
>
> - return (*prog->bpf_func)(skb, prog->insnsi);
> + return BPF_PROG_RUN(prog, skb);
> }
>
> static int kcm_read_sock_done(struct strparser *strp, int err)
>
^ permalink raw reply
* Re: [PATCH] Revert "net: get rid of an signed integer overflow in ip_idents_reserve()"
From: Shaokun Zhang @ 2019-09-06 1:25 UTC (permalink / raw)
To: Eric Dumazet, netdev, linux-kernel
Cc: Yang Guo, David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI,
Jiri Pirko
In-Reply-To: <afa992f6-eb5e-8104-9a03-f992b184a6b6@gmail.com>
Hi Eric,
On 2019/7/26 17:58, Eric Dumazet wrote:
>
>
> On 7/26/19 11:17 AM, Shaokun Zhang wrote:
>> From: Yang Guo <guoyang2@huawei.com>
>>
>> There is an significant performance regression with the following
>> commit-id <adb03115f459>
>> ("net: get rid of an signed integer overflow in ip_idents_reserve()").
>>
>>
>
> So, you jump around and took ownership of this issue, while some of us
> are already working on it ?
>
Any update about this issue?
Thanks,
Shaokun
> Have you first checked that current UBSAN versions will not complain anymore ?
>
> A revert adding back the original issue would be silly, performance of
> benchmarks is nice but secondary.
>
>
>
^ permalink raw reply
* Re: WARNING in hso_free_net_device
From: Hui Peng @ 2019-09-06 2:05 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Stephen Hemminger, syzbot+44d53c7255bb1aea22d2, alexios.zavras,
David S. Miller, Greg Kroah-Hartman, LKML, USB list,
Mathias Payer, netdev, rfontana, syzkaller-bugs, Thomas Gleixner,
Oliver Neukum
In-Reply-To: <CAAeHK+y3eQ7bXvo1tiAkwLCsFkbSU5B+6hsKbdEzkSXP2_Jyzg@mail.gmail.com>
On 9/5/2019 7:24 AM, Andrey Konovalov wrote:
> On Thu, Sep 5, 2019 at 4:20 AM Hui Peng <benquike@gmail.com> wrote:
>>
>> Can you guys have a look at the attached patch?
>
> Let's try it:
>
> #syz test: https://github.com/google/kasan.git eea39f24
>
> FYI: there are two more reports coming from this driver, which might
> (or might not) have the same root cause. One of them has a suggested
> fix by Oliver.
>
> https://syzkaller.appspot.com/bug?extid=67b2bd0e34f952d0321e
> https://syzkaller.appspot.com/bug?extid=93f2f45b19519b289613
>
I think they are different, though similar.
This one is resulted from unregistering a network device.
These 2 are resulted from unregistering a tty device.
>>
>> On 9/4/19 6:41 PM, Stephen Hemminger wrote:
>>> On Wed, 4 Sep 2019 16:27:50 -0400
>>> Hui Peng <benquike@gmail.com> wrote:
>>>
>>>> Hi, all:
>>>>
>>>> I looked at the bug a little.
>>>>
>>>> The issue is that in the error handling code, hso_free_net_device
>>>> unregisters
>>>>
>>>> the net_device (hso_net->net) by calling unregister_netdev. In the
>>>> error handling code path,
>>>>
>>>> hso_net->net has not been registered yet.
>>>>
>>>> I think there are two ways to solve the issue:
>>>>
>>>> 1. fix it in drivers/net/usb/hso.c to avoiding unregistering the
>>>> net_device when it is still not registered
>>>>
>>>> 2. fix it in unregister_netdev. We can add a field in net_device to
>>>> record whether it is registered, and make unregister_netdev return if
>>>> the net_device is not registered yet.
>>>>
>>>> What do you guys think ?
>>> #1
^ permalink raw reply
* RE: [PATCH REPOST 1/2] can: flexcan: fix deadlock when using self wakeup
From: Joakim Zhang @ 2019-09-06 2:11 UTC (permalink / raw)
To: Sean Nyekjaer, mkl@pengutronix.de, linux-can@vger.kernel.org
Cc: wg@grandegger.com, netdev@vger.kernel.org, dl-linux-imx,
Martin Hundebøll
In-Reply-To: <1655f342-7aaf-5e36-d141-d00eee84f3ec@geanix.com>
> -----Original Message-----
> From: Sean Nyekjaer <sean@geanix.com>
> Sent: 2019年9月5日 21:18
> To: Joakim Zhang <qiangqing.zhang@nxp.com>; mkl@pengutronix.de;
> linux-can@vger.kernel.org
> Cc: wg@grandegger.com; netdev@vger.kernel.org; dl-linux-imx
> <linux-imx@nxp.com>; Martin Hundebøll <martin@geanix.com>
> Subject: Re: [PATCH REPOST 1/2] can: flexcan: fix deadlock when using self
> wakeup
>
>
>
> On 05/09/2019 09.10, Joakim Zhang wrote:
> > Hi Sean,
> >
> > Could you update lastest flexcan driver using linux-can-next/flexcan and then
> merge below two patches from linux-can/testing?
> > d0b53616716e (HEAD -> testing, origin/testing) can: flexcan: add LPSR
> > mode support for i.MX7D 803eb6bad65b can: flexcan: fix deadlock when
> > using self wakeup
> >
> > Best Regards,
> > Joakim Zhang
>
> The testing branch have some UBI bugs, when suspending it crashes...
> So will have to leave this, until they are resolved :-)
I think you can find the base and cherry-pick all above flexcan related latest patches to your local stable tree.
I did this and test wakeup function on i.MX8QM/QXP before.
BTW, I think without CAN FD related patches, you still can test wakeup function on i.MX6/7 with this patch(may need fix merge conflicts)
This patch has been merged into our 4.19 kernel and passed the wakeup test for i.MX6/7/8. I went through the flexcan suspend/resume process again,
and not find logical issue. If you met wakeup failure, could you help to locate the problem more accurate. Failure log you provided last time, strange
and illogical.
Thanks a lot! 😊
Best Regards,
Joakim Zhang
> /Sean
^ permalink raw reply
* [PATCH net v2] isdn/capi: check message length in capi_write()
From: Eric Biggers @ 2019-09-06 2:36 UTC (permalink / raw)
To: netdev, David Miller; +Cc: Karsten Keil, syzkaller-bugs
In-Reply-To: <20190901.114406.528788701327829265.davem@davemloft.net>
From: Eric Biggers <ebiggers@google.com>
syzbot reported:
BUG: KMSAN: uninit-value in capi_write+0x791/0xa90 drivers/isdn/capi/capi.c:700
CPU: 0 PID: 10025 Comm: syz-executor379 Not tainted 4.20.0-rc7+ #2
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x173/0x1d0 lib/dump_stack.c:113
kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
__msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:313
capi_write+0x791/0xa90 drivers/isdn/capi/capi.c:700
do_loop_readv_writev fs/read_write.c:703 [inline]
do_iter_write+0x83e/0xd80 fs/read_write.c:961
vfs_writev fs/read_write.c:1004 [inline]
do_writev+0x397/0x840 fs/read_write.c:1039
__do_sys_writev fs/read_write.c:1112 [inline]
__se_sys_writev+0x9b/0xb0 fs/read_write.c:1109
__x64_sys_writev+0x4a/0x70 fs/read_write.c:1109
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
entry_SYSCALL_64_after_hwframe+0x63/0xe7
[...]
The problem is that capi_write() is reading past the end of the message.
Fix it by checking the message's length in the needed places.
Reported-and-tested-by: syzbot+0849c524d9c634f5ae66@syzkaller.appspotmail.com
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
Changed v1 => v2:
- Use CAPI_DATA_B3_REQ_LEN, and define and use a constant for
CAPI_DISCONNECT_B3_RESP_LEN.
drivers/isdn/capi/capi.c | 10 +++++++++-
include/uapi/linux/isdn/capicmd.h | 1 +
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 3c3ad42f22bf..c92b405b7646 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -688,6 +688,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
if (!cdev->ap.applid)
return -ENODEV;
+ if (count < CAPIMSG_BASELEN)
+ return -EINVAL;
+
skb = alloc_skb(count, GFP_USER);
if (!skb)
return -ENOMEM;
@@ -698,7 +701,8 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
}
mlen = CAPIMSG_LEN(skb->data);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
- if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
+ if (count < CAPI_DATA_B3_REQ_LEN ||
+ (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
kfree_skb(skb);
return -EINVAL;
}
@@ -711,6 +715,10 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
+ if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
+ kfree_skb(skb);
+ return -EINVAL;
+ }
mutex_lock(&cdev->lock);
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->lock);
diff --git a/include/uapi/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
index 4941628a4fb9..5ec88e7548a9 100644
--- a/include/uapi/linux/isdn/capicmd.h
+++ b/include/uapi/linux/isdn/capicmd.h
@@ -16,6 +16,7 @@
#define CAPI_MSG_BASELEN 8
#define CAPI_DATA_B3_REQ_LEN (CAPI_MSG_BASELEN+4+4+2+2+2)
#define CAPI_DATA_B3_RESP_LEN (CAPI_MSG_BASELEN+4+2)
+#define CAPI_DISCONNECT_B3_RESP_LEN (CAPI_MSG_BASELEN+4)
/*----- CAPI commands -----*/
#define CAPI_ALERT 0x01
--
2.23.0
^ permalink raw reply related
* Re: [PATCH] rtl8xxxu: add bluetooth co-existence support for single antenna
From: Chris Chiu @ 2019-09-06 2:44 UTC (permalink / raw)
To: Jes Sorensen, Kalle Valo, David Miller
Cc: linux-wireless, netdev, Linux Kernel, Linux Upstreaming Team
In-Reply-To: <20190903053735.85957-1-chiu@endlessm.com>
On Tue, Sep 3, 2019 at 1:37 PM Chris Chiu <chiu@endlessm.com> wrote:
>
> The RTL8723BU suffers the wifi disconnection problem while bluetooth
> device connected. While wifi is doing tx/rx, the bluetooth will scan
> without results. This is due to the wifi and bluetooth share the same
> single antenna for RF communication and they need to have a mechanism
> to collaborate.
>
> BT information is provided via the packet sent from co-processor to
> host (C2H). It contains the status of BT but the rtl8723bu_handle_c2h
> dose not really handle it. And there's no bluetooth coexistence
> mechanism to deal with it.
>
> This commit adds a workqueue to set the tdma configurations and
> coefficient table per the parsed bluetooth link status and given
> wifi connection state. The tdma/coef table comes from the vendor
> driver code of the RTL8192EU and RTL8723BU. However, this commit is
> only for single antenna scenario which RTL8192EU is default dual
> antenna. The rtl8xxxu_parse_rxdesc24 which invokes the handle_c2h
> is only for 8723b and 8192e so the mechanism is expected to work
> on both chips with single antenna. Note RTL8192EU dual antenna is
> not supported.
>
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> ---
> .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 37 +++
> .../realtek/rtl8xxxu/rtl8xxxu_8723b.c | 2 -
> .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 243 +++++++++++++++++-
> 3 files changed, 275 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index 582c2a346cec..22e95b11bfbb 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> @@ -1220,6 +1220,37 @@ enum ratr_table_mode_new {
> RATEID_IDX_BGN_3SS = 14,
> };
>
> +#define BT_INFO_8723B_1ANT_B_FTP BIT(7)
> +#define BT_INFO_8723B_1ANT_B_A2DP BIT(6)
> +#define BT_INFO_8723B_1ANT_B_HID BIT(5)
> +#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT(4)
> +#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT(3)
> +#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT(2)
> +#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT(1)
> +#define BT_INFO_8723B_1ANT_B_CONNECTION BIT(0)
> +
> +enum _BT_8723B_1ANT_STATUS {
> + BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE = 0x0,
> + BT_8723B_1ANT_STATUS_CONNECTED_IDLE = 0x1,
> + BT_8723B_1ANT_STATUS_INQ_PAGE = 0x2,
> + BT_8723B_1ANT_STATUS_ACL_BUSY = 0x3,
> + BT_8723B_1ANT_STATUS_SCO_BUSY = 0x4,
> + BT_8723B_1ANT_STATUS_ACL_SCO_BUSY = 0x5,
> + BT_8723B_1ANT_STATUS_MAX
> +};
> +
> +struct rtl8xxxu_btcoex {
> + u8 bt_status;
> + bool bt_busy;
> + bool has_sco;
> + bool has_a2dp;
> + bool has_hid;
> + bool has_pan;
> + bool hid_only;
> + bool a2dp_only;
> + bool c2h_bt_inquiry;
> +};
> +
> #define RTL8XXXU_RATR_STA_INIT 0
> #define RTL8XXXU_RATR_STA_HIGH 1
> #define RTL8XXXU_RATR_STA_MID 2
> @@ -1340,6 +1371,10 @@ struct rtl8xxxu_priv {
> */
> struct ieee80211_vif *vif;
> struct delayed_work ra_watchdog;
> + struct work_struct c2hcmd_work;
> + struct sk_buff_head c2hcmd_queue;
> + spinlock_t c2hcmd_lock;
> + struct rtl8xxxu_btcoex bt_coex;
> };
>
> struct rtl8xxxu_rx_urb {
> @@ -1486,6 +1521,8 @@ void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
> struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
> bool short_preamble, bool ampdu_enable,
> u32 rts_rate);
> +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
> + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5);
>
> extern struct rtl8xxxu_fileops rtl8192cu_fops;
> extern struct rtl8xxxu_fileops rtl8192eu_fops;
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> index ceffe05bd65b..9ba661b3d767 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> @@ -1580,9 +1580,7 @@ static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv)
> /*
> * Software control, antenna at WiFi side
> */
> -#ifdef NEED_PS_TDMA
> rtl8723bu_set_ps_tdma(priv, 0x08, 0x00, 0x00, 0x00, 0x00);
> -#endif
>
> rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555);
> rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555);
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index a6f358b9e447..4f72c2d14d44 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -3820,9 +3820,8 @@ void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv)
> rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
> }
>
> -#ifdef NEED_PS_TDMA
> -static void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
> - u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5)
> +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
> + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5)
> {
> struct h2c_cmd h2c;
>
> @@ -3835,7 +3834,6 @@ static void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
> h2c.b_type_dma.data5 = arg5;
> rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_type_dma));
> }
> -#endif
>
> void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv)
> {
> @@ -5186,12 +5184,239 @@ static void rtl8xxxu_rx_urb_work(struct work_struct *work)
> }
> }
>
> +void rtl8723bu_set_coex_with_type(struct rtl8xxxu_priv *priv, u8 type)
> +{
> + switch (type) {
> + case 0:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 1:
> + case 3:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 2:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 4:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaa5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 5:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaa5a5a5a);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 6:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + case 7:
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0xaaaaaaaa);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa);
> + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff);
> + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +void rtl8723bu_update_bt_link_info(struct rtl8xxxu_priv *priv, u8 bt_info)
> +{
> + struct rtl8xxxu_btcoex *btcoex = &priv->bt_coex;
> +
> + if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE)
> + btcoex->c2h_bt_inquiry = true;
> + else
> + btcoex->c2h_bt_inquiry = false;
> +
> + if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) {
> + btcoex->bt_status = BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE;
> + btcoex->has_sco = false;
> + btcoex->has_hid = false;
> + btcoex->has_pan = false;
> + btcoex->has_a2dp = false;
> + } else {
> + if ((bt_info & 0x1f) == BT_INFO_8723B_1ANT_B_CONNECTION)
> + btcoex->bt_status = BT_8723B_1ANT_STATUS_CONNECTED_IDLE;
> + else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) ||
> + (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY))
> + btcoex->bt_status = BT_8723B_1ANT_STATUS_SCO_BUSY;
> + else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY)
> + btcoex->bt_status = BT_8723B_1ANT_STATUS_ACL_BUSY;
> + else
> + btcoex->bt_status = BT_8723B_1ANT_STATUS_MAX;
> +
> + if (bt_info & BT_INFO_8723B_1ANT_B_FTP)
> + btcoex->has_pan = true;
> + else
> + btcoex->has_pan = false;
> +
> + if (bt_info & BT_INFO_8723B_1ANT_B_A2DP)
> + btcoex->has_a2dp = true;
> + else
> + btcoex->has_a2dp = false;
> +
> + if (bt_info & BT_INFO_8723B_1ANT_B_HID)
> + btcoex->has_hid = true;
> + else
> + btcoex->has_hid = false;
> +
> + if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO)
> + btcoex->has_sco = true;
> + else
> + btcoex->has_sco = false;
> + }
> +
> + if (!btcoex->has_a2dp &&
> + !btcoex->has_sco &&
> + !btcoex->has_pan &&
> + btcoex->has_hid)
> + btcoex->hid_only = true;
> + else
> + btcoex->hid_only = false;
> +
> + if (!btcoex->has_sco &&
> + !btcoex->has_pan &&
> + !btcoex->has_hid &&
> + btcoex->has_a2dp)
> + btcoex->has_a2dp = true;
> + else
> + btcoex->has_a2dp = false;
> +
> + if (btcoex->bt_status == BT_8723B_1ANT_STATUS_SCO_BUSY ||
> + btcoex->bt_status == BT_8723B_1ANT_STATUS_ACL_BUSY)
> + btcoex->bt_busy = true;
> + else
> + btcoex->bt_busy = false;
> +}
> +
> +static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
> +{
> + struct rtl8xxxu_priv *priv;
> + struct rtl8723bu_c2h *c2h;
> + struct ieee80211_vif *vif;
> + struct device *dev;
> + struct sk_buff *skb = NULL;
> + unsigned long flags;
> + int len;
> + u8 bt_info = 0;
> + struct rtl8xxxu_btcoex *btcoex;
> +
> + priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work);
> + vif = priv->vif;
> + btcoex = &priv->bt_coex;
> + dev = &priv->udev->dev;
> +
> + if (priv->rf_paths > 1)
> + goto out;
> +
> + while (!skb_queue_empty(&priv->c2hcmd_queue)) {
> + spin_lock_irqsave(&priv->c2hcmd_lock, flags);
> + skb = __skb_dequeue(&priv->c2hcmd_queue);
> + spin_unlock_irqrestore(&priv->c2hcmd_lock, flags);
> +
> + c2h = (struct rtl8723bu_c2h *)skb->data;
> + len = skb->len - 2;
> +
> + switch (c2h->id) {
> + case C2H_8723B_BT_INFO:
> + bt_info = c2h->bt_info.bt_info;
> +
> + rtl8723bu_update_bt_link_info(priv, bt_info);
> +
> + if (btcoex->c2h_bt_inquiry) {
> + if (vif && !vif->bss_conf.assoc) {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + rtl8723bu_set_coex_with_type(priv, 0);
> + } else if (btcoex->has_sco ||
> + btcoex->has_hid ||
> + btcoex->has_a2dp) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if (btcoex->has_pan) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x3f, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + rtl8723bu_set_coex_with_type(priv, 7);
> + }
> +
> + return;
> + }
> +
> + if (vif && vif->bss_conf.assoc) {
> + u32 val32 = 0;
> + u32 high_prio_tx = 0, high_prio_rx = 0;
> +
> + val32 = rtl8xxxu_read32(priv, 0x770);
> + high_prio_tx = val32 & 0x0000ffff;
> + high_prio_rx = (val32 & 0xffff0000) >> 16;
> +
> + if (btcoex->bt_busy) {
> + if (btcoex->hid_only) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x20, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 5);
> + } else if (btcoex->a2dp_only) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if ((btcoex->has_a2dp &&
> + btcoex->has_pan) ||
> + (btcoex->has_hid &&
> + btcoex->has_a2dp &&
> + btcoex->has_pan)) {
> + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, 0x3, 0x10, 0x10);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if (btcoex->has_hid &&
> + btcoex->has_a2dp) {
> + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, 0x3, 0x10, 0x10);
> + rtl8723bu_set_coex_with_type(priv, 3);
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + }
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + if (high_prio_tx + high_prio_rx <= 60)
> + rtl8723bu_set_coex_with_type(priv, 2);
> + else
> + rtl8723bu_set_coex_with_type(priv, 7);
> + }
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + rtl8723bu_set_coex_with_type(priv, 0);
> + }
> + break;
> + default:
> + break;
> + }
> + }
> +
> +out:
> + dev_kfree_skb(skb);
> +}
> +
> static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
> struct sk_buff *skb)
> {
> struct rtl8723bu_c2h *c2h = (struct rtl8723bu_c2h *)skb->data;
> struct device *dev = &priv->udev->dev;
> int len;
> + unsigned long flags;
>
> len = skb->len - 2;
>
> @@ -5229,6 +5454,12 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
> 16, 1, c2h->raw.payload, len, false);
> break;
> }
> +
> + spin_lock_irqsave(&priv->c2hcmd_lock, flags);
> + __skb_queue_tail(&priv->c2hcmd_queue, skb);
> + spin_unlock_irqrestore(&priv->c2hcmd_lock, flags);
> +
> + schedule_work(&priv->c2hcmd_work);
> }
>
> int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
> @@ -5353,7 +5584,6 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
> struct device *dev = &priv->udev->dev;
> dev_dbg(dev, "%s: C2H packet\n", __func__);
> rtl8723bu_handle_c2h(priv, skb);
> - dev_kfree_skb(skb);
> return RX_TYPE_C2H;
> }
>
> @@ -6272,6 +6502,9 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
> spin_lock_init(&priv->rx_urb_lock);
> INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
> INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
> + spin_lock_init(&priv->c2hcmd_lock);
> + INIT_WORK(&priv->c2hcmd_work, rtl8xxxu_c2hcmd_callback);
> + skb_queue_head_init(&priv->c2hcmd_queue);
>
> usb_set_intfdata(interface, hw);
>
> --
> 2.20.1
>
Gentle ping. Cheers.
Chris
^ permalink raw reply
* Re: [PATCH] net/skbuff: silence warnings under memory pressure
From: Sergey Senozhatsky @ 2019-09-06 2:50 UTC (permalink / raw)
To: Steven Rostedt
Cc: Qian Cai, Sergey Senozhatsky, Petr Mladek, Sergey Senozhatsky,
Michal Hocko, Eric Dumazet, davem, netdev, linux-mm, linux-kernel
In-Reply-To: <20190905131413.0aa4e4f1@oasis.local.home>
On (09/05/19 13:14), Steven Rostedt wrote:
> > Hmm, from the article,
> >
> > https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter
> >
> > "Since transmission of a single or multiple characters may take a long time
> > relative to CPU speeds, a UART maintains a flag showing busy status so that the
> > host system knows if there is at least one character in the transmit buffer or
> > shift register; "ready for next character(s)" may also be signaled with an
> > interrupt."
>
> I'm pretty sure all serial consoles do a busy loop on the UART and not
> use interrupts to notify when it's available.
Yes. Besides, we call console drivers with local IRQs disabled.
-ss
^ permalink raw reply
* Re: linux-next: build failure after merge of the net-next tree
From: Masahiro Yamada @ 2019-09-06 2:52 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Stephen Rothwell, David Miller, Networking,
Linux Next Mailing List, Linux Kernel Mailing List,
Andrii Nakryiko, Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <CAEf4BzZLBV3o=t9+a4o4T7KZ_M04vddD0RMVs3s4JvDsvQ8onA@mail.gmail.com>
On Fri, Sep 6, 2019 at 4:26 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Tue, Sep 3, 2019 at 11:20 PM Masahiro Yamada
> <yamada.masahiro@socionext.com> wrote:
> >
> > On Wed, Sep 4, 2019 at 3:00 PM Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> > >
> > > Hi all,
> > >
> > > After merging the net-next tree, today's linux-next build (arm
> > > multi_v7_defconfig) failed like this:
> > >
> > > scripts/link-vmlinux.sh: 74: Bad substitution
> > >
> > > Caused by commit
> > >
> > > 341dfcf8d78e ("btf: expose BTF info through sysfs")
> > >
> > > interacting with commit
> > >
> > > 1267f9d3047d ("kbuild: add $(BASH) to run scripts with bash-extension")
> > >
> > > from the kbuild tree.
> >
> >
> > I knew that they were using bash-extension
> > in the #!/bin/sh script. :-D
> >
> > In fact, I wrote my patch in order to break their code
> > and make btf people realize that they were doing wrong.
>
> Was there a specific reason to wait until this would break during
> Stephen's merge, instead of giving me a heads up (or just replying on
> original patch) and letting me fix it and save everyone's time and
> efforts?
>
> Either way, I've fixed the issue in
> https://patchwork.ozlabs.org/patch/1158620/ and will pay way more
> attention to BASH-specific features going forward (I found it pretty
> hard to verify stuff like this, unfortunately). But again, code review
> process is the best place to catch this and I really hope in the
> future we can keep this process productive. Thanks!
I could have pointed it out if I had noticed
it in the review process.
I actually noticed your patch by Stephen's
former email. (i.e. when it appeared in linux-next)
(I try my best to check kbuild ML, and also search for
my name in LKML in case I am explicitly addressed,
but a large number of emails fall off my filter)
It was somewhat too late when I noticed it.
Of course, I still could email you afterward, or even send a patch to btf ML,
but I did not fix a particular instance of breakage
because there are already the same type of breakages in code base.
Then, I applied the all-or-nothing checker because I thought it was
the only way to address the root cause of the problems.
I admit I could have done the process better.
Sorry if I made people uncomfortable and waste time.
Thanks.
> >
> >
> >
> > > The change in the net-next tree turned link-vmlinux.sh into a bash script
> > > (I think).
> > >
> > > I have applied the following patch for today:
> >
> >
> > But, this is a temporary fix only for linux-next.
> >
> > scripts/link-vmlinux.sh does not need to use the
> > bash-extension ${@:2} in the first place.
> >
> > I hope btf people will write the correct code.
>
> I replaced ${@:2} with shift and ${@}, I hope that's a correct fix,
> but if you think it's not, please reply on the patch and let me know.
>
>
> >
> > Thanks.
> >
> >
> >
> >
> > > From: Stephen Rothwell <sfr@canb.auug.org.au>
> > > Date: Wed, 4 Sep 2019 15:43:41 +1000
> > > Subject: [PATCH] link-vmlinux.sh is now a bash script
> > >
> > > Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
> > > ---
> > > Makefile | 4 ++--
> > > scripts/link-vmlinux.sh | 2 +-
> > > 2 files changed, 3 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/Makefile b/Makefile
> > > index ac97fb282d99..523d12c5cebe 100644
> > > --- a/Makefile
> > > +++ b/Makefile
> > > @@ -1087,7 +1087,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
> > >
> > > # Final link of vmlinux with optional arch pass after final link
> > > cmd_link-vmlinux = \
> > > - $(CONFIG_SHELL) $< $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) ; \
> > > + $(BASH) $< $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) ; \
> > > $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
> > >
> > > vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
> > > @@ -1403,7 +1403,7 @@ clean: rm-files := $(CLEAN_FILES)
> > > PHONY += archclean vmlinuxclean
> > >
> > > vmlinuxclean:
> > > - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
> > > + $(Q)$(BASH) $(srctree)/scripts/link-vmlinux.sh clean
> > > $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
> > >
> > > clean: archclean vmlinuxclean
> > > diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> > > index f7edb75f9806..ea1f8673869d 100755
> > > --- a/scripts/link-vmlinux.sh
> > > +++ b/scripts/link-vmlinux.sh
> > > @@ -1,4 +1,4 @@
> > > -#!/bin/sh
> > > +#!/bin/bash
> > > # SPDX-License-Identifier: GPL-2.0
> > > #
> > > # link vmlinux
> > > --
> > > 2.23.0.rc1
> > >
> > > --
> > > Cheers,
> > > Stephen Rothwell
> >
> >
> >
> > --
> > Best Regards
> > Masahiro Yamada
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* [PATCH] net: Remove the source address setting in connect() for UDP
From: Enke Chen @ 2019-09-06 2:54 UTC (permalink / raw)
To: David S . Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI, netdev
Cc: enkechen, linux-kernel, xe-linux-external
The connect() system call for a UDP socket is for setting the destination
address and port. But the current code mistakenly sets the source address
for the socket as well. Remove the source address setting in connect() for
UDP in this patch.
Implications of the bug:
- Packet drop:
On a multi-homed device, an address assigned to any interface may
qualify as a source address when originating a packet. If needed, the
IP_PKTINFO option can be used to explicitly specify the source address.
But with the source address being mistakenly set for the socket in
connect(), a return packet (for the socket) destined to an interface
address different from that source address would be wrongly dropped
due to address mismatch.
This can be reproduced easily. The dropped packets are shown in the
following output by "netstat -s" for UDP:
xxx packets to unknown port received
- Source address selection:
The source address, if unspecified via "bind()" or IP_PKTINFO, should
be determined by routing at the time of packet origination, and not at
the time when the connect() call is made. The difference matters as
routing can change, e.g., by interface down/up events, and using a
source address of an "down" interface is known to be problematic.
There is no backward compatibility issue here as the source address setting
in connect() is not needed anyway.
- No impact on the source address selection when the source address
is explicitly specified by "bind()", or by the "IP_PKTINFO" option.
- In the case that the source address is not explicitly specified,
the selection of the source address would be more accurate and
reliable based on the up-to-date routing table.
Signed-off-by: Enke Chen <enkechen@cisco.com>
---
net/ipv4/datagram.c | 7 -------
net/ipv6/datagram.c | 15 +--------------
2 files changed, 1 insertion(+), 21 deletions(-)
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index f915abff1350..4065808ec6c1 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -64,13 +64,6 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
err = -EACCES;
goto out;
}
- if (!inet->inet_saddr)
- inet->inet_saddr = fl4->saddr; /* Update source address */
- if (!inet->inet_rcv_saddr) {
- inet->inet_rcv_saddr = fl4->saddr;
- if (sk->sk_prot->rehash)
- sk->sk_prot->rehash(sk);
- }
inet->inet_daddr = fl4->daddr;
inet->inet_dport = usin->sin_port;
sk->sk_state = TCP_ESTABLISHED;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ecf440a4f593..80388cd50dc3 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -197,19 +197,6 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
goto out;
ipv6_addr_set_v4mapped(inet->inet_daddr, &sk->sk_v6_daddr);
-
- if (ipv6_addr_any(&np->saddr) ||
- ipv6_mapped_addr_any(&np->saddr))
- ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
-
- if (ipv6_addr_any(&sk->sk_v6_rcv_saddr) ||
- ipv6_mapped_addr_any(&sk->sk_v6_rcv_saddr)) {
- ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
- &sk->sk_v6_rcv_saddr);
- if (sk->sk_prot->rehash)
- sk->sk_prot->rehash(sk);
- }
-
goto out;
}
@@ -247,7 +234,7 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
* destination cache for it.
*/
- err = ip6_datagram_dst_update(sk, true);
+ err = ip6_datagram_dst_update(sk, false);
if (err) {
/* Restore the socket peer info, to keep it consistent with
* the old socket state
--
2.19.1
^ permalink raw reply related
* Re: [PATCH v2] net-ipv6: fix excessive RTF_ADDRCONF flag on ::1/128 local route (and others)
From: Maciej Żenczykowski @ 2019-09-06 3:31 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S . Miller, Linux NetDev, David Ahern, Lorenzo Colitti
In-Reply-To: <98b8a95f-245a-0bdf-6a4c-c07a372d4d0f@gmail.com>
> Shouldn't it use
>
> if (!IS_ERR(f6i))
> f6i->dst_nocount = true;
>
> ???
Yes, certainly. I'll send a fix.
^ permalink raw reply
* Re: [PATCH] net/skbuff: silence warnings under memory pressure
From: Sergey Senozhatsky @ 2019-09-06 3:39 UTC (permalink / raw)
To: Steven Rostedt
Cc: Sergey Senozhatsky, Qian Cai, Petr Mladek, Sergey Senozhatsky,
Michal Hocko, Eric Dumazet, davem, netdev, linux-mm, linux-kernel
In-Reply-To: <20190905132334.52b13d95@oasis.local.home>
On (09/05/19 13:23), Steven Rostedt wrote:
> > I think we can queue significantly much less irq_work-s from printk().
> >
> > Petr, Steven, what do you think?
[..]
> I mean, really, do we need to keep calling wake up if it
> probably never even executed?
I guess ratelimiting you are talking about ("if it probably never even
executed") would be to check if we have already called wake up on the
log_wait ->head. For that we need to, at least, take log_wait spin_lock
and check that ->head is still in TASK_INTERRUPTIBLE; which is (quite,
but not exactly) close to what wake_up_interruptible() does - it doesn't
wake up the same task twice, it bails out on `p->state & state' check.
Or did I miss something?
-ss
^ permalink raw reply
* RE: [PATCH bpf-next] kbuild: replace BASH-specific ${@:2} with shift and ${@}
From: yamada.masahiro @ 2019-09-06 3:53 UTC (permalink / raw)
To: andriin, bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, sfr
In-Reply-To: <20190905175938.599455-1-andriin@fb.com>
> -----Original Message-----
> From: Andrii Nakryiko <andriin@fb.com>
> Sent: Friday, September 06, 2019 3:00 AM
> To: bpf@vger.kernel.org; netdev@vger.kernel.org; ast@fb.com;
> daniel@iogearbox.net
> Cc: andrii.nakryiko@gmail.com; kernel-team@fb.com; Andrii Nakryiko
> <andriin@fb.com>; Stephen Rothwell <sfr@canb.auug.org.au>; Yamada,
> Masahiro/山田 真弘 <yamada.masahiro@socionext.com>
> Subject: [PATCH bpf-next] kbuild: replace BASH-specific ${@:2} with shift
> and ${@}
>
> ${@:2} is BASH-specific extension, which makes link-vmlinux.sh rely on
> BASH. Use shift and ${@} instead to fix this issue.
>
> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs")
> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
^ permalink raw reply
* [PATCH] net-ipv6: addrconf_f6i_alloc - fix non-null pointer check to !IS_ERR()
From: Maciej Żenczykowski @ 2019-09-06 3:56 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, David Ahern, Lorenzo Colitti, Eric Dumazet
In-Reply-To: <CANP3RGcbEP2N-CDQ6N649k0-cV4AhQeWqF-niz7EMPFOFpkU1w@mail.gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Fixes a stupid bug I recently introduced...
ip6_route_info_create() returns an ERR_PTR(err) and not a NULL on error.
Fixes: d55a2e374a94 ("net-ipv6: fix excessive RTF_ADDRCONF flag on ::1/128 local route (and others)'")
Cc: David Ahern <dsahern@gmail.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/route.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 003562dd3395..2fb2b913214c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4383,7 +4383,7 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
}
f6i = ip6_route_info_create(&cfg, gfp_flags, NULL);
- if (f6i)
+ if (!IS_ERR(f6i))
f6i->dst_nocount = true;
return f6i;
}
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* Re: [PATCH] net/skbuff: silence warnings under memory pressure
From: Sergey Senozhatsky @ 2019-09-06 4:32 UTC (permalink / raw)
To: Qian Cai
Cc: Sergey Senozhatsky, Steven Rostedt, Petr Mladek,
Sergey Senozhatsky, Michal Hocko, Eric Dumazet, davem, netdev,
linux-mm, linux-kernel
In-Reply-To: <1567699393.5576.96.camel@lca.pw>
On (09/05/19 12:03), Qian Cai wrote:
> > ---
> > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> > index cd51aa7d08a9..89cb47882254 100644
> > --- a/kernel/printk/printk.c
> > +++ b/kernel/printk/printk.c
> > @@ -2027,8 +2027,11 @@ asmlinkage int vprintk_emit(int facility, int level,
> > pending_output = (curr_log_seq != log_next_seq);
> > logbuf_unlock_irqrestore(flags);
> >
> > + if (!pending_output)
> > + return printed_len;
> > +
> > /* If called from the scheduler, we can not call up(). */
> > - if (!in_sched && pending_output) {
> > + if (!in_sched) {
> > /*
> > * Disable preemption to avoid being preempted while holding
> > * console_sem which would prevent anyone from printing to
> > @@ -2043,10 +2046,11 @@ asmlinkage int vprintk_emit(int facility, int level,
> > if (console_trylock_spinning())
> > console_unlock();
> > preempt_enable();
> > - }
> >
> > - if (pending_output)
> > + wake_up_interruptible(&log_wait);
> > + } else {
> > wake_up_klogd();
> > + }
> > return printed_len;
> > }
> > EXPORT_SYMBOL(vprintk_emit);
> > ---
Qian Cai, any chance you can test that patch?
-ss
^ permalink raw reply
* Need more information on "ifi_change" in "struct ifinfomsg"
From: dhan lin @ 2019-09-06 5:08 UTC (permalink / raw)
To: netdev
In-Reply-To: <CAMvS6vYbphKKM4evbV6Vre7vaR8r+oJgZ8TuQU6VtBSjVqH7dA@mail.gmail.com>
Hi All,
There is a field called ifi_change in "struct ifinfomsg". man page for
rtnetlink says its for future use and should be always set to
0xFFFFFFFF.
But ive run some sample tests, to confirm the value is not as per man
pages explanation.
Its 0 most of the times and non-zero sometimes.
I've the following question,
Is ifi_change set only when there is a state change in interface values?
>>My application is not interested in processing the netlink messages without any state changes.
>>Can i add a BPF socket filter to drop all Netlink messages with ifi_change=0?
with regards,
dhanlin
^ permalink raw reply
* Re: [PATCH] net-ipv6: addrconf_f6i_alloc - fix non-null pointer check to !IS_ERR()
From: Eric Dumazet @ 2019-09-06 5:10 UTC (permalink / raw)
To: Maciej Żenczykowski
Cc: Maciej Żenczykowski, David S . Miller, netdev, David Ahern,
Lorenzo Colitti
In-Reply-To: <20190906035637.47097-1-zenczykowski@gmail.com>
On Fri, Sep 6, 2019 at 5:56 AM Maciej Żenczykowski
<zenczykowski@gmail.com> wrote:
>
> From: Maciej Żenczykowski <maze@google.com>
>
> Fixes a stupid bug I recently introduced...
> ip6_route_info_create() returns an ERR_PTR(err) and not a NULL on error.
>
> Fixes: d55a2e374a94 ("net-ipv6: fix excessive RTF_ADDRCONF flag on ::1/128 local route (and others)'")
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Lorenzo Colitti <lorenzo@google.com>
> Cc: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Maciej Żenczykowski <maze@google.com>
> ---
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Thanks.
^ permalink raw reply
* Re: [PATCH v2 2/2] PTP: add support for one-shot output
From: Richard Cochran @ 2019-09-06 5:35 UTC (permalink / raw)
To: Felipe Balbi; +Cc: Christopher S Hall, netdev, linux-kernel, davem
In-Reply-To: <87h85roy9p.fsf@gmail.com>
On Thu, Sep 05, 2019 at 01:03:46PM +0300, Felipe Balbi wrote:
> This a bit confusing, really. Specially when the comment right above
> those flags states:
>
> /* PTP_xxx bits, for the flags field within the request structures. */
Agreed, it is confusing. Go ahead and remove this comment.
> Seems like we will, at least, make it clear which flags are valid for
> which request structures.
Yes, please do make it as clear as you can.
Thanks,
Richard
^ permalink raw reply
* Re: [patch net-next] net: fib_notifier: move fib_notifier_ops from struct net into per-net struct
From: Eric Dumazet @ 2019-09-06 5:54 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: davem, idosch, dsahern, mlxsw
In-Reply-To: <20190905180656.4756-1-jiri@resnulli.us>
On 9/5/19 8:06 PM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> No need for fib_notifier_ops to be in struct net. It is used only by
> fib_notifier as a private data. Use net_generic to introduce per-net
> fib_notifier struct and move fib_notifier_ops there.
>
>
...
> static struct pernet_operations fib_notifier_net_ops = {
> .init = fib_notifier_net_init,
> .exit = fib_notifier_net_exit,
> + .id = &fib_notifier_net_id,
> + .size = sizeof(struct fib_notifier_net),
> };
>
> static int __init fib_notifier_init(void)
>
Note that this will allocate a block of memory (in ops_init()) to hold this,
plus a second one to hold the pointer to this block.
Due to kmalloc() constraints, this block will use more memory.
Not sure your patch is a win, since it makes things a bit more complex.
Is it a preparation patch so that you can add later other fields in struct fib_notifier_net ?
^ permalink raw reply
* Re: [patch net-next] net: fib_notifier: move fib_notifier_ops from struct net into per-net struct
From: Jiri Pirko @ 2019-09-06 6:05 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, idosch, dsahern, mlxsw
In-Reply-To: <bb24e9d5-24c6-d590-e490-be2226016288@gmail.com>
Fri, Sep 06, 2019 at 07:54:39AM CEST, eric.dumazet@gmail.com wrote:
>
>
>On 9/5/19 8:06 PM, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> No need for fib_notifier_ops to be in struct net. It is used only by
>> fib_notifier as a private data. Use net_generic to introduce per-net
>> fib_notifier struct and move fib_notifier_ops there.
>>
>>
>
>...
>
>> static struct pernet_operations fib_notifier_net_ops = {
>> .init = fib_notifier_net_init,
>> .exit = fib_notifier_net_exit,
>> + .id = &fib_notifier_net_id,
>> + .size = sizeof(struct fib_notifier_net),
>> };
>>
>> static int __init fib_notifier_init(void)
>>
>
>Note that this will allocate a block of memory (in ops_init()) to hold this,
>plus a second one to hold the pointer to this block.
>
>Due to kmalloc() constraints, this block will use more memory.
I'm aware. But we have net_generic for exactly this purpose not to
pullute struct net.
>
>Not sure your patch is a win, since it makes things a bit more complex.
>
>Is it a preparation patch so that you can add later other fields in struct fib_notifier_net ?
Yes.
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox