Lines 315-320
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
315 |
struct inpcb *last; |
315 |
struct inpcb *last; |
316 |
struct inpcbhead *pcblist; |
316 |
struct inpcbhead *pcblist; |
317 |
struct ip6_moptions *imo; |
317 |
struct ip6_moptions *imo; |
|
|
318 |
bool inp_locked = false; |
318 |
|
319 |
|
319 |
/* |
320 |
/* |
320 |
* In the event that laddr should be set to the link-local |
321 |
* In the event that laddr should be set to the link-local |
Lines 365-371
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
365 |
* and source-specific multicast. [RFC3678] |
366 |
* and source-specific multicast. [RFC3678] |
366 |
*/ |
367 |
*/ |
367 |
imo = inp->in6p_moptions; |
368 |
imo = inp->in6p_moptions; |
368 |
if (imo && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
369 |
if (imo != NULL) { |
369 |
struct sockaddr_in6 mcaddr; |
370 |
struct sockaddr_in6 mcaddr; |
370 |
int blocked; |
371 |
int blocked; |
371 |
|
372 |
|
Lines 392-399
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
392 |
INP_RUNLOCK(inp); /* XXX */ |
393 |
INP_RUNLOCK(inp); /* XXX */ |
393 |
continue; |
394 |
continue; |
394 |
} |
395 |
} |
395 |
|
396 |
inp_locked = true; |
396 |
INP_RUNLOCK(inp); |
|
|
397 |
} |
397 |
} |
398 |
if (last != NULL) { |
398 |
if (last != NULL) { |
399 |
struct mbuf *n; |
399 |
struct mbuf *n; |
Lines 409-414
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
409 |
UDP_PROBE(receive, NULL, last, |
409 |
UDP_PROBE(receive, NULL, last, |
410 |
ip6, last, uh); |
410 |
ip6, last, uh); |
411 |
if (udp6_append(last, n, off, fromsa)) { |
411 |
if (udp6_append(last, n, off, fromsa)) { |
|
|
412 |
if (inp_locked) |
413 |
INP_RUNLOCK(inp); |
412 |
/* XXX-BZ do we leak m here? */ |
414 |
/* XXX-BZ do we leak m here? */ |
413 |
*mp = NULL; |
415 |
*mp = NULL; |
414 |
return (IPPROTO_DONE); |
416 |
return (IPPROTO_DONE); |
Lines 426-434
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
426 |
* non-shared port. It assumes that an application |
428 |
* non-shared port. It assumes that an application |
427 |
* will never clear these options after setting them. |
429 |
* will never clear these options after setting them. |
428 |
*/ |
430 |
*/ |
|
|
431 |
if (!inp_locked) { |
432 |
INP_RLOCK(last); |
433 |
if (__predict_true(last->inp_flags2 & INP_FREED) != 0) { |
434 |
INP_RUNLOCK(last); |
435 |
continue; |
436 |
} |
437 |
inp_locked = true; |
438 |
} |
429 |
if ((last->inp_socket->so_options & |
439 |
if ((last->inp_socket->so_options & |
430 |
(SO_REUSEPORT|SO_REUSEPORT_LB|SO_REUSEADDR)) == 0) |
440 |
(SO_REUSEPORT|SO_REUSEPORT_LB|SO_REUSEADDR)) == 0) |
431 |
break; |
441 |
break; |
|
|
442 |
|
443 |
if (inp_locked) { |
444 |
INP_RUNLOCK(last); |
445 |
inp_locked = false; |
446 |
} |
432 |
} |
447 |
} |
433 |
|
448 |
|
434 |
if (last == NULL) { |
449 |
if (last == NULL) { |
Lines 441-447
udp6_input(struct mbuf **mp, int *offp, int proto)
Link Here
|
441 |
UDPSTAT_INC(udps_noportmcast); |
456 |
UDPSTAT_INC(udps_noportmcast); |
442 |
goto badunlocked; |
457 |
goto badunlocked; |
443 |
} |
458 |
} |
444 |
INP_RLOCK(last); |
459 |
|
|
|
460 |
if (!inp_locked) |
461 |
INP_RLOCK(last); |
462 |
|
445 |
if (__predict_true(last->inp_flags2 & INP_FREED) == 0) { |
463 |
if (__predict_true(last->inp_flags2 & INP_FREED) == 0) { |
446 |
if (nxt == IPPROTO_UDPLITE) |
464 |
if (nxt == IPPROTO_UDPLITE) |
447 |
UDPLITE_PROBE(receive, NULL, last, ip6, last, uh); |
465 |
UDPLITE_PROBE(receive, NULL, last, ip6, last, uh); |