summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-07-21 13:01:21 +0000
committerbz <bz@FreeBSD.org>2010-07-21 13:01:21 +0000
commitb43b431ac5818712fd49d5f56f6be7e14471acf5 (patch)
tree0b1727917ead89d30288f037e385dc158e3e3f2a /sys/netinet6
parentb4224af6478755d76e224d01882ff1b023987648 (diff)
downloadFreeBSD-src-b43b431ac5818712fd49d5f56f6be7e14471acf5.zip
FreeBSD-src-b43b431ac5818712fd49d5f56f6be7e14471acf5.tar.gz
Since r186119 IP6 input counters for octets and packets were not
working anymore. In addition more checks and operations were missing. In case lla_lookup results in a match, get the ifaddr to update the statistics counters, and check that the address is neither tentative, duplicate or otherwise invalid before accepting the packet. If ok, record the address information in the mbuf. [ as is done in case lla_lookup does not return a result and we go through the FIB ]. Reported by: remko Tested by: remko MFC after: 2 weeks
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_input.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 9e7573a..ec82250 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -514,10 +514,54 @@ passin:
(struct sockaddr *)&dst6);
IF_AFDATA_UNLOCK(ifp);
if ((lle != NULL) && (lle->la_flags & LLE_IFADDR)) {
- ours = 1;
- deliverifp = ifp;
+ struct ifaddr *ifa;
+ struct in6_ifaddr *ia6;
+ int bad;
+
+ bad = 1;
+#define sa_equal(a1, a2) \
+ (bcmp((a1), (a2), ((a1))->sin6_len) == 0)
+ IF_ADDR_LOCK(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family != dst6.sin6_family)
+ continue;
+ if (sa_equal(&dst6, ifa->ifa_addr))
+ break;
+ }
+ KASSERT(ifa != NULL, ("%s: ifa not found for lle %p",
+ __func__, lle));
+#undef sa_equal
+
+ ia6 = (struct in6_ifaddr *)ifa;
+ if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
+ /* Count the packet in the ip address stats */
+ ia6->ia_ifa.if_ipackets++;
+ ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
+
+ /*
+ * record address information into m_tag.
+ */
+ (void)ip6_setdstifaddr(m, ia6);
+
+ bad = 0;
+ } else {
+ char ip6bufs[INET6_ADDRSTRLEN];
+ char ip6bufd[INET6_ADDRSTRLEN];
+ /* address is not ready, so discard the packet. */
+ nd6log((LOG_INFO,
+ "ip6_input: packet to an unready address %s->%s\n",
+ ip6_sprintf(ip6bufs, &ip6->ip6_src),
+ ip6_sprintf(ip6bufd, &ip6->ip6_dst)));
+ }
+ IF_ADDR_UNLOCK(ifp);
LLE_RUNLOCK(lle);
- goto hbhcheck;
+ if (bad)
+ goto bad;
+ else {
+ ours = 1;
+ deliverifp = ifp;
+ goto hbhcheck;
+ }
}
if (lle != NULL)
LLE_RUNLOCK(lle);
OpenPOWER on IntegriCloud