flow_dissector: add support for tunnel control flags
Dissect [no]csum, [no]dontfrag, [no]oam, [no]crit flags from skb metadata. This is a prerequisite for matching these control flags using TC flower. Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Davide Caratti <dcaratti@redhat.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
4fdb6b6063
commit
668b6a2ef8
@@ -329,6 +329,14 @@ struct flow_dissector_key_cfm {
|
||||
#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
|
||||
#define FLOW_DIS_CFM_MDL_MAX 7
|
||||
|
||||
/**
|
||||
* struct flow_dissector_key_enc_flags: tunnel metadata control flags
|
||||
* @flags: tunnel control flags
|
||||
*/
|
||||
struct flow_dissector_key_enc_flags {
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
enum flow_dissector_key_id {
|
||||
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
|
||||
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
|
||||
@@ -363,6 +371,7 @@ enum flow_dissector_key_id {
|
||||
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
|
||||
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
|
||||
FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
|
||||
FLOW_DISSECTOR_KEY_ENC_FLAGS, /* struct flow_dissector_key_enc_flags */
|
||||
|
||||
FLOW_DISSECTOR_KEY_MAX,
|
||||
};
|
||||
|
||||
@@ -247,6 +247,18 @@ static inline bool ip_tunnel_is_options_present(const unsigned long *flags)
|
||||
return ip_tunnel_flags_intersect(flags, present);
|
||||
}
|
||||
|
||||
static inline void ip_tunnel_set_encflags_present(unsigned long *flags)
|
||||
{
|
||||
IP_TUNNEL_DECLARE_FLAGS(present) = { };
|
||||
|
||||
__set_bit(IP_TUNNEL_CSUM_BIT, present);
|
||||
__set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, present);
|
||||
__set_bit(IP_TUNNEL_OAM_BIT, present);
|
||||
__set_bit(IP_TUNNEL_CRIT_OPT_BIT, present);
|
||||
|
||||
ip_tunnel_flags_or(flags, flags, present);
|
||||
}
|
||||
|
||||
static inline bool ip_tunnel_flags_is_be16_compat(const unsigned long *flags)
|
||||
{
|
||||
IP_TUNNEL_DECLARE_FLAGS(supp) = { };
|
||||
|
||||
@@ -382,7 +382,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
|
||||
!dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_ENC_IP) &&
|
||||
!dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_ENC_OPTS))
|
||||
FLOW_DISSECTOR_KEY_ENC_OPTS) &&
|
||||
!dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_ENC_FLAGS))
|
||||
return;
|
||||
|
||||
info = skb_tunnel_info(skb);
|
||||
@@ -475,6 +477,18 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
|
||||
IP_TUNNEL_GENEVE_OPT_BIT);
|
||||
enc_opt->dst_opt_type = val < __IP_TUNNEL_FLAG_NUM ? val : 0;
|
||||
}
|
||||
|
||||
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_FLAGS)) {
|
||||
struct flow_dissector_key_enc_flags *enc_flags;
|
||||
IP_TUNNEL_DECLARE_FLAGS(flags) = {};
|
||||
|
||||
enc_flags = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_ENC_FLAGS,
|
||||
target_container);
|
||||
ip_tunnel_set_encflags_present(flags);
|
||||
ip_tunnel_flags_and(flags, flags, info->key.tun_flags);
|
||||
enc_flags->flags = bitmap_read(flags, IP_TUNNEL_CSUM_BIT, 32);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user