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> 26de40a3e8SChristoph Hellwig #include <linux/sockptr.h> 27020e71a3SEric Dumazet #include <linux/static_key.h> 2814c85021SArnaldo Carvalho de Melo 2914c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h> 30aa661581SFrancesco Fusco #include <net/route.h> 311da177e4SLinus Torvalds #include <net/snmp.h> 3286b08d86SKOVACS Krisztian #include <net/flow.h> 331bd758ebSJiri Pirko #include <net/flow_dissector.h> 34f0b1e64cSMartin KaFai Lau #include <net/netns/hash.h> 35fade5641SVadim Fedorenko #include <net/lwtunnel.h> 361da177e4SLinus Torvalds 377ed14d97SGao Feng #define IPV4_MAX_PMTU 65535U /* RFC 2675, Section 5.1 */ 38b5476022SEric Dumazet #define IPV4_MIN_MTU 68 /* RFC 791 */ 397ed14d97SGao Feng 409ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem; 419ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_min; 429ab948a9SDavid Ahern extern unsigned int sysctl_fib_sync_mem_max; 439ab948a9SDavid Ahern 441da177e4SLinus Torvalds struct sock; 451da177e4SLinus Torvalds 46fd2c3ef7SEric Dumazet struct inet_skb_parm { 470b922b7aSDavid Ahern int iif; 481da177e4SLinus Torvalds struct ip_options opt; /* Compiled IP options */ 49a04a480dSDavid Ahern u16 flags; 501da177e4SLinus Torvalds 51df4d9254SHannes Frederic Sowa #define IPSKB_FORWARDED BIT(0) 52df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TUNNEL_SIZE BIT(1) 53df4d9254SHannes Frederic Sowa #define IPSKB_XFRM_TRANSFORMED BIT(2) 54df4d9254SHannes Frederic Sowa #define IPSKB_FRAG_COMPLETE BIT(3) 55df4d9254SHannes Frederic Sowa #define IPSKB_REROUTED BIT(4) 56df4d9254SHannes Frederic Sowa #define IPSKB_DOREDIRECT BIT(5) 57d6b915e2SFlorian Westphal #define IPSKB_FRAG_PMTU BIT(6) 589ee6c5dcSLance Richardson #define IPSKB_L3SLAVE BIT(7) 59e6175a2eSEyal Birger #define IPSKB_NOPOLICY BIT(8) 605f2d04f1SPatrick McHardy 615f2d04f1SPatrick McHardy u16 frag_max_size; 621da177e4SLinus Torvalds }; 631da177e4SLinus Torvalds 64a04a480dSDavid Ahern static inline bool ipv4_l3mdev_skb(u16 flags) 65a04a480dSDavid Ahern { 66a04a480dSDavid Ahern return !!(flags & IPSKB_L3SLAVE); 67a04a480dSDavid Ahern } 68a04a480dSDavid Ahern 69c9bdd4b5SArnaldo Carvalho de Melo static inline unsigned int ip_hdrlen(const struct sk_buff *skb) 70c9bdd4b5SArnaldo Carvalho de Melo { 71eddc9ec5SArnaldo Carvalho de Melo return ip_hdr(skb)->ihl * 4; 72c9bdd4b5SArnaldo Carvalho de Melo } 73c9bdd4b5SArnaldo Carvalho de Melo 74fd2c3ef7SEric Dumazet struct ipcm_cookie { 7524025c46SSoheil Hassas Yeganeh struct sockcm_cookie sockc; 76c1d18f9fSAl Viro __be32 addr; 771da177e4SLinus Torvalds int oif; 78f6d8bd05SEric Dumazet struct ip_options_rcu *opt; 79f02db315SFrancesco Fusco __u8 ttl; 80f02db315SFrancesco Fusco __s16 tos; 81f02db315SFrancesco Fusco char priority; 82bec1f6f6SWillem de Bruijn __u16 gso_size; 831da177e4SLinus Torvalds }; 841da177e4SLinus Torvalds 8535178206SWillem de Bruijn static inline void ipcm_init(struct ipcm_cookie *ipcm) 8635178206SWillem de Bruijn { 8735178206SWillem de Bruijn *ipcm = (struct ipcm_cookie) { .tos = -1 }; 8835178206SWillem de Bruijn } 8935178206SWillem de Bruijn 9035178206SWillem de Bruijn static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, 9135178206SWillem de Bruijn const struct inet_sock *inet) 9235178206SWillem de Bruijn { 9335178206SWillem de Bruijn ipcm_init(ipcm); 9435178206SWillem de Bruijn 95c6af0c22SWillem de Bruijn ipcm->sockc.mark = inet->sk.sk_mark; 9635178206SWillem de Bruijn ipcm->sockc.tsflags = inet->sk.sk_tsflags; 974c971d2fSEric Dumazet ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); 9835178206SWillem de Bruijn ipcm->addr = inet->inet_saddr; 9935178206SWillem de Bruijn } 10035178206SWillem de Bruijn 1011da177e4SLinus Torvalds #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) 1024b261c75SHannes Frederic Sowa #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb)) 1031da177e4SLinus Torvalds 104fb74c277SDavid Ahern /* return enslaved device index if relevant */ 105d6bb2d1eSEric Dumazet static inline int inet_sdif(const struct sk_buff *skb) 106fb74c277SDavid Ahern { 107fb74c277SDavid Ahern #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) 108fb74c277SDavid Ahern if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags)) 109fb74c277SDavid Ahern return IPCB(skb)->iif; 110fb74c277SDavid Ahern #endif 111fb74c277SDavid Ahern return 0; 112fb74c277SDavid Ahern } 113fb74c277SDavid Ahern 1145796ef75SKirill Tkhai /* Special input handler for packets caught by router alert option. 1155796ef75SKirill Tkhai They are selected only by protocol field, and then processed likely 1165796ef75SKirill Tkhai local ones; but only if someone wants them! Otherwise, router 1175796ef75SKirill Tkhai not running rsvpd will kill RSVP. 1185796ef75SKirill Tkhai 1195796ef75SKirill Tkhai It is user level problem, what it will make with them. 1205796ef75SKirill Tkhai I have no idea, how it will masquearde or NAT them (it is joke, joke :-)), 1215796ef75SKirill Tkhai but receiver should be enough clever f.e. to forward mtrace requests, 1225796ef75SKirill Tkhai sent to multicast group to reach destination designated router. 1235796ef75SKirill Tkhai */ 1245796ef75SKirill Tkhai 125fd2c3ef7SEric Dumazet struct ip_ra_chain { 12643a951e9SEric Dumazet struct ip_ra_chain __rcu *next; 1271da177e4SLinus Torvalds struct sock *sk; 128592fcb9dSEric Dumazet union { 1291da177e4SLinus Torvalds void (*destructor)(struct sock *); 130592fcb9dSEric Dumazet struct sock *saved_sk; 131592fcb9dSEric Dumazet }; 13266018506SEric Dumazet struct rcu_head rcu; 1331da177e4SLinus Torvalds }; 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds /* IP flags. */ 1361da177e4SLinus Torvalds #define IP_CE 0x8000 /* Flag: "Congestion" */ 1371da177e4SLinus Torvalds #define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 1381da177e4SLinus Torvalds #define IP_MF 0x2000 /* Flag: "More Fragments" */ 1391da177e4SLinus Torvalds #define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ 1421da177e4SLinus Torvalds 14314c85021SArnaldo Carvalho de Melo struct msghdr; 14414c85021SArnaldo Carvalho de Melo struct net_device; 14514c85021SArnaldo Carvalho de Melo struct packet_type; 14614c85021SArnaldo Carvalho de Melo struct rtable; 14714c85021SArnaldo Carvalho de Melo struct sockaddr; 14814c85021SArnaldo Carvalho de Melo 14972c1d3bdSWANG Cong int igmp_mc_init(void); 1501da177e4SLinus Torvalds 1511da177e4SLinus Torvalds /* 1521da177e4SLinus Torvalds * Functions provided by ip.c 1531da177e4SLinus Torvalds */ 1541da177e4SLinus Torvalds 155cfe673b0SEric Dumazet int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, 15613d8eaa0SAl Viro __be32 saddr, __be32 daddr, 157de033b7dSWei Wang struct ip_options_rcu *opt, u8 tos); 1585c3a0fd7SJoe Perches int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, 1595c3a0fd7SJoe Perches struct net_device *orig_dev); 16017266ee9SEdward Cree void ip_list_rcv(struct list_head *head, struct packet_type *pt, 16117266ee9SEdward Cree struct net_device *orig_dev); 1625c3a0fd7SJoe Perches int ip_local_deliver(struct sk_buff *skb); 16368cb7d53SPaolo Abeni void ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int proto); 1645c3a0fd7SJoe Perches int ip_mr_input(struct sk_buff *skb); 165ede2059dSEric W. Biederman int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb); 166ede2059dSEric W. Biederman int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb); 167694869b3SEric W. Biederman int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, 168694869b3SEric W. Biederman int (*output)(struct net *, struct sock *, struct sk_buff *)); 169c8b17be0SPablo Neira Ayuso 170c8b17be0SPablo Neira Ayuso struct ip_fraglist_iter { 171c8b17be0SPablo Neira Ayuso struct sk_buff *frag; 172c8b17be0SPablo Neira Ayuso struct iphdr *iph; 173c8b17be0SPablo Neira Ayuso int offset; 174c8b17be0SPablo Neira Ayuso unsigned int hlen; 175c8b17be0SPablo Neira Ayuso }; 176c8b17be0SPablo Neira Ayuso 177c8b17be0SPablo Neira Ayuso void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph, 178c8b17be0SPablo Neira Ayuso unsigned int hlen, struct ip_fraglist_iter *iter); 179c8b17be0SPablo Neira Ayuso void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter); 180c8b17be0SPablo Neira Ayuso 181c8b17be0SPablo Neira Ayuso static inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter) 182c8b17be0SPablo Neira Ayuso { 183c8b17be0SPablo Neira Ayuso struct sk_buff *skb = iter->frag; 184c8b17be0SPablo Neira Ayuso 185c8b17be0SPablo Neira Ayuso iter->frag = skb->next; 186c8b17be0SPablo Neira Ayuso skb_mark_not_on_list(skb); 187c8b17be0SPablo Neira Ayuso 188c8b17be0SPablo Neira Ayuso return skb; 189c8b17be0SPablo Neira Ayuso } 190c8b17be0SPablo Neira Ayuso 191065ff79fSPablo Neira Ayuso struct ip_frag_state { 192e7a409c3SEric Dumazet bool DF; 193065ff79fSPablo Neira Ayuso unsigned int hlen; 194065ff79fSPablo Neira Ayuso unsigned int ll_rs; 195065ff79fSPablo Neira Ayuso unsigned int mtu; 196065ff79fSPablo Neira Ayuso unsigned int left; 197065ff79fSPablo Neira Ayuso int offset; 198065ff79fSPablo Neira Ayuso int ptr; 199065ff79fSPablo Neira Ayuso __be16 not_last_frag; 200065ff79fSPablo Neira Ayuso }; 201065ff79fSPablo Neira Ayuso 202065ff79fSPablo Neira Ayuso void ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs, 203e7a409c3SEric Dumazet unsigned int mtu, bool DF, struct ip_frag_state *state); 204065ff79fSPablo Neira Ayuso struct sk_buff *ip_frag_next(struct sk_buff *skb, 205065ff79fSPablo Neira Ayuso struct ip_frag_state *state); 206065ff79fSPablo Neira Ayuso 2075c3a0fd7SJoe Perches void ip_send_check(struct iphdr *ip); 208cf91a99dSEric W. Biederman int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 20933224b16SEric W. Biederman int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 210aad88724SEric Dumazet 21169b9e1e0SXin Long int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 21269b9e1e0SXin Long __u8 tos); 2135c3a0fd7SJoe Perches void ip_init(void); 2145c3a0fd7SJoe Perches int ip_append_data(struct sock *sk, struct flowi4 *fl4, 2151da177e4SLinus Torvalds int getfrag(void *from, char *to, int offset, int len, 2161da177e4SLinus Torvalds int odd, struct sk_buff *skb), 2171da177e4SLinus Torvalds void *from, int len, int protolen, 2181da177e4SLinus Torvalds struct ipcm_cookie *ipc, 2192e77d89bSEric Dumazet struct rtable **rt, 2201da177e4SLinus Torvalds unsigned int flags); 2215c3a0fd7SJoe Perches int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, 2225c3a0fd7SJoe Perches struct sk_buff *skb); 2235c3a0fd7SJoe Perches ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, 2241da177e4SLinus Torvalds int offset, size_t size, int flags); 2255c3a0fd7SJoe Perches struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2261c32c5adSHerbert Xu struct sk_buff_head *queue, 2271c32c5adSHerbert Xu struct inet_cork *cork); 2285c3a0fd7SJoe Perches int ip_send_skb(struct net *net, struct sk_buff *skb); 2295c3a0fd7SJoe Perches int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); 2305c3a0fd7SJoe Perches void ip_flush_pending_frames(struct sock *sk); 2315c3a0fd7SJoe Perches struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2325c3a0fd7SJoe Perches int getfrag(void *from, char *to, int offset, 2335c3a0fd7SJoe Perches int len, int odd, struct sk_buff *skb), 2341c32c5adSHerbert Xu void *from, int length, int transhdrlen, 2355c3a0fd7SJoe Perches struct ipcm_cookie *ipc, struct rtable **rtp, 2361cd7884dSWillem de Bruijn struct inet_cork *cork, unsigned int flags); 2371c32c5adSHerbert Xu 23805e22e83SEric Dumazet int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); 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 29659f09ae8SEric Dumazet static inline u64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offt) 29759f09ae8SEric Dumazet { 29859f09ae8SEric Dumazet return *(((unsigned long *)per_cpu_ptr(mib, cpu)) + offt); 29959f09ae8SEric Dumazet } 30059f09ae8SEric Dumazet 301698365faSWANG Cong unsigned long snmp_fold_field(void __percpu *mib, int offt); 3024ce3c183SEric Dumazet #if BITS_PER_LONG==32 303c4c6bc31SRaghavendra K T u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 304c4c6bc31SRaghavendra K T size_t syncp_offset); 305698365faSWANG Cong u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off); 3064ce3c183SEric Dumazet #else 307c4c6bc31SRaghavendra K T static inline u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 308c4c6bc31SRaghavendra K T size_t syncp_offset) 309c4c6bc31SRaghavendra K T { 310c4c6bc31SRaghavendra K T return snmp_get_cpu_field(mib, cpu, offct); 311c4c6bc31SRaghavendra K T 312c4c6bc31SRaghavendra K T } 313c4c6bc31SRaghavendra K T 314698365faSWANG Cong static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off) 3154ce3c183SEric Dumazet { 3164ce3c183SEric Dumazet return snmp_fold_field(mib, offt); 3174ce3c183SEric Dumazet } 3184ce3c183SEric Dumazet #endif 31933490170SYOSHIFUJI Hideaki 3206348ef2dSJia He #define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \ 3216348ef2dSJia He { \ 3226348ef2dSJia He int i, c; \ 3236348ef2dSJia He for_each_possible_cpu(c) { \ 3246348ef2dSJia He for (i = 0; stats_list[i].name; i++) \ 3256348ef2dSJia He buff64[i] += snmp_get_cpu_field64( \ 3266348ef2dSJia He mib_statistic, \ 3276348ef2dSJia He c, stats_list[i].entry, \ 3286348ef2dSJia He offset); \ 3296348ef2dSJia He } \ 3306348ef2dSJia He } 3316348ef2dSJia He 3326348ef2dSJia He #define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \ 3336348ef2dSJia He { \ 3346348ef2dSJia He int i, c; \ 3356348ef2dSJia He for_each_possible_cpu(c) { \ 3366348ef2dSJia He for (i = 0; stats_list[i].name; i++) \ 3376348ef2dSJia He buff[i] += snmp_get_cpu_field( \ 3386348ef2dSJia He mib_statistic, \ 3396348ef2dSJia He c, stats_list[i].entry); \ 3406348ef2dSJia He } \ 3416348ef2dSJia He } 3426348ef2dSJia He 3430bbf87d8SEric W. Biederman void inet_get_local_port_range(struct net *net, int *low, int *high); 344227b60f5SStephen Hemminger 345fcd77db0SDavid S. Miller #ifdef CONFIG_SYSCTL 34666e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 347e3826f1eSAmerigo Wang { 348122ff243SWANG Cong if (!net->ipv4.sysctl_local_reserved_ports) 34930429fbaSMaciej Żenczykowski return false; 350122ff243SWANG Cong return test_bit(port, net->ipv4.sysctl_local_reserved_ports); 351e3826f1eSAmerigo Wang } 35220e61da7SWANG Cong 35320e61da7SWANG Cong static inline bool sysctl_dev_name_is_allowed(const char *name) 35420e61da7SWANG Cong { 35520e61da7SWANG Cong return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; 35620e61da7SWANG Cong } 35720e61da7SWANG Cong 35882f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3594548b683SKrister Johansen { 36082f31ebfSMaciej Żenczykowski return port < net->ipv4.sysctl_ip_prot_sock; 3614548b683SKrister Johansen } 3624548b683SKrister Johansen 363122ff243SWANG Cong #else 36466e2f5f7SMaciej Żenczykowski static inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 365122ff243SWANG Cong { 36630429fbaSMaciej Żenczykowski return false; 367122ff243SWANG Cong } 3684548b683SKrister Johansen 36982f31ebfSMaciej Żenczykowski static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3704548b683SKrister Johansen { 37182f31ebfSMaciej Żenczykowski return port < PROT_SOCK; 3724548b683SKrister Johansen } 373122ff243SWANG Cong #endif 374e3826f1eSAmerigo Wang 375822c8685SDeepa Dinamani __be32 inet_current_timestamp(void); 376822c8685SDeepa Dinamani 37720380731SArnaldo Carvalho de Melo /* From inetpeer.c */ 37820380731SArnaldo Carvalho de Melo extern int inet_peer_threshold; 37920380731SArnaldo Carvalho de Melo extern int inet_peer_minttl; 38020380731SArnaldo Carvalho de Melo extern int inet_peer_maxttl; 38120380731SArnaldo Carvalho de Melo 3825c3a0fd7SJoe Perches void ipfrag_init(void); 38320380731SArnaldo Carvalho de Melo 3845c3a0fd7SJoe Perches void ip_static_sysctl_init(void); 385bd7b1533SAl Viro 386e110861fSLorenzo Colitti #define IP4_REPLY_MARK(net, mark) \ 387e110861fSLorenzo Colitti ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0) 388e110861fSLorenzo Colitti 389d18cd551SDavid S. Miller static inline bool ip_is_fragment(const struct iphdr *iph) 390d18cd551SDavid S. Miller { 391d18cd551SDavid S. Miller return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; 392d18cd551SDavid S. Miller } 393d18cd551SDavid S. Miller 3941da177e4SLinus Torvalds #ifdef CONFIG_INET 39514c85021SArnaldo Carvalho de Melo #include <net/dst.h> 39614c85021SArnaldo Carvalho de Melo 3971da177e4SLinus Torvalds /* The function in 2.2 was invalid, producing wrong result for 3981da177e4SLinus Torvalds * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ 3991da177e4SLinus Torvalds static inline 4001da177e4SLinus Torvalds int ip_decrease_ttl(struct iphdr *iph) 4011da177e4SLinus Torvalds { 4025c78f275SAl Viro u32 check = (__force u32)iph->check; 4035c78f275SAl Viro check += (__force u32)htons(0x0100); 4045c78f275SAl Viro iph->check = (__force __sum16)(check + (check>=0xFFFF)); 4051da177e4SLinus Torvalds return --iph->ttl; 4061da177e4SLinus Torvalds } 4071da177e4SLinus Torvalds 408d52e5a7eSSabrina Dubroca static inline int ip_mtu_locked(const struct dst_entry *dst) 409d52e5a7eSSabrina Dubroca { 410d52e5a7eSSabrina Dubroca const struct rtable *rt = (const struct rtable *)dst; 411d52e5a7eSSabrina Dubroca 412d52e5a7eSSabrina Dubroca return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU); 413d52e5a7eSSabrina Dubroca } 414d52e5a7eSSabrina Dubroca 4151da177e4SLinus Torvalds static inline 4164e3f5d72SEric Dumazet int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) 4171da177e4SLinus Torvalds { 4184e3f5d72SEric Dumazet u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc); 4194e3f5d72SEric Dumazet 4204e3f5d72SEric Dumazet return pmtudisc == IP_PMTUDISC_DO || 4214e3f5d72SEric Dumazet (pmtudisc == IP_PMTUDISC_WANT && 422d52e5a7eSSabrina Dubroca !ip_mtu_locked(dst)); 4231da177e4SLinus Torvalds } 4241da177e4SLinus Torvalds 425f87c10a8SHannes Frederic Sowa static inline bool ip_sk_accept_pmtu(const struct sock *sk) 426f87c10a8SHannes Frederic Sowa { 4271b346576SHannes Frederic Sowa return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE && 4281b346576SHannes Frederic Sowa inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT; 429f87c10a8SHannes Frederic Sowa } 430f87c10a8SHannes Frederic Sowa 431f87c10a8SHannes Frederic Sowa static inline bool ip_sk_use_pmtu(const struct sock *sk) 432f87c10a8SHannes Frederic Sowa { 433f87c10a8SHannes Frederic Sowa return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; 434f87c10a8SHannes Frederic Sowa } 435f87c10a8SHannes Frederic Sowa 43660ff7467SWANG Cong static inline bool ip_sk_ignore_df(const struct sock *sk) 4371b346576SHannes Frederic Sowa { 4381b346576SHannes Frederic Sowa return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO || 4391b346576SHannes Frederic Sowa inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT; 4401b346576SHannes Frederic Sowa } 4411b346576SHannes Frederic Sowa 442f87c10a8SHannes Frederic Sowa static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, 443f87c10a8SHannes Frederic Sowa bool forwarding) 444f87c10a8SHannes Frederic Sowa { 445ac6627a2SVadim Fedorenko const struct rtable *rt = container_of(dst, struct rtable, dst); 446f87c10a8SHannes Frederic Sowa struct net *net = dev_net(dst->dev); 44702a1b175SMaciej Żenczykowski unsigned int mtu; 448f87c10a8SHannes Frederic Sowa 449*60c158dcSKuniyuki Iwashima if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || 450d52e5a7eSSabrina Dubroca ip_mtu_locked(dst) || 451ac6627a2SVadim Fedorenko !forwarding) { 452ac6627a2SVadim Fedorenko mtu = rt->rt_pmtu; 453ac6627a2SVadim Fedorenko if (mtu && time_before(jiffies, rt->dst.expires)) 454ac6627a2SVadim Fedorenko goto out; 455ac6627a2SVadim Fedorenko } 456f87c10a8SHannes Frederic Sowa 45702a1b175SMaciej Żenczykowski /* 'forwarding = true' case should always honour route mtu */ 45802a1b175SMaciej Żenczykowski mtu = dst_metric_raw(dst, RTAX_MTU); 459ac6627a2SVadim Fedorenko if (mtu) 460ac6627a2SVadim Fedorenko goto out; 461ac6627a2SVadim Fedorenko 462ac6627a2SVadim Fedorenko mtu = READ_ONCE(dst->dev->mtu); 463ac6627a2SVadim Fedorenko 464ac6627a2SVadim Fedorenko if (unlikely(ip_mtu_locked(dst))) { 465ac6627a2SVadim Fedorenko if (rt->rt_uses_gateway && mtu > 576) 466ac6627a2SVadim Fedorenko mtu = 576; 467ac6627a2SVadim Fedorenko } 468ac6627a2SVadim Fedorenko 469ac6627a2SVadim Fedorenko out: 470ac6627a2SVadim Fedorenko mtu = min_t(unsigned int, mtu, IP_MAX_MTU); 47102a1b175SMaciej Żenczykowski 472fade5641SVadim Fedorenko return mtu - lwtunnel_headroom(dst->lwtstate, mtu); 473f87c10a8SHannes Frederic Sowa } 474f87c10a8SHannes Frederic Sowa 475fedbb6b4SShmulik Ladkani static inline unsigned int ip_skb_dst_mtu(struct sock *sk, 476fedbb6b4SShmulik Ladkani const struct sk_buff *skb) 477f87c10a8SHannes Frederic Sowa { 478fade5641SVadim Fedorenko unsigned int mtu; 479fade5641SVadim Fedorenko 480caf3f267SEric Dumazet if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { 481f87c10a8SHannes Frederic Sowa bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; 482caf3f267SEric Dumazet 483f87c10a8SHannes Frederic Sowa return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); 484f87c10a8SHannes Frederic Sowa } 485caf3f267SEric Dumazet 486fade5641SVadim Fedorenko mtu = min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU); 487fade5641SVadim Fedorenko return mtu - lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu); 488f87c10a8SHannes Frederic Sowa } 489f87c10a8SHannes Frederic Sowa 490767a2217SDavid Ahern struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, 491d7e774f3SDavid Ahern int fc_mx_len, 492d7e774f3SDavid Ahern struct netlink_ext_ack *extack); 493cc5f0eb2SDavid Ahern static inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics) 494cc5f0eb2SDavid Ahern { 495cc5f0eb2SDavid Ahern if (fib_metrics != &dst_default_metrics && 496cc5f0eb2SDavid Ahern refcount_dec_and_test(&fib_metrics->refcnt)) 497cc5f0eb2SDavid Ahern kfree(fib_metrics); 498cc5f0eb2SDavid Ahern } 499a919525aSDavid Ahern 500e1255ed4SDavid Ahern /* ipv4 and ipv6 both use refcounted metrics if it is not the default */ 501e1255ed4SDavid Ahern static inline 502e1255ed4SDavid Ahern void ip_dst_init_metrics(struct dst_entry *dst, struct dst_metrics *fib_metrics) 503e1255ed4SDavid Ahern { 504e1255ed4SDavid Ahern dst_init_metrics(dst, fib_metrics->metrics, true); 505e1255ed4SDavid Ahern 506e1255ed4SDavid Ahern if (fib_metrics != &dst_default_metrics) { 507e1255ed4SDavid Ahern dst->_metrics |= DST_METRICS_REFCOUNTED; 508e1255ed4SDavid Ahern refcount_inc(&fib_metrics->refcnt); 509e1255ed4SDavid Ahern } 510e1255ed4SDavid Ahern } 511e1255ed4SDavid Ahern 5121620a336SDavid Ahern static inline 5131620a336SDavid Ahern void ip_dst_metrics_put(struct dst_entry *dst) 5141620a336SDavid Ahern { 5151620a336SDavid Ahern struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); 5161620a336SDavid Ahern 5171620a336SDavid Ahern if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) 5181620a336SDavid Ahern kfree(p); 5191620a336SDavid Ahern } 5201620a336SDavid Ahern 521b6a7719aSHannes Frederic Sowa void __ip_select_ident(struct net *net, struct iphdr *iph, int segs); 52273f156a6SEric Dumazet 523b6a7719aSHannes Frederic Sowa static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, 524b6a7719aSHannes Frederic Sowa struct sock *sk, int segs) 5251da177e4SLinus Torvalds { 526703133deSAnsis Atteka struct iphdr *iph = ip_hdr(skb); 527703133deSAnsis Atteka 52823f57406SEric Dumazet /* We had many attacks based on IPID, use the private 52923f57406SEric Dumazet * generator as much as we can. 5301da177e4SLinus Torvalds */ 531c720c7e8SEric Dumazet if (sk && inet_sk(sk)->inet_daddr) { 532c720c7e8SEric Dumazet iph->id = htons(inet_sk(sk)->inet_id); 53373f156a6SEric Dumazet inet_sk(sk)->inet_id += segs; 53423f57406SEric Dumazet return; 53573f156a6SEric Dumazet } 53623f57406SEric Dumazet if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { 53723f57406SEric Dumazet iph->id = 0; 53873f156a6SEric Dumazet } else { 53923f57406SEric Dumazet /* Unfortunately we need the big hammer to get a suitable IPID */ 540b6a7719aSHannes Frederic Sowa __ip_select_ident(net, iph, segs); 54173f156a6SEric Dumazet } 54273f156a6SEric Dumazet } 54373f156a6SEric Dumazet 544b6a7719aSHannes Frederic Sowa static inline void ip_select_ident(struct net *net, struct sk_buff *skb, 545b6a7719aSHannes Frederic Sowa struct sock *sk) 54673f156a6SEric Dumazet { 547b6a7719aSHannes Frederic Sowa ip_select_ident_segs(net, skb, sk, 1); 5481da177e4SLinus Torvalds } 5491da177e4SLinus Torvalds 550ed70fcfcSTom Herbert static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto) 551ed70fcfcSTom Herbert { 552ed70fcfcSTom Herbert return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 553ed70fcfcSTom Herbert skb->len, proto, 0); 554ed70fcfcSTom Herbert } 555ed70fcfcSTom Herbert 556c3f83241STom Herbert /* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store 557c3f83241STom Herbert * Equivalent to : flow->v4addrs.src = iph->saddr; 558c3f83241STom Herbert * flow->v4addrs.dst = iph->daddr; 559c3f83241STom Herbert */ 560c3f83241STom Herbert static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow, 561c3f83241STom Herbert const struct iphdr *iph) 562c3f83241STom Herbert { 563c3f83241STom Herbert BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) != 564c3f83241STom Herbert offsetof(typeof(flow->addrs), v4addrs.src) + 565c3f83241STom Herbert sizeof(flow->addrs.v4addrs.src)); 566c3f83241STom Herbert memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs)); 567c3f83241STom Herbert flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 568c3f83241STom Herbert } 569c3f83241STom Herbert 5701da177e4SLinus Torvalds /* 5711da177e4SLinus Torvalds * Map a multicast IP onto multicast MAC for type ethernet. 5721da177e4SLinus Torvalds */ 5731da177e4SLinus Torvalds 574714e85beSAl Viro static inline void ip_eth_mc_map(__be32 naddr, char *buf) 5751da177e4SLinus Torvalds { 576714e85beSAl Viro __u32 addr=ntohl(naddr); 5771da177e4SLinus Torvalds buf[0]=0x01; 5781da177e4SLinus Torvalds buf[1]=0x00; 5791da177e4SLinus Torvalds buf[2]=0x5e; 5801da177e4SLinus Torvalds buf[5]=addr&0xFF; 5811da177e4SLinus Torvalds addr>>=8; 5821da177e4SLinus Torvalds buf[4]=addr&0xFF; 5831da177e4SLinus Torvalds addr>>=8; 5841da177e4SLinus Torvalds buf[3]=addr&0x7F; 5851da177e4SLinus Torvalds } 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds /* 5881da177e4SLinus Torvalds * Map a multicast IP onto multicast MAC for type IP-over-InfiniBand. 5891da177e4SLinus Torvalds * Leave P_Key as 0 to be filled in by driver. 5901da177e4SLinus Torvalds */ 5911da177e4SLinus Torvalds 592a9e527e3SRolf Manderscheid static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 5931da177e4SLinus Torvalds { 594714e85beSAl Viro __u32 addr; 595a9e527e3SRolf Manderscheid unsigned char scope = broadcast[5] & 0xF; 596a9e527e3SRolf Manderscheid 5971da177e4SLinus Torvalds buf[0] = 0; /* Reserved */ 5981da177e4SLinus Torvalds buf[1] = 0xff; /* Multicast QPN */ 5991da177e4SLinus Torvalds buf[2] = 0xff; 6001da177e4SLinus Torvalds buf[3] = 0xff; 601714e85beSAl Viro addr = ntohl(naddr); 6021da177e4SLinus Torvalds buf[4] = 0xff; 603a9e527e3SRolf Manderscheid buf[5] = 0x10 | scope; /* scope from broadcast address */ 6041da177e4SLinus Torvalds buf[6] = 0x40; /* IPv4 signature */ 6051da177e4SLinus Torvalds buf[7] = 0x1b; 606a9e527e3SRolf Manderscheid buf[8] = broadcast[8]; /* P_Key */ 607a9e527e3SRolf Manderscheid buf[9] = broadcast[9]; 6081da177e4SLinus Torvalds buf[10] = 0; 6091da177e4SLinus Torvalds buf[11] = 0; 6101da177e4SLinus Torvalds buf[12] = 0; 6111da177e4SLinus Torvalds buf[13] = 0; 6121da177e4SLinus Torvalds buf[14] = 0; 6131da177e4SLinus Torvalds buf[15] = 0; 6141da177e4SLinus Torvalds buf[19] = addr & 0xff; 6151da177e4SLinus Torvalds addr >>= 8; 6161da177e4SLinus Torvalds buf[18] = addr & 0xff; 6171da177e4SLinus Torvalds addr >>= 8; 6181da177e4SLinus Torvalds buf[17] = addr & 0xff; 6191da177e4SLinus Torvalds addr >>= 8; 6201da177e4SLinus Torvalds buf[16] = addr & 0x0f; 6211da177e4SLinus Torvalds } 6221da177e4SLinus Torvalds 62393ca3bb5STimo Teräs static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 62493ca3bb5STimo Teräs { 62593ca3bb5STimo Teräs if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) 62693ca3bb5STimo Teräs memcpy(buf, broadcast, 4); 62793ca3bb5STimo Teräs else 62893ca3bb5STimo Teräs memcpy(buf, &naddr, sizeof(naddr)); 62993ca3bb5STimo Teräs } 63093ca3bb5STimo Teräs 631dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 6321da177e4SLinus Torvalds #include <linux/ipv6.h> 6331da177e4SLinus Torvalds #endif 6341da177e4SLinus Torvalds 6351da177e4SLinus Torvalds static __inline__ void inet_reset_saddr(struct sock *sk) 6361da177e4SLinus Torvalds { 637c720c7e8SEric Dumazet inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0; 638dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 6391da177e4SLinus Torvalds if (sk->sk_family == PF_INET6) { 6401da177e4SLinus Torvalds struct ipv6_pinfo *np = inet6_sk(sk); 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds memset(&np->saddr, 0, sizeof(np->saddr)); 643efe4208fSEric Dumazet memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr)); 6441da177e4SLinus Torvalds } 6451da177e4SLinus Torvalds #endif 6461da177e4SLinus Torvalds } 6471da177e4SLinus Torvalds 6481da177e4SLinus Torvalds #endif 6491da177e4SLinus Torvalds 65072afa352SDavid Ahern static inline unsigned int ipv4_addr_hash(__be32 ip) 65172afa352SDavid Ahern { 65272afa352SDavid Ahern return (__force unsigned int) ip; 65372afa352SDavid Ahern } 65472afa352SDavid Ahern 655f0b1e64cSMartin KaFai Lau static inline u32 ipv4_portaddr_hash(const struct net *net, 656f0b1e64cSMartin KaFai Lau __be32 saddr, 657f0b1e64cSMartin KaFai Lau unsigned int port) 658f0b1e64cSMartin KaFai Lau { 659f0b1e64cSMartin KaFai Lau return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port; 660f0b1e64cSMartin KaFai Lau } 661f0b1e64cSMartin KaFai Lau 6625c3a0fd7SJoe Perches bool ip_call_ra_chain(struct sk_buff *skb); 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds /* 665b798232fSRami Rosen * Functions provided by ip_fragment.c 6661da177e4SLinus Torvalds */ 6671da177e4SLinus Torvalds 668fd2c3ef7SEric Dumazet enum ip_defrag_users { 6691da177e4SLinus Torvalds IP_DEFRAG_LOCAL_DELIVER, 6701da177e4SLinus Torvalds IP_DEFRAG_CALL_RA_CHAIN, 6711da177e4SLinus Torvalds IP_DEFRAG_CONNTRACK_IN, 6724be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHRT_MAX, 6731da177e4SLinus Torvalds IP_DEFRAG_CONNTRACK_OUT, 6744be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX, 6758fa9ff68SPatrick McHardy IP_DEFRAG_CONNTRACK_BRIDGE_IN, 6764be929beSAlexey Dobriyan __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, 6771da177e4SLinus Torvalds IP_DEFRAG_VS_IN, 6781da177e4SLinus Torvalds IP_DEFRAG_VS_OUT, 679595fc71bSDavid S. Miller IP_DEFRAG_VS_FWD, 680595fc71bSDavid S. Miller IP_DEFRAG_AF_PACKET, 681bc416d97SEric Dumazet IP_DEFRAG_MACVLAN, 6821da177e4SLinus Torvalds }; 6831da177e4SLinus Torvalds 6845cf42280SAndy Zhou /* Return true if the value of 'user' is between 'lower_bond' 6855cf42280SAndy Zhou * and 'upper_bond' inclusively. 6865cf42280SAndy Zhou */ 6875cf42280SAndy Zhou static inline bool ip_defrag_user_in_between(u32 user, 6885cf42280SAndy Zhou enum ip_defrag_users lower_bond, 6895cf42280SAndy Zhou enum ip_defrag_users upper_bond) 6905cf42280SAndy Zhou { 6915cf42280SAndy Zhou return user >= lower_bond && user <= upper_bond; 6925cf42280SAndy Zhou } 6935cf42280SAndy Zhou 69419bcf9f2SEric W. Biederman int ip_defrag(struct net *net, struct sk_buff *skb, u32 user); 695bc416d97SEric Dumazet #ifdef CONFIG_INET 69619bcf9f2SEric W. Biederman struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user); 697bc416d97SEric Dumazet #else 69819bcf9f2SEric W. Biederman static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user) 699bc416d97SEric Dumazet { 700bc416d97SEric Dumazet return skb; 701bc416d97SEric Dumazet } 702bc416d97SEric Dumazet #endif 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds /* 7051da177e4SLinus Torvalds * Functions provided by ip_forward.c 7061da177e4SLinus Torvalds */ 7071da177e4SLinus Torvalds 7085c3a0fd7SJoe Perches int ip_forward(struct sk_buff *skb); 7091da177e4SLinus Torvalds 7101da177e4SLinus Torvalds /* 7111da177e4SLinus Torvalds * Functions provided by ip_options.c 7121da177e4SLinus Torvalds */ 7131da177e4SLinus Torvalds 7145c3a0fd7SJoe Perches void ip_options_build(struct sk_buff *skb, struct ip_options *opt, 7154f0e3040SJakub Kicinski __be32 daddr, struct rtable *rt); 71624a2d43dSEric Dumazet 71791ed1e66SPaolo Abeni int __ip_options_echo(struct net *net, struct ip_options *dopt, 71891ed1e66SPaolo Abeni struct sk_buff *skb, const struct ip_options *sopt); 71991ed1e66SPaolo Abeni static inline int ip_options_echo(struct net *net, struct ip_options *dopt, 72091ed1e66SPaolo Abeni struct sk_buff *skb) 72124a2d43dSEric Dumazet { 72291ed1e66SPaolo Abeni return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt); 72324a2d43dSEric Dumazet } 72424a2d43dSEric Dumazet 7255c3a0fd7SJoe Perches void ip_options_fragment(struct sk_buff *skb); 7263da1ed7aSNazarov Sergey int __ip_options_compile(struct net *net, struct ip_options *opt, 7273da1ed7aSNazarov Sergey struct sk_buff *skb, __be32 *info); 7285c3a0fd7SJoe Perches int ip_options_compile(struct net *net, struct ip_options *opt, 7295c3a0fd7SJoe Perches struct sk_buff *skb); 7305c3a0fd7SJoe Perches int ip_options_get(struct net *net, struct ip_options_rcu **optp, 731de40a3e8SChristoph Hellwig sockptr_t data, int optlen); 7325c3a0fd7SJoe Perches void ip_options_undo(struct ip_options *opt); 7335c3a0fd7SJoe Perches void ip_forward_options(struct sk_buff *skb); 7348c83f2dfSStephen Suryaputra int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); 7351da177e4SLinus Torvalds 7361da177e4SLinus Torvalds /* 7371da177e4SLinus Torvalds * Functions provided by ip_sockglue.c 7381da177e4SLinus Torvalds */ 7391da177e4SLinus Torvalds 740fbf8866dSShawn Bohrer void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); 741ad959036SPaolo Abeni void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, 742ad959036SPaolo Abeni struct sk_buff *skb, int tlen, int offset); 74324025c46SSoheil Hassas Yeganeh int ip_cmsg_send(struct sock *sk, struct msghdr *msg, 744c8e6ad08SHannes Frederic Sowa struct ipcm_cookie *ipc, bool allow_ipv6); 745020e71a3SEric Dumazet DECLARE_STATIC_KEY_FALSE(ip4_min_ttl); 746a7b75c5aSChristoph Hellwig int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, 7475c3a0fd7SJoe Perches unsigned int optlen); 7485c3a0fd7SJoe Perches int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, 7495c3a0fd7SJoe Perches int __user *optlen); 7505c3a0fd7SJoe Perches int ip_ra_control(struct sock *sk, unsigned char on, 7515c3a0fd7SJoe Perches void (*destructor)(struct sock *)); 7521da177e4SLinus Torvalds 75385fbaa75SHannes Frederic Sowa int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); 7545c3a0fd7SJoe Perches void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, 7555c3a0fd7SJoe Perches u32 info, u8 *payload); 7565c3a0fd7SJoe Perches void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, 7571da177e4SLinus Torvalds u32 info); 7581da177e4SLinus Torvalds 7595961de9fSTom Herbert static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) 7605961de9fSTom Herbert { 761ad959036SPaolo Abeni ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0); 7625961de9fSTom Herbert } 7635961de9fSTom Herbert 7644cdf507dSEric Dumazet bool icmp_global_allow(void); 7654cdf507dSEric Dumazet extern int sysctl_icmp_msgs_per_sec; 7664cdf507dSEric Dumazet extern int sysctl_icmp_msgs_burst; 7674cdf507dSEric Dumazet 76820380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS 7695c3a0fd7SJoe Perches int ip_misc_proc_init(void); 77020380731SArnaldo Carvalho de Melo #endif 77120380731SArnaldo Carvalho de Melo 7725e1a99eaSHangbin Liu int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, 773404eb77eSRoopa Prabhu struct netlink_ext_ack *extack); 774404eb77eSRoopa Prabhu 775501a90c9SEric Dumazet static inline bool inetdev_valid_mtu(unsigned int mtu) 776501a90c9SEric Dumazet { 777501a90c9SEric Dumazet return likely(mtu >= IPV4_MIN_MTU); 778501a90c9SEric Dumazet } 779501a90c9SEric Dumazet 780c4e446bfSChristoph Hellwig void ip_sock_set_freebind(struct sock *sk); 7812de569bdSChristoph Hellwig int ip_sock_set_mtu_discover(struct sock *sk, int val); 782c1f9ec57SChristoph Hellwig void ip_sock_set_pktinfo(struct sock *sk); 783db45c0efSChristoph Hellwig void ip_sock_set_recverr(struct sock *sk); 7846ebf71baSChristoph Hellwig void ip_sock_set_tos(struct sock *sk, int val); 7854f47d5d5SPoorva Sonparote void __ip_sock_set_tos(struct sock *sk, int val); 7866ebf71baSChristoph Hellwig 7871da177e4SLinus Torvalds #endif /* _IP_H */ 788