net: flow_dissector: add support for cfm packets

Add support for dissecting cfm packets. The cfm packet header
fields maintenance domain level and opcode can be dissected.

Signed-off-by: Zahari Doychev <zdoychev@maxlinear.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Zahari Doychev 2023-06-08 12:56:46 +02:00 committed by Jakub Kicinski
parent 3a2cb45ca0
commit d7ad70b5ef
2 changed files with 51 additions and 0 deletions

View File

@ -301,6 +301,26 @@ struct flow_dissector_key_l2tpv3 {
__be32 session_id;
};
/**
* struct flow_dissector_key_cfm
* @mdl_ver: maintenance domain level (mdl) and cfm protocol version
* @opcode: code specifying a type of cfm protocol packet
*
* See 802.1ag, ITU-T G.8013/Y.1731
* 1 2
* |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | mdl | version | opcode |
* +-----+---------+-+-+-+-+-+-+-+-+
*/
struct flow_dissector_key_cfm {
u8 mdl_ver;
u8 opcode;
};
#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
#define FLOW_DIS_CFM_MDL_MAX 7
enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@ -333,6 +353,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
FLOW_DISSECTOR_KEY_MAX,
};

View File

@ -557,6 +557,30 @@ __skb_flow_dissect_arp(const struct sk_buff *skb,
return FLOW_DISSECT_RET_OUT_GOOD;
}
static enum flow_dissect_ret
__skb_flow_dissect_cfm(const struct sk_buff *skb,
struct flow_dissector *flow_dissector,
void *target_container, const void *data,
int nhoff, int hlen)
{
struct flow_dissector_key_cfm *key, *hdr, _hdr;
if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_CFM))
return FLOW_DISSECT_RET_OUT_GOOD;
hdr = __skb_header_pointer(skb, nhoff, sizeof(*key), data, hlen, &_hdr);
if (!hdr)
return FLOW_DISSECT_RET_OUT_BAD;
key = skb_flow_dissector_target(flow_dissector, FLOW_DISSECTOR_KEY_CFM,
target_container);
key->mdl_ver = hdr->mdl_ver;
key->opcode = hdr->opcode;
return FLOW_DISSECT_RET_OUT_GOOD;
}
static enum flow_dissect_ret
__skb_flow_dissect_gre(const struct sk_buff *skb,
struct flow_dissector_key_control *key_control,
@ -1400,6 +1424,12 @@ proto_again:
break;
}
case htons(ETH_P_CFM):
fdret = __skb_flow_dissect_cfm(skb, flow_dissector,
target_container, data,
nhoff, hlen);
break;
default:
fdret = FLOW_DISSECT_RET_OUT_BAD;
break;