18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * INET An implementation of the TCP/IP protocol suite for the LINUX 48c2ecf20Sopenharmony_ci * operating system. INET is implemented using the BSD Socket 58c2ecf20Sopenharmony_ci * interface as the means of communication with the user level. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Definitions for the IP module. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Version: @(#)ip.h 1.0.2 05/07/93 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Authors: Ross Biro 128c2ecf20Sopenharmony_ci * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 138c2ecf20Sopenharmony_ci * Alan Cox, <gw4pts@gw4pts.ampr.org> 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Changes: 168c2ecf20Sopenharmony_ci * Mike McLagan : Routing by source 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci#ifndef _IP_H 198c2ecf20Sopenharmony_ci#define _IP_H 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <linux/types.h> 228c2ecf20Sopenharmony_ci#include <linux/ip.h> 238c2ecf20Sopenharmony_ci#include <linux/in.h> 248c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 258c2ecf20Sopenharmony_ci#include <linux/jhash.h> 268c2ecf20Sopenharmony_ci#include <linux/sockptr.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include <net/inet_sock.h> 298c2ecf20Sopenharmony_ci#include <net/route.h> 308c2ecf20Sopenharmony_ci#include <net/snmp.h> 318c2ecf20Sopenharmony_ci#include <net/flow.h> 328c2ecf20Sopenharmony_ci#include <net/flow_dissector.h> 338c2ecf20Sopenharmony_ci#include <net/netns/hash.h> 348c2ecf20Sopenharmony_ci#include <net/lwtunnel.h> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define IPV4_MAX_PMTU 65535U /* RFC 2675, Section 5.1 */ 378c2ecf20Sopenharmony_ci#define IPV4_MIN_MTU 68 /* RFC 791 */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ciextern unsigned int sysctl_fib_sync_mem; 408c2ecf20Sopenharmony_ciextern unsigned int sysctl_fib_sync_mem_min; 418c2ecf20Sopenharmony_ciextern unsigned int sysctl_fib_sync_mem_max; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct sock; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistruct inet_skb_parm { 468c2ecf20Sopenharmony_ci int iif; 478c2ecf20Sopenharmony_ci struct ip_options opt; /* Compiled IP options */ 488c2ecf20Sopenharmony_ci u16 flags; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define IPSKB_FORWARDED BIT(0) 518c2ecf20Sopenharmony_ci#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) 528c2ecf20Sopenharmony_ci#define IPSKB_XFRM_TRANSFORMED BIT(2) 538c2ecf20Sopenharmony_ci#define IPSKB_FRAG_COMPLETE BIT(3) 548c2ecf20Sopenharmony_ci#define IPSKB_REROUTED BIT(4) 558c2ecf20Sopenharmony_ci#define IPSKB_DOREDIRECT BIT(5) 568c2ecf20Sopenharmony_ci#define IPSKB_FRAG_PMTU BIT(6) 578c2ecf20Sopenharmony_ci#define IPSKB_L3SLAVE BIT(7) 588c2ecf20Sopenharmony_ci#define IPSKB_NOPOLICY BIT(8) 598c2ecf20Sopenharmony_ci#define IPSKB_MULTIPATH BIT(9) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci u16 frag_max_size; 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic inline bool ipv4_l3mdev_skb(u16 flags) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci return !!(flags & IPSKB_L3SLAVE); 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic inline unsigned int ip_hdrlen(const struct sk_buff *skb) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci return ip_hdr(skb)->ihl * 4; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistruct ipcm_cookie { 758c2ecf20Sopenharmony_ci struct sockcm_cookie sockc; 768c2ecf20Sopenharmony_ci __be32 addr; 778c2ecf20Sopenharmony_ci int oif; 788c2ecf20Sopenharmony_ci struct ip_options_rcu *opt; 798c2ecf20Sopenharmony_ci __u8 protocol; 808c2ecf20Sopenharmony_ci __u8 ttl; 818c2ecf20Sopenharmony_ci __s16 tos; 828c2ecf20Sopenharmony_ci char priority; 838c2ecf20Sopenharmony_ci __u16 gso_size; 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic inline void ipcm_init(struct ipcm_cookie *ipcm) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci *ipcm = (struct ipcm_cookie) { .tos = -1 }; 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic inline void ipcm_init_sk(struct ipcm_cookie *ipcm, 928c2ecf20Sopenharmony_ci const struct inet_sock *inet) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci ipcm_init(ipcm); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci ipcm->sockc.mark = inet->sk.sk_mark; 978c2ecf20Sopenharmony_ci ipcm->sockc.tsflags = inet->sk.sk_tsflags; 988c2ecf20Sopenharmony_ci ipcm->oif = inet->sk.sk_bound_dev_if; 998c2ecf20Sopenharmony_ci ipcm->addr = inet->inet_saddr; 1008c2ecf20Sopenharmony_ci ipcm->protocol = inet->inet_num; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) 1048c2ecf20Sopenharmony_ci#define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb)) 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* return enslaved device index if relevant */ 1078c2ecf20Sopenharmony_cistatic inline int inet_sdif(struct sk_buff *skb) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) 1108c2ecf20Sopenharmony_ci if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags)) 1118c2ecf20Sopenharmony_ci return IPCB(skb)->iif; 1128c2ecf20Sopenharmony_ci#endif 1138c2ecf20Sopenharmony_ci return 0; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci/* Special input handler for packets caught by router alert option. 1178c2ecf20Sopenharmony_ci They are selected only by protocol field, and then processed likely 1188c2ecf20Sopenharmony_ci local ones; but only if someone wants them! Otherwise, router 1198c2ecf20Sopenharmony_ci not running rsvpd will kill RSVP. 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci It is user level problem, what it will make with them. 1228c2ecf20Sopenharmony_ci I have no idea, how it will masquearde or NAT them (it is joke, joke :-)), 1238c2ecf20Sopenharmony_ci but receiver should be enough clever f.e. to forward mtrace requests, 1248c2ecf20Sopenharmony_ci sent to multicast group to reach destination designated router. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistruct ip_ra_chain { 1288c2ecf20Sopenharmony_ci struct ip_ra_chain __rcu *next; 1298c2ecf20Sopenharmony_ci struct sock *sk; 1308c2ecf20Sopenharmony_ci union { 1318c2ecf20Sopenharmony_ci void (*destructor)(struct sock *); 1328c2ecf20Sopenharmony_ci struct sock *saved_sk; 1338c2ecf20Sopenharmony_ci }; 1348c2ecf20Sopenharmony_ci struct rcu_head rcu; 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci/* IP flags. */ 1388c2ecf20Sopenharmony_ci#define IP_CE 0x8000 /* Flag: "Congestion" */ 1398c2ecf20Sopenharmony_ci#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 1408c2ecf20Sopenharmony_ci#define IP_MF 0x2000 /* Flag: "More Fragments" */ 1418c2ecf20Sopenharmony_ci#define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistruct msghdr; 1468c2ecf20Sopenharmony_cistruct net_device; 1478c2ecf20Sopenharmony_cistruct packet_type; 1488c2ecf20Sopenharmony_cistruct rtable; 1498c2ecf20Sopenharmony_cistruct sockaddr; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciint igmp_mc_init(void); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci/* 1548c2ecf20Sopenharmony_ci * Functions provided by ip.c 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ciint ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, 1588c2ecf20Sopenharmony_ci __be32 saddr, __be32 daddr, 1598c2ecf20Sopenharmony_ci struct ip_options_rcu *opt, u8 tos); 1608c2ecf20Sopenharmony_ciint ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, 1618c2ecf20Sopenharmony_ci struct net_device *orig_dev); 1628c2ecf20Sopenharmony_civoid ip_list_rcv(struct list_head *head, struct packet_type *pt, 1638c2ecf20Sopenharmony_ci struct net_device *orig_dev); 1648c2ecf20Sopenharmony_ciint ip_local_deliver(struct sk_buff *skb); 1658c2ecf20Sopenharmony_civoid ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int proto); 1668c2ecf20Sopenharmony_ciint ip_mr_input(struct sk_buff *skb); 1678c2ecf20Sopenharmony_ciint ip_output(struct net *net, struct sock *sk, struct sk_buff *skb); 1688c2ecf20Sopenharmony_ciint ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb); 1698c2ecf20Sopenharmony_ciint ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, 1708c2ecf20Sopenharmony_ci int (*output)(struct net *, struct sock *, struct sk_buff *)); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistruct ip_fraglist_iter { 1738c2ecf20Sopenharmony_ci struct sk_buff *frag; 1748c2ecf20Sopenharmony_ci struct iphdr *iph; 1758c2ecf20Sopenharmony_ci int offset; 1768c2ecf20Sopenharmony_ci unsigned int hlen; 1778c2ecf20Sopenharmony_ci}; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_civoid ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph, 1808c2ecf20Sopenharmony_ci unsigned int hlen, struct ip_fraglist_iter *iter); 1818c2ecf20Sopenharmony_civoid ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci struct sk_buff *skb = iter->frag; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci iter->frag = skb->next; 1888c2ecf20Sopenharmony_ci skb_mark_not_on_list(skb); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci return skb; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistruct ip_frag_state { 1948c2ecf20Sopenharmony_ci bool DF; 1958c2ecf20Sopenharmony_ci unsigned int hlen; 1968c2ecf20Sopenharmony_ci unsigned int ll_rs; 1978c2ecf20Sopenharmony_ci unsigned int mtu; 1988c2ecf20Sopenharmony_ci unsigned int left; 1998c2ecf20Sopenharmony_ci int offset; 2008c2ecf20Sopenharmony_ci int ptr; 2018c2ecf20Sopenharmony_ci __be16 not_last_frag; 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_civoid ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs, 2058c2ecf20Sopenharmony_ci unsigned int mtu, bool DF, struct ip_frag_state *state); 2068c2ecf20Sopenharmony_cistruct sk_buff *ip_frag_next(struct sk_buff *skb, 2078c2ecf20Sopenharmony_ci struct ip_frag_state *state); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_civoid ip_send_check(struct iphdr *ip); 2108c2ecf20Sopenharmony_ciint __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 2118c2ecf20Sopenharmony_ciint ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ciint __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 2148c2ecf20Sopenharmony_ci __u8 tos); 2158c2ecf20Sopenharmony_civoid ip_init(void); 2168c2ecf20Sopenharmony_ciint ip_append_data(struct sock *sk, struct flowi4 *fl4, 2178c2ecf20Sopenharmony_ci int getfrag(void *from, char *to, int offset, int len, 2188c2ecf20Sopenharmony_ci int odd, struct sk_buff *skb), 2198c2ecf20Sopenharmony_ci void *from, int len, int protolen, 2208c2ecf20Sopenharmony_ci struct ipcm_cookie *ipc, 2218c2ecf20Sopenharmony_ci struct rtable **rt, 2228c2ecf20Sopenharmony_ci unsigned int flags); 2238c2ecf20Sopenharmony_ciint ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, 2248c2ecf20Sopenharmony_ci struct sk_buff *skb); 2258c2ecf20Sopenharmony_cissize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, 2268c2ecf20Sopenharmony_ci int offset, size_t size, int flags); 2278c2ecf20Sopenharmony_cistruct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2288c2ecf20Sopenharmony_ci struct sk_buff_head *queue, 2298c2ecf20Sopenharmony_ci struct inet_cork *cork); 2308c2ecf20Sopenharmony_ciint ip_send_skb(struct net *net, struct sk_buff *skb); 2318c2ecf20Sopenharmony_ciint ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); 2328c2ecf20Sopenharmony_civoid ip_flush_pending_frames(struct sock *sk); 2338c2ecf20Sopenharmony_cistruct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4, 2348c2ecf20Sopenharmony_ci int getfrag(void *from, char *to, int offset, 2358c2ecf20Sopenharmony_ci int len, int odd, struct sk_buff *skb), 2368c2ecf20Sopenharmony_ci void *from, int length, int transhdrlen, 2378c2ecf20Sopenharmony_ci struct ipcm_cookie *ipc, struct rtable **rtp, 2388c2ecf20Sopenharmony_ci struct inet_cork *cork, unsigned int flags); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ciint ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base); 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet) 2488c2ecf20Sopenharmony_ci{ 2498c2ecf20Sopenharmony_ci return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos); 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/* datagram.c */ 2588c2ecf20Sopenharmony_ciint __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); 2598c2ecf20Sopenharmony_ciint ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_civoid ip4_datagram_release_cb(struct sock *sk); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistruct ip_reply_arg { 2648c2ecf20Sopenharmony_ci struct kvec iov[1]; 2658c2ecf20Sopenharmony_ci int flags; 2668c2ecf20Sopenharmony_ci __wsum csum; 2678c2ecf20Sopenharmony_ci int csumoffset; /* u16 offset of csum in iov[0].iov_base */ 2688c2ecf20Sopenharmony_ci /* -1 if not needed */ 2698c2ecf20Sopenharmony_ci int bound_dev_if; 2708c2ecf20Sopenharmony_ci u8 tos; 2718c2ecf20Sopenharmony_ci kuid_t uid; 2728c2ecf20Sopenharmony_ci}; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#define IP_REPLY_ARG_NOSRCCHECK 1 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_cistatic inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) 2778c2ecf20Sopenharmony_ci{ 2788c2ecf20Sopenharmony_ci return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_civoid ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, 2828c2ecf20Sopenharmony_ci const struct ip_options *sopt, 2838c2ecf20Sopenharmony_ci __be32 daddr, __be32 saddr, 2848c2ecf20Sopenharmony_ci const struct ip_reply_arg *arg, 2858c2ecf20Sopenharmony_ci unsigned int len, u64 transmit_time); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci#define IP_INC_STATS(net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field) 2888c2ecf20Sopenharmony_ci#define __IP_INC_STATS(net, field) __SNMP_INC_STATS64((net)->mib.ip_statistics, field) 2898c2ecf20Sopenharmony_ci#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val) 2908c2ecf20Sopenharmony_ci#define __IP_ADD_STATS(net, field, val) __SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val) 2918c2ecf20Sopenharmony_ci#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val) 2928c2ecf20Sopenharmony_ci#define __IP_UPD_PO_STATS(net, field, val) __SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val) 2938c2ecf20Sopenharmony_ci#define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field) 2948c2ecf20Sopenharmony_ci#define __NET_INC_STATS(net, field) __SNMP_INC_STATS((net)->mib.net_statistics, field) 2958c2ecf20Sopenharmony_ci#define NET_ADD_STATS(net, field, adnd) SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) 2968c2ecf20Sopenharmony_ci#define __NET_ADD_STATS(net, field, adnd) __SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ciu64 snmp_get_cpu_field(void __percpu *mib, int cpu, int offct); 2998c2ecf20Sopenharmony_ciunsigned long snmp_fold_field(void __percpu *mib, int offt); 3008c2ecf20Sopenharmony_ci#if BITS_PER_LONG==32 3018c2ecf20Sopenharmony_ciu64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 3028c2ecf20Sopenharmony_ci size_t syncp_offset); 3038c2ecf20Sopenharmony_ciu64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off); 3048c2ecf20Sopenharmony_ci#else 3058c2ecf20Sopenharmony_cistatic inline u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offct, 3068c2ecf20Sopenharmony_ci size_t syncp_offset) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci return snmp_get_cpu_field(mib, cpu, offct); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return snmp_fold_field(mib, offt); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci#endif 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci#define snmp_get_cpu_field64_batch(buff64, stats_list, mib_statistic, offset) \ 3198c2ecf20Sopenharmony_ci{ \ 3208c2ecf20Sopenharmony_ci int i, c; \ 3218c2ecf20Sopenharmony_ci for_each_possible_cpu(c) { \ 3228c2ecf20Sopenharmony_ci for (i = 0; stats_list[i].name; i++) \ 3238c2ecf20Sopenharmony_ci buff64[i] += snmp_get_cpu_field64( \ 3248c2ecf20Sopenharmony_ci mib_statistic, \ 3258c2ecf20Sopenharmony_ci c, stats_list[i].entry, \ 3268c2ecf20Sopenharmony_ci offset); \ 3278c2ecf20Sopenharmony_ci } \ 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci#define snmp_get_cpu_field_batch(buff, stats_list, mib_statistic) \ 3318c2ecf20Sopenharmony_ci{ \ 3328c2ecf20Sopenharmony_ci int i, c; \ 3338c2ecf20Sopenharmony_ci for_each_possible_cpu(c) { \ 3348c2ecf20Sopenharmony_ci for (i = 0; stats_list[i].name; i++) \ 3358c2ecf20Sopenharmony_ci buff[i] += snmp_get_cpu_field( \ 3368c2ecf20Sopenharmony_ci mib_statistic, \ 3378c2ecf20Sopenharmony_ci c, stats_list[i].entry); \ 3388c2ecf20Sopenharmony_ci } \ 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_civoid inet_get_local_port_range(struct net *net, int *low, int *high); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci#ifdef CONFIG_SYSCTL 3448c2ecf20Sopenharmony_cistatic inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci if (!net->ipv4.sysctl_local_reserved_ports) 3478c2ecf20Sopenharmony_ci return false; 3488c2ecf20Sopenharmony_ci return test_bit(port, net->ipv4.sysctl_local_reserved_ports); 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic inline bool sysctl_dev_name_is_allowed(const char *name) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; 3548c2ecf20Sopenharmony_ci} 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistatic inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3578c2ecf20Sopenharmony_ci{ 3588c2ecf20Sopenharmony_ci return port < READ_ONCE(net->ipv4.sysctl_ip_prot_sock); 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci#else 3628c2ecf20Sopenharmony_cistatic inline bool inet_is_local_reserved_port(struct net *net, unsigned short port) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci return false; 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) 3688c2ecf20Sopenharmony_ci{ 3698c2ecf20Sopenharmony_ci return port < PROT_SOCK; 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci#endif 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci__be32 inet_current_timestamp(void); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci/* From inetpeer.c */ 3768c2ecf20Sopenharmony_ciextern int inet_peer_threshold; 3778c2ecf20Sopenharmony_ciextern int inet_peer_minttl; 3788c2ecf20Sopenharmony_ciextern int inet_peer_maxttl; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_civoid ipfrag_init(void); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_civoid ip_static_sysctl_init(void); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#define IP4_REPLY_MARK(net, mark) \ 3858c2ecf20Sopenharmony_ci (READ_ONCE((net)->ipv4.sysctl_fwmark_reflect) ? (mark) : 0) 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_cistatic inline bool ip_is_fragment(const struct iphdr *iph) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; 3908c2ecf20Sopenharmony_ci} 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci#ifdef CONFIG_INET 3938c2ecf20Sopenharmony_ci#include <net/dst.h> 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci/* The function in 2.2 was invalid, producing wrong result for 3968c2ecf20Sopenharmony_ci * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ 3978c2ecf20Sopenharmony_cistatic inline 3988c2ecf20Sopenharmony_ciint ip_decrease_ttl(struct iphdr *iph) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci u32 check = (__force u32)iph->check; 4018c2ecf20Sopenharmony_ci check += (__force u32)htons(0x0100); 4028c2ecf20Sopenharmony_ci iph->check = (__force __sum16)(check + (check>=0xFFFF)); 4038c2ecf20Sopenharmony_ci return --iph->ttl; 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_cistatic inline int ip_mtu_locked(const struct dst_entry *dst) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci const struct rtable *rt = (const struct rtable *)dst; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU); 4118c2ecf20Sopenharmony_ci} 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_cistatic inline 4148c2ecf20Sopenharmony_ciint ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) 4158c2ecf20Sopenharmony_ci{ 4168c2ecf20Sopenharmony_ci u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc); 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci return pmtudisc == IP_PMTUDISC_DO || 4198c2ecf20Sopenharmony_ci (pmtudisc == IP_PMTUDISC_WANT && 4208c2ecf20Sopenharmony_ci !ip_mtu_locked(dst)); 4218c2ecf20Sopenharmony_ci} 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_cistatic inline bool ip_sk_accept_pmtu(const struct sock *sk) 4248c2ecf20Sopenharmony_ci{ 4258c2ecf20Sopenharmony_ci return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE && 4268c2ecf20Sopenharmony_ci inet_sk(sk)->pmtudisc != IP_PMTUDISC_OMIT; 4278c2ecf20Sopenharmony_ci} 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_cistatic inline bool ip_sk_use_pmtu(const struct sock *sk) 4308c2ecf20Sopenharmony_ci{ 4318c2ecf20Sopenharmony_ci return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; 4328c2ecf20Sopenharmony_ci} 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_cistatic inline bool ip_sk_ignore_df(const struct sock *sk) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO || 4378c2ecf20Sopenharmony_ci inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT; 4388c2ecf20Sopenharmony_ci} 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_cistatic inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, 4418c2ecf20Sopenharmony_ci bool forwarding) 4428c2ecf20Sopenharmony_ci{ 4438c2ecf20Sopenharmony_ci struct net *net = dev_net(dst->dev); 4448c2ecf20Sopenharmony_ci unsigned int mtu; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || 4478c2ecf20Sopenharmony_ci ip_mtu_locked(dst) || 4488c2ecf20Sopenharmony_ci !forwarding) 4498c2ecf20Sopenharmony_ci return dst_mtu(dst); 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci /* 'forwarding = true' case should always honour route mtu */ 4528c2ecf20Sopenharmony_ci mtu = dst_metric_raw(dst, RTAX_MTU); 4538c2ecf20Sopenharmony_ci if (!mtu) 4548c2ecf20Sopenharmony_ci mtu = min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci return mtu - lwtunnel_headroom(dst->lwtstate, mtu); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_cistatic inline unsigned int ip_skb_dst_mtu(struct sock *sk, 4608c2ecf20Sopenharmony_ci const struct sk_buff *skb) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci unsigned int mtu; 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { 4658c2ecf20Sopenharmony_ci bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci mtu = min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU); 4718c2ecf20Sopenharmony_ci return mtu - lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu); 4728c2ecf20Sopenharmony_ci} 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistruct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, 4758c2ecf20Sopenharmony_ci int fc_mx_len, 4768c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack); 4778c2ecf20Sopenharmony_cistatic inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics) 4788c2ecf20Sopenharmony_ci{ 4798c2ecf20Sopenharmony_ci if (fib_metrics != &dst_default_metrics && 4808c2ecf20Sopenharmony_ci refcount_dec_and_test(&fib_metrics->refcnt)) 4818c2ecf20Sopenharmony_ci kfree(fib_metrics); 4828c2ecf20Sopenharmony_ci} 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci/* ipv4 and ipv6 both use refcounted metrics if it is not the default */ 4858c2ecf20Sopenharmony_cistatic inline 4868c2ecf20Sopenharmony_civoid ip_dst_init_metrics(struct dst_entry *dst, struct dst_metrics *fib_metrics) 4878c2ecf20Sopenharmony_ci{ 4888c2ecf20Sopenharmony_ci dst_init_metrics(dst, fib_metrics->metrics, true); 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci if (fib_metrics != &dst_default_metrics) { 4918c2ecf20Sopenharmony_ci dst->_metrics |= DST_METRICS_REFCOUNTED; 4928c2ecf20Sopenharmony_ci refcount_inc(&fib_metrics->refcnt); 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cistatic inline 4978c2ecf20Sopenharmony_civoid ip_dst_metrics_put(struct dst_entry *dst) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) 5028c2ecf20Sopenharmony_ci kfree(p); 5038c2ecf20Sopenharmony_ci} 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ciu32 ip_idents_reserve(u32 hash, int segs); 5068c2ecf20Sopenharmony_civoid __ip_select_ident(struct net *net, struct iphdr *iph, int segs); 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_cistatic inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, 5098c2ecf20Sopenharmony_ci struct sock *sk, int segs) 5108c2ecf20Sopenharmony_ci{ 5118c2ecf20Sopenharmony_ci struct iphdr *iph = ip_hdr(skb); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci /* We had many attacks based on IPID, use the private 5148c2ecf20Sopenharmony_ci * generator as much as we can. 5158c2ecf20Sopenharmony_ci */ 5168c2ecf20Sopenharmony_ci if (sk && inet_sk(sk)->inet_daddr) { 5178c2ecf20Sopenharmony_ci iph->id = htons(inet_sk(sk)->inet_id); 5188c2ecf20Sopenharmony_ci inet_sk(sk)->inet_id += segs; 5198c2ecf20Sopenharmony_ci return; 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { 5228c2ecf20Sopenharmony_ci iph->id = 0; 5238c2ecf20Sopenharmony_ci } else { 5248c2ecf20Sopenharmony_ci /* Unfortunately we need the big hammer to get a suitable IPID */ 5258c2ecf20Sopenharmony_ci __ip_select_ident(net, iph, segs); 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic inline void ip_select_ident(struct net *net, struct sk_buff *skb, 5308c2ecf20Sopenharmony_ci struct sock *sk) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci ip_select_ident_segs(net, skb, sk, 1); 5338c2ecf20Sopenharmony_ci} 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_cistatic inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto) 5368c2ecf20Sopenharmony_ci{ 5378c2ecf20Sopenharmony_ci return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 5388c2ecf20Sopenharmony_ci skb->len, proto, 0); 5398c2ecf20Sopenharmony_ci} 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci/* copy IPv4 saddr & daddr to flow_keys, possibly using 64bit load/store 5428c2ecf20Sopenharmony_ci * Equivalent to : flow->v4addrs.src = iph->saddr; 5438c2ecf20Sopenharmony_ci * flow->v4addrs.dst = iph->daddr; 5448c2ecf20Sopenharmony_ci */ 5458c2ecf20Sopenharmony_cistatic inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow, 5468c2ecf20Sopenharmony_ci const struct iphdr *iph) 5478c2ecf20Sopenharmony_ci{ 5488c2ecf20Sopenharmony_ci BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) != 5498c2ecf20Sopenharmony_ci offsetof(typeof(flow->addrs), v4addrs.src) + 5508c2ecf20Sopenharmony_ci sizeof(flow->addrs.v4addrs.src)); 5518c2ecf20Sopenharmony_ci memcpy(&flow->addrs.v4addrs, &iph->addrs, sizeof(flow->addrs.v4addrs)); 5528c2ecf20Sopenharmony_ci flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 5538c2ecf20Sopenharmony_ci} 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_cistatic inline __wsum inet_gro_compute_pseudo(struct sk_buff *skb, int proto) 5568c2ecf20Sopenharmony_ci{ 5578c2ecf20Sopenharmony_ci const struct iphdr *iph = skb_gro_network_header(skb); 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci return csum_tcpudp_nofold(iph->saddr, iph->daddr, 5608c2ecf20Sopenharmony_ci skb_gro_len(skb), proto, 0); 5618c2ecf20Sopenharmony_ci} 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci/* 5648c2ecf20Sopenharmony_ci * Map a multicast IP onto multicast MAC for type ethernet. 5658c2ecf20Sopenharmony_ci */ 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_cistatic inline void ip_eth_mc_map(__be32 naddr, char *buf) 5688c2ecf20Sopenharmony_ci{ 5698c2ecf20Sopenharmony_ci __u32 addr=ntohl(naddr); 5708c2ecf20Sopenharmony_ci buf[0]=0x01; 5718c2ecf20Sopenharmony_ci buf[1]=0x00; 5728c2ecf20Sopenharmony_ci buf[2]=0x5e; 5738c2ecf20Sopenharmony_ci buf[5]=addr&0xFF; 5748c2ecf20Sopenharmony_ci addr>>=8; 5758c2ecf20Sopenharmony_ci buf[4]=addr&0xFF; 5768c2ecf20Sopenharmony_ci addr>>=8; 5778c2ecf20Sopenharmony_ci buf[3]=addr&0x7F; 5788c2ecf20Sopenharmony_ci} 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci/* 5818c2ecf20Sopenharmony_ci * Map a multicast IP onto multicast MAC for type IP-over-InfiniBand. 5828c2ecf20Sopenharmony_ci * Leave P_Key as 0 to be filled in by driver. 5838c2ecf20Sopenharmony_ci */ 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_cistatic inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 5868c2ecf20Sopenharmony_ci{ 5878c2ecf20Sopenharmony_ci __u32 addr; 5888c2ecf20Sopenharmony_ci unsigned char scope = broadcast[5] & 0xF; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci buf[0] = 0; /* Reserved */ 5918c2ecf20Sopenharmony_ci buf[1] = 0xff; /* Multicast QPN */ 5928c2ecf20Sopenharmony_ci buf[2] = 0xff; 5938c2ecf20Sopenharmony_ci buf[3] = 0xff; 5948c2ecf20Sopenharmony_ci addr = ntohl(naddr); 5958c2ecf20Sopenharmony_ci buf[4] = 0xff; 5968c2ecf20Sopenharmony_ci buf[5] = 0x10 | scope; /* scope from broadcast address */ 5978c2ecf20Sopenharmony_ci buf[6] = 0x40; /* IPv4 signature */ 5988c2ecf20Sopenharmony_ci buf[7] = 0x1b; 5998c2ecf20Sopenharmony_ci buf[8] = broadcast[8]; /* P_Key */ 6008c2ecf20Sopenharmony_ci buf[9] = broadcast[9]; 6018c2ecf20Sopenharmony_ci buf[10] = 0; 6028c2ecf20Sopenharmony_ci buf[11] = 0; 6038c2ecf20Sopenharmony_ci buf[12] = 0; 6048c2ecf20Sopenharmony_ci buf[13] = 0; 6058c2ecf20Sopenharmony_ci buf[14] = 0; 6068c2ecf20Sopenharmony_ci buf[15] = 0; 6078c2ecf20Sopenharmony_ci buf[19] = addr & 0xff; 6088c2ecf20Sopenharmony_ci addr >>= 8; 6098c2ecf20Sopenharmony_ci buf[18] = addr & 0xff; 6108c2ecf20Sopenharmony_ci addr >>= 8; 6118c2ecf20Sopenharmony_ci buf[17] = addr & 0xff; 6128c2ecf20Sopenharmony_ci addr >>= 8; 6138c2ecf20Sopenharmony_ci buf[16] = addr & 0x0f; 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_cistatic inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) 6178c2ecf20Sopenharmony_ci{ 6188c2ecf20Sopenharmony_ci if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) 6198c2ecf20Sopenharmony_ci memcpy(buf, broadcast, 4); 6208c2ecf20Sopenharmony_ci else 6218c2ecf20Sopenharmony_ci memcpy(buf, &naddr, sizeof(naddr)); 6228c2ecf20Sopenharmony_ci} 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 6258c2ecf20Sopenharmony_ci#include <linux/ipv6.h> 6268c2ecf20Sopenharmony_ci#endif 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_cistatic __inline__ void inet_reset_saddr(struct sock *sk) 6298c2ecf20Sopenharmony_ci{ 6308c2ecf20Sopenharmony_ci inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0; 6318c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 6328c2ecf20Sopenharmony_ci if (sk->sk_family == PF_INET6) { 6338c2ecf20Sopenharmony_ci struct ipv6_pinfo *np = inet6_sk(sk); 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci memset(&np->saddr, 0, sizeof(np->saddr)); 6368c2ecf20Sopenharmony_ci memset(&sk->sk_v6_rcv_saddr, 0, sizeof(sk->sk_v6_rcv_saddr)); 6378c2ecf20Sopenharmony_ci } 6388c2ecf20Sopenharmony_ci#endif 6398c2ecf20Sopenharmony_ci} 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci#endif 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic inline unsigned int ipv4_addr_hash(__be32 ip) 6448c2ecf20Sopenharmony_ci{ 6458c2ecf20Sopenharmony_ci return (__force unsigned int) ip; 6468c2ecf20Sopenharmony_ci} 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_cistatic inline u32 ipv4_portaddr_hash(const struct net *net, 6498c2ecf20Sopenharmony_ci __be32 saddr, 6508c2ecf20Sopenharmony_ci unsigned int port) 6518c2ecf20Sopenharmony_ci{ 6528c2ecf20Sopenharmony_ci return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port; 6538c2ecf20Sopenharmony_ci} 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_cibool ip_call_ra_chain(struct sk_buff *skb); 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci/* 6588c2ecf20Sopenharmony_ci * Functions provided by ip_fragment.c 6598c2ecf20Sopenharmony_ci */ 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_cienum ip_defrag_users { 6628c2ecf20Sopenharmony_ci IP_DEFRAG_LOCAL_DELIVER, 6638c2ecf20Sopenharmony_ci IP_DEFRAG_CALL_RA_CHAIN, 6648c2ecf20Sopenharmony_ci IP_DEFRAG_CONNTRACK_IN, 6658c2ecf20Sopenharmony_ci __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHRT_MAX, 6668c2ecf20Sopenharmony_ci IP_DEFRAG_CONNTRACK_OUT, 6678c2ecf20Sopenharmony_ci __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX, 6688c2ecf20Sopenharmony_ci IP_DEFRAG_CONNTRACK_BRIDGE_IN, 6698c2ecf20Sopenharmony_ci __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, 6708c2ecf20Sopenharmony_ci IP_DEFRAG_VS_IN, 6718c2ecf20Sopenharmony_ci IP_DEFRAG_VS_OUT, 6728c2ecf20Sopenharmony_ci IP_DEFRAG_VS_FWD, 6738c2ecf20Sopenharmony_ci IP_DEFRAG_AF_PACKET, 6748c2ecf20Sopenharmony_ci IP_DEFRAG_MACVLAN, 6758c2ecf20Sopenharmony_ci}; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci/* Return true if the value of 'user' is between 'lower_bond' 6788c2ecf20Sopenharmony_ci * and 'upper_bond' inclusively. 6798c2ecf20Sopenharmony_ci */ 6808c2ecf20Sopenharmony_cistatic inline bool ip_defrag_user_in_between(u32 user, 6818c2ecf20Sopenharmony_ci enum ip_defrag_users lower_bond, 6828c2ecf20Sopenharmony_ci enum ip_defrag_users upper_bond) 6838c2ecf20Sopenharmony_ci{ 6848c2ecf20Sopenharmony_ci return user >= lower_bond && user <= upper_bond; 6858c2ecf20Sopenharmony_ci} 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ciint ip_defrag(struct net *net, struct sk_buff *skb, u32 user); 6888c2ecf20Sopenharmony_ci#ifdef CONFIG_INET 6898c2ecf20Sopenharmony_cistruct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user); 6908c2ecf20Sopenharmony_ci#else 6918c2ecf20Sopenharmony_cistatic inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user) 6928c2ecf20Sopenharmony_ci{ 6938c2ecf20Sopenharmony_ci return skb; 6948c2ecf20Sopenharmony_ci} 6958c2ecf20Sopenharmony_ci#endif 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci/* 6988c2ecf20Sopenharmony_ci * Functions provided by ip_forward.c 6998c2ecf20Sopenharmony_ci */ 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ciint ip_forward(struct sk_buff *skb); 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci/* 7048c2ecf20Sopenharmony_ci * Functions provided by ip_options.c 7058c2ecf20Sopenharmony_ci */ 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_civoid ip_options_build(struct sk_buff *skb, struct ip_options *opt, 7088c2ecf20Sopenharmony_ci __be32 daddr, struct rtable *rt, int is_frag); 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ciint __ip_options_echo(struct net *net, struct ip_options *dopt, 7118c2ecf20Sopenharmony_ci struct sk_buff *skb, const struct ip_options *sopt); 7128c2ecf20Sopenharmony_cistatic inline int ip_options_echo(struct net *net, struct ip_options *dopt, 7138c2ecf20Sopenharmony_ci struct sk_buff *skb) 7148c2ecf20Sopenharmony_ci{ 7158c2ecf20Sopenharmony_ci return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt); 7168c2ecf20Sopenharmony_ci} 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_civoid ip_options_fragment(struct sk_buff *skb); 7198c2ecf20Sopenharmony_ciint __ip_options_compile(struct net *net, struct ip_options *opt, 7208c2ecf20Sopenharmony_ci struct sk_buff *skb, __be32 *info); 7218c2ecf20Sopenharmony_ciint ip_options_compile(struct net *net, struct ip_options *opt, 7228c2ecf20Sopenharmony_ci struct sk_buff *skb); 7238c2ecf20Sopenharmony_ciint ip_options_get(struct net *net, struct ip_options_rcu **optp, 7248c2ecf20Sopenharmony_ci sockptr_t data, int optlen); 7258c2ecf20Sopenharmony_civoid ip_options_undo(struct ip_options *opt); 7268c2ecf20Sopenharmony_civoid ip_forward_options(struct sk_buff *skb); 7278c2ecf20Sopenharmony_ciint ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci/* 7308c2ecf20Sopenharmony_ci * Functions provided by ip_sockglue.c 7318c2ecf20Sopenharmony_ci */ 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_civoid ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); 7348c2ecf20Sopenharmony_civoid ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, 7358c2ecf20Sopenharmony_ci struct sk_buff *skb, int tlen, int offset); 7368c2ecf20Sopenharmony_ciint ip_cmsg_send(struct sock *sk, struct msghdr *msg, 7378c2ecf20Sopenharmony_ci struct ipcm_cookie *ipc, bool allow_ipv6); 7388c2ecf20Sopenharmony_ciint ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, 7398c2ecf20Sopenharmony_ci unsigned int optlen); 7408c2ecf20Sopenharmony_ciint ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, 7418c2ecf20Sopenharmony_ci int __user *optlen); 7428c2ecf20Sopenharmony_ciint ip_ra_control(struct sock *sk, unsigned char on, 7438c2ecf20Sopenharmony_ci void (*destructor)(struct sock *)); 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ciint ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); 7468c2ecf20Sopenharmony_civoid ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, 7478c2ecf20Sopenharmony_ci u32 info, u8 *payload); 7488c2ecf20Sopenharmony_civoid ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, 7498c2ecf20Sopenharmony_ci u32 info); 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_cistatic inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) 7528c2ecf20Sopenharmony_ci{ 7538c2ecf20Sopenharmony_ci ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0); 7548c2ecf20Sopenharmony_ci} 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_cibool icmp_global_allow(void); 7578c2ecf20Sopenharmony_ciextern int sysctl_icmp_msgs_per_sec; 7588c2ecf20Sopenharmony_ciextern int sysctl_icmp_msgs_burst; 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS 7618c2ecf20Sopenharmony_ciint ip_misc_proc_init(void); 7628c2ecf20Sopenharmony_ci#endif 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ciint rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, 7658c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_cistatic inline bool inetdev_valid_mtu(unsigned int mtu) 7688c2ecf20Sopenharmony_ci{ 7698c2ecf20Sopenharmony_ci return likely(mtu >= IPV4_MIN_MTU); 7708c2ecf20Sopenharmony_ci} 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_civoid ip_sock_set_freebind(struct sock *sk); 7738c2ecf20Sopenharmony_ciint ip_sock_set_mtu_discover(struct sock *sk, int val); 7748c2ecf20Sopenharmony_civoid ip_sock_set_pktinfo(struct sock *sk); 7758c2ecf20Sopenharmony_civoid ip_sock_set_recverr(struct sock *sk); 7768c2ecf20Sopenharmony_civoid ip_sock_set_tos(struct sock *sk, int val); 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci#endif /* _IP_H */ 779