* [PATCH net-next 0/2] flow_dissector, cls_flower: Add support for multiple MPLS Label Stack Entries
@ 2020-05-20 17:28 Guillaume Nault
2020-05-20 17:28 ` [PATCH net-next 1/2] flow_dissector: Parse " Guillaume Nault
2020-05-20 17:28 ` [PATCH net-next 2/2] cls_flower: Support filtering on " Guillaume Nault
0 siblings, 2 replies; 6+ messages in thread
From: Guillaume Nault @ 2020-05-20 17:28 UTC (permalink / raw)
To: David Miller, Jakub Kicinski
Cc: netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko, Benjamin LaHaise,
Tom Herbert, Liel Shoshan, Rony Efraim
Currently, the flow dissector and the Flower classifier can only handle
the first entry of an MPLS label stack. This patch series generalises
the code to allow parsing and matching the labels that follow.
Patch 1 extends the flow dissector to parse MPLS LSEs until the Bottom
Of Stack bit is reached. The number of parsed LSEs is capped at
FLOW_DIS_MPLS_MAX (arbitrarily set to 7).
Patch 2 extends Flower. It defines new netlink attributes, which are
independent from the previous MPLS ones. Mixing the old and the new
attributes in a same filter is not allowed. For backward compatibility,
the old attributes are used when dumping filters that don't require the
new ones.
Guillaume Nault (2):
flow_dissector: Parse multiple MPLS Label Stack Entries
cls_flower: Support filtering on multiple MPLS Label Stack Entries
include/net/flow_dissector.h | 14 +-
include/uapi/linux/pkt_cls.h | 23 +++
net/core/flow_dissector.c | 49 ++++--
net/sched/cls_flower.c | 295 +++++++++++++++++++++++++++++++++--
4 files changed, 347 insertions(+), 34 deletions(-)
--
2.21.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next 1/2] flow_dissector: Parse multiple MPLS Label Stack Entries
2020-05-20 17:28 [PATCH net-next 0/2] flow_dissector, cls_flower: Add support for multiple MPLS Label Stack Entries Guillaume Nault
@ 2020-05-20 17:28 ` Guillaume Nault
2020-05-21 1:24 ` kbuild test robot
2020-05-21 11:54 ` kbuild test robot
2020-05-20 17:28 ` [PATCH net-next 2/2] cls_flower: Support filtering on " Guillaume Nault
1 sibling, 2 replies; 6+ messages in thread
From: Guillaume Nault @ 2020-05-20 17:28 UTC (permalink / raw)
To: David Miller, Jakub Kicinski
Cc: netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko, Benjamin LaHaise,
Tom Herbert, Liel Shoshan, Rony Efraim
The current MPLS dissector only parses the first MPLS Label Stack
Entry (second LSE can be parsed too, but only to set a key_id).
This patch adds the possibility to parse several LSEs by making
__skb_flow_dissect_mpls() return FLOW_DISSECT_RET_PROTO_AGAIN as long
as the Bottom Of Stack bit hasn't been seen, up to a maximum of
FLOW_DIS_MPLS_MAX entries.
FLOW_DIS_MPLS_MAX is arbitrarily set to 7. This should be enough for
many practical purposes, without wasting too much space.
To record the parsed values, flow_dissector_key_mpls is modified to
store an array of stack entries, instead of just the values of the
first one. A bit field, "used_lses", is also added to keep track of
the LSEs that have been set. The objective is to avoid defining a
new FLOW_DISSECTOR_KEY_MPLS_XX for each level of the MPLS stack.
TC flower, which is the only user of FLOW_DISSECTOR_KEY_MPLS, is
adapted for the new struct flow_dissector_key_mpls layout. Matching
on several MPLS Label Stack Entries will be added in the next patch.
Finally, the behaviour of the FLOW_DISSECTOR_KEY_MPLS_ENTROPY key is
slightly modified. Instead of recording the first Entropy Label, it
now records the last one. This shouldn't have any consequences since
there doesn't seem to have any user of FLOW_DISSECTOR_KEY_MPLS_ENTROPY
in the tree. We'd probably better do a hash of all parsed MPLS labels
instead (excluding reserved labels) anyway. That'd give better entropy
and would probably also simplify the code. But that's not the purpose
of this patch, so I'm keeping that as a future exercise.
Signed-off-by: Guillaume Nault <gnault@redhat.com>
---
include/net/flow_dissector.h | 14 +++++++++-
net/core/flow_dissector.c | 49 ++++++++++++++++++++++-----------
net/sched/cls_flower.c | 52 +++++++++++++++++++++++++-----------
3 files changed, 82 insertions(+), 33 deletions(-)
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 628383915827..4fb1a69c6ecf 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -59,13 +59,25 @@ struct flow_dissector_key_vlan {
__be16 vlan_tpid;
};
-struct flow_dissector_key_mpls {
+struct flow_dissector_mpls_lse {
u32 mpls_ttl:8,
mpls_bos:1,
mpls_tc:3,
mpls_label:20;
};
+#define FLOW_DIS_MPLS_MAX 7
+struct flow_dissector_key_mpls {
+ struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
+ u8 used_lses; /* One bit set for each Label Stack Entry in use */
+};
+
+static inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
+ int lse_index)
+{
+ mpls->used_lses |= 1 << lse_index;
+}
+
#define FLOW_DIS_TUN_OPTS_MAX 255
/**
* struct flow_dissector_key_enc_opts:
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 3eff84824c8b..214d08aa3439 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -464,47 +464,59 @@ EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
static enum flow_dissect_ret
__skb_flow_dissect_mpls(const struct sk_buff *skb,
struct flow_dissector *flow_dissector,
- void *target_container, void *data, int nhoff, int hlen)
+ void *target_container, void *data, int nhoff, int hlen,
+ int lse_index, bool *entropy_label)
{
- struct flow_dissector_key_keyid *key_keyid;
- struct mpls_label *hdr, _hdr[2];
- u32 entry, label;
+ struct mpls_label *hdr, _hdr;
+ u32 entry, label, bos;
if (!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
return FLOW_DISSECT_RET_OUT_GOOD;
+ if (lse_index >= FLOW_DIS_MPLS_MAX)
+ return FLOW_DISSECT_RET_OUT_GOOD;
+
hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
hlen, &_hdr);
if (!hdr)
return FLOW_DISSECT_RET_OUT_BAD;
- entry = ntohl(hdr[0].entry);
+ entry = ntohl(hdr->entry);
label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
+ bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
struct flow_dissector_key_mpls *key_mpls;
+ struct flow_dissector_mpls_lse *lse;
key_mpls = skb_flow_dissector_target(flow_dissector,
FLOW_DISSECTOR_KEY_MPLS,
target_container);
- key_mpls->mpls_label = label;
- key_mpls->mpls_ttl = (entry & MPLS_LS_TTL_MASK)
- >> MPLS_LS_TTL_SHIFT;
- key_mpls->mpls_tc = (entry & MPLS_LS_TC_MASK)
- >> MPLS_LS_TC_SHIFT;
- key_mpls->mpls_bos = (entry & MPLS_LS_S_MASK)
- >> MPLS_LS_S_SHIFT;
+ lse = &key_mpls->ls[lse_index];
+
+ lse->mpls_ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
+ lse->mpls_bos = bos;
+ lse->mpls_tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
+ lse->mpls_label = label;
+ dissector_set_mpls_lse(key_mpls, lse_index);
}
- if (label == MPLS_LABEL_ENTROPY) {
+ if (*entropy_label &&
+ dissector_uses_key(flow_dissector,
+ FLOW_DISSECTOR_KEY_MPLS_ENTROPY)) {
+ struct flow_dissector_key_keyid *key_keyid;
+
key_keyid = skb_flow_dissector_target(flow_dissector,
FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
target_container);
- key_keyid->keyid = hdr[1].entry & htonl(MPLS_LS_LABEL_MASK);
+ key_keyid->keyid = label;
}
- return FLOW_DISSECT_RET_OUT_GOOD;
+
+ *entropy_label = label == MPLS_LABEL_ENTROPY;
+
+ return bos ? FLOW_DISSECT_RET_OUT_GOOD : FLOW_DISSECT_RET_PROTO_AGAIN;
}
static enum flow_dissect_ret
@@ -963,6 +975,8 @@ bool __skb_flow_dissect(const struct net *net,
struct bpf_prog *attached = NULL;
enum flow_dissect_ret fdret;
enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
+ bool mpls_el = false;
+ int mpls_lse = 0;
int num_hdrs = 0;
u8 ip_proto = 0;
bool ret;
@@ -1262,7 +1276,10 @@ bool __skb_flow_dissect(const struct net *net,
case htons(ETH_P_MPLS_MC):
fdret = __skb_flow_dissect_mpls(skb, flow_dissector,
target_container, data,
- nhoff, hlen);
+ nhoff, hlen, mpls_lse,
+ &mpls_el);
+ nhoff += sizeof(struct mpls_label);
+ mpls_lse++;
break;
case htons(ETH_P_FCOE):
if ((hlen - nhoff) < FCOE_HEADER_LEN) {
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 0c574700da75..f524afe0b7f5 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -781,9 +781,17 @@ static int fl_set_key_mpls(struct nlattr **tb,
struct flow_dissector_key_mpls *key_mask,
struct netlink_ext_ack *extack)
{
+ struct flow_dissector_mpls_lse *lse_mask;
+ struct flow_dissector_mpls_lse *lse_val;
+
+ lse_val = &key_val->ls[0];
+ lse_mask = &key_mask->ls[0];
+
if (tb[TCA_FLOWER_KEY_MPLS_TTL]) {
- key_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]);
- key_mask->mpls_ttl = MPLS_TTL_MASK;
+ lse_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]);
+ lse_mask->mpls_ttl = MPLS_TTL_MASK;
+ dissector_set_mpls_lse(key_val, 0);
+ dissector_set_mpls_lse(key_mask, 0);
}
if (tb[TCA_FLOWER_KEY_MPLS_BOS]) {
u8 bos = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_BOS]);
@@ -794,8 +802,10 @@ static int fl_set_key_mpls(struct nlattr **tb,
"Bottom Of Stack (BOS) must be 0 or 1");
return -EINVAL;
}
- key_val->mpls_bos = bos;
- key_mask->mpls_bos = MPLS_BOS_MASK;
+ lse_val->mpls_bos = bos;
+ lse_mask->mpls_bos = MPLS_BOS_MASK;
+ dissector_set_mpls_lse(key_val, 0);
+ dissector_set_mpls_lse(key_mask, 0);
}
if (tb[TCA_FLOWER_KEY_MPLS_TC]) {
u8 tc = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TC]);
@@ -806,8 +816,10 @@ static int fl_set_key_mpls(struct nlattr **tb,
"Traffic Class (TC) must be between 0 and 7");
return -EINVAL;
}
- key_val->mpls_tc = tc;
- key_mask->mpls_tc = MPLS_TC_MASK;
+ lse_val->mpls_tc = tc;
+ lse_mask->mpls_tc = MPLS_TC_MASK;
+ dissector_set_mpls_lse(key_val, 0);
+ dissector_set_mpls_lse(key_mask, 0);
}
if (tb[TCA_FLOWER_KEY_MPLS_LABEL]) {
u32 label = nla_get_u32(tb[TCA_FLOWER_KEY_MPLS_LABEL]);
@@ -818,8 +830,10 @@ static int fl_set_key_mpls(struct nlattr **tb,
"Label must be between 0 and 1048575");
return -EINVAL;
}
- key_val->mpls_label = label;
- key_mask->mpls_label = MPLS_LABEL_MASK;
+ lse_val->mpls_label = label;
+ lse_mask->mpls_label = MPLS_LABEL_MASK;
+ dissector_set_mpls_lse(key_val, 0);
+ dissector_set_mpls_lse(key_mask, 0);
}
return 0;
}
@@ -2222,31 +2236,37 @@ static int fl_dump_key_mpls(struct sk_buff *skb,
struct flow_dissector_key_mpls *mpls_key,
struct flow_dissector_key_mpls *mpls_mask)
{
+ struct flow_dissector_mpls_lse *lse_mask;
+ struct flow_dissector_mpls_lse *lse_key;
int err;
if (!memchr_inv(mpls_mask, 0, sizeof(*mpls_mask)))
return 0;
- if (mpls_mask->mpls_ttl) {
+
+ lse_mask = &mpls_mask->ls[0];
+ lse_key = &mpls_key->ls[0];
+
+ if (lse_mask->mpls_ttl) {
err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_TTL,
- mpls_key->mpls_ttl);
+ lse_key->mpls_ttl);
if (err)
return err;
}
- if (mpls_mask->mpls_tc) {
+ if (lse_mask->mpls_tc) {
err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_TC,
- mpls_key->mpls_tc);
+ lse_key->mpls_tc);
if (err)
return err;
}
- if (mpls_mask->mpls_label) {
+ if (lse_mask->mpls_label) {
err = nla_put_u32(skb, TCA_FLOWER_KEY_MPLS_LABEL,
- mpls_key->mpls_label);
+ lse_key->mpls_label);
if (err)
return err;
}
- if (mpls_mask->mpls_bos) {
+ if (lse_mask->mpls_bos) {
err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_BOS,
- mpls_key->mpls_bos);
+ lse_key->mpls_bos);
if (err)
return err;
}
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH net-next 2/2] cls_flower: Support filtering on multiple MPLS Label Stack Entries
2020-05-20 17:28 [PATCH net-next 0/2] flow_dissector, cls_flower: Add support for multiple MPLS Label Stack Entries Guillaume Nault
2020-05-20 17:28 ` [PATCH net-next 1/2] flow_dissector: Parse " Guillaume Nault
@ 2020-05-20 17:28 ` Guillaume Nault
1 sibling, 0 replies; 6+ messages in thread
From: Guillaume Nault @ 2020-05-20 17:28 UTC (permalink / raw)
To: David Miller, Jakub Kicinski
Cc: netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko, Benjamin LaHaise,
Tom Herbert, Liel Shoshan, Rony Efraim
With struct flow_dissector_key_mpls now recording the first
FLOW_DIS_MPLS_MAX labels, we can extend Flower to filter on any of
these LSEs independently.
In order to avoid creating new netlink attributes for every possible
depth, let's define a new TCA_FLOWER_KEY_MPLS_OPTS nested attribute
that contains the list of LSEs to match. Each LSE is represented by
another attribute, TCA_FLOWER_KEY_MPLS_OPTS_LSE, which then contains
the attributes representing the depth and the MPLS fields to match at
this depth (label, TTL, etc.).
For each MPLS field, the mask is always set to all-ones, as this is
what the original API did. We could allow user configurable masks in
the future if there is demand for more flexibility.
The new API also allows to only specify an LSE depth. In that case,
Flower only verifies that the MPLS label stack depth is greater or
equal to the provided depth (that is, an LSE exists at this depth).
Filters that only match on one (or more) fields of the first LSE are
dumped using the old netlink attributes, to avoid confusing user space
programs that don't understand the new API.
Signed-off-by: Guillaume Nault <gnault@redhat.com>
---
include/uapi/linux/pkt_cls.h | 23 ++++
net/sched/cls_flower.c | 243 ++++++++++++++++++++++++++++++++++-
2 files changed, 265 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index fc672b232437..7576209d96f9 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -576,6 +576,8 @@ enum {
TCA_FLOWER_KEY_CT_LABELS, /* u128 */
TCA_FLOWER_KEY_CT_LABELS_MASK, /* u128 */
+ TCA_FLOWER_KEY_MPLS_OPTS,
+
__TCA_FLOWER_MAX,
};
@@ -640,6 +642,27 @@ enum {
#define TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX \
(__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX - 1)
+enum {
+ TCA_FLOWER_KEY_MPLS_OPTS_UNSPEC,
+ TCA_FLOWER_KEY_MPLS_OPTS_LSE,
+ __TCA_FLOWER_KEY_MPLS_OPTS_MAX,
+};
+
+#define TCA_FLOWER_KEY_MPLS_OPTS_MAX (__TCA_FLOWER_KEY_MPLS_OPTS_MAX - 1)
+
+enum {
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_UNSPEC,
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH,
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL,
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS,
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_TC,
+ TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL,
+ __TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX,
+};
+
+#define TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX \
+ (__TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX - 1)
+
enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index f524afe0b7f5..96f5999281e0 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -668,6 +668,7 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_MPLS_BOS] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_MPLS_TC] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_MPLS_LABEL] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_MPLS_OPTS] = { .type = NLA_NESTED },
[TCA_FLOWER_KEY_TCP_FLAGS] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_TCP_FLAGS_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
@@ -726,6 +727,20 @@ erspan_opt_policy[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX + 1] = {
[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID] = { .type = NLA_U8 },
};
+static const struct nla_policy
+mpls_opts_policy[TCA_FLOWER_KEY_MPLS_OPTS_MAX + 1] = {
+ [TCA_FLOWER_KEY_MPLS_OPTS_LSE] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+mpls_stack_entry_policy[TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX + 1] = {
+ [TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_MPLS_OPT_LSE_TC] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL] = { .type = NLA_U32 },
+};
+
static void fl_set_key_val(struct nlattr **tb,
void *val, int val_type,
void *mask, int mask_type, int len)
@@ -776,6 +791,126 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
return 0;
}
+static int fl_set_key_mpls_lse(const struct nlattr *nla_lse,
+ struct flow_dissector_key_mpls *key_val,
+ struct flow_dissector_key_mpls *key_mask,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX + 1];
+ struct flow_dissector_mpls_lse *lse_mask;
+ struct flow_dissector_mpls_lse *lse_val;
+ u8 lse_index;
+ u8 depth;
+ int err;
+
+ err = nla_parse_nested(tb, TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX, nla_lse,
+ mpls_stack_entry_policy, extack);
+ if (err < 0)
+ return err;
+
+ if (!tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH]) {
+ NL_SET_ERR_MSG(extack, "Missing MPLS option \"depth\"");
+ return -EINVAL;
+ }
+
+ depth = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH]);
+
+ /* LSE depth starts at 1, for consistency with terminology used by
+ * RFC 3031 (section 3.9), where depth 0 refers to unlabeled packets.
+ */
+ if (depth < 1 || depth > FLOW_DIS_MPLS_MAX) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH],
+ "Invalid MPLS depth");
+ return -EINVAL;
+ }
+ lse_index = depth - 1;
+
+ dissector_set_mpls_lse(key_val, lse_index);
+ dissector_set_mpls_lse(key_mask, lse_index);
+
+ lse_val = &key_val->ls[lse_index];
+ lse_mask = &key_mask->ls[lse_index];
+
+ if (tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL]) {
+ lse_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL]);
+ lse_mask->mpls_ttl = MPLS_TTL_MASK;
+ }
+ if (tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS]) {
+ u8 bos = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS]);
+
+ if (bos & ~MPLS_BOS_MASK) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS],
+ "Bottom Of Stack (BOS) must be 0 or 1");
+ return -EINVAL;
+ }
+ lse_val->mpls_bos = bos;
+ lse_mask->mpls_bos = MPLS_BOS_MASK;
+ }
+ if (tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TC]) {
+ u8 tc = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TC]);
+
+ if (tc & ~MPLS_TC_MASK) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TC],
+ "Traffic Class (TC) must be between 0 and 7");
+ return -EINVAL;
+ }
+ lse_val->mpls_tc = tc;
+ lse_mask->mpls_tc = MPLS_TC_MASK;
+ }
+ if (tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL]) {
+ u32 label = nla_get_u32(tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL]);
+
+ if (label & ~MPLS_LABEL_MASK) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL],
+ "Label must be between 0 and 1048575");
+ return -EINVAL;
+ }
+ lse_val->mpls_label = label;
+ lse_mask->mpls_label = MPLS_LABEL_MASK;
+ }
+
+ return 0;
+}
+
+static int fl_set_key_mpls_opts(const struct nlattr *nla_mpls_opts,
+ struct flow_dissector_key_mpls *key_val,
+ struct flow_dissector_key_mpls *key_mask,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *nla_lse;
+ int rem;
+ int err;
+
+ if (!(nla_mpls_opts->nla_type & NLA_F_NESTED)) {
+ NL_SET_ERR_MSG_ATTR(extack, nla_mpls_opts,
+ "NLA_F_NESTED is missing");
+ return -EINVAL;
+ }
+
+ nla_for_each_nested(nla_lse, nla_mpls_opts, rem) {
+ if (nla_type(nla_lse) != TCA_FLOWER_KEY_MPLS_OPTS_LSE) {
+ NL_SET_ERR_MSG_ATTR(extack, nla_lse,
+ "Invalid MPLS option type");
+ return -EINVAL;
+ }
+
+ err = fl_set_key_mpls_lse(nla_lse, key_val, key_mask, extack);
+ if (err < 0)
+ return err;
+ }
+ if (rem) {
+ NL_SET_ERR_MSG(extack,
+ "Bytes leftover after parsing MPLS options");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int fl_set_key_mpls(struct nlattr **tb,
struct flow_dissector_key_mpls *key_val,
struct flow_dissector_key_mpls *key_mask,
@@ -784,6 +919,21 @@ static int fl_set_key_mpls(struct nlattr **tb,
struct flow_dissector_mpls_lse *lse_mask;
struct flow_dissector_mpls_lse *lse_val;
+ if (tb[TCA_FLOWER_KEY_MPLS_OPTS]) {
+ if (tb[TCA_FLOWER_KEY_MPLS_TTL] ||
+ tb[TCA_FLOWER_KEY_MPLS_BOS] ||
+ tb[TCA_FLOWER_KEY_MPLS_TC] ||
+ tb[TCA_FLOWER_KEY_MPLS_LABEL]) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_FLOWER_KEY_MPLS_OPTS],
+ "MPLS label, Traffic Class, Bottom Of Stack and Time To Live must be encapsulated in the MPLS options attribute");
+ return -EBADMSG;
+ }
+
+ return fl_set_key_mpls_opts(tb[TCA_FLOWER_KEY_MPLS_OPTS],
+ key_val, key_mask, extack);
+ }
+
lse_val = &key_val->ls[0];
lse_mask = &key_mask->ls[0];
@@ -2232,6 +2382,89 @@ static int fl_dump_key_port_range(struct sk_buff *skb, struct fl_flow_key *key,
return 0;
}
+static int fl_dump_key_mpls_opt_lse(struct sk_buff *skb,
+ struct flow_dissector_key_mpls *mpls_key,
+ struct flow_dissector_key_mpls *mpls_mask,
+ u8 lse_index)
+{
+ struct flow_dissector_mpls_lse *lse_mask = &mpls_mask->ls[lse_index];
+ struct flow_dissector_mpls_lse *lse_key = &mpls_key->ls[lse_index];
+ int err;
+
+ err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH,
+ lse_index + 1);
+ if (err)
+ return err;
+
+ if (lse_mask->mpls_ttl) {
+ err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL,
+ lse_key->mpls_ttl);
+ if (err)
+ return err;
+ }
+ if (lse_mask->mpls_bos) {
+ err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS,
+ lse_key->mpls_bos);
+ if (err)
+ return err;
+ }
+ if (lse_mask->mpls_tc) {
+ err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_OPT_LSE_TC,
+ lse_key->mpls_tc);
+ if (err)
+ return err;
+ }
+ if (lse_mask->mpls_label) {
+ err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL,
+ lse_key->mpls_label);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int fl_dump_key_mpls_opts(struct sk_buff *skb,
+ struct flow_dissector_key_mpls *mpls_key,
+ struct flow_dissector_key_mpls *mpls_mask)
+{
+ struct nlattr *opts;
+ struct nlattr *lse;
+ u8 lse_index;
+ int err;
+
+ opts = nla_nest_start(skb, TCA_FLOWER_KEY_MPLS_OPTS);
+ if (!opts)
+ return -EMSGSIZE;
+
+ for (lse_index = 0; lse_index < FLOW_DIS_MPLS_MAX; lse_index++) {
+ if (!(mpls_mask->used_lses & 1 << lse_index))
+ continue;
+
+ lse = nla_nest_start(skb, TCA_FLOWER_KEY_MPLS_OPTS_LSE);
+ if (!lse) {
+ err = -EMSGSIZE;
+ goto err_opts;
+ }
+
+ err = fl_dump_key_mpls_opt_lse(skb, mpls_key, mpls_mask,
+ lse_index);
+ if (err)
+ goto err_opts_lse;
+ nla_nest_end(skb, lse);
+ }
+ nla_nest_end(skb, opts);
+
+ return 0;
+
+err_opts_lse:
+ nla_nest_cancel(skb, lse);
+err_opts:
+ nla_nest_cancel(skb, opts);
+
+ return err;
+}
+
static int fl_dump_key_mpls(struct sk_buff *skb,
struct flow_dissector_key_mpls *mpls_key,
struct flow_dissector_key_mpls *mpls_mask)
@@ -2240,12 +2473,20 @@ static int fl_dump_key_mpls(struct sk_buff *skb,
struct flow_dissector_mpls_lse *lse_key;
int err;
- if (!memchr_inv(mpls_mask, 0, sizeof(*mpls_mask)))
+ if (!mpls_mask->used_lses)
return 0;
lse_mask = &mpls_mask->ls[0];
lse_key = &mpls_key->ls[0];
+ /* For backward compatibility, don't use the MPLS nested attributes if
+ * the rule can be expressed using the old attributes.
+ */
+ if (mpls_mask->used_lses & ~1 ||
+ (!lse_mask->mpls_ttl && !lse_mask->mpls_bos &&
+ !lse_mask->mpls_tc && !lse_mask->mpls_label))
+ return fl_dump_key_mpls_opts(skb, mpls_key, mpls_mask);
+
if (lse_mask->mpls_ttl) {
err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_TTL,
lse_key->mpls_ttl);
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] flow_dissector: Parse multiple MPLS Label Stack Entries
2020-05-20 17:28 ` [PATCH net-next 1/2] flow_dissector: Parse " Guillaume Nault
@ 2020-05-21 1:24 ` kbuild test robot
2020-05-21 10:09 ` Guillaume Nault
2020-05-21 11:54 ` kbuild test robot
1 sibling, 1 reply; 6+ messages in thread
From: kbuild test robot @ 2020-05-21 1:24 UTC (permalink / raw)
To: Guillaume Nault, David Miller, Jakub Kicinski
Cc: kbuild-all, netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko,
Benjamin LaHaise, Tom Herbert, Liel Shoshan, Rony Efraim
[-- Attachment #1: Type: text/plain, Size: 22381 bytes --]
Hi Guillaume,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net-next/master]
[also build test ERROR on net/master sparc-next/master linus/master v5.7-rc6 next-20200519]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Guillaume-Nault/flow_dissector-cls_flower-Add-support-for-multiple-MPLS-Label-Stack-Entries/20200521-052254
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 4f65e2f483b6f764c15094d14dd53dda048a4048
config: alpha-allyesconfig (attached as .config)
compiler: alpha-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=alpha
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>, old ones prefixed by <<):
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c: In function 'nfp_flower_compile_mac':
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:100:12: note: in expansion of macro 'FIELD_PREP'
100 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
| ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:100:12: note: in expansion of macro 'FIELD_PREP'
100 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
| ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
| ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 | ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); | ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:101:5: note: in expansion of macro 'FIELD_PREP'
101 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
| ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:101:5: note: in expansion of macro 'FIELD_PREP'
101 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
| ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
| ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 | ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); | ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:102:5: note: in expansion of macro 'FIELD_PREP'
102 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
| ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:102:5: note: in expansion of macro 'FIELD_PREP'
102 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
| ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
| ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 | ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); | ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:12: note: in expansion of macro 'FIELD_PREP'
105 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
| ^~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:12: note: in expansion of macro 'FIELD_PREP'
105 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
| ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 | t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
| ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 | ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); | ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:106:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
106 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:5: note: in expansion of macro 'FIELD_PREP'
106 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
| ^~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
106 | FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
| ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 | if (!(condition)) | ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? | ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); | ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:5: note: in expansion of macro 'FIELD_PREP'
vim +100 drivers/net/ethernet/netronome/nfp/flower/match.c
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 76
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 77 static void
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 78 nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext,
31c491e56ad1ad John Hurley 2019-12-17 79 struct nfp_flower_mac_mpls *msk, struct flow_rule *rule)
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 80 {
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 81 memset(ext, 0, sizeof(struct nfp_flower_mac_mpls));
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 82 memset(msk, 0, sizeof(struct nfp_flower_mac_mpls));
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 83
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 84 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 85 struct flow_match_eth_addrs match;
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 86
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 87 flow_rule_match_eth_addrs(rule, &match);
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 88 /* Populate mac frame. */
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 89 ether_addr_copy(ext->mac_dst, &match.key->dst[0]);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 90 ether_addr_copy(ext->mac_src, &match.key->src[0]);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 91 ether_addr_copy(msk->mac_dst, &match.mask->dst[0]);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 92 ether_addr_copy(msk->mac_src, &match.mask->src[0]);
a7cd39e0c7805a Pieter Jansen van Vuuren 2017-08-25 93 }
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 94
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 95 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 96 struct flow_match_mpls match;
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06 97 u32 t_mpls;
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06 98
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 99 flow_rule_match_mpls(rule, &match);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 @100 t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 @101 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 @102 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06 103 NFP_FLOWER_MASK_MPLS_Q;
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 104 ext->mpls_lse = cpu_to_be32(t_mpls);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 105 t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 106 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 107 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.mask->mpls_bos) |
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 108 NFP_FLOWER_MASK_MPLS_Q;
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 109 msk->mpls_lse = cpu_to_be32(t_mpls);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 110 } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25 111 /* Check for mpls ether type and set NFP_FLOWER_MASK_MPLS_Q
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25 112 * bit, which indicates an mpls ether type but without any
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25 113 * mpls fields.
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25 114 */
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 115 struct flow_match_basic match;
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25 116
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 117 flow_rule_match_basic(rule, &match);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 118 if (match.key->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 119 match.key->n_proto == cpu_to_be16(ETH_P_MPLS_MC)) {
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 120 ext->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 121 msk->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
8f2566225ae2d6 Pablo Neira Ayuso 2019-02-02 122 }
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06 123 }
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 124 }
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29 125
:::::: The code at line 100 was first introduced by commit
:::::: 8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb flow_offload: add flow_rule and flow_match structures and use them
:::::: TO: Pablo Neira Ayuso <pablo@netfilter.org>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 61383 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] flow_dissector: Parse multiple MPLS Label Stack Entries
2020-05-21 1:24 ` kbuild test robot
@ 2020-05-21 10:09 ` Guillaume Nault
0 siblings, 0 replies; 6+ messages in thread
From: Guillaume Nault @ 2020-05-21 10:09 UTC (permalink / raw)
To: kbuild test robot
Cc: David Miller, Jakub Kicinski, kbuild-all, netdev,
Jamal Hadi Salim, Cong Wang, Jiri Pirko, Benjamin LaHaise,
Tom Herbert, Liel Shoshan, Rony Efraim
On Thu, May 21, 2020 at 09:24:25AM +0800, kbuild test robot wrote:
> All errors (new ones prefixed by >>, old ones prefixed by <<):
>
> In file included from include/linux/build_bug.h:5,
> from include/linux/bitfield.h:10,
> from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
> drivers/net/ethernet/netronome/nfp/flower/match.c: In function 'nfp_flower_compile_mac':
> >> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
>
Sorry, I didn't realise this was used by NFP.
I'll respin.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] flow_dissector: Parse multiple MPLS Label Stack Entries
2020-05-20 17:28 ` [PATCH net-next 1/2] flow_dissector: Parse " Guillaume Nault
2020-05-21 1:24 ` kbuild test robot
@ 2020-05-21 11:54 ` kbuild test robot
1 sibling, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2020-05-21 11:54 UTC (permalink / raw)
To: Guillaume Nault, David Miller, Jakub Kicinski
Cc: kbuild-all, netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko,
Benjamin LaHaise, Tom Herbert, Liel Shoshan, Rony Efraim
[-- Attachment #1: Type: text/plain, Size: 6767 bytes --]
Hi Guillaume,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
[also build test WARNING on net/master sparc-next/master linus/master v5.7-rc6 next-20200519]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Guillaume-Nault/flow_dissector-cls_flower-Add-support-for-multiple-MPLS-Label-Stack-Entries/20200521-052254
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 4f65e2f483b6f764c15094d14dd53dda048a4048
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-193-gb8fad4bc-dirty
# save the attached .config to linux build tree
make C=1 ARCH=i386 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: cast from unknown type
drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: cast from unknown type
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse: sparse: incompatible types for operation (|):
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse: void
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse: void
drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: cast from unknown type
drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: cast from unknown type
drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: cast from unknown type
drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse: sparse: incompatible types for operation (|):
drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse: void
drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse: void
drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: cast from unknown type
--
net/core/flow_dissector.c:256:43: sparse: sparse: restricted __be16 degrades to integer
>> net/core/flow_dissector.c:514:34: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] keyid @@ got unsignrestricted __be32 [usertype] keyid @@
>> net/core/flow_dissector.c:514:34: sparse: expected restricted __be32 [usertype] keyid
>> net/core/flow_dissector.c:514:34: sparse: got unsigned int [assigned] [usertype] label
vim +514 net/core/flow_dissector.c
463
464 static enum flow_dissect_ret
465 __skb_flow_dissect_mpls(const struct sk_buff *skb,
466 struct flow_dissector *flow_dissector,
467 void *target_container, void *data, int nhoff, int hlen,
468 int lse_index, bool *entropy_label)
469 {
470 struct mpls_label *hdr, _hdr;
471 u32 entry, label, bos;
472
473 if (!dissector_uses_key(flow_dissector,
474 FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
475 !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
476 return FLOW_DISSECT_RET_OUT_GOOD;
477
478 if (lse_index >= FLOW_DIS_MPLS_MAX)
479 return FLOW_DISSECT_RET_OUT_GOOD;
480
481 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
482 hlen, &_hdr);
483 if (!hdr)
484 return FLOW_DISSECT_RET_OUT_BAD;
485
486 entry = ntohl(hdr->entry);
487 label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
488 bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
489
490 if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
491 struct flow_dissector_key_mpls *key_mpls;
492 struct flow_dissector_mpls_lse *lse;
493
494 key_mpls = skb_flow_dissector_target(flow_dissector,
495 FLOW_DISSECTOR_KEY_MPLS,
496 target_container);
497 lse = &key_mpls->ls[lse_index];
498
499 lse->mpls_ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
500 lse->mpls_bos = bos;
501 lse->mpls_tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
502 lse->mpls_label = label;
503 dissector_set_mpls_lse(key_mpls, lse_index);
504 }
505
506 if (*entropy_label &&
507 dissector_uses_key(flow_dissector,
508 FLOW_DISSECTOR_KEY_MPLS_ENTROPY)) {
509 struct flow_dissector_key_keyid *key_keyid;
510
511 key_keyid = skb_flow_dissector_target(flow_dissector,
512 FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
513 target_container);
> 514 key_keyid->keyid = label;
515 }
516
517 *entropy_label = label == MPLS_LABEL_ENTROPY;
518
519 return bos ? FLOW_DISSECT_RET_OUT_GOOD : FLOW_DISSECT_RET_PROTO_AGAIN;
520 }
521
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 72520 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-05-21 12:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-20 17:28 [PATCH net-next 0/2] flow_dissector, cls_flower: Add support for multiple MPLS Label Stack Entries Guillaume Nault
2020-05-20 17:28 ` [PATCH net-next 1/2] flow_dissector: Parse " Guillaume Nault
2020-05-21 1:24 ` kbuild test robot
2020-05-21 10:09 ` Guillaume Nault
2020-05-21 11:54 ` kbuild test robot
2020-05-20 17:28 ` [PATCH net-next 2/2] cls_flower: Support filtering on " Guillaume Nault
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).