xref: /linux/include/net/inet_sock.h (revision a52079dad4718fa924ae81a939f8a665366f562b)
114c85021SArnaldo Carvalho de Melo /*
214c85021SArnaldo Carvalho de Melo  * INET		An implementation of the TCP/IP protocol suite for the LINUX
314c85021SArnaldo Carvalho de Melo  *		operating system.  INET is implemented using the  BSD Socket
414c85021SArnaldo Carvalho de Melo  *		interface as the means of communication with the user level.
514c85021SArnaldo Carvalho de Melo  *
614c85021SArnaldo Carvalho de Melo  *		Definitions for inet_sock
714c85021SArnaldo Carvalho de Melo  *
814c85021SArnaldo Carvalho de Melo  * Authors:	Many, reorganised here by
914c85021SArnaldo Carvalho de Melo  * 		Arnaldo Carvalho de Melo <acme@mandriva.com>
1014c85021SArnaldo Carvalho de Melo  *
1114c85021SArnaldo Carvalho de Melo  *		This program is free software; you can redistribute it and/or
1214c85021SArnaldo Carvalho de Melo  *		modify it under the terms of the GNU General Public License
1314c85021SArnaldo Carvalho de Melo  *		as published by the Free Software Foundation; either version
1414c85021SArnaldo Carvalho de Melo  *		2 of the License, or (at your option) any later version.
1514c85021SArnaldo Carvalho de Melo  */
1614c85021SArnaldo Carvalho de Melo #ifndef _INET_SOCK_H
1714c85021SArnaldo Carvalho de Melo #define _INET_SOCK_H
1814c85021SArnaldo Carvalho de Melo 
19c44d13d6STom Herbert #include <linux/bitops.h>
2045e3ff82SVegard Nossum #include <linux/kmemcheck.h>
2114c85021SArnaldo Carvalho de Melo #include <linux/string.h>
2214c85021SArnaldo Carvalho de Melo #include <linux/types.h>
23b3da2cf3SDavid S. Miller #include <linux/jhash.h>
24fec5e652STom Herbert #include <linux/netdevice.h>
2514c85021SArnaldo Carvalho de Melo 
2614c85021SArnaldo Carvalho de Melo #include <net/flow.h>
2714c85021SArnaldo Carvalho de Melo #include <net/sock.h>
2814c85021SArnaldo Carvalho de Melo #include <net/request_sock.h>
290b441916SPavel Emelyanov #include <net/netns/hash.h>
30d34ac51bSEric Dumazet #include <net/tcp_states.h>
3114c85021SArnaldo Carvalho de Melo 
3214c85021SArnaldo Carvalho de Melo /** struct ip_options - IP Options
3314c85021SArnaldo Carvalho de Melo  *
3414c85021SArnaldo Carvalho de Melo  * @faddr - Saved first hop address
35ac8a4810SLi Wei  * @nexthop - Saved nexthop address in LSRR and SSRR
3614c85021SArnaldo Carvalho de Melo  * @is_strictroute - Strict source route
3714c85021SArnaldo Carvalho de Melo  * @srr_is_hit - Packet destination addr was our one
3814c85021SArnaldo Carvalho de Melo  * @is_changed - IP checksum more not valid
3914c85021SArnaldo Carvalho de Melo  * @rr_needaddr - Need to record addr of outgoing dev
4014c85021SArnaldo Carvalho de Melo  * @ts_needtime - Need to record timestamp
4114c85021SArnaldo Carvalho de Melo  * @ts_needaddr - Need to record addr of outgoing dev
4214c85021SArnaldo Carvalho de Melo  */
4314c85021SArnaldo Carvalho de Melo struct ip_options {
443ca3c68eSAl Viro 	__be32		faddr;
45ac8a4810SLi Wei 	__be32		nexthop;
4614c85021SArnaldo Carvalho de Melo 	unsigned char	optlen;
4714c85021SArnaldo Carvalho de Melo 	unsigned char	srr;
4814c85021SArnaldo Carvalho de Melo 	unsigned char	rr;
4914c85021SArnaldo Carvalho de Melo 	unsigned char	ts;
50ef722495SDenis V. Lunev 	unsigned char	is_strictroute:1,
5114c85021SArnaldo Carvalho de Melo 			srr_is_hit:1,
5214c85021SArnaldo Carvalho de Melo 			is_changed:1,
5314c85021SArnaldo Carvalho de Melo 			rr_needaddr:1,
5414c85021SArnaldo Carvalho de Melo 			ts_needtime:1,
5514c85021SArnaldo Carvalho de Melo 			ts_needaddr:1;
5614c85021SArnaldo Carvalho de Melo 	unsigned char	router_alert;
5711a03f78SPaul Moore 	unsigned char	cipso;
5814c85021SArnaldo Carvalho de Melo 	unsigned char	__pad2;
5914c85021SArnaldo Carvalho de Melo 	unsigned char	__data[0];
6014c85021SArnaldo Carvalho de Melo };
6114c85021SArnaldo Carvalho de Melo 
62f6d8bd05SEric Dumazet struct ip_options_rcu {
63f6d8bd05SEric Dumazet 	struct rcu_head rcu;
64f6d8bd05SEric Dumazet 	struct ip_options opt;
65f6d8bd05SEric Dumazet };
66f6d8bd05SEric Dumazet 
67f6d8bd05SEric Dumazet struct ip_options_data {
68f6d8bd05SEric Dumazet 	struct ip_options_rcu	opt;
69f6d8bd05SEric Dumazet 	char			data[40];
70f6d8bd05SEric Dumazet };
7114c85021SArnaldo Carvalho de Melo 
7214c85021SArnaldo Carvalho de Melo struct inet_request_sock {
7314c85021SArnaldo Carvalho de Melo 	struct request_sock	req;
74634fb979SEric Dumazet #define ir_loc_addr		req.__req_common.skc_rcv_saddr
75634fb979SEric Dumazet #define ir_rmt_addr		req.__req_common.skc_daddr
76b44084c2SEric Dumazet #define ir_num			req.__req_common.skc_num
77634fb979SEric Dumazet #define ir_rmt_port		req.__req_common.skc_dport
78634fb979SEric Dumazet #define ir_v6_rmt_addr		req.__req_common.skc_v6_daddr
79634fb979SEric Dumazet #define ir_v6_loc_addr		req.__req_common.skc_v6_rcv_saddr
80634fb979SEric Dumazet #define ir_iif			req.__req_common.skc_bound_dev_if
8133cf7c90SEric Dumazet #define ir_cookie		req.__req_common.skc_cookie
8233cf7c90SEric Dumazet #define ireq_net		req.__req_common.skc_net
83d34ac51bSEric Dumazet #define ireq_state		req.__req_common.skc_state
843f66b083SEric Dumazet #define ireq_family		req.__req_common.skc_family
85634fb979SEric Dumazet 
8645e3ff82SVegard Nossum 	kmemcheck_bitfield_begin(flags);
8714c85021SArnaldo Carvalho de Melo 	u16			snd_wscale : 4,
8814c85021SArnaldo Carvalho de Melo 				rcv_wscale : 4,
8914c85021SArnaldo Carvalho de Melo 				tstamp_ok  : 1,
9014c85021SArnaldo Carvalho de Melo 				sack_ok	   : 1,
9114c85021SArnaldo Carvalho de Melo 				wscale_ok  : 1,
9214c85021SArnaldo Carvalho de Melo 				ecn_ok	   : 1,
9388ef4a5aSKOVACS Krisztian 				acked	   : 1,
9488ef4a5aSKOVACS Krisztian 				no_srccheck: 1;
9545e3ff82SVegard Nossum 	kmemcheck_bitfield_end(flags);
96adc17d6aSEric Dumazet 	u32                     ir_mark;
97476eab82SOctavian Purdila 	union {
98f6d8bd05SEric Dumazet 		struct ip_options_rcu	*opt;
99634fb979SEric Dumazet 		struct sk_buff		*pktopts;
100476eab82SOctavian Purdila 	};
10114c85021SArnaldo Carvalho de Melo };
10214c85021SArnaldo Carvalho de Melo 
10314c85021SArnaldo Carvalho de Melo static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
10414c85021SArnaldo Carvalho de Melo {
10514c85021SArnaldo Carvalho de Melo 	return (struct inet_request_sock *)sk;
10614c85021SArnaldo Carvalho de Melo }
10714c85021SArnaldo Carvalho de Melo 
108adc17d6aSEric Dumazet static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
10984f39b08SLorenzo Colitti {
110adc17d6aSEric Dumazet 	if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)
11184f39b08SLorenzo Colitti 		return skb->mark;
112adc17d6aSEric Dumazet 
11384f39b08SLorenzo Colitti 	return sk->sk_mark;
11484f39b08SLorenzo Colitti }
11584f39b08SLorenzo Colitti 
1161470ddf7SHerbert Xu struct inet_cork {
1171470ddf7SHerbert Xu 	unsigned int		flags;
118bdc712b4SDavid S. Miller 	__be32			addr;
1191470ddf7SHerbert Xu 	struct ip_options	*opt;
120bdc712b4SDavid S. Miller 	unsigned int		fragsize;
1211470ddf7SHerbert Xu 	int			length; /* Total length of all frames */
1225640f768SEric Dumazet 	struct dst_entry	*dst;
1231470ddf7SHerbert Xu 	u8			tx_flags;
124aa661581SFrancesco Fusco 	__u8			ttl;
125aa661581SFrancesco Fusco 	__s16			tos;
126aa661581SFrancesco Fusco 	char			priority;
1271470ddf7SHerbert Xu };
1281470ddf7SHerbert Xu 
129bdc712b4SDavid S. Miller struct inet_cork_full {
130bdc712b4SDavid S. Miller 	struct inet_cork	base;
131bdc712b4SDavid S. Miller 	struct flowi		fl;
132bdc712b4SDavid S. Miller };
133bdc712b4SDavid S. Miller 
13414c85021SArnaldo Carvalho de Melo struct ip_mc_socklist;
13514c85021SArnaldo Carvalho de Melo struct ipv6_pinfo;
13614c85021SArnaldo Carvalho de Melo struct rtable;
13714c85021SArnaldo Carvalho de Melo 
13814c85021SArnaldo Carvalho de Melo /** struct inet_sock - representation of INET sockets
13914c85021SArnaldo Carvalho de Melo  *
14014c85021SArnaldo Carvalho de Melo  * @sk - ancestor class
14114c85021SArnaldo Carvalho de Melo  * @pinet6 - pointer to IPv6 control block
142c720c7e8SEric Dumazet  * @inet_daddr - Foreign IPv4 addr
143c720c7e8SEric Dumazet  * @inet_rcv_saddr - Bound local IPv4 addr
144c720c7e8SEric Dumazet  * @inet_dport - Destination port
145c720c7e8SEric Dumazet  * @inet_num - Local port
146c720c7e8SEric Dumazet  * @inet_saddr - Sending source
14714c85021SArnaldo Carvalho de Melo  * @uc_ttl - Unicast TTL
148c720c7e8SEric Dumazet  * @inet_sport - Source port
149c720c7e8SEric Dumazet  * @inet_id - ID counter for DF pkts
15014c85021SArnaldo Carvalho de Melo  * @tos - TOS
15114c85021SArnaldo Carvalho de Melo  * @mc_ttl - Multicasting TTL
15214c85021SArnaldo Carvalho de Melo  * @is_icsk - is this an inet_connection_sock?
15376e21053SErich E. Hoover  * @uc_index - Unicast outgoing device index
15414c85021SArnaldo Carvalho de Melo  * @mc_index - Multicast device index
15514c85021SArnaldo Carvalho de Melo  * @mc_list - Group array
15614c85021SArnaldo Carvalho de Melo  * @cork - info to build ip hdr on each ip frag while socket is corked
15714c85021SArnaldo Carvalho de Melo  */
15814c85021SArnaldo Carvalho de Melo struct inet_sock {
15914c85021SArnaldo Carvalho de Melo 	/* sk and pinet6 has to be the first two members of inet_sock */
16014c85021SArnaldo Carvalho de Melo 	struct sock		sk;
161dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
16214c85021SArnaldo Carvalho de Melo 	struct ipv6_pinfo	*pinet6;
16314c85021SArnaldo Carvalho de Melo #endif
16414c85021SArnaldo Carvalho de Melo 	/* Socket demultiplex comparisons on incoming packets. */
16568835abaSEric Dumazet #define inet_daddr		sk.__sk_common.skc_daddr
16668835abaSEric Dumazet #define inet_rcv_saddr		sk.__sk_common.skc_rcv_saddr
167ce43b03eSEric Dumazet #define inet_dport		sk.__sk_common.skc_dport
168ce43b03eSEric Dumazet #define inet_num		sk.__sk_common.skc_num
16968835abaSEric Dumazet 
170c720c7e8SEric Dumazet 	__be32			inet_saddr;
17114c85021SArnaldo Carvalho de Melo 	__s16			uc_ttl;
17214c85021SArnaldo Carvalho de Melo 	__u16			cmsg_flags;
173c720c7e8SEric Dumazet 	__be16			inet_sport;
174c720c7e8SEric Dumazet 	__u16			inet_id;
175d218d111SStephen Hemminger 
176f6d8bd05SEric Dumazet 	struct ip_options_rcu __rcu	*inet_opt;
177ce43b03eSEric Dumazet 	int			rx_dst_ifindex;
17814c85021SArnaldo Carvalho de Melo 	__u8			tos;
179d218d111SStephen Hemminger 	__u8			min_ttl;
18014c85021SArnaldo Carvalho de Melo 	__u8			mc_ttl;
18114c85021SArnaldo Carvalho de Melo 	__u8			pmtudisc;
18214c85021SArnaldo Carvalho de Melo 	__u8			recverr:1,
18314c85021SArnaldo Carvalho de Melo 				is_icsk:1,
18414c85021SArnaldo Carvalho de Melo 				freebind:1,
18514c85021SArnaldo Carvalho de Melo 				hdrincl:1,
186f5715aeaSKOVACS Krisztian 				mc_loop:1,
187f771bef9SNivedita Singhvi 				transparent:1,
1887b2ff18eSJiri Olsa 				mc_all:1,
1897b2ff18eSJiri Olsa 				nodefrag:1;
19090c337daSEric Dumazet 	__u8			bind_address_no_port:1;
1914c507d28SJiri Benc 	__u8			rcv_tos;
192224d019cSTom Herbert 	__u8			convert_csum;
19376e21053SErich E. Hoover 	int			uc_index;
19414c85021SArnaldo Carvalho de Melo 	int			mc_index;
195011a9261SAl Viro 	__be32			mc_addr;
1961d7138deSEric Dumazet 	struct ip_mc_socklist __rcu	*mc_list;
197bdc712b4SDavid S. Miller 	struct inet_cork_full	cork;
19814c85021SArnaldo Carvalho de Melo };
19914c85021SArnaldo Carvalho de Melo 
20014c85021SArnaldo Carvalho de Melo #define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
20114c85021SArnaldo Carvalho de Melo #define IPCORK_ALLFRAG	2	/* always fragment (for ipv6 for now) */
20214c85021SArnaldo Carvalho de Melo 
203c44d13d6STom Herbert /* cmsg flags for inet */
204c44d13d6STom Herbert #define IP_CMSG_PKTINFO		BIT(0)
205c44d13d6STom Herbert #define IP_CMSG_TTL		BIT(1)
206c44d13d6STom Herbert #define IP_CMSG_TOS		BIT(2)
207c44d13d6STom Herbert #define IP_CMSG_RECVOPTS	BIT(3)
208c44d13d6STom Herbert #define IP_CMSG_RETOPTS		BIT(4)
209c44d13d6STom Herbert #define IP_CMSG_PASSSEC		BIT(5)
210c44d13d6STom Herbert #define IP_CMSG_ORIGDSTADDR	BIT(6)
211ad6f939aSTom Herbert #define IP_CMSG_CHECKSUM	BIT(7)
212c44d13d6STom Herbert 
21354abc686SEric Dumazet /* SYNACK messages might be attached to request sockets.
21454abc686SEric Dumazet  * Some places want to reach the listener in this case.
21554abc686SEric Dumazet  */
21654abc686SEric Dumazet static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
21754abc686SEric Dumazet {
21854abc686SEric Dumazet 	struct sock *sk = skb->sk;
21954abc686SEric Dumazet 
22054abc686SEric Dumazet 	if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
22154abc686SEric Dumazet 		sk = inet_reqsk(sk)->rsk_listener;
22254abc686SEric Dumazet 	return sk;
22354abc686SEric Dumazet }
22454abc686SEric Dumazet 
22514c85021SArnaldo Carvalho de Melo static inline struct inet_sock *inet_sk(const struct sock *sk)
22614c85021SArnaldo Carvalho de Melo {
22714c85021SArnaldo Carvalho de Melo 	return (struct inet_sock *)sk;
22814c85021SArnaldo Carvalho de Melo }
22914c85021SArnaldo Carvalho de Melo 
23014c85021SArnaldo Carvalho de Melo static inline void __inet_sk_copy_descendant(struct sock *sk_to,
23114c85021SArnaldo Carvalho de Melo 					     const struct sock *sk_from,
23214c85021SArnaldo Carvalho de Melo 					     const int ancestor_size)
23314c85021SArnaldo Carvalho de Melo {
23414c85021SArnaldo Carvalho de Melo 	memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
23514c85021SArnaldo Carvalho de Melo 	       sk_from->sk_prot->obj_size - ancestor_size);
23614c85021SArnaldo Carvalho de Melo }
237dfd56b8bSEric Dumazet #if !(IS_ENABLED(CONFIG_IPV6))
23814c85021SArnaldo Carvalho de Melo static inline void inet_sk_copy_descendant(struct sock *sk_to,
23914c85021SArnaldo Carvalho de Melo 					   const struct sock *sk_from)
24014c85021SArnaldo Carvalho de Melo {
24114c85021SArnaldo Carvalho de Melo 	__inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
24214c85021SArnaldo Carvalho de Melo }
24314c85021SArnaldo Carvalho de Melo #endif
24414c85021SArnaldo Carvalho de Melo 
2451fd51155SJoe Perches int inet_sk_rebuild_header(struct sock *sk);
24614c85021SArnaldo Carvalho de Melo 
24765cd8033SHannes Frederic Sowa static inline unsigned int __inet_ehashfn(const __be32 laddr,
24865cd8033SHannes Frederic Sowa 					  const __u16 lport,
24965cd8033SHannes Frederic Sowa 					  const __be32 faddr,
25065cd8033SHannes Frederic Sowa 					  const __be16 fport,
25165cd8033SHannes Frederic Sowa 					  u32 initval)
25214c85021SArnaldo Carvalho de Melo {
2537adc3830SDavid S. Miller 	return jhash_3words((__force __u32) laddr,
2547adc3830SDavid S. Miller 			    (__force __u32) faddr,
255b3da2cf3SDavid S. Miller 			    ((__u32) lport) << 16 | (__force __u32)fport,
25665cd8033SHannes Frederic Sowa 			    initval);
25714c85021SArnaldo Carvalho de Melo }
25814c85021SArnaldo Carvalho de Melo 
259e49bb337SEric Dumazet struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
260a1a5344dSEric Dumazet 				      struct sock *sk_listener,
261a1a5344dSEric Dumazet 				      bool attach_listener);
262ce4a7d0dSArnaldo Carvalho de Melo 
26388ef4a5aSKOVACS Krisztian static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
26488ef4a5aSKOVACS Krisztian {
265a4daad6bSDavid S. Miller 	__u8 flags = 0;
266a4daad6bSDavid S. Miller 
26747670b76SJulian Anastasov 	if (inet_sk(sk)->transparent || inet_sk(sk)->hdrincl)
268a4daad6bSDavid S. Miller 		flags |= FLOWI_FLAG_ANYSRC;
269a4daad6bSDavid S. Miller 	return flags;
27088ef4a5aSKOVACS Krisztian }
27188ef4a5aSKOVACS Krisztian 
272224d019cSTom Herbert static inline void inet_inc_convert_csum(struct sock *sk)
273224d019cSTom Herbert {
274224d019cSTom Herbert 	inet_sk(sk)->convert_csum++;
275224d019cSTom Herbert }
276224d019cSTom Herbert 
277224d019cSTom Herbert static inline void inet_dec_convert_csum(struct sock *sk)
278224d019cSTom Herbert {
279224d019cSTom Herbert 	if (inet_sk(sk)->convert_csum > 0)
280224d019cSTom Herbert 		inet_sk(sk)->convert_csum--;
281224d019cSTom Herbert }
282224d019cSTom Herbert 
283224d019cSTom Herbert static inline bool inet_get_convert_csum(struct sock *sk)
284224d019cSTom Herbert {
285224d019cSTom Herbert 	return !!inet_sk(sk)->convert_csum;
286224d019cSTom Herbert }
287224d019cSTom Herbert 
28814c85021SArnaldo Carvalho de Melo #endif	/* _INET_SOCK_H */
289