| 213 | } |
| 214 | |
| 215 | static void |
| 216 | in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp, |
| 217 | const struct sockaddr *sa, void *ctx) |
| 218 | { |
| 219 | struct epoch_tracker et; |
| 220 | struct gre_socket *gs; |
| 221 | struct gre_softc *sc; |
| 222 | struct sockaddr_in6 dst; |
| 223 | |
| 224 | NET_EPOCH_ENTER(et); |
| 225 | /* |
| 226 | * udp_append() holds reference to inp, it is safe to check |
| 227 | * inp_flags2 without INP_RLOCK(). |
| 228 | * If socket was closed before we have entered NET_EPOCH section, |
| 229 | * INP_FREED flag should be set. Otherwise it should be safe to |
| 230 | * make access to ctx data, because gre_so will be freed by |
| 231 | * gre_sofree() via NET_EPOCH_CALL(). |
| 232 | */ |
| 233 | if (__predict_false(inp->inp_flags2 & INP_FREED)) { |
| 234 | NET_EPOCH_EXIT(et); |
| 235 | m_freem(m); |
| 236 | return; |
| 237 | } |
| 238 | |
| 239 | gs = (struct gre_socket *)ctx; |
| 240 | dst = *(const struct sockaddr_in6 *)sa; |
| 241 | if (sa6_embedscope(&dst, 0)) { |
| 242 | NET_EPOCH_EXIT(et); |
| 243 | m_freem(m); |
| 244 | return; |
| 245 | } |
| 246 | CK_LIST_FOREACH(sc, &gs->list, chain) { |
| 247 | if (IN6_ARE_ADDR_EQUAL(&sc->gre_oip6.ip6_dst, &dst.sin6_addr)) |
| 248 | break; |
| 249 | } |
| 250 | if (sc != NULL && (GRE2IFP(sc)->if_flags & IFF_UP) != 0){ |
| 251 | gre_input(m, off + sizeof(struct udphdr), IPPROTO_UDP, sc); |
| 252 | NET_EPOCH_EXIT(et); |
| 253 | return; |
| 254 | } |
| 255 | m_freem(m); |
| 256 | NET_EPOCH_EXIT(et); |
| 257 | } |
| 258 | |
| 259 | static int |
| 260 | in6_gre_setup_socket(struct gre_softc *sc) |
nothing calls this directly
no test coverage detected