diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2020-09-06 04:46:10 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2022-08-02 14:31:57 +0900 |
commit | dfc382e84f6cdc44665f566d0076e4260e8b1615 (patch) | |
tree | bdb09600ae2629d8568f2189e73e3b4c95b65dff | |
parent | 3d7cb6b04c3f3115719235cc6866b10326de34cd (diff) | |
download | linux-ky/patches-5.19.tar.gz |
net/flow_dissector: dissect into ip/ipv6 header inside MPLSky/patches-5.19
-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 6aee04f75e3e..d115968893b4 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -413,9 +413,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, @@ -431,7 +431,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; @@ -464,7 +464,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 @@ -1263,7 +1275,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; @@ -1833,6 +1845,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[] = { |