| 1544 | #undef IS2292 |
| 1545 | |
| 1546 | void |
| 1547 | ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu) |
| 1548 | { |
| 1549 | struct socket *so; |
| 1550 | struct mbuf *m_mtu; |
| 1551 | struct ip6_mtuinfo mtuctl; |
| 1552 | |
| 1553 | KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); |
| 1554 | /* |
| 1555 | * Notify the error by sending IPV6_PATHMTU ancillary data if |
| 1556 | * application wanted to know the MTU value. |
| 1557 | * NOTE: we notify disconnected sockets, because some udp |
| 1558 | * applications keep sending sockets disconnected. |
| 1559 | * NOTE: our implementation doesn't notify connected sockets that has |
| 1560 | * foreign address that is different than given destination addresses |
| 1561 | * (this is permitted by RFC 3542). |
| 1562 | */ |
| 1563 | if ((inp->inp_flags & IN6P_MTU) == 0 || ( |
| 1564 | !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && |
| 1565 | !IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &dst->sin6_addr))) |
| 1566 | return; |
| 1567 | |
| 1568 | mtuctl.ip6m_mtu = mtu; |
| 1569 | mtuctl.ip6m_addr = *dst; |
| 1570 | if (sa6_recoverscope(&mtuctl.ip6m_addr)) |
| 1571 | return; |
| 1572 | |
| 1573 | if ((m_mtu = sbcreatecontrol((caddr_t)&mtuctl, sizeof(mtuctl), |
| 1574 | IPV6_PATHMTU, IPPROTO_IPV6)) == NULL) |
| 1575 | return; |
| 1576 | |
| 1577 | so = inp->inp_socket; |
| 1578 | if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu) |
| 1579 | == 0) { |
| 1580 | m_freem(m_mtu); |
| 1581 | /* XXX: should count statistics */ |
| 1582 | } else |
| 1583 | sorwakeup(so); |
| 1584 | } |
| 1585 | |
| 1586 | /* |
| 1587 | * Get pointer to the previous header followed by the header |
no test coverage detected