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