162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * INET		An implementation of the TCP/IP protocol suite for the LINUX
462306a36Sopenharmony_ci *		operating system.  INET is implemented using the  BSD Socket
562306a36Sopenharmony_ci *		interface as the means of communication with the user level.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *		Definitions for the RAW-IP module.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Version:	@(#)raw.h	1.0.2	05/07/93
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * Author:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#ifndef _RAW_H
1462306a36Sopenharmony_ci#define _RAW_H
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <net/inet_sock.h>
1762306a36Sopenharmony_ci#include <net/protocol.h>
1862306a36Sopenharmony_ci#include <net/netns/hash.h>
1962306a36Sopenharmony_ci#include <linux/hash.h>
2062306a36Sopenharmony_ci#include <linux/icmp.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciextern struct proto raw_prot;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciextern struct raw_hashinfo raw_v4_hashinfo;
2562306a36Sopenharmony_cibool raw_v4_match(struct net *net, const struct sock *sk, unsigned short num,
2662306a36Sopenharmony_ci		  __be32 raddr, __be32 laddr, int dif, int sdif);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciint raw_abort(struct sock *sk, int err);
2962306a36Sopenharmony_civoid raw_icmp_error(struct sk_buff *, int, u32);
3062306a36Sopenharmony_ciint raw_local_deliver(struct sk_buff *, int);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciint raw_rcv(struct sock *, struct sk_buff *);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define RAW_HTABLE_LOG	8
3562306a36Sopenharmony_ci#define RAW_HTABLE_SIZE	(1U << RAW_HTABLE_LOG)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistruct raw_hashinfo {
3862306a36Sopenharmony_ci	spinlock_t lock;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	struct hlist_head ht[RAW_HTABLE_SIZE] ____cacheline_aligned;
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic inline u32 raw_hashfunc(const struct net *net, u32 proto)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	return hash_32(net_hash_mix(net) ^ proto, RAW_HTABLE_LOG);
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic inline void raw_hashinfo_init(struct raw_hashinfo *hashinfo)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	int i;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	spin_lock_init(&hashinfo->lock);
5362306a36Sopenharmony_ci	for (i = 0; i < RAW_HTABLE_SIZE; i++)
5462306a36Sopenharmony_ci		INIT_HLIST_HEAD(&hashinfo->ht[i]);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS
5862306a36Sopenharmony_ciint raw_proc_init(void);
5962306a36Sopenharmony_civoid raw_proc_exit(void);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistruct raw_iter_state {
6262306a36Sopenharmony_ci	struct seq_net_private p;
6362306a36Sopenharmony_ci	int bucket;
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline struct raw_iter_state *raw_seq_private(struct seq_file *seq)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	return seq->private;
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_civoid *raw_seq_start(struct seq_file *seq, loff_t *pos);
7162306a36Sopenharmony_civoid *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
7262306a36Sopenharmony_civoid raw_seq_stop(struct seq_file *seq, void *v);
7362306a36Sopenharmony_ci#endif
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciint raw_hash_sk(struct sock *sk);
7662306a36Sopenharmony_civoid raw_unhash_sk(struct sock *sk);
7762306a36Sopenharmony_civoid raw_init(void);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistruct raw_sock {
8062306a36Sopenharmony_ci	/* inet_sock has to be the first member */
8162306a36Sopenharmony_ci	struct inet_sock   inet;
8262306a36Sopenharmony_ci	struct icmp_filter filter;
8362306a36Sopenharmony_ci	u32		   ipmr_table;
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define raw_sk(ptr) container_of_const(ptr, struct raw_sock, inet.sk)
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic inline bool raw_sk_bound_dev_eq(struct net *net, int bound_dev_if,
8962306a36Sopenharmony_ci				       int dif, int sdif)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
9262306a36Sopenharmony_ci	return inet_bound_dev_eq(READ_ONCE(net->ipv4.sysctl_raw_l3mdev_accept),
9362306a36Sopenharmony_ci				 bound_dev_if, dif, sdif);
9462306a36Sopenharmony_ci#else
9562306a36Sopenharmony_ci	return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
9662306a36Sopenharmony_ci#endif
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#endif	/* _RAW_H */
100