mirror of https://github.com/F-Stack/f-stack.git
IPv6: ifconfig and route tools support ipv6. netstat TBC.
This commit is contained in:
parent
d7140ab746
commit
143d7be716
|
@ -8,6 +8,11 @@ TARGET=libffcompat.a
|
|||
|
||||
#DEBUG=-O0 -gdwarf-2 -g3
|
||||
|
||||
include ${TOPDIR}/tools/opts.mk
|
||||
ifneq (${MK_INET6_SUPPORT},"no")
|
||||
CFLAGS+= -DINET6
|
||||
endif
|
||||
|
||||
DPDK_CFLAGS= -g -Wall -Werror -include ${FF_DPDK}/include/rte_config.h
|
||||
DPDK_CFLAGS+= -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3
|
||||
DPDK_CFLAGS+= -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2
|
||||
|
|
|
@ -81,6 +81,14 @@
|
|||
#define ishexnumber(x) isxdigit(x)
|
||||
#endif
|
||||
|
||||
#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */
|
||||
#ifdef INET6
|
||||
#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */
|
||||
|
||||
#define AF_INET6_LINUX 10
|
||||
#define PF_INET6_LINUX AF_INET6
|
||||
#endif
|
||||
|
||||
void *reallocf(void *ptr, size_t size);
|
||||
|
||||
int feature_present(const char *feature);
|
||||
|
|
|
@ -0,0 +1,831 @@
|
|||
/*-
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $KAME: in6_var.h,v 1.56 2001/03/29 05:34:31 itojun Exp $
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1985, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_var.h 8.1 (Berkeley) 6/10/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IN6_VAR_H_
|
||||
#define _NETINET6_IN6_VAR_H_
|
||||
|
||||
#include <sys/tree.h>
|
||||
#include <sys/counter.h>
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/fnv_hash.h>
|
||||
#include <sys/libkern.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interface address, Internet version. One of these structures
|
||||
* is allocated for each interface with an Internet address.
|
||||
* The ifaddr structure contains the protocol-independent part
|
||||
* of the structure and is assumed to be first.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pltime/vltime are just for future reference (required to implements 2
|
||||
* hour rule for hosts). they should never be modified by nd6_timeout or
|
||||
* anywhere else.
|
||||
* userland -> kernel: accept pltime/vltime
|
||||
* kernel -> userland: throw up everything
|
||||
* in kernel: modify preferred/expire only
|
||||
*/
|
||||
struct in6_addrlifetime {
|
||||
time_t ia6t_expire; /* valid lifetime expiration time */
|
||||
time_t ia6t_preferred; /* preferred lifetime expiration time */
|
||||
u_int32_t ia6t_vltime; /* valid lifetime */
|
||||
u_int32_t ia6t_pltime; /* prefix lifetime */
|
||||
};
|
||||
|
||||
struct nd_ifinfo;
|
||||
struct scope6_id;
|
||||
struct lltable;
|
||||
struct mld_ifsoftc;
|
||||
|
||||
struct in6_ifextra {
|
||||
counter_u64_t *in6_ifstat;
|
||||
counter_u64_t *icmp6_ifstat;
|
||||
struct nd_ifinfo *nd_ifinfo;
|
||||
struct scope6_id *scope6_id;
|
||||
struct lltable *lltable;
|
||||
struct mld_ifsoftc *mld_ifinfo;
|
||||
};
|
||||
|
||||
#define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct in6_ifaddr {
|
||||
struct ifaddr ia_ifa; /* protocol-independent info */
|
||||
#define ia_ifp ia_ifa.ifa_ifp
|
||||
#define ia_flags ia_ifa.ifa_flags
|
||||
struct sockaddr_in6 ia_addr; /* interface address */
|
||||
struct sockaddr_in6 ia_net; /* network number of interface */
|
||||
struct sockaddr_in6 ia_dstaddr; /* space for destination addr */
|
||||
struct sockaddr_in6 ia_prefixmask; /* prefix mask */
|
||||
u_int32_t ia_plen; /* prefix length */
|
||||
TAILQ_ENTRY(in6_ifaddr) ia_link; /* list of IPv6 addresses */
|
||||
int ia6_flags;
|
||||
|
||||
struct in6_addrlifetime ia6_lifetime;
|
||||
time_t ia6_createtime; /* the creation time of this address, which is
|
||||
* currently used for temporary addresses only.
|
||||
*/
|
||||
time_t ia6_updatetime;
|
||||
|
||||
/* back pointer to the ND prefix (for autoconfigured addresses only) */
|
||||
struct nd_prefix *ia6_ndpr;
|
||||
|
||||
/* multicast addresses joined from the kernel */
|
||||
LIST_HEAD(, in6_multi_mship) ia6_memberships;
|
||||
/* entry in bucket of inet6 addresses */
|
||||
LIST_ENTRY(in6_ifaddr) ia6_hash;
|
||||
};
|
||||
|
||||
/* List of in6_ifaddr's. */
|
||||
TAILQ_HEAD(in6_ifaddrhead, in6_ifaddr);
|
||||
LIST_HEAD(in6_ifaddrlisthead, in6_ifaddr);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* control structure to manage address selection policy */
|
||||
struct in6_addrpolicy {
|
||||
struct sockaddr_in6 addr; /* prefix address */
|
||||
struct sockaddr_in6 addrmask; /* prefix mask */
|
||||
int preced; /* precedence */
|
||||
int label; /* matching label */
|
||||
u_quad_t use; /* statistics */
|
||||
};
|
||||
|
||||
/*
|
||||
* IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12).
|
||||
*/
|
||||
struct in6_ifstat {
|
||||
uint64_t ifs6_in_receive; /* # of total input datagram */
|
||||
uint64_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
|
||||
uint64_t ifs6_in_toobig; /* # of datagrams exceeded MTU */
|
||||
uint64_t ifs6_in_noroute; /* # of datagrams with no route */
|
||||
uint64_t ifs6_in_addrerr; /* # of datagrams with invalid dst */
|
||||
uint64_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
|
||||
/* NOTE: increment on final dst if */
|
||||
uint64_t ifs6_in_truncated; /* # of truncated datagrams */
|
||||
uint64_t ifs6_in_discard; /* # of discarded datagrams */
|
||||
/* NOTE: fragment timeout is not here */
|
||||
uint64_t ifs6_in_deliver; /* # of datagrams delivered to ULP */
|
||||
/* NOTE: increment on final dst if */
|
||||
uint64_t ifs6_out_forward; /* # of datagrams forwarded */
|
||||
/* NOTE: increment on outgoing if */
|
||||
uint64_t ifs6_out_request; /* # of outgoing datagrams from ULP */
|
||||
/* NOTE: does not include forwrads */
|
||||
uint64_t ifs6_out_discard; /* # of discarded datagrams */
|
||||
uint64_t ifs6_out_fragok; /* # of datagrams fragmented */
|
||||
uint64_t ifs6_out_fragfail; /* # of datagrams failed on fragment */
|
||||
uint64_t ifs6_out_fragcreat; /* # of fragment datagrams */
|
||||
/* NOTE: this is # after fragment */
|
||||
uint64_t ifs6_reass_reqd; /* # of incoming fragmented packets */
|
||||
/* NOTE: increment on final dst if */
|
||||
uint64_t ifs6_reass_ok; /* # of reassembled packets */
|
||||
/* NOTE: this is # after reass */
|
||||
/* NOTE: increment on final dst if */
|
||||
uint64_t ifs6_reass_fail; /* # of reass failures */
|
||||
/* NOTE: may not be packet count */
|
||||
/* NOTE: increment on final dst if */
|
||||
uint64_t ifs6_in_mcast; /* # of inbound multicast datagrams */
|
||||
uint64_t ifs6_out_mcast; /* # of outbound multicast datagrams */
|
||||
};
|
||||
|
||||
/*
|
||||
* ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry.
|
||||
* XXX: I'm not sure if this file is the right place for this structure...
|
||||
*/
|
||||
struct icmp6_ifstat {
|
||||
/*
|
||||
* Input statistics
|
||||
*/
|
||||
/* ipv6IfIcmpInMsgs, total # of input messages */
|
||||
uint64_t ifs6_in_msg;
|
||||
/* ipv6IfIcmpInErrors, # of input error messages */
|
||||
uint64_t ifs6_in_error;
|
||||
/* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
|
||||
uint64_t ifs6_in_dstunreach;
|
||||
/* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */
|
||||
uint64_t ifs6_in_adminprohib;
|
||||
/* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
|
||||
uint64_t ifs6_in_timeexceed;
|
||||
/* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
|
||||
uint64_t ifs6_in_paramprob;
|
||||
/* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
|
||||
uint64_t ifs6_in_pkttoobig;
|
||||
/* ipv6IfIcmpInEchos, # of input echo requests */
|
||||
uint64_t ifs6_in_echo;
|
||||
/* ipv6IfIcmpInEchoReplies, # of input echo replies */
|
||||
uint64_t ifs6_in_echoreply;
|
||||
/* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
|
||||
uint64_t ifs6_in_routersolicit;
|
||||
/* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
|
||||
uint64_t ifs6_in_routeradvert;
|
||||
/* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
|
||||
uint64_t ifs6_in_neighborsolicit;
|
||||
/* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */
|
||||
uint64_t ifs6_in_neighboradvert;
|
||||
/* ipv6IfIcmpInRedirects, # of input redirects */
|
||||
uint64_t ifs6_in_redirect;
|
||||
/* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
|
||||
uint64_t ifs6_in_mldquery;
|
||||
/* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
|
||||
uint64_t ifs6_in_mldreport;
|
||||
/* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
|
||||
uint64_t ifs6_in_mlddone;
|
||||
|
||||
/*
|
||||
* Output statistics. We should solve unresolved routing problem...
|
||||
*/
|
||||
/* ipv6IfIcmpOutMsgs, total # of output messages */
|
||||
uint64_t ifs6_out_msg;
|
||||
/* ipv6IfIcmpOutErrors, # of output error messages */
|
||||
uint64_t ifs6_out_error;
|
||||
/* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
|
||||
uint64_t ifs6_out_dstunreach;
|
||||
/* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */
|
||||
uint64_t ifs6_out_adminprohib;
|
||||
/* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
|
||||
uint64_t ifs6_out_timeexceed;
|
||||
/* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
|
||||
uint64_t ifs6_out_paramprob;
|
||||
/* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
|
||||
uint64_t ifs6_out_pkttoobig;
|
||||
/* ipv6IfIcmpOutEchos, # of output echo requests */
|
||||
uint64_t ifs6_out_echo;
|
||||
/* ipv6IfIcmpOutEchoReplies, # of output echo replies */
|
||||
uint64_t ifs6_out_echoreply;
|
||||
/* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
|
||||
uint64_t ifs6_out_routersolicit;
|
||||
/* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */
|
||||
uint64_t ifs6_out_routeradvert;
|
||||
/* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
|
||||
uint64_t ifs6_out_neighborsolicit;
|
||||
/* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */
|
||||
uint64_t ifs6_out_neighboradvert;
|
||||
/* ipv6IfIcmpOutRedirects, # of output redirects */
|
||||
uint64_t ifs6_out_redirect;
|
||||
/* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
|
||||
uint64_t ifs6_out_mldquery;
|
||||
/* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
|
||||
uint64_t ifs6_out_mldreport;
|
||||
/* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
|
||||
uint64_t ifs6_out_mlddone;
|
||||
};
|
||||
|
||||
struct in6_ifreq {
|
||||
char ifr_name[IFNAMSIZ];
|
||||
union {
|
||||
struct sockaddr_in6 ifru_addr;
|
||||
struct sockaddr_in6 ifru_dstaddr;
|
||||
int ifru_flags;
|
||||
int ifru_flags6;
|
||||
int ifru_metric;
|
||||
caddr_t ifru_data;
|
||||
struct in6_addrlifetime ifru_lifetime;
|
||||
struct in6_ifstat ifru_stat;
|
||||
struct icmp6_ifstat ifru_icmp6stat;
|
||||
u_int32_t ifru_scope_id[16];
|
||||
} 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;
|
||||
int ifra_vhid;
|
||||
};
|
||||
|
||||
/* pre-10.x compat */
|
||||
struct oin6_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;
|
||||
};
|
||||
|
||||
/* prefix type macro */
|
||||
#define IN6_PREFIX_ND 1
|
||||
#define IN6_PREFIX_RR 2
|
||||
|
||||
/*
|
||||
* prefix related flags passed between kernel(NDP related part) and
|
||||
* user land command(ifconfig) and daemon(rtadvd).
|
||||
*/
|
||||
struct in6_prflags {
|
||||
struct prf_ra {
|
||||
u_char onlink : 1;
|
||||
u_char autonomous : 1;
|
||||
u_char reserved : 6;
|
||||
} prf_ra;
|
||||
u_char prf_reserved1;
|
||||
u_short prf_reserved2;
|
||||
/* want to put this on 4byte offset */
|
||||
struct prf_rr {
|
||||
u_char decrvalid : 1;
|
||||
u_char decrprefd : 1;
|
||||
u_char reserved : 6;
|
||||
} prf_rr;
|
||||
u_char prf_reserved3;
|
||||
u_short prf_reserved4;
|
||||
};
|
||||
|
||||
struct in6_prefixreq {
|
||||
char ipr_name[IFNAMSIZ];
|
||||
u_char ipr_origin;
|
||||
u_char ipr_plen;
|
||||
u_int32_t ipr_vltime;
|
||||
u_int32_t ipr_pltime;
|
||||
struct in6_prflags ipr_flags;
|
||||
struct sockaddr_in6 ipr_prefix;
|
||||
};
|
||||
|
||||
#define PR_ORIG_RA 0
|
||||
#define PR_ORIG_RR 1
|
||||
#define PR_ORIG_STATIC 2
|
||||
#define PR_ORIG_KERNEL 3
|
||||
|
||||
#define ipr_raf_onlink ipr_flags.prf_ra.onlink
|
||||
#define ipr_raf_auto ipr_flags.prf_ra.autonomous
|
||||
|
||||
#define ipr_statef_onlink ipr_flags.prf_state.onlink
|
||||
|
||||
#define ipr_rrf_decrvalid ipr_flags.prf_rr.decrvalid
|
||||
#define ipr_rrf_decrprefd ipr_flags.prf_rr.decrprefd
|
||||
|
||||
struct in6_rrenumreq {
|
||||
char irr_name[IFNAMSIZ];
|
||||
u_char irr_origin;
|
||||
u_char irr_m_len; /* match len for matchprefix */
|
||||
u_char irr_m_minlen; /* minlen for matching prefix */
|
||||
u_char irr_m_maxlen; /* maxlen for matching prefix */
|
||||
u_char irr_u_uselen; /* uselen for adding prefix */
|
||||
u_char irr_u_keeplen; /* keeplen from matching prefix */
|
||||
struct irr_raflagmask {
|
||||
u_char onlink : 1;
|
||||
u_char autonomous : 1;
|
||||
u_char reserved : 6;
|
||||
} irr_raflagmask;
|
||||
u_int32_t irr_vltime;
|
||||
u_int32_t irr_pltime;
|
||||
struct in6_prflags irr_flags;
|
||||
struct sockaddr_in6 irr_matchprefix;
|
||||
struct sockaddr_in6 irr_useprefix;
|
||||
};
|
||||
|
||||
#define irr_raf_mask_onlink irr_raflagmask.onlink
|
||||
#define irr_raf_mask_auto irr_raflagmask.autonomous
|
||||
#define irr_raf_mask_reserved irr_raflagmask.reserved
|
||||
|
||||
#define irr_raf_onlink irr_flags.prf_ra.onlink
|
||||
#define irr_raf_auto irr_flags.prf_ra.autonomous
|
||||
|
||||
#define irr_statef_onlink irr_flags.prf_state.onlink
|
||||
|
||||
#define irr_rrf irr_flags.prf_rr
|
||||
#define irr_rrf_decrvalid irr_flags.prf_rr.decrvalid
|
||||
#define irr_rrf_decrprefd irr_flags.prf_rr.decrprefd
|
||||
|
||||
/*
|
||||
* Given a pointer to an in6_ifaddr (ifaddr),
|
||||
* return a pointer to the addr as a sockaddr_in6
|
||||
*/
|
||||
#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)
|
||||
|
||||
#define IFPR_IN6(x) (&((struct sockaddr_in6 *)((x)->ifpr_prefix))->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 )
|
||||
#define IN6_MASK_ADDR(a, m) do { \
|
||||
(a)->s6_addr32[0] &= (m)->s6_addr32[0]; \
|
||||
(a)->s6_addr32[1] &= (m)->s6_addr32[1]; \
|
||||
(a)->s6_addr32[2] &= (m)->s6_addr32[2]; \
|
||||
(a)->s6_addr32[3] &= (m)->s6_addr32[3]; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq)
|
||||
#define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq)
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* SIOCSxxx ioctls should be unused (see comments in in6.c), but
|
||||
* we do not shift numbers for binary compatibility.
|
||||
*/
|
||||
#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 OSIOCAIFADDR_IN6 _IOW('i', 26, struct oin6_aliasreq)
|
||||
#define SIOCAIFADDR_IN6 _IOW('i', 27, struct in6_aliasreq)
|
||||
|
||||
#define SIOCSIFPHYADDR_IN6 _IOW('i', 70, struct in6_aliasreq)
|
||||
#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)
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
|
||||
#endif
|
||||
#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq)
|
||||
#define SIOCSIFINFO_IN6 _IOWR('i', 109, struct in6_ndireq)
|
||||
#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
|
||||
#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
|
||||
#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
|
||||
#define SIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq)
|
||||
|
||||
#define SIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
|
||||
#define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq)
|
||||
#define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq)
|
||||
|
||||
#define SIOCSDEFIFACE_IN6 _IOWR('i', 85, struct in6_ndifreq)
|
||||
#define SIOCGDEFIFACE_IN6 _IOWR('i', 86, struct in6_ndifreq)
|
||||
|
||||
#define SIOCSIFINFO_FLAGS _IOWR('i', 87, struct in6_ndireq) /* XXX */
|
||||
|
||||
#define SIOCSSCOPE6 _IOW('i', 88, struct in6_ifreq)
|
||||
#define SIOCGSCOPE6 _IOWR('i', 89, struct in6_ifreq)
|
||||
#define SIOCGSCOPE6DEF _IOWR('i', 90, struct in6_ifreq)
|
||||
|
||||
#define SIOCSIFPREFIX_IN6 _IOW('i', 100, struct in6_prefixreq) /* set */
|
||||
#define SIOCGIFPREFIX_IN6 _IOWR('i', 101, struct in6_prefixreq) /* get */
|
||||
#define SIOCDIFPREFIX_IN6 _IOW('i', 102, struct in6_prefixreq) /* del */
|
||||
#define SIOCAIFPREFIX_IN6 _IOW('i', 103, struct in6_rrenumreq) /* add */
|
||||
#define SIOCCIFPREFIX_IN6 _IOW('i', 104, \
|
||||
struct in6_rrenumreq) /* change */
|
||||
#define SIOCSGIFPREFIX_IN6 _IOW('i', 105, \
|
||||
struct in6_rrenumreq) /* set global */
|
||||
|
||||
#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \
|
||||
struct sioc_sg_req6) /* get s,g pkt cnt */
|
||||
#define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \
|
||||
struct sioc_mif_req6) /* get pkt cnt per if */
|
||||
|
||||
#define SIOCAADDRCTL_POLICY _IOW('u', 108, struct in6_addrpolicy)
|
||||
#define SIOCDADDRCTL_POLICY _IOW('u', 109, struct in6_addrpolicy)
|
||||
|
||||
#define IN6_IFF_ANYCAST 0x01 /* anycast address */
|
||||
#define IN6_IFF_TENTATIVE 0x02 /* tentative address */
|
||||
#define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */
|
||||
#define IN6_IFF_DETACHED 0x08 /* may be detached from the link */
|
||||
#define IN6_IFF_DEPRECATED 0x10 /* deprecated address */
|
||||
#define IN6_IFF_NODAD 0x20 /* don't perform DAD on this address
|
||||
* (obsolete)
|
||||
*/
|
||||
#define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */
|
||||
#define IN6_IFF_TEMPORARY 0x80 /* temporary (anonymous) address. */
|
||||
#define IN6_IFF_PREFER_SOURCE 0x0100 /* preferred address for SAS */
|
||||
|
||||
/* do not input/output */
|
||||
#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
|
||||
VNET_DECLARE(struct in6_ifaddrhead, in6_ifaddrhead);
|
||||
VNET_DECLARE(struct in6_ifaddrlisthead *, in6_ifaddrhashtbl);
|
||||
VNET_DECLARE(u_long, in6_ifaddrhmask);
|
||||
#define V_in6_ifaddrhead VNET(in6_ifaddrhead)
|
||||
#define V_in6_ifaddrhashtbl VNET(in6_ifaddrhashtbl)
|
||||
#define V_in6_ifaddrhmask VNET(in6_ifaddrhmask)
|
||||
|
||||
#define IN6ADDR_NHASH_LOG2 8
|
||||
#define IN6ADDR_NHASH (1 << IN6ADDR_NHASH_LOG2)
|
||||
#define IN6ADDR_HASHVAL(x) (in6_addrhash(x))
|
||||
#define IN6ADDR_HASH(x) \
|
||||
(&V_in6_ifaddrhashtbl[IN6ADDR_HASHVAL(x) & V_in6_ifaddrhmask])
|
||||
|
||||
static __inline uint32_t
|
||||
in6_addrhash(const struct in6_addr *in6)
|
||||
{
|
||||
uint32_t x;
|
||||
|
||||
x = in6->s6_addr32[0] ^ in6->s6_addr32[1] ^ in6->s6_addr32[2] ^
|
||||
in6->s6_addr32[3];
|
||||
return (fnv_32_buf(&x, sizeof(x), FNV1_32_INIT));
|
||||
}
|
||||
|
||||
extern struct rmlock in6_ifaddr_lock;
|
||||
#define IN6_IFADDR_LOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_LOCKED)
|
||||
#define IN6_IFADDR_RLOCK(t) rm_rlock(&in6_ifaddr_lock, (t))
|
||||
#define IN6_IFADDR_RLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_RLOCKED)
|
||||
#define IN6_IFADDR_RUNLOCK(t) rm_runlock(&in6_ifaddr_lock, (t))
|
||||
#define IN6_IFADDR_WLOCK() rm_wlock(&in6_ifaddr_lock)
|
||||
#define IN6_IFADDR_WLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_WLOCKED)
|
||||
#define IN6_IFADDR_WUNLOCK() rm_wunlock(&in6_ifaddr_lock)
|
||||
|
||||
#define in6_ifstat_inc(ifp, tag) \
|
||||
do { \
|
||||
if (ifp) \
|
||||
counter_u64_add(((struct in6_ifextra *) \
|
||||
((ifp)->if_afdata[AF_INET6]))->in6_ifstat[ \
|
||||
offsetof(struct in6_ifstat, tag) / sizeof(uint64_t)], 1);\
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
extern u_char inet6ctlerrmap[];
|
||||
VNET_DECLARE(unsigned long, in6_maxmtu);
|
||||
#define V_in6_maxmtu VNET(in6_maxmtu)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* IPv6 multicast MLD-layer source entry.
|
||||
*/
|
||||
struct ip6_msource {
|
||||
RB_ENTRY(ip6_msource) im6s_link; /* RB tree links */
|
||||
struct in6_addr im6s_addr;
|
||||
struct im6s_st {
|
||||
uint16_t ex; /* # of exclusive members */
|
||||
uint16_t in; /* # of inclusive members */
|
||||
} im6s_st[2]; /* state at t0, t1 */
|
||||
uint8_t im6s_stp; /* pending query */
|
||||
};
|
||||
RB_HEAD(ip6_msource_tree, ip6_msource);
|
||||
|
||||
/*
|
||||
* IPv6 multicast PCB-layer source entry.
|
||||
*
|
||||
* NOTE: overlapping use of struct ip6_msource fields at start.
|
||||
*/
|
||||
struct in6_msource {
|
||||
RB_ENTRY(ip6_msource) im6s_link; /* Common field */
|
||||
struct in6_addr im6s_addr; /* Common field */
|
||||
uint8_t im6sl_st[2]; /* state before/at commit */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* IPv6 source tree comparison function.
|
||||
*
|
||||
* An ordered predicate is necessary; bcmp() is not documented to return
|
||||
* an indication of order, memcmp() is, and is an ISO C99 requirement.
|
||||
*/
|
||||
static __inline int
|
||||
ip6_msource_cmp(const struct ip6_msource *a, const struct ip6_msource *b)
|
||||
{
|
||||
|
||||
return (memcmp(&a->im6s_addr, &b->im6s_addr, sizeof(struct in6_addr)));
|
||||
}
|
||||
RB_PROTOTYPE(ip6_msource_tree, ip6_msource, im6s_link, ip6_msource_cmp);
|
||||
|
||||
/*
|
||||
* IPv6 multicast PCB-layer group filter descriptor.
|
||||
*/
|
||||
struct in6_mfilter {
|
||||
struct ip6_msource_tree im6f_sources; /* source list for (S,G) */
|
||||
u_long im6f_nsrc; /* # of source entries */
|
||||
uint8_t im6f_st[2]; /* state before/at commit */
|
||||
};
|
||||
|
||||
/*
|
||||
* Legacy KAME IPv6 multicast membership descriptor.
|
||||
*/
|
||||
struct in6_multi_mship {
|
||||
struct in6_multi *i6mm_maddr;
|
||||
LIST_ENTRY(in6_multi_mship) i6mm_chain;
|
||||
};
|
||||
|
||||
/*
|
||||
* IPv6 group descriptor.
|
||||
*
|
||||
* For every entry on an ifnet's if_multiaddrs list which represents
|
||||
* an IP multicast group, there is one of these structures.
|
||||
*
|
||||
* If any source filters are present, then a node will exist in the RB-tree
|
||||
* to permit fast lookup by source whenever an operation takes place.
|
||||
* This permits pre-order traversal when we issue reports.
|
||||
* Source filter trees are kept separately from the socket layer to
|
||||
* greatly simplify locking.
|
||||
*
|
||||
* When MLDv2 is active, in6m_timer is the response to group query timer.
|
||||
* The state-change timer in6m_sctimer is separate; whenever state changes
|
||||
* for the group the state change record is generated and transmitted,
|
||||
* and kept if retransmissions are necessary.
|
||||
*
|
||||
* FUTURE: in6m_link is now only used when groups are being purged
|
||||
* on a detaching ifnet. It could be demoted to a SLIST_ENTRY, but
|
||||
* because it is at the very start of the struct, we can't do this
|
||||
* w/o breaking the ABI for ifmcstat.
|
||||
*/
|
||||
struct in6_multi {
|
||||
LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
|
||||
struct in6_addr in6m_addr; /* IPv6 multicast address */
|
||||
struct ifnet *in6m_ifp; /* back pointer to ifnet */
|
||||
struct ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */
|
||||
u_int in6m_refcount; /* reference count */
|
||||
u_int in6m_state; /* state of the membership */
|
||||
u_int in6m_timer; /* MLD6 listener report timer */
|
||||
|
||||
/* New fields for MLDv2 follow. */
|
||||
struct mld_ifsoftc *in6m_mli; /* MLD info */
|
||||
SLIST_ENTRY(in6_multi) in6m_nrele; /* to-be-released by MLD */
|
||||
struct ip6_msource_tree in6m_srcs; /* tree of sources */
|
||||
u_long in6m_nsrc; /* # of tree entries */
|
||||
|
||||
struct mbufq in6m_scq; /* queue of pending
|
||||
* state-change packets */
|
||||
struct timeval in6m_lastgsrtv; /* last G-S-R query */
|
||||
uint16_t in6m_sctimer; /* state-change timer */
|
||||
uint16_t in6m_scrv; /* state-change rexmit count */
|
||||
|
||||
/*
|
||||
* SSM state counters which track state at T0 (the time the last
|
||||
* state-change report's RV timer went to zero) and T1
|
||||
* (time of pending report, i.e. now).
|
||||
* Used for computing MLDv2 state-change reports. Several refcounts
|
||||
* are maintained here to optimize for common use-cases.
|
||||
*/
|
||||
struct in6m_st {
|
||||
uint16_t iss_fmode; /* MLD filter mode */
|
||||
uint16_t iss_asm; /* # of ASM listeners */
|
||||
uint16_t iss_ex; /* # of exclusive members */
|
||||
uint16_t iss_in; /* # of inclusive members */
|
||||
uint16_t iss_rec; /* # of recorded sources */
|
||||
} in6m_st[2]; /* state at t0, t1 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper function to derive the filter mode on a source entry
|
||||
* from its internal counters. Predicates are:
|
||||
* A source is only excluded if all listeners exclude it.
|
||||
* A source is only included if no listeners exclude it,
|
||||
* and at least one listener includes it.
|
||||
* May be used by ifmcstat(8).
|
||||
*/
|
||||
static __inline uint8_t
|
||||
im6s_get_mode(const struct in6_multi *inm, const struct ip6_msource *ims,
|
||||
uint8_t t)
|
||||
{
|
||||
|
||||
t = !!t;
|
||||
if (inm->in6m_st[t].iss_ex > 0 &&
|
||||
inm->in6m_st[t].iss_ex == ims->im6s_st[t].ex)
|
||||
return (MCAST_EXCLUDE);
|
||||
else if (ims->im6s_st[t].in > 0 && ims->im6s_st[t].ex == 0)
|
||||
return (MCAST_INCLUDE);
|
||||
return (MCAST_UNDEFINED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock macros for IPv6 layer multicast address lists. IPv6 lock goes
|
||||
* before link layer multicast locks in the lock order. In most cases,
|
||||
* consumers of IN_*_MULTI() macros should acquire the locks before
|
||||
* calling them; users of the in_{add,del}multi() functions should not.
|
||||
*/
|
||||
extern struct mtx in6_multi_mtx;
|
||||
#define IN6_MULTI_LOCK() mtx_lock(&in6_multi_mtx)
|
||||
#define IN6_MULTI_UNLOCK() mtx_unlock(&in6_multi_mtx)
|
||||
#define IN6_MULTI_LOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_OWNED)
|
||||
#define IN6_MULTI_UNLOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_NOTOWNED)
|
||||
|
||||
/*
|
||||
* Look up an in6_multi record for an IPv6 multicast address
|
||||
* on the interface ifp.
|
||||
* If no record found, return NULL.
|
||||
*
|
||||
* SMPng: The IN6_MULTI_LOCK and IF_ADDR_LOCK on ifp must be held.
|
||||
*/
|
||||
static __inline struct in6_multi *
|
||||
in6m_lookup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr)
|
||||
{
|
||||
struct ifmultiaddr *ifma;
|
||||
struct in6_multi *inm;
|
||||
|
||||
IN6_MULTI_LOCK_ASSERT();
|
||||
IF_ADDR_LOCK_ASSERT(ifp);
|
||||
|
||||
inm = NULL;
|
||||
TAILQ_FOREACH(ifma, &((ifp)->if_multiaddrs), ifma_link) {
|
||||
if (ifma->ifma_addr->sa_family == AF_INET6) {
|
||||
inm = (struct in6_multi *)ifma->ifma_protospec;
|
||||
if (IN6_ARE_ADDR_EQUAL(&inm->in6m_addr, mcaddr))
|
||||
break;
|
||||
inm = NULL;
|
||||
}
|
||||
}
|
||||
return (inm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for in6m_lookup_locked().
|
||||
*
|
||||
* SMPng: Assumes that neithr the IN6_MULTI_LOCK() or IF_ADDR_LOCK() are held.
|
||||
*/
|
||||
static __inline struct in6_multi *
|
||||
in6m_lookup(struct ifnet *ifp, const struct in6_addr *mcaddr)
|
||||
{
|
||||
struct in6_multi *inm;
|
||||
|
||||
IN6_MULTI_LOCK();
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
inm = in6m_lookup_locked(ifp, mcaddr);
|
||||
IF_ADDR_RUNLOCK(ifp);
|
||||
IN6_MULTI_UNLOCK();
|
||||
|
||||
return (inm);
|
||||
}
|
||||
|
||||
/* Acquire an in6_multi record. */
|
||||
static __inline void
|
||||
in6m_acquire_locked(struct in6_multi *inm)
|
||||
{
|
||||
|
||||
IN6_MULTI_LOCK_ASSERT();
|
||||
++inm->in6m_refcount;
|
||||
}
|
||||
|
||||
struct ip6_moptions;
|
||||
struct sockopt;
|
||||
|
||||
/* Multicast KPIs. */
|
||||
int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *,
|
||||
const struct sockaddr *, const struct sockaddr *);
|
||||
int in6_mc_join(struct ifnet *, const struct in6_addr *,
|
||||
struct in6_mfilter *, struct in6_multi **, int);
|
||||
int in6_mc_join_locked(struct ifnet *, const struct in6_addr *,
|
||||
struct in6_mfilter *, struct in6_multi **, int);
|
||||
int in6_mc_leave(struct in6_multi *, struct in6_mfilter *);
|
||||
int in6_mc_leave_locked(struct in6_multi *, struct in6_mfilter *);
|
||||
void in6m_clear_recorded(struct in6_multi *);
|
||||
void in6m_commit(struct in6_multi *);
|
||||
void in6m_print(const struct in6_multi *);
|
||||
int in6m_record_source(struct in6_multi *, const struct in6_addr *);
|
||||
void in6m_release_locked(struct in6_multi *);
|
||||
void ip6_freemoptions(struct ip6_moptions *);
|
||||
int ip6_getmoptions(struct inpcb *, struct sockopt *);
|
||||
int ip6_setmoptions(struct inpcb *, struct sockopt *);
|
||||
|
||||
/* Legacy KAME multicast KPIs. */
|
||||
struct in6_multi_mship *
|
||||
in6_joingroup(struct ifnet *, struct in6_addr *, int *, int);
|
||||
int in6_leavegroup(struct in6_multi_mship *);
|
||||
|
||||
/* flags to in6_update_ifa */
|
||||
#define IN6_IFAUPDATE_DADDELAY 0x1 /* first time to configure an address */
|
||||
|
||||
int in6_mask2len(struct in6_addr *, u_char *);
|
||||
int in6_control(struct socket *, u_long, caddr_t, struct ifnet *,
|
||||
struct thread *);
|
||||
int in6_update_ifa(struct ifnet *, struct in6_aliasreq *,
|
||||
struct in6_ifaddr *, int);
|
||||
void in6_prepare_ifra(struct in6_aliasreq *, const struct in6_addr *,
|
||||
const struct in6_addr *);
|
||||
void in6_purgeaddr(struct ifaddr *);
|
||||
int in6if_do_dad(struct ifnet *);
|
||||
void in6_savemkludge(struct in6_ifaddr *);
|
||||
void *in6_domifattach(struct ifnet *);
|
||||
void in6_domifdetach(struct ifnet *, void *);
|
||||
int in6_domifmtu(struct ifnet *);
|
||||
void in6_setmaxmtu(void);
|
||||
int in6_if2idlen(struct ifnet *);
|
||||
struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int);
|
||||
struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, const struct in6_addr *);
|
||||
struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_t);
|
||||
struct in6_ifaddr *in6ifa_llaonifp(struct ifnet *);
|
||||
int in6_addr2zoneid(struct ifnet *, struct in6_addr *, u_int32_t *);
|
||||
int in6_matchlen(struct in6_addr *, struct in6_addr *);
|
||||
int in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int);
|
||||
void in6_prefixlen2mask(struct in6_addr *, int);
|
||||
int in6_prefix_ioctl(struct socket *, u_long, caddr_t,
|
||||
struct ifnet *);
|
||||
int in6_prefix_add_ifid(int, struct in6_ifaddr *);
|
||||
void in6_prefix_remove_ifid(int, struct in6_ifaddr *);
|
||||
void in6_purgeprefix(struct ifnet *);
|
||||
|
||||
int in6_is_addr_deprecated(struct sockaddr_in6 *);
|
||||
int in6_src_ioctl(u_long, caddr_t);
|
||||
|
||||
void in6_newaddrmsg(struct in6_ifaddr *, int);
|
||||
/*
|
||||
* Extended API for IPv6 FIB support.
|
||||
*/
|
||||
void in6_rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *,
|
||||
int, struct sockaddr *, u_int);
|
||||
int in6_rtrequest(int, struct sockaddr *, struct sockaddr *,
|
||||
struct sockaddr *, int, struct rtentry **, u_int);
|
||||
void in6_rtalloc(struct route_in6 *, u_int);
|
||||
void in6_rtalloc_ign(struct route_in6 *, u_long, u_int);
|
||||
struct rtentry *in6_rtalloc1(struct sockaddr *, int, u_long, u_int);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET6_IN6_VAR_H_ */
|
|
@ -0,0 +1,479 @@
|
|||
/*-
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $KAME: nd6.h,v 1.76 2001/12/18 02:10:31 itojun Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_ND6_H_
|
||||
#define _NETINET6_ND6_H_
|
||||
|
||||
/* see net/route.h, or net/if_inarp.h */
|
||||
#ifndef RTF_ANNOUNCE
|
||||
#define RTF_ANNOUNCE RTF_PROTO2
|
||||
#endif
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/callout.h>
|
||||
|
||||
struct llentry;
|
||||
|
||||
#define ND6_LLINFO_NOSTATE -2
|
||||
/*
|
||||
* We don't need the WAITDELETE state any more, but we keep the definition
|
||||
* in a comment line instead of removing it. This is necessary to avoid
|
||||
* unintentionally reusing the value for another purpose, which might
|
||||
* affect backward compatibility with old applications.
|
||||
* (20000711 jinmei@kame.net)
|
||||
*/
|
||||
/* #define ND6_LLINFO_WAITDELETE -1 */
|
||||
#define ND6_LLINFO_INCOMPLETE 0
|
||||
#define ND6_LLINFO_REACHABLE 1
|
||||
#define ND6_LLINFO_STALE 2
|
||||
#define ND6_LLINFO_DELAY 3
|
||||
#define ND6_LLINFO_PROBE 4
|
||||
|
||||
#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE)
|
||||
#define ND6_LLINFO_PERMANENT(n) (((n)->la_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE))
|
||||
|
||||
struct nd_ifinfo {
|
||||
u_int32_t linkmtu; /* LinkMTU */
|
||||
u_int32_t maxmtu; /* Upper bound of LinkMTU */
|
||||
u_int32_t basereachable; /* BaseReachableTime */
|
||||
u_int32_t reachable; /* Reachable Time */
|
||||
u_int32_t retrans; /* Retrans Timer */
|
||||
u_int32_t flags; /* Flags */
|
||||
int recalctm; /* BaseReacable re-calculation timer */
|
||||
u_int8_t chlim; /* CurHopLimit */
|
||||
u_int8_t initialized; /* Flag to see the entry is initialized */
|
||||
/* the following 3 members are for privacy extension for addrconf */
|
||||
u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
|
||||
u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
|
||||
u_int8_t randomid[8]; /* current random ID */
|
||||
};
|
||||
|
||||
#define ND6_IFF_PERFORMNUD 0x1
|
||||
#define ND6_IFF_ACCEPT_RTADV 0x2
|
||||
#define ND6_IFF_PREFER_SOURCE 0x4 /* Not used in FreeBSD. */
|
||||
#define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to
|
||||
* DAD failure. (XXX: not ND-specific)
|
||||
*/
|
||||
#define ND6_IFF_DONT_SET_IFROUTE 0x10
|
||||
#define ND6_IFF_AUTO_LINKLOCAL 0x20
|
||||
#define ND6_IFF_NO_RADR 0x40
|
||||
#define ND6_IFF_NO_PREFER_IFACE 0x80 /* XXX: not related to ND. */
|
||||
#define ND6_IFF_NO_DAD 0x100
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define ND_IFINFO(ifp) \
|
||||
(((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo)
|
||||
#define IN6_LINKMTU(ifp) \
|
||||
((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \
|
||||
? ND_IFINFO(ifp)->linkmtu \
|
||||
: ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \
|
||||
? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))
|
||||
#endif
|
||||
|
||||
struct in6_nbrinfo {
|
||||
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct in6_addr addr; /* IPv6 address of the neighbor */
|
||||
long asked; /* number of queries already sent for this addr */
|
||||
int isrouter; /* if it acts as a router */
|
||||
int state; /* reachability state */
|
||||
int expire; /* lifetime for NDP state transition */
|
||||
};
|
||||
|
||||
#define DRLSTSIZ 10
|
||||
#define PRLSTSIZ 10
|
||||
struct in6_drlist {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
struct in6_addr rtaddr;
|
||||
u_char flags;
|
||||
u_short rtlifetime;
|
||||
u_long expire;
|
||||
u_short if_index;
|
||||
} defrouter[DRLSTSIZ];
|
||||
};
|
||||
|
||||
struct in6_defrouter {
|
||||
struct sockaddr_in6 rtaddr;
|
||||
u_char flags;
|
||||
u_short rtlifetime;
|
||||
u_long expire;
|
||||
u_short if_index;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct in6_oprlist {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
struct in6_addr prefix;
|
||||
struct prf_ra raflags;
|
||||
u_char prefixlen;
|
||||
u_char origin;
|
||||
u_long vltime;
|
||||
u_long pltime;
|
||||
u_long expire;
|
||||
u_short if_index;
|
||||
u_short advrtrs; /* number of advertisement routers */
|
||||
struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
|
||||
} prefix[PRLSTSIZ];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct in6_prlist {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
struct in6_addr prefix;
|
||||
struct prf_ra raflags;
|
||||
u_char prefixlen;
|
||||
u_char origin;
|
||||
u_int32_t vltime;
|
||||
u_int32_t pltime;
|
||||
time_t expire;
|
||||
u_short if_index;
|
||||
u_short advrtrs; /* number of advertisement routers */
|
||||
struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
|
||||
} prefix[PRLSTSIZ];
|
||||
};
|
||||
|
||||
struct in6_prefix {
|
||||
struct sockaddr_in6 prefix;
|
||||
struct prf_ra raflags;
|
||||
u_char prefixlen;
|
||||
u_char origin;
|
||||
u_int32_t vltime;
|
||||
u_int32_t pltime;
|
||||
time_t expire;
|
||||
u_int32_t flags;
|
||||
int refcnt;
|
||||
u_short if_index;
|
||||
u_short advrtrs; /* number of advertisement routers */
|
||||
/* struct sockaddr_in6 advrtr[] */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct in6_ondireq {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
u_int32_t linkmtu; /* LinkMTU */
|
||||
u_int32_t maxmtu; /* Upper bound of LinkMTU */
|
||||
u_int32_t basereachable; /* BaseReachableTime */
|
||||
u_int32_t reachable; /* Reachable Time */
|
||||
u_int32_t retrans; /* Retrans Timer */
|
||||
u_int32_t flags; /* Flags */
|
||||
int recalctm; /* BaseReacable re-calculation timer */
|
||||
u_int8_t chlim; /* CurHopLimit */
|
||||
u_int8_t receivedra;
|
||||
} ndi;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct in6_ndireq {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct nd_ifinfo ndi;
|
||||
};
|
||||
|
||||
struct in6_ndifreq {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_long ifindex;
|
||||
};
|
||||
|
||||
/* Prefix status */
|
||||
#define NDPRF_ONLINK 0x1
|
||||
#define NDPRF_DETACHED 0x2
|
||||
|
||||
/* protocol constants */
|
||||
#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */
|
||||
#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */
|
||||
#define MAX_RTR_SOLICITATIONS 3
|
||||
|
||||
#define ND6_INFINITE_LIFETIME 0xffffffff
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* node constants */
|
||||
#define MAX_REACHABLE_TIME 3600000 /* msec */
|
||||
#define REACHABLE_TIME 30000 /* msec */
|
||||
#define RETRANS_TIMER 1000 /* msec */
|
||||
#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */
|
||||
#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */
|
||||
#define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */
|
||||
#define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
|
||||
#define TEMPADDR_REGEN_ADVANCE 5 /* sec */
|
||||
#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */
|
||||
#define ND_COMPUTE_RTIME(x) \
|
||||
(((MIN_RANDOM_FACTOR * (x >> 10)) + (arc4random() & \
|
||||
((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
|
||||
|
||||
TAILQ_HEAD(nd_drhead, nd_defrouter);
|
||||
struct nd_defrouter {
|
||||
TAILQ_ENTRY(nd_defrouter) dr_entry;
|
||||
struct in6_addr rtaddr;
|
||||
u_char raflags; /* flags on RA message */
|
||||
u_short rtlifetime;
|
||||
u_long expire;
|
||||
struct ifnet *ifp;
|
||||
int installed; /* is installed into kernel routing table */
|
||||
u_int refcnt;
|
||||
};
|
||||
|
||||
struct nd_prefixctl {
|
||||
struct ifnet *ndpr_ifp;
|
||||
|
||||
/* prefix */
|
||||
struct sockaddr_in6 ndpr_prefix;
|
||||
u_char ndpr_plen;
|
||||
|
||||
u_int32_t ndpr_vltime; /* advertised valid lifetime */
|
||||
u_int32_t ndpr_pltime; /* advertised preferred lifetime */
|
||||
|
||||
struct prf_ra ndpr_flags;
|
||||
};
|
||||
|
||||
|
||||
struct nd_prefix {
|
||||
struct ifnet *ndpr_ifp;
|
||||
LIST_ENTRY(nd_prefix) ndpr_entry;
|
||||
struct sockaddr_in6 ndpr_prefix; /* prefix */
|
||||
struct in6_addr ndpr_mask; /* netmask derived from the prefix */
|
||||
|
||||
u_int32_t ndpr_vltime; /* advertised valid lifetime */
|
||||
u_int32_t ndpr_pltime; /* advertised preferred lifetime */
|
||||
|
||||
time_t ndpr_expire; /* expiration time of the prefix */
|
||||
time_t ndpr_preferred; /* preferred time of the prefix */
|
||||
time_t ndpr_lastupdate; /* reception time of last advertisement */
|
||||
|
||||
struct prf_ra ndpr_flags;
|
||||
u_int32_t ndpr_stateflags; /* actual state flags */
|
||||
/* list of routers that advertise the prefix: */
|
||||
LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
|
||||
u_char ndpr_plen;
|
||||
int ndpr_refcnt; /* reference couter from addresses */
|
||||
};
|
||||
|
||||
#define ndpr_raf ndpr_flags
|
||||
#define ndpr_raf_onlink ndpr_flags.onlink
|
||||
#define ndpr_raf_auto ndpr_flags.autonomous
|
||||
#define ndpr_raf_router ndpr_flags.router
|
||||
|
||||
/*
|
||||
* Message format for use in obtaining information about prefixes
|
||||
* from inet6 sysctl function
|
||||
*/
|
||||
struct inet6_ndpr_msghdr {
|
||||
u_short inpm_msglen; /* to skip over non-understood messages */
|
||||
u_char inpm_version; /* future binary compatibility */
|
||||
u_char inpm_type; /* message type */
|
||||
struct in6_addr inpm_prefix;
|
||||
u_long prm_vltim;
|
||||
u_long prm_pltime;
|
||||
u_long prm_expire;
|
||||
u_long prm_preferred;
|
||||
struct in6_prflags prm_flags;
|
||||
u_short prm_index; /* index for associated ifp */
|
||||
u_char prm_plen; /* length of prefix in bits */
|
||||
};
|
||||
|
||||
#define prm_raf_onlink prm_flags.prf_ra.onlink
|
||||
#define prm_raf_auto prm_flags.prf_ra.autonomous
|
||||
|
||||
#define prm_statef_onlink prm_flags.prf_state.onlink
|
||||
|
||||
#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
|
||||
#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
|
||||
|
||||
struct nd_pfxrouter {
|
||||
LIST_ENTRY(nd_pfxrouter) pfr_entry;
|
||||
struct nd_defrouter *router;
|
||||
};
|
||||
|
||||
LIST_HEAD(nd_prhead, nd_prefix);
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_IP6NDP);
|
||||
#endif
|
||||
|
||||
/* nd6.c */
|
||||
VNET_DECLARE(int, nd6_prune);
|
||||
VNET_DECLARE(int, nd6_delay);
|
||||
VNET_DECLARE(int, nd6_umaxtries);
|
||||
VNET_DECLARE(int, nd6_mmaxtries);
|
||||
VNET_DECLARE(int, nd6_useloopback);
|
||||
VNET_DECLARE(int, nd6_maxnudhint);
|
||||
VNET_DECLARE(int, nd6_gctimer);
|
||||
VNET_DECLARE(struct nd_drhead, nd_defrouter);
|
||||
VNET_DECLARE(struct nd_prhead, nd_prefix);
|
||||
VNET_DECLARE(int, nd6_debug);
|
||||
VNET_DECLARE(int, nd6_onlink_ns_rfc4861);
|
||||
#define V_nd6_prune VNET(nd6_prune)
|
||||
#define V_nd6_delay VNET(nd6_delay)
|
||||
#define V_nd6_umaxtries VNET(nd6_umaxtries)
|
||||
#define V_nd6_mmaxtries VNET(nd6_mmaxtries)
|
||||
#define V_nd6_useloopback VNET(nd6_useloopback)
|
||||
#define V_nd6_maxnudhint VNET(nd6_maxnudhint)
|
||||
#define V_nd6_gctimer VNET(nd6_gctimer)
|
||||
#define V_nd_defrouter VNET(nd_defrouter)
|
||||
#define V_nd_prefix VNET(nd_prefix)
|
||||
#define V_nd6_debug VNET(nd6_debug)
|
||||
#define V_nd6_onlink_ns_rfc4861 VNET(nd6_onlink_ns_rfc4861)
|
||||
|
||||
/* Lock for the prefix and default router lists. */
|
||||
VNET_DECLARE(struct rwlock, nd6_lock);
|
||||
#define V_nd6_lock VNET(nd6_lock)
|
||||
|
||||
#define ND6_RLOCK() rw_rlock(&V_nd6_lock)
|
||||
#define ND6_RUNLOCK() rw_runlock(&V_nd6_lock)
|
||||
#define ND6_WLOCK() rw_wlock(&V_nd6_lock)
|
||||
#define ND6_WUNLOCK() rw_wunlock(&V_nd6_lock)
|
||||
#define ND6_WLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_WLOCKED)
|
||||
#define ND6_RLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_RLOCKED)
|
||||
#define ND6_LOCK_ASSERT() rw_assert(&V_nd6_lock, RA_LOCKED)
|
||||
#define ND6_UNLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_UNLOCKED)
|
||||
|
||||
#define nd6log(x) do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* nd6_rtr.c */
|
||||
VNET_DECLARE(int, nd6_defifindex);
|
||||
VNET_DECLARE(int, ip6_desync_factor); /* seconds */
|
||||
VNET_DECLARE(u_int32_t, ip6_temp_preferred_lifetime); /* seconds */
|
||||
VNET_DECLARE(u_int32_t, ip6_temp_valid_lifetime); /* seconds */
|
||||
VNET_DECLARE(int, ip6_temp_regen_advance); /* seconds */
|
||||
#define V_nd6_defifindex VNET(nd6_defifindex)
|
||||
#define V_ip6_desync_factor VNET(ip6_desync_factor)
|
||||
#define V_ip6_temp_preferred_lifetime VNET(ip6_temp_preferred_lifetime)
|
||||
#define V_ip6_temp_valid_lifetime VNET(ip6_temp_valid_lifetime)
|
||||
#define V_ip6_temp_regen_advance VNET(ip6_temp_regen_advance)
|
||||
|
||||
union nd_opts {
|
||||
struct nd_opt_hdr *nd_opt_array[16]; /* max = ND_OPT_NONCE */
|
||||
struct {
|
||||
struct nd_opt_hdr *zero;
|
||||
struct nd_opt_hdr *src_lladdr;
|
||||
struct nd_opt_hdr *tgt_lladdr;
|
||||
struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */
|
||||
struct nd_opt_rd_hdr *rh;
|
||||
struct nd_opt_mtu *mtu;
|
||||
struct nd_opt_hdr *__res6;
|
||||
struct nd_opt_hdr *__res7;
|
||||
struct nd_opt_hdr *__res8;
|
||||
struct nd_opt_hdr *__res9;
|
||||
struct nd_opt_hdr *__res10;
|
||||
struct nd_opt_hdr *__res11;
|
||||
struct nd_opt_hdr *__res12;
|
||||
struct nd_opt_hdr *__res13;
|
||||
struct nd_opt_nonce *nonce;
|
||||
struct nd_opt_hdr *__res15;
|
||||
struct nd_opt_hdr *search; /* multiple opts */
|
||||
struct nd_opt_hdr *last; /* multiple opts */
|
||||
int done;
|
||||
struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
|
||||
} nd_opt_each;
|
||||
};
|
||||
#define nd_opts_src_lladdr nd_opt_each.src_lladdr
|
||||
#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
|
||||
#define nd_opts_pi nd_opt_each.pi_beg
|
||||
#define nd_opts_pi_end nd_opt_each.pi_end
|
||||
#define nd_opts_rh nd_opt_each.rh
|
||||
#define nd_opts_mtu nd_opt_each.mtu
|
||||
#define nd_opts_nonce nd_opt_each.nonce
|
||||
#define nd_opts_search nd_opt_each.search
|
||||
#define nd_opts_last nd_opt_each.last
|
||||
#define nd_opts_done nd_opt_each.done
|
||||
|
||||
/* XXX: need nd6_var.h?? */
|
||||
/* nd6.c */
|
||||
void nd6_init(void);
|
||||
#ifdef VIMAGE
|
||||
void nd6_destroy(void);
|
||||
#endif
|
||||
struct nd_ifinfo *nd6_ifattach(struct ifnet *);
|
||||
void nd6_ifdetach(struct ifnet *, struct nd_ifinfo *);
|
||||
int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *);
|
||||
void nd6_option_init(void *, int, union nd_opts *);
|
||||
struct nd_opt_hdr *nd6_option(union nd_opts *);
|
||||
int nd6_options(union nd_opts *);
|
||||
struct llentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *);
|
||||
struct llentry *nd6_alloc(const struct in6_addr *, int, struct ifnet *);
|
||||
void nd6_setmtu(struct ifnet *);
|
||||
void nd6_llinfo_setstate(struct llentry *lle, int newstate);
|
||||
void nd6_timer(void *);
|
||||
void nd6_purge(struct ifnet *);
|
||||
int nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
|
||||
char *desten, uint32_t *pflags);
|
||||
int nd6_resolve(struct ifnet *, int, struct mbuf *,
|
||||
const struct sockaddr *, u_char *, uint32_t *, struct llentry **);
|
||||
int nd6_ioctl(u_long, caddr_t, struct ifnet *);
|
||||
void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
|
||||
char *, int, int, int);
|
||||
void nd6_grab_holdchain(struct llentry *, struct mbuf **,
|
||||
struct sockaddr_in6 *);
|
||||
int nd6_flush_holdchain(struct ifnet *, struct ifnet *, struct mbuf *,
|
||||
struct sockaddr_in6 *);
|
||||
int nd6_add_ifa_lle(struct in6_ifaddr *);
|
||||
void nd6_rem_ifa_lle(struct in6_ifaddr *, int);
|
||||
int nd6_output_ifp(struct ifnet *, struct ifnet *, struct mbuf *,
|
||||
struct sockaddr_in6 *, struct route *);
|
||||
|
||||
/* nd6_nbr.c */
|
||||
void nd6_na_input(struct mbuf *, int, int);
|
||||
void nd6_na_output(struct ifnet *, const struct in6_addr *,
|
||||
const struct in6_addr *, u_long, int, struct sockaddr *);
|
||||
void nd6_ns_input(struct mbuf *, int, int);
|
||||
void nd6_ns_output(struct ifnet *, const struct in6_addr *,
|
||||
const struct in6_addr *, const struct in6_addr *, uint8_t *);
|
||||
caddr_t nd6_ifptomac(struct ifnet *);
|
||||
void nd6_dad_init(void);
|
||||
void nd6_dad_start(struct ifaddr *, int);
|
||||
void nd6_dad_stop(struct ifaddr *);
|
||||
|
||||
/* nd6_rtr.c */
|
||||
void nd6_rs_input(struct mbuf *, int, int);
|
||||
void nd6_ra_input(struct mbuf *, int, int);
|
||||
void defrouter_reset(void);
|
||||
void defrouter_select(void);
|
||||
void defrouter_ref(struct nd_defrouter *);
|
||||
void defrouter_rele(struct nd_defrouter *);
|
||||
bool defrouter_remove(struct in6_addr *, struct ifnet *);
|
||||
void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *);
|
||||
void defrouter_del(struct nd_defrouter *);
|
||||
void prelist_remove(struct nd_prefix *);
|
||||
int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
|
||||
struct nd_prefix **);
|
||||
void pfxlist_onlink_check(void);
|
||||
struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
|
||||
struct nd_defrouter *defrouter_lookup_locked(struct in6_addr *, struct ifnet *);
|
||||
struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *);
|
||||
void rt6_flush(struct in6_addr *, struct ifnet *);
|
||||
int nd6_setdefaultiface(int);
|
||||
int in6_tmpifadd(const struct in6_ifaddr *, int, int);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET6_ND6_H_ */
|
|
@ -53,8 +53,9 @@ ioctl_va(int fd, unsigned long com, void *data, int argc, ...)
|
|||
unsigned size;
|
||||
void *cpy_mem;
|
||||
size_t offset, clen;
|
||||
int af = 0;
|
||||
|
||||
if (argc != 0 && argc != 3) {
|
||||
if (argc != 0 && argc != 3 && argc != 1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -66,6 +67,11 @@ ioctl_va(int fd, unsigned long com, void *data, int argc, ...)
|
|||
cpy_mem = va_arg(ap, void *);
|
||||
clen = va_arg(ap, size_t);
|
||||
va_end(ap);
|
||||
} else if (argc == 1) {
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
af = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
if (com > 0xffffffff) {
|
||||
|
@ -92,7 +98,18 @@ ioctl_va(int fd, unsigned long com, void *data, int argc, ...)
|
|||
return -1;
|
||||
}
|
||||
|
||||
msg->msg_type = FF_IOCTL;
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6) {
|
||||
msg->msg_type = FF_IOCTL6;
|
||||
} else
|
||||
#endif
|
||||
if (af == AF_INET)
|
||||
msg->msg_type = FF_IOCTL;
|
||||
else {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->ioctl.cmd = com;
|
||||
msg->ioctl.data = msg->buf_addr;
|
||||
memcpy(msg->ioctl.data, data, size);
|
||||
|
|
|
@ -52,6 +52,7 @@ static const char rcsid[] =
|
|||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h> /* Define ND6_INFINITE_LIFETIME */
|
||||
|
||||
#include "ifconfig.h"
|
||||
|
@ -175,9 +176,13 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
|||
u_int32_t flags6;
|
||||
struct in6_addrlifetime lifetime;
|
||||
struct timespec now;
|
||||
#ifndef FSTACK
|
||||
int error, n_flags;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC_FAST, &now);
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
#endif
|
||||
|
||||
memset(&null_sin, 0, sizeof(null_sin));
|
||||
|
||||
|
@ -191,15 +196,25 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
|||
return;
|
||||
}
|
||||
ifr6.ifr_addr = *sin;
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
|
||||
#else
|
||||
if (ioctl_va(s6, SIOCGIFAFLAG_IN6, &ifr6, 1, AF_INET6) == -1) {
|
||||
#endif
|
||||
|
||||
warn("ioctl(SIOCGIFAFLAG_IN6)");
|
||||
close(s6);
|
||||
return;
|
||||
}
|
||||
|
||||
flags6 = ifr6.ifr_ifru.ifru_flags6;
|
||||
memset(&lifetime, 0, sizeof(lifetime));
|
||||
ifr6.ifr_addr = *sin;
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr6) < 0) {
|
||||
#else
|
||||
if (ioctl_va(s6, SIOCGIFALIFETIME_IN6, &ifr6, 1, AF_INET6) == -1) {
|
||||
#endif
|
||||
warn("ioctl(SIOCGIFALIFETIME_IN6)");
|
||||
close(s6);
|
||||
return;
|
||||
|
@ -207,6 +222,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
|||
lifetime = ifr6.ifr_ifru.ifru_lifetime;
|
||||
close(s6);
|
||||
|
||||
#ifndef FSTACK
|
||||
if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0)
|
||||
n_flags = 0;
|
||||
else if (f_addr != NULL && strcmp(f_addr, "host") == 0)
|
||||
|
@ -217,7 +233,8 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
|||
addr_buf, sizeof(addr_buf), NULL, 0,
|
||||
n_flags);
|
||||
if (error != 0)
|
||||
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
|
||||
#endif
|
||||
inet_ntop(AF_INET6_LINUX, &sin->sin6_addr, addr_buf,
|
||||
sizeof(addr_buf));
|
||||
printf("\tinet6 %s", addr_buf);
|
||||
|
||||
|
@ -230,14 +247,17 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
|||
if (sin != NULL && sin->sin6_family == AF_INET6) {
|
||||
int error;
|
||||
|
||||
#ifndef FSTACK
|
||||
error = getnameinfo((struct sockaddr *)sin,
|
||||
sin->sin6_len, addr_buf,
|
||||
sizeof(addr_buf), NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
if (error != 0)
|
||||
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
|
||||
#else
|
||||
inet_ntop(AF_INET6_LINUX, &sin->sin6_addr, addr_buf,
|
||||
sizeof(addr_buf));
|
||||
printf(" --> %s ", addr_buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,8 +347,10 @@ static void
|
|||
in6_getaddr(const char *s, int which)
|
||||
{
|
||||
struct sockaddr_in6 *sin = sin6tab[which];
|
||||
#ifndef FSTACK
|
||||
struct addrinfo hints, *res;
|
||||
int error = -1;
|
||||
#endif
|
||||
|
||||
newaddr &= 1;
|
||||
|
||||
|
@ -345,16 +367,22 @@ in6_getaddr(const char *s, int which)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef FSTACK
|
||||
if (inet_pton(AF_INET6_LINUX, s, &sin->sin6_addr) != 1)
|
||||
errx(1, "%s: bad value", s);
|
||||
return;
|
||||
#else
|
||||
if (sin->sin6_family == AF_INET6) {
|
||||
bzero(&hints, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_INET6;
|
||||
error = getaddrinfo(s, NULL, &hints, &res);
|
||||
}
|
||||
if (error != 0) {
|
||||
if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
|
||||
if (inet_pton(AF_INET6_LINUX, s, &sin->sin6_addr) != 1)
|
||||
errx(1, "%s: bad value", s);
|
||||
} else
|
||||
bcopy(res->ai_addr, sin, res->ai_addrlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -433,26 +461,48 @@ in6_status_tunnel(int s)
|
|||
char dst[NI_MAXHOST];
|
||||
struct in6_ifreq in6_ifr;
|
||||
const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr;
|
||||
#ifdef FSTACK
|
||||
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
|
||||
#endif
|
||||
|
||||
memset(&in6_ifr, 0, sizeof(in6_ifr));
|
||||
strlcpy(in6_ifr.ifr_name, name, sizeof(in6_ifr.ifr_name));
|
||||
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0)
|
||||
#else
|
||||
if (ioctl_va(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr, 1, AF_INET6) == -1)
|
||||
#endif
|
||||
return;
|
||||
if (sa->sa_family != AF_INET6)
|
||||
return;
|
||||
|
||||
#ifndef FSTACK
|
||||
if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0,
|
||||
NI_NUMERICHOST) != 0)
|
||||
src[0] = '\0';
|
||||
#else
|
||||
if (inet_ntop(AF_INET6_LINUX, &sin6->sin6_addr, src, sizeof(src)) == NULL)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr) < 0)
|
||||
#else
|
||||
if (ioctl_va(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr, 1, AF_INET6) == -1)
|
||||
#endif
|
||||
return;
|
||||
if (sa->sa_family != AF_INET6)
|
||||
return;
|
||||
|
||||
#ifndef FSTACK
|
||||
if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0,
|
||||
NI_NUMERICHOST) != 0)
|
||||
dst[0] = '\0';
|
||||
|
||||
#else
|
||||
if (inet_ntop(AF_INET6_LINUX, &sin6->sin6_addr, dst, sizeof(dst)) == NULL)
|
||||
return;
|
||||
#endif
|
||||
printf("\ttunnel inet6 %s --> %s\n", src, dst);
|
||||
}
|
||||
|
||||
|
@ -467,7 +517,11 @@ in6_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
|
|||
memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
|
||||
dstres->ai_addr->sa_len);
|
||||
|
||||
if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0)
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s, SIOCSIFPHYADDR_IN6, (caddr_t)&in6_addreq) < 0)
|
||||
#else
|
||||
if (ioctl_va(s, SIOCSIFPHYADDR_IN6, (caddr_t)&in6_addreq, 1, AF_INET6) == -1)
|
||||
#endif
|
||||
warn("SIOCSIFPHYADDR_IN6");
|
||||
}
|
||||
|
||||
|
@ -534,12 +588,12 @@ static __constructor void
|
|||
inet6_ctor(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
#ifndef FSTACK
|
||||
#ifndef RESCUE
|
||||
if (!feature_present("inet6"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
for (i = 0; i < nitems(inet6_cmds); i++)
|
||||
cmd_register(&inet6_cmds[i]);
|
||||
af_register(&af_inet6);
|
||||
|
|
|
@ -50,6 +50,7 @@ static const char rcsid[] =
|
|||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#include "ifconfig.h"
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip_carp.h>
|
||||
|
||||
#include <netinet6/in6_var.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -922,7 +922,11 @@ top:
|
|||
int ret;
|
||||
strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name,
|
||||
sizeof ifr.ifr_name);
|
||||
#ifndef FSTACK
|
||||
ret = ioctl(s, afp->af_difaddr, afp->af_ridreq);
|
||||
#else
|
||||
ret = ioctl_va(s, afp->af_difaddr, afp->af_ridreq, 1, afp->af_af);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
|
||||
/* means no previous address for interface */
|
||||
|
@ -940,7 +944,11 @@ top:
|
|||
if (newaddr && (setaddr || setmask)) {
|
||||
strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name,
|
||||
sizeof ifr.ifr_name);
|
||||
#ifndef FSTACK
|
||||
if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0)
|
||||
#else
|
||||
if (ioctl_va(s, afp->af_aifaddr, afp->af_addreq, 1, afp->af_af) < 0)
|
||||
#endif
|
||||
Perror("ioctl (SIOCAIFADDR)");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
MK_INET_SUPPORT="yes"
|
||||
MK_INET6_SUPPORT="no"
|
||||
MK_INET6_SUPPORT="yes"
|
||||
MK_IFMEDIA_SUPPORT="no"
|
||||
MK_MAC_SUPPORT="no"
|
||||
MK_SFP_SUPPORT="no"
|
||||
|
|
|
@ -84,8 +84,6 @@ __FBSDID("$FreeBSD$");
|
|||
|
||||
#define write(a, b, c) rtioctl((b), (c), (0))
|
||||
|
||||
#define CLOCK_REALTIME_FAST CLOCK_REALTIME
|
||||
|
||||
#endif
|
||||
|
||||
struct fibl {
|
||||
|
@ -629,9 +627,16 @@ routename(struct sockaddr *sa)
|
|||
rt_line, sizeof(rt_line), NULL, 0,
|
||||
(nflag == 0) ? 0 : NI_NUMERICHOST);
|
||||
#else
|
||||
const char *dst = NULL;
|
||||
error = 0;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
|
||||
const char *dst = inet_ntop(AF_INET, &sin->sin_addr, rt_line, sizeof(rt_line));
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
|
||||
if (sa->sa_family == AF_INET6)
|
||||
dst = inet_ntop(AF_INET6_LINUX, &sin6->sin6_addr, rt_line, sizeof(rt_line));
|
||||
else
|
||||
#endif
|
||||
dst = inet_ntop(AF_INET, &sin->sin_addr, rt_line, sizeof(rt_line));
|
||||
if (dst == NULL) {
|
||||
error = EAI_NONAME;
|
||||
}
|
||||
|
@ -723,6 +728,7 @@ netname(struct sockaddr *sa)
|
|||
cp = np->n_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define C(x) (unsigned)((x) & 0xff)
|
||||
if (cp != NULL)
|
||||
strncpy(net_line, cp, sizeof(net_line));
|
||||
|
@ -738,6 +744,7 @@ netname(struct sockaddr *sa)
|
|||
(void)sprintf(net_line, "%u.%u.%u.%u", C(in.s_addr >> 24),
|
||||
C(in.s_addr >> 16), C(in.s_addr >> 8),
|
||||
C(in.s_addr));
|
||||
|
||||
#undef C
|
||||
break;
|
||||
}
|
||||
|
@ -752,10 +759,15 @@ netname(struct sockaddr *sa)
|
|||
memcpy(&sin6, sa, sa->sa_len);
|
||||
sin6.sin6_len = sizeof(sin6);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#ifndef FSTACK
|
||||
if (nflag)
|
||||
niflags |= NI_NUMERICHOST;
|
||||
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
|
||||
net_line, sizeof(net_line), NULL, 0, niflags) != 0)
|
||||
#else
|
||||
if (inet_ntop(AF_INET6_LINUX, &sin6.sin6_addr, net_line, sizeof(net_line)) == NULL)
|
||||
|
||||
#endif
|
||||
strncpy(net_line, "invalid", sizeof(net_line));
|
||||
|
||||
return(net_line);
|
||||
|
@ -1314,12 +1326,15 @@ getaddr(int idx, char *str, struct hostent **hpp, int nrflags)
|
|||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
#ifndef FSTACK
|
||||
struct addrinfo hints, *res;
|
||||
int ecode;
|
||||
#endif
|
||||
|
||||
q = NULL;
|
||||
if (idx == RTAX_DST && (q = strchr(str, '/')) != NULL)
|
||||
*q = '\0';
|
||||
#ifndef FSTACK
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = sa->sa_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
@ -1329,6 +1344,10 @@ getaddr(int idx, char *str, struct hostent **hpp, int nrflags)
|
|||
errx(EX_OSERR, "%s: %s", str, gai_strerror(ecode));
|
||||
memcpy(sa, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
#else
|
||||
if (inet_pton(AF_INET6_LINUX, str, &((struct sockaddr_in6 *)sa)->sin6_addr) == -1)
|
||||
errx(EX_OSERR, "%s: %d, %s", str, errno, strerror(errno));
|
||||
#endif
|
||||
if (q != NULL)
|
||||
*q++ = '/';
|
||||
if (idx == RTAX_DST)
|
||||
|
@ -1961,7 +1980,11 @@ sodump(struct sockaddr *sa, const char *which)
|
|||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#ifdef FSTACK
|
||||
(void)printf("%s: inet6 %s; ", which, inet_ntop(AF_INET6_LINUX,
|
||||
#else
|
||||
(void)printf("%s: inet6 %s; ", which, inet_ntop(sa->sa_family,
|
||||
#endif
|
||||
&((struct sockaddr_in6 *)(void *)sa)->sin6_addr, nbuf,
|
||||
sizeof(nbuf)));
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue