xref: /openbmc/linux/include/net/ip.h (revision 1620a336)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
31da177e4SLinus Torvalds  *		operating system.  INET is implemented using the  BSD Socket
41da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *		Definitions for the IP module.
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Version:	@(#)ip.h	1.0.2	05/07/93
91da177e4SLinus Torvalds  *
1002c30a84SJesper Juhl  * Authors:	Ross Biro
111da177e4SLinus Torvalds  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
121da177e4SLinus Torvalds  *		Alan Cox, <gw4pts@gw4pts.ampr.org>
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  * Changes:
151da177e4SLinus Torvalds  *		Mike McLagan    :       Routing by source
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  *		This program is free software; you can redistribute it and/or
181da177e4SLinus Torvalds  *		modify it under the terms of the GNU General Public License
191da177e4SLinus Torvalds  *		as published by the Free Software Foundation; either version
201da177e4SLinus Torvalds  *		2 of the License, or (at your option) any later version.
211da177e4SLinus Torvalds  */
221da177e4SLinus Torvalds #ifndef _IP_H
231da177e4SLinus Torvalds #define _IP_H
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #include <linux/types.h>
261da177e4SLinus Torvalds #include <linux/ip.h>
271da177e4SLinus Torvalds #include <linux/in.h>
28c9bdd4b5SArnaldo Carvalho de Melo #include <linux/skbuff.h>
29f0b1e64cSMartin KaFai Lau #include <linux/jhash.h>
3014c85021SArnaldo Carvalho de Melo 
3114c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h>
32aa661581SFrancesco Fusco #include <net/route.h>
331da177e4SLinus Torvalds #include <net/snmp.h>
3486b08d86SKOVACS Krisztian #include <net/flow.h>
351bd758ebSJiri Pirko #include <net/flow_dissector.h>
36f0b1e64cSMartin KaFai Lau #include <net/netns/hash.h>
371da177e4SLinus Torvalds 
387ed14d97SGao Feng #define IPV4_MAX_PMTU		65535U		/* RFC 2675, Section 5.1 */
39b5476022SEric Dumazet #define IPV4_MIN_MTU		68			/* RFC 791 */
407ed14d97SGao Feng 
411da177e4SLinus Torvalds struct sock;
421da177e4SLinus Torvalds 
43fd2c3ef7SEric Dumazet struct inet_skb_parm {
440b922b7aSDavid Ahern 	int			iif;
451da177e4SLinus Torvalds 	struct ip_options	opt;		/* Compiled IP options		*/
46a04a480dSDavid Ahern 	u16			flags;
471da177e4SLinus Torvalds 
48df4d9254SHannes Frederic Sowa #define IPSKB_FORWARDED		BIT(0)
49df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TUNNEL_SIZE	BIT(1)
50df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TRANSFORMED	BIT(2)
51df4d9254SHannes Frederic Sowa #define IPSKB_FRAG_COMPLETE	BIT(3)
52df4d9254SHannes Frederic Sowa #define IPSKB_REROUTED		BIT(4)
53df4d9254SHannes Frederic Sowa #define IPSKB_DOREDIRECT	BIT(5)
54d6b915e2SFlorian Westphal #define IPSKB_FRAG_PMTU		BIT(6)
559ee6c5dcSLance Richardson #define IPSKB_L3SLAVE		BIT(7)
565f2d04f1SPatrick McHardy 
575f2d04f1SPatrick McHardy 	u16			frag_max_size;
581da177e4SLinus Torvalds };
591da177e4SLinus Torvalds 
60a04a480dSDavid Ahern static inline bool ipv4_l3mdev_skb(u16 flags)
61a04a480dSDavid Ahern {
62a04a480dSDavid Ahern 	return !!(flags & IPSKB_L3SLAVE);
63a04a480dSDavid Ahern }
64a04a480dSDavid Ahern 
65c9bdd4b5SArnaldo Carvalho de Melo static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
66c9bdd4b5SArnaldo Carvalho de Melo {
67eddc9ec5SArnaldo Carvalho de Melo 	return ip_hdr(skb)->ihl * 4;
68c9bdd4b5SArnaldo Carvalho de Melo }
69c9bdd4b5SArnaldo Carvalho de Melo 
70fd2c3ef7SEric Dumazet struct ipcm_cookie {
7124025c46SSoheil Hassas Yeganeh 	struct sockcm_cookie	sockc;
72c1d18f9fSAl Viro 	__be32			addr;
731da177e4SLinus Torvalds 	int			oif;
74f6d8bd05SEric Dumazet 	struct ip_options_rcu	*opt;
75f02db315SFrancesco Fusco 	__u8			ttl;
76f02db315SFrancesco Fusco 	__s16			tos;
77f02db315SFrancesco Fusco 	char			priority;
78bec1f6f6SWillem de Bruijn 	__u16			gso_size;
791da177e4SLinus Torvalds };
801da177e4SLinus Torvalds 
8135178206SWillem de Bruijn static inline void ipcm_init(struct ipcm_cookie *ipcm)
8235178206SWillem de Bruijn {
8335178206SWillem de Bruijn 	*ipcm = (struct ipcm_cookie) { .tos = -1 };
8435178206SWillem de Bruijn }
8535178206SWillem de Bruijn 
8635178206SWillem de Bruijn static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
8735178206SWillem de Bruijn 				const struct inet_sock *inet)
8835178206SWillem de Bruijn {
8935178206SWillem de Bruijn 	ipcm_init(ipcm);
9035178206SWillem de Bruijn 
9135178206SWillem de Bruijn 	ipcm->sockc.tsflags = inet->sk.sk_tsflags;
9235178206SWillem de Bruijn 	ipcm->oif = inet->sk.sk_bound_dev_if;
9335178206SWillem de Bruijn 	ipcm->addr = inet->inet_saddr;
9435178206SWillem de Bruijn }
9535178206SWillem de Bruijn 
961da177e4SLinus Torvalds #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
974b261c75SHannes Frederic Sowa #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb))
981da177e4SLinus Torvalds 
99fb74c277SDavid Ahern /* return enslaved device index if relevant */
100fb74c277SDavid Ahern static inline int inet_sdif(struct sk_buff *skb)
101fb74c277SDavid Ahern {
102fb74c277SDavid Ahern #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
103fb74c277SDavid Ahern 	if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags))
104fb74c277SDavid Ahern 		return IPCB(skb)->iif;
105fb74c277SDavid Ahern #endif
106fb74c277SDavid Ahern 	return 0;
107fb74c277SDavid Ahern }
108fb74c277SDavid Ahern 
1095796ef75SKirill Tkhai /* Special input handler for packets caught by router alert option.
1105796ef75SKirill Tkhai    They are selected only by protocol field, and then processed likely
1115796ef75SKirill Tkhai    local ones; but only if someone wants them! Otherwise, router
1125796ef75SKirill Tkhai    not running rsvpd will kill RSVP.
1135796ef75SKirill Tkhai 
1145796ef75SKirill Tkhai    It is user level problem, what it will make with them.
1155796ef75SKirill Tkhai    I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
1165796ef75SKirill Tkhai    but receiver should be enough clever f.e. to forward mtrace requests,
1175796ef75SKirill Tkhai    sent to multicast group to reach destination designated router.
1185796ef75SKirill Tkhai  */
1195796ef75SKirill Tkhai 
120fd2c3ef7SEric Dumazet struct ip_ra_chain {
12143a951e9SEric Dumazet 	struct ip_ra_chain __rcu *next;
1221da177e4SLinus Torvalds 	struct sock		*sk;
123592fcb9dSEric Dumazet 	union {
1241da177e4SLinus Torvalds 		void			(*destructor)(struct sock *);
125592fcb9dSEric Dumazet 		struct sock		*saved_sk;
126592fcb9dSEric Dumazet 	};
12766018506SEric Dumazet 	struct rcu_head		rcu;
1281da177e4SLinus Torvalds };
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds /* IP flags. */
1311da177e4SLinus Torvalds #define IP_CE		0x8000		/* Flag: "Congestion"		*/
1321da177e4SLinus Torvalds #define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
1331da177e4SLinus Torvalds #define IP_MF		0x2000		/* Flag: "More Fragments"	*/
1341da177e4SLinus Torvalds #define IP_OFFSET	0x1FFF		/* "Fragment Offset" part	*/
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds #define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/
1371da177e4SLinus Torvalds 
13814c85021SArnaldo Carvalho de Melo struct msghdr;
13914c85021SArnaldo Carvalho de Melo struct net_device;
14014c85021SArnaldo Carvalho de Melo struct packet_type;
14114c85021SArnaldo Carvalho de Melo struct rtable;
14214c85021SArnaldo Carvalho de Melo struct sockaddr;
14314c85021SArnaldo Carvalho de Melo 
14472c1d3bdSWANG Cong int igmp_mc_init(void);
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds /*
1471da177e4SLinus Torvalds  *	Functions provided by ip.c
1481da177e4SLinus Torvalds  */
1491da177e4SLinus Torvalds 
150cfe673b0SEric Dumazet int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
15113d8eaa0SAl Viro 			  __be32 saddr, __be32 daddr,
152f6d8bd05SEric Dumazet 			  struct ip_options_rcu *opt);
1535c3a0fd7SJoe Perches int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
1545c3a0fd7SJoe Perches 	   struct net_device *orig_dev);
15517266ee9SEdward Cree void ip_list_rcv(struct list_head *head, struct packet_type *pt,
15617266ee9SEdward Cree 		 struct net_device *orig_dev);
1575c3a0fd7SJoe Perches int ip_local_deliver(struct sk_buff *skb);
1585c3a0fd7SJoe Perches int ip_mr_input(struct sk_buff *skb);
159ede2059dSEric W. Biederman int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
160ede2059dSEric W. Biederman int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb);
161694869b3SEric W. Biederman int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
162694869b3SEric W. Biederman 		   int (*output)(struct net *, struct sock *, struct sk_buff *));
1635c3a0fd7SJoe Perches void ip_send_check(struct iphdr *ip);
164cf91a99dSEric W. Biederman int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
16533224b16SEric W. Biederman int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
166aad88724SEric Dumazet 
16769b9e1e0SXin Long int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
16869b9e1e0SXin Long 		    __u8 tos);
1695c3a0fd7SJoe Perches void ip_init(void);
1705c3a0fd7SJoe Perches int ip_append_data(struct sock *sk, struct flowi4 *fl4,
1711da177e4SLinus Torvalds 		   int getfrag(void *from, char *to, int offset, int len,
1721da177e4SLinus Torvalds 			       int odd, struct sk_buff *skb),
1731da177e4SLinus Torvalds 		   void *from, int len, int protolen,
1741da177e4SLinus Torvalds 		   struct ipcm_cookie *ipc,
1752e77d89bSEric Dumazet 		   struct rtable **rt,
1761da177e4SLinus Torvalds 		   unsigned int flags);
1775c3a0fd7SJoe Perches int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd,
1785c3a0fd7SJoe Perches 		       struct sk_buff *skb);
1795c3a0fd7SJoe Perches ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
1801da177e4SLinus Torvalds 		       int offset, size_t size, int flags);
1815c3a0fd7SJoe Perches struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4,
1821c32c5adSHerbert Xu 			      struct sk_buff_head *queue,
1831c32c5adSHerbert Xu 			      struct inet_cork *cork);
1845c3a0fd7SJoe Perches int ip_send_skb(struct net *net, struct sk_buff *skb);
1855c3a0fd7SJoe Perches int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4);
1865c3a0fd7SJoe Perches void ip_flush_pending_frames(struct sock *sk);
1875c3a0fd7SJoe Perches struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
1885c3a0fd7SJoe Perches 			    int getfrag(void *from, char *to, int offset,
1895c3a0fd7SJoe Perches 					int len, int odd, struct sk_buff *skb),
1901c32c5adSHerbert Xu 			    void *from, int length, int transhdrlen,
1915c3a0fd7SJoe Perches 			    struct ipcm_cookie *ipc, struct rtable **rtp,
1921cd7884dSWillem de Bruijn 			    struct inet_cork *cork, unsigned int flags);
1931c32c5adSHerbert Xu 
19469b9e1e0SXin Long static inline int ip_queue_xmit(struct sock *sk, struct sk_buff *skb,
19569b9e1e0SXin Long 				struct flowi *fl)
19669b9e1e0SXin Long {
19769b9e1e0SXin Long 	return __ip_queue_xmit(sk, skb, fl, inet_sk(sk)->tos);
19869b9e1e0SXin Long }
19969b9e1e0SXin Long 
20077968b78SDavid S. Miller static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
2011c32c5adSHerbert Xu {
20277968b78SDavid S. Miller 	return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
2031c32c5adSHerbert Xu }
2041da177e4SLinus Torvalds 
205aa661581SFrancesco Fusco static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet)
206aa661581SFrancesco Fusco {
207aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos);
208aa661581SFrancesco Fusco }
209aa661581SFrancesco Fusco 
210aa661581SFrancesco Fusco static inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk)
211aa661581SFrancesco Fusco {
212aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk);
213aa661581SFrancesco Fusco }
214aa661581SFrancesco Fusco 
2151da177e4SLinus Torvalds /* datagram.c */
21603645a11SEric Dumazet int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
2175c3a0fd7SJoe Perches int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
2181da177e4SLinus Torvalds 
2195c3a0fd7SJoe Perches void ip4_datagram_release_cb(struct sock *sk);
2208141ed9fSSteffen Klassert 
2211da177e4SLinus Torvalds struct ip_reply_arg {
2221da177e4SLinus Torvalds 	struct kvec iov[1];
22388ef4a5aSKOVACS Krisztian 	int	    flags;
224d6f5493cSAl Viro 	__wsum 	    csum;
2251da177e4SLinus Torvalds 	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
2261da177e4SLinus Torvalds 				/* -1 if not needed */
227f0e48dbfSPatrick McHardy 	int	    bound_dev_if;
22866b13d99SEric Dumazet 	u8  	    tos;
229e2d118a1SLorenzo Colitti 	kuid_t	    uid;
2301da177e4SLinus Torvalds };
2311da177e4SLinus Torvalds 
23288ef4a5aSKOVACS Krisztian #define IP_REPLY_ARG_NOSRCCHECK 1
23388ef4a5aSKOVACS Krisztian 
23486b08d86SKOVACS Krisztian static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
23586b08d86SKOVACS Krisztian {
23686b08d86SKOVACS Krisztian 	return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
23786b08d86SKOVACS Krisztian }
23886b08d86SKOVACS Krisztian 
239bdbbb852SEric Dumazet void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
24024a2d43dSEric Dumazet 			   const struct ip_options *sopt,
24124a2d43dSEric Dumazet 			   __be32 daddr, __be32 saddr,
24224a2d43dSEric Dumazet 			   const struct ip_reply_arg *arg,
24370e73416SDavid S. Miller 			   unsigned int len);
2441da177e4SLinus Torvalds 
2454ce3c183SEric Dumazet #define IP_INC_STATS(net, field)	SNMP_INC_STATS64((net)->mib.ip_statistics, field)
24613415e46SEric Dumazet #define __IP_INC_STATS(net, field)	__SNMP_INC_STATS64((net)->mib.ip_statistics, field)
2474ce3c183SEric Dumazet #define IP_ADD_STATS(net, field, val)	SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
24813415e46SEric Dumazet #define __IP_ADD_STATS(net, field, val) __SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
2494ce3c183SEric Dumazet #define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
25013415e46SEric Dumazet #define __IP_UPD_PO_STATS(net, field, val) __SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
25161a7e260SPavel Emelyanov #define NET_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.net_statistics, field)
25213415e46SEric Dumazet #define __NET_INC_STATS(net, field)	__SNMP_INC_STATS((net)->mib.net_statistics, field)
253f7324acdSDavid S. Miller #define NET_ADD_STATS(net, field, adnd)	SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
25413415e46SEric Dumazet #define __NET_ADD_STATS(net, field, adnd) __SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
2551da177e4SLinus Torvalds 
256c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offct);
257698365faSWANG Cong unsigned long snmp_fold_field(void __percpu *mib, int offt);
2584ce3c183SEric Dumazet #if BITS_PER_LONG==32
259c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
260c4c6bc31SRaghavendra K T 			 size_t syncp_offset);
261698365faSWANG Cong u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off);
2624ce3c183SEric Dumazet #else
263c4c6bc31SRaghavendra K T static inline u64  snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
264c4c6bc31SRaghavendra K T 					size_t syncp_offset)
265c4c6bc31SRaghavendra K T {
266c4c6bc31SRaghavendra K T 	return snmp_get_cpu_field(mib, cpu, offct);
267c4c6bc31SRaghavendra K T 
268c4c6bc31SRaghavendra K T }
269c4c6bc31SRaghavendra K T 
270698365faSWANG Cong static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off)
2714ce3c183SEric Dumazet {
2724ce3c183SEric Dumazet 	return snmp_fold_field(mib, offt);
2734ce3c183SEric Dumazet }
2744ce3c183SEric Dumazet #endif
27533490170SYOSHIFUJI Hideaki 
2766348ef2dSJia He #define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \
2776348ef2dSJia He { \
2786348ef2dSJia He 	int i, c; \
2796348ef2dSJia He 	for_each_possible_cpu(c) { \
2806348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
2816348ef2dSJia He 			buff64[i] += snmp_get_cpu_field64( \
2826348ef2dSJia He 					mib_statistic, \
2836348ef2dSJia He 					c, stats_list[i].entry, \
2846348ef2dSJia He 					offset); \
2856348ef2dSJia He 	} \
2866348ef2dSJia He }
2876348ef2dSJia He 
2886348ef2dSJia He #define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \
2896348ef2dSJia He { \
2906348ef2dSJia He 	int i, c; \
2916348ef2dSJia He 	for_each_possible_cpu(c) { \
2926348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
2936348ef2dSJia He 			buff[i] += snmp_get_cpu_field( \
2946348ef2dSJia He 						mib_statistic, \
2956348ef2dSJia He 						c, stats_list[i].entry); \
2966348ef2dSJia He 	} \
2976348ef2dSJia He }
2986348ef2dSJia He 
2990bbf87d8SEric W. Biederman void inet_get_local_port_range(struct net *net, int *low, int *high);
300227b60f5SStephen Hemminger 
301fcd77db0SDavid S. Miller #ifdef CONFIG_SYSCTL
302122ff243SWANG Cong static inline int inet_is_local_reserved_port(struct net *net, int port)
303e3826f1eSAmerigo Wang {
304122ff243SWANG Cong 	if (!net->ipv4.sysctl_local_reserved_ports)
305122ff243SWANG Cong 		return 0;
306122ff243SWANG Cong 	return test_bit(port, net->ipv4.sysctl_local_reserved_ports);
307e3826f1eSAmerigo Wang }
30820e61da7SWANG Cong 
30920e61da7SWANG Cong static inline bool sysctl_dev_name_is_allowed(const char *name)
31020e61da7SWANG Cong {
31120e61da7SWANG Cong 	return strcmp(name, "default") != 0  && strcmp(name, "all") != 0;
31220e61da7SWANG Cong }
31320e61da7SWANG Cong 
3144548b683SKrister Johansen static inline int inet_prot_sock(struct net *net)
3154548b683SKrister Johansen {
3164548b683SKrister Johansen 	return net->ipv4.sysctl_ip_prot_sock;
3174548b683SKrister Johansen }
3184548b683SKrister Johansen 
319122ff243SWANG Cong #else
320122ff243SWANG Cong static inline int inet_is_local_reserved_port(struct net *net, int port)
321122ff243SWANG Cong {
322122ff243SWANG Cong 	return 0;
323122ff243SWANG Cong }
3244548b683SKrister Johansen 
3254548b683SKrister Johansen static inline int inet_prot_sock(struct net *net)
3264548b683SKrister Johansen {
3274548b683SKrister Johansen 	return PROT_SOCK;
3284548b683SKrister Johansen }
329122ff243SWANG Cong #endif
330e3826f1eSAmerigo Wang 
331822c8685SDeepa Dinamani __be32 inet_current_timestamp(void);
332822c8685SDeepa Dinamani 
33320380731SArnaldo Carvalho de Melo /* From inetpeer.c */
33420380731SArnaldo Carvalho de Melo extern int inet_peer_threshold;
33520380731SArnaldo Carvalho de Melo extern int inet_peer_minttl;
33620380731SArnaldo Carvalho de Melo extern int inet_peer_maxttl;
33720380731SArnaldo Carvalho de Melo 
3385c3a0fd7SJoe Perches void ipfrag_init(void);
33920380731SArnaldo Carvalho de Melo 
3405c3a0fd7SJoe Perches void ip_static_sysctl_init(void);
341bd7b1533SAl Viro 
342e110861fSLorenzo Colitti #define IP4_REPLY_MARK(net, mark) \
343e110861fSLorenzo Colitti 	((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
344e110861fSLorenzo Colitti 
345d18cd551SDavid S. Miller static inline bool ip_is_fragment(const struct iphdr *iph)
346d18cd551SDavid S. Miller {
347d18cd551SDavid S. Miller 	return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
348d18cd551SDavid S. Miller }
349d18cd551SDavid S. Miller 
3501da177e4SLinus Torvalds #ifdef CONFIG_INET
35114c85021SArnaldo Carvalho de Melo #include <net/dst.h>
35214c85021SArnaldo Carvalho de Melo 
3531da177e4SLinus Torvalds /* The function in 2.2 was invalid, producing wrong result for
3541da177e4SLinus Torvalds  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
3551da177e4SLinus Torvalds static inline
3561da177e4SLinus Torvalds int ip_decrease_ttl(struct iphdr *iph)
3571da177e4SLinus Torvalds {
3585c78f275SAl Viro 	u32 check = (__force u32)iph->check;
3595c78f275SAl Viro 	check += (__force u32)htons(0x0100);
3605c78f275SAl Viro 	iph->check = (__force __sum16)(check + (check>=0xFFFF));
3611da177e4SLinus Torvalds 	return --iph->ttl;
3621da177e4SLinus Torvalds }
3631da177e4SLinus Torvalds 
364d52e5a7eSSabrina Dubroca static inline int ip_mtu_locked(const struct dst_entry *dst)
365d52e5a7eSSabrina Dubroca {
366d52e5a7eSSabrina Dubroca 	const struct rtable *rt = (const struct rtable *)dst;
367d52e5a7eSSabrina Dubroca 
368d52e5a7eSSabrina Dubroca 	return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
369d52e5a7eSSabrina Dubroca }
370d52e5a7eSSabrina Dubroca 
3711da177e4SLinus Torvalds static inline
3724e3f5d72SEric Dumazet int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
3731da177e4SLinus Torvalds {
3744e3f5d72SEric Dumazet 	u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc);
3754e3f5d72SEric Dumazet 
3764e3f5d72SEric Dumazet 	return  pmtudisc == IP_PMTUDISC_DO ||
3774e3f5d72SEric Dumazet 		(pmtudisc == IP_PMTUDISC_WANT &&
378d52e5a7eSSabrina Dubroca 		 !ip_mtu_locked(dst));
3791da177e4SLinus Torvalds }
3801da177e4SLinus Torvalds 
381f87c10a8SHannes Frederic Sowa static inline bool ip_sk_accept_pmtu(const struct sock *sk)
382f87c10a8SHannes Frederic Sowa {
3831b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE &&
3841b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT;
385f87c10a8SHannes Frederic Sowa }
386f87c10a8SHannes Frederic Sowa 
387f87c10a8SHannes Frederic Sowa static inline bool ip_sk_use_pmtu(const struct sock *sk)
388f87c10a8SHannes Frederic Sowa {
389f87c10a8SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE;
390f87c10a8SHannes Frederic Sowa }
391f87c10a8SHannes Frederic Sowa 
39260ff7467SWANG Cong static inline bool ip_sk_ignore_df(const struct sock *sk)
3931b346576SHannes Frederic Sowa {
3941b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO ||
3951b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT;
3961b346576SHannes Frederic Sowa }
3971b346576SHannes Frederic Sowa 
398f87c10a8SHannes Frederic Sowa static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
399f87c10a8SHannes Frederic Sowa 						    bool forwarding)
400f87c10a8SHannes Frederic Sowa {
401f87c10a8SHannes Frederic Sowa 	struct net *net = dev_net(dst->dev);
402f87c10a8SHannes Frederic Sowa 
403f87c10a8SHannes Frederic Sowa 	if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
404d52e5a7eSSabrina Dubroca 	    ip_mtu_locked(dst) ||
405f87c10a8SHannes Frederic Sowa 	    !forwarding)
406f87c10a8SHannes Frederic Sowa 		return dst_mtu(dst);
407f87c10a8SHannes Frederic Sowa 
408c780a049SEric Dumazet 	return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
409f87c10a8SHannes Frederic Sowa }
410f87c10a8SHannes Frederic Sowa 
411fedbb6b4SShmulik Ladkani static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
412fedbb6b4SShmulik Ladkani 					  const struct sk_buff *skb)
413f87c10a8SHannes Frederic Sowa {
414caf3f267SEric Dumazet 	if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) {
415f87c10a8SHannes Frederic Sowa 		bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED;
416caf3f267SEric Dumazet 
417f87c10a8SHannes Frederic Sowa 		return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
418f87c10a8SHannes Frederic Sowa 	}
419caf3f267SEric Dumazet 
420c780a049SEric Dumazet 	return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
421f87c10a8SHannes Frederic Sowa }
422f87c10a8SHannes Frederic Sowa 
423767a2217SDavid Ahern struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
424767a2217SDavid Ahern 					int fc_mx_len);
425cc5f0eb2SDavid Ahern static inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics)
426cc5f0eb2SDavid Ahern {
427cc5f0eb2SDavid Ahern 	if (fib_metrics != &dst_default_metrics &&
428cc5f0eb2SDavid Ahern 	    refcount_dec_and_test(&fib_metrics->refcnt))
429cc5f0eb2SDavid Ahern 		kfree(fib_metrics);
430cc5f0eb2SDavid Ahern }
431a919525aSDavid Ahern 
432e1255ed4SDavid Ahern /* ipv4 and ipv6 both use refcounted metrics if it is not the default */
433e1255ed4SDavid Ahern static inline
434e1255ed4SDavid Ahern void ip_dst_init_metrics(struct dst_entry *dst, struct dst_metrics *fib_metrics)
435e1255ed4SDavid Ahern {
436e1255ed4SDavid Ahern 	dst_init_metrics(dst, fib_metrics->metrics, true);
437e1255ed4SDavid Ahern 
438e1255ed4SDavid Ahern 	if (fib_metrics != &dst_default_metrics) {
439e1255ed4SDavid Ahern 		dst->_metrics |= DST_METRICS_REFCOUNTED;
440e1255ed4SDavid Ahern 		refcount_inc(&fib_metrics->refcnt);
441e1255ed4SDavid Ahern 	}
442e1255ed4SDavid Ahern }
443e1255ed4SDavid Ahern 
4441620a336SDavid Ahern static inline
4451620a336SDavid Ahern void ip_dst_metrics_put(struct dst_entry *dst)
4461620a336SDavid Ahern {
4471620a336SDavid Ahern 	struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
4481620a336SDavid Ahern 
4491620a336SDavid Ahern 	if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
4501620a336SDavid Ahern 		kfree(p);
4511620a336SDavid Ahern }
4521620a336SDavid Ahern 
45304ca6973SEric Dumazet u32 ip_idents_reserve(u32 hash, int segs);
454b6a7719aSHannes Frederic Sowa void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
45573f156a6SEric Dumazet 
456b6a7719aSHannes Frederic Sowa static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
457b6a7719aSHannes Frederic Sowa 					struct sock *sk, int segs)
4581da177e4SLinus Torvalds {
459703133deSAnsis Atteka 	struct iphdr *iph = ip_hdr(skb);
460703133deSAnsis Atteka 
46160ff7467SWANG Cong 	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
4621da177e4SLinus Torvalds 		/* This is only to work around buggy Windows95/2000
4631da177e4SLinus Torvalds 		 * VJ compression implementations.  If the ID field
4641da177e4SLinus Torvalds 		 * does not change, they drop every other packet in
4651da177e4SLinus Torvalds 		 * a TCP stream using header compression.
4661da177e4SLinus Torvalds 		 */
467c720c7e8SEric Dumazet 		if (sk && inet_sk(sk)->inet_daddr) {
468c720c7e8SEric Dumazet 			iph->id = htons(inet_sk(sk)->inet_id);
46973f156a6SEric Dumazet 			inet_sk(sk)->inet_id += segs;
47073f156a6SEric Dumazet 		} else {
4711da177e4SLinus Torvalds 			iph->id = 0;
47273f156a6SEric Dumazet 		}
47373f156a6SEric Dumazet 	} else {
474b6a7719aSHannes Frederic Sowa 		__ip_select_ident(net, iph, segs);
47573f156a6SEric Dumazet 	}
47673f156a6SEric Dumazet }
47773f156a6SEric Dumazet 
478b6a7719aSHannes Frederic Sowa static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
479b6a7719aSHannes Frederic Sowa 				   struct sock *sk)
48073f156a6SEric Dumazet {
481b6a7719aSHannes Frederic Sowa 	ip_select_ident_segs(net, skb, sk, 1);
4821da177e4SLinus Torvalds }
4831da177e4SLinus Torvalds 
484ed70fcfcSTom Herbert static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto)
485ed70fcfcSTom Herbert {
486ed70fcfcSTom Herbert 	return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
487ed70fcfcSTom Herbert 				  skb->len, proto, 0);
488ed70fcfcSTom Herbert }
489ed70fcfcSTom Herbert 
490c3f83241STom Herbert /* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store
491c3f83241STom Herbert  * Equivalent to :	flow->v4addrs.src = iph->saddr;
492c3f83241STom Herbert  *			flow->v4addrs.dst = iph->daddr;
493c3f83241STom Herbert  */
494c3f83241STom Herbert static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
495c3f83241STom Herbert 					    const struct iphdr *iph)
496c3f83241STom Herbert {
497c3f83241STom Herbert 	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
498c3f83241STom Herbert 		     offsetof(typeof(flow->addrs), v4addrs.src) +
499c3f83241STom Herbert 			      sizeof(flow->addrs.v4addrs.src));
500c3f83241STom Herbert 	memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
501c3f83241STom Herbert 	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
502c3f83241STom Herbert }
503c3f83241STom Herbert 
5041933a785STom Herbert static inline __wsum inet_gro_compute_pseudo(struct sk_buff *skb, int proto)
5051933a785STom Herbert {
5061933a785STom Herbert 	const struct iphdr *iph = skb_gro_network_header(skb);
5071933a785STom Herbert 
5081933a785STom Herbert 	return csum_tcpudp_nofold(iph->saddr, iph->daddr,
5091933a785STom Herbert 				  skb_gro_len(skb), proto, 0);
5101933a785STom Herbert }
5111933a785STom Herbert 
5121da177e4SLinus Torvalds /*
5131da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type ethernet.
5141da177e4SLinus Torvalds  */
5151da177e4SLinus Torvalds 
516714e85beSAl Viro static inline void ip_eth_mc_map(__be32 naddr, char *buf)
5171da177e4SLinus Torvalds {
518714e85beSAl Viro 	__u32 addr=ntohl(naddr);
5191da177e4SLinus Torvalds 	buf[0]=0x01;
5201da177e4SLinus Torvalds 	buf[1]=0x00;
5211da177e4SLinus Torvalds 	buf[2]=0x5e;
5221da177e4SLinus Torvalds 	buf[5]=addr&0xFF;
5231da177e4SLinus Torvalds 	addr>>=8;
5241da177e4SLinus Torvalds 	buf[4]=addr&0xFF;
5251da177e4SLinus Torvalds 	addr>>=8;
5261da177e4SLinus Torvalds 	buf[3]=addr&0x7F;
5271da177e4SLinus Torvalds }
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds /*
5301da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type IP-over-InfiniBand.
5311da177e4SLinus Torvalds  *	Leave P_Key as 0 to be filled in by driver.
5321da177e4SLinus Torvalds  */
5331da177e4SLinus Torvalds 
534a9e527e3SRolf Manderscheid static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
5351da177e4SLinus Torvalds {
536714e85beSAl Viro 	__u32 addr;
537a9e527e3SRolf Manderscheid 	unsigned char scope = broadcast[5] & 0xF;
538a9e527e3SRolf Manderscheid 
5391da177e4SLinus Torvalds 	buf[0]  = 0;		/* Reserved */
5401da177e4SLinus Torvalds 	buf[1]  = 0xff;		/* Multicast QPN */
5411da177e4SLinus Torvalds 	buf[2]  = 0xff;
5421da177e4SLinus Torvalds 	buf[3]  = 0xff;
543714e85beSAl Viro 	addr    = ntohl(naddr);
5441da177e4SLinus Torvalds 	buf[4]  = 0xff;
545a9e527e3SRolf Manderscheid 	buf[5]  = 0x10 | scope;	/* scope from broadcast address */
5461da177e4SLinus Torvalds 	buf[6]  = 0x40;		/* IPv4 signature */
5471da177e4SLinus Torvalds 	buf[7]  = 0x1b;
548a9e527e3SRolf Manderscheid 	buf[8]  = broadcast[8];		/* P_Key */
549a9e527e3SRolf Manderscheid 	buf[9]  = broadcast[9];
5501da177e4SLinus Torvalds 	buf[10] = 0;
5511da177e4SLinus Torvalds 	buf[11] = 0;
5521da177e4SLinus Torvalds 	buf[12] = 0;
5531da177e4SLinus Torvalds 	buf[13] = 0;
5541da177e4SLinus Torvalds 	buf[14] = 0;
5551da177e4SLinus Torvalds 	buf[15] = 0;
5561da177e4SLinus Torvalds 	buf[19] = addr & 0xff;
5571da177e4SLinus Torvalds 	addr  >>= 8;
5581da177e4SLinus Torvalds 	buf[18] = addr & 0xff;
5591da177e4SLinus Torvalds 	addr  >>= 8;
5601da177e4SLinus Torvalds 	buf[17] = addr & 0xff;
5611da177e4SLinus Torvalds 	addr  >>= 8;
5621da177e4SLinus Torvalds 	buf[16] = addr & 0x0f;
5631da177e4SLinus Torvalds }
5641da177e4SLinus Torvalds 
56593ca3bb5STimo Teräs static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
56693ca3bb5STimo Teräs {
56793ca3bb5STimo Teräs 	if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
56893ca3bb5STimo Teräs 		memcpy(buf, broadcast, 4);
56993ca3bb5STimo Teräs 	else
57093ca3bb5STimo Teräs 		memcpy(buf, &naddr, sizeof(naddr));
57193ca3bb5STimo Teräs }
57293ca3bb5STimo Teräs 
573dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
5741da177e4SLinus Torvalds #include <linux/ipv6.h>
5751da177e4SLinus Torvalds #endif
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds static __inline__ void inet_reset_saddr(struct sock *sk)
5781da177e4SLinus Torvalds {
579c720c7e8SEric Dumazet 	inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0;
580dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
5811da177e4SLinus Torvalds 	if (sk->sk_family == PF_INET6) {
5821da177e4SLinus Torvalds 		struct ipv6_pinfo *np = inet6_sk(sk);
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds 		memset(&np->saddr, 0, sizeof(np->saddr));
585efe4208fSEric Dumazet 		memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr));
5861da177e4SLinus Torvalds 	}
5871da177e4SLinus Torvalds #endif
5881da177e4SLinus Torvalds }
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds #endif
5911da177e4SLinus Torvalds 
59272afa352SDavid Ahern static inline unsigned int ipv4_addr_hash(__be32 ip)
59372afa352SDavid Ahern {
59472afa352SDavid Ahern 	return (__force unsigned int) ip;
59572afa352SDavid Ahern }
59672afa352SDavid Ahern 
597f0b1e64cSMartin KaFai Lau static inline u32 ipv4_portaddr_hash(const struct net *net,
598f0b1e64cSMartin KaFai Lau 				     __be32 saddr,
599f0b1e64cSMartin KaFai Lau 				     unsigned int port)
600f0b1e64cSMartin KaFai Lau {
601f0b1e64cSMartin KaFai Lau 	return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;
602f0b1e64cSMartin KaFai Lau }
603f0b1e64cSMartin KaFai Lau 
6045c3a0fd7SJoe Perches bool ip_call_ra_chain(struct sk_buff *skb);
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds /*
607b798232fSRami Rosen  *	Functions provided by ip_fragment.c
6081da177e4SLinus Torvalds  */
6091da177e4SLinus Torvalds 
610fd2c3ef7SEric Dumazet enum ip_defrag_users {
6111da177e4SLinus Torvalds 	IP_DEFRAG_LOCAL_DELIVER,
6121da177e4SLinus Torvalds 	IP_DEFRAG_CALL_RA_CHAIN,
6131da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_IN,
6144be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_IN_END	= IP_DEFRAG_CONNTRACK_IN + USHRT_MAX,
6151da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_OUT,
6164be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_OUT_END	= IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX,
6178fa9ff68SPatrick McHardy 	IP_DEFRAG_CONNTRACK_BRIDGE_IN,
6184be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,
6191da177e4SLinus Torvalds 	IP_DEFRAG_VS_IN,
6201da177e4SLinus Torvalds 	IP_DEFRAG_VS_OUT,
621595fc71bSDavid S. Miller 	IP_DEFRAG_VS_FWD,
622595fc71bSDavid S. Miller 	IP_DEFRAG_AF_PACKET,
623bc416d97SEric Dumazet 	IP_DEFRAG_MACVLAN,
6241da177e4SLinus Torvalds };
6251da177e4SLinus Torvalds 
6265cf42280SAndy Zhou /* Return true if the value of 'user' is between 'lower_bond'
6275cf42280SAndy Zhou  * and 'upper_bond' inclusively.
6285cf42280SAndy Zhou  */
6295cf42280SAndy Zhou static inline bool ip_defrag_user_in_between(u32 user,
6305cf42280SAndy Zhou 					     enum ip_defrag_users lower_bond,
6315cf42280SAndy Zhou 					     enum ip_defrag_users upper_bond)
6325cf42280SAndy Zhou {
6335cf42280SAndy Zhou 	return user >= lower_bond && user <= upper_bond;
6345cf42280SAndy Zhou }
6355cf42280SAndy Zhou 
63619bcf9f2SEric W. Biederman int ip_defrag(struct net *net, struct sk_buff *skb, u32 user);
637bc416d97SEric Dumazet #ifdef CONFIG_INET
63819bcf9f2SEric W. Biederman struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user);
639bc416d97SEric Dumazet #else
64019bcf9f2SEric W. Biederman static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
641bc416d97SEric Dumazet {
642bc416d97SEric Dumazet 	return skb;
643bc416d97SEric Dumazet }
644bc416d97SEric Dumazet #endif
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds /*
6471da177e4SLinus Torvalds  *	Functions provided by ip_forward.c
6481da177e4SLinus Torvalds  */
6491da177e4SLinus Torvalds 
6505c3a0fd7SJoe Perches int ip_forward(struct sk_buff *skb);
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds /*
6531da177e4SLinus Torvalds  *	Functions provided by ip_options.c
6541da177e4SLinus Torvalds  */
6551da177e4SLinus Torvalds 
6565c3a0fd7SJoe Perches void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
657f6d8bd05SEric Dumazet 		      __be32 daddr, struct rtable *rt, int is_frag);
65824a2d43dSEric Dumazet 
65991ed1e66SPaolo Abeni int __ip_options_echo(struct net *net, struct ip_options *dopt,
66091ed1e66SPaolo Abeni 		      struct sk_buff *skb, const struct ip_options *sopt);
66191ed1e66SPaolo Abeni static inline int ip_options_echo(struct net *net, struct ip_options *dopt,
66291ed1e66SPaolo Abeni 				  struct sk_buff *skb)
66324a2d43dSEric Dumazet {
66491ed1e66SPaolo Abeni 	return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt);
66524a2d43dSEric Dumazet }
66624a2d43dSEric Dumazet 
6675c3a0fd7SJoe Perches void ip_options_fragment(struct sk_buff *skb);
6685c3a0fd7SJoe Perches int ip_options_compile(struct net *net, struct ip_options *opt,
6695c3a0fd7SJoe Perches 		       struct sk_buff *skb);
6705c3a0fd7SJoe Perches int ip_options_get(struct net *net, struct ip_options_rcu **optp,
6714c6ea29dSArnaldo Carvalho de Melo 		   unsigned char *data, int optlen);
6725c3a0fd7SJoe Perches int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
6734c6ea29dSArnaldo Carvalho de Melo 			     unsigned char __user *data, int optlen);
6745c3a0fd7SJoe Perches void ip_options_undo(struct ip_options *opt);
6755c3a0fd7SJoe Perches void ip_forward_options(struct sk_buff *skb);
6765c3a0fd7SJoe Perches int ip_options_rcv_srr(struct sk_buff *skb);
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds /*
6791da177e4SLinus Torvalds  *	Functions provided by ip_sockglue.c
6801da177e4SLinus Torvalds  */
6811da177e4SLinus Torvalds 
682fbf8866dSShawn Bohrer void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
683ad959036SPaolo Abeni void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
684ad959036SPaolo Abeni 			 struct sk_buff *skb, int tlen, int offset);
68524025c46SSoheil Hassas Yeganeh int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
686c8e6ad08SHannes Frederic Sowa 		 struct ipcm_cookie *ipc, bool allow_ipv6);
6875c3a0fd7SJoe Perches int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
6885c3a0fd7SJoe Perches 		  unsigned int optlen);
6895c3a0fd7SJoe Perches int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
6905c3a0fd7SJoe Perches 		  int __user *optlen);
6915c3a0fd7SJoe Perches int compat_ip_setsockopt(struct sock *sk, int level, int optname,
6925c3a0fd7SJoe Perches 			 char __user *optval, unsigned int optlen);
6935c3a0fd7SJoe Perches int compat_ip_getsockopt(struct sock *sk, int level, int optname,
6945c3a0fd7SJoe Perches 			 char __user *optval, int __user *optlen);
6955c3a0fd7SJoe Perches int ip_ra_control(struct sock *sk, unsigned char on,
6965c3a0fd7SJoe Perches 		  void (*destructor)(struct sock *));
6971da177e4SLinus Torvalds 
69885fbaa75SHannes Frederic Sowa int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
6995c3a0fd7SJoe Perches void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
7005c3a0fd7SJoe Perches 		   u32 info, u8 *payload);
7015c3a0fd7SJoe Perches void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
7021da177e4SLinus Torvalds 		    u32 info);
7031da177e4SLinus Torvalds 
7045961de9fSTom Herbert static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
7055961de9fSTom Herbert {
706ad959036SPaolo Abeni 	ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
7075961de9fSTom Herbert }
7085961de9fSTom Herbert 
7094cdf507dSEric Dumazet bool icmp_global_allow(void);
7104cdf507dSEric Dumazet extern int sysctl_icmp_msgs_per_sec;
7114cdf507dSEric Dumazet extern int sysctl_icmp_msgs_burst;
7124cdf507dSEric Dumazet 
71320380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS
7145c3a0fd7SJoe Perches int ip_misc_proc_init(void);
71520380731SArnaldo Carvalho de Melo #endif
71620380731SArnaldo Carvalho de Melo 
717404eb77eSRoopa Prabhu int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto,
718404eb77eSRoopa Prabhu 				struct netlink_ext_ack *extack);
719404eb77eSRoopa Prabhu 
7201da177e4SLinus Torvalds #endif	/* _IP_H */
721