* [RFC PATCH iproute2 0/5] Initial, PoC implementation of sw datapath of tc+CT
From: Marcelo Ricardo Leitner @ 2019-01-25 2:33 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
Same comments as for the kernel patches. Whatever is not in accordance
to the planning RFC, is because it is still in progress.
Marcelo Ricardo Leitner (5):
flower: add support for CT fields
act_ct: first import
act_ct: add support for commit flag
act/ct: add support for force flag
act/ct: add support for clear flag
include/uapi/linux/pkt_cls.h | 9 +
include/uapi/linux/tc_act/tc_ct.h | 38 ++++
tc/Makefile | 1 +
tc/f_flower.c | 158 +++++++++++++-
tc/m_ct.c | 337 ++++++++++++++++++++++++++++++
5 files changed, 541 insertions(+), 2 deletions(-)
create mode 100644 include/uapi/linux/tc_act/tc_ct.h
create mode 100644 tc/m_ct.c
--
2.20.1
^ permalink raw reply
* [RFC PATCH iproute2 1/5] flower: add support for CT fields
From: Marcelo Ricardo Leitner @ 2019-01-25 2:33 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548287070.git.mleitner@redhat.com>
Except ct_label, just a place holder for now.
Parsing of ct_state definitely should be handled better.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/uapi/linux/pkt_cls.h | 9 ++
tc/f_flower.c | 158 ++++++++++++++++++++++++++++++++++-
2 files changed, 165 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 95d0db2a8350dffb1dd20816591f3b179913fb2e..ba1f3bc01b2fdfd810e37a2b3853a1da1f838acf 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -490,6 +490,15 @@ enum {
TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */
TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */
+ TCA_FLOWER_KEY_CT_ZONE, /* u16 */
+ TCA_FLOWER_KEY_CT_ZONE_MASK, /* u16 */
+ TCA_FLOWER_KEY_CT_STATE, /* u8 */
+ TCA_FLOWER_KEY_CT_STATE_MASK, /* u8 */
+ TCA_FLOWER_KEY_CT_MARK, /* u32 */
+ TCA_FLOWER_KEY_CT_MARK_MASK, /* u32 */
+ TCA_FLOWER_KEY_CT_LABEL, /* 128 bits */
+ TCA_FLOWER_KEY_CT_LABEL_MASK, /* 128 bits */
+
__TCA_FLOWER_MAX,
};
diff --git a/tc/f_flower.c b/tc/f_flower.c
index c563666702b50973703f37c0174bfae3f242fdf3..40706d7156131f0b6603a4abdbe9108451e5cff7 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -81,7 +81,11 @@ static void explain(void)
" enc_ttl MASKED-IP_TTL |\n"
" geneve_opts MASKED-OPTIONS |\n"
" ip_flags IP-FLAGS | \n"
- " enc_dst_port [ port_number ] }\n"
+ " enc_dst_port [ port_number ] | \n"
+ " ct_mark MASKED-MARK | \n"
+ " ct_zone MASKED-ZONE | \n"
+ " ct_state MASKED-state | \n"
+ " ct_label MASKED-label } \n"
" FILTERID := X:Y:Z\n"
" MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
" ACTION-SPEC := ... look at individual actions\n"
@@ -331,7 +335,7 @@ static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
static int flower_parse_u8(char *str, int value_type, int mask_type,
int (*value_from_name)(const char *str,
- __u8 *value),
+ __u8 *value),
bool (*value_validate)(__u8 value),
struct nlmsghdr *n)
{
@@ -372,6 +376,92 @@ err:
return err;
}
+static int flower_parse_u16(char *str, int value_type, int mask_type,
+ int (*value_from_name)(const char *str,
+ __u16 *value),
+ bool (*value_validate)(__u16 value),
+ struct nlmsghdr *n)
+{
+ char *slash;
+ int ret, err = -1;
+ __u16 value, mask;
+
+ slash = strchr(str, '/');
+ if (slash)
+ *slash = '\0';
+
+ ret = value_from_name ? value_from_name(str, &value) : -1;
+ if (ret < 0) {
+ ret = get_u16(&value, str, 10);
+ if (ret)
+ goto err;
+ }
+
+ if (value_validate && !value_validate(value))
+ goto err;
+
+ if (slash) {
+ ret = get_u16(&mask, slash + 1, 10);
+ if (ret)
+ goto err;
+ }
+ else {
+ mask = UINT16_MAX;
+ }
+
+ addattr16(n, MAX_MSG, value_type, value);
+ addattr16(n, MAX_MSG, mask_type, mask);
+
+ err = 0;
+err:
+ if (slash)
+ *slash = '/';
+ return err;
+}
+
+static int flower_parse_u32(char *str, int value_type, int mask_type,
+ int (*value_from_name)(const char *str,
+ __u32 *value),
+ bool (*value_validate)(__u32 value),
+ struct nlmsghdr *n)
+{
+ char *slash;
+ int ret, err = -1;
+ __u32 value, mask;
+
+ slash = strchr(str, '/');
+ if (slash)
+ *slash = '\0';
+
+ ret = value_from_name ? value_from_name(str, &value) : -1;
+ if (ret < 0) {
+ ret = get_u32(&value, str, 10);
+ if (ret)
+ goto err;
+ }
+
+ if (value_validate && !value_validate(value))
+ goto err;
+
+ if (slash) {
+ ret = get_u32(&mask, slash + 1, 10);
+ if (ret)
+ goto err;
+ }
+ else {
+ mask = UINT32_MAX;
+ }
+
+ addattr32(n, MAX_MSG, value_type, value);
+ addattr32(n, MAX_MSG, mask_type, mask);
+
+ err = 0;
+err:
+ if (slash)
+ *slash = '/';
+ return err;
+}
+
static const char *flower_print_arp_op_to_name(__u8 op)
{
switch (op) {
@@ -796,6 +886,40 @@ static int flower_parse_enc_opts(char *str, struct nlmsghdr *n)
return 0;
}
+static int flower_parse_ct_mark(char *str, struct nlmsghdr *n)
+{
+ return flower_parse_u32(str,
+ TCA_FLOWER_KEY_CT_MARK,
+ TCA_FLOWER_KEY_CT_MARK_MASK,
+ NULL, NULL, n);
+}
+
+static int flower_parse_ct_zone(char *str, struct nlmsghdr *n)
+{
+ return flower_parse_u16(str,
+ TCA_FLOWER_KEY_CT_ZONE,
+ TCA_FLOWER_KEY_CT_ZONE_MASK,
+ NULL, NULL, n);
+}
+
+static int flower_parse_ct_state(char *str, struct nlmsghdr *n)
+{
+ return flower_parse_u8(str,
+ TCA_FLOWER_KEY_CT_STATE,
+ TCA_FLOWER_KEY_CT_STATE_MASK,
+ NULL, NULL, n);
+}
+
+/*
+static int flower_parse_ct_label(char *str, struct nlmsghdr *n)
+{
+ return flower_parse_u128_masked(str,
+ TCA_FLOWER_KEY_CT_LABEL,
+ TCA_FLOWER_KEY_CT_LABEL_MASK,
+ n);
+}
+*/
+
static int flower_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{
@@ -1255,6 +1379,35 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"geneve_opts\"\n");
return -1;
}
+ } else if (matches(*argv, "ct_mark") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ct_mark(*argv, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"ct_mark\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "ct_zone") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ct_zone(*argv, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"ct_zone\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "ct_state") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ct_state(*argv, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"ct_state\"\n");
+ return -1;
+ }
+/* } else if (matches(*argv, "ct_label") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ct_label(*argv, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"ct_label\"\n");
+ return -1;
+ }
+*/
} else if (matches(*argv, "action") == 0) {
NEXT_ARG();
ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
@@ -1919,6 +2072,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
flower_print_enc_opts("enc_opt", tb[TCA_FLOWER_KEY_ENC_OPTS],
tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
+ /* FIXME: print ct fields */
flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
tb[TCA_FLOWER_KEY_FLAGS],
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 4/6] net/sched: act_ct: add support for force flag
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
OvS ct action has this 'force' flag, which basically forces ConnTrack to
consider that this packet, this specific direction, is the original one.
Implement that similarly: if the ct entry is there and the direction is not
the expected one, destroy it and create a new one.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/uapi/linux/tc_act/tc_ct.h | 1 +
net/sched/act_ct.c | 16 +++++++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/tc_act/tc_ct.h b/include/uapi/linux/tc_act/tc_ct.h
index 37b95cda1dedd283b0244a03a20860ba22966dfa..009e53ee83fb3125bc5c4ca86954af3bf6a0287a 100644
--- a/include/uapi/linux/tc_act/tc_ct.h
+++ b/include/uapi/linux/tc_act/tc_ct.h
@@ -25,6 +25,7 @@ enum {
enum {
TC_CT_COMMIT,
+ TC_CT_FORCE,
__TC_CT_MAX
};
#define TC_CT_MAX (__TC_CT_MAX - 1)
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index f69509954149a0c8be710916a5289a4448049b5d..8a1b5d6a7cd8360c50011d992368464db213a020 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -165,6 +165,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_ct *p = to_tcf_ct(a);
+ enum ip_conntrack_info ctinfo;
struct nf_hook_state state = {
.hook = NF_INET_PRE_ROUTING,
};
@@ -173,6 +174,8 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
int action, err;
int nh_ofs;
+ /* Again needs to be here because we need a new ref on the ct. */
+again:
spin_lock(&p->tcf_lock);
tcf_lastuse_update(&p->tcf_tm);
@@ -218,8 +221,19 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
if (err != NF_ACCEPT)
goto drop;
- new_ct = (struct nf_conn *)skb_nfct(skb);
+ new_ct = nf_ct_get(skb, &ctinfo);
if (new_ct) {
+ /* Force conntrack entry direction. */
+ if (flags & BIT(TC_CT_FORCE) &&
+ CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) {
+ if (nf_ct_is_confirmed(new_ct))
+ nf_ct_delete(new_ct, 0, 0);
+
+ nf_conntrack_put(&new_ct->ct_general);
+ nf_ct_set(skb, NULL, 0);
+ goto again;
+ }
+
if (mark_mask) {
new_ct->mark = (new_ct->mark &~ mark_mask) | (mark & mark_mask);
if (nf_ct_is_confirmed(new_ct))
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 6/6] net/sched: act_ct: allow sending a packet through conntrack multiple times
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
The first time it may use conntrack to track the tunnel information,
then jump into another chain, and go through conntrack again so that
the inner header is tracked.
This commit clears previous conntrack info if any so that we can
submit it to conntrack again.
Header offsets are supposed to be updated by the decapsulating action.
The main difference from just adding another act_ct(clear) action is that
the clear flag also sets the UNTRACKED mark in the packet (like OvS does).
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
net/sched/act_ct.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 77d55c05ed95d8abc8c35a3d19f453a586139914..6e446db3bcdda772dbe1090d5c584156f6cc59eb 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -196,16 +196,19 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
if (unlikely(action == TC_ACT_SHOT))
goto drop;
- if (flags & BIT(TC_CT_CLEAR)) {
- new_ct = nf_ct_get(skb, &ctinfo);
- if (new_ct) {
- if (nf_ct_is_confirmed(new_ct))
- nf_ct_delete(new_ct, 0, 0);
+ new_ct = nf_ct_get(skb, &ctinfo);
+ if (new_ct) {
+ if (nf_ct_is_confirmed(new_ct))
+ nf_ct_delete(new_ct, 0, 0);
- nf_conntrack_put(&new_ct->ct_general);
+ nf_conntrack_put(&new_ct->ct_general);
+
+ if (flags & BIT(TC_CT_CLEAR)) {
nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
goto out;
}
+
+ nf_ct_set(skb, NULL, 0);
}
/* FIXME: For when we support cloning the packet
@@ -218,7 +221,6 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
skb_pull_rcsum(skb, nh_ofs);
/* FIXME: OvS trims the packet here. Should we? */
- /* FIXME: Need to handle multiple calls to CT action here. */
if (ct)
nf_ct_set(skb, ct, IP_CT_NEW);
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 5/6] net/sched: act_ct: add support for clear flag
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
OvS ct action supports a 'clear' flag: it removes any ConnTrack marking in
the packet. Implement it similarly here: drop the reference and return.
Note that the packet is also marked as UNTRACKED.
Yes, parsing should ensure that clear is not used with any other flags as
they are mutually exclusive.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/uapi/linux/tc_act/tc_ct.h | 1 +
net/sched/act_ct.c | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/include/uapi/linux/tc_act/tc_ct.h b/include/uapi/linux/tc_act/tc_ct.h
index 009e53ee83fb3125bc5c4ca86954af3bf6a0287a..636f435b86e006aa36034f86c65fd5c220ca8a13 100644
--- a/include/uapi/linux/tc_act/tc_ct.h
+++ b/include/uapi/linux/tc_act/tc_ct.h
@@ -26,6 +26,7 @@ enum {
enum {
TC_CT_COMMIT,
TC_CT_FORCE,
+ TC_CT_CLEAR,
__TC_CT_MAX
};
#define TC_CT_MAX (__TC_CT_MAX - 1)
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 8a1b5d6a7cd8360c50011d992368464db213a020..77d55c05ed95d8abc8c35a3d19f453a586139914 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -196,6 +196,18 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
if (unlikely(action == TC_ACT_SHOT))
goto drop;
+ if (flags & BIT(TC_CT_CLEAR)) {
+ new_ct = nf_ct_get(skb, &ctinfo);
+ if (new_ct) {
+ if (nf_ct_is_confirmed(new_ct))
+ nf_ct_delete(new_ct, 0, 0);
+
+ nf_conntrack_put(&new_ct->ct_general);
+ nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
+ goto out;
+ }
+ }
+
/* FIXME: For when we support cloning the packet
orig_skb = skb;
skb = skb_clone(orig_skb, GFP_ATOMIC);
@@ -257,6 +269,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
skb_push(skb, nh_ofs);
skb_postpush_rcsum(skb, skb->data, nh_ofs);
+out:
return TC_ACT_PIPE;
drop:
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next V4 5/5] vhost: access vq metadata through kernel virtual address
From: Jason Wang @ 2019-01-25 2:33 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: virtualization, netdev, linux-kernel, kvm
In-Reply-To: <20190123235219-mutt-send-email-mst@kernel.org>
On 2019/1/24 下午12:53, Michael S. Tsirkin wrote:
>>>> - How hard is it to figure out which mode uses which code.
>> It's as simple as tracing __get_user() usage in vhost process?
>>
>> Thanks
> Well there are now mtu notifiers etc etc. It's hardly as well
> contained as that.
>
>
We can setup filter out exactly what sets of function that we wan to
trace. E.g we can only trace the usage of __get_user() and
invalidate_range_start(). This should be sufficient.
In the long run, we may want to have some tracepoints for vhost_net.
Thanks
^ permalink raw reply
* [RFC PATCH 3/6] net/sched: add CT action
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
This is where most of the code is and the main pain points.
The implementation is using spinlock on the datapath for now just for
simplicity. Lets get the basics done and then move forward.
Open points:
- nf_ct_netns_get() accepts IPv4, IPv6 or both. It would be interesting to
match on what was specified to the filter, but not sure if that's really
wanted neither how.
- iptables CT target can set a different zone for each direction and also
infer it from the mark. These are NOT used by OvS. We can focus on this
later but probably want to consider the need now.
- datapath fork
As described in the planning RFC PATCH, OvS ct action creates a fork in the
datapath: consider that the packet is being sent through conntrack. The
original packet, without conntrack information, will first finish
executing the current list of actions. After that is done, a packet clone
created by the ct action will be inserted into the specified chain, and
resume its processing. Somehow we need to be able to inject this packet
and we can't use the interface backlog for it, as that would create a
massive reordering.
- The handling of multiple calls to CT action is needed because the first
call may be on a packet still with tunnel headers, and then without it.
It is handled in a subsequent patch by dropping any conntrack present in
the skb.
On protocol type on datapath, note that tc can match on both at once, IPv4
and IPv6. So far we can't easily tell which filter tc is using. We could
tell conntrack to work with both (NFPROTO_INET), but that would be kind of
a lazy solution here. Instead, lets trust the packet header: if it is
here, it's because tc matched, so we can either process it as IPv4 or IPv6.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/net/tc_act/tc_ct.h | 29 +++
include/uapi/linux/tc_act/tc_ct.h | 36 +++
net/sched/Kconfig | 6 +
net/sched/Makefile | 1 +
net/sched/act_ct.c | 356 ++++++++++++++++++++++++++++++
5 files changed, 428 insertions(+)
create mode 100644 include/net/tc_act/tc_ct.h
create mode 100644 include/uapi/linux/tc_act/tc_ct.h
create mode 100644 net/sched/act_ct.c
diff --git a/include/net/tc_act/tc_ct.h b/include/net/tc_act/tc_ct.h
new file mode 100644
index 0000000000000000000000000000000000000000..65682460f501b5886d9266f811c8ed30a4510304
--- /dev/null
+++ b/include/net/tc_act/tc_ct.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_TC_CT_H
+#define __NET_TC_CT_H
+
+#include <linux/types.h>
+#include <net/act_api.h>
+#include <uapi/linux/netfilter/xt_connlabel.h>
+
+struct tcf_ct {
+ struct tc_action common;
+ struct net *net;
+
+ u16 zone;
+ u32 mark;
+ u32 mark_mask;
+ u32 chain;
+
+ /* FIXME: Use nf_conn_labels instead? But it pulls all netfilter */
+#define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE)
+ u32 label[NF_CT_LABELS_MAX_SIZE / sizeof(long)];
+ u32 label_mask[NF_CT_LABELS_MAX_SIZE / sizeof(long)];
+
+ u32 flags;
+ struct nf_conn *ct;
+};
+
+#define to_tcf_ct(a) ((struct tcf_ct *)a)
+
+#endif /* __NET_TC_CT_H */
diff --git a/include/uapi/linux/tc_act/tc_ct.h b/include/uapi/linux/tc_act/tc_ct.h
new file mode 100644
index 0000000000000000000000000000000000000000..37b95cda1dedd283b0244a03a20860ba22966dfa
--- /dev/null
+++ b/include/uapi/linux/tc_act/tc_ct.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_TC_CT_H
+#define __LINUX_TC_CT_H
+
+#include <linux/pkt_cls.h>
+#include <linux/types.h>
+
+#define TCA_ACT_CT 27
+
+enum {
+ TCA_CT_UNSPEC,
+ TCA_CT_TM,
+ TCA_CT_PARMS,
+ TCA_CT_PAD,
+ TCA_CT_ZONE,
+ TCA_CT_MARK,
+ TCA_CT_MARK_MASK,
+ TCA_CT_LABEL,
+ TCA_CT_LABEL_MASK,
+ TCA_CT_CHAIN,
+ TCA_CT_FLAGS,
+ __TCA_CT_MAX
+};
+#define TCA_CT_MAX (__TCA_CT_MAX - 1)
+
+enum {
+ TC_CT_COMMIT,
+ __TC_CT_MAX
+};
+#define TC_CT_MAX (__TC_CT_MAX - 1)
+
+struct tc_ct {
+ tc_gen;
+};
+
+#endif
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 1b9afdee5ba976ba64200d8f85050cf053b7d65c..2c7f963b78f7511bbee8814b1c5bfdb488386c5d 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -912,6 +912,12 @@ config NET_ACT_TUNNEL_KEY
To compile this code as a module, choose M here: the
module will be called act_tunnel_key.
+config NET_ACT_CT
+ tristate "Conntrack manipulation"
+ depends on NET_CLS_ACT
+ ---help---
+ FIXME
+
config NET_IFE_SKBMARK
tristate "Support to encoding decoding skb mark on IFE action"
depends on NET_ACT_IFE
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 8a40431d7b5c420d86427933a9af383e093812b7..f2f6db5b8352a9594b72bc6197caf2228b45c079 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_NET_ACT_BPF) += act_bpf.o
obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o
obj-$(CONFIG_NET_ACT_SKBMOD) += act_skbmod.o
obj-$(CONFIG_NET_ACT_IFE) += act_ife.o
+obj-$(CONFIG_NET_ACT_CT) += act_ct.o
obj-$(CONFIG_NET_IFE_SKBMARK) += act_meta_mark.o
obj-$(CONFIG_NET_IFE_SKBPRIO) += act_meta_skbprio.o
obj-$(CONFIG_NET_IFE_SKBTCINDEX) += act_meta_skbtcindex.o
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
new file mode 100644
index 0000000000000000000000000000000000000000..f69509954149a0c8be710916a5289a4448049b5d
--- /dev/null
+++ b/net/sched/act_ct.c
@@ -0,0 +1,356 @@
+/*
+ * Conntrack manipulation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/rtnetlink.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/tc_act/tc_ct.h>
+#include <net/act_api.h>
+#include <net/netlink.h>
+#include <net/tc_act/tc_ct.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_labels.h>
+
+static unsigned int ct_net_id;
+static struct tc_action_ops act_ct_ops;
+
+static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = {
+ [TCA_CT_PARMS] = { .len = sizeof(struct tc_ct) },
+ [TCA_CT_ZONE] = { .type = NLA_U16 },
+ [TCA_CT_MARK] = { .type = NLA_U32 },
+ [TCA_CT_MARK_MASK] = { .type = NLA_U32 },
+ [TCA_CT_LABEL] = { .type = NLA_BINARY,
+ .len = 128/BITS_PER_BYTE },
+ [TCA_CT_LABEL_MASK] = { .type = NLA_BINARY,
+ .len = 128/BITS_PER_BYTE },
+ [TCA_CT_CHAIN] = { .type = NLA_U32 },
+ [TCA_CT_FLAGS] = { .type = NLA_U32 },
+};
+
+static int tcf_ct_init(struct net *net, struct nlattr *nla, struct nlattr *est,
+ struct tc_action **a, int ovr, int bind,
+ bool rtnl_held, struct netlink_ext_ack *extack)
+{
+ struct tc_action_net *tn = net_generic(net, ct_net_id);
+ struct nlattr *tb[TCA_CT_MAX + 1];
+ struct nf_conntrack_zone zone;
+ struct nf_conn *ct, *_ct;
+ struct tc_ct *parm;
+ int ret = 0, err;
+ struct tcf_ct *p;
+ u16 zone_id = NF_CT_DEFAULT_ZONE_ID;
+
+ if (!nla)
+ return -EINVAL;
+
+ err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, NULL);
+ if (err < 0)
+ return err;
+
+ if (!tb[TCA_CT_PARMS])
+ return -EINVAL;
+ parm = nla_data(tb[TCA_CT_PARMS]);
+
+ if (tb[TCA_CT_ZONE])
+ zone_id = nla_get_u16(tb[TCA_CT_ZONE]);
+
+ err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
+ if (!err) {
+ ret = tcf_idr_create(tn, parm->index, est, a,
+ &act_ct_ops, bind, false);
+ if (ret) {
+ tcf_idr_cleanup(tn, parm->index);
+ return ret;
+ }
+ ret = ACT_P_CREATED;
+ } else if (err > 0) {
+ if (bind)
+ return 0;
+ if (!ovr) {
+ ret = -EEXIST;
+ goto err1;
+ }
+ } else {
+ return err;
+ }
+
+ /* XXX Need translation from AF_INET to NFPROTO_ */
+ err = nf_ct_netns_get(net, NFPROTO_IPV4 /* XXX par->family */);
+ if (err < 0) {
+ ret = err;
+ goto err1;
+ }
+
+ /* XXX: CT target supports setting a different zone on each direction */
+ /* XXX: CT supports inferring zone id from the mark, but we probably
+ * don't need that here.
+ if (info->flags & XT_CT_ZONE_MARK)
+ zone.flags |= NF_CT_FLAG_MARK;
+ */
+ nf_ct_zone_init(&zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0);
+
+ ct = nf_ct_tmpl_alloc(net, &zone, GFP_KERNEL);
+ if (!ct) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ __set_bit(IPS_CONFIRMED_BIT, &ct->status);
+ nf_conntrack_get(&ct->ct_general);
+
+ p = to_tcf_ct(*a);
+ spin_lock_bh(&p->tcf_lock);
+ p->zone = zone_id;
+ if (tb[TCA_CT_MARK] && tb[TCA_CT_MARK_MASK]) {
+ p->mark = nla_get_u32(tb[TCA_CT_MARK]);
+ p->mark_mask = nla_get_u32(tb[TCA_CT_MARK_MASK]);
+ }
+ if (tb[TCA_CT_LABEL] && tb[TCA_CT_LABEL_MASK]) {
+ nla_memcpy(p->label, tb[TCA_CT_LABEL], sizeof(p->label));
+ nla_memcpy(p->label_mask, tb[TCA_CT_LABEL_MASK],
+ sizeof(p->label_mask));
+ nf_connlabels_replace(ct, p->label, p->label_mask,
+ sizeof(p->label)/sizeof(u32));
+ }
+ if (tb[TCA_CT_CHAIN])
+ p->chain = nla_get_u32(tb[TCA_CT_CHAIN]);
+ if (tb[TCA_CT_FLAGS])
+ p->flags = nla_get_u32(tb[TCA_CT_FLAGS]);
+ p->net = net;
+
+ p->tcf_action = parm->action;
+
+ _ct = p->ct;
+ p->ct = ct;
+
+ spin_unlock_bh(&p->tcf_lock);
+
+ if (_ct) {
+ nf_conntrack_put(&_ct->ct_general);
+ }
+
+ if (ret == ACT_P_CREATED)
+ tcf_idr_insert(tn, *a);
+
+ return ret;
+
+err1:
+ tcf_idr_release(*a, bind);
+ return ret;
+}
+
+static void tcf_ct_cleanup(struct tc_action *a)
+{
+ struct tcf_ct *p = to_tcf_ct(a);
+
+ if (p->ct) {
+ nf_conntrack_put(&p->ct->ct_general);
+ }
+}
+
+static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
+ struct tcf_result *res)
+{
+ struct tcf_ct *p = to_tcf_ct(a);
+ struct nf_hook_state state = {
+ .hook = NF_INET_PRE_ROUTING,
+ };
+ struct nf_conn *ct, *new_ct;
+ u32 mark, mark_mask, flags;
+ int action, err;
+ int nh_ofs;
+
+ spin_lock(&p->tcf_lock);
+
+ tcf_lastuse_update(&p->tcf_tm);
+ mark = p->mark;
+ mark_mask = p->mark_mask;
+ flags = p->flags;
+ state.net = p->net;
+ action = p->tcf_action;
+ ct = p->ct;
+ if (ct)
+ /* This gets transferred to conntrack */
+ nf_conntrack_get(&ct->ct_general);
+
+ bstats_update(&p->tcf_bstats, skb);
+
+ spin_unlock(&p->tcf_lock);
+
+ if (unlikely(action == TC_ACT_SHOT))
+ goto drop;
+
+ /* FIXME: For when we support cloning the packet
+ orig_skb = skb;
+ skb = skb_clone(orig_skb, GFP_ATOMIC);
+ */
+
+ /* The conntrack module expects to be working at L3. */
+ nh_ofs = skb_network_offset(skb);
+ skb_pull_rcsum(skb, nh_ofs);
+ /* FIXME: OvS trims the packet here. Should we? */
+
+ /* FIXME: Need to handle multiple calls to CT action here. */
+ if (ct)
+ nf_ct_set(skb, ct, IP_CT_NEW);
+
+ if (skb->protocol == htons(ETH_P_IPV6)) {
+ state.pf = NFPROTO_IPV6;
+ } else {
+ /* FIXME: should we restrict this even further? */
+ state.pf = NFPROTO_IPV4;
+ }
+
+ err = nf_conntrack_in(skb, &state);
+ if (err != NF_ACCEPT)
+ goto drop;
+
+ new_ct = (struct nf_conn *)skb_nfct(skb);
+ if (new_ct) {
+ if (mark_mask) {
+ new_ct->mark = (new_ct->mark &~ mark_mask) | (mark & mark_mask);
+ if (nf_ct_is_confirmed(new_ct))
+ nf_conntrack_event_cache(IPCT_MARK, new_ct);
+ }
+
+ nf_ct_deliver_cached_events(new_ct);
+ }
+
+ if (flags & BIT(TC_CT_COMMIT)) {
+ err = nf_conntrack_confirm(skb);
+ if (err != NF_ACCEPT) {
+ printk("failed to confirm %d\n", err);
+ goto drop;
+ }
+ }
+
+ /* FIXME: inject the packet into another chain (as it would happen if
+ * it had a miss in hw too)
+ */
+
+ skb_push(skb, nh_ofs);
+ skb_postpush_rcsum(skb, skb->data, nh_ofs);
+ return TC_ACT_PIPE;
+
+drop:
+ spin_lock(&p->tcf_lock);
+ p->tcf_qstats.drops++;
+ spin_unlock(&p->tcf_lock);
+ return TC_ACT_SHOT;
+}
+
+static int tcf_ct_dump(struct sk_buff *skb, struct tc_action *a,
+ int bind, int ref)
+{
+ unsigned char *b = skb_tail_pointer(skb);
+ struct tcf_ct *p = to_tcf_ct(a);
+ struct tc_ct opt = {
+ .index = p->tcf_index,
+ .refcnt = refcount_read(&p->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
+ };
+ struct tcf_t t;
+
+ spin_lock_bh(&p->tcf_lock);
+ nla_put_u16(skb, TCA_CT_ZONE, p->zone);
+ nla_put_u32(skb, TCA_CT_MARK, p->mark);
+ nla_put_u32(skb, TCA_CT_MARK_MASK, p->mark_mask);
+ nla_put_u32(skb, TCA_CT_CHAIN, p->chain);
+ nla_put(skb, TCA_CT_LABEL, sizeof(p->label), p->label);
+ nla_put(skb, TCA_CT_LABEL_MASK, sizeof(p->label_mask), p->label_mask);
+ nla_put_u32(skb, TCA_CT_FLAGS, p->flags);
+ opt.action = p->tcf_action;
+
+ if (nla_put(skb, TCA_CT_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
+
+ tcf_tm_dump(&t, &p->tcf_tm);
+ if (nla_put_64bit(skb, TCA_CT_TM, sizeof(t), &t, TCA_CT_PAD))
+ goto nla_put_failure;
+ spin_unlock_bh(&p->tcf_lock);
+
+ return skb->len;
+
+nla_put_failure:
+ spin_unlock_bh(&p->tcf_lock);
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static int tcf_ct_walker(struct net *net, struct sk_buff *skb,
+ struct netlink_callback *cb, int type,
+ const struct tc_action_ops *ops,
+ struct netlink_ext_ack *extack)
+{
+ struct tc_action_net *tn = net_generic(net, ct_net_id);
+
+ return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+}
+
+static int tcf_ct_search(struct net *net, struct tc_action **a, u32 index)
+{
+ struct tc_action_net *tn = net_generic(net, ct_net_id);
+
+ return tcf_idr_search(tn, a, index);
+}
+
+static struct tc_action_ops act_ct_ops = {
+ .kind = "ct",
+ .type = TCA_ACT_CT,
+ .owner = THIS_MODULE,
+ .act = tcf_ct_act,
+ .dump = tcf_ct_dump,
+ .init = tcf_ct_init,
+ .cleanup = tcf_ct_cleanup,
+ .walk = tcf_ct_walker,
+ .lookup = tcf_ct_search,
+ .size = sizeof(struct tcf_ct),
+};
+
+static __net_init int ct_init_net(struct net *net)
+{
+ struct tc_action_net *tn = net_generic(net, ct_net_id);
+
+ return tc_action_net_init(tn, &act_ct_ops);
+}
+
+static void __net_exit ct_exit_net(struct list_head *net_list)
+{
+ tc_action_net_exit(net_list, ct_net_id);
+}
+
+static struct pernet_operations ct_net_ops = {
+ .init = ct_init_net,
+ .exit_batch = ct_exit_net,
+ .id = &ct_net_id,
+ .size = sizeof(struct tc_action_net),
+};
+
+MODULE_DESCRIPTION("Connection Tracking actions");
+MODULE_LICENSE("GPL");
+
+static int __init ct_init_module(void)
+{
+ return tcf_register_action(&act_ct_ops, &ct_net_ops);
+}
+
+static void __exit ct_cleanup_module(void)
+{
+ tcf_unregister_action(&act_ct_ops, &ct_net_ops);
+}
+
+module_init(ct_init_module);
+module_exit(ct_cleanup_module);
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 1/6] flow_dissector: add support for matching on ConnTrack
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
This a preliminary patch to add support on flow dissector for matching on
ConnTrack information.
2 FIXMEs in place:
- reusing nf_conn_labels may not be feasible, as we don't want to pull too
much of ConnTrack into flow dissector.
- CT may be there, but it may not be using labels. As hashing zeroes is
different than not having the information, it should either be handled as
a new dissector key or have an extra bit in flow_dissector_key_ct
indicating its presence. Having it as an extra key may speed searches not
using labels.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/net/flow_dissector.h | 17 ++++++++++++++
include/uapi/linux/netfilter/xt_connlabel.h | 5 +++++
net/core/flow_dissector.c | 25 +++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 6a4586dcdeded9b6cfe7d299d368b6a6ea6801cc..2b5a20a0f65c28d9907697ac3ef7e03d0e20209a 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -4,7 +4,9 @@
#include <linux/types.h>
#include <linux/in6.h>
+#include <linux/bits.h>
#include <uapi/linux/if_ether.h>
+#include <uapi/linux/netfilter/xt_connlabel.h>
/**
* struct flow_dissector_key_control:
@@ -199,6 +201,19 @@ struct flow_dissector_key_ip {
__u8 ttl;
};
+/**
+ * struct flow_dissector_key_ct:
+ */
+struct flow_dissector_key_ct {
+ __u16 zone;
+ __u8 state;
+ __u32 mark;
+ /* FIXME: Use nf_conn_labels instead? But it pulls all netfilter */
+#define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE)
+ unsigned long label[NF_CT_LABELS_MAX_SIZE / sizeof(long)];
+#undef NF_CT_LABELS_MAX_SIZE
+};
+
enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -224,6 +239,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */
FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
+ FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
FLOW_DISSECTOR_KEY_MAX,
};
@@ -254,6 +270,7 @@ struct flow_keys {
#define FLOW_KEYS_HASH_START_FIELD basic
struct flow_dissector_key_basic basic;
struct flow_dissector_key_tags tags;
+ struct flow_dissector_key_ct ct;
struct flow_dissector_key_vlan vlan;
struct flow_dissector_key_vlan cvlan;
struct flow_dissector_key_keyid keyid;
diff --git a/include/uapi/linux/netfilter/xt_connlabel.h b/include/uapi/linux/netfilter/xt_connlabel.h
index 2312f0ec07b2791ffaece0a95eebaefa727f14be..20a1c1fe79a7676c4b9f8727c393443f2d545784 100644
--- a/include/uapi/linux/netfilter/xt_connlabel.h
+++ b/include/uapi/linux/netfilter/xt_connlabel.h
@@ -1,4 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _NF_CONNTRACK_CONNLABEL_H
+#define _NF_CONNTRACK_CONNLABEL_H
+
#include <linux/types.h>
#define XT_CONNLABEL_MAXBIT 127
@@ -11,3 +14,5 @@ struct xt_connlabel_mtinfo {
__u16 bit;
__u16 options;
};
+
+#endif
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 2e8d91e54179c32b41ab53b9fa424fe1691acde0..73336466423aedff9a6fc4724f6c6efe44d5225a 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -26,6 +26,8 @@
#include <scsi/fc/fc_fcoe.h>
#include <uapi/linux/batadv_packet.h>
#include <linux/bpf.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_labels.h>
static DEFINE_MUTEX(flow_dissector_mutex);
@@ -798,6 +800,29 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
}
rcu_read_unlock();
+ if (dissector_uses_key(flow_dissector,
+ FLOW_DISSECTOR_KEY_CT)) {
+ struct flow_dissector_key_ct *key_ct;
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn_labels *labels;
+ struct nf_conn *ct;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct) {
+ key_ct = skb_flow_dissector_target(flow_dissector,
+ FLOW_DISSECTOR_KEY_CT,
+ target_container);
+ key_ct->zone = ct->zone.id;
+ key_ct->state = ctinfo;
+ key_ct->mark = ct->mark;
+ labels = nf_ct_labels_find(ct);
+ /* FIXME: should this be a new key then? */
+ if (labels)
+ memcpy(key_ct->label, labels->bits,
+ sizeof(key_ct->label));
+ }
+ }
+
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
struct ethhdr *eth = eth_hdr(skb);
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 2/6] net/sched: flower: add support for matching on ConnTrack
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <cover.1548285996.git.mleitner@redhat.com>
Hook on flow dissector's new interface on ConnTrack from previous patch.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
include/uapi/linux/pkt_cls.h | 9 +++++++++
net/sched/cls_flower.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 95d0db2a8350dffb1dd20816591f3b179913fb2e..ba1f3bc01b2fdfd810e37a2b3853a1da1f838acf 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -490,6 +490,15 @@ enum {
TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */
TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */
+ TCA_FLOWER_KEY_CT_ZONE, /* u16 */
+ TCA_FLOWER_KEY_CT_ZONE_MASK, /* u16 */
+ TCA_FLOWER_KEY_CT_STATE, /* u8 */
+ TCA_FLOWER_KEY_CT_STATE_MASK, /* u8 */
+ TCA_FLOWER_KEY_CT_MARK, /* u32 */
+ TCA_FLOWER_KEY_CT_MARK_MASK, /* u32 */
+ TCA_FLOWER_KEY_CT_LABEL, /* 128 bits */
+ TCA_FLOWER_KEY_CT_LABEL_MASK, /* 128 bits */
+
__TCA_FLOWER_MAX,
};
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 85e9f8e1da10aa7b01b0f51768edfefbe63d6a10..430b7fceeca0998b8c904acd91f8de53571814ff 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -57,6 +57,7 @@ struct fl_flow_key {
struct flow_dissector_key_enc_opts enc_opts;
struct flow_dissector_key_ports tp_min;
struct flow_dissector_key_ports tp_max;
+ struct flow_dissector_key_ct ct;
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
struct fl_flow_mask_range {
@@ -1079,6 +1080,22 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
fl_set_key_ip(tb, true, &key->enc_ip, &mask->enc_ip);
+ fl_set_key_val(tb, &key->ct.mark, TCA_FLOWER_KEY_CT_MARK,
+ &mask->ct.mark, TCA_FLOWER_KEY_CT_MARK_MASK,
+ sizeof(key->ct.mark));
+
+ fl_set_key_val(tb, &key->ct.zone, TCA_FLOWER_KEY_CT_ZONE,
+ &mask->ct.zone, TCA_FLOWER_KEY_CT_ZONE_MASK,
+ sizeof(key->ct.zone));
+
+ fl_set_key_val(tb, &key->ct.state, TCA_FLOWER_KEY_CT_STATE,
+ &mask->ct.state, TCA_FLOWER_KEY_CT_STATE_MASK,
+ sizeof(key->ct.state));
+
+ fl_set_key_val(tb, &key->ct.label, TCA_FLOWER_KEY_CT_LABEL,
+ &mask->ct.label, TCA_FLOWER_KEY_CT_LABEL_MASK,
+ sizeof(key->ct.label));
+
if (tb[TCA_FLOWER_KEY_ENC_OPTS]) {
ret = fl_set_enc_opt(tb, key, mask, extack);
if (ret)
@@ -1183,6 +1200,8 @@ static void fl_init_dissector(struct flow_dissector *dissector,
FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);
FL_KEY_SET_IF_MASKED(mask, keys, cnt,
FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);
+ FL_KEY_SET_IF_MASKED(mask, keys, cnt,
+ FLOW_DISSECTOR_KEY_CT, ct);
skb_flow_dissector_init(dissector, keys, cnt);
}
@@ -1994,6 +2013,20 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net,
fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts))
goto nla_put_failure;
+ if (fl_dump_key_val(skb, &key->ct.zone, TCA_FLOWER_KEY_CT_ZONE,
+ &mask->ct.zone, TCA_FLOWER_KEY_CT_ZONE_MASK,
+ sizeof(key->ct.zone)) ||
+ fl_dump_key_val(skb, &key->ct.mark, TCA_FLOWER_KEY_CT_MARK,
+ &mask->ct.mark, TCA_FLOWER_KEY_CT_MARK_MASK,
+ sizeof(key->ct.mark)) ||
+ fl_dump_key_val(skb, &key->ct.state, TCA_FLOWER_KEY_CT_STATE,
+ &mask->ct.state, TCA_FLOWER_KEY_CT_STATE_MASK,
+ sizeof(key->ct.state)) ||
+ fl_dump_key_val(skb, &key->ct.label, TCA_FLOWER_KEY_CT_LABEL,
+ &mask->ct.label, TCA_FLOWER_KEY_CT_LABEL_MASK,
+ sizeof(key->ct.label)))
+ goto nla_put_failure;
+
if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
goto nla_put_failure;
--
2.20.1
^ permalink raw reply related
* [RFC PATCH 0/6] Initial, PoC implementation of sw datapath of tc+CT
From: Marcelo Ricardo Leitner @ 2019-01-25 2:32 UTC (permalink / raw)
To: Guy Shattah, Marcelo Leitner, Aaron Conole, John Hurley,
Simon Horman, Justin Pettit, Gregory Rose, Eelco Chaudron,
Flavio Leitner, Florian Westphal, Jiri Pirko, Rashid Khan,
Sushil Kulkarni, Andy Gospodarek, Roi Dayan, Yossi Kuperman,
Or Gerlitz, Rony Efraim, davem@davemloft.net
Cc: netdev
In-Reply-To: <AM6PR05MB52376C239DEFB7E22700B904BD990@AM6PR05MB5237.eurprd05.prod.outlook.com>
We have been working on the sw datapath of tc+CT. We may not have much
yet, but this should help to shed some light on what is needed,
sw-datapath-wise speaking. Lets grease the wheels!
Some key features are still missing like proper handling of conntrack
labels, indexing all CT entries on a given act_ct action (so that we can
purge them if the action is removed) and properly match on ct_state.
All in all, if anything in there is not aligned with the planning RFC PATCH,
is because it is still in progress, but fell free to highlight it
anyway.
A LOT more will be needed for handling the offloading.
With these patches, this construction:
./tc filter del dev veth1 ingress
./tc filter add dev veth1 ingress proto ip \
matchall \
action ct zone 1 commit \
action goto chain 100
./tc filter add dev veth1 ingress proto ip chain 100 \
flower ct_zone 2 \
action drop
./tc filter add dev veth1 ingress proto ip chain 100 \
flower ct_zone 1 \
action drop
works, in the sense that replaying a tcp packet gets dropped by the last
rule on chain 100, while the first one misses it. Regarding the goto
chain used here, yes, that action has to be done within the ct action
(as described in the planning and in the FIXME tag in 3rd patch).
Marcelo Ricardo Leitner (6):
flow_dissector: add support for matching on ConnTrack
net/sched: flower: add support for matching on ConnTrack
net/sched: add CT action
net/sched: act_ct: add support for force flag
net/sched: act_ct: add support for clear flag
net/sched: act_ct: allow sending a packet through conntrack multiple
times
include/net/flow_dissector.h | 17 +
include/net/tc_act/tc_ct.h | 29 ++
include/uapi/linux/netfilter/xt_connlabel.h | 5 +
include/uapi/linux/pkt_cls.h | 9 +
include/uapi/linux/tc_act/tc_ct.h | 38 ++
net/core/flow_dissector.c | 25 ++
net/sched/Kconfig | 6 +
net/sched/Makefile | 1 +
net/sched/act_ct.c | 385 ++++++++++++++++++++
net/sched/cls_flower.c | 33 ++
10 files changed, 548 insertions(+)
create mode 100644 include/net/tc_act/tc_ct.h
create mode 100644 include/uapi/linux/tc_act/tc_ct.h
create mode 100644 net/sched/act_ct.c
--
2.20.1
^ permalink raw reply
* Re: [PATCH v4 bpf-next 1/9] bpf: introduce bpf_spin_lock
From: Eric Dumazet @ 2019-01-25 2:29 UTC (permalink / raw)
To: Alexei Starovoitov, Peter Zijlstra
Cc: Alexei Starovoitov, davem, daniel, jakub.kicinski, netdev,
kernel-team, mingo, will.deacon, Paul McKenney, jannh
In-Reply-To: <20190124235857.xyb5xx2ufr6x5mbt@ast-mbp.dhcp.thefacebook.com>
On 01/24/2019 03:58 PM, Alexei Starovoitov wrote:
> On Thu, Jan 24, 2019 at 07:01:09PM +0100, Peter Zijlstra wrote:
>> and from NMI ...
>
> progs are not preemptable and map syscall accessors have bpf_prog_active counters.
> So nmi/kprobe progs will not be running when syscall is running.
> Hence dead lock is not possible and irq_save is not needed.
Speaking of NMI, how pcpu_freelist_push() and pop() can actually work ?
It seems bpf_get_stackid() can be called from NMI, and lockdep seems to complain loudly
lpaa5:/export/hda3/google/edumazet# ./test_progs
test_pkt_access:PASS:ipv4 48 nsec
test_pkt_access:PASS:ipv6 49 nsec
test_prog_run_xattr:PASS:load 0 nsec
test_prog_run_xattr:PASS:run 316 nsec
test_prog_run_xattr:PASS:data_size_out 316 nsec
test_prog_run_xattr:PASS:overflow 316 nsec
test_prog_run_xattr:PASS:run_no_output 431 nsec
test_prog_run_xattr:PASS:run_wrong_size_out 431 nsec
test_xdp:PASS:ipv4 1397 nsec
test_xdp:PASS:ipv6 523 nsec
test_xdp_adjust_tail:PASS:ipv4 382 nsec
test_xdp_adjust_tail:PASS:ipv6 210 nsec
test_l4lb:PASS:ipv4 143 nsec
test_l4lb:PASS:ipv6 164 nsec
libbpf: incorrect bpf_call opcode
libbpf: incorrect bpf_call opcode
test_tcp_estats:PASS: 0 nsec
test_bpf_obj_id:PASS:get-fd-by-notexist-prog-id 0 nsec
test_bpf_obj_id:PASS:get-fd-by-notexist-map-id 0 nsec
test_bpf_obj_id:PASS:get-map-info(fd) 0 nsec
test_bpf_obj_id:PASS:get-prog-info(fd) 0 nsec
test_bpf_obj_id:PASS:get-map-info(fd) 0 nsec
test_bpf_obj_id:PASS:get-prog-info(fd) 0 nsec
test_bpf_obj_id:PASS:get-prog-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-prog-fd-bad-nr-map-ids 0 nsec
test_bpf_obj_id:PASS:get-prog-info(next_id->fd) 0 nsec
test_bpf_obj_id:PASS:get-prog-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-prog-fd-bad-nr-map-ids 0 nsec
test_bpf_obj_id:PASS:get-prog-info(next_id->fd) 0 nsec
test_bpf_obj_id:PASS:check total prog id found by get_next_id 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:check get-map-info(next_id->fd) 0 nsec
test_bpf_obj_id:PASS:get-map-fd(next_id) 0 nsec
test_bpf_obj_id:PASS:check get-map-info(next_id->fd) 0 nsec
test_bpf_obj_id:PASS:check total map id found by get_next_id 0 nsec
test_pkt_md_access:PASS: 76 nsec
test_obj_name:PASS:check-bpf-prog-name 0 nsec
test_obj_name:PASS:check-bpf-map-name 0 nsec
test_obj_name:PASS:check-bpf-prog-name 0 nsec
test_obj_name:PASS:check-bpf-map-name 0 nsec
test_obj_name:PASS:check-bpf-prog-name 0 nsec
test_obj_name:PASS:check-bpf-map-name 0 nsec
test_obj_name:PASS:check-bpf-prog-name 0 nsec
test_obj_name:PASS:check-bpf-map-name 0 nsec
test_tp_attach_query:PASS:open 0 nsec
test_tp_attach_query:PASS:read 0 nsec
test_tp_attach_query:PASS:prog_load 0 nsec
test_tp_attach_query:PASS:bpf_obj_get_info_by_fd 0 nsec
test_tp_attach_query:PASS:perf_event_open 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_enable 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_set_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:prog_load 0 nsec
test_tp_attach_query:PASS:bpf_obj_get_info_by_fd 0 nsec
test_tp_attach_query:PASS:perf_event_open 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_enable 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_set_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:prog_load 0 nsec
test_tp_attach_query:PASS:bpf_obj_get_info_by_fd 0 nsec
test_tp_attach_query:PASS:perf_event_open 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_enable 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_set_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_tp_attach_query:PASS:perf_event_ioc_query_bpf 0 nsec
test_stacktrace_map:PASS:prog_load 0 nsec
test_stacktrace_map:PASS:open 0 nsec
test_stacktrace_map:PASS:perf_event_open 0 nsec
test_stacktrace_map:PASS:compare_map_keys stackid_hmap vs. stackmap 0 nsec
test_stacktrace_map:PASS:compare_map_keys stackmap vs. stackid_hmap 0 nsec
test_stacktrace_map:PASS:compare_stack_ips stackmap vs. stack_amap 0 nsec
test_stacktrace_build_id:PASS:prog_load 0 nsec
test_stacktrace_build_id:PASS:open 0 nsec
test_stacktrace_build_id:PASS:read 0 nsec
test_stacktrace_build_id:PASS:perf_event_open 0 nsec
test_stacktrace_build_id:PASS:perf_event_ioc_enable 0 nsec
test_stacktrace_build_id:PASS:perf_event_ioc_set_bpf 0 nsec
test_stacktrace_build_id:PASS:bpf_find_map control_map 0 nsec
test_stacktrace_build_id:PASS:bpf_find_map stackid_hmap 0 nsec
test_stacktrace_build_id:PASS:bpf_find_map stackmap 0 nsec
test_stacktrace_build_id:PASS:bpf_find_map stack_amap 0 nsec
test_stacktrace_build_id:PASS:compare_map_keys stackid_hmap vs. stackmap 0 nsec
test_stacktrace_build_id:PASS:compare_map_keys stackmap vs. stackid_hmap 0 nsec
test_stacktrace_build_id:PASS:get build_id with readelf 0 nsec
test_stacktrace_build_id:PASS:get_next_key from stackmap 0 nsec
test_stacktrace_build_id:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id:PASS:build id match 0 nsec
test_stacktrace_build_id:PASS:compare_stack_ips stackmap vs. stack_amap 0 nsec
test_stacktrace_build_id_nmi:PASS:prog_load 0 nsec
test_stacktrace_build_id_nmi:PASS:perf_event_open 0 nsec
test_stacktrace_build_id_nmi:PASS:perf_event_ioc_enable 0 nsec
test_stacktrace_build_id_nmi:PASS:perf_event_ioc_set_bpf 0 nsec
test_stacktrace_build_id_nmi:PASS:bpf_find_map control_map 0 nsec
test_stacktrace_build_id_nmi:PASS:bpf_find_map stackid_hmap 0 nsec
test_stacktrace_build_id_nmi:PASS:bpf_find_map stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:bpf_find_map stack_amap 0 nsec
test_stacktrace_build_id_nmi:PASS:compare_map_keys stackid_hmap vs. stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:compare_map_keys stackmap vs. stackid_hmap 0 nsec
test_stacktrace_build_id_nmi:PASS:get build_id with readelf 0 nsec
test_stacktrace_build_id_nmi:PASS:get_next_key from stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:lookup_elem from stackmap 0 nsec
test_stacktrace_build_id_nmi:PASS:build id match 0 nsec
test_stacktrace_map_raw_tp:PASS:prog_load raw tp 0 nsec
test_stacktrace_map_raw_tp:PASS:raw_tp_open 0 nsec
test_stacktrace_map_raw_tp:PASS:compare_map_keys stackid_hmap vs. stackmap 0 nsec
test_stacktrace_map_raw_tp:PASS:compare_map_keys stackmap vs. stackid_hmap 0 nsec
test_get_stack_raw_tp:PASS:prog_load raw tp 0 nsec
test_get_stack_raw_tp:PASS:raw_tp_open 0 nsec
test_get_stack_raw_tp:PASS:bpf_find_map 0 nsec
test_get_stack_raw_tp:PASS:load_kallsyms 0 nsec
test_get_stack_raw_tp:PASS:perf_event_open 0 nsec
test_get_stack_raw_tp:PASS:bpf_map_update_elem 0 nsec
test_get_stack_raw_tp:PASS:ioctl PERF_EVENT_IOC_ENABLE 0 nsec
test_get_stack_raw_tp:PASS:perf_event_mmap 0 nsec
test_get_stack_raw_tp:PASS:perf_event_poller 0 nsec
test_task_fd_query_rawtp:PASS:prog_load raw tp 0 nsec
test_task_fd_query_rawtp:PASS:raw_tp_open 0 nsec
test_task_fd_query_rawtp:PASS:bpf_task_fd_query 0 nsec
test_task_fd_query_rawtp:PASS:check_results 0 nsec
test_task_fd_query_rawtp:PASS:bpf_task_fd_query (len = 0) 0 nsec
test_task_fd_query_rawtp:PASS:check_results 0 nsec
test_task_fd_query_rawtp:PASS:bpf_task_fd_query (buf = 0) 0 nsec
test_task_fd_query_rawtp:PASS:check_results 0 nsec
test_task_fd_query_rawtp:PASS:bpf_task_fd_query (len = 3) 0 nsec
test_task_fd_query_rawtp:PASS:check_results 0 nsec
test_task_fd_query_tp_core:PASS:bpf_prog_load 0 nsec
test_task_fd_query_tp_core:PASS:open 0 nsec
test_task_fd_query_tp_core:PASS:read 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_open 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_ioc_enable 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_ioc_set_bpf 0 nsec
test_task_fd_query_tp_core:PASS:bpf_task_fd_query 0 nsec
test_task_fd_query_tp_core:PASS:check_results 0 nsec
test_task_fd_query_tp_core:PASS:bpf_prog_load 0 nsec
test_task_fd_query_tp_core:PASS:open 0 nsec
test_task_fd_query_tp_core:PASS:read 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_open 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_ioc_enable 0 nsec
test_task_fd_query_tp_core:PASS:perf_event_ioc_set_bpf 0 nsec
test_task_fd_query_tp_core:PASS:bpf_task_fd_query 0 nsec
test_task_fd_query_tp_core:PASS:check_results 0 nsec
test_reference_tracking:PASS:sk_lookup_success 0 nsec
test_reference_tracking:PASS:sk_lookup_success_simple 0 nsec
test_reference_tracking:PASS:fail_use_after_free 0 nsec
test_reference_tracking:PASS:fail_modify_sk_pointer 0 nsec
test_reference_tracking:PASS:fail_modify_sk_or_null_pointer 0 nsec
test_reference_tracking:PASS:fail_no_release 0 nsec
test_reference_tracking:PASS:fail_release_twice 0 nsec
test_reference_tracking:PASS:fail_release_unchecked 0 nsec
test_reference_tracking:PASS:fail_no_release_subcall 0 nsec
test_queue_stack_map:PASS:bpf_map_pop_elem 342 nsec
test_queue_stack_map:PASS:check-queue-stack-map-empty 323 nsec
test_queue_stack_map:PASS:bpf_map_push_elem 323 nsec
test_queue_stack_map:PASS:bpf_map_pop_elem 325 nsec
test_queue_stack_map:PASS:check-queue-stack-map-empty 311 nsec
test_queue_stack_map:PASS:bpf_map_push_elem 311 nsec
Summary: 175 PASSED, 2 FAILED
[ 429.727565] ========================================================
[ 429.733916] WARNING: possible irq lock inversion dependency detected
[ 429.740282] 5.0.0-dbg-DEV #550 Not tainted
[ 429.744381] --------------------------------------------------------
[ 429.750743] dd/16374 just changed the state of lock:
[ 429.755751] 0000000062c2321f (&head->lock){+...}, at: pcpu_freelist_push+0x28/0x50
[ 429.763348] but this lock was taken by another, HARDIRQ-safe lock in the past:
[ 429.770609] (&rq->lock){-.-.}
[ 429.770610]
and interrupts could create inverse lock ordering between them.
[ 429.785089]
other info that might help us debug this:
[ 429.791630] Possible interrupt unsafe locking scenario:
[ 429.798432] CPU0 CPU1
[ 429.802964] ---- ----
[ 429.807513] lock(&head->lock);
[ 429.810746] local_irq_disable();
[ 429.816700] lock(&rq->lock);
[ 429.822322] lock(&head->lock);
[ 429.828094] <Interrupt>
[ 429.830724] lock(&rq->lock);
[ 429.833977]
*** DEADLOCK ***
[ 429.839929] 1 lock held by dd/16374:
[ 429.843526] #0: 00000000a4c09748 (rcu_read_lock){....}, at: trace_call_bpf+0x38/0x1f0
[ 429.851498]
the shortest dependencies between 2nd lock and 1st lock:
[ 429.859348] -> (&rq->lock){-.-.} {
[ 429.862847] IN-HARDIRQ-W at:
[ 429.866091] lock_acquire+0xa7/0x190
[ 429.871531] _raw_spin_lock+0x2f/0x40
[ 429.877051] scheduler_tick+0x51/0x100
[ 429.882621] update_process_times+0x6f/0x90
[ 429.888660] tick_periodic+0x2b/0xc0
[ 429.894065] tick_handle_periodic+0x25/0x70
[ 429.900096] timer_interrupt+0x15/0x20
[ 429.905729] __handle_irq_event_percpu+0x44/0x2b0
[ 429.912265] handle_irq_event+0x60/0xc0
[ 429.917924] handle_edge_irq+0x8b/0x220
[ 429.923570] handle_irq+0x21/0x30
[ 429.928724] do_IRQ+0x64/0x120
[ 429.933613] ret_from_intr+0x0/0x1d
[ 429.938935] timer_irq_works+0x5b/0xfd
[ 429.944528] setup_IO_APIC+0x378/0x82b
[ 429.950101] apic_intr_mode_init+0x16d/0x172
[ 429.956202] x86_late_time_init+0x15/0x1c
[ 429.962049] start_kernel+0x44b/0x4fe
[ 429.967532] x86_64_start_reservations+0x24/0x26
[ 429.973988] x86_64_start_kernel+0x6f/0x72
[ 429.979942] secondary_startup_64+0xa4/0xb0
[ 429.985960] IN-SOFTIRQ-W at:
[ 429.989183] lock_acquire+0xa7/0x190
[ 429.994582] _raw_spin_lock+0x2f/0x40
[ 430.000067] try_to_wake_up+0x1ef/0x610
[ 430.005740] wake_up_process+0x15/0x20
[ 430.011314] swake_up_one+0x36/0x70
[ 430.016648] rcu_gp_kthread_wake+0x3c/0x40
[ 430.022591] rcu_accelerate_cbs_unlocked+0x8c/0xd0
[ 430.029219] rcu_process_callbacks+0xdd/0xc50
[ 430.035434] __do_softirq+0x105/0x465
[ 430.040952] irq_exit+0xc8/0xd0
[ 430.045932] smp_apic_timer_interrupt+0xa5/0x230
[ 430.052387] apic_timer_interrupt+0xf/0x20
[ 430.058331] clear_page_erms+0x7/0x10
[ 430.063825] __alloc_pages_nodemask+0x165/0x390
[ 430.070201] dsalloc_pages+0x65/0x90
[ 430.075657] reserve_ds_buffers+0x136/0x500
[ 430.081679] x86_reserve_hardware+0x16d/0x180
[ 430.087874] x86_pmu_event_init+0x4b/0x210
[ 430.093828] perf_try_init_event+0x8f/0xb0
[ 430.099744] perf_event_alloc+0xa1d/0xc90
[ 430.105576] perf_event_create_kernel_counter+0x24/0x150
[ 430.112721] hardlockup_detector_event_create+0x41/0x90
[ 430.119785] hardlockup_detector_perf_enable+0xe/0x40
[ 430.126653] watchdog_nmi_enable+0xe/0x20
[ 430.132501] watchdog_enable+0xb8/0xd0
[ 430.138097] softlockup_start_fn+0x15/0x20
[ 430.144015] smp_call_on_cpu_callback+0x2a/0x60
[ 430.150393] process_one_work+0x1f4/0x580
[ 430.156231] worker_thread+0x6f/0x430
[ 430.161708] kthread+0x132/0x170
[ 430.166791] ret_from_fork+0x24/0x30
[ 430.172180] INITIAL USE at:
[ 430.175334] lock_acquire+0xa7/0x190
[ 430.180656] _raw_spin_lock_irqsave+0x3a/0x50
[ 430.186763] rq_attach_root+0x1d/0xd0
[ 430.192153] sched_init+0x30b/0x40d
[ 430.197409] start_kernel+0x283/0x4fe
[ 430.202825] x86_64_start_reservations+0x24/0x26
[ 430.209181] x86_64_start_kernel+0x6f/0x72
[ 430.215032] secondary_startup_64+0xa4/0xb0
[ 430.220964] }
[ 430.222724] ... key at: [<ffffffff88f7dc28>] __key.71964+0x0/0x8
[ 430.229345] ... acquired at:
[ 430.232404] _raw_spin_lock+0x2f/0x40
[ 430.236260] pcpu_freelist_pop+0x77/0xf0
[ 430.240349] bpf_get_stackid+0x1c4/0x440
[ 430.244465] bpf_get_stackid_tp+0x11/0x20
[ 430.250156] -> (&head->lock){+...} {
[ 430.253742] HARDIRQ-ON-W at:
[ 430.256878] lock_acquire+0xa7/0x190
[ 430.262095] _raw_spin_lock+0x2f/0x40
[ 430.267397] pcpu_freelist_push+0x28/0x50
[ 430.273088] bpf_get_stackid+0x41e/0x440
[ 430.278677] bpf_get_stackid_tp+0x11/0x20
[ 430.284350] INITIAL USE at:
[ 430.287411] lock_acquire+0xa7/0x190
[ 430.292591] _raw_spin_lock+0x2f/0x40
[ 430.297833] pcpu_freelist_populate+0xc3/0x120
[ 430.303840] htab_map_alloc+0x41e/0x550
[ 430.309245] __do_sys_bpf+0x27e/0x1b50
[ 430.314591] __x64_sys_bpf+0x1a/0x20
[ 430.319738] do_syscall_64+0x5a/0x460
[ 430.324962] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 430.331598] }
[ 430.333274] ... key at: [<ffffffff89bfce48>] __key.13162+0x0/0x8
[ 430.339821] ... acquired at:
[ 430.342795] mark_lock+0x3c4/0x630
[ 430.346371] __lock_acquire+0x3b2/0x1850
[ 430.350493] lock_acquire+0xa7/0x190
[ 430.354282] _raw_spin_lock+0x2f/0x40
[ 430.358129] pcpu_freelist_push+0x28/0x50
[ 430.362331] bpf_get_stackid+0x41e/0x440
[ 430.366438] bpf_get_stackid_tp+0x11/0x20
[ 430.372128]
stack backtrace:
[ 430.376479] CPU: 29 PID: 16374 Comm: dd Not tainted 5.0.0-dbg-DEV #550
[ 430.383008] Hardware name: Intel RML,PCH/Iota_QC_19, BIOS 2.54.0 06/07/2018
[ 430.389967] Call Trace:
[ 430.392433] dump_stack+0x67/0x95
[ 430.395756] print_irq_inversion_bug.part.38+0x1b8/0x1c4
[ 430.401066] check_usage_backwards+0x156/0x160
[ 430.405523] mark_lock+0x3c4/0x630
[ 430.408925] ? mark_lock+0x3c4/0x630
[ 430.412496] ? print_shortest_lock_dependencies+0x1b0/0x1b0
[ 430.418092] __lock_acquire+0x3b2/0x1850
[ 430.422018] ? find_get_entry+0x1b1/0x320
[ 430.426050] ? find_get_entry+0x1d0/0x320
[ 430.430063] lock_acquire+0xa7/0x190
[ 430.433667] ? lock_acquire+0xa7/0x190
[ 430.437433] ? pcpu_freelist_push+0x28/0x50
[ 430.441635] _raw_spin_lock+0x2f/0x40
[ 430.445317] ? pcpu_freelist_push+0x28/0x50
[ 430.449494] pcpu_freelist_push+0x28/0x50
[ 430.453513] bpf_get_stackid+0x41e/0x440
[ 430.457446] bpf_get_stackid_tp+0x11/0x20
[ 430.461450] ? trace_call_bpf+0xe4/0x1f0
[ 430.465365] ? perf_trace_run_bpf_submit+0x42/0xb0
[ 430.470155] ? perf_trace_urandom_read+0xbf/0x100
[ 430.474851] ? urandom_read+0x20f/0x350
[ 430.478685] ? vfs_read+0xb8/0x190
[ 430.482096] ? __x64_sys_read+0x61/0xd0
[ 430.485949] ? do_syscall_64+0x21/0x460
[ 430.489797] ? do_syscall_64+0x5a/0x460
[ 430.493635] ? entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 451.715758] perf: interrupt took too long (2516 > 2500), lowering kernel.perf_event_max_sample_rate to 79000
^ permalink raw reply
* Re: [PATCH net] sctp: set flow sport from saddr only when it's 0
From: David Miller @ 2019-01-25 2:25 UTC (permalink / raw)
To: lucien.xin; +Cc: linux-kernel, netdev, linux-sctp, marcelo.leitner, nhorman
In-Reply-To: <91961be2ab833139b1a4b0188ba47c2581b991d4.1548096161.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 22 Jan 2019 02:42:41 +0800
> Now sctp_transport_pmtu() passes transport->saddr into .get_dst() to set
> flow sport from 'saddr'. However, transport->saddr is set only when
> transport->dst exists in sctp_transport_route().
>
> If sctp_transport_pmtu() is called without transport->saddr set, like
> when transport->dst doesn't exists, the flow sport will be set to 0
> from transport->saddr, which will cause a wrong route to be got.
>
> Commit 6e91b578bf3f ("sctp: re-use sctp_transport_pmtu in
> sctp_transport_route") made the issue be triggered more easily
> since sctp_transport_pmtu() would be called in sctp_transport_route()
> after that.
>
> In gerneral, fl4->fl4_sport should always be set to
> htons(asoc->base.bind_addr.port), unless transport->asoc doesn't exist
> in sctp_v4/6_get_dst(), which is the case:
>
> sctp_ootb_pkt_new() ->
> sctp_transport_route()
>
> For that, we can simply handle it by setting flow sport from saddr only
> when it's 0 in sctp_v4/6_get_dst().
>
> Fixes: 6e91b578bf3f ("sctp: re-use sctp_transport_pmtu in sctp_transport_route")
> Reported-by: Ying Xu <yinxu@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH net] sctp: set chunk transport correctly when it's a new asoc
From: David Miller @ 2019-01-25 2:25 UTC (permalink / raw)
To: lucien.xin; +Cc: linux-kernel, netdev, linux-sctp, marcelo.leitner, nhorman
In-Reply-To: <d08f8708003363950333c0690960ce3d97897bd4.1548096129.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 22 Jan 2019 02:42:09 +0800
> In the paths:
>
> sctp_sf_do_unexpected_init() ->
> sctp_make_init_ack()
> sctp_sf_do_dupcook_a/b()() ->
> sctp_sf_do_5_1D_ce()
>
> The new chunk 'retval' transport is set from the incoming chunk 'chunk'
> transport. However, 'retval' transport belong to the new asoc, which
> is a different one from 'chunk' transport's asoc.
>
> It will cause that the 'retval' chunk gets set with a wrong transport.
> Later when sending it and because of Commit b9fd683982c9 ("sctp: add
> sctp_packet_singleton"), sctp_packet_singleton() will set some fields,
> like vtag to 'retval' chunk from that wrong transport's asoc.
>
> This patch is to fix it by setting 'retval' transport correctly which
> belongs to the right asoc in sctp_make_init_ack() and
> sctp_sf_do_5_1D_ce().
>
> Fixes: b9fd683982c9 ("sctp: add sctp_packet_singleton")
> Reported-by: Ying Xu <yinxu@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH net] sctp: improve the events for sctp stream adding
From: David Miller @ 2019-01-25 2:25 UTC (permalink / raw)
To: lucien.xin; +Cc: linux-kernel, netdev, linux-sctp, marcelo.leitner, nhorman
In-Reply-To: <a4261c440ed5821ddd5943ec7ed163004953d8b8.1548096012.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 22 Jan 2019 02:40:12 +0800
> This patch is to improve sctp stream adding events in 2 places:
>
> 1. In sctp_process_strreset_addstrm_out(), move up SCTP_MAX_STREAM
> and in stream allocation failure checks, as the adding has to
> succeed after reconf_timer stops for the in stream adding
> request retransmission.
>
> 3. In sctp_process_strreset_addstrm_in(), no event should be sent,
> as no in or out stream is added here.
>
> Fixes: 50a41591f110 ("sctp: implement receiver-side procedures for the Add Outgoing Streams Request Parameter")
> Fixes: c5c4ebb3ab87 ("sctp: implement receiver-side procedures for the Add Incoming Streams Request Parameter")
> Reported-by: Ying Xu <yinxu@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH net] sctp: improve the events for sctp stream reset
From: David Miller @ 2019-01-25 2:25 UTC (permalink / raw)
To: lucien.xin; +Cc: linux-kernel, netdev, linux-sctp, marcelo.leitner, nhorman
In-Reply-To: <dc740e7814086bd4d759c39310c98b214a76ae21.1548095974.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 22 Jan 2019 02:39:34 +0800
> This patch is to improve sctp stream reset events in 4 places:
>
> 1. In sctp_process_strreset_outreq(), the flag should always be set with
> SCTP_STREAM_RESET_INCOMING_SSN instead of OUTGOING, as receiver's in
> stream is reset here.
> 2. In sctp_process_strreset_outreq(), move up SCTP_STRRESET_ERR_WRONG_SSN
> check, as the reset has to succeed after reconf_timer stops for the
> in stream reset request retransmission.
> 3. In sctp_process_strreset_inreq(), no event should be sent, as no in
> or out stream is reset here.
> 4. In sctp_process_strreset_resp(), SCTP_STREAM_RESET_INCOMING_SSN or
> OUTGOING event should always be sent for stream reset requests, no
> matter it fails or succeeds to process the request.
>
> Fixes: 810544764536 ("sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter")
> Fixes: 16e1a91965b0 ("sctp: implement receiver-side procedures for the Incoming SSN Reset Request Parameter")
> Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter")
> Reported-by: Ying Xu <yinxu@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH stable 4.4 06/11] ipv6: defrag: drop non-last frags smaller than min mtu
From: maowenan @ 2019-01-25 2:24 UTC (permalink / raw)
To: Greg KH; +Cc: netdev, eric.dumazet, davem, stable, edumazet
In-Reply-To: <20190124183103.GA18657@kroah.com>
On 2019/1/25 2:31, Greg KH wrote:
> On Wed, Jan 23, 2019 at 10:19:41AM +0800, Mao Wenan wrote:
>> From: Florian Westphal <fw@strlen.de>
>>
>> [ Upstream commit 0ed4229b08c13c84a3c301a08defdc9e7f4467e6 ]
>>
>> don't bother with pathological cases, they only waste cycles.
>> IPv6 requires a minimum MTU of 1280 so we should never see fragments
>> smaller than this (except last frag).
>>
>> v3: don't use awkward "-offset + len"
>> v2: drop IPv4 part, which added same check w. IPV4_MIN_MTU (68).
>> There were concerns that there could be even smaller frags
>> generated by intermediate nodes, e.g. on radio networks.
>>
>> Cc: Peter Oskolkov <posk@google.com>
>> Cc: Eric Dumazet <edumazet@google.com>
>> Signed-off-by: Florian Westphal <fw@strlen.de>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>> ---
>> net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++++
>> net/ipv6/reassembly.c | 4 ++++
>> 2 files changed, 8 insertions(+)
>>
>> diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
>> index 9cd8863..c5033a2 100644
>> --- a/net/ipv6/netfilter/nf_conntrack_reasm.c
>> +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
>> @@ -602,6 +602,10 @@ struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 use
>> hdr = ipv6_hdr(clone);
>> fhdr = (struct frag_hdr *)skb_transport_header(clone);
>>
>> + if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU &&
>> + fhdr->frag_off & htons(IP6_MF))
>> + return -EINVAL;
>
> This backport is incorrect, you should be returning a pointer, right?
Thank you for correcting me, the return value should be a pointer,
I will fix it and test all of patches again, then resend v2.
sorry for my mistake.
>
> How did you test this? This should have blown up under test :(
>
> I'm going to drop this whole series. Please fix it up and test it
> properly and then resend.
>
> thanks,
>
> greg k-h
>
> .
>
^ permalink raw reply
* [PATCH -next] ptp: fix debugfs_simple_attr.cocci warnings
From: YueHaibing @ 2019-01-25 2:28 UTC (permalink / raw)
To: Yangbo Lu, Richard Cochran, davem; +Cc: YueHaibing, netdev, kernel-janitors
Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE
for debugfs files.
Semantic patch information:
Rationale: DEFINE_SIMPLE_ATTRIBUTE + debugfs_create_file()
imposes some significant overhead as compared to
DEFINE_DEBUGFS_ATTRIBUTE + debugfs_create_file_unsafe().
Generated by: scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/ptp/ptp_qoriq_debugfs.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/ptp/ptp_qoriq_debugfs.c b/drivers/ptp/ptp_qoriq_debugfs.c
index d904332..97059502 100644
--- a/drivers/ptp/ptp_qoriq_debugfs.c
+++ b/drivers/ptp/ptp_qoriq_debugfs.c
@@ -33,8 +33,8 @@ static int ptp_qoriq_fiper1_lpbk_set(void *data, u64 val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(ptp_qoriq_fiper1_fops, ptp_qoriq_fiper1_lpbk_get,
- ptp_qoriq_fiper1_lpbk_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(ptp_qoriq_fiper1_fops, ptp_qoriq_fiper1_lpbk_get,
+ ptp_qoriq_fiper1_lpbk_set, "%llu\n");
static int ptp_qoriq_fiper2_lpbk_get(void *data, u64 *val)
{
@@ -64,8 +64,8 @@ static int ptp_qoriq_fiper2_lpbk_set(void *data, u64 val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(ptp_qoriq_fiper2_fops, ptp_qoriq_fiper2_lpbk_get,
- ptp_qoriq_fiper2_lpbk_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(ptp_qoriq_fiper2_fops, ptp_qoriq_fiper2_lpbk_get,
+ ptp_qoriq_fiper2_lpbk_set, "%llu\n");
void ptp_qoriq_create_debugfs(struct qoriq_ptp *qoriq_ptp)
{
@@ -79,11 +79,11 @@ void ptp_qoriq_create_debugfs(struct qoriq_ptp *qoriq_ptp)
qoriq_ptp->debugfs_root = root;
- if (!debugfs_create_file("fiper1-loopback", 0600, root, qoriq_ptp,
- &ptp_qoriq_fiper1_fops))
+ if (!debugfs_create_file_unsafe("fiper1-loopback", 0600, root,
+ qoriq_ptp, &ptp_qoriq_fiper1_fops))
goto err_node;
- if (!debugfs_create_file("fiper2-loopback", 0600, root, qoriq_ptp,
- &ptp_qoriq_fiper2_fops))
+ if (!debugfs_create_file_unsafe("fiper2-loopback", 0600, root,
+ qoriq_ptp, &ptp_qoriq_fiper2_fops))
goto err_node;
return;
^ permalink raw reply related
* [PATCH v2] net: altera_tse: fix msgdma_tx_completion on non-zero fill_level case
From: Atsushi Nemoto @ 2019-01-25 2:02 UTC (permalink / raw)
To: Thor Thayer, netdev; +Cc: Dalon L Westergreen, Tomonori Sakita
From: Tomonori Sakita <tomonori.sakita@sord.co.jp>
If fill_level was not zero and status was not BUSY,
result of "tx_prod - tx_cons - inuse" might be zero.
Subtracting 1 unconditionally results invalid negative return value
on this case.
Make sure not to return an negative value.
Signed-off-by: Tomonori Sakita <tomonori.sakita@sord.co.jp>
Signed-off-by: Atsushi Nemoto <atsushi.nemoto@sord.co.jp>
Reviewed-by: Dalon L Westergreen <dalon.westergreen@linux.intel.com>
---
Changes in v2:
Use max_t instead of just removing the "- 1".
drivers/net/ethernet/altera/altera_msgdma.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c
index 0fb986b..0ae723f 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.c
+++ b/drivers/net/ethernet/altera/altera_msgdma.c
@@ -145,7 +145,8 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv)
& 0xffff;
if (inuse) { /* Tx FIFO is not empty */
- ready = priv->tx_prod - priv->tx_cons - inuse - 1;
+ ready = max_t(int,
+ priv->tx_prod - priv->tx_cons - inuse - 1, 0);
} else {
/* Check for buffered last packet */
status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v2] ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel
From: David Miller @ 2019-01-25 1:54 UTC (permalink / raw)
To: wenxu; +Cc: netdev
In-Reply-To: <1547874685-25151-1-git-send-email-wenxu@ucloud.cn>
From: wenxu@ucloud.cn
Date: Sat, 19 Jan 2019 13:11:25 +0800
> From: wenxu <wenxu@ucloud.cn>
>
> ip l add dev tun type gretap key 1000
> ip a a dev tun 10.0.0.1/24
>
> Packets with tun-id 1000 can be recived by tun dev. But packet can't
> be sent through dev tun for non-tunnel-dst
>
> With this patch: tunnel-dst can be get through lwtunnel like beflow:
> ip r a 10.0.0.7 encap ip dst 172.168.0.11 dev tun
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH stable 4.4 05/11] ip: use rb trees for IP frag queue.
From: maowenan @ 2019-01-25 1:50 UTC (permalink / raw)
To: Greg KH; +Cc: netdev, eric.dumazet, davem, stable, edumazet
In-Reply-To: <20190124175800.GD7484@kroah.com>
On 2019/1/25 1:58, Greg KH wrote:
> On Wed, Jan 23, 2019 at 10:19:40AM +0800, Mao Wenan wrote:
>> From: Peter Oskolkov <posk@google.com>
>>
>> [ Upstream commit fa0f527358bd900ef92f925878ed6bfbd51305cc ]
>
> This commit is not in the 4.14.y tree, any specific reason why not?
I found the commit 6b921536f1707a240e6f53843f1f26231016fda5 net: sk_buff rbnode reorg in v4.14.y
including the fixes.
>
> thanks,
>
> greg k-h
>
>
^ permalink raw reply
* Re: [PATCH v4 bpf-next 1/9] bpf: introduce bpf_spin_lock
From: Jann Horn @ 2019-01-25 1:46 UTC (permalink / raw)
To: paulmck
Cc: Alexei Starovoitov, Peter Zijlstra, Alexei Starovoitov,
David S. Miller, Daniel Borkmann, jakub.kicinski,
Network Development, kernel-team, Ingo Molnar, Will Deacon
In-Reply-To: <20190125012224.GZ4240@linux.ibm.com>
On Fri, Jan 25, 2019 at 2:22 AM Paul E. McKenney <paulmck@linux.ibm.com> wrote:
> On Thu, Jan 24, 2019 at 04:05:16PM -0800, Alexei Starovoitov wrote:
> > On Thu, Jan 24, 2019 at 03:42:32PM -0800, Paul E. McKenney wrote:
> > > On Thu, Jan 24, 2019 at 07:56:52PM +0100, Peter Zijlstra wrote:
> > > > On Thu, Jan 24, 2019 at 07:01:09PM +0100, Peter Zijlstra wrote:
> > > > >
> > > > > Thanks for having kernel/locking people on Cc...
> > > > >
> > > > > On Wed, Jan 23, 2019 at 08:13:55PM -0800, Alexei Starovoitov wrote:
> > > > >
> > > > > > Implementation details:
> > > > > > - on !SMP bpf_spin_lock() becomes nop
> > > > >
> > > > > Because no BPF program is preemptible? I don't see any assertions or
> > > > > even a comment that says this code is non-preemptible.
> > > > >
> > > > > AFAICT some of the BPF_RUN_PROG things are under rcu_read_lock() only,
> > > > > which is not sufficient.
> > > > >
> > > > > > - on architectures that don't support queued_spin_lock trivial lock is used.
> > > > > > Note that arch_spin_lock cannot be used, since not all archs agree that
> > > > > > zero == unlocked and sizeof(arch_spinlock_t) != sizeof(__u32).
> > > > >
> > > > > I really don't much like direct usage of qspinlock; esp. not as a
> > > > > surprise.
> > >
> > > Substituting the lightweight-reader SRCU as discussed earlier would allow
> > > use of a more generic locking primitive, for example, one that allowed
> > > blocking, at least in cases were the context allowed this.
> > >
> > > git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
> > > branch srcu-lr.2019.01.16a.
> > >
> > > One advantage of a more generic locking primitive would be keeping BPF
> > > programs independent of internal changes to spinlock primitives.
> >
> > Let's keep "srcu in bpf" discussion separate from bpf_spin_lock discussion.
> > bpf is not switching to srcu any time soon.
> > If/when it happens it will be only for certain prog+map types
> > like bpf syscall probes that need to be able to do copy_from_user
> > from bpf prog.
>
> Hmmm... What prevents BPF programs from looping infinitely within an
> RCU reader, and as you noted, preemption disabled?
>
> If BPF programs are in fact allowed to loop infinitely, it would be
> very good for the health of the kernel to have preemption enabled.
> And to be within an SRCU read-side critical section instead of an RCU
> read-side critical section.
The BPF verifier prevents loops; this is in push_insn() in
kernel/bpf/verifier.c, which errors out with -EINVAL when a back edge
is encountered. For non-root programs, that limits the maximum number
of instructions per eBPF engine execution to
BPF_MAXINSNS*MAX_TAIL_CALL_CNT==4096*32==131072 (but that includes
call instructions, which can cause relatively expensive operations
like hash table lookups). For programs created with CAP_SYS_ADMIN,
things get more tricky because you can create your own functions and
call them repeatedly; I'm not sure whether the pessimal runtime there
becomes exponential, or whether there is some check that catches this.
^ permalink raw reply
* Re: [PATCH net-next 1/7] net: tls: Save iv in tls_rec for async crypto requests
From: David Miller @ 2019-01-25 1:23 UTC (permalink / raw)
To: davejwatson
Cc: jakub.kicinski, netdev, vakul.garg, borisp, aviadye,
john.fastabend, daniel
In-Reply-To: <20190124223428.emnizzj2sb6zuokc@davejwatson-mba.dhcp.thefacebook.com>
From: Dave Watson <davejwatson@fb.com>
Date: Thu, 24 Jan 2019 22:34:29 +0000
> Later patches touch the same code, so would need to be in both to
> avoid merge conflicts.
Dave, here is the way you should handle this.
Submit this patch for net. Let me know that something you want to
submit for net-next depends upon it.
I will high-prio my merge to Linus to that I can fast forward net
and then merge it into net-next. I will let you know this has
happened.
Then you can submit the net-next parts on top.
Thanks.
^ permalink raw reply
* Re: [PATCH v4 bpf-next 1/9] bpf: introduce bpf_spin_lock
From: Paul E. McKenney @ 2019-01-25 1:22 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Peter Zijlstra, Alexei Starovoitov, davem, daniel, jakub.kicinski,
netdev, kernel-team, mingo, will.deacon, jannh
In-Reply-To: <20190125000515.jizijxz4n735gclx@ast-mbp.dhcp.thefacebook.com>
On Thu, Jan 24, 2019 at 04:05:16PM -0800, Alexei Starovoitov wrote:
> On Thu, Jan 24, 2019 at 03:42:32PM -0800, Paul E. McKenney wrote:
> > On Thu, Jan 24, 2019 at 07:56:52PM +0100, Peter Zijlstra wrote:
> > > On Thu, Jan 24, 2019 at 07:01:09PM +0100, Peter Zijlstra wrote:
> > > >
> > > > Thanks for having kernel/locking people on Cc...
> > > >
> > > > On Wed, Jan 23, 2019 at 08:13:55PM -0800, Alexei Starovoitov wrote:
> > > >
> > > > > Implementation details:
> > > > > - on !SMP bpf_spin_lock() becomes nop
> > > >
> > > > Because no BPF program is preemptible? I don't see any assertions or
> > > > even a comment that says this code is non-preemptible.
> > > >
> > > > AFAICT some of the BPF_RUN_PROG things are under rcu_read_lock() only,
> > > > which is not sufficient.
> > > >
> > > > > - on architectures that don't support queued_spin_lock trivial lock is used.
> > > > > Note that arch_spin_lock cannot be used, since not all archs agree that
> > > > > zero == unlocked and sizeof(arch_spinlock_t) != sizeof(__u32).
> > > >
> > > > I really don't much like direct usage of qspinlock; esp. not as a
> > > > surprise.
> >
> > Substituting the lightweight-reader SRCU as discussed earlier would allow
> > use of a more generic locking primitive, for example, one that allowed
> > blocking, at least in cases were the context allowed this.
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
> > branch srcu-lr.2019.01.16a.
> >
> > One advantage of a more generic locking primitive would be keeping BPF
> > programs independent of internal changes to spinlock primitives.
>
> Let's keep "srcu in bpf" discussion separate from bpf_spin_lock discussion.
> bpf is not switching to srcu any time soon.
> If/when it happens it will be only for certain prog+map types
> like bpf syscall probes that need to be able to do copy_from_user
> from bpf prog.
Hmmm... What prevents BPF programs from looping infinitely within an
RCU reader, and as you noted, preemption disabled?
If BPF programs are in fact allowed to loop infinitely, it would be
very good for the health of the kernel to have preemption enabled.
And to be within an SRCU read-side critical section instead of an RCU
read-side critical section.
Thanx, Paul
^ permalink raw reply
* Re: [PATCH net-next v3 2/2] net/mlx5e: Don't overwrite pedit action when multiple pedit used
From: Tonghao Zhang @ 2019-01-25 1:16 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Saeed Mahameed, Linux Netdev List
In-Reply-To: <CAJ3xEMjSagw=G7mUt2cXQBJbcWJuTwvu=OUobs1j2u5uSK_PXw@mail.gmail.com>
On Fri, Jan 25, 2019 at 1:21 AM Or Gerlitz <gerlitz.or@gmail.com> wrote:
>
> On Tue, Jan 22, 2019 at 4:38 PM <xiangxia.m.yue@gmail.com> wrote:
> >
> > From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> >
> > In some case, we may use multiple pedit actions to modify packets.
> > The command shown as below: the last pedit action is effective.
> >
> > $ tc filter add dev netdev_rep parent ffff: protocol ip prio 1 \
> > flower skip_sw ip_proto icmp dst_ip 3.3.3.3 \
> > action pedit ex munge ip dst set 192.168.1.100 pipe \
> > action pedit ex munge eth src set 00:00:00:00:00:01 pipe \
> > action pedit ex munge eth dst set 00:00:00:00:00:02 pipe \
> > action csum ip pipe \
> > action tunnel_key set src_ip 1.1.1.100 dst_ip 1.1.1.200 dst_port 4789 id 100 \
> > action mirred egress redirect dev vxlan0
> >
> > To fix it, we add max_mod_hdr_actions to mlx5e_tc_flow_parse_attr struction,
> > max_mod_hdr_actions will store the max pedit action number we support and
> > num_mod_hdr_actions indicates how many pedit action we used, and store all
> > pedit action to mod_hdr_actions.
>
> There's a comment just above offload_pedit_fields saying:
>
> /* On input attr->num_mod_hdr_actions tells how many HW actions can be parsed at
> * max from the SW pedit action. On success, it says how many HW actions were
> * actually parsed.
> */
>
> I guess it will have to change now, right?
yes, v4 will be sent
^ permalink raw reply
* Re: [PATCH bpf-next v2 0/3] AF_XDP: add socket monitoring support
From: Daniel Borkmann @ 2019-01-25 0:58 UTC (permalink / raw)
To: bjorn.topel, ast, netdev
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson
In-Reply-To: <20190124185939.23628-1-bjorn.topel@gmail.com>
On 01/24/2019 07:59 PM, bjorn.topel@gmail.com wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
>
> This series adds an AF_XDP sock_diag interface for querying sockets
> from user-space. Tools like iproute2 ss(8) can use this interface to
> list open AF_XDP sockets.
>
> The diagnostic provides information about the Rx/Tx/fill/completetion
> rings, umem, memory usage and such. For a complete list, please refer
> to the xsk_diag.c file.
>
> The AF_XDP sock_diag interface is optional, and can be built as a
> module.
>
> A separate patch series, adding ss(8) iproute2 support, will follow.
>
> v1->v2: * Removed extra newline
> * Zero-out all user-space facing structures prior setting the
> members
> * Added explicit "pad" member in _msg struct
> * Removed unused variable "req" in xsk_diag_handler_dump()
>
> Thanks to Daniel for reviewing the series!
>
> Cheers,
> Björn
>
>
> Björn Töpel (3):
> net: xsk: track AF_XDP sockets on a per-netns list
> xsk: add id to umem
> xsk: add sock_diag interface for AF_XDP
>
> include/net/net_namespace.h | 4 +
> include/net/netns/xdp.h | 13 +++
> include/net/xdp_sock.h | 1 +
> include/uapi/linux/xdp_diag.h | 72 +++++++++++++
> net/xdp/Kconfig | 8 ++
> net/xdp/Makefile | 1 +
> net/xdp/xdp_umem.c | 13 +++
> net/xdp/xsk.c | 36 ++++++-
> net/xdp/xsk.h | 12 +++
> net/xdp/xsk_diag.c | 191 ++++++++++++++++++++++++++++++++++
> 10 files changed, 346 insertions(+), 5 deletions(-)
> create mode 100644 include/net/netns/xdp.h
> create mode 100644 include/uapi/linux/xdp_diag.h
> create mode 100644 net/xdp/xsk.h
> create mode 100644 net/xdp/xsk_diag.c
Applied, thanks!
^ 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