xref: /openbmc/linux/include/net/ip.h (revision d6bb2d1e)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
41da177e4SLinus Torvalds  *		operating system.  INET is implemented using the  BSD Socket
51da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *		Definitions for the IP module.
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  * Version:	@(#)ip.h	1.0.2	05/07/93
101da177e4SLinus Torvalds  *
1102c30a84SJesper Juhl  * Authors:	Ross Biro
121da177e4SLinus Torvalds  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
131da177e4SLinus Torvalds  *		Alan Cox, <gw4pts@gw4pts.ampr.org>
141da177e4SLinus Torvalds  *
151da177e4SLinus Torvalds  * Changes:
161da177e4SLinus Torvalds  *		Mike McLagan    :       Routing by source
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds #ifndef _IP_H
191da177e4SLinus Torvalds #define _IP_H
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #include <linux/types.h>
221da177e4SLinus Torvalds #include <linux/ip.h>
231da177e4SLinus Torvalds #include <linux/in.h>
24c9bdd4b5SArnaldo Carvalho de Melo #include <linux/skbuff.h>
25f0b1e64cSMartin KaFai Lau #include <linux/jhash.h>
26de40a3e8SChristoph Hellwig #include <linux/sockptr.h>
2714c85021SArnaldo Carvalho de Melo 
2814c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h>
29aa661581SFrancesco Fusco #include <net/route.h>
301da177e4SLinus Torvalds #include <net/snmp.h>
3186b08d86SKOVACS Krisztian #include <net/flow.h>
321bd758ebSJiri Pirko #include <net/flow_dissector.h>
33f0b1e64cSMartin KaFai Lau #include <net/netns/hash.h>
341da177e4SLinus Torvalds 
357ed14d97SGao Feng #define IPV4_MAX_PMTU		65535U		/* RFC 2675, Section 5.1 */
36b5476022SEric Dumazet #define IPV4_MIN_MTU		68			/* RFC 791 */
377ed14d97SGao Feng 
389ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem;
399ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_min;
409ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_max;
419ab948a9SDavid Ahern 
421da177e4SLinus Torvalds struct sock;
431da177e4SLinus Torvalds 
44fd2c3ef7SEric Dumazet struct inet_skb_parm {
450b922b7aSDavid Ahern 	int			iif;
461da177e4SLinus Torvalds 	struct ip_options	opt;		/* Compiled IP options		*/
47a04a480dSDavid Ahern 	u16			flags;
481da177e4SLinus Torvalds 
49df4d9254SHannes Frederic Sowa #define IPSKB_FORWARDED		BIT(0)
50df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TUNNEL_SIZE	BIT(1)
51df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TRANSFORMED	BIT(2)
52df4d9254SHannes Frederic Sowa #define IPSKB_FRAG_COMPLETE	BIT(3)
53df4d9254SHannes Frederic Sowa #define IPSKB_REROUTED		BIT(4)
54df4d9254SHannes Frederic Sowa #define IPSKB_DOREDIRECT	BIT(5)
55d6b915e2SFlorian Westphal #define IPSKB_FRAG_PMTU		BIT(6)
569ee6c5dcSLance Richardson #define IPSKB_L3SLAVE		BIT(7)
575f2d04f1SPatrick McHardy 
585f2d04f1SPatrick McHardy 	u16			frag_max_size;
591da177e4SLinus Torvalds };
601da177e4SLinus Torvalds 
61a04a480dSDavid Ahern static inline bool ipv4_l3mdev_skb(u16 flags)
62a04a480dSDavid Ahern {
63a04a480dSDavid Ahern 	return !!(flags & IPSKB_L3SLAVE);
64a04a480dSDavid Ahern }
65a04a480dSDavid Ahern 
66c9bdd4b5SArnaldo Carvalho de Melo static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
67c9bdd4b5SArnaldo Carvalho de Melo {
68eddc9ec5SArnaldo Carvalho de Melo 	return ip_hdr(skb)->ihl * 4;
69c9bdd4b5SArnaldo Carvalho de Melo }
70c9bdd4b5SArnaldo Carvalho de Melo 
71fd2c3ef7SEric Dumazet struct ipcm_cookie {
7224025c46SSoheil Hassas Yeganeh 	struct sockcm_cookie	sockc;
73c1d18f9fSAl Viro 	__be32			addr;
741da177e4SLinus Torvalds 	int			oif;
75f6d8bd05SEric Dumazet 	struct ip_options_rcu	*opt;
76f02db315SFrancesco Fusco 	__u8			ttl;
77f02db315SFrancesco Fusco 	__s16			tos;
78f02db315SFrancesco Fusco 	char			priority;
79bec1f6f6SWillem de Bruijn 	__u16			gso_size;
801da177e4SLinus Torvalds };
811da177e4SLinus Torvalds 
8235178206SWillem de Bruijn static inline void ipcm_init(struct ipcm_cookie *ipcm)
8335178206SWillem de Bruijn {
8435178206SWillem de Bruijn 	*ipcm = (struct ipcm_cookie) { .tos = -1 };
8535178206SWillem de Bruijn }
8635178206SWillem de Bruijn 
8735178206SWillem de Bruijn static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
8835178206SWillem de Bruijn 				const struct inet_sock *inet)
8935178206SWillem de Bruijn {
9035178206SWillem de Bruijn 	ipcm_init(ipcm);
9135178206SWillem de Bruijn 
92c6af0c22SWillem de Bruijn 	ipcm->sockc.mark = inet->sk.sk_mark;
9335178206SWillem de Bruijn 	ipcm->sockc.tsflags = inet->sk.sk_tsflags;
9435178206SWillem de Bruijn 	ipcm->oif = inet->sk.sk_bound_dev_if;
9535178206SWillem de Bruijn 	ipcm->addr = inet->inet_saddr;
9635178206SWillem de Bruijn }
9735178206SWillem de Bruijn 
981da177e4SLinus Torvalds #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
994b261c75SHannes Frederic Sowa #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb))
1001da177e4SLinus Torvalds 
101fb74c277SDavid Ahern /* return enslaved device index if relevant */
102*d6bb2d1eSEric Dumazet static inline int inet_sdif(const struct sk_buff *skb)
103fb74c277SDavid Ahern {
104fb74c277SDavid Ahern #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
105fb74c277SDavid Ahern 	if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags))
106fb74c277SDavid Ahern 		return IPCB(skb)->iif;
107fb74c277SDavid Ahern #endif
108fb74c277SDavid Ahern 	return 0;
109fb74c277SDavid Ahern }
110fb74c277SDavid Ahern 
1115796ef75SKirill Tkhai /* Special input handler for packets caught by router alert option.
1125796ef75SKirill Tkhai    They are selected only by protocol field, and then processed likely
1135796ef75SKirill Tkhai    local ones; but only if someone wants them! Otherwise, router
1145796ef75SKirill Tkhai    not running rsvpd will kill RSVP.
1155796ef75SKirill Tkhai 
1165796ef75SKirill Tkhai    It is user level problem, what it will make with them.
1175796ef75SKirill Tkhai    I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
1185796ef75SKirill Tkhai    but receiver should be enough clever f.e. to forward mtrace requests,
1195796ef75SKirill Tkhai    sent to multicast group to reach destination designated router.
1205796ef75SKirill Tkhai  */
1215796ef75SKirill Tkhai 
122fd2c3ef7SEric Dumazet struct ip_ra_chain {
12343a951e9SEric Dumazet 	struct ip_ra_chain __rcu *next;
1241da177e4SLinus Torvalds 	struct sock		*sk;
125592fcb9dSEric Dumazet 	union {
1261da177e4SLinus Torvalds 		void			(*destructor)(struct sock *);
127592fcb9dSEric Dumazet 		struct sock		*saved_sk;
128592fcb9dSEric Dumazet 	};
12966018506SEric Dumazet 	struct rcu_head		rcu;
1301da177e4SLinus Torvalds };
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds /* IP flags. */
1331da177e4SLinus Torvalds #define IP_CE		0x8000		/* Flag: "Congestion"		*/
1341da177e4SLinus Torvalds #define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
1351da177e4SLinus Torvalds #define IP_MF		0x2000		/* Flag: "More Fragments"	*/
1361da177e4SLinus Torvalds #define IP_OFFSET	0x1FFF		/* "Fragment Offset" part	*/
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds #define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/
1391da177e4SLinus Torvalds 
14014c85021SArnaldo Carvalho de Melo struct msghdr;
14114c85021SArnaldo Carvalho de Melo struct net_device;
14214c85021SArnaldo Carvalho de Melo struct packet_type;
14314c85021SArnaldo Carvalho de Melo struct rtable;
14414c85021SArnaldo Carvalho de Melo struct sockaddr;
14514c85021SArnaldo Carvalho de Melo 
14672c1d3bdSWANG Cong int igmp_mc_init(void);
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds /*
1491da177e4SLinus Torvalds  *	Functions provided by ip.c
1501da177e4SLinus Torvalds  */
1511da177e4SLinus Torvalds 
152cfe673b0SEric Dumazet int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
15313d8eaa0SAl Viro 			  __be32 saddr, __be32 daddr,
154de033b7dSWei Wang 			  struct ip_options_rcu *opt, u8 tos);
1555c3a0fd7SJoe Perches int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
1565c3a0fd7SJoe Perches 	   struct net_device *orig_dev);
15717266ee9SEdward Cree void ip_list_rcv(struct list_head *head, struct packet_type *pt,
15817266ee9SEdward Cree 		 struct net_device *orig_dev);
1595c3a0fd7SJoe Perches int ip_local_deliver(struct sk_buff *skb);
16068cb7d53SPaolo Abeni void ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int proto);
1615c3a0fd7SJoe Perches int ip_mr_input(struct sk_buff *skb);
162ede2059dSEric W. Biederman int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
163ede2059dSEric W. Biederman int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb);
164694869b3SEric W. Biederman int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
165694869b3SEric W. Biederman 		   int (*output)(struct net *, struct sock *, struct sk_buff *));
166c8b17be0SPablo Neira Ayuso 
167c8b17be0SPablo Neira Ayuso struct ip_fraglist_iter {
168c8b17be0SPablo Neira Ayuso 	struct sk_buff	*frag;
169c8b17be0SPablo Neira Ayuso 	struct iphdr	*iph;
170c8b17be0SPablo Neira Ayuso 	int		offset;
171c8b17be0SPablo Neira Ayuso 	unsigned int	hlen;
172c8b17be0SPablo Neira Ayuso };
173c8b17be0SPablo Neira Ayuso 
174c8b17be0SPablo Neira Ayuso void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph,
175c8b17be0SPablo Neira Ayuso 		      unsigned int hlen, struct ip_fraglist_iter *iter);
176c8b17be0SPablo Neira Ayuso void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter);
177c8b17be0SPablo Neira Ayuso 
178c8b17be0SPablo Neira Ayuso static inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter)
179c8b17be0SPablo Neira Ayuso {
180c8b17be0SPablo Neira Ayuso 	struct sk_buff *skb = iter->frag;
181c8b17be0SPablo Neira Ayuso 
182c8b17be0SPablo Neira Ayuso 	iter->frag = skb->next;
183c8b17be0SPablo Neira Ayuso 	skb_mark_not_on_list(skb);
184c8b17be0SPablo Neira Ayuso 
185c8b17be0SPablo Neira Ayuso 	return skb;
186c8b17be0SPablo Neira Ayuso }
187c8b17be0SPablo Neira Ayuso 
188065ff79fSPablo Neira Ayuso struct ip_frag_state {
189e7a409c3SEric Dumazet 	bool		DF;
190065ff79fSPablo Neira Ayuso 	unsigned int	hlen;
191065ff79fSPablo Neira Ayuso 	unsigned int	ll_rs;
192065ff79fSPablo Neira Ayuso 	unsigned int	mtu;
193065ff79fSPablo Neira Ayuso 	unsigned int	left;
194065ff79fSPablo Neira Ayuso 	int		offset;
195065ff79fSPablo Neira Ayuso 	int		ptr;
196065ff79fSPablo Neira Ayuso 	__be16		not_last_frag;
197065ff79fSPablo Neira Ayuso };
198065ff79fSPablo Neira Ayuso 
199065ff79fSPablo Neira Ayuso void ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs,
200e7a409c3SEric Dumazet 		  unsigned int mtu, bool DF, struct ip_frag_state *state);
201065ff79fSPablo Neira Ayuso struct sk_buff *ip_frag_next(struct sk_buff *skb,
202065ff79fSPablo Neira Ayuso 			     struct ip_frag_state *state);
203065ff79fSPablo Neira Ayuso 
2045c3a0fd7SJoe Perches void ip_send_check(struct iphdr *ip);
205cf91a99dSEric W. Biederman int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
20633224b16SEric W. Biederman int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
207aad88724SEric Dumazet 
20869b9e1e0SXin Long int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
20969b9e1e0SXin Long 		    __u8 tos);
2105c3a0fd7SJoe Perches void ip_init(void);
2115c3a0fd7SJoe Perches int ip_append_data(struct sock *sk, struct flowi4 *fl4,
2121da177e4SLinus Torvalds 		   int getfrag(void *from, char *to, int offset, int len,
2131da177e4SLinus Torvalds 			       int odd, struct sk_buff *skb),
2141da177e4SLinus Torvalds 		   void *from, int len, int protolen,
2151da177e4SLinus Torvalds 		   struct ipcm_cookie *ipc,
2162e77d89bSEric Dumazet 		   struct rtable **rt,
2171da177e4SLinus Torvalds 		   unsigned int flags);
2185c3a0fd7SJoe Perches int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd,
2195c3a0fd7SJoe Perches 		       struct sk_buff *skb);
2205c3a0fd7SJoe Perches ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
2211da177e4SLinus Torvalds 		       int offset, size_t size, int flags);
2225c3a0fd7SJoe Perches struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4,
2231c32c5adSHerbert Xu 			      struct sk_buff_head *queue,
2241c32c5adSHerbert Xu 			      struct inet_cork *cork);
2255c3a0fd7SJoe Perches int ip_send_skb(struct net *net, struct sk_buff *skb);
2265c3a0fd7SJoe Perches int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4);
2275c3a0fd7SJoe Perches void ip_flush_pending_frames(struct sock *sk);
2285c3a0fd7SJoe Perches struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
2295c3a0fd7SJoe Perches 			    int getfrag(void *from, char *to, int offset,
2305c3a0fd7SJoe Perches 					int len, int odd, struct sk_buff *skb),
2311c32c5adSHerbert Xu 			    void *from, int length, int transhdrlen,
2325c3a0fd7SJoe Perches 			    struct ipcm_cookie *ipc, struct rtable **rtp,
2331cd7884dSWillem de Bruijn 			    struct inet_cork *cork, unsigned int flags);
2341c32c5adSHerbert Xu 
23505e22e83SEric Dumazet int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
23669b9e1e0SXin Long 
23777968b78SDavid S. Miller static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
2381c32c5adSHerbert Xu {
23977968b78SDavid S. Miller 	return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
2401c32c5adSHerbert Xu }
2411da177e4SLinus Torvalds 
242aa661581SFrancesco Fusco static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet)
243aa661581SFrancesco Fusco {
244aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos);
245aa661581SFrancesco Fusco }
246aa661581SFrancesco Fusco 
247aa661581SFrancesco Fusco static inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk)
248aa661581SFrancesco Fusco {
249aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk);
250aa661581SFrancesco Fusco }
251aa661581SFrancesco Fusco 
2521da177e4SLinus Torvalds /* datagram.c */
25303645a11SEric Dumazet int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
2545c3a0fd7SJoe Perches int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
2551da177e4SLinus Torvalds 
2565c3a0fd7SJoe Perches void ip4_datagram_release_cb(struct sock *sk);
2578141ed9fSSteffen Klassert 
2581da177e4SLinus Torvalds struct ip_reply_arg {
2591da177e4SLinus Torvalds 	struct kvec iov[1];
26088ef4a5aSKOVACS Krisztian 	int	    flags;
261d6f5493cSAl Viro 	__wsum 	    csum;
2621da177e4SLinus Torvalds 	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
2631da177e4SLinus Torvalds 				/* -1 if not needed */
264f0e48dbfSPatrick McHardy 	int	    bound_dev_if;
26566b13d99SEric Dumazet 	u8  	    tos;
266e2d118a1SLorenzo Colitti 	kuid_t	    uid;
2671da177e4SLinus Torvalds };
2681da177e4SLinus Torvalds 
26988ef4a5aSKOVACS Krisztian #define IP_REPLY_ARG_NOSRCCHECK 1
27088ef4a5aSKOVACS Krisztian 
27186b08d86SKOVACS Krisztian static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
27286b08d86SKOVACS Krisztian {
27386b08d86SKOVACS Krisztian 	return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
27486b08d86SKOVACS Krisztian }
27586b08d86SKOVACS Krisztian 
276bdbbb852SEric Dumazet void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
27724a2d43dSEric Dumazet 			   const struct ip_options *sopt,
27824a2d43dSEric Dumazet 			   __be32 daddr, __be32 saddr,
27924a2d43dSEric Dumazet 			   const struct ip_reply_arg *arg,
280d6fb396cSEric Dumazet 			   unsigned int len, u64 transmit_time);
2811da177e4SLinus Torvalds 
2824ce3c183SEric Dumazet #define IP_INC_STATS(net, field)	SNMP_INC_STATS64((net)->mib.ip_statistics, field)
28313415e46SEric Dumazet #define __IP_INC_STATS(net, field)	__SNMP_INC_STATS64((net)->mib.ip_statistics, field)
2844ce3c183SEric Dumazet #define IP_ADD_STATS(net, field, val)	SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
28513415e46SEric Dumazet #define __IP_ADD_STATS(net, field, val) __SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
2864ce3c183SEric Dumazet #define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
28713415e46SEric Dumazet #define __IP_UPD_PO_STATS(net, field, val) __SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
28861a7e260SPavel Emelyanov #define NET_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.net_statistics, field)
28913415e46SEric Dumazet #define __NET_INC_STATS(net, field)	__SNMP_INC_STATS((net)->mib.net_statistics, field)
290f7324acdSDavid S. Miller #define NET_ADD_STATS(net, field, adnd)	SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
29113415e46SEric Dumazet #define __NET_ADD_STATS(net, field, adnd) __SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
2921da177e4SLinus Torvalds 
293c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offct);
294698365faSWANG Cong unsigned long snmp_fold_field(void __percpu *mib, int offt);
2954ce3c183SEric Dumazet #if BITS_PER_LONG==32
296c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
297c4c6bc31SRaghavendra K T 			 size_t syncp_offset);
298698365faSWANG Cong u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off);
2994ce3c183SEric Dumazet #else
300c4c6bc31SRaghavendra K T static inline u64  snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
301c4c6bc31SRaghavendra K T 					size_t syncp_offset)
302c4c6bc31SRaghavendra K T {
303c4c6bc31SRaghavendra K T 	return snmp_get_cpu_field(mib, cpu, offct);
304c4c6bc31SRaghavendra K T 
305c4c6bc31SRaghavendra K T }
306c4c6bc31SRaghavendra K T 
307698365faSWANG Cong static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off)
3084ce3c183SEric Dumazet {
3094ce3c183SEric Dumazet 	return snmp_fold_field(mib, offt);
3104ce3c183SEric Dumazet }
3114ce3c183SEric Dumazet #endif
31233490170SYOSHIFUJI Hideaki 
3136348ef2dSJia He #define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \
3146348ef2dSJia He { \
3156348ef2dSJia He 	int i, c; \
3166348ef2dSJia He 	for_each_possible_cpu(c) { \
3176348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
3186348ef2dSJia He 			buff64[i] += snmp_get_cpu_field64( \
3196348ef2dSJia He 					mib_statistic, \
3206348ef2dSJia He 					c, stats_list[i].entry, \
3216348ef2dSJia He 					offset); \
3226348ef2dSJia He 	} \
3236348ef2dSJia He }
3246348ef2dSJia He 
3256348ef2dSJia He #define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \
3266348ef2dSJia He { \
3276348ef2dSJia He 	int i, c; \
3286348ef2dSJia He 	for_each_possible_cpu(c) { \
3296348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
3306348ef2dSJia He 			buff[i] += snmp_get_cpu_field( \
3316348ef2dSJia He 						mib_statistic, \
3326348ef2dSJia He 						c, stats_list[i].entry); \
3336348ef2dSJia He 	} \
3346348ef2dSJia He }
3356348ef2dSJia He 
3360bbf87d8SEric W. Biederman void inet_get_local_port_range(struct net *net, int *low, int *high);
337227b60f5SStephen Hemminger 
338fcd77db0SDavid S. Miller #ifdef CONFIG_SYSCTL
33966e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port)
340e3826f1eSAmerigo Wang {
341122ff243SWANG Cong 	if (!net->ipv4.sysctl_local_reserved_ports)
34230429fbaSMaciej Żenczykowski 		return false;
343122ff243SWANG Cong 	return test_bit(port, net->ipv4.sysctl_local_reserved_ports);
344e3826f1eSAmerigo Wang }
34520e61da7SWANG Cong 
34620e61da7SWANG Cong static inline bool sysctl_dev_name_is_allowed(const char *name)
34720e61da7SWANG Cong {
34820e61da7SWANG Cong 	return strcmp(name, "default") != 0  && strcmp(name, "all") != 0;
34920e61da7SWANG Cong }
35020e61da7SWANG Cong 
35182f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
3524548b683SKrister Johansen {
35382f31ebfSMaciej Żenczykowski 	return port < net->ipv4.sysctl_ip_prot_sock;
3544548b683SKrister Johansen }
3554548b683SKrister Johansen 
356122ff243SWANG Cong #else
35766e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port)
358122ff243SWANG Cong {
35930429fbaSMaciej Żenczykowski 	return false;
360122ff243SWANG Cong }
3614548b683SKrister Johansen 
36282f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
3634548b683SKrister Johansen {
36482f31ebfSMaciej Żenczykowski 	return port < PROT_SOCK;
3654548b683SKrister Johansen }
366122ff243SWANG Cong #endif
367e3826f1eSAmerigo Wang 
368822c8685SDeepa Dinamani __be32 inet_current_timestamp(void);
369822c8685SDeepa Dinamani 
37020380731SArnaldo Carvalho de Melo /* From inetpeer.c */
37120380731SArnaldo Carvalho de Melo extern int inet_peer_threshold;
37220380731SArnaldo Carvalho de Melo extern int inet_peer_minttl;
37320380731SArnaldo Carvalho de Melo extern int inet_peer_maxttl;
37420380731SArnaldo Carvalho de Melo 
3755c3a0fd7SJoe Perches void ipfrag_init(void);
37620380731SArnaldo Carvalho de Melo 
3775c3a0fd7SJoe Perches void ip_static_sysctl_init(void);
378bd7b1533SAl Viro 
379e110861fSLorenzo Colitti #define IP4_REPLY_MARK(net, mark) \
380e110861fSLorenzo Colitti 	((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
381e110861fSLorenzo Colitti 
382d18cd551SDavid S. Miller static inline bool ip_is_fragment(const struct iphdr *iph)
383d18cd551SDavid S. Miller {
384d18cd551SDavid S. Miller 	return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
385d18cd551SDavid S. Miller }
386d18cd551SDavid S. Miller 
3871da177e4SLinus Torvalds #ifdef CONFIG_INET
38814c85021SArnaldo Carvalho de Melo #include <net/dst.h>
38914c85021SArnaldo Carvalho de Melo 
3901da177e4SLinus Torvalds /* The function in 2.2 was invalid, producing wrong result for
3911da177e4SLinus Torvalds  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
3921da177e4SLinus Torvalds static inline
3931da177e4SLinus Torvalds int ip_decrease_ttl(struct iphdr *iph)
3941da177e4SLinus Torvalds {
3955c78f275SAl Viro 	u32 check = (__force u32)iph->check;
3965c78f275SAl Viro 	check += (__force u32)htons(0x0100);
3975c78f275SAl Viro 	iph->check = (__force __sum16)(check + (check>=0xFFFF));
3981da177e4SLinus Torvalds 	return --iph->ttl;
3991da177e4SLinus Torvalds }
4001da177e4SLinus Torvalds 
401d52e5a7eSSabrina Dubroca static inline int ip_mtu_locked(const struct dst_entry *dst)
402d52e5a7eSSabrina Dubroca {
403d52e5a7eSSabrina Dubroca 	const struct rtable *rt = (const struct rtable *)dst;
404d52e5a7eSSabrina Dubroca 
405d52e5a7eSSabrina Dubroca 	return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
406d52e5a7eSSabrina Dubroca }
407d52e5a7eSSabrina Dubroca 
4081da177e4SLinus Torvalds static inline
4094e3f5d72SEric Dumazet int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
4101da177e4SLinus Torvalds {
4114e3f5d72SEric Dumazet 	u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc);
4124e3f5d72SEric Dumazet 
4134e3f5d72SEric Dumazet 	return  pmtudisc == IP_PMTUDISC_DO ||
4144e3f5d72SEric Dumazet 		(pmtudisc == IP_PMTUDISC_WANT &&
415d52e5a7eSSabrina Dubroca 		 !ip_mtu_locked(dst));
4161da177e4SLinus Torvalds }
4171da177e4SLinus Torvalds 
418f87c10a8SHannes Frederic Sowa static inline bool ip_sk_accept_pmtu(const struct sock *sk)
419f87c10a8SHannes Frederic Sowa {
4201b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE &&
4211b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT;
422f87c10a8SHannes Frederic Sowa }
423f87c10a8SHannes Frederic Sowa 
424f87c10a8SHannes Frederic Sowa static inline bool ip_sk_use_pmtu(const struct sock *sk)
425f87c10a8SHannes Frederic Sowa {
426f87c10a8SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE;
427f87c10a8SHannes Frederic Sowa }
428f87c10a8SHannes Frederic Sowa 
42960ff7467SWANG Cong static inline bool ip_sk_ignore_df(const struct sock *sk)
4301b346576SHannes Frederic Sowa {
4311b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO ||
4321b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT;
4331b346576SHannes Frederic Sowa }
4341b346576SHannes Frederic Sowa 
435f87c10a8SHannes Frederic Sowa static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
436f87c10a8SHannes Frederic Sowa 						    bool forwarding)
437f87c10a8SHannes Frederic Sowa {
438f87c10a8SHannes Frederic Sowa 	struct net *net = dev_net(dst->dev);
43902a1b175SMaciej Żenczykowski 	unsigned int mtu;
440f87c10a8SHannes Frederic Sowa 
441f87c10a8SHannes Frederic Sowa 	if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
442d52e5a7eSSabrina Dubroca 	    ip_mtu_locked(dst) ||
443f87c10a8SHannes Frederic Sowa 	    !forwarding)
444f87c10a8SHannes Frederic Sowa 		return dst_mtu(dst);
445f87c10a8SHannes Frederic Sowa 
44602a1b175SMaciej Żenczykowski 	/* 'forwarding = true' case should always honour route mtu */
44702a1b175SMaciej Żenczykowski 	mtu = dst_metric_raw(dst, RTAX_MTU);
44802a1b175SMaciej Żenczykowski 	if (mtu)
44902a1b175SMaciej Żenczykowski 		return mtu;
45002a1b175SMaciej Żenczykowski 
451c780a049SEric Dumazet 	return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
452f87c10a8SHannes Frederic Sowa }
453f87c10a8SHannes Frederic Sowa 
454fedbb6b4SShmulik Ladkani static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
455fedbb6b4SShmulik Ladkani 					  const struct sk_buff *skb)
456f87c10a8SHannes Frederic Sowa {
457caf3f267SEric Dumazet 	if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) {
458f87c10a8SHannes Frederic Sowa 		bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED;
459caf3f267SEric Dumazet 
460f87c10a8SHannes Frederic Sowa 		return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
461f87c10a8SHannes Frederic Sowa 	}
462caf3f267SEric Dumazet 
463c780a049SEric Dumazet 	return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
464f87c10a8SHannes Frederic Sowa }
465f87c10a8SHannes Frederic Sowa 
466767a2217SDavid Ahern struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
467d7e774f3SDavid Ahern 					int fc_mx_len,
468d7e774f3SDavid Ahern 					struct netlink_ext_ack *extack);
469cc5f0eb2SDavid Ahern static inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics)
470cc5f0eb2SDavid Ahern {
471cc5f0eb2SDavid Ahern 	if (fib_metrics != &dst_default_metrics &&
472cc5f0eb2SDavid Ahern 	    refcount_dec_and_test(&fib_metrics->refcnt))
473cc5f0eb2SDavid Ahern 		kfree(fib_metrics);
474cc5f0eb2SDavid Ahern }
475a919525aSDavid Ahern 
476e1255ed4SDavid Ahern /* ipv4 and ipv6 both use refcounted metrics if it is not the default */
477e1255ed4SDavid Ahern static inline
478e1255ed4SDavid Ahern void ip_dst_init_metrics(struct dst_entry *dst, struct dst_metrics *fib_metrics)
479e1255ed4SDavid Ahern {
480e1255ed4SDavid Ahern 	dst_init_metrics(dst, fib_metrics->metrics, true);
481e1255ed4SDavid Ahern 
482e1255ed4SDavid Ahern 	if (fib_metrics != &dst_default_metrics) {
483e1255ed4SDavid Ahern 		dst->_metrics |= DST_METRICS_REFCOUNTED;
484e1255ed4SDavid Ahern 		refcount_inc(&fib_metrics->refcnt);
485e1255ed4SDavid Ahern 	}
486e1255ed4SDavid Ahern }
487e1255ed4SDavid Ahern 
4881620a336SDavid Ahern static inline
4891620a336SDavid Ahern void ip_dst_metrics_put(struct dst_entry *dst)
4901620a336SDavid Ahern {
4911620a336SDavid Ahern 	struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
4921620a336SDavid Ahern 
4931620a336SDavid Ahern 	if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
4941620a336SDavid Ahern 		kfree(p);
4951620a336SDavid Ahern }
4961620a336SDavid Ahern 
49704ca6973SEric Dumazet u32 ip_idents_reserve(u32 hash, int segs);
498b6a7719aSHannes Frederic Sowa void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
49973f156a6SEric Dumazet 
500b6a7719aSHannes Frederic Sowa static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
501b6a7719aSHannes Frederic Sowa 					struct sock *sk, int segs)
5021da177e4SLinus Torvalds {
503703133deSAnsis Atteka 	struct iphdr *iph = ip_hdr(skb);
504703133deSAnsis Atteka 
50560ff7467SWANG Cong 	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
5061da177e4SLinus Torvalds 		/* This is only to work around buggy Windows95/2000
5071da177e4SLinus Torvalds 		 * VJ compression implementations.  If the ID field
5081da177e4SLinus Torvalds 		 * does not change, they drop every other packet in
5091da177e4SLinus Torvalds 		 * a TCP stream using header compression.
5101da177e4SLinus Torvalds 		 */
511c720c7e8SEric Dumazet 		if (sk && inet_sk(sk)->inet_daddr) {
512c720c7e8SEric Dumazet 			iph->id = htons(inet_sk(sk)->inet_id);
51373f156a6SEric Dumazet 			inet_sk(sk)->inet_id += segs;
51473f156a6SEric Dumazet 		} else {
5151da177e4SLinus Torvalds 			iph->id = 0;
51673f156a6SEric Dumazet 		}
51773f156a6SEric Dumazet 	} else {
518b6a7719aSHannes Frederic Sowa 		__ip_select_ident(net, iph, segs);
51973f156a6SEric Dumazet 	}
52073f156a6SEric Dumazet }
52173f156a6SEric Dumazet 
522b6a7719aSHannes Frederic Sowa static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
523b6a7719aSHannes Frederic Sowa 				   struct sock *sk)
52473f156a6SEric Dumazet {
525b6a7719aSHannes Frederic Sowa 	ip_select_ident_segs(net, skb, sk, 1);
5261da177e4SLinus Torvalds }
5271da177e4SLinus Torvalds 
528ed70fcfcSTom Herbert static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto)
529ed70fcfcSTom Herbert {
530ed70fcfcSTom Herbert 	return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
531ed70fcfcSTom Herbert 				  skb->len, proto, 0);
532ed70fcfcSTom Herbert }
533ed70fcfcSTom Herbert 
534c3f83241STom Herbert /* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store
535c3f83241STom Herbert  * Equivalent to :	flow->v4addrs.src = iph->saddr;
536c3f83241STom Herbert  *			flow->v4addrs.dst = iph->daddr;
537c3f83241STom Herbert  */
538c3f83241STom Herbert static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
539c3f83241STom Herbert 					    const struct iphdr *iph)
540c3f83241STom Herbert {
541c3f83241STom Herbert 	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
542c3f83241STom Herbert 		     offsetof(typeof(flow->addrs), v4addrs.src) +
543c3f83241STom Herbert 			      sizeof(flow->addrs.v4addrs.src));
544c3f83241STom Herbert 	memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
545c3f83241STom Herbert 	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
546c3f83241STom Herbert }
547c3f83241STom Herbert 
5481933a785STom Herbert static inline __wsum inet_gro_compute_pseudo(struct sk_buff *skb, int proto)
5491933a785STom Herbert {
5501933a785STom Herbert 	const struct iphdr *iph = skb_gro_network_header(skb);
5511933a785STom Herbert 
5521933a785STom Herbert 	return csum_tcpudp_nofold(iph->saddr, iph->daddr,
5531933a785STom Herbert 				  skb_gro_len(skb), proto, 0);
5541933a785STom Herbert }
5551933a785STom Herbert 
5561da177e4SLinus Torvalds /*
5571da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type ethernet.
5581da177e4SLinus Torvalds  */
5591da177e4SLinus Torvalds 
560714e85beSAl Viro static inline void ip_eth_mc_map(__be32 naddr, char *buf)
5611da177e4SLinus Torvalds {
562714e85beSAl Viro 	__u32 addr=ntohl(naddr);
5631da177e4SLinus Torvalds 	buf[0]=0x01;
5641da177e4SLinus Torvalds 	buf[1]=0x00;
5651da177e4SLinus Torvalds 	buf[2]=0x5e;
5661da177e4SLinus Torvalds 	buf[5]=addr&0xFF;
5671da177e4SLinus Torvalds 	addr>>=8;
5681da177e4SLinus Torvalds 	buf[4]=addr&0xFF;
5691da177e4SLinus Torvalds 	addr>>=8;
5701da177e4SLinus Torvalds 	buf[3]=addr&0x7F;
5711da177e4SLinus Torvalds }
5721da177e4SLinus Torvalds 
5731da177e4SLinus Torvalds /*
5741da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type IP-over-InfiniBand.
5751da177e4SLinus Torvalds  *	Leave P_Key as 0 to be filled in by driver.
5761da177e4SLinus Torvalds  */
5771da177e4SLinus Torvalds 
578a9e527e3SRolf Manderscheid static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
5791da177e4SLinus Torvalds {
580714e85beSAl Viro 	__u32 addr;
581a9e527e3SRolf Manderscheid 	unsigned char scope = broadcast[5] & 0xF;
582a9e527e3SRolf Manderscheid 
5831da177e4SLinus Torvalds 	buf[0]  = 0;		/* Reserved */
5841da177e4SLinus Torvalds 	buf[1]  = 0xff;		/* Multicast QPN */
5851da177e4SLinus Torvalds 	buf[2]  = 0xff;
5861da177e4SLinus Torvalds 	buf[3]  = 0xff;
587714e85beSAl Viro 	addr    = ntohl(naddr);
5881da177e4SLinus Torvalds 	buf[4]  = 0xff;
589a9e527e3SRolf Manderscheid 	buf[5]  = 0x10 | scope;	/* scope from broadcast address */
5901da177e4SLinus Torvalds 	buf[6]  = 0x40;		/* IPv4 signature */
5911da177e4SLinus Torvalds 	buf[7]  = 0x1b;
592a9e527e3SRolf Manderscheid 	buf[8]  = broadcast[8];		/* P_Key */
593a9e527e3SRolf Manderscheid 	buf[9]  = broadcast[9];
5941da177e4SLinus Torvalds 	buf[10] = 0;
5951da177e4SLinus Torvalds 	buf[11] = 0;
5961da177e4SLinus Torvalds 	buf[12] = 0;
5971da177e4SLinus Torvalds 	buf[13] = 0;
5981da177e4SLinus Torvalds 	buf[14] = 0;
5991da177e4SLinus Torvalds 	buf[15] = 0;
6001da177e4SLinus Torvalds 	buf[19] = addr & 0xff;
6011da177e4SLinus Torvalds 	addr  >>= 8;
6021da177e4SLinus Torvalds 	buf[18] = addr & 0xff;
6031da177e4SLinus Torvalds 	addr  >>= 8;
6041da177e4SLinus Torvalds 	buf[17] = addr & 0xff;
6051da177e4SLinus Torvalds 	addr  >>= 8;
6061da177e4SLinus Torvalds 	buf[16] = addr & 0x0f;
6071da177e4SLinus Torvalds }
6081da177e4SLinus Torvalds 
60993ca3bb5STimo Teräs static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
61093ca3bb5STimo Teräs {
61193ca3bb5STimo Teräs 	if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
61293ca3bb5STimo Teräs 		memcpy(buf, broadcast, 4);
61393ca3bb5STimo Teräs 	else
61493ca3bb5STimo Teräs 		memcpy(buf, &naddr, sizeof(naddr));
61593ca3bb5STimo Teräs }
61693ca3bb5STimo Teräs 
617dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
6181da177e4SLinus Torvalds #include <linux/ipv6.h>
6191da177e4SLinus Torvalds #endif
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds static __inline__ void inet_reset_saddr(struct sock *sk)
6221da177e4SLinus Torvalds {
623c720c7e8SEric Dumazet 	inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0;
624dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
6251da177e4SLinus Torvalds 	if (sk->sk_family == PF_INET6) {
6261da177e4SLinus Torvalds 		struct ipv6_pinfo *np = inet6_sk(sk);
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 		memset(&np->saddr, 0, sizeof(np->saddr));
629efe4208fSEric Dumazet 		memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr));
6301da177e4SLinus Torvalds 	}
6311da177e4SLinus Torvalds #endif
6321da177e4SLinus Torvalds }
6331da177e4SLinus Torvalds 
6341da177e4SLinus Torvalds #endif
6351da177e4SLinus Torvalds 
63672afa352SDavid Ahern static inline unsigned int ipv4_addr_hash(__be32 ip)
63772afa352SDavid Ahern {
63872afa352SDavid Ahern 	return (__force unsigned int) ip;
63972afa352SDavid Ahern }
64072afa352SDavid Ahern 
641f0b1e64cSMartin KaFai Lau static inline u32 ipv4_portaddr_hash(const struct net *net,
642f0b1e64cSMartin KaFai Lau 				     __be32 saddr,
643f0b1e64cSMartin KaFai Lau 				     unsigned int port)
644f0b1e64cSMartin KaFai Lau {
645f0b1e64cSMartin KaFai Lau 	return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;
646f0b1e64cSMartin KaFai Lau }
647f0b1e64cSMartin KaFai Lau 
6485c3a0fd7SJoe Perches bool ip_call_ra_chain(struct sk_buff *skb);
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds /*
651b798232fSRami Rosen  *	Functions provided by ip_fragment.c
6521da177e4SLinus Torvalds  */
6531da177e4SLinus Torvalds 
654fd2c3ef7SEric Dumazet enum ip_defrag_users {
6551da177e4SLinus Torvalds 	IP_DEFRAG_LOCAL_DELIVER,
6561da177e4SLinus Torvalds 	IP_DEFRAG_CALL_RA_CHAIN,
6571da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_IN,
6584be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_IN_END	= IP_DEFRAG_CONNTRACK_IN + USHRT_MAX,
6591da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_OUT,
6604be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_OUT_END	= IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX,
6618fa9ff68SPatrick McHardy 	IP_DEFRAG_CONNTRACK_BRIDGE_IN,
6624be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,
6631da177e4SLinus Torvalds 	IP_DEFRAG_VS_IN,
6641da177e4SLinus Torvalds 	IP_DEFRAG_VS_OUT,
665595fc71bSDavid S. Miller 	IP_DEFRAG_VS_FWD,
666595fc71bSDavid S. Miller 	IP_DEFRAG_AF_PACKET,
667bc416d97SEric Dumazet 	IP_DEFRAG_MACVLAN,
6681da177e4SLinus Torvalds };
6691da177e4SLinus Torvalds 
6705cf42280SAndy Zhou /* Return true if the value of 'user' is between 'lower_bond'
6715cf42280SAndy Zhou  * and 'upper_bond' inclusively.
6725cf42280SAndy Zhou  */
6735cf42280SAndy Zhou static inline bool ip_defrag_user_in_between(u32 user,
6745cf42280SAndy Zhou 					     enum ip_defrag_users lower_bond,
6755cf42280SAndy Zhou 					     enum ip_defrag_users upper_bond)
6765cf42280SAndy Zhou {
6775cf42280SAndy Zhou 	return user >= lower_bond && user <= upper_bond;
6785cf42280SAndy Zhou }
6795cf42280SAndy Zhou 
68019bcf9f2SEric W. Biederman int ip_defrag(struct net *net, struct sk_buff *skb, u32 user);
681bc416d97SEric Dumazet #ifdef CONFIG_INET
68219bcf9f2SEric W. Biederman struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user);
683bc416d97SEric Dumazet #else
68419bcf9f2SEric W. Biederman static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
685bc416d97SEric Dumazet {
686bc416d97SEric Dumazet 	return skb;
687bc416d97SEric Dumazet }
688bc416d97SEric Dumazet #endif
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds /*
6911da177e4SLinus Torvalds  *	Functions provided by ip_forward.c
6921da177e4SLinus Torvalds  */
6931da177e4SLinus Torvalds 
6945c3a0fd7SJoe Perches int ip_forward(struct sk_buff *skb);
6951da177e4SLinus Torvalds 
6961da177e4SLinus Torvalds /*
6971da177e4SLinus Torvalds  *	Functions provided by ip_options.c
6981da177e4SLinus Torvalds  */
6991da177e4SLinus Torvalds 
7005c3a0fd7SJoe Perches void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
701f6d8bd05SEric Dumazet 		      __be32 daddr, struct rtable *rt, int is_frag);
70224a2d43dSEric Dumazet 
70391ed1e66SPaolo Abeni int __ip_options_echo(struct net *net, struct ip_options *dopt,
70491ed1e66SPaolo Abeni 		      struct sk_buff *skb, const struct ip_options *sopt);
70591ed1e66SPaolo Abeni static inline int ip_options_echo(struct net *net, struct ip_options *dopt,
70691ed1e66SPaolo Abeni 				  struct sk_buff *skb)
70724a2d43dSEric Dumazet {
70891ed1e66SPaolo Abeni 	return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt);
70924a2d43dSEric Dumazet }
71024a2d43dSEric Dumazet 
7115c3a0fd7SJoe Perches void ip_options_fragment(struct sk_buff *skb);
7123da1ed7aSNazarov Sergey int __ip_options_compile(struct net *net, struct ip_options *opt,
7133da1ed7aSNazarov Sergey 			 struct sk_buff *skb, __be32 *info);
7145c3a0fd7SJoe Perches int ip_options_compile(struct net *net, struct ip_options *opt,
7155c3a0fd7SJoe Perches 		       struct sk_buff *skb);
7165c3a0fd7SJoe Perches int ip_options_get(struct net *net, struct ip_options_rcu **optp,
717de40a3e8SChristoph Hellwig 		   sockptr_t data, int optlen);
7185c3a0fd7SJoe Perches void ip_options_undo(struct ip_options *opt);
7195c3a0fd7SJoe Perches void ip_forward_options(struct sk_buff *skb);
7208c83f2dfSStephen Suryaputra int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds /*
7231da177e4SLinus Torvalds  *	Functions provided by ip_sockglue.c
7241da177e4SLinus Torvalds  */
7251da177e4SLinus Torvalds 
726fbf8866dSShawn Bohrer void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
727ad959036SPaolo Abeni void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
728ad959036SPaolo Abeni 			 struct sk_buff *skb, int tlen, int offset);
72924025c46SSoheil Hassas Yeganeh int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
730c8e6ad08SHannes Frederic Sowa 		 struct ipcm_cookie *ipc, bool allow_ipv6);
731a7b75c5aSChristoph Hellwig int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
7325c3a0fd7SJoe Perches 		  unsigned int optlen);
7335c3a0fd7SJoe Perches int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
7345c3a0fd7SJoe Perches 		  int __user *optlen);
7355c3a0fd7SJoe Perches int ip_ra_control(struct sock *sk, unsigned char on,
7365c3a0fd7SJoe Perches 		  void (*destructor)(struct sock *));
7371da177e4SLinus Torvalds 
73885fbaa75SHannes Frederic Sowa int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
7395c3a0fd7SJoe Perches void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
7405c3a0fd7SJoe Perches 		   u32 info, u8 *payload);
7415c3a0fd7SJoe Perches void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
7421da177e4SLinus Torvalds 		    u32 info);
7431da177e4SLinus Torvalds 
7445961de9fSTom Herbert static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
7455961de9fSTom Herbert {
746ad959036SPaolo Abeni 	ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
7475961de9fSTom Herbert }
7485961de9fSTom Herbert 
7494cdf507dSEric Dumazet bool icmp_global_allow(void);
7504cdf507dSEric Dumazet extern int sysctl_icmp_msgs_per_sec;
7514cdf507dSEric Dumazet extern int sysctl_icmp_msgs_burst;
7524cdf507dSEric Dumazet 
75320380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS
7545c3a0fd7SJoe Perches int ip_misc_proc_init(void);
75520380731SArnaldo Carvalho de Melo #endif
75620380731SArnaldo Carvalho de Melo 
7575e1a99eaSHangbin Liu int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family,
758404eb77eSRoopa Prabhu 				struct netlink_ext_ack *extack);
759404eb77eSRoopa Prabhu 
760501a90c9SEric Dumazet static inline bool inetdev_valid_mtu(unsigned int mtu)
761501a90c9SEric Dumazet {
762501a90c9SEric Dumazet 	return likely(mtu >= IPV4_MIN_MTU);
763501a90c9SEric Dumazet }
764501a90c9SEric Dumazet 
765c4e446bfSChristoph Hellwig void ip_sock_set_freebind(struct sock *sk);
7662de569bdSChristoph Hellwig int ip_sock_set_mtu_discover(struct sock *sk, int val);
767c1f9ec57SChristoph Hellwig void ip_sock_set_pktinfo(struct sock *sk);
768db45c0efSChristoph Hellwig void ip_sock_set_recverr(struct sock *sk);
7696ebf71baSChristoph Hellwig void ip_sock_set_tos(struct sock *sk, int val);
7706ebf71baSChristoph Hellwig 
7711da177e4SLinus Torvalds #endif	/* _IP_H */
772