Index: sys/net/if_stf.c =================================================================== --- sys/net/if_stf.c +++ sys/net/if_stf.c @@ -89,6 +89,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,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"); @@ -346,6 +379,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); @@ -405,6 +440,8 @@ */ } + SDT_PROBE0(if_stf, , encapcheck, accept); + /* stf interface makes single side match only */ return (32); } @@ -424,6 +461,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; @@ -448,9 +487,13 @@ *addr = addr6; *mask = mask6; + SDT_PROBE2(if_stf, , getsrcifa6, found, addr, mask); + return (0); } + SDT_PROBE0(if_stf, , getsrcifa6, notfound); + return (ENOENT); } @@ -467,10 +510,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 @@ -482,6 +528,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); } @@ -493,6 +540,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); } @@ -500,6 +548,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); } } @@ -518,6 +568,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); } } @@ -537,6 +589,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 *); @@ -548,6 +601,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)); @@ -565,6 +619,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); } @@ -632,13 +687,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); } /* @@ -647,9 +708,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); } @@ -665,14 +734,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); } @@ -689,6 +762,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); } @@ -697,8 +771,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 *); @@ -709,6 +786,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); } @@ -719,6 +797,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); } @@ -730,11 +809,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); } @@ -770,6 +851,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); } @@ -778,6 +860,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), @@ -786,12 +869,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 * @@ -800,6 +888,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)) { @@ -841,6 +931,8 @@ sin->sin_addr.s_addr = htonl(v4prefix | (uint32_t)v6prefix); } + SDT_PROBE1(if_stf, , getin4addr, out, sin); + return (sin); } @@ -878,6 +970,8 @@ sc_cur->v4prefixlen = args.v4_prefixlen; if (sc_cur->v4prefixlen == 0) sc_cur->v4prefixlen = 32; + 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; @@ -888,6 +982,8 @@ if (error) break; sc_cur->braddr = args.braddr.s_addr; + SDT_PROBE1(if_stf, , ioctl, sdstv4, + sc_cur->braddr); } else error = EINVAL; break; @@ -909,6 +1005,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;