12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * INET An implementation of the TCP/IP protocol suite for the LINUX 41da177e4SLinus Torvalds * operating system. INET is implemented using the BSD Socket 51da177e4SLinus Torvalds * interface as the means of communication with the user level. 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * Definitions for the IP module. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * Version: @(#)ip.h 1.0.2 05/07/93 101da177e4SLinus Torvalds * 1102c30a84SJesper Juhl * Authors: Ross Biro 121da177e4SLinus Torvalds * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 131da177e4SLinus Torvalds * Alan Cox, <gw4pts@gw4pts.ampr.org> 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * Changes: 161da177e4SLinus Torvalds * Mike McLagan : Routing by source 171da177e4SLinus Torvalds */ 181da177e4SLinus Torvalds #ifndef _IP_H 191da177e4SLinus Torvalds #define _IP_H 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #include <linux/types.h> 221da177e4SLinus Torvalds #include <linux/ip.h> 231da177e4SLinus Torvalds #include <linux/in.h> 24c9bdd4b5SArnaldo Carvalho de Melo #include <linux/skbuff.h> 25f0b1e64cSMartin KaFai Lau #include <linux/jhash.h> 2614c85021SArnaldo Carvalho de Melo 2714c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h> 28aa661581SFrancesco Fusco #include <net/route.h> 291da177e4SLinus Torvalds #include <net/snmp.h> 3086b08d86SKOVACS Krisztian #include <net/flow.h> 311bd758ebSJiri Pirko #include <net/flow_dissector.h> 32f0b1e64cSMartin KaFai Lau #include <net/netns/hash.h> 331da177e4SLinus Torvalds 347ed14d97SGao Feng #define IPV4_MAX_PMTU 65535U /* RFC 2675, Section 5.1 */ 35b5476022SEric Dumazet #define IPV4_MIN_MTU 68 /* RFC 791 */ 367ed14d97SGao Feng 379ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem; 389ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_min; 399ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_max; 409ab948a9SDavid Ahern 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 91c6af0c22SWillem de Bruijn ipcm->sockc.mark = inet->sk.sk_mark; 9235178206SWillem de Bruijn ipcm->sockc.tsflags = inet->sk.sk_tsflags; 9335178206SWillem de Bruijn ipcm->oif = inet->sk.sk_bound_dev_if; 9435178206SWillem de Bruijn ipcm->addr = inet->inet_saddr; 9535178206SWillem de Bruijn } 9635178206SWillem de Bruijn 971da177e4SLinus Torvalds #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) 984b261c75SHannes Frederic Sowa #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb)) 991da177e4SLinus Torvalds 100fb74c277SDavid Ahern /* return enslaved device index if relevant */ 101fb74c277SDavid Ahern static inline int inet_sdif(struct sk_buff *skb) 102fb74c277SDavid Ahern { 103fb74c277SDavid Ahern #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) 104fb74c277SDavid Ahern if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags)) 105fb74c277SDavid Ahern return IPCB(skb)->iif; 106fb74c277SDavid Ahern #endif 107fb74c277SDavid Ahern return 0; 108fb74c277SDavid Ahern } 109fb74c277SDavid Ahern 1105796ef75SKirill Tkhai /* Special input handler for packets caught by router alert option. 1115796ef75SKirill Tkhai They are selected only by protocol field, and then processed likely 1125796ef75SKirill Tkhai local ones; but only if someone wants them! Otherwise, router 1135796ef75SKirill Tkhai not running rsvpd will kill RSVP. 1145796ef75SKirill Tkhai 1155796ef75SKirill Tkhai It is user level problem, what it will make with them. 1165796ef75SKirill Tkhai I have no idea, how it will masquearde or NAT them (it is joke, joke :-)), 1175796ef75SKirill Tkhai but receiver should be enough clever f.e. to forward mtrace requests, 1185796ef75SKirill Tkhai sent to multicast group to reach destination designated router. 1195796ef75SKirill Tkhai */ 1205796ef75SKirill Tkhai 121fd2c3ef7SEric Dumazet struct ip_ra_chain { 12243a951e9SEric Dumazet struct ip_ra_chain __rcu *next; 1231da177e4SLinus Torvalds struct sock *sk; 124592fcb9dSEric Dumazet union { 1251da177e4SLinus Torvalds void (*destructor)(struct sock *); 126592fcb9dSEric Dumazet struct sock *saved_sk; 127592fcb9dSEric Dumazet }; 12866018506SEric Dumazet struct rcu_head rcu; 1291da177e4SLinus Torvalds }; 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds /* IP flags. */ 1321da177e4SLinus Torvalds #define IP_CE 0x8000 /* Flag: "Congestion" */ 1331da177e4SLinus Torvalds #define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 1341da177e4SLinus Torvalds #define IP_MF 0x2000 /* Flag: "More Fragments" */ 1351da177e4SLinus Torvalds #define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ 1381da177e4SLinus Torvalds 13914c85021SArnaldo Carvalho de Melo struct msghdr; 14014c85021SArnaldo Carvalho de Melo struct net_device; 14114c85021SArnaldo Carvalho de Melo struct packet_type; 14214c85021SArnaldo Carvalho de Melo struct rtable; 14314c85021SArnaldo Carvalho de Melo struct sockaddr; 14414c85021SArnaldo Carvalho de Melo 14572c1d3bdSWANG Cong int igmp_mc_init(void); 1461da177e4SLinus Torvalds 1471da177e4SLinus Torvalds /* 1481da177e4SLinus Torvalds * Functions provided by ip.c 1491da177e4SLinus Torvalds */ 1501da177e4SLinus Torvalds 151cfe673b0SEric Dumazet int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, 15213d8eaa0SAl Viro __be32 saddr, __be32 daddr, 153f6d8bd05SEric Dumazet struct ip_options_rcu *opt); 1545c3a0fd7SJoe Perches int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, 1555c3a0fd7SJoe Perches struct net_device *orig_dev); 15617266ee9SEdward Cree void ip_list_rcv(struct list_head *head, struct packet_type *pt, 15717266ee9SEdward Cree struct net_device *orig_dev); 1585c3a0fd7SJoe Perches int ip_local_deliver(struct sk_buff *skb); 15968cb7d53SPaolo Abeni void ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int proto); 1605c3a0fd7SJoe Perches int ip_mr_input(struct sk_buff *skb); 161ede2059dSEric W. Biederman int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb); 162ede2059dSEric W. Biederman int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb); 163694869b3SEric W. Biederman int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, 164694869b3SEric W. Biederman int (*output)(struct net *, struct sock *, struct sk_buff *)); 165c8b17be0SPablo Neira Ayuso 166c8b17be0SPablo Neira Ayuso struct ip_fraglist_iter { 167c8b17be0SPablo Neira Ayuso struct sk_buff *frag; 168c8b17be0SPablo Neira Ayuso struct iphdr *iph; 169c8b17be0SPablo Neira Ayuso int offset; 170c8b17be0SPablo Neira Ayuso unsigned int hlen; 171c8b17be0SPablo Neira Ayuso }; 172c8b17be0SPablo Neira Ayuso 173c8b17be0SPablo Neira Ayuso void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph, 174c8b17be0SPablo Neira Ayuso unsigned int hlen, struct ip_fraglist_iter *iter); 175c8b17be0SPablo Neira Ayuso void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter); 176c8b17be0SPablo Neira Ayuso 177c8b17be0SPablo Neira Ayuso static inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter) 178c8b17be0SPablo Neira Ayuso { 179c8b17be0SPablo Neira Ayuso struct sk_buff *skb = iter->frag; 180c8b17be0SPablo Neira Ayuso 181c8b17be0SPablo Neira Ayuso iter->frag = skb->next; 182c8b17be0SPablo Neira Ayuso skb_mark_not_on_list(skb); 183c8b17be0SPablo Neira Ayuso 184c8b17be0SPablo Neira Ayuso return skb; 185c8b17be0SPablo Neira Ayuso } 186c8b17be0SPablo Neira Ayuso 187065ff79fSPablo Neira Ayuso struct ip_frag_state { 188e7a409c3SEric Dumazet bool DF; 189065ff79fSPablo Neira Ayuso unsigned int hlen; 190065ff79fSPablo Neira Ayuso unsigned int ll_rs; 191065ff79fSPablo Neira Ayuso unsigned int mtu; 192065ff79fSPablo Neira Ayuso unsigned int left; 193065ff79fSPablo Neira Ayuso int offset; 194065ff79fSPablo Neira Ayuso int ptr; 195065ff79fSPablo Neira Ayuso __be16 not_last_frag; 196065ff79fSPablo Neira Ayuso }; 197065ff79fSPablo Neira Ayuso 198065ff79fSPablo Neira Ayuso void ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs, 199e7a409c3SEric Dumazet unsigned int mtu, bool DF, struct ip_frag_state *state); 200065ff79fSPablo Neira Ayuso struct sk_buff *ip_frag_next(struct sk_buff *skb, 201065ff79fSPablo Neira Ayuso struct ip_frag_state *state); 202065ff79fSPablo Neira Ayuso 2035c3a0fd7SJoe Perches void ip_send_check(struct iphdr *ip); 204cf91a99dSEric W. Biederman int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 20533224b16SEric W. Biederman int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 206aad88724SEric Dumazet 20769b9e1e0SXin Long int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 20869b9e1e0SXin Long __u8 tos); 2095c3a0fd7SJoe Perches void ip_init(void); 2105c3a0fd7SJoe Perches int ip_append_data(struct sock *sk, struct flowi4 *fl4, 2111da177e4SLinus Torvalds int getfrag(void *from, char *to, int offset, int len, 2121da177e4SLinus Torvalds int odd, struct sk_buff *skb), 2131da177e4SLinus Torvalds void *from, int len, int protolen, 2141da177e4SLinus Torvalds struct ipcm_cookie *ipc, 2152e77d89bSEric Dumazet struct rtable **rt, 2161da177e4SLinus Torvalds unsigned int flags); 2175c3a0fd7SJoe Perches int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, 2185c3a0fd7SJoe Perches struct sk_buff *skb); 2195c3a0fd7SJoe Perches ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, 2201da177e4SLinus Torvalds int offset, size_t size, int flags); 2215c3a0fd7SJoe Perches struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2221c32c5adSHerbert Xu struct sk_buff_head *queue, 2231c32c5adSHerbert Xu struct inet_cork *cork); 2245c3a0fd7SJoe Perches int ip_send_skb(struct net *net, struct sk_buff *skb); 2255c3a0fd7SJoe Perches int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); 2265c3a0fd7SJoe Perches void ip_flush_pending_frames(struct sock *sk); 2275c3a0fd7SJoe Perches struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2285c3a0fd7SJoe Perches int getfrag(void *from, char *to, int offset, 2295c3a0fd7SJoe Perches int len, int odd, struct sk_buff *skb), 2301c32c5adSHerbert Xu void *from, int length, int transhdrlen, 2315c3a0fd7SJoe Perches struct ipcm_cookie *ipc, struct rtable **rtp, 2321cd7884dSWillem de Bruijn struct inet_cork *cork, unsigned int flags); 2331c32c5adSHerbert Xu 23469b9e1e0SXin Long static inline int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, 23569b9e1e0SXin Long struct flowi *fl) 23669b9e1e0SXin Long { 23769b9e1e0SXin Long return __ip_queue_xmit(sk, skb, fl, inet_sk(sk)->tos); 23869b9e1e0SXin Long } 23969b9e1e0SXin Long 24077968b78SDavid S. Miller static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) 2411c32c5adSHerbert Xu { 24277968b78SDavid S. Miller return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base); 2431c32c5adSHerbert Xu } 2441da177e4SLinus Torvalds 245aa661581SFrancesco Fusco static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet) 246aa661581SFrancesco Fusco { 247aa661581SFrancesco Fusco return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos); 248aa661581SFrancesco Fusco } 249aa661581SFrancesco Fusco 250aa661581SFrancesco Fusco static inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk) 251aa661581SFrancesco Fusco { 252aa661581SFrancesco Fusco return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk); 253aa661581SFrancesco Fusco } 254aa661581SFrancesco Fusco 2551da177e4SLinus Torvalds /* datagram.c */ 25603645a11SEric Dumazet int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); 2575c3a0fd7SJoe Perches int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); 2581da177e4SLinus Torvalds 2595c3a0fd7SJoe Perches void ip4_datagram_release_cb(struct sock *sk); 2608141ed9fSSteffen Klassert 2611da177e4SLinus Torvalds struct ip_reply_arg { 2621da177e4SLinus Torvalds struct kvec iov[1]; 26388ef4a5aSKOVACS Krisztian int flags; 264d6f5493cSAl Viro __wsum csum; 2651da177e4SLinus Torvalds int csumoffset; /* u16 offset of csum in iov[0].iov_base */ 2661da177e4SLinus Torvalds /* -1 if not needed */ 267f0e48dbfSPatrick McHardy int bound_dev_if; 26866b13d99SEric Dumazet u8 tos; 269e2d118a1SLorenzo Colitti kuid_t uid; 2701da177e4SLinus Torvalds }; 2711da177e4SLinus Torvalds 27288ef4a5aSKOVACS Krisztian #define IP_REPLY_ARG_NOSRCCHECK 1 27388ef4a5aSKOVACS Krisztian 27486b08d86SKOVACS Krisztian static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) 27586b08d86SKOVACS Krisztian { 27686b08d86SKOVACS Krisztian return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0; 27786b08d86SKOVACS Krisztian } 27886b08d86SKOVACS Krisztian 279bdbbb852SEric Dumazet void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, 28024a2d43dSEric Dumazet const struct ip_options *sopt, 28124a2d43dSEric Dumazet __be32 daddr, __be32 saddr, 28224a2d43dSEric Dumazet const struct ip_reply_arg *arg, 283d6fb396cSEric Dumazet unsigned int len, u64 transmit_time); 2841da177e4SLinus Torvalds 2854ce3c183SEric Dumazet #define IP_INC_STATS(net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field) 28613415e46SEric Dumazet #define __IP_INC_STATS(net, field) __SNMP_INC_STATS64((net)->mib.ip_statistics, field) 2874ce3c183SEric Dumazet #define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val) 28813415e46SEric Dumazet #define __IP_ADD_STATS(net, field, val) __SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val) 2894ce3c183SEric Dumazet #define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val) 29013415e46SEric Dumazet #define __IP_UPD_PO_STATS(net, field, val) __SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val) 29161a7e260SPavel Emelyanov #define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field) 29213415e46SEric Dumazet #define __NET_INC_STATS(net, field) __SNMP_INC_STATS((net)->mib.net_statistics, field) 293f7324acdSDavid S. Miller #define NET_ADD_STATS(net, field, adnd) SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) 29413415e46SEric Dumazet #define __NET_ADD_STATS(net, field, adnd) __SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) 2951da177e4SLinus Torvalds 296c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offct); 297698365faSWANG Cong unsigned long snmp_fold_field(void __percpu *mib, int offt); 2984ce3c183SEric Dumazet #if BITS_PER_LONG==32 299c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 300c4c6bc31SRaghavendra K T size_t syncp_offset); 301698365faSWANG Cong u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off); 3024ce3c183SEric Dumazet #else 303c4c6bc31SRaghavendra K T static inline u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 304c4c6bc31SRaghavendra K T size_t syncp_offset) 305c4c6bc31SRaghavendra K T { 306c4c6bc31SRaghavendra K T return snmp_get_cpu_field(mib, cpu, offct); 307c4c6bc31SRaghavendra K T 308c4c6bc31SRaghavendra K T } 309c4c6bc31SRaghavendra K T 310698365faSWANG Cong static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off) 3114ce3c183SEric Dumazet { 3124ce3c183SEric Dumazet return snmp_fold_field(mib, offt); 3134ce3c183SEric Dumazet } 3144ce3c183SEric Dumazet #endif 31533490170SYOSHIFUJI Hideaki 3166348ef2dSJia He #define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \ 3176348ef2dSJia He { \ 3186348ef2dSJia He int i, c; \ 3196348ef2dSJia He for_each_possible_cpu(c) { \ 3206348ef2dSJia He for (i = 0; stats_list[i].name; i++) \ 3216348ef2dSJia He buff64[i] += snmp_get_cpu_field64( \ 3226348ef2dSJia He mib_statistic, \ 3236348ef2dSJia He c, stats_list[i].entry, \ 3246348ef2dSJia He offset); \ 3256348ef2dSJia He } \ 3266348ef2dSJia He } 3276348ef2dSJia He 3286348ef2dSJia He #define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \ 3296348ef2dSJia He { \ 3306348ef2dSJia He int i, c; \ 3316348ef2dSJia He for_each_possible_cpu(c) { \ 3326348ef2dSJia He for (i = 0; stats_list[i].name; i++) \ 3336348ef2dSJia He buff[i] += snmp_get_cpu_field( \ 3346348ef2dSJia He mib_statistic, \ 3356348ef2dSJia He c, stats_list[i].entry); \ 3366348ef2dSJia He } \ 3376348ef2dSJia He } 3386348ef2dSJia He 3390bbf87d8SEric W. Biederman void inet_get_local_port_range(struct net *net, int *low, int *high); 340227b60f5SStephen Hemminger 341fcd77db0SDavid S. Miller #ifdef CONFIG_SYSCTL 34266e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 343e3826f1eSAmerigo Wang { 344122ff243SWANG Cong if (!net->ipv4.sysctl_local_reserved_ports) 34530429fbaSMaciej Żenczykowski return false; 346122ff243SWANG Cong return test_bit(port, net->ipv4.sysctl_local_reserved_ports); 347e3826f1eSAmerigo Wang } 34820e61da7SWANG Cong 34920e61da7SWANG Cong static inline bool sysctl_dev_name_is_allowed(const char *name) 35020e61da7SWANG Cong { 35120e61da7SWANG Cong return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; 35220e61da7SWANG Cong } 35320e61da7SWANG Cong 35482f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3554548b683SKrister Johansen { 35682f31ebfSMaciej Żenczykowski return port < net->ipv4.sysctl_ip_prot_sock; 3574548b683SKrister Johansen } 3584548b683SKrister Johansen 359122ff243SWANG Cong #else 36066e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 361122ff243SWANG Cong { 36230429fbaSMaciej Żenczykowski return false; 363122ff243SWANG Cong } 3644548b683SKrister Johansen 36582f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3664548b683SKrister Johansen { 36782f31ebfSMaciej Żenczykowski return port < PROT_SOCK; 3684548b683SKrister Johansen } 369122ff243SWANG Cong #endif 370e3826f1eSAmerigo Wang 371822c8685SDeepa Dinamani __be32 inet_current_timestamp(void); 372822c8685SDeepa Dinamani 37320380731SArnaldo Carvalho de Melo /* From inetpeer.c */ 37420380731SArnaldo Carvalho de Melo extern int inet_peer_threshold; 37520380731SArnaldo Carvalho de Melo extern int inet_peer_minttl; 37620380731SArnaldo Carvalho de Melo extern int inet_peer_maxttl; 37720380731SArnaldo Carvalho de Melo 3785c3a0fd7SJoe Perches void ipfrag_init(void); 37920380731SArnaldo Carvalho de Melo 3805c3a0fd7SJoe Perches void ip_static_sysctl_init(void); 381bd7b1533SAl Viro 382e110861fSLorenzo Colitti #define IP4_REPLY_MARK(net, mark) \ 383e110861fSLorenzo Colitti ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0) 384e110861fSLorenzo Colitti 385d18cd551SDavid S. Miller static inline bool ip_is_fragment(const struct iphdr *iph) 386d18cd551SDavid S. Miller { 387d18cd551SDavid S. Miller return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; 388d18cd551SDavid S. Miller } 389d18cd551SDavid S. Miller 3901da177e4SLinus Torvalds #ifdef CONFIG_INET 39114c85021SArnaldo Carvalho de Melo #include <net/dst.h> 39214c85021SArnaldo Carvalho de Melo 3931da177e4SLinus Torvalds /* The function in 2.2 was invalid, producing wrong result for 3941da177e4SLinus Torvalds * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ 3951da177e4SLinus Torvalds static inline 3961da177e4SLinus Torvalds int ip_decrease_ttl(struct iphdr *iph) 3971da177e4SLinus Torvalds { 3985c78f275SAl Viro u32 check = (__force u32)iph->check; 3995c78f275SAl Viro check += (__force u32)htons(0x0100); 4005c78f275SAl Viro iph->check = (__force __sum16)(check + (check>=0xFFFF)); 4011da177e4SLinus Torvalds return --iph->ttl; 4021da177e4SLinus Torvalds } 4031da177e4SLinus Torvalds 404d52e5a7eSSabrina Dubroca static inline int ip_mtu_locked(const struct dst_entry *dst) 405d52e5a7eSSabrina Dubroca { 406d52e5a7eSSabrina Dubroca const struct rtable *rt = (const struct rtable *)dst; 407d52e5a7eSSabrina Dubroca 408d52e5a7eSSabrina Dubroca return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU); 409d52e5a7eSSabrina Dubroca } 410d52e5a7eSSabrina Dubroca 4111da177e4SLinus Torvalds static inline 4124e3f5d72SEric Dumazet int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) 4131da177e4SLinus Torvalds { 4144e3f5d72SEric Dumazet u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc); 4154e3f5d72SEric Dumazet 4164e3f5d72SEric Dumazet return pmtudisc == IP_PMTUDISC_DO || 4174e3f5d72SEric Dumazet (pmtudisc == IP_PMTUDISC_WANT && 418d52e5a7eSSabrina Dubroca !ip_mtu_locked(dst)); 4191da177e4SLinus Torvalds } 4201da177e4SLinus Torvalds 421f87c10a8SHannes Frederic Sowa static inline bool ip_sk_accept_pmtu(const struct sock *sk) 422f87c10a8SHannes Frederic Sowa { 4231b346576SHannes Frederic Sowa return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE && 4241b346576SHannes Frederic Sowa inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT; 425f87c10a8SHannes Frederic Sowa } 426f87c10a8SHannes Frederic Sowa 427f87c10a8SHannes Frederic Sowa static inline bool ip_sk_use_pmtu(const struct sock *sk) 428f87c10a8SHannes Frederic Sowa { 429f87c10a8SHannes Frederic Sowa return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; 430f87c10a8SHannes Frederic Sowa } 431f87c10a8SHannes Frederic Sowa 43260ff7467SWANG Cong static inline bool ip_sk_ignore_df(const struct sock *sk) 4331b346576SHannes Frederic Sowa { 4341b346576SHannes Frederic Sowa return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO || 4351b346576SHannes Frederic Sowa inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT; 4361b346576SHannes Frederic Sowa } 4371b346576SHannes Frederic Sowa 438f87c10a8SHannes Frederic Sowa static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, 439f87c10a8SHannes Frederic Sowa bool forwarding) 440f87c10a8SHannes Frederic Sowa { 441f87c10a8SHannes Frederic Sowa struct net *net = dev_net(dst->dev); 442f87c10a8SHannes Frederic Sowa 443f87c10a8SHannes Frederic Sowa if (net->ipv4.sysctl_ip_fwd_use_pmtu || 444d52e5a7eSSabrina Dubroca ip_mtu_locked(dst) || 445f87c10a8SHannes Frederic Sowa !forwarding) 446f87c10a8SHannes Frederic Sowa return dst_mtu(dst); 447f87c10a8SHannes Frederic Sowa 448c780a049SEric Dumazet return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU); 449f87c10a8SHannes Frederic Sowa } 450f87c10a8SHannes Frederic Sowa 451fedbb6b4SShmulik Ladkani static inline unsigned int ip_skb_dst_mtu(struct sock *sk, 452fedbb6b4SShmulik Ladkani const struct sk_buff *skb) 453f87c10a8SHannes Frederic Sowa { 454caf3f267SEric Dumazet if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { 455f87c10a8SHannes Frederic Sowa bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; 456caf3f267SEric Dumazet 457f87c10a8SHannes Frederic Sowa return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); 458f87c10a8SHannes Frederic Sowa } 459caf3f267SEric Dumazet 460c780a049SEric Dumazet return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU); 461f87c10a8SHannes Frederic Sowa } 462f87c10a8SHannes Frederic Sowa 463767a2217SDavid Ahern struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, 464d7e774f3SDavid Ahern int fc_mx_len, 465d7e774f3SDavid Ahern struct netlink_ext_ack *extack); 466cc5f0eb2SDavid Ahern static inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics) 467cc5f0eb2SDavid Ahern { 468cc5f0eb2SDavid Ahern if (fib_metrics != &dst_default_metrics && 469cc5f0eb2SDavid Ahern refcount_dec_and_test(&fib_metrics->refcnt)) 470cc5f0eb2SDavid Ahern kfree(fib_metrics); 471cc5f0eb2SDavid Ahern } 472a919525aSDavid Ahern 473e1255ed4SDavid Ahern /* ipv4 and ipv6 both use refcounted metrics if it is not the default */ 474e1255ed4SDavid Ahern static inline 475e1255ed4SDavid Ahern void ip_dst_init_metrics(struct dst_entry *dst, struct dst_metrics *fib_metrics) 476e1255ed4SDavid Ahern { 477e1255ed4SDavid Ahern dst_init_metrics(dst, fib_metrics->metrics, true); 478e1255ed4SDavid Ahern 479e1255ed4SDavid Ahern if (fib_metrics != &dst_default_metrics) { 480e1255ed4SDavid Ahern dst->_metrics |= DST_METRICS_REFCOUNTED; 481e1255ed4SDavid Ahern refcount_inc(&fib_metrics->refcnt); 482e1255ed4SDavid Ahern } 483e1255ed4SDavid Ahern } 484e1255ed4SDavid Ahern 4851620a336SDavid Ahern static inline 4861620a336SDavid Ahern void ip_dst_metrics_put(struct dst_entry *dst) 4871620a336SDavid Ahern { 4881620a336SDavid Ahern struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); 4891620a336SDavid Ahern 4901620a336SDavid Ahern if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) 4911620a336SDavid Ahern kfree(p); 4921620a336SDavid Ahern } 4931620a336SDavid Ahern 49404ca6973SEric Dumazet u32 ip_idents_reserve(u32 hash, int segs); 495b6a7719aSHannes Frederic Sowa void __ip_select_ident(struct net *net, struct iphdr *iph, int segs); 49673f156a6SEric Dumazet 497b6a7719aSHannes Frederic Sowa static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, 498b6a7719aSHannes Frederic Sowa struct sock *sk, int segs) 4991da177e4SLinus Torvalds { 500703133deSAnsis Atteka struct iphdr *iph = ip_hdr(skb); 501703133deSAnsis Atteka 50260ff7467SWANG Cong if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { 5031da177e4SLinus Torvalds /* This is only to work around buggy Windows95/2000 5041da177e4SLinus Torvalds * VJ compression implementations. If the ID field 5051da177e4SLinus Torvalds * does not change, they drop every other packet in 5061da177e4SLinus Torvalds * a TCP stream using header compression. 5071da177e4SLinus Torvalds */ 508c720c7e8SEric Dumazet if (sk && inet_sk(sk)->inet_daddr) { 509c720c7e8SEric Dumazet iph->id = htons(inet_sk(sk)->inet_id); 51073f156a6SEric Dumazet inet_sk(sk)->inet_id += segs; 51173f156a6SEric Dumazet } else { 5121da177e4SLinus Torvalds iph->id = 0; 51373f156a6SEric Dumazet } 51473f156a6SEric Dumazet } else { 515b6a7719aSHannes Frederic Sowa __ip_select_ident(net, iph, segs); 51673f156a6SEric Dumazet } 51773f156a6SEric Dumazet } 51873f156a6SEric Dumazet 519b6a7719aSHannes Frederic Sowa static inline void ip_select_ident(struct net *net, struct sk_buff *skb, 520b6a7719aSHannes Frederic Sowa struct sock *sk) 52173f156a6SEric Dumazet { 522b6a7719aSHannes Frederic Sowa ip_select_ident_segs(net, skb, sk, 1); 5231da177e4SLinus Torvalds } 5241da177e4SLinus Torvalds 525ed70fcfcSTom Herbert static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto) 526ed70fcfcSTom Herbert { 527ed70fcfcSTom Herbert return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 528ed70fcfcSTom Herbert skb->len, proto, 0); 529ed70fcfcSTom Herbert } 530ed70fcfcSTom Herbert 531c3f83241STom Herbert /* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store 532c3f83241STom Herbert * Equivalent to : flow->v4addrs.src = iph->saddr; 533c3f83241STom Herbert * flow->v4addrs.dst = iph->daddr; 534c3f83241STom Herbert */ 535c3f83241STom Herbert static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow, 536c3f83241STom Herbert const struct iphdr *iph) 537c3f83241STom Herbert { 538c3f83241STom Herbert BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) != 539c3f83241STom Herbert offsetof(typeof(flow->addrs), v4addrs.src) + 540c3f83241STom Herbert sizeof(flow->addrs.v4addrs.src)); 541c3f83241STom Herbert memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs)); 542c3f83241STom Herbert flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 543c3f83241STom Herbert } 544c3f83241STom Herbert 5451933a785STom Herbert static inline __wsum inet_gro_compute_pseudo(struct sk_buff *skb, int proto) 5461933a785STom Herbert { 5471933a785STom Herbert const struct iphdr *iph = skb_gro_network_header(skb); 5481933a785STom Herbert 5491933a785STom Herbert return csum_tcpudp_nofold(iph->saddr, iph->daddr, 5501933a785STom Herbert skb_gro_len(skb), proto, 0); 5511933a785STom Herbert } 5521933a785STom Herbert 5531da177e4SLinus Torvalds /* 5541da177e4SLinus Torvalds * Map a multicast IP onto multicast MAC for type ethernet. 5551da177e4SLinus Torvalds */ 5561da177e4SLinus Torvalds 557714e85beSAl Viro static inline void ip_eth_mc_map(__be32 naddr, char *buf) 5581da177e4SLinus Torvalds { 559714e85beSAl Viro __u32 addr=ntohl(naddr); 5601da177e4SLinus Torvalds buf[0]=0x01; 5611da177e4SLinus Torvalds buf[1]=0x00; 5621da177e4SLinus Torvalds buf[2]=0x5e; 5631da177e4SLinus Torvalds buf[5]=addr&0xFF; 5641da177e4SLinus Torvalds addr>>=8; 5651da177e4SLinus Torvalds buf[4]=addr&0xFF; 5661da177e4SLinus Torvalds addr>>=8; 5671da177e4SLinus Torvalds buf[3]=addr&0x7F; 5681da177e4SLinus Torvalds } 5691da177e4SLinus Torvalds 5701da177e4SLinus Torvalds /* 5711da177e4SLinus Torvalds * Map a multicast IP onto multicast MAC for type IP-over-InfiniBand. 5721da177e4SLinus Torvalds * Leave P_Key as 0 to be filled in by driver. 5731da177e4SLinus Torvalds */ 5741da177e4SLinus Torvalds 575a9e527e3SRolf Manderscheid static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 5761da177e4SLinus Torvalds { 577714e85beSAl Viro __u32 addr; 578a9e527e3SRolf Manderscheid unsigned char scope = broadcast[5] & 0xF; 579a9e527e3SRolf Manderscheid 5801da177e4SLinus Torvalds buf[0] = 0; /* Reserved */ 5811da177e4SLinus Torvalds buf[1] = 0xff; /* Multicast QPN */ 5821da177e4SLinus Torvalds buf[2] = 0xff; 5831da177e4SLinus Torvalds buf[3] = 0xff; 584714e85beSAl Viro addr = ntohl(naddr); 5851da177e4SLinus Torvalds buf[4] = 0xff; 586a9e527e3SRolf Manderscheid buf[5] = 0x10 | scope; /* scope from broadcast address */ 5871da177e4SLinus Torvalds buf[6] = 0x40; /* IPv4 signature */ 5881da177e4SLinus Torvalds buf[7] = 0x1b; 589a9e527e3SRolf Manderscheid buf[8] = broadcast[8]; /* P_Key */ 590a9e527e3SRolf Manderscheid buf[9] = broadcast[9]; 5911da177e4SLinus Torvalds buf[10] = 0; 5921da177e4SLinus Torvalds buf[11] = 0; 5931da177e4SLinus Torvalds buf[12] = 0; 5941da177e4SLinus Torvalds buf[13] = 0; 5951da177e4SLinus Torvalds buf[14] = 0; 5961da177e4SLinus Torvalds buf[15] = 0; 5971da177e4SLinus Torvalds buf[19] = addr & 0xff; 5981da177e4SLinus Torvalds addr >>= 8; 5991da177e4SLinus Torvalds buf[18] = addr & 0xff; 6001da177e4SLinus Torvalds addr >>= 8; 6011da177e4SLinus Torvalds buf[17] = addr & 0xff; 6021da177e4SLinus Torvalds addr >>= 8; 6031da177e4SLinus Torvalds buf[16] = addr & 0x0f; 6041da177e4SLinus Torvalds } 6051da177e4SLinus Torvalds 60693ca3bb5STimo Teräs static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 60793ca3bb5STimo Teräs { 60893ca3bb5STimo Teräs if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) 60993ca3bb5STimo Teräs memcpy(buf, broadcast, 4); 61093ca3bb5STimo Teräs else 61193ca3bb5STimo Teräs memcpy(buf, &naddr, sizeof(naddr)); 61293ca3bb5STimo Teräs } 61393ca3bb5STimo Teräs 614dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 6151da177e4SLinus Torvalds #include <linux/ipv6.h> 6161da177e4SLinus Torvalds #endif 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds static __inline__ void inet_reset_saddr(struct sock *sk) 6191da177e4SLinus Torvalds { 620c720c7e8SEric Dumazet inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0; 621dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 6221da177e4SLinus Torvalds if (sk->sk_family == PF_INET6) { 6231da177e4SLinus Torvalds struct ipv6_pinfo *np = inet6_sk(sk); 6241da177e4SLinus Torvalds 6251da177e4SLinus Torvalds memset(&np->saddr, 0, sizeof(np->saddr)); 626efe4208fSEric Dumazet memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr)); 6271da177e4SLinus Torvalds } 6281da177e4SLinus Torvalds #endif 6291da177e4SLinus Torvalds } 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds #endif 6321da177e4SLinus Torvalds 63372afa352SDavid Ahern static inline unsigned int ipv4_addr_hash(__be32 ip) 63472afa352SDavid Ahern { 63572afa352SDavid Ahern return (__force unsigned int) ip; 63672afa352SDavid Ahern } 63772afa352SDavid Ahern 638f0b1e64cSMartin KaFai Lau static inline u32 ipv4_portaddr_hash(const struct net *net, 639f0b1e64cSMartin KaFai Lau __be32 saddr, 640f0b1e64cSMartin KaFai Lau unsigned int port) 641f0b1e64cSMartin KaFai Lau { 642f0b1e64cSMartin KaFai Lau return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port; 643f0b1e64cSMartin KaFai Lau } 644f0b1e64cSMartin KaFai Lau 6455c3a0fd7SJoe Perches bool ip_call_ra_chain(struct sk_buff *skb); 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds /* 648b798232fSRami Rosen * Functions provided by ip_fragment.c 6491da177e4SLinus Torvalds */ 6501da177e4SLinus Torvalds 651fd2c3ef7SEric Dumazet enum ip_defrag_users { 6521da177e4SLinus Torvalds IP_DEFRAG_LOCAL_DELIVER, 6531da177e4SLinus Torvalds IP_DEFRAG_CALL_RA_CHAIN, 6541da177e4SLinus Torvalds IP_DEFRAG_CONNTRACK_IN, 6554be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHRT_MAX, 6561da177e4SLinus Torvalds IP_DEFRAG_CONNTRACK_OUT, 6574be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX, 6588fa9ff68SPatrick McHardy IP_DEFRAG_CONNTRACK_BRIDGE_IN, 6594be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, 6601da177e4SLinus Torvalds IP_DEFRAG_VS_IN, 6611da177e4SLinus Torvalds IP_DEFRAG_VS_OUT, 662595fc71bSDavid S. Miller IP_DEFRAG_VS_FWD, 663595fc71bSDavid S. Miller IP_DEFRAG_AF_PACKET, 664bc416d97SEric Dumazet IP_DEFRAG_MACVLAN, 6651da177e4SLinus Torvalds }; 6661da177e4SLinus Torvalds 6675cf42280SAndy Zhou /* Return true if the value of 'user' is between 'lower_bond' 6685cf42280SAndy Zhou * and 'upper_bond' inclusively. 6695cf42280SAndy Zhou */ 6705cf42280SAndy Zhou static inline bool ip_defrag_user_in_between(u32 user, 6715cf42280SAndy Zhou enum ip_defrag_users lower_bond, 6725cf42280SAndy Zhou enum ip_defrag_users upper_bond) 6735cf42280SAndy Zhou { 6745cf42280SAndy Zhou return user >= lower_bond && user <= upper_bond; 6755cf42280SAndy Zhou } 6765cf42280SAndy Zhou 67719bcf9f2SEric W. Biederman int ip_defrag(struct net *net, struct sk_buff *skb, u32 user); 678bc416d97SEric Dumazet #ifdef CONFIG_INET 67919bcf9f2SEric W. Biederman struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user); 680bc416d97SEric Dumazet #else 68119bcf9f2SEric W. Biederman static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user) 682bc416d97SEric Dumazet { 683bc416d97SEric Dumazet return skb; 684bc416d97SEric Dumazet } 685bc416d97SEric Dumazet #endif 6861da177e4SLinus Torvalds 6871da177e4SLinus Torvalds /* 6881da177e4SLinus Torvalds * Functions provided by ip_forward.c 6891da177e4SLinus Torvalds */ 6901da177e4SLinus Torvalds 6915c3a0fd7SJoe Perches int ip_forward(struct sk_buff *skb); 6921da177e4SLinus Torvalds 6931da177e4SLinus Torvalds /* 6941da177e4SLinus Torvalds * Functions provided by ip_options.c 6951da177e4SLinus Torvalds */ 6961da177e4SLinus Torvalds 6975c3a0fd7SJoe Perches void ip_options_build(struct sk_buff *skb, struct ip_options *opt, 698f6d8bd05SEric Dumazet __be32 daddr, struct rtable *rt, int is_frag); 69924a2d43dSEric Dumazet 70091ed1e66SPaolo Abeni int __ip_options_echo(struct net *net, struct ip_options *dopt, 70191ed1e66SPaolo Abeni struct sk_buff *skb, const struct ip_options *sopt); 70291ed1e66SPaolo Abeni static inline int ip_options_echo(struct net *net, struct ip_options *dopt, 70391ed1e66SPaolo Abeni struct sk_buff *skb) 70424a2d43dSEric Dumazet { 70591ed1e66SPaolo Abeni return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt); 70624a2d43dSEric Dumazet } 70724a2d43dSEric Dumazet 7085c3a0fd7SJoe Perches void ip_options_fragment(struct sk_buff *skb); 7093da1ed7aSNazarov Sergey int __ip_options_compile(struct net *net, struct ip_options *opt, 7103da1ed7aSNazarov Sergey struct sk_buff *skb, __be32 *info); 7115c3a0fd7SJoe Perches int ip_options_compile(struct net *net, struct ip_options *opt, 7125c3a0fd7SJoe Perches struct sk_buff *skb); 7135c3a0fd7SJoe Perches int ip_options_get(struct net *net, struct ip_options_rcu **optp, 7144c6ea29dSArnaldo Carvalho de Melo unsigned char *data, int optlen); 7155c3a0fd7SJoe Perches int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, 7164c6ea29dSArnaldo Carvalho de Melo unsigned char __user *data, int optlen); 7175c3a0fd7SJoe Perches void ip_options_undo(struct ip_options *opt); 7185c3a0fd7SJoe Perches void ip_forward_options(struct sk_buff *skb); 7198c83f2dfSStephen Suryaputra int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds /* 7221da177e4SLinus Torvalds * Functions provided by ip_sockglue.c 7231da177e4SLinus Torvalds */ 7241da177e4SLinus Torvalds 725fbf8866dSShawn Bohrer void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); 726ad959036SPaolo Abeni void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, 727ad959036SPaolo Abeni struct sk_buff *skb, int tlen, int offset); 72824025c46SSoheil Hassas Yeganeh int ip_cmsg_send(struct sock *sk, struct msghdr *msg, 729c8e6ad08SHannes Frederic Sowa struct ipcm_cookie *ipc, bool allow_ipv6); 7305c3a0fd7SJoe Perches int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, 7315c3a0fd7SJoe Perches unsigned int optlen); 7325c3a0fd7SJoe Perches int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, 7335c3a0fd7SJoe Perches int __user *optlen); 7345c3a0fd7SJoe Perches int compat_ip_setsockopt(struct sock *sk, int level, int optname, 7355c3a0fd7SJoe Perches char __user *optval, unsigned int optlen); 7365c3a0fd7SJoe Perches int compat_ip_getsockopt(struct sock *sk, int level, int optname, 7375c3a0fd7SJoe Perches char __user *optval, int __user *optlen); 7385c3a0fd7SJoe Perches int ip_ra_control(struct sock *sk, unsigned char on, 7395c3a0fd7SJoe Perches void (*destructor)(struct sock *)); 7401da177e4SLinus Torvalds 74185fbaa75SHannes Frederic Sowa int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); 7425c3a0fd7SJoe Perches void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, 7435c3a0fd7SJoe Perches u32 info, u8 *payload); 7445c3a0fd7SJoe Perches void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, 7451da177e4SLinus Torvalds u32 info); 7461da177e4SLinus Torvalds 7475961de9fSTom Herbert static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) 7485961de9fSTom Herbert { 749ad959036SPaolo Abeni ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0); 7505961de9fSTom Herbert } 7515961de9fSTom Herbert 7524cdf507dSEric Dumazet bool icmp_global_allow(void); 7534cdf507dSEric Dumazet extern int sysctl_icmp_msgs_per_sec; 7544cdf507dSEric Dumazet extern int sysctl_icmp_msgs_burst; 7554cdf507dSEric Dumazet 75620380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS 7575c3a0fd7SJoe Perches int ip_misc_proc_init(void); 75820380731SArnaldo Carvalho de Melo #endif 75920380731SArnaldo Carvalho de Melo 7605e1a99eaSHangbin Liu int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, 761404eb77eSRoopa Prabhu struct netlink_ext_ack *extack); 762404eb77eSRoopa Prabhu 763501a90c9SEric Dumazet static inline bool inetdev_valid_mtu(unsigned int mtu) 764501a90c9SEric Dumazet { 765501a90c9SEric Dumazet return likely(mtu >= IPV4_MIN_MTU); 766501a90c9SEric Dumazet } 767501a90c9SEric Dumazet 768c4e446bfSChristoph Hellwig void ip_sock_set_freebind(struct sock *sk); 7692de569bdSChristoph Hellwig int ip_sock_set_mtu_discover(struct sock *sk, int val); 770db45c0efSChristoph Hellwig void ip_sock_set_recverr(struct sock *sk); 7716ebf71baSChristoph Hellwig void ip_sock_set_tos(struct sock *sk, int val); 7726ebf71baSChristoph Hellwig 7731da177e4SLinus Torvalds #endif /* _IP_H */ 774