#ifndef _NETINET6_IN6_VAR_H_
#define _NETINET6_IN6_VAR_H_
#include <sys/callout.h>
#include <sys/ioccom.h>
struct in6_addrlifetime {
time_t ia6t_expire;
time_t ia6t_preferred;
u_int32_t ia6t_vltime;
u_int32_t ia6t_pltime;
};
struct lltable;
struct nd_kifinfo;
struct in6_ifextra {
struct in6_ifstat *in6_ifstat;
struct icmp6_ifstat *icmp6_ifstat;
struct nd_kifinfo *nd_ifinfo;
struct scope6_id *scope6_id;
struct lltable *lltable;
};
LIST_HEAD(in6_multihead, in6_multi);
struct in6_ifaddr {
struct ifaddr ia_ifa;
#define ia_ifp ia_ifa.ifa_ifp
#define ia_flags ia_ifa.ifa_flags
struct sockaddr_in6 ia_addr;
struct sockaddr_in6 ia_net;
struct sockaddr_in6 ia_dstaddr;
struct sockaddr_in6 ia_prefixmask;
u_int32_t ia_plen;
struct in6_ifaddr *ia_next;
struct in6_multihead _ia6_multiaddrs;
int ia6_flags;
struct in6_addrlifetime ia6_lifetime;
time_t ia6_createtime;
time_t ia6_updatetime;
LIST_HEAD(, in6_multi_mship) ia6_memberships;
#ifdef _KERNEL
struct pslist_entry ia6_pslist_entry;
#endif
};
#ifdef _KERNEL
static __inline void
ia6_acquire(struct in6_ifaddr *ia, struct psref *psref)
{
KASSERT(ia != NULL);
ifa_acquire(&ia->ia_ifa, psref);
}
static __inline void
ia6_release(struct in6_ifaddr *ia, struct psref *psref)
{
if (ia == NULL)
return;
ifa_release(&ia->ia_ifa, psref);
}
#endif
struct in6_addrpolicy {
struct sockaddr_in6 addr;
struct sockaddr_in6 addrmask;
int preced;
int label;
u_quad_t use;
};
struct in6_ifstat {
u_quad_t ifs6_in_receive;
u_quad_t ifs6_in_hdrerr;
u_quad_t ifs6_in_toobig;
u_quad_t ifs6_in_noroute;
u_quad_t ifs6_in_addrerr;
u_quad_t ifs6_in_protounknown;
u_quad_t ifs6_in_truncated;
u_quad_t ifs6_in_discard;
u_quad_t ifs6_in_deliver;
u_quad_t ifs6_out_forward;
u_quad_t ifs6_out_request;
u_quad_t ifs6_out_discard;
u_quad_t ifs6_out_fragok;
u_quad_t ifs6_out_fragfail;
u_quad_t ifs6_out_fragcreat;
u_quad_t ifs6_reass_reqd;
u_quad_t ifs6_reass_ok;
u_quad_t ifs6_reass_fail;
u_quad_t ifs6_in_mcast;
u_quad_t ifs6_out_mcast;
};
struct icmp6_ifstat {
u_quad_t ifs6_in_msg;
u_quad_t ifs6_in_error;
u_quad_t ifs6_in_dstunreach;
u_quad_t ifs6_in_adminprohib;
u_quad_t ifs6_in_timeexceed;
u_quad_t ifs6_in_paramprob;
u_quad_t ifs6_in_pkttoobig;
u_quad_t ifs6_in_echo;
u_quad_t ifs6_in_echoreply;
u_quad_t ifs6_in_routersolicit;
u_quad_t ifs6_in_routeradvert;
u_quad_t ifs6_in_neighborsolicit;
u_quad_t ifs6_in_neighboradvert;
u_quad_t ifs6_in_redirect;
u_quad_t ifs6_in_mldquery;
u_quad_t ifs6_in_mldreport;
u_quad_t ifs6_in_mlddone;
u_quad_t ifs6_out_msg;
u_quad_t ifs6_out_error;
u_quad_t ifs6_out_dstunreach;
u_quad_t ifs6_out_adminprohib;
u_quad_t ifs6_out_timeexceed;
u_quad_t ifs6_out_paramprob;
u_quad_t ifs6_out_pkttoobig;
u_quad_t ifs6_out_echo;
u_quad_t ifs6_out_echoreply;
u_quad_t ifs6_out_routersolicit;
u_quad_t ifs6_out_routeradvert;
u_quad_t ifs6_out_neighborsolicit;
u_quad_t ifs6_out_neighboradvert;
u_quad_t ifs6_out_redirect;
u_quad_t ifs6_out_mldquery;
u_quad_t ifs6_out_mldreport;
u_quad_t ifs6_out_mlddone;
};
struct in6_ifreq {
char ifr_name[IFNAMSIZ];
union {
struct sockaddr_in6 ifru_addr;
struct sockaddr_in6 ifru_dstaddr;
short ifru_flags;
int ifru_flags6;
int ifru_metric;
void * ifru_data;
struct in6_addrlifetime ifru_lifetime;
struct in6_ifstat ifru_stat;
struct icmp6_ifstat ifru_icmp6stat;
} ifr_ifru;
};
struct in6_aliasreq {
char ifra_name[IFNAMSIZ];
struct sockaddr_in6 ifra_addr;
struct sockaddr_in6 ifra_dstaddr;
struct sockaddr_in6 ifra_prefixmask;
int ifra_flags;
struct in6_addrlifetime ifra_lifetime;
};
#define IA6_IN6(ia) (&((ia)->ia_addr.sin6_addr))
#define IA6_DSTIN6(ia) (&((ia)->ia_dstaddr.sin6_addr))
#define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr))
#define IA6_SIN6(ia) (&((ia)->ia_addr))
#define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr))
#define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr)
#define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr)
#ifdef _KERNEL
#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
(((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
(((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
(((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
#endif
#define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq)
#define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq)
#ifdef _KERNEL
#define SIOCSIFDSTADDR_IN6 _IOW('i', 14, struct in6_ifreq)
#define SIOCSIFNETMASK_IN6 _IOW('i', 22, struct in6_ifreq)
#endif
#define SIOCGIFDSTADDR_IN6 _IOWR('i', 34, struct in6_ifreq)
#define SIOCGIFNETMASK_IN6 _IOWR('i', 37, struct in6_ifreq)
#define SIOCDIFADDR_IN6 _IOW('i', 25, struct in6_ifreq)
#define SIOCGIFPSRCADDR_IN6 _IOWR('i', 71, struct in6_ifreq)
#define SIOCGIFPDSTADDR_IN6 _IOWR('i', 72, struct in6_ifreq)
#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
#if 0
#define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq)
#endif
#define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq)
#define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq)
#define SIOCGIFALIFETIME_IN6 _IOWR('i', 106, struct in6_ifreq)
#define SIOCAIFADDR_IN6 _IOW('i', 107, struct in6_aliasreq)
#define SIOCSIFPHYADDR_IN6 _IOW('i', 110, struct in6_aliasreq)
#define SIOCGIFINFO_IN6 _IOWR('i', 113, struct in6_ndireq)
#define SIOCSIFINFO_IN6 _IOWR('i', 114, struct in6_ndireq)
#define SIOCSIFINFO_FLAGS _IOWR('i', 115, struct in6_ndireq)
#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \
struct sioc_sg_req6)
#define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \
struct sioc_mif_req6)
#define SIOCAADDRCTL_POLICY _IOW('u', 108, struct in6_addrpolicy)
#define SIOCDADDRCTL_POLICY _IOW('u', 109, struct in6_addrpolicy)
#define IN6_IFF_ANYCAST 0x01
#define IN6_IFF_TENTATIVE 0x02
#define IN6_IFF_DUPLICATED 0x04
#define IN6_IFF_DETACHED 0x08
#define IN6_IFF_DEPRECATED 0x10
#define IN6_IFF_NODAD 0x20
#define IN6_IFF_AUTOCONF 0x40
#define IN6_IFF_TEMPORARY 0x80
#define IN6_IFFBITS \
"\020\1ANYCAST\2TENTATIVE\3DUPLICATED\4DETACHED\5DEPRECATED\6NODAD" \
"\7AUTOCONF\10TEMPORARY"
#define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED)
#ifdef _KERNEL
#define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b))
#define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b))
#endif
#ifdef _KERNEL
#include <sys/mutex.h>
#include <sys/pserialize.h>
#include <net/pktqueue.h>
extern pktqueue_t *ip6_pktq;
MALLOC_DECLARE(M_IP6OPT);
extern struct pslist_head in6_ifaddr_list;
extern kmutex_t in6_ifaddr_lock;
#define IN6_ADDRLIST_ENTRY_INIT(__ia) \
PSLIST_ENTRY_INIT((__ia), ia6_pslist_entry)
#define IN6_ADDRLIST_ENTRY_DESTROY(__ia) \
PSLIST_ENTRY_DESTROY((__ia), ia6_pslist_entry)
#define IN6_ADDRLIST_READER_EMPTY() \
(PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \
ia6_pslist_entry) == NULL)
#define IN6_ADDRLIST_READER_FIRST() \
PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \
ia6_pslist_entry)
#define IN6_ADDRLIST_READER_NEXT(__ia) \
PSLIST_READER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry)
#define IN6_ADDRLIST_READER_FOREACH(__ia) \
PSLIST_READER_FOREACH((__ia), &in6_ifaddr_list, \
struct in6_ifaddr, ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_INSERT_HEAD(__ia) \
PSLIST_WRITER_INSERT_HEAD(&in6_ifaddr_list, (__ia), ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_REMOVE(__ia) \
PSLIST_WRITER_REMOVE((__ia), ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_FOREACH(__ia) \
PSLIST_WRITER_FOREACH((__ia), &in6_ifaddr_list, struct in6_ifaddr, \
ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_FIRST() \
PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \
ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_NEXT(__ia) \
PSLIST_WRITER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \
PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia6_pslist_entry)
#define IN6_ADDRLIST_WRITER_EMPTY() \
(PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \
ia6_pslist_entry) == NULL)
#define IN6_ADDRLIST_WRITER_INSERT_TAIL(__new) \
do { \
if (IN6_ADDRLIST_WRITER_EMPTY()) { \
IN6_ADDRLIST_WRITER_INSERT_HEAD((__new)); \
} else { \
struct in6_ifaddr *__ia; \
IN6_ADDRLIST_WRITER_FOREACH(__ia) { \
if (IN6_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \
IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia,\
(__new)); \
break; \
} \
} \
} \
} while (0)
#define in6_ifstat_inc(ifp, tag) \
do { \
if (ifp) \
((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \
} while ( 0)
extern const struct in6_addr zeroin6_addr;
extern const u_char inet6ctlerrmap[];
extern bool in6_present;
#endif
struct in6_multi_mship {
struct in6_multi *i6mm_maddr;
LIST_ENTRY(in6_multi_mship) i6mm_chain;
};
struct in6_multi {
LIST_ENTRY(in6_multi) in6m_entry;
struct in6_addr in6m_addr;
struct ifnet *in6m_ifp;
struct in6_ifaddr *_in6m_ia;
u_int in6m_refcount;
u_int in6m_state;
int in6m_timer;
struct timeval in6m_timer_expire;
callout_t in6m_timer_ch;
};
#define IN6M_TIMER_UNDEF -1
#ifdef _KERNEL
#define IN6_IFAUPDATE_DADDELAY 0x1
#if 0
static __inline struct in6_multi_mship *
in6_lookup_mship(struct in6_addr *addr, struct ifnet *ifp,
struct ip6_moptions *imop)
{
struct in6_multi_mship *imm;
LIST_FOREACH(imm, &imop->im6o_memberships, i6mm_chain) {
if (imm->i6mm_maddr->in6m_ifp != ifp)
continue;
if (IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
addr))
break;
}
return imm;
}
#define IN6_LOOKUP_MSHIP(__addr, __ifp, __imop, __imm) \
\
\
\
\
do { \
(__imm) = in6_lookup_mship(&(__addr), (__ifp), (__imop)); \
} while ( 0)
#endif
void in6_init(void);
void in6_multi_lock(int);
void in6_multi_unlock(void);
bool in6_multi_locked(int);
struct in6_multi *
in6_lookup_multi(const struct in6_addr *, const struct ifnet *);
bool in6_multi_group(const struct in6_addr *, const struct ifnet *);
void in6_purge_multi(struct ifnet *);
struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *,
int *, int);
void in6_delmulti(struct in6_multi *);
void in6_delmulti_locked(struct in6_multi *);
void in6_lookup_and_delete_multi(const struct in6_addr *,
const struct ifnet *);
struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *,
int *, int);
int in6_leavegroup(struct in6_multi_mship *);
int in6_mask2len(struct in6_addr *, u_char *);
int in6_control(struct socket *, u_long, void *, struct ifnet *);
int in6_update_ifa(struct ifnet *, struct in6_aliasreq *, int);
void in6_purgeaddr(struct ifaddr *);
void in6_purgeif(struct ifnet *);
void *in6_domifattach(struct ifnet *);
void in6_domifdetach(struct ifnet *, void *);
void in6_ifremlocal(struct ifaddr *);
void in6_ifaddlocal(struct ifaddr *);
struct in6_ifaddr *
in6ifa_ifpforlinklocal(const struct ifnet *, int);
struct in6_ifaddr *
in6ifa_ifpforlinklocal_psref(const struct ifnet *, int, struct psref *);
struct in6_ifaddr *
in6ifa_ifpwithaddr(const struct ifnet *, const struct in6_addr *);
struct in6_ifaddr *
in6ifa_ifpwithaddr_psref(const struct ifnet *, const struct in6_addr *,
struct psref *);
struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_t);
struct ifaddr *
in6ifa_first_lladdr(const struct ifnet *);
struct ifaddr *
in6ifa_first_lladdr_psref(const struct ifnet *, struct psref *);
int in6_matchlen(struct in6_addr *, struct in6_addr *);
void in6_prefixlen2mask(struct in6_addr *, int);
void in6_purge_mcast_references(struct in6_multi *);
int ip6flow_fastforward(struct mbuf **);
int in6_src_ioctl(u_long, void *);
int in6_is_addr_deprecated(struct sockaddr_in6 *);
struct in6pcb;
#define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
void in6_sysctl_multicast_setup(struct sysctllog **);
#endif
#endif