Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/ip6_gre.c
Show First 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | CK_LIST_FOREACH(sc, &GRE_SRCHASH(&sin->sin6_addr), srchash) { | ||||
in6_gre_set_running(sc); | in6_gre_set_running(sc); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp, | in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp, | ||||
const struct sockaddr *sa, void *ctx) | const struct sockaddr *sa, void *ctx) | ||||
{ | { | ||||
struct epoch_tracker et; | |||||
struct gre_socket *gs; | struct gre_socket *gs; | ||||
struct gre_softc *sc; | struct gre_softc *sc; | ||||
struct sockaddr_in6 dst; | struct sockaddr_in6 dst; | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ASSERT(); | ||||
/* | |||||
* udp_append() holds reference to inp, it is safe to check | |||||
* inp_flags2 without INP_RLOCK(). | |||||
* If socket was closed before we have entered NET_EPOCH section, | |||||
* INP_FREED flag should be set. Otherwise it should be safe to | |||||
* make access to ctx data, because gre_so will be freed by | |||||
* gre_sofree() via NET_EPOCH_CALL(). | |||||
*/ | |||||
if (__predict_false(inp->inp_flags2 & INP_FREED)) { | |||||
NET_EPOCH_EXIT(et); | |||||
m_freem(m); | |||||
return; | |||||
} | |||||
gs = (struct gre_socket *)ctx; | gs = (struct gre_socket *)ctx; | ||||
dst = *(const struct sockaddr_in6 *)sa; | dst = *(const struct sockaddr_in6 *)sa; | ||||
if (sa6_embedscope(&dst, 0)) { | if (sa6_embedscope(&dst, 0)) { | ||||
NET_EPOCH_EXIT(et); | |||||
m_freem(m); | m_freem(m); | ||||
return; | return; | ||||
} | } | ||||
CK_LIST_FOREACH(sc, &gs->list, chain) { | CK_LIST_FOREACH(sc, &gs->list, chain) { | ||||
if (IN6_ARE_ADDR_EQUAL(&sc->gre_oip6.ip6_dst, &dst.sin6_addr)) | if (IN6_ARE_ADDR_EQUAL(&sc->gre_oip6.ip6_dst, &dst.sin6_addr)) | ||||
break; | break; | ||||
} | } | ||||
if (sc != NULL && (GRE2IFP(sc)->if_flags & IFF_UP) != 0){ | if (sc != NULL && (GRE2IFP(sc)->if_flags & IFF_UP) != 0){ | ||||
gre_input(m, off + sizeof(struct udphdr), IPPROTO_UDP, sc); | gre_input(m, off + sizeof(struct udphdr), IPPROTO_UDP, sc); | ||||
NET_EPOCH_EXIT(et); | |||||
return; | return; | ||||
} | } | ||||
m_freem(m); | m_freem(m); | ||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
static int | static int | ||||
in6_gre_setup_socket(struct gre_softc *sc) | in6_gre_setup_socket(struct gre_softc *sc) | ||||
{ | { | ||||
struct sockopt sopt; | struct sockopt sopt; | ||||
struct sockaddr_in6 sin6; | struct sockaddr_in6 sin6; | ||||
struct in6_gre_socket *s; | struct in6_gre_socket *s; | ||||
▲ Show 20 Lines • Show All 330 Lines • Show Last 20 Lines |