diff options
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 24 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 1 | ||||
-rw-r--r-- | sys/netinet6/in6_var.h | 1 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 3 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 14 |
5 files changed, 33 insertions, 10 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 8514f73..ef22f03 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/in_pcb.h> +#include <netinet/ip_carp.h> #include <netinet/ip6.h> #include <netinet6/ip6_var.h> @@ -272,6 +273,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct in6_ifaddr *ia = NULL; struct in6_aliasreq *ifra = (struct in6_aliasreq *)data; struct sockaddr_in6 *sa6; + int carp_attached = 0; int error; switch (cmd) { @@ -652,6 +654,18 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; } + if (ifra->ifra_vhid > 0) { + if (carp_attach_p != NULL) + error = (*carp_attach_p)(&ia->ia_ifa, + ifra->ifra_vhid); + else + error = EPROTONOSUPPORT; + if (error) + goto out; + else + carp_attached = 1; + } + /* * then, make the prefix on-link on the interface. * XXX: we'd rather create the prefix before the address, but @@ -695,9 +709,14 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, * nd6_prelist_add will install the corresponding * interface route. */ - if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) + if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) { + if (carp_attached) + (*carp_detach_p)(&ia->ia_ifa); goto out; + } if (pr == NULL) { + if (carp_attached) + (*carp_detach_p)(&ia->ia_ifa); log(LOG_ERR, "nd6_prelist_add succeeded but " "no prefix\n"); error = EINVAL; @@ -1301,6 +1320,9 @@ in6_purgeaddr(struct ifaddr *ifa) struct rtentry *rt; struct ifaddr *ifa0, *nifa; + if (ifa->ifa_carp) + (*carp_detach_p)(ifa); + /* * find another IPv6 address as the gateway for the * link-local and node-local all-nodes multicast diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 2ff7455..1dae2c0 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -705,7 +705,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) switch (ifp->if_type) { case IFT_PFLOG: case IFT_PFSYNC: - case IFT_CARP: return; } diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 00342fd..3e93e71 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -287,6 +287,7 @@ struct in6_aliasreq { struct sockaddr_in6 ifra_prefixmask; int ifra_flags; struct in6_addrlifetime ifra_lifetime; + int ifra_vhid; }; /* prefix type macro */ diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 875daa0..5d6f8c0 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2173,9 +2173,6 @@ nd6_need_cache(struct ifnet *ifp) #ifdef IFT_IEEE80211 case IFT_IEEE80211: #endif -#ifdef IFT_CARP - case IFT_CARP: -#endif case IFT_INFINIBAND: case IFT_GIF: /* XXX need more cases? */ case IFT_PPP: diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 0221c72..a2aaeea 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -225,7 +225,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) /* (1) and (3) check. */ if (ifp->if_carp) ifa = (*carp_iamatch6_p)(ifp, &taddr6); - if (ifa == NULL) + else ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); /* (2) check. */ @@ -688,7 +688,14 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; } - ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); + /* + * This effectively disables the DAD check on a non-master CARP + * address. + */ + if (ifp->if_carp) + ifa = (*carp_iamatch6_p)(ifp, &taddr6); + else + ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); /* * Target address matches one of my interface address. @@ -1133,9 +1140,6 @@ nd6_ifptomac(struct ifnet *ifp) #ifdef IFT_IEEE80211 case IFT_IEEE80211: #endif -#ifdef IFT_CARP - case IFT_CARP: -#endif case IFT_INFINIBAND: case IFT_BRIDGE: case IFT_ISO88025: |