Commit d7ad70b5 authored by Zahari Doychev's avatar Zahari Doychev Committed by Jakub Kicinski
Browse files

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: default avatarZahari Doychev <zdoychev@maxlinear.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 3a2cb45c
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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,
};
+30 −0
Original line number Diff line number Diff line
@@ -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 @@ bool __skb_flow_dissect(const struct net *net,
		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;