Remove in-kernel handling of Router Advertisements

This is much better handled by a user-land tool.
Proposed on tech-net here:
https://mail-index.netbsd.org/tech-net/2020/04/22/msg007766.html

Note that the ioctl SIOCGIFINFO_IN6 no longer sets flags. That now
needs to be done using the pre-existing SIOCSIFINFO_FLAGS ioctl.

Compat is fully provided where it makes sense, but trying to turn on
RA handling will obviously throw an error as it no longer exists.

Note that if you use IPv6 temporary addresses, this now needs to be
turned on in dhcpcd.conf(5) rather than in sysctl.conf(5).
This commit is contained in:
roy 2020-06-12 11:04:44 +00:00
parent 3148a52497
commit b05648aa26
30 changed files with 463 additions and 5876 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.842 2020/06/06 21:26:00 thorpej Exp $
# $NetBSD: mi,v 1.843 2020/06/12 11:04:44 roy Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3884,7 +3884,7 @@
./usr/tests/net/ndp/Kyuafile tests-net-tests atf,rump,kyua
./usr/tests/net/ndp/t_dad tests-net-tests atf,rump
./usr/tests/net/ndp/t_ndp tests-net-tests atf,rump
./usr/tests/net/ndp/t_ra tests-net-tests atf,rump
./usr/tests/net/ndp/t_ra tests-obsolete obsolete
./usr/tests/net/net tests-net-tests compattestfile,atf
./usr/tests/net/net/Atffile tests-net-tests compattestfile,atf
./usr/tests/net/net/Kyuafile tests-net-tests compattestfile,atf,kyua

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.42 2020/05/18 21:19:34 jmcneill Exp $
# $NetBSD: Makefile,v 1.43 2020/06/12 11:04:44 roy Exp $
.include <bsd.own.mk>
@ -57,9 +57,9 @@ EXTRA_DIST_FILES+= NetBSD.dist.tests.compat
.endif
.endif
.if ${MKDTB} != "no"
EXTRA_DIST_FILES+= NetBSD.dist.dtb
.endif
#.if ${MKDTB} != "no"
#EXTRA_DIST_FILES+= NetBSD.dist.dtb
#.endif
.if ${MKDTRACE} != "no"
EXTRA_DIST_FILES+= NetBSD.dist.dtrace

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# $NetBSD: network,v 1.78 2020/04/15 20:31:57 kim Exp $
# $NetBSD: network,v 1.79 2020/06/12 11:04:45 roy Exp $
#
# PROVIDE: network
@ -50,7 +50,6 @@ network_start()
network_start_defaultroute
network_start_defaultroute6
have_inet6 &&
network_start_ipv6_autoconf
network_wait_dad
network_start_resolv
network_start_local
@ -171,7 +170,6 @@ network_start_ipv6_route()
/sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject
/sbin/sysctl -qw net.inet6.ip6.forwarding=0
/sbin/sysctl -qw net.inet6.ip6.accept_rtadv=0
case $ip6mode in
router)
@ -187,8 +185,10 @@ network_start_ipv6_route()
;;
autohost)
echo 'IPv6 mode: autoconfigured host'
/sbin/sysctl -qw net.inet6.ip6.accept_rtadv=1
if ! checkyesno dhcpcd; then
warn "rtsol and kernel ra handling have been removed"
warn "please configure dhcpcd in its place."
fi
;;
host)
@ -319,15 +319,14 @@ network_start_interfaces()
;;
dhcp)
if ! checkyesno dhcpcd; then
/sbin/dhcpcd -n \
/sbin/dhcpcd -n --dhcp \
${dhcpcd_flags} $int
fi
;;
rtsol)
if ! checkyesno dhcpcd; then
/sbin/sysctl -qw \
net.inet6.ip6.accept_rtadv=1
/sbin/dhcpcd -q6T --nodhcp6 $int
/sbin/dhcpcd -n --ipv6rs \
${dhcpcd_flags} $int
fi
;;
*)
@ -439,20 +438,6 @@ network_start_defaultroute6()
fi
}
network_start_ipv6_autoconf()
{
# IPv6 interface autoconfiguration.
# dhcpcd will ensure DAD completes before forking
if checkyesnox rtsol && ! checkyesno dhcpcd; then
if [ "$ip6mode" = "autohost" ]; then
echo
warn "rtsol has been removed, " \
"please configure dhcpcd in its place."
fi
fi
}
network_wait_dad()
{
# Wait for the DAD flags to clear from all addresses.

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_43.c,v 1.24 2019/12/12 02:15:42 pgoyette Exp $ */
/* $NetBSD: if_43.c,v 1.25 2020/06/12 11:04:45 roy Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1990, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.24 2019/12/12 02:15:42 pgoyette Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.25 2020/06/12 11:04:45 roy Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@ -164,7 +164,6 @@ compat_cvtcmd(u_long cmd)
case SIOCDIFADDR:
case SIOCDIFADDR_IN6:
case SIOCDIFPHYADDR:
case SIOCGDEFIFACE_IN6:
case SIOCG80211NWID:
case SIOCG80211STATS:
case SIOCG80211ZSTATS:
@ -192,7 +191,6 @@ compat_cvtcmd(u_long cmd)
case SIOCIFCREATE:
case SIOCIFDESTROY:
case SIOCS80211NWID:
case SIOCSDEFIFACE_IN6:
case SIOCSIFADDR:
case SIOCSIFADDR_IN6:
case SIOCSIFBRDADDR:
@ -205,9 +203,6 @@ compat_cvtcmd(u_long cmd)
case SIOCSIFMTU:
case SIOCSIFNETMASK:
case SIOCSIFNETMASK_IN6:
case SIOCSNDFLUSH_IN6:
case SIOCSPFXFLUSH_IN6:
case SIOCSRTRFLUSH_IN6:
case SIOCSVH:
case TAPGIFNAME:
return ncmd;

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_var.h,v 1.5 2019/12/15 16:48:26 tsutsui Exp $ */
/* $NetBSD: in6_var.h,v 1.6 2020/06/12 11:04:45 roy Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -49,9 +49,27 @@ struct in6_aliasreq50 {
struct in6_addrlifetime50 ifra_lifetime;
};
#define OSIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
struct prf_ra {
u_int32_t onlink : 1;
u_int32_t autonomous : 1;
u_int32_t router : 1;
u_int32_t reserved : 5;
};
#define OSIOCAIFADDR_IN6 _IOW('i', 26, struct in6_aliasreq50)
#define OSIOCSIFPHYADDR_IN6 _IOW('i', 70, struct in6_aliasreq50)
#define OSIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist)
#define OSIOCGPRLST_IN6 _IOWR('i', 75, struct in6_oprlist)
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
#define OSIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
#define OSIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
#define OSIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq)
#define OSIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
#define OSIOCSDEFIFACE_IN6 _IOWR('i', 85, struct in6_ndifreq90)
#define OSIOCGDEFIFACE_IN6 _IOWR('i', 86, struct in6_ndifreq90)
#define OSIOCSIFINFO_FLAGS_90 _IOWR('i', 87, struct in6_ndireq90)
#define OSIOCGIFINFO_IN6_90 _IOWR('i', 108, struct in6_ndireq90)
#define OSIOCSIFINFO_IN6_90 _IOWR('i', 109, struct in6_ndireq90)
static __inline void in6_addrlifetime_to_in6_addrlifetime50(
struct in6_addrlifetime *al)

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.477 2020/05/05 09:26:29 jdolecek Exp $ */
/* $NetBSD: if.c,v 1.478 2020/06/12 11:04:45 roy Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.477 2020/05/05 09:26:29 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.478 2020/06/12 11:04:45 roy Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@ -3139,15 +3139,6 @@ ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
if (ifp->if_mtu == ifr->ifr_mtu)
break;
ifp->if_mtu = ifr->ifr_mtu;
/*
* If the link MTU changed, do network layer specific procedure.
*/
#ifdef INET6
KERNEL_LOCK_UNLESS_NET_MPSAFE();
if (in6_present)
nd6_setmtu(ifp);
KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
#endif
return ENETRESET;
case SIOCSIFDESCR:
error = kauth_authorize_network(curlwp->l_cred,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_vlan.c,v 1.151 2020/02/01 02:58:15 riastradh Exp $ */
/* $NetBSD: if_vlan.c,v 1.152 2020/06/12 11:04:45 roy Exp $ */
/*
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.151 2020/02/01 02:58:15 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.152 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -541,12 +541,6 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag)
nmib->ifvm_p = p;
nmib->ifvm_tag = vid;
ifv->ifv_if.if_mtu = p->if_mtu - nmib->ifvm_mtufudge;
#ifdef INET6
KERNEL_LOCK_UNLESS_NET_MPSAFE();
if (in6_present)
nd6_setmtu(ifp);
KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
#endif
ifv->ifv_if.if_flags = p->if_flags &
(IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.h,v 1.53 2020/03/09 21:20:55 roy Exp $ */
/* $NetBSD: icmp6.h,v 1.54 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */
@ -633,8 +633,10 @@ struct icmp6_filter {
#define ICMPV6CTL_MTUDISC_HIWAT 16
#define ICMPV6CTL_MTUDISC_LOWAT 17
#define ICMPV6CTL_ND6_DEBUG 18
#define ICMPV6CTL_ND6_DRLIST 19
#define ICMPV6CTL_ND6_PRLIST 20
#ifdef _KERNEL
#define OICMPV6CTL_ND6_DRLIST 19
#define OICMPV6CTL_ND6_PRLIST 20
#endif
#define ICMPV6CTL_ND6_MAXQLEN 24
#ifdef _KERNEL

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_output.c,v 1.212 2019/11/17 08:21:25 mlelstv Exp $ */
/* $NetBSD: tcp_output.c,v 1.213 2020/06/12 11:04:45 roy Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -135,7 +135,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.212 2019/11/17 08:21:25 mlelstv Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.213 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -307,7 +307,7 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep,
* for IPv6, path MTU discovery is always turned on,
* or the node must use packet size <= 1280.
*/
size = tp->t_mtudisc ? IN6_LINKMTU(ifp) : IPV6_MMTU;
size = tp->t_mtudisc ? ifp->if_mtu : IPV6_MMTU;
size -= hdrlen;
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_subr.c,v 1.283 2019/08/06 15:48:18 riastradh Exp $ */
/* $NetBSD: tcp_subr.c,v 1.284 2020/06/12 11:04:45 roy Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.283 2019/08/06 15:48:18 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.284 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -1819,26 +1819,22 @@ tcp_mss_to_advertise(const struct ifnet *ifp, int af)
if (ifp != NULL)
switch (af) {
#ifdef INET6
case AF_INET6: /* FALLTHROUGH */
#endif
case AF_INET:
mss = ifp->if_mtu;
break;
#ifdef INET6
case AF_INET6:
mss = IN6_LINKMTU(ifp);
break;
#endif
}
if (tcp_mss_ifmtu == 0)
switch (af) {
#ifdef INET6
case AF_INET6: /* FALLTHROUGH */
#endif
case AF_INET:
mss = uimax(in_maxmtu, mss);
break;
#ifdef INET6
case AF_INET6:
mss = uimax(in6_maxmtu, mss);
break;
#endif
}
switch (af) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.c,v 1.244 2020/03/09 21:20:56 roy Exp $ */
/* $NetBSD: icmp6.c,v 1.245 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@ -62,9 +62,10 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.244 2020/03/09 21:20:56 roy Exp $");
__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.245 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#include "opt_inet.h"
#include "opt_ipsec.h"
#endif
@ -790,33 +791,24 @@ _icmp6_input(struct mbuf *m, int off, int proto)
case ND_ROUTER_SOLICIT:
icmp6_ifstat_inc(rcvif, ifs6_in_routersolicit);
if (code != 0)
goto badcode;
if (icmp6len < sizeof(struct nd_router_solicit))
goto badlen;
if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) {
/* give up local */
nd6_rs_input(m, off, icmp6len);
m = NULL;
goto freeit;
}
nd6_rs_input(n, off, icmp6len);
/* m stays. */
break;
/* FALLTHROUGH */
case ND_ROUTER_ADVERT:
icmp6_ifstat_inc(rcvif, ifs6_in_routeradvert);
if (icmp6->icmp6_type == ND_ROUTER_ADVERT)
icmp6_ifstat_inc(rcvif, ifs6_in_routeradvert);
if (code != 0)
goto badcode;
if (icmp6len < sizeof(struct nd_router_advert))
if ((icmp6->icmp6_type == ND_ROUTER_SOLICIT &&
icmp6len < sizeof(struct nd_router_solicit)) ||
(icmp6->icmp6_type == ND_ROUTER_ADVERT &&
icmp6len < sizeof(struct nd_router_advert)))
goto badlen;
if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) {
/* give up local */
nd6_ra_input(m, off, icmp6len);
nd6_rtr_cache(m, off, icmp6len, icmp6->icmp6_type);
m = NULL;
goto freeit;
}
nd6_ra_input(n, off, icmp6len);
nd6_rtr_cache(n, off, icmp6len, icmp6->icmp6_type);
/* m stays. */
break;
@ -1160,7 +1152,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
if (rt && (rt->rt_flags & RTF_HOST) &&
!(rt->rt_rmx.rmx_locks & RTV_MTU) &&
(rt->rt_rmx.rmx_mtu > mtu || rt->rt_rmx.rmx_mtu == 0)) {
if (mtu < IN6_LINKMTU(rt->rt_ifp)) {
if (mtu < rt->rt_ifp->if_mtu) {
ICMP6_STATINC(ICMP6_STAT_PMTUCHG);
rt->rt_rmx.rmx_mtu = mtu;
}
@ -2868,6 +2860,7 @@ icmp6_redirect_timeout(struct rtentry *rt, struct rttimer *r)
}
}
#ifdef COMPAT_90
/*
* sysctl helper routine for the net.inet6.icmp6.nd6 nodes. silly?
*/
@ -2885,6 +2878,7 @@ sysctl_net_inet6_icmp6_nd6(SYSCTLFN_ARGS)
/*XXXUNCONST*/
__UNCONST(newp), newlen));
}
#endif
static int
sysctl_net_inet6_icmp6_stats(SYSCTLFN_ARGS)
@ -3062,20 +3056,22 @@ sysctl_net_inet6_icmp6_setup(struct sysctllog **clog)
NULL, 0, &nd6_debug, 0,
CTL_NET, PF_INET6, IPPROTO_ICMPV6,
ICMPV6CTL_ND6_DEBUG, CTL_EOL);
#ifdef COMPAT_90
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "nd6_drlist",
SYSCTL_DESCR("Default router list"),
sysctl_net_inet6_icmp6_nd6, 0, NULL, 0,
CTL_NET, PF_INET6, IPPROTO_ICMPV6,
ICMPV6CTL_ND6_DRLIST, CTL_EOL);
OICMPV6CTL_ND6_DRLIST, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "nd6_prlist",
SYSCTL_DESCR("Prefix list"),
sysctl_net_inet6_icmp6_nd6, 0, NULL, 0,
CTL_NET, PF_INET6, IPPROTO_ICMPV6,
ICMPV6CTL_ND6_PRLIST, CTL_EOL);
OICMPV6CTL_ND6_PRLIST, CTL_EOL);
#endif
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxqueuelen",

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.c,v 1.277 2020/01/20 18:38:22 thorpej Exp $ */
/* $NetBSD: in6.c,v 1.278 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.277 2020/01/20 18:38:22 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.278 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -108,6 +108,9 @@ __KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.277 2020/01/20 18:38:22 thorpej Exp $");
#ifdef COMPAT_50
#include <compat/netinet6/in6_var.h>
#endif
#ifdef COMPAT_90
#include <compat/netinet6/nd6.h>
#endif
MALLOC_DEFINE(M_IP6OPT, "ip6_options", "IPv6 options");
@ -407,36 +410,32 @@ in6_control1(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
return EOPNOTSUPP;
switch (cmd) {
case SIOCSNDFLUSH_IN6:
case SIOCSPFXFLUSH_IN6:
case SIOCSRTRFLUSH_IN6:
case SIOCSDEFIFACE_IN6:
#ifdef OSIOCSIFINFO_IN6_90
case OSIOCSIFINFO_FLAGS_90:
case OSIOCSIFINFO_IN6_90:
case OSIOCSDEFIFACE_IN6:
case OSIOCSNDFLUSH_IN6:
case OSIOCSPFXFLUSH_IN6:
case OSIOCSRTRFLUSH_IN6:
#endif
case SIOCSIFINFO_FLAGS:
case SIOCSIFINFO_IN6:
/* Privileged. */
/* FALLTHROUGH */
#ifdef OSIOCGIFINFO_IN6
case OSIOCGIFINFO_IN6:
#endif
#ifdef OSIOCGIFINFO_IN6_90
case OSIOCGDRLST_IN6:
case OSIOCGPRLST_IN6:
case OSIOCGIFINFO_IN6_90:
case OSIOCGDEFIFACE_IN6:
#endif
case SIOCGIFINFO_IN6:
case SIOCGDRLST_IN6:
case SIOCGPRLST_IN6:
case SIOCGNBRINFO_IN6:
case SIOCGDEFIFACE_IN6:
return nd6_ioctl(cmd, data, ifp);
}
switch (cmd) {
case SIOCSIFPREFIX_IN6:
case SIOCDIFPREFIX_IN6:
case SIOCAIFPREFIX_IN6:
case SIOCCIFPREFIX_IN6:
case SIOCSGIFPREFIX_IN6:
case SIOCGIFPREFIX_IN6:
log(LOG_NOTICE,
"prefix ioctls are now invalidated. "
"please use ifconfig.\n");
return EOPNOTSUPP;
}
switch (cmd) {
case SIOCALIFADDR:
case SIOCDLIFADDR:
@ -479,9 +478,6 @@ in6_control1(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
case SIOCGIFPSRCADDR_IN6:
case SIOCGIFPDSTADDR_IN6:
case SIOCGIFAFLAG_IN6:
case SIOCSNDFLUSH_IN6:
case SIOCSPFXFLUSH_IN6:
case SIOCSRTRFLUSH_IN6:
case SIOCGIFALIFETIME_IN6:
#ifdef OSIOCGIFALIFETIME_IN6
case OSIOCGIFALIFETIME_IN6:
@ -738,10 +734,14 @@ in6_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
int error, s;
switch (cmd) {
case SIOCSNDFLUSH_IN6:
case SIOCSPFXFLUSH_IN6:
case SIOCSRTRFLUSH_IN6:
case SIOCSDEFIFACE_IN6:
#ifdef OSIOCSIFINFO_IN6_90
case OSIOCSIFINFO_FLAGS_90:
case OSIOCSIFINFO_IN6_90:
case OSIOCSDEFIFACE_IN6:
case OSIOCSNDFLUSH_IN6:
case OSIOCSPFXFLUSH_IN6:
case OSIOCSRTRFLUSH_IN6:
#endif
case SIOCSIFINFO_FLAGS:
case SIOCSIFINFO_IN6:
@ -1200,26 +1200,6 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra,
/* set prefix mask */
if (ifra->ifra_prefixmask.sin6_len) {
if (ia->ia_prefixmask.sin6_len) {
/*
* We prohibit changing the prefix length of an
* existing autoconf address, because the operation
* would confuse prefix management.
*/
if (ia->ia6_ndpr != NULL &&
in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) !=
plen)
{
nd6log(LOG_INFO, "the prefix length of an"
" existing (%s) autoconf address should"
" not be changed\n",
IN6_PRINT(ip6buf,
&ia->ia_addr.sin6_addr));
error = EINVAL;
if (hostIsNew)
free(ia, M_IFADDR);
return error;
}
if (!IN6_ARE_ADDR_EQUAL(&ia->ia_prefixmask.sin6_addr,
&ifra->ifra_prefixmask.sin6_addr))
in6_ifremprefix(ia);
@ -1461,26 +1441,6 @@ in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
ifa_remove(ifp, &ia->ia_ifa);
/* Assume ifa_remove called pserialize_perform and psref_destroy */
mutex_exit(&in6_ifaddr_lock);
/*
* Release the reference to the ND prefix.
*/
if (ia->ia6_ndpr != NULL) {
nd6_prefix_unref(ia->ia6_ndpr);
ia->ia6_ndpr = NULL;
}
/*
* Also, if the address being removed is autoconf'ed, call
* nd6_pfxlist_onlink_check() since the release might affect the status of
* other (detached) addresses.
*/
if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
ND6_WLOCK();
nd6_pfxlist_onlink_check();
ND6_UNLOCK();
}
IN6_ADDRLIST_ENTRY_DESTROY(ia);
/*
@ -2239,11 +2199,6 @@ in6_if_link_up(struct ifnet *ifp)
}
pserialize_read_exit(s);
curlwp_bindx(bound);
/* Restore any detached prefixes */
ND6_WLOCK();
nd6_pfxlist_onlink_check();
ND6_UNLOCK();
}
void
@ -2270,11 +2225,6 @@ in6_if_link_down(struct ifnet *ifp)
int s, bound;
char ip6buf[INET6_ADDRSTRLEN];
/* Any prefixes on this interface should be detached as well */
ND6_WLOCK();
nd6_pfxlist_onlink_check();
ND6_UNLOCK();
bound = curlwp_bind();
s = pserialize_read_enter();
IFADDR_READER_FOREACH(ifa, ifp) {
@ -2336,31 +2286,6 @@ in6_if_link_state_change(struct ifnet *ifp, int link_state)
}
}
/*
* Calculate max IPv6 MTU through all the interfaces and store it
* to in6_maxmtu.
*/
void
in6_setmaxmtu(void)
{
unsigned long maxmtu = 0;
struct ifnet *ifp;
int s;
s = pserialize_read_enter();
IFNET_READER_FOREACH(ifp) {
/* this function can be called during ifnet initialization */
if (!ifp->if_afdata[AF_INET6])
continue;
if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
IN6_LINKMTU(ifp) > maxmtu)
maxmtu = IN6_LINKMTU(ifp);
}
pserialize_read_exit(s);
if (maxmtu) /* update only when maxmtu is positive */
in6_maxmtu = maxmtu;
}
int
in6_tunnel_validate(const struct ip6_hdr *ip6, const struct in6_addr *src,
const struct in6_addr *dst)
@ -2379,46 +2304,6 @@ in6_tunnel_validate(const struct ip6_hdr *ip6, const struct in6_addr *src,
return sizeof(*src) + sizeof(*dst);
}
/*
* Provide the length of interface identifiers to be used for the link attached
* to the given interface. The length should be defined in "IPv6 over
* xxx-link" document. Note that address architecture might also define
* the length for a particular set of address prefixes, regardless of the
* link type. As clarified in rfc2462bis, those two definitions should be
* consistent, and those really are as of August 2004.
*/
int
in6_if2idlen(struct ifnet *ifp)
{
switch (ifp->if_type) {
case IFT_ETHER: /* RFC2464 */
case IFT_PROPVIRTUAL: /* XXX: no RFC. treat it as ether */
case IFT_L2VLAN: /* ditto */
case IFT_IEEE80211: /* ditto */
case IFT_PPP: /* RFC2472 */
case IFT_ARCNET: /* RFC2497 */
case IFT_FRELAY: /* RFC2590 */
case IFT_IEEE1394: /* RFC3146 */
case IFT_GIF: /* draft-ietf-v6ops-mech-v2-07 */
case IFT_LOOP: /* XXX: is this really correct? */
return 64;
default:
/*
* Unknown link type:
* It might be controversial to use the today's common constant
* of 64 for these cases unconditionally. For full compliance,
* we should return an error in this case. On the other hand,
* if we simply miss the standard for the link type or a new
* standard is defined for a new link type, the IFID length
* is very likely to be the common constant. As a compromise,
* we always use the constant, but make an explicit notice
* indicating the "unknown" case.
*/
printf("in6_if2idlen: unknown link type (%d)\n", ifp->if_type);
return 64;
}
}
#define IN6_LLTBL_DEFAULT_HSIZE 32
#define IN6_LLTBL_HASH(k, h) \
(((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1))
@ -2713,9 +2598,6 @@ in6_domifattach(struct ifnet *ifp)
ext->nd_ifinfo = nd6_ifattach(ifp);
ext->scope6_id = scope6_ifattach(ifp);
ext->nprefixes = 0;
ext->ndefrouters = 0;
ext->lltable = in6_lltattach(ifp);
return ext;

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.h,v 1.98 2019/11/01 04:28:14 knakahara Exp $ */
/* $NetBSD: in6.h,v 1.99 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
/*
@ -506,7 +506,7 @@ struct ip6_mtuinfo {
#define IPV6CTL_MAXFRAGPACKETS 9 /* max packets reassembly queue */
#define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */
#define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimum logging interval */
#define IPV6CTL_ACCEPT_RTADV 12
/* 12 was IPV6CTL_ACCEPT_RTADV */
#define IPV6CTL_KEEPFAITH 13
#define IPV6CTL_LOG_INTERVAL 14
#define IPV6CTL_HDRNESTLIMIT 15
@ -516,7 +516,7 @@ struct ip6_mtuinfo {
#define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */
#define IPV6CTL_KAME_VERSION 20
#define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */
#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */
/* 22 was IPV6CTL_RR_PRUNE */
/* 23: reserved */
#define IPV6CTL_V6ONLY 24
/* 25 to 27: reserved */
@ -532,10 +532,8 @@ struct ip6_mtuinfo {
/* 40: reserved */
#define IPV6CTL_MAXFRAGS 41 /* max fragments */
#define IPV6CTL_IFQ 42 /* IPv6 packet input queue */
#define IPV6CTL_RTADV_MAXROUTES 43 /* maximum number of routes */
/* via router advertisement */
#define IPV6CTL_RTADV_NUMROUTES 44 /* current number of routes */
/* via router advertisement */
/* 43 was IPV6CTL_RTADV_MAXROUTES */
/* 44 was IPV6CTL_RTADV_NUMROUTES */
#define IPV6CTL_GIF_PMTU 45 /* gif(4) Path MTU setting */
#define IPV6CTL_IPSEC_HLIM 46 /* default HLIM for ipsecif encap packet */
#define IPV6CTL_IPSEC_PMTU 47 /* ipsecif(4) Path MTU setting */

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_ifattach.c,v 1.118 2020/01/20 18:38:22 thorpej Exp $ */
/* $NetBSD: in6_ifattach.c,v 1.119 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.118 2020/01/20 18:38:22 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.119 2020/06/12 11:04:45 roy Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -59,24 +59,15 @@ __KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.118 2020/01/20 18:38:22 thorpej E
#include <netinet6/ip6_mroute.h>
#include <netinet6/scope6_var.h>
unsigned long in6_maxmtu = 0;
int ip6_auto_linklocal = 1; /* enable by default */
static callout_t in6_tmpaddrtimer_ch;
#if 0
static int get_hostid_ifid(struct ifnet *, struct in6_addr *);
#endif
static int get_rand_ifid(struct in6_addr *);
static int generate_tmp_ifid(u_int8_t *, const u_int8_t *, u_int8_t *);
static int get_ifid(struct ifnet *, struct ifnet *, struct in6_addr *);
static int in6_ifattach_linklocal(struct ifnet *, struct ifnet *);
static int in6_ifattach_loopback(struct ifnet *);
static void in6_tmpaddrtimer(void *);
#define EUI64_GBIT 0x01
#define EUI64_UBIT 0x02
#define EUI64_TO_IFID(in6) do {(in6)->s6_addr[8] ^= EUI64_UBIT; } while (/*CONSTCOND*/ 0)
@ -88,8 +79,6 @@ static void in6_tmpaddrtimer(void *);
#define IFID_LOCAL(in6) (!EUI64_LOCAL(in6))
#define IFID_UNIVERSAL(in6) (!EUI64_UNIVERSAL(in6))
#define GEN_TEMPID_RETRY_MAX 5
#if 0
/*
* Generate a last-resort interface identifier from hostid.
@ -171,146 +160,6 @@ get_rand_ifid(struct in6_addr *in6) /* upper 64bits are preserved */
return 0;
}
static int
generate_tmp_ifid(u_int8_t *seed0, const u_int8_t *seed1, u_int8_t *ret)
{
MD5_CTX ctxt;
u_int8_t seed[16], digest[16], nullbuf[8];
/*
* interface ID for subnet anycast addresses.
* XXX: we assume the unicast address range that requires IDs
* in EUI-64 format.
*/
static const uint8_t anycast_id[8] = { 0xfd, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80 };
static const uint8_t isatap_id[4] = { 0x00, 0x00, 0x5e, 0xfe };
int badid, retry = 0;
/* If there's no hisotry, start with a random seed. */
memset(nullbuf, 0, sizeof(nullbuf));
if (memcmp(nullbuf, seed0, sizeof(nullbuf)) == 0) {
cprng_fast(seed, sizeof(seed));
} else
memcpy(seed, seed0, 8);
/* copy the right-most 64-bits of the given address */
/* XXX assumption on the size of IFID */
memcpy(&seed[8], seed1, 8);
again:
/* for debugging purposes only */
#if 0
{
int i;
printf("generate_tmp_ifid: new randomized ID from: ");
for (i = 0; i < 16; i++)
printf("%02x", seed[i]);
printf(" ");
}
#endif
/* generate 16 bytes of pseudo-random value. */
memset(&ctxt, 0, sizeof(ctxt));
MD5Init(&ctxt);
MD5Update(&ctxt, seed, sizeof(seed));
MD5Final(digest, &ctxt);
/*
* draft-ietf-ipngwg-temp-addresses-v2-00.txt 3.2.1. (3)
* Take the left-most 64-bits of the MD5 digest and set bit 6 (the
* left-most bit is numbered 0) to zero.
*/
memcpy(ret, digest, 8);
ret[0] &= ~EUI64_UBIT;
/*
* Reject inappropriate identifiers according to
* draft-ietf-ipngwg-temp-addresses-v2-00.txt 3.2.1. (4)
* At this moment, we reject following cases:
* - all 0 identifier
* - identifiers that conflict with reserved subnet anycast addresses,
* which are defined in RFC 2526.
* - identifiers that conflict with ISATAP addresses
* - identifiers used in our own addresses
*/
badid = 0;
if (memcmp(nullbuf, ret, sizeof(nullbuf)) == 0)
badid = 1;
else if (memcmp(anycast_id, ret, 7) == 0 &&
(anycast_id[7] & ret[7]) == anycast_id[7]) {
badid = 1;
} else if (memcmp(isatap_id, ret, sizeof(isatap_id)) == 0)
badid = 1;
else {
struct in6_ifaddr *ia;
int s = pserialize_read_enter();
IN6_ADDRLIST_READER_FOREACH(ia) {
if (!memcmp(&ia->ia_addr.sin6_addr.s6_addr[8],
ret, 8)) {
badid = 1;
break;
}
}
pserialize_read_exit(s);
}
/*
* In the event that an unacceptable identifier has been generated,
* restart the process, using the right-most 64 bits of the MD5 digest
* obtained in place of the history value.
*/
if (badid) {
/* for debugging purposes only */
#if 0
{
int i;
printf("unacceptable random ID: ");
for (i = 0; i < 16; i++)
printf("%02x", digest[i]);
printf("\n");
}
#endif
if (++retry < GEN_TEMPID_RETRY_MAX) {
memcpy(seed, &digest[8], 8);
goto again;
} else {
/*
* We're so unlucky. Give up for now, and return
* all 0 IDs to tell the caller not to make a
* temporary address.
*/
nd6log(LOG_NOTICE, "never found a good ID\n");
memset(ret, 0, 8);
}
}
/*
* draft-ietf-ipngwg-temp-addresses-v2-00.txt 3.2.1. (6)
* Take the rightmost 64-bits of the MD5 digest and save them in
* stable storage as the history value to be used in the next
* iteration of the algorithm.
*/
memcpy(seed0, &digest[8], 8);
/* for debugging purposes only */
#if 0
{
int i;
printf("to: ");
for (i = 0; i < 16; i++)
printf("%02x", digest[i]);
printf("\n");
}
#endif
return 0;
}
/*
* Get interface identifier for the specified interface.
*
@ -816,87 +665,4 @@ in6_ifdetach(struct ifnet *ifp)
/* remove neighbor management table */
nd6_purge(ifp, NULL);
nd6_assert_purged(ifp);
}
int
in6_get_tmpifid(struct ifnet *ifp, u_int8_t *retbuf,
const u_int8_t *baseid, int generate)
{
u_int8_t nullbuf[8];
struct nd_ifinfo *ndi = ND_IFINFO(ifp);
memset(nullbuf, 0, sizeof(nullbuf));
if (memcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) {
/* we've never created a random ID. Create a new one. */
generate = 1;
}
if (generate) {
memcpy(ndi->randomseed1, baseid, sizeof(ndi->randomseed1));
/* generate_tmp_ifid will update seedn and buf */
(void)generate_tmp_ifid(ndi->randomseed0, ndi->randomseed1,
ndi->randomid);
}
memcpy(retbuf, ndi->randomid, 8);
if (generate && memcmp(retbuf, nullbuf, sizeof(nullbuf)) == 0) {
/* generate_tmp_ifid could not found a good ID. */
return -1;
}
return 0;
}
void
in6_tmpaddrtimer_init(void)
{
/* timer for regeneration of temporary addresses randomize ID */
callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE);
callout_setfunc(&in6_tmpaddrtimer_ch, in6_tmpaddrtimer, NULL);
in6_tmpaddrtimer_schedule();
}
void
in6_tmpaddrtimer_schedule(void)
{
callout_schedule(&in6_tmpaddrtimer_ch,
(ip6_temp_preferred_lifetime - ip6_desync_factor -
ip6_temp_regen_advance) * hz);
}
static void
in6_tmpaddrtimer(void *ignored_arg)
{
struct nd_ifinfo *ndi;
u_int8_t nullbuf[8];
struct ifnet *ifp;
int s;
/* XXX NOMPSAFE still need softnet_lock */
mutex_enter(softnet_lock);
KERNEL_LOCK(1, NULL);
in6_tmpaddrtimer_schedule();
memset(nullbuf, 0, sizeof(nullbuf));
s = pserialize_read_enter();
IFNET_READER_FOREACH(ifp) {
ndi = ND_IFINFO(ifp);
if (memcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
/*
* We've been generating a random ID on this interface.
* Create a new one.
*/
(void)generate_tmp_ifid(ndi->randomseed0,
ndi->randomseed1, ndi->randomid);
}
}
pserialize_read_exit(s);
KERNEL_UNLOCK_ONE(NULL);
mutex_exit(softnet_lock);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_proto.c,v 1.127 2020/04/24 17:36:55 jakllsch Exp $ */
/* $NetBSD: in6_proto.c,v 1.128 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.127 2020/04/24 17:36:55 jakllsch Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.128 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
@ -541,7 +541,6 @@ int ip6_forwarding = IPV6FORWARDING; /* act as router? */
int ip6_sendredirects = 1;
int ip6_defhlim = IPV6_DEFHLIM;
int ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
int ip6_accept_rtadv = 0;
int ip6_maxfragpackets = 200;
int ip6_maxfrags = 200;
int ip6_log_interval = 5;
@ -549,24 +548,13 @@ int ip6_hdrnestlimit = 15;
int ip6_dad_count = 1; /* DupAddrDetectionTransmits */
int ip6_auto_flowlabel = 1;
int ip6_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */
int ip6_rr_prune = 5; /* router renumbering prefix
* walk list every 5 sec. */
int ip6_mcast_pmtu = 0; /* enable pMTU discovery for multicast? */
int ip6_v6only = 1;
int ip6_neighborgcthresh = 2048; /* Threshold # of NDP entries for GC */
int ip6_maxifprefixes = 16; /* Max acceptable prefixes via RA per IF */
int ip6_maxifdefrouters = 16; /* Max acceptable def routers via RA */
int ip6_maxdynroutes = 4096; /* Max # of routes created via redirect */
int ip6_keepfaith = 0;
time_t ip6_log_time = 0;
int ip6_rtadv_maxroutes = 100; /* (arbitrary) initial maximum number of
* routes via rtadv expected to be
* significantly larger than common use.
* if you need to count: 3 extra initial
* routes, plus 1 per interface after the
* first one, then one per non-linklocal
* prefix */
/* icmp6 */
int pmtu_expire = 60*10;

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_var.h,v 1.102 2019/10/18 04:33:53 ozaki-r Exp $ */
/* $NetBSD: in6_var.h,v 1.103 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */
/*
@ -90,14 +90,12 @@ struct in6_addrlifetime {
};
struct lltable;
struct nd_ifinfo;
struct nd_kifinfo;
struct in6_ifextra {
struct in6_ifstat *in6_ifstat;
struct icmp6_ifstat *icmp6_ifstat;
struct nd_ifinfo *nd_ifinfo;
struct nd_kifinfo *nd_ifinfo;
struct scope6_id *scope6_id;
int nprefixes;
int ndefrouters;
struct lltable *lltable;
};
@ -124,9 +122,6 @@ struct in6_ifaddr {
*/
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;
@ -310,95 +305,6 @@ struct in6_aliasreq {
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).
* Note: We originally intended to use prf_ra{} only within in6_prflags{}, but
* it was (probably unintentionally) used in nd6.h as well. Since C++ does
* not allow such a reference, prf_ra{} was then moved outside. In general,
* however, this structure should not be used directly.
*/
struct prf_ra {
u_int32_t onlink : 1;
u_int32_t autonomous : 1;
u_int32_t router : 1;
u_int32_t reserved : 5;
};
struct in6_prflags {
struct prf_ra prf_ra;
u_char prf_reserved1;
u_short prf_reserved2;
/* want to put this on 4byte offset */
struct prf_rr {
u_int32_t decrvalid : 1;
u_int32_t decrprefd : 1;
u_int32_t 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_int32_t onlink : 1;
u_int32_t autonomous : 1;
u_int32_t 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
@ -443,16 +349,18 @@ struct in6_rrenumreq {
#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
#define SIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist)
#define SIOCGPRLST_IN6 _IOWR('i', 75, struct in6_oprlist)
#ifdef _KERNEL
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
#endif
#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
/*
* 74 was SIOCGDRLST_IN6
* 75 was SIOCGPRLST_IN6
* 76 was OSIOCGIFINFO_IN6
* 77 was SIOCSNDFLUSH_IN6
*/
#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)
/* 81 was old SIOCGIFALIFETIME_IN6 */
/*
* 79 was SIOCSPFXFLUSH_IN6
* 80 was SIOCSRTRFLUSH_IN6
* 81 was SIOCGIFALIFETIME_IN6
*/
#if 0
/* withdrawn - do not reuse number 82 */
#define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq)
@ -460,25 +368,26 @@ struct in6_rrenumreq {
#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 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 */
/*
* 85 was SIOCSDEFIFACE_IN6
* 86 was SIOCGDEFIFACE_IN6
* 87 was OSIOCSIFINFO_FLAGS
* 100 was SIOCSIFPREFIX_IN6
* 101 was SIOCGIFPREFIX_IN6
* 102 was SIOCDIFPREFIX_IN6
* 103 was SIOCAIFPREFIX_IN6
* 104 was SIOCCIFPREFIX_IN6
* 105 was SIOCSGIFPREFIX_IN6
*/
#define SIOCGIFALIFETIME_IN6 _IOWR('i', 106, struct in6_ifreq)
#define SIOCAIFADDR_IN6 _IOW('i', 107, struct in6_aliasreq)
#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq)
#define SIOCSIFINFO_IN6 _IOWR('i', 109, struct in6_ndireq)
/* 108 was OSIOCGIFINFO_IN6_90
* 109 was OSIOCSIFINFO_IN6_90 */
#define SIOCSIFPHYADDR_IN6 _IOW('i', 110, struct in6_aliasreq)
/* 110 - 112 are defined in net/if_pppoe.h */
#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)
/* XXX: Someone decided to switch to 'u' here for unknown reasons! */
#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \
@ -582,7 +491,6 @@ do { \
extern const struct in6_addr zeroin6_addr;
extern const u_char inet6ctlerrmap[];
extern unsigned long in6_maxmtu;
extern bool in6_present;
/*
@ -679,7 +587,6 @@ do { \
#endif
void in6_init(void);
void in6_tmpaddrtimer_init(void);
void in6_multi_lock(int);
void in6_multi_unlock(void);
@ -702,8 +609,6 @@ 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_setmaxmtu (void);
int in6_if2idlen (struct ifnet *);
void *in6_domifattach(struct ifnet *);
void in6_domifdetach(struct ifnet *, void *);
void in6_ifremlocal(struct ifaddr *);
@ -721,7 +626,6 @@ struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_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);
void in6_purgeprefix(struct ifnet *);
void in6_purge_mcast_references(struct in6_multi *);
int ip6flow_fastforward(struct mbuf **); /* IPv6 fast forward routine */
@ -734,8 +638,6 @@ struct in6pcb;
void in6_sysctl_multicast_setup(struct sysctllog **);
void in6_tmpaddrtimer_schedule(void);
#endif /* _KERNEL */
#endif /* !_NETINET6_IN6_VAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_forward.c,v 1.98 2019/11/01 04:23:21 knakahara Exp $ */
/* $NetBSD: ip6_forward.c,v 1.99 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.98 2019/11/01 04:23:21 knakahara Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.99 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
@ -291,14 +291,11 @@ ip6_forward(struct mbuf *m, int srcrt)
goto drop;
}
if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
if (m->m_pkthdr.len > rt->rt_ifp->if_mtu) {
in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
if (mcopy) {
u_long mtu;
mtu = IN6_LINKMTU(rt->rt_ifp);
icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
}
if (mcopy)
icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0,
rt->rt_ifp->if_mtu);
goto drop;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_input.c,v 1.215 2019/11/12 08:11:55 maxv Exp $ */
/* $NetBSD: ip6_input.c,v 1.216 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.215 2019/11/12 08:11:55 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.216 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
@ -182,9 +182,7 @@ ip6_init(void)
addrsel_policy_init();
nd6_init();
frag6_init();
ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR;
in6_tmpaddrtimer_init();
#ifdef GATEWAY
ip6flow_init(ip6_hashsize);
#endif
@ -1539,30 +1537,6 @@ sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS)
return (NETSTAT_SYSCTL(ip6stat_percpu, IP6_NSTATS));
}
static int
sysctl_net_inet6_ip6_temppltime(SYSCTLFN_ARGS)
{
int error;
uint32_t pltime;
struct sysctlnode node;
node = *rnode;
node.sysctl_data = &pltime;
pltime = ip6_temp_preferred_lifetime;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
return error;
if (pltime <= (MAX_TEMP_DESYNC_FACTOR + TEMPADDR_REGEN_ADVANCE))
return EINVAL;
ip6_temp_preferred_lifetime = pltime;
in6_tmpaddrtimer_schedule();
return 0;
}
static void
sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
{
@ -1609,27 +1583,6 @@ sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
NULL, 0, &ip6_maxfragpackets, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_MAXFRAGPACKETS, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "accept_rtadv",
SYSCTL_DESCR("Accept router advertisements"),
NULL, 0, &ip6_accept_rtadv, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_ACCEPT_RTADV, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "rtadv_maxroutes",
SYSCTL_DESCR("Maximum number of routes accepted via router advertisements"),
NULL, 0, &ip6_rtadv_maxroutes, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_RTADV_MAXROUTES, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_INT, "rtadv_numroutes",
SYSCTL_DESCR("Current number of routes accepted via router advertisements"),
NULL, 0, &nd6_numroutes, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_RTADV_NUMROUTES, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "keepfaith",
@ -1689,12 +1642,6 @@ sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
NULL, 0, &ip6_use_deprecated, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_USE_DEPRECATED, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "rr_prune", NULL,
NULL, 0, &ip6_rr_prune, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_RR_PRUNE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT
#ifndef INET6_BINDV6ONLY
@ -1755,13 +1702,6 @@ sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
sysctl_net_inet6_addrctlpolicy, 0, NULL, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
IPV6CTL_ADDRCTLPOLICY, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "use_tempaddr",
SYSCTL_DESCR("Use temporary address"),
NULL, 0, &ip6_use_tempaddr, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "prefer_tempaddr",
@ -1770,20 +1710,6 @@ sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
NULL, 0, &ip6_prefer_tempaddr, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "temppltime",
SYSCTL_DESCR("preferred lifetime of a temporary address"),
sysctl_net_inet6_ip6_temppltime, 0, NULL, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "tempvltime",
SYSCTL_DESCR("valid lifetime of a temporary address"),
NULL, 0, &ip6_temp_valid_lifetime, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxfrags",
@ -1846,22 +1772,6 @@ sysctl_net_inet6_ip6_setup(struct sysctllog **clog)
NULL, 1, &ip6_neighborgcthresh, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxifprefixes",
SYSCTL_DESCR("Maximum number of prefixes created by"
" route advertisement per interface"),
NULL, 1, &ip6_maxifprefixes, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxifdefrouters",
SYSCTL_DESCR("Maximum number of default routers created"
" by route advertisement per interface"),
NULL, 1, &ip6_maxifdefrouters, 0,
CTL_NET, PF_INET6, IPPROTO_IPV6,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxdynroutes",

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_mroute.c,v 1.131 2020/01/03 08:53:14 maxv Exp $ */
/* $NetBSD: ip6_mroute.c,v 1.132 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $ */
/*
@ -117,7 +117,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.131 2020/01/03 08:53:14 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.132 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -1530,7 +1530,6 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
static struct route ro;
bool ingroup;
struct sockaddr_in6 dst6;
u_long linkmtu;
s = splsoftnet();
@ -1596,8 +1595,7 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
* Put the packet into the sending queue of the outgoing interface
* if it would fit in the MTU of the interface.
*/
linkmtu = IN6_LINKMTU(ifp);
if (mb_copy->m_pkthdr.len <= linkmtu || linkmtu < IPV6_MMTU) {
if (mb_copy->m_pkthdr.len <= ifp->if_mtu || ifp->if_mtu < IPV6_MMTU) {
error = ip6_if_output(ifp, ifp, mb_copy, &dst6, NULL);
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
@ -1611,7 +1609,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
* a DDoS to a router.
*/
if (ip6_mcast_pmtu) {
icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, linkmtu);
icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0,
ifp->if_mtu);
} else {
/* simply discard the packet */
#ifdef MRT6DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_output.c,v 1.222 2019/11/13 02:51:22 ozaki-r Exp $ */
/* $NetBSD: ip6_output.c,v 1.223 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.222 2019/11/13 02:51:22 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.223 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -794,7 +794,7 @@ ip6_output(
error = EMSGSIZE;
goto bad;
}
if (dontfrag && (!tso && tlen > IN6_LINKMTU(ifp))) { /* case 2-b */
if (dontfrag && (!tso && tlen > ifp->if_mtu)) { /* case 2-b */
/*
* Even if the DONTFRAG option is specified, we cannot send the
* packet when the data length is larger than the MTU of the
@ -1233,14 +1233,11 @@ ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup,
int error = 0;
if (rt != NULL) {
u_int32_t ifmtu;
if (ifp == NULL)
ifp = rt->rt_ifp;
ifmtu = IN6_LINKMTU(ifp);
mtu = rt->rt_rmx.rmx_mtu;
if (mtu == 0)
mtu = ifmtu;
mtu = ifp->if_mtu;
else if (mtu < IPV6_MMTU) {
/*
* RFC2460 section 5, last paragraph:
@ -1252,7 +1249,7 @@ ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup,
*/
alwaysfrag = 1;
mtu = IPV6_MMTU;
} else if (mtu > ifmtu) {
} else if (mtu > ifp->if_mtu) {
/*
* The MTU on the route is larger than the MTU on
* the interface! This shouldn't happen, unless the
@ -1261,12 +1258,12 @@ ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup,
* route to match the interface MTU (as long as the
* field isn't locked).
*/
mtu = ifmtu;
mtu = ifp->if_mtu;
if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
rt->rt_rmx.rmx_mtu = mtu;
}
} else if (ifp) {
mtu = IN6_LINKMTU(ifp);
mtu = ifp->if_mtu;
} else
error = EHOSTUNREACH; /* XXX */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_var.h,v 1.82 2019/05/13 07:47:59 ozaki-r Exp $ */
/* $NetBSD: ip6_var.h,v 1.83 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@ -235,13 +235,9 @@ extern int ip6_defmcasthlim; /* default multicast hop limit */
extern int ip6_forwarding; /* act as router? */
extern int ip6_sendredirect; /* send ICMPv6 redirect? */
extern int ip6_use_deprecated; /* allow deprecated addr as source */
extern int ip6_rr_prune; /* router renumbering prefix
* walk list every 5 sec. */
extern int ip6_mcast_pmtu; /* enable pMTU discovery for multicast? */
extern int ip6_v6only;
extern int ip6_neighborgcthresh; /* Threshold # of NDP entries for GC */
extern int ip6_maxifprefixes; /* Max acceptable prefixes via RA per IF */
extern int ip6_maxifdefrouters; /* Max acceptable def routers via RA */
extern int ip6_maxdynroutes; /* Max # of routes created via redirect */
@ -249,8 +245,6 @@ extern struct socket *ip6_mrouter; /* multicast routing daemon */
extern int ip6_sendredirects; /* send IP redirects when forwarding? */
extern int ip6_maxfragpackets; /* Maximum packets in reassembly queue */
extern int ip6_maxfrags; /* Maximum fragments in reassembly queue */
extern int ip6_accept_rtadv; /* Acts as a host not a router */
extern int ip6_rtadv_maxroutes; /* maximum number of routes via rtadv */
extern int ip6_keepfaith; /* Firewall Aided Internet Translator */
extern int ip6_log_interval;
extern time_t ip6_log_time;
@ -265,7 +259,6 @@ extern int ip6_anonportmax; /* maximum ephemeral port */
extern int ip6_lowportmin; /* minimum reserved port */
extern int ip6_lowportmax; /* maximum reserved port */
extern int ip6_use_tempaddr; /* whether to use temporary addresses. */
extern int ip6_prefer_tempaddr; /* whether to prefer temporary addresses
in the source address selection */
extern int ip6_use_defzone; /* whether to use the default scope zone

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: nd6.h,v 1.88 2019/09/25 09:52:32 ozaki-r Exp $ */
/* $NetBSD: nd6.h,v 1.89 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@ -49,60 +49,34 @@
#define ND6_LLINFO_PERMANENT(n) (((n)->ln_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 */
uint8_t chlim; /* CurHopLimit */
uint32_t basereachable; /* BaseReachableTime */
uint32_t retrans; /* Retrans Timer */
uint32_t flags; /* Flags */
};
#ifdef _KERNEL
struct nd_kifinfo {
uint8_t chlim; /* CurHopLimit */
uint32_t basereachable; /* BaseReachableTime */
uint32_t retrans; /* Retrans Timer */
uint32_t flags; /* Flags */
int recalctm; /* BaseReacable re-calculation timer */
uint32_t reachable; /* Reachable Time */
};
#endif
#define ND6_IFF_PERFORMNUD 0x01
#define ND6_IFF_ACCEPT_RTADV 0x02 /* See "RTADV Key", below. */
/* 0x02 was ND6_IFF_ACCEPT_RTADV */
#define ND6_IFF_PREFER_SOURCE 0x04 /* XXX: not related to ND. */
#define ND6_IFF_IFDISABLED 0x08 /* IPv6 operation is disabled due to
* DAD failure. (XXX: not ND-specific)
*/
#define ND6_IFF_OVERRIDE_RTADV 0x10 /* See "RTADV Key", below. */
/* 0x10 was ND6_IFF_OVERRIDE_RTADV */
#define ND6_IFF_AUTO_LINKLOCAL 0x20
/*
* RTADV Key
*
* The flags ND6_IFF_ACCEPT_RTADV and ND6_IFF_OVERRIDE_RTADV form a
* tri-state variable. (There are actually four different states, but
* two of the states are functionally identical.)
*
* ND6_IFF_OVERRIDE_RTADV or 0: This interface does not accept
* Router Advertisements.
*
* ND6_IFF_OVERRIDE_RTADV|
* ND6_IFF_ACCEPT_RTADV: This interface accepts Router
* Advertisements regardless of the
* global setting, ip6_accept_rtadv.
*
* ND6_IFF_ACCEPT_RTADV: This interface follows the global setting,
* ip6_accept_rtadv. If ip6_accept_rtadv == 0,
* this interface does not accept Router
* Advertisements. If ip6_accept_rtadv != 0,
* this interface does accept them.
*/
#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 {
@ -114,113 +88,13 @@ struct in6_nbrinfo {
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
#define NDPRF_HOME 0x4
/* protocol constants */
#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */
#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */
#define MAX_RTR_SOLICITATIONS 3
#define ND6_INFINITE_LIFETIME ((u_int32_t)~0)
#ifdef _KERNEL
@ -230,132 +104,10 @@ struct in6_ndifreq {
#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)) + (cprng_fast32() & \
((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 flags; /* flags on RA message */
u_short rtlifetime;
u_long expire;
struct ifnet *ifp;
int installed; /* is installed into kernel routing table */
};
#define ND_DEFROUTER_LIST_INIT() \
TAILQ_INIT(&nd_defrouter)
#define ND_DEFROUTER_LIST_FOREACH(dr) \
TAILQ_FOREACH((dr), &nd_defrouter, dr_entry)
#define ND_DEFROUTER_LIST_FOREACH_SAFE(dr, dr_next) \
TAILQ_FOREACH_SAFE((dr), &nd_defrouter, dr_entry, (dr_next))
#define ND_DEFROUTER_LIST_EMPTY() \
TAILQ_EMPTY(&nd_defrouter)
#define ND_DEFROUTER_LIST_REMOVE(dr) \
TAILQ_REMOVE(&nd_defrouter, (dr), dr_entry)
#define ND_DEFROUTER_LIST_INSERT_BEFORE(dr, dr_new) \
TAILQ_INSERT_BEFORE((dr), (dr_new), dr_entry)
#define ND_DEFROUTER_LIST_INSERT_TAIL(dr) \
TAILQ_INSERT_TAIL(&nd_defrouter, (dr), dr_entry)
#define ND_DEFROUTER_LIST_FIRST() \
TAILQ_FIRST(&nd_defrouter)
#define ND_DEFROUTER_LIST_NEXT(dr) \
TAILQ_NEXT((dr), dr_entry)
struct nd_prefixctl {
struct ifnet *ndprc_ifp;
/* prefix */
struct sockaddr_in6 ndprc_prefix;
u_char ndprc_plen;
u_int32_t ndprc_vltime; /* advertised valid lifetime */
u_int32_t ndprc_pltime; /* advertised preferred lifetime */
struct prf_ra ndprc_flags;
};
#define ndprc_raf ndprc_flags
#define ndprc_raf_onlink ndprc_flags.onlink
#define ndprc_raf_auto ndprc_flags.autonomous
#define ndprc_raf_router ndprc_flags.router
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_next ndpr_entry.le_next
#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
#define ND_PREFIX_LIST_FOREACH(pr) \
LIST_FOREACH((pr), &nd_prefix, ndpr_entry)
#define ND_PREFIX_LIST_FOREACH_SAFE(pr, pr_next) \
LIST_FOREACH_SAFE((pr), &nd_prefix, ndpr_entry, (pr_next))
#define ND_PREFIX_LIST_REMOVE(pr) \
LIST_REMOVE((pr), ndpr_entry)
#define ND_PREFIX_LIST_INSERT_HEAD(pr) \
LIST_INSERT_HEAD(&nd_prefix, (pr), ndpr_entry)
/*
* 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);
#include <sys/mallocvar.h>
MALLOC_DECLARE(M_IP6NDP);
@ -367,8 +119,6 @@ extern int nd6_mmaxtries;
extern int nd6_useloopback;
extern int nd6_maxnudhint;
extern int nd6_gctimer;
extern struct nd_drhead nd_defrouter;
extern struct nd_prhead nd_prefix;
extern int nd6_debug;
#define nd6log(level, fmt, args...) \
@ -382,13 +132,6 @@ extern krwlock_t nd6_lock;
#define ND6_ASSERT_WLOCK() KASSERT(rw_write_held(&nd6_lock))
#define ND6_ASSERT_LOCK() KASSERT(rw_lock_held(&nd6_lock))
/* nd6_rtr.c */
extern int ip6_desync_factor; /* seconds */
extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */
extern u_int32_t ip6_temp_valid_lifetime; /* seconds */
extern int ip6_temp_regen_advance; /* seconds */
extern int nd6_numroutes;
union nd_opts {
struct nd_opt_hdr *nd_opt_array[16]; /* max = ND_OPT_NONCE */
struct {
@ -431,17 +174,15 @@ union nd_opts {
/* nd6.c */
void nd6_init(void);
void nd6_nbr_init(void);
struct nd_ifinfo *nd6_ifattach(struct ifnet *);
struct nd_kifinfo *nd6_ifattach(struct ifnet *);
void nd6_ifdetach(struct ifnet *, struct in6_ifextra *);
int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *);
void nd6_option_init(void *, int, union nd_opts *);
int nd6_options(union nd_opts *);
struct llentry *nd6_lookup(const struct in6_addr *, const struct ifnet *, bool);
struct llentry *nd6_create(const struct in6_addr *, const struct ifnet *);
void nd6_setmtu(struct ifnet *);
void nd6_llinfo_settimer(struct llentry *, time_t);
void nd6_purge(struct ifnet *, struct in6_ifextra *);
void nd6_assert_purged(struct ifnet *);
void nd6_nud_hint(struct rtentry *);
int nd6_resolve(struct ifnet *, const struct rtentry *, struct mbuf *,
const struct sockaddr *, uint8_t *, size_t);
@ -465,19 +206,7 @@ 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 nd6_defrouter_reset(void);
void nd6_defrouter_select(void);
void nd6_defrtrlist_del(struct nd_defrouter *, struct in6_ifextra *);
void nd6_prefix_unref(struct nd_prefix *);
void nd6_prelist_remove(struct nd_prefix *);
void nd6_invalidate_prefix(struct nd_prefix *);
void nd6_pfxlist_onlink_check(void);
struct nd_defrouter *nd6_defrouter_lookup(const struct in6_addr *, struct ifnet *);
void nd6_rt_flush(struct in6_addr *, struct ifnet *);
int in6_tmpifadd(const struct in6_ifaddr *, int, int);
bool nd6_accepts_rtadv(const struct nd_ifinfo *);
void nd6_rtr_cache(struct mbuf *, int, int, int);
#endif /* _KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: nd6_nbr.c,v 1.178 2020/04/22 19:32:11 roy Exp $ */
/* $NetBSD: nd6_nbr.c,v 1.179 2020/06/12 11:04:45 roy Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.178 2020/04/22 19:32:11 roy Exp $");
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.179 2020/06/12 11:04:45 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -611,7 +611,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
struct llentry *ln = NULL;
union nd_opts ndopts;
struct sockaddr_in6 ssin6;
bool checklink = false;
struct psref psref;
struct psref psref_ia;
char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
@ -760,14 +759,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
ln->ln_state = ND6_LLINFO_STALE;
nd6_llinfo_settimer(ln, nd6_gctimer * hz);
}
if ((ln->ln_router = is_router) != 0) {
/*
* This means a router's state has changed from
* non-reachable to probably reachable, and might
* affect the status of associated prefixes..
*/
checklink = true;
}
} else {
bool llchange;
@ -848,32 +839,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
}
}
}
if (ln->ln_router && !is_router) {
/*
* The peer dropped the router flag.
* Remove the sender from the Default Router List and
* update the Destination Cache entries.
*/
const struct in6_addr *in6 = &ln->r_l3addr.addr6;
struct nd_defrouter *dr;
ND6_WLOCK();
dr = nd6_defrouter_lookup(in6, ln->lle_tbl->llt_ifp);
if (dr)
nd6_defrtrlist_del(dr, NULL);
else if (!ip6_forwarding) {
/*
* Even if the neighbor is not in the default
* router list, the neighbor may be used
* as a next hop for some destinations
* (e.g. redirect case). So we must
* call nd6_rt_flush explicitly.
*/
nd6_rt_flush(&ip6->ip6_src, ln->lle_tbl->llt_ifp);
}
ND6_UNLOCK();
}
ln->ln_router = is_router;
}
/*
@ -895,12 +860,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
if (ln != NULL)
LLE_WUNLOCK(ln);
if (checklink) {
ND6_WLOCK();
nd6_pfxlist_onlink_check();
ND6_UNLOCK();
}
m_put_rcvif_psref(ifp, &psref);
m_freem(m);
return;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.rump,v 1.128 2020/05/29 00:05:26 kamil Exp $
# $NetBSD: Makefile.rump,v 1.129 2020/06/12 11:04:45 roy Exp $
#
.if !defined(_RUMP_MK)
@ -43,7 +43,7 @@ CPPFLAGS+= -DMIPS1=1
# which NetBSD compat to build
RUMP_NBCOMPAT?=default
.if ${RUMP_NBCOMPAT} == "all" || ${RUMP_NBCOMPAT} == "default"
RUMP_NBCOMPAT= 50 60 70 80
RUMP_NBCOMPAT= 50 60 70 80 90
.endif
.if ${RUMP_NBCOMPAT} == "none"
RUMP_NBCOMPAT=

View File

@ -1,11 +1,11 @@
# $NetBSD: Makefile,v 1.3 2016/11/24 08:52:20 ozaki-r Exp $
# $NetBSD: Makefile,v 1.4 2020/06/12 11:04:45 roy Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/ndp
.for name in dad ndp ra
.for name in dad ndp
TESTS_SH+= t_${name}
TESTS_SH_SRC_t_${name}= ../net_common.sh t_${name}.sh
.endfor

View File

@ -1,866 +0,0 @@
# $NetBSD: t_ra.sh,v 1.33 2019/10/16 07:42:22 ozaki-r Exp $
#
# Copyright (c) 2015 Internet Initiative Japan Inc.
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
RUMPSRV=unix://r1
RUMPSRV1_2=unix://r12
RUMPCLI=unix://r2
RUMPSRV3=unix://r3
RUMPSRV4=unix://r4
IP6SRV=fc00:1::1
IP6SRV1_2=fc00:1::2
IP6SRV_PREFIX=fc00:1:
IP6CLI=fc00:2::2
IP6SRV3=fc00:3::1
IP6SRV3_PREFIX=fc00:3:
IP6SRV4=fc00:4::1
IP6SRV4_PREFIX=fc00:4:
PIDFILE=./rump.rtadvd.pid
PIDFILE1_2=./rump.rtadvd.pid12
PIDFILE3=./rump.rtadvd.pid3
PIDFILE4=./rump.rtadvd.pid4
CONFIG=./rtadvd.conf
DEBUG=${DEBUG:-false}
RUMP_PROGS="rump_server rump.rtadvd rump.ndp rump.ifconfig rump.netstat"
init_server()
{
export RUMP_SERVER=$1
atf_check -s exit:0 -o match:'0.->.1' \
rump.sysctl -w net.inet6.ip6.forwarding=1
export LD_PRELOAD=/usr/lib/librumphijack.so
atf_check -s exit:0 mkdir -p /rump/var/chroot/rtadvd
unset LD_PRELOAD
unset RUMP_SERVER
}
setup_shmif0()
{
local sock=$1
local IP6ADDR=$2
rump_server_add_iface $sock shmif0 bus1
export RUMP_SERVER=$sock
atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6ADDR}
atf_check -s exit:0 rump.ifconfig shmif0 up
atf_check -s exit:0 rump.ifconfig -w 10
$DEBUG && rump.ifconfig
}
kill_rtadvd()
{
local pid=$(cat "$1")
test -n "$pid" && {
case "$pid" in
*[!0-9]*) return 1;;
esac
test "$pid" -gt 1 && kill -s KILL "${pid}"
}
rm -f "$1"
}
terminate_rtadvd()
{
local pidfile=$1
local n=5
if ! [ -f "$pidfile" ]; then
return
fi
local pid=$(cat "$pidfile")
test -n "${pid}" && kill -s TERM "${pid}"
# Note, rtadvd cannot remove its own pidfile, it chroots after
# creating it (and if it chroot'd first, we would not be able to
# control where it puts the thing, and so it would be useless.)
# However, it does truncate it... so watch for that.
while [ -s "$pidfile" ]; do
n=$((n - 1))
if [ "$n" = 0 ]; then
kill_rtadvd "$pidfile"
return
fi
sleep 0.2
done
# and finally complete the cleanup that rtadvd did not do.
rm -f "$pidfile"
}
create_rtadvdconfig()
{
cat << _EOF > ${CONFIG}
shmif0:\\
:mtu#1300:maxinterval#4:mininterval#3:
_EOF
}
create_rtadvdconfig_rltime()
{
cat << _EOF > ${CONFIG}
shmif0:\\
:mtu#1300:maxinterval#4:mininterval#3:rltime#$1:
_EOF
$DEBUG && cat ${CONFIG}
}
create_rtadvdconfig_vltime()
{
cat << _EOF > ${CONFIG}
shmif0:\\
:mtu#1300:maxinterval#4:mininterval#3:addr="$1":vltime#$2:
_EOF
$DEBUG && cat ${CONFIG}
}
RA_count()
{
RUMP_SERVER="$1" rump.netstat -p icmp6 | sed -n '
$ {
s/^.*$/0/p
q
}
/router advertisement:/!d
s/.*router advertisement: *//
s/[ ]*$//
s/^$/0/
p
q
'
}
await_RA()
{
local N=$(RA_count "$1")
while [ "$(RA_count "$1")" -le "$N" ]; do
sleep 0.2
done
}
start_rtadvd()
{
local RUMP_SERVER="$1"
export RUMP_SERVER
atf_check -s exit:0 -e ignore \
rump.rtadvd -D -c ${CONFIG} -p "$2" shmif0
# don't wait for the pid file to appear and get a pid in it.
# we look for receiving RAs instead, must more reliable
# extra delay here increases possibility of RA arriving before
# we start looking (which means we then wait for the next .. boring!)
}
check_entries()
{
local RUMP_SERVER="$1"
local srv=$2
local addr_prefix=$3
local mac_srv= ll_srv=
export RUMP_SERVER
ll_srv=$(get_linklocal_addr "$srv" shmif0)
mac_srv=$(get_macaddr "$srv" shmif0)
$DEBUG && dump_entries
atf_check -s exit:0 -o match:if=shmif0 rump.ndp -r
atf_check -s exit:0 -o match:advertised \
-o match:"${ll_srv}%shmif0 \(reachable\)" \
rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
atf_check -s exit:0 \
-o match:"$ll_srv%shmif0 +$mac_srv +shmif0 +$ONEDAYISH S R" \
-o not-match:"$addr_prefix" \
rump.ndp -n -a
atf_check -s exit:0 \
-o match:"$addr_prefix.+<(TENTATIVE,)?AUTOCONF>" \
rump.ifconfig shmif0 inet6
}
dump_entries()
{
local marker="+-+-+-+-+-+-+-+-+"
printf '%s %s\n' "$marker" 'ndp -n -a'
rump.ndp -n -a
printf '%s %s\n' "$marker" 'ndp -p'
rump.ndp -p
printf '%s %s\n' "$marker" 'ndp -r'
rump.ndp -r
printf '%s\n' "$marker"
}
atf_test_case ra_basic cleanup
ra_basic_head()
{
atf_set "descr" "Tests for basic functions of router advaertisement(RA)"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_basic_body()
{
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
init_server $RUMPSRV
setup_shmif0 ${RUMPCLI} ${IP6CLI}
export RUMP_SERVER=${RUMPCLI}
$DEBUG && rump.ndp -n -a
atf_check -s exit:0 -o match:'= 0' \
rump.sysctl net.inet6.ip6.accept_rtadv
unset RUMP_SERVER
create_rtadvdconfig
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
export RUMP_SERVER=${RUMPCLI}
atf_check -s exit:0 -o empty rump.ndp -r
atf_check -s exit:0 -o not-match:advertised rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=0 rump.ndp -n -i shmif0
atf_check -s exit:0 -o not-match:'S R' -o not-match:fc00:1: \
rump.ndp -n -a
atf_check -s exit:0 -o not-match:fc00:1: rump.ifconfig shmif0 inet6
unset RUMP_SERVER
terminate_rtadvd $PIDFILE
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
terminate_rtadvd $PIDFILE
rump_server_destroy_ifaces
}
ra_basic_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_flush_prefix_entries cleanup
ra_flush_prefix_entries_head()
{
atf_set "descr" "Tests for flushing prefixes (ndp -P)"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_flush_prefix_entries_body()
{
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
create_rtadvdconfig
export RUMP_SERVER=${RUMPCLI}
atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
unset RUMP_SERVER
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=${RUMPCLI}
# Terminate rtadvd to prevent new RA messages from coming
terminate_rtadvd $PIDFILE
# Flush all the entries in the prefix list
atf_check -s exit:0 rump.ndp -P
$DEBUG && dump_entries
atf_check -s exit:0 -o match:if=shmif0 rump.ndp -r
atf_check -s exit:0 -o empty rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
atf_check -s exit:0 -o match:"$ONEDAYISH S R" -o not-match:fc00:1: \
rump.ndp -n -a
atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6
unset RUMP_SERVER
rump_server_destroy_ifaces
}
ra_flush_prefix_entries_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_flush_defrouter_entries cleanup
ra_flush_defrouter_entries_head()
{
atf_set "descr" "Tests for flushing default routers (ndp -R)"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_flush_defrouter_entries_body()
{
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
create_rtadvdconfig
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=${RUMPCLI}
# Terminate rtadvd to prevent new RA messages from coming
terminate_rtadvd $PIDFILE
# Flush all the entries in the default router list
atf_check -s exit:0 rump.ndp -R
$DEBUG && dump_entries
atf_check -s exit:0 -o empty rump.ndp -r
atf_check -s exit:0 -o match:'No advertising router' rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
atf_check -s exit:0 -o not-match:fc00:1: rump.ndp -n -a
atf_check -s exit:0 -o match:'fc00:1:' rump.ifconfig shmif0 inet6
unset RUMP_SERVER
rump_server_destroy_ifaces
}
ra_flush_defrouter_entries_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_delete_address cleanup
ra_delete_address_head()
{
atf_set "descr" "Tests for deleting auto-configured address"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_delete_address_body()
{
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
create_rtadvdconfig
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=${RUMPCLI}
$DEBUG && rump.ifconfig shmif0
atf_check -s exit:0 rump.ifconfig shmif0 inet6 \
$(rump.ifconfig shmif0 | awk '/AUTOCONF/ {print $2}') delete
unset RUMP_SERVER
terminate_rtadvd $PIDFILE
rump_server_destroy_ifaces
}
ra_delete_address_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_multiple_routers cleanup
ra_multiple_routers_head()
{
atf_set "descr" "Tests for multiple routers"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_multiple_routers_body()
{
local n=
rump_server_fs_start $RUMPSRV netinet6
rump_server_fs_start $RUMPSRV3 netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPSRV3} ${IP6SRV3}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
init_server $RUMPSRV3
create_rtadvdconfig
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
start_rtadvd $RUMPSRV3 $PIDFILE3
await_RA "${RUMPCLI}"
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX
# Two prefixes are advertised by differnt two routers
n=$(RUMP_SERVER=$RUMPCLI rump.ndp -p | grep 'advertised by' | wc -l)
atf_check_equal $n 2
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE3
rump_server_destroy_ifaces
}
ra_multiple_routers_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE3
cleanup
}
atf_test_case ra_multiple_routers_single_prefix cleanup
ra_multiple_routers_single_prefix_head()
{
atf_set "descr" "Tests for multiple routers with a single prefix"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_multiple_routers_single_prefix_body()
{
local n=
rump_server_fs_start $RUMPSRV netinet6
rump_server_fs_start $RUMPSRV1_2 netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPSRV1_2} ${IP6SRV1_2}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
init_server $RUMPSRV1_2
create_rtadvdconfig
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
start_rtadvd $RUMPSRV1_2 $PIDFILE1_2
await_RA "${RUMPCLI}"
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
check_entries $RUMPCLI $RUMPSRV1_2 $IP6SRV_PREFIX
export RUMP_SERVER=$RUMPCLI
# One prefix is advertised by differnt two routers
n=$(rump.ndp -p |grep 'advertised by' |wc -l)
atf_check_equal $n 1
unset RUMP_SERVER
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE1_2
rump_server_destroy_ifaces
}
ra_multiple_routers_single_prefix_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE1_2
cleanup
}
atf_test_case ra_multiple_routers_maxifprefixes cleanup
ra_multiple_routers_maxifprefixes_head()
{
atf_set "descr" "Tests for exceeding the number of maximum prefixes"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_multiple_routers_maxifprefixes_body()
{
local n=
rump_server_fs_start $RUMPSRV netinet6
rump_server_fs_start $RUMPSRV3 netinet6
rump_server_fs_start $RUMPSRV4 netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPSRV3} ${IP6SRV3}
setup_shmif0 ${RUMPSRV4} ${IP6SRV4}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
init_server $RUMPSRV3
init_server $RUMPSRV4
create_rtadvdconfig
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0.->.1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
# Limit the maximum number of prefix entries to 2
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'16 -> 2' \
rump.sysctl -w net.inet6.ip6.maxifprefixes=2
start_rtadvd $RUMPSRV $PIDFILE
start_rtadvd $RUMPSRV3 $PIDFILE3
await_RA "${RUMPCLI}"
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX
start_rtadvd $RUMPSRV4 $PIDFILE4
await_RA "${RUMPCLI}"
$DEBUG && RUMP_SERVER="${RUMPCLI}" dump_entries
# There should remain two prefixes
n=$(RUMP_SERVER=${RUMPCLI} rump.ndp -p | grep 'advertised by' | wc -l)
atf_check_equal $n 2
# TODO check other conditions
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE3
terminate_rtadvd $PIDFILE4
rump_server_destroy_ifaces
}
ra_multiple_routers_maxifprefixes_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
terminate_rtadvd $PIDFILE3
terminate_rtadvd $PIDFILE4
cleanup
}
atf_test_case ra_temporary_address cleanup
ra_temporary_address_head()
{
atf_set "descr" "Tests for IPv6 temporary address"
atf_set "require.progs" "${RUMP_PROGS}"
}
check_echo_request_pkt()
{
local pkt="$2 > $3: .+ echo request"
extract_new_packets $1 > ./out
$DEBUG && echo "$pkt"
$DEBUG && cat ./out
atf_check -s exit:0 -o match:"$pkt" cat ./out
}
ra_temporary_address_body()
{
local ip_auto= ip_temp=
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 $RUMPSRV $IP6SRV
init_server $RUMPSRV
setup_shmif0 $RUMPCLI $IP6CLI
RUMP_SERVER=$RUMPCLI atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
RUMP_SERVER=$RUMPCLI atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.use_tempaddr=1
create_rtadvdconfig
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=$RUMPCLI
# Check temporary address
atf_check -s exit:0 \
-o match:"$IP6SRV_PREFIX.+<(TENTATIVE,)?AUTOCONF,TEMPORARY>" \
rump.ifconfig shmif0 inet6
#
# Testing net.inet6.ip6.prefer_tempaddr
#
atf_check -s exit:0 rump.ifconfig -w 10
$DEBUG && rump.ifconfig shmif0
ip_auto=$(rump.ifconfig shmif0 |
awk '/<AUTOCONF>/ {sub(/\/[0-9]*/, ""); print $2;}')
ip_temp=$(rump.ifconfig shmif0 |
awk '/<AUTOCONF,TEMPORARY>/ {sub(/\/[0-9]*/, ""); print $2;}')
$DEBUG && echo "AUTO=$ip_auto TEMP=$ip_temp"
# Ignore old packets
extract_new_packets bus1 > /dev/null
atf_check -s exit:0 -o ignore rump.ping6 -n -X 2 -c 1 $IP6SRV
# autoconf (non-temporal) address should be used as the source address
check_echo_request_pkt bus1 $ip_auto $IP6SRV
# Enable net.inet6.ip6.prefer_tempaddr
atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.prefer_tempaddr=1
atf_check -s exit:0 -o ignore rump.ping6 -n -X 2 -c 1 $IP6SRV
# autoconf, temporal address should be used as the source address
check_echo_request_pkt bus1 $ip_temp $IP6SRV
#
# Testing the validation of net.inet6.ip6.temppltime
#
# XXX should move to a better place
atf_check -s not-exit:0 -e match:'Invalid argument' \
rump.sysctl -w net.inet6.ip6.temppltime=$((600 + 5))
atf_check -s exit:0 -o match:'86400 -> 606' \
rump.sysctl -w net.inet6.ip6.temppltime=$((600 + 5 + 1))
unset RUMP_SERVER
terminate_rtadvd $PIDFILE
rump_server_destroy_ifaces
}
ra_temporary_address_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_defrouter_expiration cleanup
ra_defrouter_expiration_head()
{
atf_set "descr" "Tests for default router expiration"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_defrouter_expiration_body()
{
local expire_time=5
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
create_rtadvdconfig_rltime $expire_time
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0.->.1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=${RUMPCLI}
# Terminate rtadvd to prevent new RA messages from coming
terminate_rtadvd $PIDFILE
# Wait until the default routers and prefix entries are expired
# XXX need to work out a better way ... this is a race.
# XXX fortunately this race usually ends with the winner we want
# XXX (long odds on - not worth placing a bet...)
sleep $expire_time
$DEBUG && dump_entries
# Give nd6_timer a chance to sweep default routers and prefix entries
# XXX Ugh again.
sleep 2
$DEBUG && dump_entries
atf_check -s exit:0 -o not-match:if=shmif0 rump.ndp -r
atf_check -s exit:0 -o match:'No advertising router' rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
atf_check -s exit:0 -o not-match:fc00:1: rump.ndp -n -a
atf_check -s exit:0 -o match:fc00:1: rump.ifconfig shmif0 inet6
unset RUMP_SERVER
rump_server_destroy_ifaces
}
ra_defrouter_expiration_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_test_case ra_prefix_expiration cleanup
ra_prefix_expiration_head()
{
atf_set "descr" "Tests for prefix expiration"
atf_set "require.progs" "${RUMP_PROGS}"
}
ra_prefix_expiration_body()
{
local expire_time=5
rump_server_fs_start $RUMPSRV netinet6
rump_server_start $RUMPCLI netinet6
setup_shmif0 ${RUMPSRV} ${IP6SRV}
setup_shmif0 ${RUMPCLI} ${IP6CLI}
init_server $RUMPSRV
create_rtadvdconfig_vltime "${IP6SRV_PREFIX}:" $expire_time
RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
rump.sysctl -w net.inet6.ip6.accept_rtadv=1
start_rtadvd $RUMPSRV $PIDFILE
await_RA "${RUMPCLI}"
check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
export RUMP_SERVER=${RUMPCLI}
# Terminate rtadvd to prevent new RA messages from coming
terminate_rtadvd $PIDFILE
# Wait until the default routers and prefix entries are expired
# XXX need the same better way here too...
sleep $expire_time
$DEBUG && dump_entries
# Give nd6_timer a chance to sweep default routers and prefix entries
# XXX and here
sleep 2
$DEBUG && dump_entries
atf_check -s exit:0 -o match:if=shmif0 rump.ndp -r
atf_check -s exit:0 -o empty rump.ndp -p
atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
atf_check -s exit:0 -o match:"$ONEDAYISH S R" -o not-match:fc00:1: \
rump.ndp -n -a
atf_check -s exit:0 -o not-match:fc00:1: rump.ifconfig shmif0 inet6
unset RUMP_SERVER
rump_server_destroy_ifaces
}
ra_prefix_expiration_cleanup()
{
$DEBUG && dump
terminate_rtadvd $PIDFILE
cleanup
}
atf_init_test_cases()
{
atf_add_test_case ra_basic
atf_add_test_case ra_flush_prefix_entries
atf_add_test_case ra_flush_defrouter_entries
atf_add_test_case ra_delete_address
atf_add_test_case ra_multiple_routers
atf_add_test_case ra_multiple_routers_single_prefix
atf_add_test_case ra_multiple_routers_maxifprefixes
atf_add_test_case ra_temporary_address
atf_add_test_case ra_defrouter_expiration
atf_add_test_case ra_prefix_expiration
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ndp.8,v 1.29 2018/02/14 10:13:25 wiz Exp $
.\" $NetBSD: ndp.8,v 1.30 2020/06/12 11:04:46 roy Exp $
.\" $KAME: ndp.8,v 1.33 2005/10/19 14:57:42 suz Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 14, 2018
.Dd April 19, 2020
.Dt NDP 8
.Os
.\"
@ -45,12 +45,6 @@
.Fl a | Fl c | Fl p
.Nm ndp
.Op Fl nt
.Fl r
.Nm ndp
.Op Fl nt
.Fl H | Fl P | Fl R
.Nm ndp
.Op Fl nt
.Fl A Ar wait
.Nm ndp
.Op Fl nt
@ -65,9 +59,6 @@
.Op Ar expressions ...
.Nm ndp
.Op Fl nt
.Fl I Op Ar interface | Li delete
.Nm ndp
.Op Fl nt
.Fl s Ar nodename etheraddr
.Op Li temp
.Op Li proxy
@ -138,18 +129,6 @@ Delete specified NDP entry.
.It Fl f
Parse the file specified by
.Ar filename .
.It Fl H
Harmonize consistency between the routing table and the default router
list; install the top entry of the list into the kernel routing table.
.It Fl I
Shows the default interface used as the default route when
there is no default router.
.It Fl I Ar interface
Specifies the default
.Ar interface
to be used when there is no interface specified even though required.
.It Fl I Li delete
The current default interface will be deleted from the kernel.
.It Fl i Ar interface Op Ar expressions ...
View ND information for the specified interface.
If additional arguments
@ -176,34 +155,12 @@ in this case.
Turn on or off NUD (Neighbor Unreachability Detection) on the
interface.
NUD is usually turned on by default.
.It Ic accept_rtadv
Specify whether or not to accept Router Advertisement messages
received on the
.Ar interface .
Note that the kernel does not accept Router Advertisement messages,
even if the flag
.Ic accept_rtadv
is on, unless either the
.Li net.inet6.ip6.accept_rtadv
variable is non-0, or the flag
.Ic override_rtadv
is on.
This flag is set to 1 by default.
.It Ic auto_linklocal
Specify whether or not to perform automatic link-local address configuration on
.Ar interface .
This flag is set by
.Li net.inet6.ip6.auto_linklocal
sysctl variable.
.It Ic override_rtadv
Specify whether or not to override the
.Li net.inet6.ip6.accept_rtadv
variable.
If the flag is on, then it will suffice to set the flag
.Ic accept_rtadv
to make the kernel accept Router Advertisement messages on the
.Ar interface .
This flag is set to 0 by default.
.It Ic prefer_source
Prefer addresses on the
.Ar interface
@ -236,14 +193,6 @@ Specify the Cur Hop Limit on the interface.
.El
.It Fl n
Do not try to resolve numeric addresses to hostnames.
.It Fl P
Flush all the entries in the prefix list.
.It Fl p
Show prefix list.
.It Fl R
Flush all the entries in the default router list.
.It Fl r
Show default router list.
.It Fl s
Register an NDP entry for a node.
The entry will be permanent unless the word

View File

@ -1,4 +1,4 @@
/* $NetBSD: ndp.c,v 1.55 2018/12/16 08:47:43 roy Exp $ */
/* $NetBSD: ndp.c,v 1.56 2020/06/12 11:04:46 roy Exp $ */
/* $KAME: ndp.c,v 1.121 2005/07/13 11:30:13 keiichi Exp $ */
/*
@ -131,15 +131,6 @@ static int ndp_ether_aton(char *, u_char *);
__dead static void usage(void);
static int rtmsg(int, struct rt_msghdr *);
static void ifinfo(char *, int, char **);
static void rtrlist(void);
static void plist(void);
static void pfx_flush(void);
static void rtr_flush(void);
static void harmonize_rtr(void);
#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */
static void getdefif(void);
static void setdefif(char *);
#endif
static const char *sec2str(time_t);
static char *ether_str(struct sockaddr_dl *);
static void ts_print(const struct timeval *);
@ -147,15 +138,6 @@ static void ts_print(const struct timeval *);
#define NDP_F_CLEAR 1
#define NDP_F_DELETE 2
#ifdef ICMPV6CTL_ND6_DRLIST
static const char *rtpref_str[] = {
"medium", /* 00 */
"high", /* 01 */
"rsv", /* 10 */
"low" /* 11 */
};
#endif
static int mode = 0;
static char *arg = NULL;
@ -164,24 +146,11 @@ main(int argc, char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "acd:f:Ii:nprstA:HPR")) != -1)
while ((ch = getopt(argc, argv, "acd:f:i:nstA:")) != -1)
switch (ch) {
case 'a':
case 'c':
case 'p':
case 'r':
case 'H':
case 'P':
case 'R':
case 's':
case 'I':
if (mode) {
usage();
/*NOTREACHED*/
}
mode = ch;
arg = NULL;
break;
case 'd':
case 'f':
case 'i' :
@ -235,66 +204,13 @@ main(int argc, char **argv)
}
delete_one(arg);
break;
case 'I':
#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */
if (argc > 1) {
usage();
/*NOTREACHED*/
} else if (argc == 1) {
if (strcmp(*argv, "delete") == 0 ||
if_nametoindex(*argv))
setdefif(*argv);
else
errx(1, "invalid interface %s", *argv);
}
getdefif(); /* always call it to print the result */
break;
#else
errx(1, "not supported yet");
/*NOTREACHED*/
#endif
case 'p':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
plist();
break;
case 'i':
ifinfo(arg, argc, argv);
break;
case 'r':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
rtrlist();
break;
case 's':
if (argc < 2 || argc > 4)
usage();
return(set(argc, argv) ? 1 : 0);
case 'H':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
harmonize_rtr();
break;
case 'P':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
pfx_flush();
break;
case 'R':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
rtr_flush();
break;
case 0:
if (argc != 1) {
usage();
@ -784,9 +700,6 @@ usage(void)
(void)fprintf(stderr, " %s [-nt] -d hostname\n", pn);
(void)fprintf(stderr, " %s [-nt] -f filename\n", pn);
(void)fprintf(stderr, " %s [-nt] -i interface [flags...]\n", pn);
#ifdef SIOCSDEFIFACE_IN6
(void)fprintf(stderr, " %s [-nt] -I [interface|delete]\n", pn);
#endif
(void)fprintf(stderr,
" %s [-nt] -s nodename etheraddr [temp] [proxy]\n", pn);
exit(1);
@ -870,9 +783,7 @@ ifinfo(char *ifname, int argc, char **argv)
struct in6_ndireq nd;
int i, s;
u_int32_t newflags;
#ifdef IPV6CTL_USETEMPADDR
u_int8_t nullbuf[8];
#endif
bool valset = false, flagset = false;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
@ -898,6 +809,7 @@ ifinfo(char *ifname, int argc, char **argv)
newflags &= ~(f);\
else\
newflags |= (f);\
flagset = true; \
}\
} while (/*CONSTCOND*/0)
/*
@ -918,6 +830,7 @@ ifinfo(char *ifname, int argc, char **argv)
if (errno) \
err(1, "syntax error in %s's value", (f)); \
v = newval; \
valset = true; \
} \
} while (/*CONSTCOND*/0)
@ -946,56 +859,21 @@ ifinfo(char *ifname, int argc, char **argv)
ND.flags = newflags;
#ifdef SIOCSIFINFO_IN6
if (prog_ioctl(s, SIOCSIFINFO_IN6, &nd) < 0)
if (valset && prog_ioctl(s, SIOCSIFINFO_IN6, &nd) < 0)
err(1, "ioctl(SIOCSIFINFO_IN6)");
#else
if (prog_ioctl(s, SIOCSIFINFO_FLAGS, &nd) < 0)
err(1, "ioctl(SIOCSIFINFO_FLAGS)");
#endif
if (flagset && prog_ioctl(s, SIOCSIFINFO_FLAGS, &nd) < 0)
err(1, "ioctl(SIOCSIFINFO_FLAGS)");
#undef SETFLAG
#undef SETVALUE
}
if (!ND.initialized)
errx(1, "%s: not initialized yet", ifname);
if (prog_ioctl(s, SIOCGIFINFO_IN6, &nd) < 0)
err(1, "ioctl(SIOCGIFINFO_IN6)");
(void)printf("linkmtu=%d", ND.linkmtu);
(void)printf(", maxmtu=%d", ND.maxmtu);
(void)printf(", curhlim=%d", ND.chlim);
(void)printf("curhlim=%d", ND.chlim);
(void)printf(", basereachable=%ds%dms",
ND.basereachable / 1000, ND.basereachable % 1000);
(void)printf(", reachable=%ds", ND.reachable);
(void)printf(", retrans=%ds%dms", ND.retrans / 1000, ND.retrans % 1000);
#ifdef IPV6CTL_USETEMPADDR
(void)memset(nullbuf, 0, sizeof(nullbuf));
if (memcmp(nullbuf, ND.randomid, sizeof(nullbuf)) != 0) {
int j;
u_int8_t *rbuf;
for (i = 0; i < 3; i++) {
switch (i) {
case 0:
(void)printf("\nRandom seed(0): ");
rbuf = ND.randomseed0;
break;
case 1:
(void)printf("\nRandom seed(1): ");
rbuf = ND.randomseed1;
break;
case 2:
(void)printf("\nRandom ID: ");
rbuf = ND.randomid;
break;
default:
errx(1, "impossible case for tempaddr display");
}
for (j = 0; j < 8; j++)
(void)printf("%02x", rbuf[j]);
}
}
#endif
if (ND.flags) {
(void)printf("\nFlags: ");
if ((ND.flags & ND6_IFF_PERFORMNUD))
@ -1004,14 +882,6 @@ ifinfo(char *ifname, int argc, char **argv)
if ((ND.flags & ND6_IFF_IFDISABLED))
(void)printf("disabled ");
#endif
#ifdef ND6_IFF_ACCEPT_RTADV
if ((ND.flags & ND6_IFF_ACCEPT_RTADV))
(void)printf("accept_rtadv ");
#endif
#ifdef ND6_IFF_OVERRIDE_RTADV
if ((ND.flags & ND6_IFF_OVERRIDE_RTADV))
(void)printf("override_rtadv ");
#endif
#ifdef ND6_IFF_AUTO_LINKLOCAL
if ((ND.flags & ND6_IFF_AUTO_LINKLOCAL))
(void)printf("auto_linklocal ");
@ -1027,477 +897,6 @@ ifinfo(char *ifname, int argc, char **argv)
(void)prog_close(s);
}
#ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */
#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
#endif
static void
rtrlist(void)
{
#ifdef ICMPV6CTL_ND6_DRLIST
int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_DRLIST };
char *buf;
struct in6_defrouter *p, *ep;
size_t l;
struct timeval tim;
if (prog_sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) {
err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)");
/*NOTREACHED*/
}
if (l == 0)
return;
buf = malloc(l);
if (!buf) {
err(1, "malloc");
/*NOTREACHED*/
}
if (prog_sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) {
err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)");
/*NOTREACHED*/
}
ep = (struct in6_defrouter *)(void *)(buf + l);
for (p = (struct in6_defrouter *)(void *)buf; p < ep; p++) {
int rtpref;
if (getnameinfo((struct sockaddr *)(void *)&p->rtaddr,
(socklen_t)p->rtaddr.sin6_len, host_buf, sizeof(host_buf),
NULL, 0, (nflag ? NI_NUMERICHOST : 0)) != 0)
(void)strlcpy(host_buf, "?", sizeof(host_buf));
(void)printf("%s if=%s", host_buf,
if_indextoname((unsigned int)p->if_index, ifix_buf));
(void)printf(", flags=%s%s",
p->flags & ND_RA_FLAG_MANAGED ? "M" : "",
p->flags & ND_RA_FLAG_OTHER ? "O" : "");
rtpref = ((uint32_t)(p->flags & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff;
(void)printf(", pref=%s", rtpref_str[rtpref]);
(void)gettimeofday(&tim, 0);
if (p->expire == 0)
(void)printf(", expire=Never\n");
else
(void)printf(", expire=%s\n",
sec2str((time_t)(p->expire - tim.tv_sec)));
}
free(buf);
#else
struct in6_drlist dr;
int s, i;
struct timeval time;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
err(1, "socket");
/* NOTREACHED */
}
(void)memset(&dr, 0, sizeof(dr));
(void)strlcpy(dr.ifname, "lo0", sizeof(dr.ifname)); /* dummy */
if (prog_ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) {
err(1, "ioctl(SIOCGDRLST_IN6)");
/* NOTREACHED */
}
#define DR dr.defrouter[i]
for (i = 0 ; DR.if_index && i < DRLSTSIZ ; i++) {
struct sockaddr_in6 sin6;
(void)memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_addr = DR.rtaddr;
(void)getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
host_buf, sizeof(host_buf), NULL, 0,
(nflag ? NI_NUMERICHOST : 0));
(void)printf("%s if=%s", host_buf,
if_indextoname(DR.if_index, ifix_buf));
(void)printf(", flags=%s%s",
DR.flags & ND_RA_FLAG_MANAGED ? "M" : "",
DR.flags & ND_RA_FLAG_OTHER ? "O" : "");
gettimeofday(&time, 0);
if (DR.expire == 0)
(void)printf(", expire=Never\n");
else
(void)printf(", expire=%s\n",
sec2str(DR.expire - time.tv_sec));
}
#undef DR
(void)prog_close(s);
#endif
}
static void
plist(void)
{
#ifdef ICMPV6CTL_ND6_PRLIST
int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_PRLIST };
char *buf, *p, *ep;
struct in6_prefix pfx;
size_t l;
struct timeval tim;
const int niflags = NI_NUMERICHOST;
int ninflags = nflag ? NI_NUMERICHOST : 0;
char namebuf[NI_MAXHOST];
if (prog_sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) {
err(1, "sysctl(ICMPV6CTL_ND6_PRLIST)");
/*NOTREACHED*/
}
buf = malloc(l);
if (!buf) {
err(1, "malloc");
/*NOTREACHED*/
}
if (prog_sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) {
err(1, "sysctl(ICMPV6CTL_ND6_PRLIST)");
/*NOTREACHED*/
}
ep = buf + l;
for (p = buf; p < ep; ) {
memcpy(&pfx, p, sizeof(pfx));
p += sizeof(pfx);
if (getnameinfo((struct sockaddr*)&pfx.prefix,
(socklen_t)pfx.prefix.sin6_len, namebuf, sizeof(namebuf),
NULL, 0, niflags) != 0)
(void)strlcpy(namebuf, "?", sizeof(namebuf));
(void)printf("%s/%d if=%s\n", namebuf, pfx.prefixlen,
if_indextoname((unsigned int)pfx.if_index, ifix_buf));
(void)gettimeofday(&tim, 0);
/*
* meaning of fields, especially flags, is very different
* by origin. notify the difference to the users.
*/
(void)printf("flags=%s%s%s%s%s",
pfx.raflags.onlink ? "L" : "",
pfx.raflags.autonomous ? "A" : "",
(pfx.flags & NDPRF_ONLINK) != 0 ? "O" : "",
(pfx.flags & NDPRF_DETACHED) != 0 ? "D" : "",
#ifdef NDPRF_HOME
(pfx.flags & NDPRF_HOME) != 0 ? "H" : ""
#else
""
#endif
);
if (pfx.vltime == ND6_INFINITE_LIFETIME)
(void)printf(" vltime=infinity");
else
(void)printf(" vltime=%lu", (unsigned long)pfx.vltime);
if (pfx.pltime == ND6_INFINITE_LIFETIME)
(void)printf(", pltime=infinity");
else
(void)printf(", pltime=%lu", (unsigned long)pfx.pltime);
if (pfx.expire == 0)
(void)printf(", expire=Never");
else if (pfx.expire >= tim.tv_sec)
(void)printf(", expire=%s",
sec2str(pfx.expire - tim.tv_sec));
else
(void)printf(", expired");
(void)printf(", ref=%d", pfx.refcnt);
(void)printf("\n");
/*
* "advertising router" list is meaningful only if the prefix
* information is from RA.
*/
if (pfx.advrtrs) {
int j;
struct sockaddr_in6 sin6;
(void)printf(" advertised by\n");
for (j = 0; j < pfx.advrtrs && p <= ep; j++) {
struct in6_nbrinfo *nbi;
memcpy(&sin6, p, sizeof(sin6));
p += sizeof(sin6);
if (getnameinfo((struct sockaddr *)&sin6,
(socklen_t)sin6.sin6_len, namebuf,
sizeof(namebuf), NULL, 0, ninflags) != 0)
(void)strlcpy(namebuf, "?", sizeof(namebuf));
(void)printf(" %s", namebuf);
nbi = getnbrinfo(&sin6.sin6_addr,
(unsigned int)pfx.if_index, 0);
if (nbi) {
switch (nbi->state) {
case ND6_LLINFO_REACHABLE:
case ND6_LLINFO_STALE:
case ND6_LLINFO_DELAY:
case ND6_LLINFO_PROBE:
(void)printf(" (reachable)\n");
break;
default:
(void)printf(" (unreachable)\n");
}
} else
(void)printf(" (no neighbor state)\n");
}
} else
(void)printf(" No advertising router\n");
}
free(buf);
#else
struct in6_prlist pr;
int s, i;
struct timeval time;
(void)gettimeofday(&time, 0);
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
err(1, "socket");
/* NOTREACHED */
}
(void)memset(&pr, 0, sizeof(pr));
(void)strlcpy(pr.ifname, "lo0", sizeof(pr.ifname)); /* dummy */
if (prog_ioctl(s, SIOCGPRLST_IN6, (caddr_t)&pr) < 0) {
err(1, "ioctl(SIOCGPRLST_IN6)");
/* NOTREACHED */
}
#define PR pr.prefix[i]
for (i = 0; PR.if_index && i < PRLSTSIZ ; i++) {
struct sockaddr_in6 p6;
char namebuf[NI_MAXHOST];
int niflags;
#ifdef NDPRF_ONLINK
p6 = PR.prefix;
#else
(void)memset(&p6, 0, sizeof(p6));
p6.sin6_family = AF_INET6;
p6.sin6_len = sizeof(p6);
p6.sin6_addr = PR.prefix;
#endif
niflags = NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&p6,
sizeof(p6), namebuf, sizeof(namebuf),
NULL, 0, niflags)) {
warnx("getnameinfo failed");
continue;
}
(void)printf("%s/%d if=%s\n", namebuf, PR.prefixlen,
if_indextoname(PR.if_index, ifix_buf));
(void)gettimeofday(&time, 0);
/*
* meaning of fields, especially flags, is very different
* by origin. notify the difference to the users.
*/
#if 0
(void)printf(" %s",
PR.origin == PR_ORIG_RA ? "" : "advertise: ");
#endif
#ifdef NDPRF_ONLINK
(void)printf("flags=%s%s%s%s%s",
PR.raflags.onlink ? "L" : "",
PR.raflags.autonomous ? "A" : "",
(PR.flags & NDPRF_ONLINK) != 0 ? "O" : "",
(PR.flags & NDPRF_DETACHED) != 0 ? "D" : "",
#ifdef NDPRF_HOME
(PR.flags & NDPRF_HOME) != 0 ? "H" : ""
#else
""
#endif
);
#else
(void)printf("flags=%s%s",
PR.raflags.onlink ? "L" : "",
PR.raflags.autonomous ? "A" : "");
#endif
if (PR.vltime == ND6_INFINITE_LIFETIME)
(void)printf(" vltime=infinity");
else
(void)printf(" vltime=%lu", PR.vltime);
if (PR.pltime == ND6_INFINITE_LIFETIME)
(void)printf(", pltime=infinity");
else
(void)printf(", pltime=%lu", PR.pltime);
if (PR.expire == 0)
(void)printf(", expire=Never");
else if (PR.expire >= time.tv_sec)
(void)printf(", expire=%s",
sec2str(PR.expire - time.tv_sec));
else
(void)printf(", expired");
#ifdef NDPRF_ONLINK
(void)printf(", ref=%d", PR.refcnt);
#endif
#if 0
switch (PR.origin) {
case PR_ORIG_RA:
(void)printf(", origin=RA");
break;
case PR_ORIG_RR:
(void)printf(", origin=RR");
break;
case PR_ORIG_STATIC:
(void)printf(", origin=static");
break;
case PR_ORIG_KERNEL:
(void)printf(", origin=kernel");
break;
default:
(void)printf(", origin=?");
break;
}
#endif
(void)printf("\n");
/*
* "advertising router" list is meaningful only if the prefix
* information is from RA.
*/
if (0 && /* prefix origin is almost obsolted */
PR.origin != PR_ORIG_RA)
;
else if (PR.advrtrs) {
int j;
(void)printf(" advertised by\n");
for (j = 0; j < PR.advrtrs; j++) {
struct sockaddr_in6 sin6;
struct in6_nbrinfo *nbi;
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_addr = PR.advrtr[j];
sin6.sin6_scope_id = PR.if_index; /* XXX */
(void)getnameinfo((struct sockaddr *)&sin6,
sin6.sin6_len, host_buf,
sizeof(host_buf), NULL, 0,
(nflag ? NI_NUMERICHOST : 0));
(void)printf(" %s", host_buf);
nbi = getnbrinfo(&sin6.sin6_addr,
PR.if_index, 0);
if (nbi) {
switch (nbi->state) {
case ND6_LLINFO_REACHABLE:
case ND6_LLINFO_STALE:
case ND6_LLINFO_DELAY:
case ND6_LLINFO_PROBE:
(void)printf(" (reachable)\n");
break;
default:
(void)printf(" (unreachable)\n");
}
} else
(void)printf(" (no neighbor state)\n");
}
if (PR.advrtrs > DRLSTSIZ)
(void)printf(" and %d routers\n",
PR.advrtrs - DRLSTSIZ);
} else
(void)printf(" No advertising router\n");
}
#undef PR
(void)prog_close(s);
#endif
}
static void
pfx_flush(void)
{
int s;
struct in6_ifreq ifr;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, "lo0");
if (prog_ioctl(s, SIOCSPFXFLUSH_IN6, &ifr) < 0)
err(1, "ioctl(SIOCSPFXFLUSH_IN6)");
(void)prog_close(s);
}
static void
rtr_flush(void)
{
int s;
struct in6_ifreq ifr;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, "lo0");
if (prog_ioctl(s, SIOCSRTRFLUSH_IN6, &ifr) < 0)
err(1, "ioctl(SIOCSRTRFLUSH_IN6)");
(void)prog_close(s);
}
static void
harmonize_rtr(void)
{
char dummyif[IFNAMSIZ+8];
int s;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
(void)strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */
if (prog_ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0)
err(1, "ioctl(SIOCSNDFLUSH_IN6)");
(void)prog_close(s);
}
#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */
static void
setdefif(char *ifname)
{
struct in6_ndifreq ndifreq;
unsigned int ifindex;
int s;
if (strcasecmp(ifname, "delete") == 0)
ifindex = 0;
else {
if ((ifindex = if_nametoindex(ifname)) == 0)
err(1, "failed to resolve i/f index for %s", ifname);
}
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
(void)strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */
ndifreq.ifindex = ifindex;
if (prog_ioctl(s, SIOCSDEFIFACE_IN6, &ndifreq) < 0)
err(1, "ioctl(SIOCSDEFIFACE_IN6)");
(void)prog_close(s);
}
static void
getdefif(void)
{
struct in6_ndifreq ndifreq;
char ifname[IFNAMSIZ+8];
int s;
if ((s = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
(void)memset(&ndifreq, 0, sizeof(ndifreq));
(void)strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */
if (prog_ioctl(s, SIOCGDEFIFACE_IN6, &ndifreq) < 0)
err(1, "ioctl(SIOCGDEFIFACE_IN6)");
if (ndifreq.ifindex == 0)
(void)printf("No default interface.\n");
else {
if ((if_indextoname((unsigned int)ndifreq.ifindex, ifname)) == NULL)
err(1, "failed to resolve ifname for index %lu",
ndifreq.ifindex);
(void)printf("ND default interface = %s\n", ifname);
}
(void)prog_close(s);
}
#endif
static const char *
sec2str(time_t total)
{