summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet6/frag6.c25
-rw-r--r--sys/netinet6/icmp6.c68
-rw-r--r--sys/netinet6/ip6_input.c42
-rw-r--r--sys/netinet6/ip6_var.h4
-rw-r--r--sys/netinet6/route6.c7
5 files changed, 69 insertions, 77 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 121307d..3bb425f 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -144,14 +144,13 @@ frag6_input(mp, offp, proto)
struct ip6_frag *ip6f;
struct ip6q *q6;
struct ip6asfrag *af6, *ip6af, *af6dwn;
+#ifdef IN6_IFSTAT_STRICT
+ struct in6_ifaddr *ia;
+#endif
int offset = *offp, nxt, i, next;
int first_frag = 0;
int fragoff, frgpartlen; /* must be larger than u_int16_t */
struct ifnet *dstifp;
-#ifdef IN6_IFSTAT_STRICT
- static struct route_in6 ro;
- struct sockaddr_in6 *dst;
-#endif
ip6 = mtod(m, struct ip6_hdr *);
#ifndef PULLDOWN_TEST
@@ -166,22 +165,8 @@ frag6_input(mp, offp, proto)
dstifp = NULL;
#ifdef IN6_IFSTAT_STRICT
/* find the destination interface of the packet. */
- dst = (struct sockaddr_in6 *)&ro.ro_dst;
- if (ro.ro_rt
- && ((ro.ro_rt->rt_flags & RTF_UP) == 0
- || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) {
- RTFREE(ro.ro_rt);
- ro.ro_rt = (struct rtentry *)0;
- }
- if (ro.ro_rt == NULL) {
- bzero(dst, sizeof(*dst));
- dst->sin6_family = AF_INET6;
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_addr = ip6->ip6_dst;
- }
- rtalloc((struct route *)&ro);
- if (ro.ro_rt != NULL && ro.ro_rt->rt_ifa != NULL)
- dstifp = ((struct in6_ifaddr *)ro.ro_rt->rt_ifa)->ia_ifp;
+ if ((ia = ip6_getdstifaddr(m)) != NULL)
+ dstifp = ia->ia_ifp;
#else
/* we are violating the spec, this is not the destination interface */
if ((m->m_flags & M_PKTHDR) != 0)
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 30e534f..91ae896 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1185,8 +1185,8 @@ ni6_input(m, off)
struct ni_reply_fqdn *fqdn;
int addrs; /* for NI_QTYPE_NODEADDR */
struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */
- struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */
- struct sockaddr_in6 sin6_d; /* XXX: we should retrieve this from m_aux */
+ struct sockaddr_in6 sin6_sbj; /* subject address */
+ struct sockaddr_in6 sin6_d;
struct ip6_hdr *ip6;
int oldfqdn = 0; /* if 1, return pascal string (03 draft) */
char *subj = NULL;
@@ -1203,32 +1203,41 @@ ni6_input(m, off)
}
#endif
+ bzero(&sin6_d, sizeof(sin6_d));
+ sin6_d.sin6_family = AF_INET6; /* not used, actually */
+ sin6_d.sin6_len = sizeof(sin6_d); /* ditto */
+ sin6_d.sin6_addr = ip6->ip6_dst;
+ if (in6_addr2zoneid(m->m_pkthdr.rcvif, &ip6->ip6_dst,
+ &sin6_d.sin6_scope_id)) {
+ goto bad;
+ }
+ if (in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL))
+ goto bad; /* XXX should not happen */
+
/*
* Validate IPv6 destination address.
*
* The Responder must discard the Query without further processing
* unless it is one of the Responder's unicast or anycast addresses, or
* a link-local scope multicast address which the Responder has joined.
- * [icmp-name-lookups-07, Section 4.]
+ * [icmp-name-lookups-08, Section 4.]
*/
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
- /* XXX scopeid */
- if ((ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)&sin6)) != NULL) {
- /* unicast/anycast, fine */
- if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
- (icmp6_nodeinfo & 4) == 0) {
+ if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
+ if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst))
+ goto bad;
+ /* else it's a link-local multicast, fine */
+ } else { /* unicast or anycast */
+ if ((ia6 = ip6_getdstifaddr(m)) == NULL)
+ goto bad; /* XXX impossible */
+
+ if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) &&
+ !(icmp6_nodeinfo & 4)) {
nd6log((LOG_DEBUG, "ni6_input: ignore node info to "
"a temporary address in %s:%d",
__FILE__, __LINE__));
goto bad;
}
- } else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr))
- ; /* link-local multicast, fine */
- else
- goto bad;
+ }
/* validate query Subject field. */
qtype = ntohs(ni6->ni_qtype);
@@ -1261,7 +1270,7 @@ ni6_input(m, off)
goto bad;
#endif
- if (subjlen != sizeof(sin6.sin6_addr))
+ if (subjlen != sizeof(struct in6_addr))
goto bad;
/*
@@ -1279,24 +1288,21 @@ ni6_input(m, off)
* We do not do proxy at this moment.
*/
/* m_pulldown instead of copy? */
+ bzero(&sin6_sbj, sizeof(sin6_sbj));
+ sin6_sbj.sin6_family = AF_INET6;
+ sin6_sbj.sin6_len = sizeof(sin6_sbj);
m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
- subjlen, (caddr_t)&sin6.sin6_addr);
+ subjlen, (caddr_t)&sin6_sbj.sin6_addr);
if (in6_addr2zoneid(m->m_pkthdr.rcvif,
- &sin6.sin6_addr, &sin6.sin6_scope_id)) {
+ &sin6_sbj.sin6_addr, &sin6_sbj.sin6_scope_id)) {
goto bad;
}
- in6_embedscope(&sin6.sin6_addr, &sin6, NULL, NULL);
- bzero(&sin6_d, sizeof(sin6_d));
- sin6_d.sin6_family = AF_INET6; /* not used, actually */
- sin6_d.sin6_len = sizeof(sin6_d); /* ditto */
- sin6_d.sin6_addr = ip6->ip6_dst;
- if (in6_addr2zoneid(m->m_pkthdr.rcvif,
- &ip6->ip6_dst, &sin6_d.sin6_scope_id)) {
- goto bad;
- }
- in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL);
- subj = (char *)&sin6;
- if (SA6_ARE_ADDR_EQUAL(&sin6, &sin6_d))
+ if (in6_embedscope(&sin6_sbj.sin6_addr, &sin6_sbj,
+ NULL, NULL))
+ goto bad; /* XXX should not happen */
+
+ subj = (char *)&sin6_sbj;
+ if (SA6_ARE_ADDR_EQUAL(&sin6_sbj, &sin6_d))
break;
/*
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index b823097..fdeebf7 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -157,7 +157,7 @@ int ip6_fw_enable = 1;
struct ip6stat ip6stat;
static void ip6_init2 __P((void *));
-static struct ip6aux *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
+static struct m_tag *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
#ifdef PULLDOWN_TEST
static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int));
@@ -259,7 +259,7 @@ ip6_input(m)
#endif
/*
- * make sure we don't have onion peering information into m_aux.
+ * make sure we don't have onion peering information into m_tag.
*/
ip6_delaux(m);
@@ -544,7 +544,7 @@ ip6_input(m)
(struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa;
/*
- * record address information into m_aux.
+ * record address information into m_tag.
*/
(void)ip6_setdstifaddr(m, ia6);
@@ -596,7 +596,7 @@ ip6_input(m)
hbhcheck:
/*
- * record address information into m_aux, if we don't have one yet.
+ * record address information into m_tag, if we don't have one yet.
* note that we are unable to record it, if the address is not listed
* as our interface address (e.g. multicast addresses, addresses
* within FAITH prefixes and such).
@@ -801,28 +801,28 @@ ip6_input(m)
* set/grab in6_ifaddr correspond to IPv6 destination address.
* XXX backward compatibility wrapper
*/
-static struct ip6aux *
+static struct m_tag *
ip6_setdstifaddr(m, ia6)
struct mbuf *m;
struct in6_ifaddr *ia6;
{
- struct ip6aux *n;
+ struct m_tag *mtag;
- n = ip6_addaux(m);
- if (n)
- n->ip6a_dstia6 = ia6;
- return n; /* NULL if failed to set */
+ mtag = ip6_addaux(m);
+ if (mtag)
+ ((struct ip6aux *)(mtag + 1))->ip6a_dstia6 = ia6;
+ return mtag; /* NULL if failed to set */
}
struct in6_ifaddr *
ip6_getdstifaddr(m)
struct mbuf *m;
{
- struct ip6aux *n;
+ struct m_tag *mtag;
- n = ip6_findaux(m);
- if (n)
- return n->ip6a_dstia6;
+ mtag = ip6_findaux(m);
+ if (mtag)
+ return ((struct ip6aux *)(mtag + 1))->ip6a_dstia6;
else
return NULL;
}
@@ -1534,7 +1534,7 @@ ip6_lasthdr(m, off, proto, nxtp)
}
}
-struct ip6aux *
+struct m_tag *
ip6_addaux(m)
struct mbuf *m;
{
@@ -1544,22 +1544,22 @@ ip6_addaux(m)
if (!mtag) {
mtag = m_tag_get(PACKET_TAG_IPV6_INPUT, sizeof(struct ip6aux),
M_NOWAIT);
- if (mtag)
+ if (mtag) {
m_tag_prepend(m, mtag);
+ bzero(mtag + 1, sizeof(struct ip6aux));
+ }
}
- if (mtag)
- bzero(mtag+1, sizeof (struct ip6aux));
- return mtag ? (struct ip6aux*)(mtag+1) : NULL;
+ return mtag;
}
-struct ip6aux *
+struct m_tag *
ip6_findaux(m)
struct mbuf *m;
{
struct m_tag *mtag;
mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
- return mtag ? (struct ip6aux*)(mtag+1) : NULL;
+ return mtag;
}
void
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 6edaa1c..8206755 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -345,8 +345,8 @@ char * ip6_get_prevhdr __P((struct mbuf *, int));
int ip6_nexthdr __P((struct mbuf *, int, int, int *));
int ip6_lasthdr __P((struct mbuf *, int, int, int *));
-struct ip6aux *ip6_addaux __P((struct mbuf *));
-struct ip6aux *ip6_findaux __P((struct mbuf *));
+struct m_tag *ip6_addaux __P((struct mbuf *));
+struct m_tag *ip6_findaux __P((struct mbuf *));
void ip6_delaux __P((struct mbuf *));
int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c
index c4b0f61..567d0ba 100644
--- a/sys/netinet6/route6.c
+++ b/sys/netinet6/route6.c
@@ -60,10 +60,11 @@ route6_input(mp, offp, proto)
struct mbuf *m = *mp;
struct ip6_rthdr *rh;
int off = *offp, rhlen;
- struct ip6aux *ip6a;
+ struct m_tag *mtag;
- ip6a = ip6_findaux(m);
- if (ip6a) {
+ mtag = ip6_findaux(m);
+ if (mtag) {
+ struct ip6aux *ip6a = (struct ip6aux *)(mtag + 1);
/* XXX reject home-address option before rthdr */
if (ip6a->ip6a_flags & IP6A_SWAP) {
ip6stat.ip6s_badoptions++;
OpenPOWER on IntegriCloud