supported IPV6_RECVPATHMTU socket option.
Obtained from: KAME
This commit is contained in:
parent
41460aa51a
commit
efddf5c64d
@ -1192,7 +1192,7 @@ tcp6_ctlinput(cmd, sa, d)
|
||||
|
||||
in6_pcbnotify(&tcb, sa, th.th_dport,
|
||||
(struct sockaddr *)ip6cp->ip6c_src,
|
||||
th.th_sport, cmd, notify);
|
||||
th.th_sport, cmd, NULL, notify);
|
||||
|
||||
inc.inc_fport = th.th_dport;
|
||||
inc.inc_lport = th.th_sport;
|
||||
@ -1202,7 +1202,7 @@ tcp6_ctlinput(cmd, sa, d)
|
||||
syncache_unreach(&inc, &th);
|
||||
} else
|
||||
in6_pcbnotify(&tcb, sa, 0, (const struct sockaddr *)sa6_src,
|
||||
0, cmd, notify);
|
||||
0, cmd, NULL, notify);
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
|
@ -1192,7 +1192,7 @@ tcp6_ctlinput(cmd, sa, d)
|
||||
|
||||
in6_pcbnotify(&tcb, sa, th.th_dport,
|
||||
(struct sockaddr *)ip6cp->ip6c_src,
|
||||
th.th_sport, cmd, notify);
|
||||
th.th_sport, cmd, NULL, notify);
|
||||
|
||||
inc.inc_fport = th.th_dport;
|
||||
inc.inc_lport = th.th_sport;
|
||||
@ -1202,7 +1202,7 @@ tcp6_ctlinput(cmd, sa, d)
|
||||
syncache_unreach(&inc, &th);
|
||||
} else
|
||||
in6_pcbnotify(&tcb, sa, 0, (const struct sockaddr *)sa6_src,
|
||||
0, cmd, notify);
|
||||
0, cmd, NULL, notify);
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
|
@ -610,12 +610,13 @@ in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
* Must be called at splnet.
|
||||
*/
|
||||
void
|
||||
in6_pcbnotify(head, dst, fport_arg, src, lport_arg, cmd, notify)
|
||||
in6_pcbnotify(head, dst, fport_arg, src, lport_arg, cmd, cmdarg, notify)
|
||||
struct inpcbhead *head;
|
||||
struct sockaddr *dst;
|
||||
const struct sockaddr *src;
|
||||
u_int fport_arg, lport_arg;
|
||||
int cmd;
|
||||
void *cmdarg;
|
||||
struct inpcb *(*notify) __P((struct inpcb *, int));
|
||||
{
|
||||
struct inpcb *inp, *ninp;
|
||||
@ -661,6 +662,22 @@ in6_pcbnotify(head, dst, fport_arg, src, lport_arg, cmd, notify)
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the error designates a new path MTU for a destination
|
||||
* and the application (associated with this socket) wanted to
|
||||
* know the value, notify. Note that we notify for all
|
||||
* disconnected sockets if the corresponding application
|
||||
* wanted. This is because some UDP applications keep sending
|
||||
* sockets disconnected.
|
||||
* XXX: should we avoid to notify the value to TCP sockets?
|
||||
*/
|
||||
if (cmd == PRC_MSGSIZE && (inp->inp_flags & IN6P_MTU) != 0 &&
|
||||
(IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) ||
|
||||
IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &sa6_dst->sin6_addr))) {
|
||||
ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst,
|
||||
(u_int32_t *)cmdarg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect if we should notify the error. If no source and
|
||||
* destination ports are specifed, but non-zero flowinfo and
|
||||
|
@ -91,7 +91,7 @@ struct inpcb *
|
||||
struct in6_addr *, u_int, struct in6_addr *,
|
||||
u_int, int, struct ifnet *));
|
||||
void in6_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
|
||||
u_int, const struct sockaddr *, u_int, int,
|
||||
u_int, const struct sockaddr *, u_int, int, void *,
|
||||
struct inpcb *(*)(struct inpcb *, int)));
|
||||
struct inpcb *
|
||||
in6_rtchange __P((struct inpcb *, int));
|
||||
|
@ -1307,6 +1307,45 @@ ip6_savecontrol(in6p, m, mp)
|
||||
#undef IS2292
|
||||
}
|
||||
|
||||
void
|
||||
ip6_notify_pmtu(in6p, dst, mtu)
|
||||
struct inpcb *in6p;
|
||||
struct sockaddr_in6 *dst;
|
||||
u_int32_t *mtu;
|
||||
{
|
||||
struct socket *so;
|
||||
struct mbuf *m_mtu;
|
||||
struct ip6_mtuinfo mtuctl;
|
||||
|
||||
so = in6p->inp_socket;
|
||||
|
||||
if (mtu == NULL)
|
||||
return;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (so == NULL) /* I believe this is impossible */
|
||||
panic("ip6_notify_pmtu: socket is NULL");
|
||||
#endif
|
||||
|
||||
bzero(&mtuctl, sizeof(mtuctl)); /* zero-clear for safety */
|
||||
mtuctl.ip6m_mtu = *mtu;
|
||||
mtuctl.ip6m_addr = *dst;
|
||||
in6_recoverscope(&mtuctl.ip6m_addr, &mtuctl.ip6m_addr.sin6_addr, NULL);
|
||||
|
||||
if ((m_mtu = sbcreatecontrol((caddr_t)&mtuctl, sizeof(mtuctl),
|
||||
IPV6_PATHMTU, IPPROTO_IPV6)) == NULL)
|
||||
return;
|
||||
|
||||
if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu)
|
||||
== 0) {
|
||||
m_freem(m_mtu);
|
||||
/* XXX: should count statistics */
|
||||
} else
|
||||
sorwakeup(so);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PULLDOWN_TEST
|
||||
/*
|
||||
* pull single extension header from mbuf chain. returns single mbuf that
|
||||
|
@ -278,6 +278,7 @@ rip6_ctlinput(cmd, sa, d)
|
||||
int off = 0;
|
||||
struct ip6ctlparam *ip6cp = NULL;
|
||||
const struct sockaddr_in6 *sa6_src = NULL;
|
||||
void *cmdarg;
|
||||
struct inpcb *(*notify) __P((struct inpcb *, int)) = in6_rtchange;
|
||||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
@ -299,15 +300,17 @@ rip6_ctlinput(cmd, sa, d)
|
||||
m = ip6cp->ip6c_m;
|
||||
ip6 = ip6cp->ip6c_ip6;
|
||||
off = ip6cp->ip6c_off;
|
||||
cmdarg = ip6cp->ip6c_cmdarg;
|
||||
sa6_src = ip6cp->ip6c_src;
|
||||
} else {
|
||||
m = NULL;
|
||||
ip6 = NULL;
|
||||
cmdarg = NULL;
|
||||
sa6_src = &sa6_any;
|
||||
}
|
||||
|
||||
(void) in6_pcbnotify(&ripcb, sa, 0, (const struct sockaddr *)sa6_src,
|
||||
0, cmd, notify);
|
||||
0, cmd, cmdarg, notify);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -435,6 +435,7 @@ udp6_ctlinput(cmd, sa, d)
|
||||
int off = 0;
|
||||
struct ip6ctlparam *ip6cp = NULL;
|
||||
const struct sockaddr_in6 *sa6_src = NULL;
|
||||
void *cmdarg;
|
||||
struct inpcb *(*notify) __P((struct inpcb *, int)) = udp_notify;
|
||||
struct udp_portonly {
|
||||
u_int16_t uh_sport;
|
||||
@ -460,10 +461,12 @@ udp6_ctlinput(cmd, sa, d)
|
||||
m = ip6cp->ip6c_m;
|
||||
ip6 = ip6cp->ip6c_ip6;
|
||||
off = ip6cp->ip6c_off;
|
||||
cmdarg = ip6cp->ip6c_cmdarg;
|
||||
sa6_src = ip6cp->ip6c_src;
|
||||
} else {
|
||||
m = NULL;
|
||||
ip6 = NULL;
|
||||
cmdarg = NULL;
|
||||
sa6_src = &sa6_any;
|
||||
}
|
||||
|
||||
@ -481,12 +484,12 @@ udp6_ctlinput(cmd, sa, d)
|
||||
m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
|
||||
|
||||
(void) in6_pcbnotify(&udb, sa, uh.uh_dport,
|
||||
(struct sockaddr *)ip6cp->ip6c_src,
|
||||
uh.uh_sport, cmd, notify);
|
||||
(struct sockaddr *)ip6cp->ip6c_src,
|
||||
uh.uh_sport, cmd, cmdarg, notify);
|
||||
} else
|
||||
(void) in6_pcbnotify(&udb, sa, 0,
|
||||
(const struct sockaddr *)sa6_src,
|
||||
0, cmd, notify);
|
||||
0, cmd, cmdarg, notify);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
x
Reference in New Issue
Block a user