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