xref: /openbmc/linux/include/net/ip.h (revision bec1f6f6)
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;
752244d07bSOliver Hartkopp 	__u8			tx_flags;
76f02db315SFrancesco Fusco 	__u8			ttl;
77f02db315SFrancesco Fusco 	__s16			tos;
78f02db315SFrancesco Fusco 	char			priority;
79bec1f6f6SWillem de Bruijn 	__u16			gso_size;
801da177e4SLinus Torvalds };
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
834b261c75SHannes Frederic Sowa #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb))
841da177e4SLinus Torvalds 
85fb74c277SDavid Ahern /* return enslaved device index if relevant */
86fb74c277SDavid Ahern static inline int inet_sdif(struct sk_buff *skb)
87fb74c277SDavid Ahern {
88fb74c277SDavid Ahern #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
89fb74c277SDavid Ahern 	if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags))
90fb74c277SDavid Ahern 		return IPCB(skb)->iif;
91fb74c277SDavid Ahern #endif
92fb74c277SDavid Ahern 	return 0;
93fb74c277SDavid Ahern }
94fb74c277SDavid Ahern 
955796ef75SKirill Tkhai /* Special input handler for packets caught by router alert option.
965796ef75SKirill Tkhai    They are selected only by protocol field, and then processed likely
975796ef75SKirill Tkhai    local ones; but only if someone wants them! Otherwise, router
985796ef75SKirill Tkhai    not running rsvpd will kill RSVP.
995796ef75SKirill Tkhai 
1005796ef75SKirill Tkhai    It is user level problem, what it will make with them.
1015796ef75SKirill Tkhai    I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
1025796ef75SKirill Tkhai    but receiver should be enough clever f.e. to forward mtrace requests,
1035796ef75SKirill Tkhai    sent to multicast group to reach destination designated router.
1045796ef75SKirill Tkhai  */
1055796ef75SKirill Tkhai 
106fd2c3ef7SEric Dumazet struct ip_ra_chain {
10743a951e9SEric Dumazet 	struct ip_ra_chain __rcu *next;
1081da177e4SLinus Torvalds 	struct sock		*sk;
109592fcb9dSEric Dumazet 	union {
1101da177e4SLinus Torvalds 		void			(*destructor)(struct sock *);
111592fcb9dSEric Dumazet 		struct sock		*saved_sk;
112592fcb9dSEric Dumazet 	};
11366018506SEric Dumazet 	struct rcu_head		rcu;
1141da177e4SLinus Torvalds };
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds /* IP flags. */
1171da177e4SLinus Torvalds #define IP_CE		0x8000		/* Flag: "Congestion"		*/
1181da177e4SLinus Torvalds #define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
1191da177e4SLinus Torvalds #define IP_MF		0x2000		/* Flag: "More Fragments"	*/
1201da177e4SLinus Torvalds #define IP_OFFSET	0x1FFF		/* "Fragment Offset" part	*/
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds #define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/
1231da177e4SLinus Torvalds 
12414c85021SArnaldo Carvalho de Melo struct msghdr;
12514c85021SArnaldo Carvalho de Melo struct net_device;
12614c85021SArnaldo Carvalho de Melo struct packet_type;
12714c85021SArnaldo Carvalho de Melo struct rtable;
12814c85021SArnaldo Carvalho de Melo struct sockaddr;
12914c85021SArnaldo Carvalho de Melo 
13072c1d3bdSWANG Cong int igmp_mc_init(void);
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds /*
1331da177e4SLinus Torvalds  *	Functions provided by ip.c
1341da177e4SLinus Torvalds  */
1351da177e4SLinus Torvalds 
136cfe673b0SEric Dumazet int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
13713d8eaa0SAl Viro 			  __be32 saddr, __be32 daddr,
138f6d8bd05SEric Dumazet 			  struct ip_options_rcu *opt);
1395c3a0fd7SJoe Perches int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
1405c3a0fd7SJoe Perches 	   struct net_device *orig_dev);
1415c3a0fd7SJoe Perches int ip_local_deliver(struct sk_buff *skb);
1425c3a0fd7SJoe Perches int ip_mr_input(struct sk_buff *skb);
143ede2059dSEric W. Biederman int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
144ede2059dSEric W. Biederman int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb);
145694869b3SEric W. Biederman int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
146694869b3SEric W. Biederman 		   int (*output)(struct net *, struct sock *, struct sk_buff *));
1475c3a0fd7SJoe Perches void ip_send_check(struct iphdr *ip);
148cf91a99dSEric W. Biederman int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
14933224b16SEric W. Biederman int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
150aad88724SEric Dumazet 
151b0270e91SEric Dumazet int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
1525c3a0fd7SJoe Perches void ip_init(void);
1535c3a0fd7SJoe Perches int ip_append_data(struct sock *sk, struct flowi4 *fl4,
1541da177e4SLinus Torvalds 		   int getfrag(void *from, char *to, int offset, int len,
1551da177e4SLinus Torvalds 			       int odd, struct sk_buff *skb),
1561da177e4SLinus Torvalds 		   void *from, int len, int protolen,
1571da177e4SLinus Torvalds 		   struct ipcm_cookie *ipc,
1582e77d89bSEric Dumazet 		   struct rtable **rt,
1591da177e4SLinus Torvalds 		   unsigned int flags);
1605c3a0fd7SJoe Perches int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd,
1615c3a0fd7SJoe Perches 		       struct sk_buff *skb);
1625c3a0fd7SJoe Perches ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
1631da177e4SLinus Torvalds 		       int offset, size_t size, int flags);
1645c3a0fd7SJoe Perches struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4,
1651c32c5adSHerbert Xu 			      struct sk_buff_head *queue,
1661c32c5adSHerbert Xu 			      struct inet_cork *cork);
1675c3a0fd7SJoe Perches int ip_send_skb(struct net *net, struct sk_buff *skb);
1685c3a0fd7SJoe Perches int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4);
1695c3a0fd7SJoe Perches void ip_flush_pending_frames(struct sock *sk);
1705c3a0fd7SJoe Perches struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
1715c3a0fd7SJoe Perches 			    int getfrag(void *from, char *to, int offset,
1725c3a0fd7SJoe Perches 					int len, int odd, struct sk_buff *skb),
1731c32c5adSHerbert Xu 			    void *from, int length, int transhdrlen,
1745c3a0fd7SJoe Perches 			    struct ipcm_cookie *ipc, struct rtable **rtp,
1751cd7884dSWillem de Bruijn 			    struct inet_cork *cork, unsigned int flags);
1761c32c5adSHerbert Xu 
17777968b78SDavid S. Miller static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
1781c32c5adSHerbert Xu {
17977968b78SDavid S. Miller 	return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
1801c32c5adSHerbert Xu }
1811da177e4SLinus Torvalds 
182aa661581SFrancesco Fusco static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet)
183aa661581SFrancesco Fusco {
184aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos);
185aa661581SFrancesco Fusco }
186aa661581SFrancesco Fusco 
187aa661581SFrancesco Fusco static inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk)
188aa661581SFrancesco Fusco {
189aa661581SFrancesco Fusco 	return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk);
190aa661581SFrancesco Fusco }
191aa661581SFrancesco Fusco 
1921da177e4SLinus Torvalds /* datagram.c */
19303645a11SEric Dumazet int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
1945c3a0fd7SJoe Perches int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
1951da177e4SLinus Torvalds 
1965c3a0fd7SJoe Perches void ip4_datagram_release_cb(struct sock *sk);
1978141ed9fSSteffen Klassert 
1981da177e4SLinus Torvalds struct ip_reply_arg {
1991da177e4SLinus Torvalds 	struct kvec iov[1];
20088ef4a5aSKOVACS Krisztian 	int	    flags;
201d6f5493cSAl Viro 	__wsum 	    csum;
2021da177e4SLinus Torvalds 	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
2031da177e4SLinus Torvalds 				/* -1 if not needed */
204f0e48dbfSPatrick McHardy 	int	    bound_dev_if;
20566b13d99SEric Dumazet 	u8  	    tos;
206e2d118a1SLorenzo Colitti 	kuid_t	    uid;
2071da177e4SLinus Torvalds };
2081da177e4SLinus Torvalds 
20988ef4a5aSKOVACS Krisztian #define IP_REPLY_ARG_NOSRCCHECK 1
21088ef4a5aSKOVACS Krisztian 
21186b08d86SKOVACS Krisztian static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
21286b08d86SKOVACS Krisztian {
21386b08d86SKOVACS Krisztian 	return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
21486b08d86SKOVACS Krisztian }
21586b08d86SKOVACS Krisztian 
216bdbbb852SEric Dumazet void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
21724a2d43dSEric Dumazet 			   const struct ip_options *sopt,
21824a2d43dSEric Dumazet 			   __be32 daddr, __be32 saddr,
21924a2d43dSEric Dumazet 			   const struct ip_reply_arg *arg,
22070e73416SDavid S. Miller 			   unsigned int len);
2211da177e4SLinus Torvalds 
2224ce3c183SEric Dumazet #define IP_INC_STATS(net, field)	SNMP_INC_STATS64((net)->mib.ip_statistics, field)
22313415e46SEric Dumazet #define __IP_INC_STATS(net, field)	__SNMP_INC_STATS64((net)->mib.ip_statistics, field)
2244ce3c183SEric Dumazet #define IP_ADD_STATS(net, field, val)	SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
22513415e46SEric Dumazet #define __IP_ADD_STATS(net, field, val) __SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
2264ce3c183SEric Dumazet #define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
22713415e46SEric Dumazet #define __IP_UPD_PO_STATS(net, field, val) __SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
22861a7e260SPavel Emelyanov #define NET_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.net_statistics, field)
22913415e46SEric Dumazet #define __NET_INC_STATS(net, field)	__SNMP_INC_STATS((net)->mib.net_statistics, field)
230f7324acdSDavid S. Miller #define NET_ADD_STATS(net, field, adnd)	SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
23113415e46SEric Dumazet #define __NET_ADD_STATS(net, field, adnd) __SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd)
2321da177e4SLinus Torvalds 
233c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offct);
234698365faSWANG Cong unsigned long snmp_fold_field(void __percpu *mib, int offt);
2354ce3c183SEric Dumazet #if BITS_PER_LONG==32
236c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
237c4c6bc31SRaghavendra K T 			 size_t syncp_offset);
238698365faSWANG Cong u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off);
2394ce3c183SEric Dumazet #else
240c4c6bc31SRaghavendra K T static inline u64  snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct,
241c4c6bc31SRaghavendra K T 					size_t syncp_offset)
242c4c6bc31SRaghavendra K T {
243c4c6bc31SRaghavendra K T 	return snmp_get_cpu_field(mib, cpu, offct);
244c4c6bc31SRaghavendra K T 
245c4c6bc31SRaghavendra K T }
246c4c6bc31SRaghavendra K T 
247698365faSWANG Cong static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off)
2484ce3c183SEric Dumazet {
2494ce3c183SEric Dumazet 	return snmp_fold_field(mib, offt);
2504ce3c183SEric Dumazet }
2514ce3c183SEric Dumazet #endif
25233490170SYOSHIFUJI Hideaki 
2536348ef2dSJia He #define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \
2546348ef2dSJia He { \
2556348ef2dSJia He 	int i, c; \
2566348ef2dSJia He 	for_each_possible_cpu(c) { \
2576348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
2586348ef2dSJia He 			buff64[i] += snmp_get_cpu_field64( \
2596348ef2dSJia He 					mib_statistic, \
2606348ef2dSJia He 					c, stats_list[i].entry, \
2616348ef2dSJia He 					offset); \
2626348ef2dSJia He 	} \
2636348ef2dSJia He }
2646348ef2dSJia He 
2656348ef2dSJia He #define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \
2666348ef2dSJia He { \
2676348ef2dSJia He 	int i, c; \
2686348ef2dSJia He 	for_each_possible_cpu(c) { \
2696348ef2dSJia He 		for (i = 0; stats_list[i].name; i++) \
2706348ef2dSJia He 			buff[i] += snmp_get_cpu_field( \
2716348ef2dSJia He 						mib_statistic, \
2726348ef2dSJia He 						c, stats_list[i].entry); \
2736348ef2dSJia He 	} \
2746348ef2dSJia He }
2756348ef2dSJia He 
2760bbf87d8SEric W. Biederman void inet_get_local_port_range(struct net *net, int *low, int *high);
277227b60f5SStephen Hemminger 
278fcd77db0SDavid S. Miller #ifdef CONFIG_SYSCTL
279122ff243SWANG Cong static inline int inet_is_local_reserved_port(struct net *net, int port)
280e3826f1eSAmerigo Wang {
281122ff243SWANG Cong 	if (!net->ipv4.sysctl_local_reserved_ports)
282122ff243SWANG Cong 		return 0;
283122ff243SWANG Cong 	return test_bit(port, net->ipv4.sysctl_local_reserved_ports);
284e3826f1eSAmerigo Wang }
28520e61da7SWANG Cong 
28620e61da7SWANG Cong static inline bool sysctl_dev_name_is_allowed(const char *name)
28720e61da7SWANG Cong {
28820e61da7SWANG Cong 	return strcmp(name, "default") != 0  && strcmp(name, "all") != 0;
28920e61da7SWANG Cong }
29020e61da7SWANG Cong 
2914548b683SKrister Johansen static inline int inet_prot_sock(struct net *net)
2924548b683SKrister Johansen {
2934548b683SKrister Johansen 	return net->ipv4.sysctl_ip_prot_sock;
2944548b683SKrister Johansen }
2954548b683SKrister Johansen 
296122ff243SWANG Cong #else
297122ff243SWANG Cong static inline int inet_is_local_reserved_port(struct net *net, int port)
298122ff243SWANG Cong {
299122ff243SWANG Cong 	return 0;
300122ff243SWANG Cong }
3014548b683SKrister Johansen 
3024548b683SKrister Johansen static inline int inet_prot_sock(struct net *net)
3034548b683SKrister Johansen {
3044548b683SKrister Johansen 	return PROT_SOCK;
3054548b683SKrister Johansen }
306122ff243SWANG Cong #endif
307e3826f1eSAmerigo Wang 
308822c8685SDeepa Dinamani __be32 inet_current_timestamp(void);
309822c8685SDeepa Dinamani 
31020380731SArnaldo Carvalho de Melo /* From inetpeer.c */
31120380731SArnaldo Carvalho de Melo extern int inet_peer_threshold;
31220380731SArnaldo Carvalho de Melo extern int inet_peer_minttl;
31320380731SArnaldo Carvalho de Melo extern int inet_peer_maxttl;
31420380731SArnaldo Carvalho de Melo 
3155c3a0fd7SJoe Perches void ipfrag_init(void);
31620380731SArnaldo Carvalho de Melo 
3175c3a0fd7SJoe Perches void ip_static_sysctl_init(void);
318bd7b1533SAl Viro 
319e110861fSLorenzo Colitti #define IP4_REPLY_MARK(net, mark) \
320e110861fSLorenzo Colitti 	((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
321e110861fSLorenzo Colitti 
322d18cd551SDavid S. Miller static inline bool ip_is_fragment(const struct iphdr *iph)
323d18cd551SDavid S. Miller {
324d18cd551SDavid S. Miller 	return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
325d18cd551SDavid S. Miller }
326d18cd551SDavid S. Miller 
3271da177e4SLinus Torvalds #ifdef CONFIG_INET
32814c85021SArnaldo Carvalho de Melo #include <net/dst.h>
32914c85021SArnaldo Carvalho de Melo 
3301da177e4SLinus Torvalds /* The function in 2.2 was invalid, producing wrong result for
3311da177e4SLinus Torvalds  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
3321da177e4SLinus Torvalds static inline
3331da177e4SLinus Torvalds int ip_decrease_ttl(struct iphdr *iph)
3341da177e4SLinus Torvalds {
3355c78f275SAl Viro 	u32 check = (__force u32)iph->check;
3365c78f275SAl Viro 	check += (__force u32)htons(0x0100);
3375c78f275SAl Viro 	iph->check = (__force __sum16)(check + (check>=0xFFFF));
3381da177e4SLinus Torvalds 	return --iph->ttl;
3391da177e4SLinus Torvalds }
3401da177e4SLinus Torvalds 
341d52e5a7eSSabrina Dubroca static inline int ip_mtu_locked(const struct dst_entry *dst)
342d52e5a7eSSabrina Dubroca {
343d52e5a7eSSabrina Dubroca 	const struct rtable *rt = (const struct rtable *)dst;
344d52e5a7eSSabrina Dubroca 
345d52e5a7eSSabrina Dubroca 	return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
346d52e5a7eSSabrina Dubroca }
347d52e5a7eSSabrina Dubroca 
3481da177e4SLinus Torvalds static inline
3494e3f5d72SEric Dumazet int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
3501da177e4SLinus Torvalds {
3514e3f5d72SEric Dumazet 	u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc);
3524e3f5d72SEric Dumazet 
3534e3f5d72SEric Dumazet 	return  pmtudisc == IP_PMTUDISC_DO ||
3544e3f5d72SEric Dumazet 		(pmtudisc == IP_PMTUDISC_WANT &&
355d52e5a7eSSabrina Dubroca 		 !ip_mtu_locked(dst));
3561da177e4SLinus Torvalds }
3571da177e4SLinus Torvalds 
358f87c10a8SHannes Frederic Sowa static inline bool ip_sk_accept_pmtu(const struct sock *sk)
359f87c10a8SHannes Frederic Sowa {
3601b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE &&
3611b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT;
362f87c10a8SHannes Frederic Sowa }
363f87c10a8SHannes Frederic Sowa 
364f87c10a8SHannes Frederic Sowa static inline bool ip_sk_use_pmtu(const struct sock *sk)
365f87c10a8SHannes Frederic Sowa {
366f87c10a8SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE;
367f87c10a8SHannes Frederic Sowa }
368f87c10a8SHannes Frederic Sowa 
36960ff7467SWANG Cong static inline bool ip_sk_ignore_df(const struct sock *sk)
3701b346576SHannes Frederic Sowa {
3711b346576SHannes Frederic Sowa 	return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO ||
3721b346576SHannes Frederic Sowa 	       inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT;
3731b346576SHannes Frederic Sowa }
3741b346576SHannes Frederic Sowa 
375f87c10a8SHannes Frederic Sowa static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
376f87c10a8SHannes Frederic Sowa 						    bool forwarding)
377f87c10a8SHannes Frederic Sowa {
378f87c10a8SHannes Frederic Sowa 	struct net *net = dev_net(dst->dev);
379f87c10a8SHannes Frederic Sowa 
380f87c10a8SHannes Frederic Sowa 	if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
381d52e5a7eSSabrina Dubroca 	    ip_mtu_locked(dst) ||
382f87c10a8SHannes Frederic Sowa 	    !forwarding)
383f87c10a8SHannes Frederic Sowa 		return dst_mtu(dst);
384f87c10a8SHannes Frederic Sowa 
385c780a049SEric Dumazet 	return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
386f87c10a8SHannes Frederic Sowa }
387f87c10a8SHannes Frederic Sowa 
388fedbb6b4SShmulik Ladkani static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
389fedbb6b4SShmulik Ladkani 					  const struct sk_buff *skb)
390f87c10a8SHannes Frederic Sowa {
391caf3f267SEric Dumazet 	if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) {
392f87c10a8SHannes Frederic Sowa 		bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED;
393caf3f267SEric Dumazet 
394f87c10a8SHannes Frederic Sowa 		return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
395f87c10a8SHannes Frederic Sowa 	}
396caf3f267SEric Dumazet 
397c780a049SEric Dumazet 	return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
398f87c10a8SHannes Frederic Sowa }
399f87c10a8SHannes Frederic Sowa 
400a919525aSDavid Ahern int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
401a919525aSDavid Ahern 		       u32 *metrics);
402a919525aSDavid Ahern 
40304ca6973SEric Dumazet u32 ip_idents_reserve(u32 hash, int segs);
404b6a7719aSHannes Frederic Sowa void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
40573f156a6SEric Dumazet 
406b6a7719aSHannes Frederic Sowa static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
407b6a7719aSHannes Frederic Sowa 					struct sock *sk, int segs)
4081da177e4SLinus Torvalds {
409703133deSAnsis Atteka 	struct iphdr *iph = ip_hdr(skb);
410703133deSAnsis Atteka 
41160ff7467SWANG Cong 	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
4121da177e4SLinus Torvalds 		/* This is only to work around buggy Windows95/2000
4131da177e4SLinus Torvalds 		 * VJ compression implementations.  If the ID field
4141da177e4SLinus Torvalds 		 * does not change, they drop every other packet in
4151da177e4SLinus Torvalds 		 * a TCP stream using header compression.
4161da177e4SLinus Torvalds 		 */
417c720c7e8SEric Dumazet 		if (sk && inet_sk(sk)->inet_daddr) {
418c720c7e8SEric Dumazet 			iph->id = htons(inet_sk(sk)->inet_id);
41973f156a6SEric Dumazet 			inet_sk(sk)->inet_id += segs;
42073f156a6SEric Dumazet 		} else {
4211da177e4SLinus Torvalds 			iph->id = 0;
42273f156a6SEric Dumazet 		}
42373f156a6SEric Dumazet 	} else {
424b6a7719aSHannes Frederic Sowa 		__ip_select_ident(net, iph, segs);
42573f156a6SEric Dumazet 	}
42673f156a6SEric Dumazet }
42773f156a6SEric Dumazet 
428b6a7719aSHannes Frederic Sowa static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
429b6a7719aSHannes Frederic Sowa 				   struct sock *sk)
43073f156a6SEric Dumazet {
431b6a7719aSHannes Frederic Sowa 	ip_select_ident_segs(net, skb, sk, 1);
4321da177e4SLinus Torvalds }
4331da177e4SLinus Torvalds 
434ed70fcfcSTom Herbert static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto)
435ed70fcfcSTom Herbert {
436ed70fcfcSTom Herbert 	return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
437ed70fcfcSTom Herbert 				  skb->len, proto, 0);
438ed70fcfcSTom Herbert }
439ed70fcfcSTom Herbert 
440c3f83241STom Herbert /* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store
441c3f83241STom Herbert  * Equivalent to :	flow->v4addrs.src = iph->saddr;
442c3f83241STom Herbert  *			flow->v4addrs.dst = iph->daddr;
443c3f83241STom Herbert  */
444c3f83241STom Herbert static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
445c3f83241STom Herbert 					    const struct iphdr *iph)
446c3f83241STom Herbert {
447c3f83241STom Herbert 	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
448c3f83241STom Herbert 		     offsetof(typeof(flow->addrs), v4addrs.src) +
449c3f83241STom Herbert 			      sizeof(flow->addrs.v4addrs.src));
450c3f83241STom Herbert 	memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
451c3f83241STom Herbert 	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
452c3f83241STom Herbert }
453c3f83241STom Herbert 
4541933a785STom Herbert static inline __wsum inet_gro_compute_pseudo(struct sk_buff *skb, int proto)
4551933a785STom Herbert {
4561933a785STom Herbert 	const struct iphdr *iph = skb_gro_network_header(skb);
4571933a785STom Herbert 
4581933a785STom Herbert 	return csum_tcpudp_nofold(iph->saddr, iph->daddr,
4591933a785STom Herbert 				  skb_gro_len(skb), proto, 0);
4601933a785STom Herbert }
4611933a785STom Herbert 
4621da177e4SLinus Torvalds /*
4631da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type ethernet.
4641da177e4SLinus Torvalds  */
4651da177e4SLinus Torvalds 
466714e85beSAl Viro static inline void ip_eth_mc_map(__be32 naddr, char *buf)
4671da177e4SLinus Torvalds {
468714e85beSAl Viro 	__u32 addr=ntohl(naddr);
4691da177e4SLinus Torvalds 	buf[0]=0x01;
4701da177e4SLinus Torvalds 	buf[1]=0x00;
4711da177e4SLinus Torvalds 	buf[2]=0x5e;
4721da177e4SLinus Torvalds 	buf[5]=addr&0xFF;
4731da177e4SLinus Torvalds 	addr>>=8;
4741da177e4SLinus Torvalds 	buf[4]=addr&0xFF;
4751da177e4SLinus Torvalds 	addr>>=8;
4761da177e4SLinus Torvalds 	buf[3]=addr&0x7F;
4771da177e4SLinus Torvalds }
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds /*
4801da177e4SLinus Torvalds  *	Map a multicast IP onto multicast MAC for type IP-over-InfiniBand.
4811da177e4SLinus Torvalds  *	Leave P_Key as 0 to be filled in by driver.
4821da177e4SLinus Torvalds  */
4831da177e4SLinus Torvalds 
484a9e527e3SRolf Manderscheid static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
4851da177e4SLinus Torvalds {
486714e85beSAl Viro 	__u32 addr;
487a9e527e3SRolf Manderscheid 	unsigned char scope = broadcast[5] & 0xF;
488a9e527e3SRolf Manderscheid 
4891da177e4SLinus Torvalds 	buf[0]  = 0;		/* Reserved */
4901da177e4SLinus Torvalds 	buf[1]  = 0xff;		/* Multicast QPN */
4911da177e4SLinus Torvalds 	buf[2]  = 0xff;
4921da177e4SLinus Torvalds 	buf[3]  = 0xff;
493714e85beSAl Viro 	addr    = ntohl(naddr);
4941da177e4SLinus Torvalds 	buf[4]  = 0xff;
495a9e527e3SRolf Manderscheid 	buf[5]  = 0x10 | scope;	/* scope from broadcast address */
4961da177e4SLinus Torvalds 	buf[6]  = 0x40;		/* IPv4 signature */
4971da177e4SLinus Torvalds 	buf[7]  = 0x1b;
498a9e527e3SRolf Manderscheid 	buf[8]  = broadcast[8];		/* P_Key */
499a9e527e3SRolf Manderscheid 	buf[9]  = broadcast[9];
5001da177e4SLinus Torvalds 	buf[10] = 0;
5011da177e4SLinus Torvalds 	buf[11] = 0;
5021da177e4SLinus Torvalds 	buf[12] = 0;
5031da177e4SLinus Torvalds 	buf[13] = 0;
5041da177e4SLinus Torvalds 	buf[14] = 0;
5051da177e4SLinus Torvalds 	buf[15] = 0;
5061da177e4SLinus Torvalds 	buf[19] = addr & 0xff;
5071da177e4SLinus Torvalds 	addr  >>= 8;
5081da177e4SLinus Torvalds 	buf[18] = addr & 0xff;
5091da177e4SLinus Torvalds 	addr  >>= 8;
5101da177e4SLinus Torvalds 	buf[17] = addr & 0xff;
5111da177e4SLinus Torvalds 	addr  >>= 8;
5121da177e4SLinus Torvalds 	buf[16] = addr & 0x0f;
5131da177e4SLinus Torvalds }
5141da177e4SLinus Torvalds 
51593ca3bb5STimo Teräs static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
51693ca3bb5STimo Teräs {
51793ca3bb5STimo Teräs 	if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
51893ca3bb5STimo Teräs 		memcpy(buf, broadcast, 4);
51993ca3bb5STimo Teräs 	else
52093ca3bb5STimo Teräs 		memcpy(buf, &naddr, sizeof(naddr));
52193ca3bb5STimo Teräs }
52293ca3bb5STimo Teräs 
523dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
5241da177e4SLinus Torvalds #include <linux/ipv6.h>
5251da177e4SLinus Torvalds #endif
5261da177e4SLinus Torvalds 
5271da177e4SLinus Torvalds static __inline__ void inet_reset_saddr(struct sock *sk)
5281da177e4SLinus Torvalds {
529c720c7e8SEric Dumazet 	inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0;
530dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
5311da177e4SLinus Torvalds 	if (sk->sk_family == PF_INET6) {
5321da177e4SLinus Torvalds 		struct ipv6_pinfo *np = inet6_sk(sk);
5331da177e4SLinus Torvalds 
5341da177e4SLinus Torvalds 		memset(&np->saddr, 0, sizeof(np->saddr));
535efe4208fSEric Dumazet 		memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr));
5361da177e4SLinus Torvalds 	}
5371da177e4SLinus Torvalds #endif
5381da177e4SLinus Torvalds }
5391da177e4SLinus Torvalds 
5401da177e4SLinus Torvalds #endif
5411da177e4SLinus Torvalds 
54272afa352SDavid Ahern static inline unsigned int ipv4_addr_hash(__be32 ip)
54372afa352SDavid Ahern {
54472afa352SDavid Ahern 	return (__force unsigned int) ip;
54572afa352SDavid Ahern }
54672afa352SDavid Ahern 
547f0b1e64cSMartin KaFai Lau static inline u32 ipv4_portaddr_hash(const struct net *net,
548f0b1e64cSMartin KaFai Lau 				     __be32 saddr,
549f0b1e64cSMartin KaFai Lau 				     unsigned int port)
550f0b1e64cSMartin KaFai Lau {
551f0b1e64cSMartin KaFai Lau 	return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;
552f0b1e64cSMartin KaFai Lau }
553f0b1e64cSMartin KaFai Lau 
5545c3a0fd7SJoe Perches bool ip_call_ra_chain(struct sk_buff *skb);
5551da177e4SLinus Torvalds 
5561da177e4SLinus Torvalds /*
557b798232fSRami Rosen  *	Functions provided by ip_fragment.c
5581da177e4SLinus Torvalds  */
5591da177e4SLinus Torvalds 
560fd2c3ef7SEric Dumazet enum ip_defrag_users {
5611da177e4SLinus Torvalds 	IP_DEFRAG_LOCAL_DELIVER,
5621da177e4SLinus Torvalds 	IP_DEFRAG_CALL_RA_CHAIN,
5631da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_IN,
5644be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_IN_END	= IP_DEFRAG_CONNTRACK_IN + USHRT_MAX,
5651da177e4SLinus Torvalds 	IP_DEFRAG_CONNTRACK_OUT,
5664be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_OUT_END	= IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX,
5678fa9ff68SPatrick McHardy 	IP_DEFRAG_CONNTRACK_BRIDGE_IN,
5684be929beSAlexey Dobriyan 	__IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,
5691da177e4SLinus Torvalds 	IP_DEFRAG_VS_IN,
5701da177e4SLinus Torvalds 	IP_DEFRAG_VS_OUT,
571595fc71bSDavid S. Miller 	IP_DEFRAG_VS_FWD,
572595fc71bSDavid S. Miller 	IP_DEFRAG_AF_PACKET,
573bc416d97SEric Dumazet 	IP_DEFRAG_MACVLAN,
5741da177e4SLinus Torvalds };
5751da177e4SLinus Torvalds 
5765cf42280SAndy Zhou /* Return true if the value of 'user' is between 'lower_bond'
5775cf42280SAndy Zhou  * and 'upper_bond' inclusively.
5785cf42280SAndy Zhou  */
5795cf42280SAndy Zhou static inline bool ip_defrag_user_in_between(u32 user,
5805cf42280SAndy Zhou 					     enum ip_defrag_users lower_bond,
5815cf42280SAndy Zhou 					     enum ip_defrag_users upper_bond)
5825cf42280SAndy Zhou {
5835cf42280SAndy Zhou 	return user >= lower_bond && user <= upper_bond;
5845cf42280SAndy Zhou }
5855cf42280SAndy Zhou 
58619bcf9f2SEric W. Biederman int ip_defrag(struct net *net, struct sk_buff *skb, u32 user);
587bc416d97SEric Dumazet #ifdef CONFIG_INET
58819bcf9f2SEric W. Biederman struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user);
589bc416d97SEric Dumazet #else
59019bcf9f2SEric W. Biederman static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
591bc416d97SEric Dumazet {
592bc416d97SEric Dumazet 	return skb;
593bc416d97SEric Dumazet }
594bc416d97SEric Dumazet #endif
5951da177e4SLinus Torvalds 
5961da177e4SLinus Torvalds /*
5971da177e4SLinus Torvalds  *	Functions provided by ip_forward.c
5981da177e4SLinus Torvalds  */
5991da177e4SLinus Torvalds 
6005c3a0fd7SJoe Perches int ip_forward(struct sk_buff *skb);
6011da177e4SLinus Torvalds 
6021da177e4SLinus Torvalds /*
6031da177e4SLinus Torvalds  *	Functions provided by ip_options.c
6041da177e4SLinus Torvalds  */
6051da177e4SLinus Torvalds 
6065c3a0fd7SJoe Perches void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
607f6d8bd05SEric Dumazet 		      __be32 daddr, struct rtable *rt, int is_frag);
60824a2d43dSEric Dumazet 
60991ed1e66SPaolo Abeni int __ip_options_echo(struct net *net, struct ip_options *dopt,
61091ed1e66SPaolo Abeni 		      struct sk_buff *skb, const struct ip_options *sopt);
61191ed1e66SPaolo Abeni static inline int ip_options_echo(struct net *net, struct ip_options *dopt,
61291ed1e66SPaolo Abeni 				  struct sk_buff *skb)
61324a2d43dSEric Dumazet {
61491ed1e66SPaolo Abeni 	return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt);
61524a2d43dSEric Dumazet }
61624a2d43dSEric Dumazet 
6175c3a0fd7SJoe Perches void ip_options_fragment(struct sk_buff *skb);
6185c3a0fd7SJoe Perches int ip_options_compile(struct net *net, struct ip_options *opt,
6195c3a0fd7SJoe Perches 		       struct sk_buff *skb);
6205c3a0fd7SJoe Perches int ip_options_get(struct net *net, struct ip_options_rcu **optp,
6214c6ea29dSArnaldo Carvalho de Melo 		   unsigned char *data, int optlen);
6225c3a0fd7SJoe Perches int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
6234c6ea29dSArnaldo Carvalho de Melo 			     unsigned char __user *data, int optlen);
6245c3a0fd7SJoe Perches void ip_options_undo(struct ip_options *opt);
6255c3a0fd7SJoe Perches void ip_forward_options(struct sk_buff *skb);
6265c3a0fd7SJoe Perches int ip_options_rcv_srr(struct sk_buff *skb);
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds /*
6291da177e4SLinus Torvalds  *	Functions provided by ip_sockglue.c
6301da177e4SLinus Torvalds  */
6311da177e4SLinus Torvalds 
632fbf8866dSShawn Bohrer void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
633ad959036SPaolo Abeni void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
634ad959036SPaolo Abeni 			 struct sk_buff *skb, int tlen, int offset);
63524025c46SSoheil Hassas Yeganeh int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
636c8e6ad08SHannes Frederic Sowa 		 struct ipcm_cookie *ipc, bool allow_ipv6);
6375c3a0fd7SJoe Perches int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
6385c3a0fd7SJoe Perches 		  unsigned int optlen);
6395c3a0fd7SJoe Perches int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
6405c3a0fd7SJoe Perches 		  int __user *optlen);
6415c3a0fd7SJoe Perches int compat_ip_setsockopt(struct sock *sk, int level, int optname,
6425c3a0fd7SJoe Perches 			 char __user *optval, unsigned int optlen);
6435c3a0fd7SJoe Perches int compat_ip_getsockopt(struct sock *sk, int level, int optname,
6445c3a0fd7SJoe Perches 			 char __user *optval, int __user *optlen);
6455c3a0fd7SJoe Perches int ip_ra_control(struct sock *sk, unsigned char on,
6465c3a0fd7SJoe Perches 		  void (*destructor)(struct sock *));
6471da177e4SLinus Torvalds 
64885fbaa75SHannes Frederic Sowa int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
6495c3a0fd7SJoe Perches void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
6505c3a0fd7SJoe Perches 		   u32 info, u8 *payload);
6515c3a0fd7SJoe Perches void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
6521da177e4SLinus Torvalds 		    u32 info);
6531da177e4SLinus Torvalds 
6545961de9fSTom Herbert static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
6555961de9fSTom Herbert {
656ad959036SPaolo Abeni 	ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
6575961de9fSTom Herbert }
6585961de9fSTom Herbert 
6594cdf507dSEric Dumazet bool icmp_global_allow(void);
6604cdf507dSEric Dumazet extern int sysctl_icmp_msgs_per_sec;
6614cdf507dSEric Dumazet extern int sysctl_icmp_msgs_burst;
6624cdf507dSEric Dumazet 
66320380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS
6645c3a0fd7SJoe Perches int ip_misc_proc_init(void);
66520380731SArnaldo Carvalho de Melo #endif
66620380731SArnaldo Carvalho de Melo 
6671da177e4SLinus Torvalds #endif	/* _IP_H */
668