12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * inet6 interface/address list definitions
41da177e4SLinus Torvalds * Linux INET6 implementation
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Authors:
71da177e4SLinus Torvalds * Pedro Roque <roque@di.fc.ul.pt>
81da177e4SLinus Torvalds */
91da177e4SLinus Torvalds
101da177e4SLinus Torvalds #ifndef _NET_IF_INET6_H
111da177e4SLinus Torvalds #define _NET_IF_INET6_H
121da177e4SLinus Torvalds
131da177e4SLinus Torvalds #include <net/snmp.h>
141da177e4SLinus Torvalds #include <linux/ipv6.h>
151be92460SReshetova, Elena #include <linux/refcount.h>
161da177e4SLinus Torvalds
171da177e4SLinus Torvalds /* inet6_dev.if_flags */
181da177e4SLinus Torvalds
191da177e4SLinus Torvalds #define IF_RA_OTHERCONF 0x80
201da177e4SLinus Torvalds #define IF_RA_MANAGED 0x40
211da177e4SLinus Torvalds #define IF_RA_RCVD 0x20
221da177e4SLinus Torvalds #define IF_RS_SENT 0x10
233c21edbdSYOSHIFUJI Hideaki #define IF_READY 0x80000000
241da177e4SLinus Torvalds
25e9d3e084SHerbert Xu enum {
26c15b1ccaSHannes Frederic Sowa INET6_IFADDR_STATE_PREDAD,
27e9d3e084SHerbert Xu INET6_IFADDR_STATE_DAD,
28e9d3e084SHerbert Xu INET6_IFADDR_STATE_POSTDAD,
29c15b1ccaSHannes Frederic Sowa INET6_IFADDR_STATE_ERRDAD,
30e9d3e084SHerbert Xu INET6_IFADDR_STATE_DEAD,
31e9d3e084SHerbert Xu };
32e9d3e084SHerbert Xu
33fd2c3ef7SEric Dumazet struct inet6_ifaddr {
341da177e4SLinus Torvalds struct in6_addr addr;
351da177e4SLinus Torvalds __u32 prefix_len;
368308f3ffSDavid Ahern __u32 rt_priority;
371da177e4SLinus Torvalds
3876f793e3SLorenzo Colitti /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */
391da177e4SLinus Torvalds __u32 valid_lft;
401da177e4SLinus Torvalds __u32 prefered_lft;
41271201c0SReshetova, Elena refcount_t refcnt;
421da177e4SLinus Torvalds spinlock_t lock;
43e9d3e084SHerbert Xu
44e9d3e084SHerbert Xu int state;
451da177e4SLinus Torvalds
46479840ffSJiri Pirko __u32 flags;
47b7b1bfceSHannes Frederic Sowa __u8 dad_probes;
485f40ef77SHannes Frederic Sowa __u8 stable_privacy_retry;
491da177e4SLinus Torvalds
501da177e4SLinus Torvalds __u16 scope;
51adc176c5SErik Nordmark __u64 dad_nonce;
521da177e4SLinus Torvalds
5304ec5cfcSRichard Kennedy unsigned long cstamp; /* created timestamp */
5404ec5cfcSRichard Kennedy unsigned long tstamp; /* updated timestamp */
5504ec5cfcSRichard Kennedy
56c15b1ccaSHannes Frederic Sowa struct delayed_work dad_work;
571da177e4SLinus Torvalds
581da177e4SLinus Torvalds struct inet6_dev *idev;
598d1c802bSDavid Ahern struct fib6_info *rt;
601da177e4SLinus Torvalds
61c2e21293Sstephen hemminger struct hlist_node addr_lst;
62502a2ffdSstephen hemminger struct list_head if_list;
63*51454ea4SNiels Dossche /*
64*51454ea4SNiels Dossche * Used to safely traverse idev->addr_list in process context
65*51454ea4SNiels Dossche * if the idev->lock needed to protect idev->addr_list cannot be held.
66*51454ea4SNiels Dossche * In that case, add the items to this list temporarily and iterate
67*51454ea4SNiels Dossche * without holding idev->lock.
68*51454ea4SNiels Dossche * See addrconf_ifdown and dev_forward_change.
69*51454ea4SNiels Dossche */
70*51454ea4SNiels Dossche struct list_head if_list_aux;
711da177e4SLinus Torvalds
72372e6c8fSstephen hemminger struct list_head tmp_list;
731da177e4SLinus Torvalds struct inet6_ifaddr *ifpub;
741da177e4SLinus Torvalds int regen_count;
755d9efa7eSDavid S. Miller
76617fe29dSDaniel Borkmann bool tokenized;
77617fe29dSDaniel Borkmann
7847f0bd50SJacques de Laval u8 ifa_proto;
7947f0bd50SJacques de Laval
805c578aedSstephen hemminger struct rcu_head rcu;
81caeaba79SNicolas Dichtel struct in6_addr peer_addr;
821da177e4SLinus Torvalds };
831da177e4SLinus Torvalds
84fd2c3ef7SEric Dumazet struct ip6_sf_socklist {
851da177e4SLinus Torvalds unsigned int sl_max;
861da177e4SLinus Torvalds unsigned int sl_count;
87882ba1f7STaehee Yoo struct rcu_head rcu;
880fa39d6dSGustavo A. R. Silva struct in6_addr sl_addr[];
891da177e4SLinus Torvalds };
901da177e4SLinus Torvalds
911da177e4SLinus Torvalds #define IP6_SFBLOCK 10 /* allocate this many at once */
921da177e4SLinus Torvalds
93fd2c3ef7SEric Dumazet struct ipv6_mc_socklist {
941da177e4SLinus Torvalds struct in6_addr addr;
951da177e4SLinus Torvalds int ifindex;
9614105c19SEric Dumazet unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
97456b61bcSEric Dumazet struct ipv6_mc_socklist __rcu *next;
98882ba1f7STaehee Yoo struct ip6_sf_socklist __rcu *sflist;
99456b61bcSEric Dumazet struct rcu_head rcu;
1001da177e4SLinus Torvalds };
1011da177e4SLinus Torvalds
102fd2c3ef7SEric Dumazet struct ip6_sf_list {
1034b200e39STaehee Yoo struct ip6_sf_list __rcu *sf_next;
1041da177e4SLinus Torvalds struct in6_addr sf_addr;
1051da177e4SLinus Torvalds unsigned long sf_count[2]; /* include/exclude counts */
1061da177e4SLinus Torvalds unsigned char sf_gsresp; /* include in g & s response? */
1071da177e4SLinus Torvalds unsigned char sf_oldin; /* change state */
1081da177e4SLinus Torvalds unsigned char sf_crcount; /* retrans. left to send */
1094b200e39STaehee Yoo struct rcu_head rcu;
1101da177e4SLinus Torvalds };
1111da177e4SLinus Torvalds
1121da177e4SLinus Torvalds #define MAF_TIMER_RUNNING 0x01
1131da177e4SLinus Torvalds #define MAF_LAST_REPORTER 0x02
1141da177e4SLinus Torvalds #define MAF_LOADED 0x04
1151da177e4SLinus Torvalds #define MAF_NOREPORT 0x08
1161da177e4SLinus Torvalds #define MAF_GSQUERY 0x10
1171da177e4SLinus Torvalds
118fd2c3ef7SEric Dumazet struct ifmcaddr6 {
1191da177e4SLinus Torvalds struct in6_addr mca_addr;
1201da177e4SLinus Torvalds struct inet6_dev *idev;
12188e2ca30STaehee Yoo struct ifmcaddr6 __rcu *next;
1224b200e39STaehee Yoo struct ip6_sf_list __rcu *mca_sources;
1234b200e39STaehee Yoo struct ip6_sf_list __rcu *mca_tomb;
1241da177e4SLinus Torvalds unsigned int mca_sfmode;
125246f19d1SArnaldo Carvalho de Melo unsigned char mca_crcount;
1261da177e4SLinus Torvalds unsigned long mca_sfcount[2];
1272d9a93b4STaehee Yoo struct delayed_work mca_work;
12895c96174SEric Dumazet unsigned int mca_flags;
1291da177e4SLinus Torvalds int mca_users;
130d3981bc6SReshetova, Elena refcount_t mca_refcnt;
1311da177e4SLinus Torvalds unsigned long mca_cstamp;
1321da177e4SLinus Torvalds unsigned long mca_tstamp;
13388e2ca30STaehee Yoo struct rcu_head rcu;
1341da177e4SLinus Torvalds };
1351da177e4SLinus Torvalds
1361da177e4SLinus Torvalds /* Anycast stuff */
1371da177e4SLinus Torvalds
138fd2c3ef7SEric Dumazet struct ipv6_ac_socklist {
1391da177e4SLinus Torvalds struct in6_addr acl_addr;
1401da177e4SLinus Torvalds int acl_ifindex;
1411da177e4SLinus Torvalds struct ipv6_ac_socklist *acl_next;
1421da177e4SLinus Torvalds };
1431da177e4SLinus Torvalds
144fd2c3ef7SEric Dumazet struct ifacaddr6 {
1451da177e4SLinus Torvalds struct in6_addr aca_addr;
1468d1c802bSDavid Ahern struct fib6_info *aca_rt;
1471da177e4SLinus Torvalds struct ifacaddr6 *aca_next;
1482384d025SJeff Barnhill struct hlist_node aca_addr_lst;
1491da177e4SLinus Torvalds int aca_users;
150affa78bcSReshetova, Elena refcount_t aca_refcnt;
1511da177e4SLinus Torvalds unsigned long aca_cstamp;
1521da177e4SLinus Torvalds unsigned long aca_tstamp;
1532384d025SJeff Barnhill struct rcu_head rcu;
1541da177e4SLinus Torvalds };
1551da177e4SLinus Torvalds
1561da177e4SLinus Torvalds #define IFA_HOST IPV6_ADDR_LOOPBACK
1571da177e4SLinus Torvalds #define IFA_LINK IPV6_ADDR_LINKLOCAL
1581da177e4SLinus Torvalds #define IFA_SITE IPV6_ADDR_SITELOCAL
1591da177e4SLinus Torvalds
1601da177e4SLinus Torvalds struct ipv6_devstat {
1611da177e4SLinus Torvalds struct proc_dir_entry *proc_dir_entry;
162a11d206dSYOSHIFUJI Hideaki DEFINE_SNMP_STAT(struct ipstats_mib, ipv6);
163be281e55SEric Dumazet DEFINE_SNMP_STAT_ATOMIC(struct icmpv6_mib_device, icmpv6dev);
164be281e55SEric Dumazet DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib_device, icmpv6msgdev);
1651da177e4SLinus Torvalds };
1661da177e4SLinus Torvalds
167fd2c3ef7SEric Dumazet struct inet6_dev {
1681da177e4SLinus Torvalds struct net_device *dev;
1698c727003SEric Dumazet netdevice_tracker dev_tracker;
1701da177e4SLinus Torvalds
171502a2ffdSstephen hemminger struct list_head addr_list;
1721da177e4SLinus Torvalds
17388e2ca30STaehee Yoo struct ifmcaddr6 __rcu *mc_list;
17488e2ca30STaehee Yoo struct ifmcaddr6 __rcu *mc_tomb;
17589225d1cSDaniel Borkmann
17689225d1cSDaniel Borkmann unsigned char mc_qrv; /* Query Robustness Variable */
1771da177e4SLinus Torvalds unsigned char mc_gq_running;
1781da177e4SLinus Torvalds unsigned char mc_ifc_count;
179b173ee48SHannes Frederic Sowa unsigned char mc_dad_count;
18089225d1cSDaniel Borkmann
18189225d1cSDaniel Borkmann unsigned long mc_v1_seen; /* Max time we stay in MLDv1 mode */
18289225d1cSDaniel Borkmann unsigned long mc_qi; /* Query Interval */
18389225d1cSDaniel Borkmann unsigned long mc_qri; /* Query Response Interval */
1844e7e5cfeSArnaldo Carvalho de Melo unsigned long mc_maxdelay;
18589225d1cSDaniel Borkmann
1862d9a93b4STaehee Yoo struct delayed_work mc_gq_work; /* general query work */
1872d9a93b4STaehee Yoo struct delayed_work mc_ifc_work; /* interface change work */
1882d9a93b4STaehee Yoo struct delayed_work mc_dad_work; /* dad complete mc work */
189f185de28STaehee Yoo struct delayed_work mc_query_work; /* mld query work */
190f185de28STaehee Yoo struct delayed_work mc_report_work; /* mld report work */
191f185de28STaehee Yoo
192f185de28STaehee Yoo struct sk_buff_head mc_query_queue; /* mld query queue */
193f185de28STaehee Yoo struct sk_buff_head mc_report_queue; /* mld report queue */
194f185de28STaehee Yoo
195f185de28STaehee Yoo spinlock_t mc_query_lock; /* mld query queue lock */
196f185de28STaehee Yoo spinlock_t mc_report_lock; /* mld query report lock */
19763ed8de4STaehee Yoo struct mutex mc_lock; /* mld global lock */
1981da177e4SLinus Torvalds
1991da177e4SLinus Torvalds struct ifacaddr6 *ac_list;
2001da177e4SLinus Torvalds rwlock_t lock;
2011be92460SReshetova, Elena refcount_t refcnt;
2021da177e4SLinus Torvalds __u32 if_flags;
2031da177e4SLinus Torvalds int dead;
2041da177e4SLinus Torvalds
20576506a98SJiri Bohac u32 desync_factor;
206372e6c8fSstephen hemminger struct list_head tempaddr_list;
2071da177e4SLinus Torvalds
208f53adae4SDaniel Borkmann struct in6_addr token;
209f53adae4SDaniel Borkmann
2101da177e4SLinus Torvalds struct neigh_parms *nd_parms;
2111da177e4SLinus Torvalds struct ipv6_devconf cnf;
2121da177e4SLinus Torvalds struct ipv6_devstat stats;
213b7b1bfceSHannes Frederic Sowa
214b7b1bfceSHannes Frederic Sowa struct timer_list rs_timer;
215bd11f074SMaciej Żenczykowski __s32 rs_interval; /* in jiffies */
216b7b1bfceSHannes Frederic Sowa __u8 rs_probes;
217b7b1bfceSHannes Frederic Sowa
2181da177e4SLinus Torvalds unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
2198814c4b5SYOSHIFUJI Hideaki struct rcu_head rcu;
22049b99da2SRocco Yue
22149b99da2SRocco Yue unsigned int ra_mtu;
2221da177e4SLinus Torvalds };
2231da177e4SLinus Torvalds
ipv6_eth_mc_map(const struct in6_addr * addr,char * buf)224b71d1d42SEric Dumazet static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
2251da177e4SLinus Torvalds {
2261da177e4SLinus Torvalds /*
2271da177e4SLinus Torvalds * +-------+-------+-------+-------+-------+-------+
2281da177e4SLinus Torvalds * | 33 | 33 | DST13 | DST14 | DST15 | DST16 |
2291da177e4SLinus Torvalds * +-------+-------+-------+-------+-------+-------+
2301da177e4SLinus Torvalds */
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds buf[0]= 0x33;
2331da177e4SLinus Torvalds buf[1]= 0x33;
2341da177e4SLinus Torvalds
2351da177e4SLinus Torvalds memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32));
2361da177e4SLinus Torvalds }
2371da177e4SLinus Torvalds
ipv6_arcnet_mc_map(const struct in6_addr * addr,char * buf)2381da177e4SLinus Torvalds static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf)
2391da177e4SLinus Torvalds {
2401da177e4SLinus Torvalds buf[0] = 0x00;
2411da177e4SLinus Torvalds }
2421da177e4SLinus Torvalds
ipv6_ib_mc_map(const struct in6_addr * addr,const unsigned char * broadcast,char * buf)243a9e527e3SRolf Manderscheid static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
244a9e527e3SRolf Manderscheid const unsigned char *broadcast, char *buf)
2451da177e4SLinus Torvalds {
246a9e527e3SRolf Manderscheid unsigned char scope = broadcast[5] & 0xF;
247a9e527e3SRolf Manderscheid
2481da177e4SLinus Torvalds buf[0] = 0; /* Reserved */
2491da177e4SLinus Torvalds buf[1] = 0xff; /* Multicast QPN */
2501da177e4SLinus Torvalds buf[2] = 0xff;
2511da177e4SLinus Torvalds buf[3] = 0xff;
2521da177e4SLinus Torvalds buf[4] = 0xff;
253a9e527e3SRolf Manderscheid buf[5] = 0x10 | scope; /* scope from broadcast address */
2541da177e4SLinus Torvalds buf[6] = 0x60; /* IPv6 signature */
2551da177e4SLinus Torvalds buf[7] = 0x1b;
256a9e527e3SRolf Manderscheid buf[8] = broadcast[8]; /* P_Key */
257a9e527e3SRolf Manderscheid buf[9] = broadcast[9];
2581da177e4SLinus Torvalds memcpy(buf + 10, addr->s6_addr + 6, 10);
2591da177e4SLinus Torvalds }
26093ca3bb5STimo Teräs
ipv6_ipgre_mc_map(const struct in6_addr * addr,const unsigned char * broadcast,char * buf)26193ca3bb5STimo Teräs static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
26293ca3bb5STimo Teräs const unsigned char *broadcast, char *buf)
26393ca3bb5STimo Teräs {
26493ca3bb5STimo Teräs if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
26593ca3bb5STimo Teräs memcpy(buf, broadcast, 4);
26693ca3bb5STimo Teräs } else {
26793ca3bb5STimo Teräs /* v4mapped? */
26893ca3bb5STimo Teräs if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
26993ca3bb5STimo Teräs (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
27093ca3bb5STimo Teräs return -EINVAL;
27193ca3bb5STimo Teräs memcpy(buf, &addr->s6_addr32[3], 4);
27293ca3bb5STimo Teräs }
27393ca3bb5STimo Teräs return 0;
27493ca3bb5STimo Teräs }
27593ca3bb5STimo Teräs
2761da177e4SLinus Torvalds #endif
277