linux/net/core/flow_dissector.c

// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/export.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
#include <linux/filter.h>
#include <net/dsa.h>
#include <net/dst_metadata.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/gre.h>
#include <net/pptp.h>
#include <net/tipc.h>
#include <linux/igmp.h>
#include <linux/icmp.h>
#include <linux/sctp.h>
#include <linux/dccp.h>
#include <linux/if_tunnel.h>
#include <linux/if_pppox.h>
#include <linux/ppp_defs.h>
#include <linux/stddef.h>
#include <linux/if_ether.h>
#include <linux/if_hsr.h>
#include <linux/mpls.h>
#include <linux/tcp.h>
#include <linux/ptp_classify.h>
#include <net/flow_dissector.h>
#include <net/pkt_cls.h>
#include <scsi/fc/fc_fcoe.h>
#include <uapi/linux/batadv_packet.h>
#include <linux/bpf.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_labels.h>
#endif
#include <linux/bpf-netns.h>

static void dissector_set_key(struct flow_dissector *flow_dissector,
			      enum flow_dissector_key_id key_id)
{}

void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
			     const struct flow_dissector_key *key,
			     unsigned int key_count)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_BPF_SYSCALL
int flow_dissector_bpf_prog_attach_check(struct net *net,
					 struct bpf_prog *prog)
{}
#endif /* CONFIG_BPF_SYSCALL */

/**
 * __skb_flow_get_ports - extract the upper layer ports and return them
 * @skb: sk_buff to extract the ports from
 * @thoff: transport header offset
 * @ip_proto: protocol for which to get port offset
 * @data: raw buffer pointer to the packet, if NULL use skb->data
 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
 *
 * The function will try to retrieve the ports at offset thoff + poff where poff
 * is the protocol port offset returned from proto_ports_offset
 */
__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
			    const void *data, int hlen)
{}
EXPORT_SYMBOL();

static bool icmp_has_id(u8 type)
{}

/**
 * skb_flow_get_icmp_tci - extract ICMP(6) Type, Code and Identifier fields
 * @skb: sk_buff to extract from
 * @key_icmp: struct flow_dissector_key_icmp to fill
 * @data: raw buffer pointer to the packet
 * @thoff: offset to extract at
 * @hlen: packet header length
 */
void skb_flow_get_icmp_tci(const struct sk_buff *skb,
			   struct flow_dissector_key_icmp *key_icmp,
			   const void *data, int thoff, int hlen)
{}
EXPORT_SYMBOL();

/* If FLOW_DISSECTOR_KEY_ICMP is set, dissect an ICMP packet
 * using skb_flow_get_icmp_tci().
 */
static void __skb_flow_dissect_icmp(const struct sk_buff *skb,
				    struct flow_dissector *flow_dissector,
				    void *target_container, const void *data,
				    int thoff, int hlen)
{}

static void __skb_flow_dissect_ah(const struct sk_buff *skb,
				  struct flow_dissector *flow_dissector,
				  void *target_container, const void *data,
				  int nhoff, int hlen)
{}

static void __skb_flow_dissect_esp(const struct sk_buff *skb,
				   struct flow_dissector *flow_dissector,
				   void *target_container, const void *data,
				   int nhoff, int hlen)
{}

static void __skb_flow_dissect_l2tpv3(const struct sk_buff *skb,
				      struct flow_dissector *flow_dissector,
				      void *target_container, const void *data,
				      int nhoff, int hlen)
{}

void skb_flow_dissect_meta(const struct sk_buff *skb,
			   struct flow_dissector *flow_dissector,
			   void *target_container)
{}
EXPORT_SYMBOL();

static void
skb_flow_dissect_set_enc_control(enum flow_dissector_key_id type,
				 u32 ctrl_flags,
				 struct flow_dissector *flow_dissector,
				 void *target_container)
{}

void
skb_flow_dissect_ct(const struct sk_buff *skb,
		    struct flow_dissector *flow_dissector,
		    void *target_container, u16 *ctinfo_map,
		    size_t mapsize, bool post_ct, u16 zone)
{}
EXPORT_SYMBOL();

void
skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
			     struct flow_dissector *flow_dissector,
			     void *target_container)
{}
EXPORT_SYMBOL();

void skb_flow_dissect_hash(const struct sk_buff *skb,
			   struct flow_dissector *flow_dissector,
			   void *target_container)
{}
EXPORT_SYMBOL();

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)
{}

static enum flow_dissect_ret
__skb_flow_dissect_arp(const struct sk_buff *skb,
		       struct flow_dissector *flow_dissector,
		       void *target_container, const void *data,
		       int nhoff, int hlen)
{}

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)
{}

static enum flow_dissect_ret
__skb_flow_dissect_gre(const struct sk_buff *skb,
		       struct flow_dissector_key_control *key_control,
		       struct flow_dissector *flow_dissector,
		       void *target_container, const void *data,
		       __be16 *p_proto, int *p_nhoff, int *p_hlen,
		       unsigned int flags)
{}

/**
 * __skb_flow_dissect_batadv() - dissect batman-adv header
 * @skb: sk_buff to with the batman-adv header
 * @key_control: flow dissectors control key
 * @data: raw buffer pointer to the packet, if NULL use skb->data
 * @p_proto: pointer used to update the protocol to process next
 * @p_nhoff: pointer used to update inner network header offset
 * @hlen: packet header length
 * @flags: any combination of FLOW_DISSECTOR_F_*
 *
 * ETH_P_BATMAN packets are tried to be dissected. Only
 * &struct batadv_unicast packets are actually processed because they contain an
 * inner ethernet header and are usually followed by actual network header. This
 * allows the flow dissector to continue processing the packet.
 *
 * Return: FLOW_DISSECT_RET_PROTO_AGAIN when &struct batadv_unicast was found,
 *  FLOW_DISSECT_RET_OUT_GOOD when dissector should stop after encapsulation,
 *  otherwise FLOW_DISSECT_RET_OUT_BAD
 */
static enum flow_dissect_ret
__skb_flow_dissect_batadv(const struct sk_buff *skb,
			  struct flow_dissector_key_control *key_control,
			  const void *data, __be16 *p_proto, int *p_nhoff,
			  int hlen, unsigned int flags)
{}

static void
__skb_flow_dissect_tcp(const struct sk_buff *skb,
		       struct flow_dissector *flow_dissector,
		       void *target_container, const void *data,
		       int thoff, int hlen)
{}

static void
__skb_flow_dissect_ports(const struct sk_buff *skb,
			 struct flow_dissector *flow_dissector,
			 void *target_container, const void *data,
			 int nhoff, u8 ip_proto, int hlen)
{}

static void
__skb_flow_dissect_ipv4(const struct sk_buff *skb,
			struct flow_dissector *flow_dissector,
			void *target_container, const void *data,
			const struct iphdr *iph)
{}

static void
__skb_flow_dissect_ipv6(const struct sk_buff *skb,
			struct flow_dissector *flow_dissector,
			void *target_container, const void *data,
			const struct ipv6hdr *iph)
{}

/* Maximum number of protocol headers that can be parsed in
 * __skb_flow_dissect
 */
#define MAX_FLOW_DISSECT_HDRS

static bool skb_flow_dissect_allowed(int *num_hdrs)
{}

static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
				     struct flow_dissector *flow_dissector,
				     void *target_container)
{}

u32 bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
		     __be16 proto, int nhoff, int hlen, unsigned int flags)
{}

static bool is_pppoe_ses_hdr_valid(const struct pppoe_hdr *hdr)
{}

/**
 * __skb_flow_dissect - extract the flow_keys struct and return it
 * @net: associated network namespace, derived from @skb if NULL
 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
 * @flow_dissector: list of keys to dissect
 * @target_container: target structure to put dissected values into
 * @data: raw buffer pointer to the packet, if NULL use skb->data
 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
 * @flags: flags that control the dissection process, e.g.
 *         FLOW_DISSECTOR_F_STOP_AT_ENCAP.
 *
 * The function will try to retrieve individual keys into target specified
 * by flow_dissector from either the skbuff or a raw buffer specified by the
 * rest parameters.
 *
 * Caller must take care of zeroing target container memory.
 */
bool __skb_flow_dissect(const struct net *net,
			const struct sk_buff *skb,
			struct flow_dissector *flow_dissector,
			void *target_container, const void *data,
			__be16 proto, int nhoff, int hlen, unsigned int flags)
{}
EXPORT_SYMBOL();

static siphash_aligned_key_t hashrnd;
static __always_inline void __flow_hash_secret_init(void)
{}

static const void *flow_keys_hash_start(const struct flow_keys *flow)
{}

static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
{}

__be32 flow_get_u32_src(const struct flow_keys *flow)
{}
EXPORT_SYMBOL();

__be32 flow_get_u32_dst(const struct flow_keys *flow)
{}
EXPORT_SYMBOL();

/* Sort the source and destination IP and the ports,
 * to have consistent hash within the two directions
 */
static inline void __flow_hash_consistentify(struct flow_keys *keys)
{}

static inline u32 __flow_hash_from_keys(struct flow_keys *keys,
					const siphash_key_t *keyval)
{}

u32 flow_hash_from_keys(struct flow_keys *keys)
{}
EXPORT_SYMBOL();

u32 flow_hash_from_keys_seed(struct flow_keys *keys,
			     const siphash_key_t *keyval)
{}
EXPORT_SYMBOL();

static inline u32 ___skb_get_hash(const struct sk_buff *skb,
				  struct flow_keys *keys,
				  const siphash_key_t *keyval)
{}

struct _flow_keys_digest_data {};

void make_flow_keys_digest(struct flow_keys_digest *digest,
			   const struct flow_keys *flow)
{}
EXPORT_SYMBOL();

static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;

u32 __skb_get_hash_symmetric_net(const struct net *net, const struct sk_buff *skb)
{}
EXPORT_SYMBOL_GPL();

/**
 * __skb_get_hash_net: calculate a flow hash
 * @net: associated network namespace, derived from @skb if NULL
 * @skb: sk_buff to calculate flow hash from
 *
 * This function calculates a flow hash based on src/dst addresses
 * and src/dst port numbers.  Sets hash in skb to non-zero hash value
 * on success, zero indicates no valid hash.  Also, sets l4_hash in skb
 * if hash is a canonical 4-tuple hash over transport ports.
 */
void __skb_get_hash_net(const struct net *net, struct sk_buff *skb)
{}
EXPORT_SYMBOL();

__u32 skb_get_hash_perturb(const struct sk_buff *skb,
			   const siphash_key_t *perturb)
{}
EXPORT_SYMBOL();

u32 __skb_get_poff(const struct sk_buff *skb, const void *data,
		   const struct flow_keys_basic *keys, int hlen)
{}

/**
 * skb_get_poff - get the offset to the payload
 * @skb: sk_buff to get the payload offset from
 *
 * The function will get the offset to the payload as far as it could
 * be dissected.  The main user is currently BPF, so that we can dynamically
 * truncate packets without needing to push actual payload to the user
 * space and can analyze headers only, instead.
 */
u32 skb_get_poff(const struct sk_buff *skb)
{}

__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
{}
EXPORT_SYMBOL();

static const struct flow_dissector_key flow_keys_dissector_keys[] =;

static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] =;

static const struct flow_dissector_key flow_keys_basic_dissector_keys[] =;

struct flow_dissector flow_keys_dissector __read_mostly;
EXPORT_SYMBOL();

struct flow_dissector flow_keys_basic_dissector __read_mostly;
EXPORT_SYMBOL();

static int __init init_default_flow_dissectors(void)
{}
core_initcall(init_default_flow_dissectors);