diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 9c5ff4a49e79..757b1d1e1a59 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -278,6 +278,12 @@ ip6_input(m) #undef M2MMAX } + /* drop the packet if IPv6 operation is disabled on the IF */ + if ((ND_IFINFO(m->m_pkthdr.rcvif)->flags & ND6_IFF_IFDISABLED)) { + m_freem(m); + return; + } + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); ip6stat.ip6s_total++; diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index ae3664fa89fc..93186a5f8d2c 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1996,6 +1996,12 @@ nd6_output(ifp, origifp, m0, dst, rt0) return (0); sendpkt: + /* discard the packet if IPv6 operation is disabled on the interface */ + if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { + error = ENETDOWN; /* better error? */ + goto bad; + } + #ifdef IPSEC /* clean ipsec history once it goes out of the node */ ipsec_delaux(m); diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 33d241602e9b..760671c604c3 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -88,6 +88,10 @@ struct nd_ifinfo { #define ND6_IFF_PERFORMNUD 0x1 #define ND6_IFF_ACCEPT_RTADV 0x2 +#define ND6_IFF_PREFER_SOURCE 0x4 /* XXX: not related to ND. */ +#define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to + * DAD failure. (XXX: not ND-specific) + */ #ifdef _KERNEL #define ND_IFINFO(ifp) \ diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8 index ea33646af2d7..4d99527d781f 100644 --- a/usr.sbin/ndp/ndp.8 +++ b/usr.sbin/ndp/ndp.8 @@ -198,6 +198,19 @@ selection, see the .Pa IMPLEMENTATION file supplied with the KAME kit. .It Xo +.Ic disabled +.Xc +Disable IPv6 operation on the interface. +When disabled, the interface discards any IPv6 packets +received on or being sent to the interface. +In the sending case, an error of ENETDOWN will be returned to the +application. +This flag is typically set automatically in the kernel as a result of +a certain failure of Duplicate Address Detection. +While the flag can be set or cleared by hand with the +.Nm +command, it is not generally advisable to modify this flag manually. +.It Xo .Ic basereachable=(number) .Xc Specify the BaseReachbleTimer on the interface in millisecond. diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 96e8c149a2f2..33e1a6a9b718 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -989,6 +989,7 @@ ifinfo(ifname, argc, argv) } \ } while (0) + SETFLAG("disabled", ND6_IFF_IFDISABLED); SETFLAG("nud", ND6_IFF_PERFORMNUD); #ifdef ND6_IFF_ACCEPT_RTADV SETFLAG("accept_rtadv", ND6_IFF_ACCEPT_RTADV); @@ -1055,6 +1056,10 @@ ifinfo(ifname, argc, argv) #endif if (ND.flags) { printf("\nFlags: "); +#ifdef ND6_IFF_IFDISABLED + if ((ND.flags & ND6_IFF_IFDISABLED)) + printf("disabled "); +#endif if ((ND.flags & ND6_IFF_PERFORMNUD)) printf("nud "); #ifdef ND6_IFF_ACCEPT_RTADV