diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2020-09-06 04:46:10 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2022-02-12 22:26:38 +0900 |
commit | 3642dcffabf6d3f0eabf01a09a979677274956f2 (patch) | |
tree | 470fc7820750fb9f7d14b5709e792778d58414e5 | |
parent | df0cc57e057f18e44dac8e6c18aba47ab53202f9 (diff) | |
download | linux-ky/patches-5.16.tar.gz |
net/flow_dissector: dissect into ip/ipv6 header inside MPLSky/patches-5.16
-rw-r--r-- | net/core/flow_dissector.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 1b094c481f1d..ba0d716f982f 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -411,9 +411,9 @@ static enum flow_dissect_ret __skb_flow_dissect_mpls(const struct sk_buff *skb, struct flow_dissector *flow_dissector, void *target_container, const void *data, int nhoff, - int hlen, int lse_index, bool *entropy_label) + int hlen, int lse_index, bool *entropy_label, __be16 *proto) { - struct mpls_label *hdr, _hdr; + struct mpls_label *hdr, _hdr[2]; u32 entry, label, bos; if (!dissector_uses_key(flow_dissector, @@ -429,7 +429,7 @@ __skb_flow_dissect_mpls(const struct sk_buff *skb, if (!hdr) return FLOW_DISSECT_RET_OUT_BAD; - entry = ntohl(hdr->entry); + entry = ntohl(hdr[0].entry); label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT; bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT; @@ -462,7 +462,19 @@ __skb_flow_dissect_mpls(const struct sk_buff *skb, *entropy_label = label == MPLS_LABEL_ENTROPY; - return bos ? FLOW_DISSECT_RET_OUT_GOOD : FLOW_DISSECT_RET_PROTO_AGAIN; + if (bos) { + /* A wild assumption. I use IPv4 and IPv6 only */ + u8 firstbyte = ntohl(hdr[1].entry) >> 24; + if (0x45 <= firstbyte && firstbyte <= 0x4f) { + *proto = htons(ETH_P_IP); + return FLOW_DISSECT_RET_PROTO_AGAIN; + } else if (0x60 <= firstbyte && firstbyte <= 0x6f) { + *proto = htons(ETH_P_IPV6); + return FLOW_DISSECT_RET_PROTO_AGAIN; + } + return FLOW_DISSECT_RET_OUT_GOOD; + } + return FLOW_DISSECT_RET_PROTO_AGAIN; } static enum flow_dissect_ret @@ -1240,7 +1252,7 @@ proto_again: fdret = __skb_flow_dissect_mpls(skb, flow_dissector, target_container, data, nhoff, hlen, mpls_lse, - &mpls_el); + &mpls_el, &proto); nhoff += sizeof(struct mpls_label); mpls_lse++; break; @@ -1793,6 +1805,11 @@ static const struct flow_dissector_key flow_keys_dissector_keys[] = { .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID, .offset = offsetof(struct flow_keys, keyid), }, + { + .key_id = FLOW_DISSECTOR_KEY_MPLS, + /* XXX: Reusing keyid */ + .offset = offsetof(struct flow_keys, keyid), + }, }; static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = { |