18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * inet6 interface/address list definitions 48c2ecf20Sopenharmony_ci * Linux INET6 implementation 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Authors: 78c2ecf20Sopenharmony_ci * Pedro Roque <roque@di.fc.ul.pt> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef _NET_IF_INET6_H 118c2ecf20Sopenharmony_ci#define _NET_IF_INET6_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <net/snmp.h> 148c2ecf20Sopenharmony_ci#include <linux/ipv6.h> 158c2ecf20Sopenharmony_ci#include <linux/refcount.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* inet6_dev.if_flags */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define IF_RA_OTHERCONF 0x80 208c2ecf20Sopenharmony_ci#define IF_RA_MANAGED 0x40 218c2ecf20Sopenharmony_ci#define IF_RA_RCVD 0x20 228c2ecf20Sopenharmony_ci#define IF_RS_SENT 0x10 238c2ecf20Sopenharmony_ci#define IF_READY 0x80000000 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cienum { 268c2ecf20Sopenharmony_ci INET6_IFADDR_STATE_PREDAD, 278c2ecf20Sopenharmony_ci INET6_IFADDR_STATE_DAD, 288c2ecf20Sopenharmony_ci INET6_IFADDR_STATE_POSTDAD, 298c2ecf20Sopenharmony_ci INET6_IFADDR_STATE_ERRDAD, 308c2ecf20Sopenharmony_ci INET6_IFADDR_STATE_DEAD, 318c2ecf20Sopenharmony_ci}; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistruct inet6_ifaddr { 348c2ecf20Sopenharmony_ci struct in6_addr addr; 358c2ecf20Sopenharmony_ci __u32 prefix_len; 368c2ecf20Sopenharmony_ci __u32 rt_priority; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */ 398c2ecf20Sopenharmony_ci __u32 valid_lft; 408c2ecf20Sopenharmony_ci __u32 prefered_lft; 418c2ecf20Sopenharmony_ci refcount_t refcnt; 428c2ecf20Sopenharmony_ci spinlock_t lock; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci int state; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci __u32 flags; 478c2ecf20Sopenharmony_ci __u8 dad_probes; 488c2ecf20Sopenharmony_ci __u8 stable_privacy_retry; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci __u16 scope; 518c2ecf20Sopenharmony_ci __u64 dad_nonce; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci unsigned long cstamp; /* created timestamp */ 548c2ecf20Sopenharmony_ci unsigned long tstamp; /* updated timestamp */ 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci struct delayed_work dad_work; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci struct inet6_dev *idev; 598c2ecf20Sopenharmony_ci struct fib6_info *rt; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci struct hlist_node addr_lst; 628c2ecf20Sopenharmony_ci struct list_head if_list; 638c2ecf20Sopenharmony_ci /* 648c2ecf20Sopenharmony_ci * Used to safely traverse idev->addr_list in process context 658c2ecf20Sopenharmony_ci * if the idev->lock needed to protect idev->addr_list cannot be held. 668c2ecf20Sopenharmony_ci * In that case, add the items to this list temporarily and iterate 678c2ecf20Sopenharmony_ci * without holding idev->lock. 688c2ecf20Sopenharmony_ci * See addrconf_ifdown and dev_forward_change. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci struct list_head if_list_aux; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci struct list_head tmp_list; 738c2ecf20Sopenharmony_ci struct inet6_ifaddr *ifpub; 748c2ecf20Sopenharmony_ci int regen_count; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci bool tokenized; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci struct rcu_head rcu; 798c2ecf20Sopenharmony_ci struct in6_addr peer_addr; 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistruct ip6_sf_socklist { 838c2ecf20Sopenharmony_ci unsigned int sl_max; 848c2ecf20Sopenharmony_ci unsigned int sl_count; 858c2ecf20Sopenharmony_ci struct in6_addr sl_addr[]; 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#define IP6_SFLSIZE(count) (sizeof(struct ip6_sf_socklist) + \ 898c2ecf20Sopenharmony_ci (count) * sizeof(struct in6_addr)) 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define IP6_SFBLOCK 10 /* allocate this many at once */ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistruct ipv6_mc_socklist { 948c2ecf20Sopenharmony_ci struct in6_addr addr; 958c2ecf20Sopenharmony_ci int ifindex; 968c2ecf20Sopenharmony_ci unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ 978c2ecf20Sopenharmony_ci struct ipv6_mc_socklist __rcu *next; 988c2ecf20Sopenharmony_ci rwlock_t sflock; 998c2ecf20Sopenharmony_ci struct ip6_sf_socklist *sflist; 1008c2ecf20Sopenharmony_ci struct rcu_head rcu; 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistruct ip6_sf_list { 1048c2ecf20Sopenharmony_ci struct ip6_sf_list *sf_next; 1058c2ecf20Sopenharmony_ci struct in6_addr sf_addr; 1068c2ecf20Sopenharmony_ci unsigned long sf_count[2]; /* include/exclude counts */ 1078c2ecf20Sopenharmony_ci unsigned char sf_gsresp; /* include in g & s response? */ 1088c2ecf20Sopenharmony_ci unsigned char sf_oldin; /* change state */ 1098c2ecf20Sopenharmony_ci unsigned char sf_crcount; /* retrans. left to send */ 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define MAF_TIMER_RUNNING 0x01 1138c2ecf20Sopenharmony_ci#define MAF_LAST_REPORTER 0x02 1148c2ecf20Sopenharmony_ci#define MAF_LOADED 0x04 1158c2ecf20Sopenharmony_ci#define MAF_NOREPORT 0x08 1168c2ecf20Sopenharmony_ci#define MAF_GSQUERY 0x10 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistruct ifmcaddr6 { 1198c2ecf20Sopenharmony_ci struct in6_addr mca_addr; 1208c2ecf20Sopenharmony_ci struct inet6_dev *idev; 1218c2ecf20Sopenharmony_ci struct ifmcaddr6 *next; 1228c2ecf20Sopenharmony_ci struct ip6_sf_list *mca_sources; 1238c2ecf20Sopenharmony_ci struct ip6_sf_list *mca_tomb; 1248c2ecf20Sopenharmony_ci unsigned int mca_sfmode; 1258c2ecf20Sopenharmony_ci unsigned char mca_crcount; 1268c2ecf20Sopenharmony_ci unsigned long mca_sfcount[2]; 1278c2ecf20Sopenharmony_ci struct timer_list mca_timer; 1288c2ecf20Sopenharmony_ci unsigned int mca_flags; 1298c2ecf20Sopenharmony_ci int mca_users; 1308c2ecf20Sopenharmony_ci refcount_t mca_refcnt; 1318c2ecf20Sopenharmony_ci spinlock_t mca_lock; 1328c2ecf20Sopenharmony_ci unsigned long mca_cstamp; 1338c2ecf20Sopenharmony_ci unsigned long mca_tstamp; 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/* Anycast stuff */ 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct ipv6_ac_socklist { 1398c2ecf20Sopenharmony_ci struct in6_addr acl_addr; 1408c2ecf20Sopenharmony_ci int acl_ifindex; 1418c2ecf20Sopenharmony_ci struct ipv6_ac_socklist *acl_next; 1428c2ecf20Sopenharmony_ci}; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistruct ifacaddr6 { 1458c2ecf20Sopenharmony_ci struct in6_addr aca_addr; 1468c2ecf20Sopenharmony_ci struct fib6_info *aca_rt; 1478c2ecf20Sopenharmony_ci struct ifacaddr6 *aca_next; 1488c2ecf20Sopenharmony_ci struct hlist_node aca_addr_lst; 1498c2ecf20Sopenharmony_ci int aca_users; 1508c2ecf20Sopenharmony_ci refcount_t aca_refcnt; 1518c2ecf20Sopenharmony_ci unsigned long aca_cstamp; 1528c2ecf20Sopenharmony_ci unsigned long aca_tstamp; 1538c2ecf20Sopenharmony_ci struct rcu_head rcu; 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci#define IFA_HOST IPV6_ADDR_LOOPBACK 1578c2ecf20Sopenharmony_ci#define IFA_LINK IPV6_ADDR_LINKLOCAL 1588c2ecf20Sopenharmony_ci#define IFA_SITE IPV6_ADDR_SITELOCAL 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistruct ipv6_devstat { 1618c2ecf20Sopenharmony_ci struct proc_dir_entry *proc_dir_entry; 1628c2ecf20Sopenharmony_ci DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); 1638c2ecf20Sopenharmony_ci DEFINE_SNMP_STAT_ATOMIC(struct icmpv6_mib_device, icmpv6dev); 1648c2ecf20Sopenharmony_ci DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib_device, icmpv6msgdev); 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistruct inet6_dev { 1688c2ecf20Sopenharmony_ci struct net_device *dev; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci struct list_head addr_list; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci struct ifmcaddr6 *mc_list; 1738c2ecf20Sopenharmony_ci struct ifmcaddr6 *mc_tomb; 1748c2ecf20Sopenharmony_ci spinlock_t mc_lock; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci unsigned char mc_qrv; /* Query Robustness Variable */ 1778c2ecf20Sopenharmony_ci unsigned char mc_gq_running; 1788c2ecf20Sopenharmony_ci unsigned char mc_ifc_count; 1798c2ecf20Sopenharmony_ci unsigned char mc_dad_count; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci unsigned long mc_v1_seen; /* Max time we stay in MLDv1 mode */ 1828c2ecf20Sopenharmony_ci unsigned long mc_qi; /* Query Interval */ 1838c2ecf20Sopenharmony_ci unsigned long mc_qri; /* Query Response Interval */ 1848c2ecf20Sopenharmony_ci unsigned long mc_maxdelay; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci struct timer_list mc_gq_timer; /* general query timer */ 1878c2ecf20Sopenharmony_ci struct timer_list mc_ifc_timer; /* interface change timer */ 1888c2ecf20Sopenharmony_ci struct timer_list mc_dad_timer; /* dad complete mc timer */ 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci struct ifacaddr6 *ac_list; 1918c2ecf20Sopenharmony_ci rwlock_t lock; 1928c2ecf20Sopenharmony_ci refcount_t refcnt; 1938c2ecf20Sopenharmony_ci __u32 if_flags; 1948c2ecf20Sopenharmony_ci int dead; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci u32 desync_factor; 1978c2ecf20Sopenharmony_ci struct list_head tempaddr_list; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci struct in6_addr token; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci struct neigh_parms *nd_parms; 2028c2ecf20Sopenharmony_ci struct ipv6_devconf cnf; 2038c2ecf20Sopenharmony_ci struct ipv6_devstat stats; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci struct timer_list rs_timer; 2068c2ecf20Sopenharmony_ci __s32 rs_interval; /* in jiffies */ 2078c2ecf20Sopenharmony_ci __u8 rs_probes; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ 2108c2ecf20Sopenharmony_ci struct rcu_head rcu; 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci /* 2168c2ecf20Sopenharmony_ci * +-------+-------+-------+-------+-------+-------+ 2178c2ecf20Sopenharmony_ci * | 33 | 33 | DST13 | DST14 | DST15 | DST16 | 2188c2ecf20Sopenharmony_ci * +-------+-------+-------+-------+-------+-------+ 2198c2ecf20Sopenharmony_ci */ 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci buf[0]= 0x33; 2228c2ecf20Sopenharmony_ci buf[1]= 0x33; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci buf[0] = 0x00; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic inline void ipv6_ib_mc_map(const struct in6_addr *addr, 2338c2ecf20Sopenharmony_ci const unsigned char *broadcast, char *buf) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci unsigned char scope = broadcast[5] & 0xF; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci buf[0] = 0; /* Reserved */ 2388c2ecf20Sopenharmony_ci buf[1] = 0xff; /* Multicast QPN */ 2398c2ecf20Sopenharmony_ci buf[2] = 0xff; 2408c2ecf20Sopenharmony_ci buf[3] = 0xff; 2418c2ecf20Sopenharmony_ci buf[4] = 0xff; 2428c2ecf20Sopenharmony_ci buf[5] = 0x10 | scope; /* scope from broadcast address */ 2438c2ecf20Sopenharmony_ci buf[6] = 0x60; /* IPv6 signature */ 2448c2ecf20Sopenharmony_ci buf[7] = 0x1b; 2458c2ecf20Sopenharmony_ci buf[8] = broadcast[8]; /* P_Key */ 2468c2ecf20Sopenharmony_ci buf[9] = broadcast[9]; 2478c2ecf20Sopenharmony_ci memcpy(buf + 10, addr->s6_addr + 6, 10); 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_cistatic inline int ipv6_ipgre_mc_map(const struct in6_addr *addr, 2518c2ecf20Sopenharmony_ci const unsigned char *broadcast, char *buf) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) { 2548c2ecf20Sopenharmony_ci memcpy(buf, broadcast, 4); 2558c2ecf20Sopenharmony_ci } else { 2568c2ecf20Sopenharmony_ci /* v4mapped? */ 2578c2ecf20Sopenharmony_ci if ((addr->s6_addr32[0] | addr->s6_addr32[1] | 2588c2ecf20Sopenharmony_ci (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0) 2598c2ecf20Sopenharmony_ci return -EINVAL; 2608c2ecf20Sopenharmony_ci memcpy(buf, &addr->s6_addr32[3], 4); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci return 0; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci#endif 266