aboutsummaryrefslogtreecommitdiff
path: root/include/net/if_inet6.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/if_inet6.h')
-rw-r--r--include/net/if_inet6.h142
1 files changed, 63 insertions, 79 deletions
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index e9d69d19849..b4956a5fcc3 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -30,40 +30,52 @@
#define IF_PREFIX_ONLINK 0x01
#define IF_PREFIX_AUTOCONF 0x02
-#ifdef __KERNEL__
+enum {
+ INET6_IFADDR_STATE_PREDAD,
+ INET6_IFADDR_STATE_DAD,
+ INET6_IFADDR_STATE_POSTDAD,
+ INET6_IFADDR_STATE_ERRDAD,
+ INET6_IFADDR_STATE_UP,
+ INET6_IFADDR_STATE_DEAD,
+};
struct inet6_ifaddr {
struct in6_addr addr;
__u32 prefix_len;
+ /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */
__u32 valid_lft;
__u32 prefered_lft;
atomic_t refcnt;
spinlock_t lock;
+ spinlock_t state_lock;
+
+ int state;
- __u8 probes;
- __u8 flags;
+ __u32 flags;
+ __u8 dad_probes;
__u16 scope;
unsigned long cstamp; /* created timestamp */
unsigned long tstamp; /* updated timestamp */
- struct timer_list timer;
+ struct delayed_work dad_work;
struct inet6_dev *idev;
struct rt6_info *rt;
- struct inet6_ifaddr *lst_next; /* next addr in addr_lst */
- struct inet6_ifaddr *if_next; /* next addr in inet6_dev */
+ struct hlist_node addr_lst;
+ struct list_head if_list;
-#ifdef CONFIG_IPV6_PRIVACY
- struct inet6_ifaddr *tmp_next; /* next addr in tempaddr_lst */
+ struct list_head tmp_list;
struct inet6_ifaddr *ifpub;
int regen_count;
-#endif
- int dead;
+ bool tokenized;
+
+ struct rcu_head rcu;
+ struct in6_addr peer_addr;
};
struct ip6_sf_socklist {
@@ -80,10 +92,11 @@ struct ip6_sf_socklist {
struct ipv6_mc_socklist {
struct in6_addr addr;
int ifindex;
- struct ipv6_mc_socklist *next;
+ struct ipv6_mc_socklist __rcu *next;
rwlock_t sflock;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
struct ip6_sf_socklist *sflist;
+ struct rcu_head rcu;
};
struct ip6_sf_list {
@@ -111,7 +124,7 @@ struct ifmcaddr6 {
unsigned char mca_crcount;
unsigned long mca_sfcount[2];
struct timer_list mca_timer;
- unsigned mca_flags;
+ unsigned int mca_flags;
int mca_users;
atomic_t mca_refcnt;
spinlock_t mca_lock;
@@ -146,25 +159,32 @@ struct ifacaddr6 {
struct ipv6_devstat {
struct proc_dir_entry *proc_dir_entry;
DEFINE_SNMP_STAT(struct ipstats_mib, ipv6);
- DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
- DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg);
+ DEFINE_SNMP_STAT_ATOMIC(struct icmpv6_mib_device, icmpv6dev);
+ DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib_device, icmpv6msgdev);
};
struct inet6_dev {
- struct net_device *dev;
+ struct net_device *dev;
- struct inet6_ifaddr *addr_list;
+ struct list_head addr_list;
struct ifmcaddr6 *mc_list;
struct ifmcaddr6 *mc_tomb;
- rwlock_t mc_lock;
- unsigned char mc_qrv;
+ spinlock_t mc_lock;
+
+ unsigned char mc_qrv; /* Query Robustness Variable */
unsigned char mc_gq_running;
unsigned char mc_ifc_count;
- unsigned long mc_v1_seen;
+ unsigned char mc_dad_count;
+
+ unsigned long mc_v1_seen; /* Max time we stay in MLDv1 mode */
+ unsigned long mc_qi; /* Query Interval */
+ unsigned long mc_qri; /* Query Response Interval */
unsigned long mc_maxdelay;
+
struct timer_list mc_gq_timer; /* general query timer */
struct timer_list mc_ifc_timer; /* interface change timer */
+ struct timer_list mc_dad_timer; /* dad complete mc timer */
struct ifacaddr6 *ac_list;
rwlock_t lock;
@@ -172,21 +192,24 @@ struct inet6_dev {
__u32 if_flags;
int dead;
-#ifdef CONFIG_IPV6_PRIVACY
u8 rndid[8];
struct timer_list regen_timer;
- struct inet6_ifaddr *tempaddr_list;
-#endif
+ struct list_head tempaddr_list;
+
+ struct in6_addr token;
struct neigh_parms *nd_parms;
- struct inet6_dev *next;
struct ipv6_devconf cnf;
struct ipv6_devstat stats;
+
+ struct timer_list rs_timer;
+ __u8 rs_probes;
+
unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
struct rcu_head rcu;
};
-static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
{
/*
* +-------+-------+-------+-------+-------+-------+
@@ -200,60 +223,6 @@ static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32));
}
-static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf)
-{
- /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */
-
- if (((addr->s6_addr[0] == 0xFF) &&
- ((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) &&
- (addr->s6_addr16[1] == 0) &&
- (addr->s6_addr32[1] == 0) &&
- (addr->s6_addr32[2] == 0) &&
- (addr->s6_addr16[6] == 0) &&
- (addr->s6_addr[15] == 1)) ||
- ((addr->s6_addr[0] == 0xFF) &&
- (addr->s6_addr[1] == 0x02) &&
- (addr->s6_addr16[1] == 0) &&
- (addr->s6_addr32[1] == 0) &&
- (addr->s6_addr16[4] == 0) &&
- (addr->s6_addr[10] == 0) &&
- (addr->s6_addr[11] == 1) &&
- (addr->s6_addr[12] == 0xff)))
- {
- buf[0]=0xC0;
- buf[1]=0x00;
- buf[2]=0x01;
- buf[3]=0x00;
- buf[4]=0x00;
- buf[5]=0x00;
- /* All routers FF0x::2 */
- } else if ((addr->s6_addr[0] ==0xff) &&
- ((addr->s6_addr[1] & 0xF0) == 0) &&
- (addr->s6_addr16[1] == 0) &&
- (addr->s6_addr32[1] == 0) &&
- (addr->s6_addr32[2] == 0) &&
- (addr->s6_addr16[6] == 0) &&
- (addr->s6_addr[15] == 2))
- {
- buf[0]=0xC0;
- buf[1]=0x00;
- buf[2]=0x02;
- buf[3]=0x00;
- buf[4]=0x00;
- buf[5]=0x00;
- } else {
- unsigned char i ;
-
- i = addr->s6_addr[15] & 7 ;
- buf[0]=0xC0;
- buf[1]=0x00;
- buf[2]=0x00;
- buf[3]=0x01 << i ;
- buf[4]=0x00;
- buf[5]=0x00;
- }
-}
-
static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf)
{
buf[0] = 0x00;
@@ -276,5 +245,20 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
buf[9] = broadcast[9];
memcpy(buf + 10, addr->s6_addr + 6, 10);
}
-#endif
+
+static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
+ const unsigned char *broadcast, char *buf)
+{
+ if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
+ memcpy(buf, broadcast, 4);
+ } else {
+ /* v4mapped? */
+ if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
+ (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
+ return -EINVAL;
+ memcpy(buf, &addr->s6_addr32[3], 4);
+ }
+ return 0;
+}
+
#endif