aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2020-09-06 04:46:10 +0900
committerKazuki Yamaguchi <k@rhe.jp>2021-11-07 16:09:23 +0900
commita848acd533b37d598cb390dcb545bcff85d761d1 (patch)
tree46fb9475fb414b10ed3de04590ffd7eb961cd31e
parent8bb7eca972ad531c9b149c0a51ab43a417385813 (diff)
downloadlinux-ky/patches-5.15b.tar.gz
net/flow_dissector: dissect into ip/ipv6 header inside MPLSky/patches-5.15b
-rw-r--r--net/core/flow_dissector.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index bac0184cf3de..643a27cd70bf 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -410,9 +410,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,
@@ -428,7 +428,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;
@@ -461,7 +461,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;
@@ -1778,6 +1790,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[] = {