diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -128,6 +129,38 @@ #include +SDT_PROVIDER_DEFINE(if_stf); +SDT_PROBE_DEFINE3(if_stf, , encapcheck, in, "struct mbuf *", "int", "int"); +SDT_PROBE_DEFINE0(if_stf, , encapcheck, accept); +SDT_PROBE_DEFINE3(if_stf, , getsrcifa6, in, "struct ifnet *", + "struct in6_addr *", "struct in6_addr *"); +SDT_PROBE_DEFINE2(if_stf, , getsrcifa6, found, "struct in6_addr *", + "struct in6_addr *"); +SDT_PROBE_DEFINE0(if_stf, , getsrcifa6, notfound); + +SDT_PROBE_DEFINE4(if_stf, , stf_output, in, "struct ifnet *", "struct mbuf *", + "struct sockaddr *", "struct route *"); +SDT_PROBE_DEFINE2(if_stf, , stf_output, error, "int", "int"); +SDT_PROBE_DEFINE1(if_stf, , stf_output, out, "int"); + +SDT_PROBE_DEFINE3(if_stf, , checkaddr6, in, "struct stf_softc *", + "struct in6_addr *", "struct ifnet *"); +SDT_PROBE_DEFINE2(if_stf, , checkaddr6, out, "int", "int"); + +SDT_PROBE_DEFINE3(if_stf, , stf_input, in, "struct mbuf *", "int", "int"); +SDT_PROBE_DEFINE2(if_stf, , stf_input, out, "int", "int"); + +SDT_PROBE_DEFINE3(if_stf, , ioctl, sv4net, "struct in_addr *", + "struct in_addr *", "int"); +SDT_PROBE_DEFINE1(if_stf, , ioctl, sdstv4, "struct in_addr *"); +SDT_PROBE_DEFINE1(if_stf, , ioctl, ifaddr, "struct ifaddr *"); + +SDT_PROBE_DEFINE4(if_stf, , getin4addr_in6, out, "struct in6_addr *", + "struct in6_addr *", "struct in6_addr *", "struct sockaddr_in *"); + +SDT_PROBE_DEFINE2(if_stf, , getin4addr, in, "struct in6_addr *", "struct in6_addr *"); +SDT_PROBE_DEFINE1(if_stf, , getin4addr, out, "struct sockaddr_in *"); + SYSCTL_DECL(_net_link); static SYSCTL_NODE(_net_link, IFT_STF, stf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "6to4 Interface"); @@ -349,6 +382,8 @@ struct in6_addr addr6, mask6; struct sockaddr_in sin4addr, sin4mask; + SDT_PROBE3(if_stf, , encapcheck, in, m, off, proto); + sc = (struct stf_softc *)arg; if (sc == NULL) return (0); @@ -408,6 +443,8 @@ */ } + SDT_PROBE0(if_stf, , encapcheck, accept); + /* stf interface makes single side match only */ return (32); } @@ -426,6 +463,8 @@ sc = ifp->if_softc; + SDT_PROBE3(if_stf, , getsrcifa6, in, ifp, addr, mask); + CK_STAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) { if (ia->ifa_addr->sa_family != AF_INET6) continue; @@ -449,9 +488,13 @@ *addr = addr6; *mask = mask6; + SDT_PROBE2(if_stf, , getsrcifa6, found, addr, mask); + return (0); } + SDT_PROBE0(if_stf, , getsrcifa6, notfound); + return (ENOENT); } @@ -468,10 +511,13 @@ struct in6_addr addr6, mask6; int error; + SDT_PROBE4(if_stf, , stf_output, in, ifp, m, dst, ro); + #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); if (error) { m_freem(m); + SDT_PROBE2(if_stf, , stf_output, error, error, __LINE__); return (error); } #endif @@ -483,6 +529,7 @@ if ((ifp->if_flags & IFF_UP) == 0) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENETDOWN, __LINE__); return (ENETDOWN); } @@ -494,6 +541,7 @@ if (stf_getsrcifa6(ifp, &addr6, &mask6) != 0) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENETDOWN, __LINE__); return (ENETDOWN); } @@ -501,6 +549,8 @@ m = m_pullup(m, sizeof(*ip6)); if (!m) { if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENOBUFS, + __LINE__); return (ENOBUFS); } } @@ -519,6 +569,8 @@ dst6->sin6_addr) == NULL) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENETUNREACH, + __LINE__); return (ENETUNREACH); } } @@ -538,6 +590,7 @@ M_PREPEND(m, sizeof(struct ip), M_NOWAIT); if (m == NULL) { if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENOBUFS, __LINE__); return (ENOBUFS); } ip = mtod(m, struct ip *); @@ -549,6 +602,7 @@ else if (stf_getin4addr(sc, &src4, addr6, mask6) == NULL) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + SDT_PROBE2(if_stf, , stf_output, error, ENETUNREACH, __LINE__); return (ENETUNREACH); } bcopy(&src4.sin_addr, &ip->ip_src, sizeof(ip->ip_src)); @@ -566,6 +620,7 @@ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); error = ip_output(m, NULL, NULL, 0, NULL, NULL); + SDT_PROBE1(if_stf, , stf_output, out, error); return (error); } @@ -633,13 +688,19 @@ static int stf_checkaddr6(struct stf_softc *sc, struct in6_addr *in6, struct ifnet *inifp) { + SDT_PROBE3(if_stf, , checkaddr6, in, sc, in6, inifp); + /* * check 6to4 addresses */ if (IN6_IS_ADDR_6TO4(in6)) { struct in_addr in4; + int ret; + bcopy(GET_V4(in6), &in4, sizeof(in4)); - return (stf_checkaddr4(sc, &in4, inifp)); + ret = stf_checkaddr4(sc, &in4, inifp); + SDT_PROBE2(if_stf, , checkaddr6, out, ret, __LINE__); + return (ret); } /* @@ -648,9 +709,17 @@ * (1) reject bad packets earlier, and * (2) to be safe against future ip6_input change. */ - if (IN6_IS_ADDR_V4COMPAT(in6) || IN6_IS_ADDR_V4MAPPED(in6)) + if (IN6_IS_ADDR_V4COMPAT(in6)) { + SDT_PROBE2(if_stf, , checkaddr6, out, -1, __LINE__); return (-1); + } + if (IN6_IS_ADDR_V4MAPPED(in6)) { + SDT_PROBE2(if_stf, , checkaddr6, out, -1, __LINE__); + return (-1); + } + + SDT_PROBE2(if_stf, , checkaddr6, out, 0, __LINE__); return (0); } @@ -666,14 +735,18 @@ NET_EPOCH_ASSERT(); + SDT_PROBE3(if_stf, , stf_input, in, m, off, proto); + if (proto != IPPROTO_IPV6) { m_freem(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } ip = mtod(m, struct ip *); if (sc == NULL || (STF2IFP(sc)->if_flags & IFF_UP) == 0) { m_freem(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -690,6 +763,7 @@ if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 || stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) { m_freem(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -698,8 +772,11 @@ if (m->m_len < sizeof(*ip6)) { m = m_pullup(m, sizeof(*ip6)); - if (!m) + if (!m) { + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, + __LINE__); return (IPPROTO_DONE); + } } ip6 = mtod(m, struct ip6_hdr *); @@ -710,6 +787,7 @@ if (stf_checkaddr6(sc, &ip6->ip6_dst, NULL) < 0 || stf_checkaddr6(sc, &ip6->ip6_src, m->m_pkthdr.rcvif) < 0) { m_freem(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -720,6 +798,7 @@ if ((IN6_IS_ADDR_6TO4(&ip6->ip6_src) && isrfc1918addr(&ip->ip_src)) || (IN6_IS_ADDR_6TO4(&ip6->ip6_dst) && isrfc1918addr(&ip->ip_dst))) { m_freem(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -731,11 +810,13 @@ nh = fib6_lookup(sc->sc_fibnum, &ip6->ip6_dst, 0, 0, 0); if (nh == NULL) { m_free(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } if ((nh->nh_ifp == ifp) && (!IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &nh->gw6_sa.sin6_addr))) { m_free(m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -771,6 +852,7 @@ if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); M_SETFIB(m, ifp->if_fib); netisr_dispatch(NETISR_IPV6, m); + SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__); return (IPPROTO_DONE); } @@ -779,6 +861,7 @@ struct in6_addr addr6, struct in6_addr mask6, struct in6_addr in6) { int i; + struct sockaddr_in *out; /* * When (src addr & src mask) != (in6 & src mask), @@ -787,12 +870,17 @@ */ for (i = 0; i < sizeof(addr6); i++) { if ((((u_char *)&addr6)[i] & ((u_char *)&mask6)[i]) != - (((u_char *)&in6)[i] & ((u_char *)&mask6)[i])) - return (NULL); + (((u_char *)&in6)[i] & ((u_char *)&mask6)[i])) { + SDT_PROBE4(if_stf, , getin4addr_in6, out, &addr6, + &mask6, &in6, NULL); + return (NULL); + } } /* After the mask check, use in6 instead of addr6. */ - return (stf_getin4addr(sc, sin, in6, mask6)); + out = stf_getin4addr(sc, sin, in6, mask6); + SDT_PROBE4(if_stf, , getin4addr_in6, out, &addr6, &mask6, &in6, out); + return (out); } static struct sockaddr_in * @@ -801,6 +889,8 @@ { struct in_addr *in; + SDT_PROBE2(if_stf, , getin4addr, in, &addr6, &mask6); + memset(sin, 0, sizeof(*sin)); in = &sin->sin_addr; if (IN6_IS_ADDR_6TO4(&addr6)) { @@ -845,6 +935,8 @@ sin->sin_addr.s_addr = htonl(v4prefix | (uint32_t)v6prefix); } + SDT_PROBE1(if_stf, , getin4addr, out, sin); + return (sin); } @@ -886,6 +978,8 @@ bcopy(&args.srcv4_addr, &sc_cur->srcv4_addr, sizeof(sc_cur->srcv4_addr)); sc_cur->v4prefixlen = args.v4_prefixlen; + SDT_PROBE3(if_stf, , ioctl, sv4net, sc_cur->srcv4_addr, + sc_cur->srcv4_addr, sc_cur->v4prefixlen); } else if (ifd->ifd_cmd == STF6RD_SBR) { if (ifd->ifd_len != sizeof(args)) { error = EINVAL; @@ -896,6 +990,8 @@ if (error) break; sc_cur->braddr = args.braddr.s_addr; + SDT_PROBE1(if_stf, , ioctl, sdstv4, + sc_cur->braddr); } else error = EINVAL; break; @@ -917,6 +1013,7 @@ break; case SIOCSIFADDR: ifa = (struct ifaddr *)data; + SDT_PROBE1(if_stf, , ioctl, ifaddr, ifa); if (ifa == NULL || ifa->ifa_addr->sa_family != AF_INET6) { error = EAFNOSUPPORT; break;