aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/nd6_nbr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/nd6_nbr.c')
-rw-r--r--sys/netinet6/nd6_nbr.c95
1 files changed, 53 insertions, 42 deletions
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index af6be371e38a..e91a1435332f 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -121,30 +121,33 @@ VNET_DEFINE_STATIC(int, dad_maxtry) = 15; /* max # of *tries* to
void
nd6_ns_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ifnet *ifp;
+ struct ip6_hdr *ip6;
struct nd_neighbor_solicit *nd_ns;
- struct in6_addr saddr6 = ip6->ip6_src;
- struct in6_addr daddr6 = ip6->ip6_dst;
- struct in6_addr taddr6;
- struct in6_addr myaddr6;
- char *lladdr = NULL;
- struct ifaddr *ifa = NULL;
- int lladdrlen = 0;
- int anycast = 0, proxy = 0, tentative = 0;
- int tlladdr;
- int rflag;
- union nd_opts ndopts;
+ struct in6_addr daddr6, myaddr6, saddr6, taddr6;
+ struct ifaddr *ifa;
struct sockaddr_dl proxydl;
+ union nd_opts ndopts;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ char *lladdr;
+ int anycast, lladdrlen, proxy, rflag, tentative, tlladdr;
+
+ ifa = NULL;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
- rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
- if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
- rflag = 0;
+ ifp = m->m_pkthdr.rcvif;
+ ip6 = mtod(m, struct ip6_hdr *);
+ if (ip6->ip6_hlim != 255) {
+ nd6log((LOG_ERR,
+ "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
+ ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
+ ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
+ goto bads;
+ }
+
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, icmp6len,);
nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
@@ -156,17 +159,16 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
}
#endif
ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
+
+ saddr6 = ip6->ip6_src;
+ daddr6 = ip6->ip6_dst;
taddr6 = nd_ns->nd_ns_target;
if (in6_setscope(&taddr6, ifp, NULL) != 0)
goto bad;
- if (ip6->ip6_hlim != 255) {
- nd6log((LOG_ERR,
- "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
- ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
- ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
- goto bad;
- }
+ rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
+ rflag = 0;
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
/* dst has to be a solicited node multicast address. */
@@ -215,6 +217,8 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_src_lladdr) {
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
@@ -254,6 +258,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
/* (2) check. */
+ proxy = 0;
if (ifa == NULL) {
struct sockaddr_dl rt_gateway;
struct rt_addrinfo info;
@@ -380,6 +385,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
ip6_sprintf(ip6bufs, &daddr6)));
nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n",
ip6_sprintf(ip6bufs, &taddr6)));
+ bads:
ICMP6STAT_INC(icp6s_badns);
if (ifa != NULL)
ifa_free(ifa);
@@ -614,34 +620,34 @@ nd6_ns_output(struct ifnet *ifp, const struct in6_addr *saddr6,
void
nd6_na_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct nd_neighbor_advert *nd_na;
- struct in6_addr daddr6 = ip6->ip6_dst;
- struct in6_addr taddr6;
- int flags;
- int is_router;
- int is_solicited;
- int is_override;
- char *lladdr = NULL;
- int lladdrlen = 0;
- int checklink = 0;
+ struct ifnet *ifp;
+ struct ip6_hdr *ip6;
struct ifaddr *ifa;
- struct llentry *ln = NULL;
- union nd_opts ndopts;
- struct mbuf *chain = NULL;
+ struct llentry *ln;
+ struct mbuf *chain;
+ struct nd_neighbor_advert *nd_na;
+ struct in6_addr daddr6, taddr6;
struct sockaddr_in6 sin6;
+ union nd_opts ndopts;
u_char linkhdr[LLE_MAX_LINKHDR];
- size_t linkhdrsize;
- int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ char *lladdr;
+ size_t linkhdrsize;
+ int flags, is_override, is_router, is_solicited;
+ int lladdr_off, lladdrlen, checklink;
NET_EPOCH_ASSERT();
+ chain = NULL;
+ ln = NULL;
+ checklink = 0;
+
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
+ ifp = m->m_pkthdr.rcvif;
+ ip6 = mtod(m, struct ip6_hdr *);
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
@@ -665,7 +671,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
- memset(&sin6, 0, sizeof(sin6));
taddr6 = nd_na->nd_na_target;
if (in6_setscope(&taddr6, ifp, NULL))
@@ -677,6 +682,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
ip6_sprintf(ip6bufs, &taddr6)));
goto bad;
}
+
+ daddr6 = ip6->ip6_dst;
if (IN6_IS_ADDR_MULTICAST(&daddr6))
if (is_solicited) {
nd6log((LOG_ERR,
@@ -693,6 +700,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_tgt_lladdr) {
lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
@@ -888,8 +897,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* rt->rt_flags &= ~RTF_REJECT;
*/
ln->la_asked = 0;
- if (ln->la_hold != NULL)
+ if (ln->la_hold != NULL) {
+ memset(&sin6, 0, sizeof(sin6));
nd6_grab_holdchain(ln, &chain, &sin6);
+ }
freeit:
if (ln != NULL)
LLE_WUNLOCK(ln);