aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorRandall Stewart <rrs@FreeBSD.org>2016-04-28 15:53:10 +0000
committerRandall Stewart <rrs@FreeBSD.org>2016-04-28 15:53:10 +0000
commitabb901c5d78fb904202a4b98f2996c3ad9afd542 (patch)
tree3a6517c36d65bb8d50cdb69df4ceeff85cc6d0ab /sys/netinet
parent0b33b55b014e6098f1a20bf7416822e2ed73fb8a (diff)
Notes
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctputil.c4
-rw-r--r--sys/netinet/udp_usrreq.c21
-rw-r--r--sys/netinet/udp_var.h8
3 files changed, 26 insertions, 7 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 77c62a113f79..b39d66a1cdff 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -6945,7 +6945,7 @@ sctp_over_udp_start(void)
}
/* Call the special UDP hook. */
if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket),
- sctp_recv_udp_tunneled_packet, NULL))) {
+ sctp_recv_udp_tunneled_packet, NULL, NULL))) {
sctp_over_udp_stop();
return (ret);
}
@@ -6969,7 +6969,7 @@ sctp_over_udp_start(void)
}
/* Call the special UDP hook. */
if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket),
- sctp_recv_udp_tunneled_packet, NULL))) {
+ sctp_recv_udp_tunneled_packet, NULL, NULL))) {
sctp_over_udp_stop();
return (ret);
}
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index fdc2e76dbcfb..503f059a3873 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -792,6 +792,21 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
udp_notify(inp, inetctlerrmap[cmd]);
}
INP_RUNLOCK(inp);
+ } else {
+ inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
+ ip->ip_src, uh->uh_sport,
+ INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
+ if (inp != NULL) {
+ struct udpcb *up;
+
+ up = intoudpcb(inp);
+ if (up->u_icmp_func != NULL) {
+ INP_RUNLOCK(inp);
+ (*up->u_icmp_func)(cmd, sa, vip, up->u_tun_ctx);
+ } else {
+ INP_RUNLOCK(inp);
+ }
+ }
}
} else
in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd],
@@ -1748,7 +1763,7 @@ udp_attach(struct socket *so, int proto, struct thread *td)
#endif /* INET */
int
-udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, void *ctx)
+udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, udp_tun_icmp_t i, void *ctx)
{
struct inpcb *inp;
struct udpcb *up;
@@ -1759,11 +1774,13 @@ udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, void *ctx)
KASSERT(inp != NULL, ("udp_set_kernel_tunneling: inp == NULL"));
INP_WLOCK(inp);
up = intoudpcb(inp);
- if (up->u_tun_func != NULL) {
+ if ((up->u_tun_func != NULL) ||
+ (up->u_icmp_func != NULL)) {
INP_WUNLOCK(inp);
return (EBUSY);
}
up->u_tun_func = f;
+ up->u_icmp_func = i;
up->u_tun_ctx = ctx;
INP_WUNLOCK(inp);
return (0);
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 40d35ef43812..6d19deea103e 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -55,14 +55,16 @@ struct udpiphdr {
struct inpcb;
struct mbuf;
-typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *,
+typedef void(*udp_tun_func_t)(struct mbuf *, int, struct inpcb *,
const struct sockaddr *, void *);
-
+typedef void(*udp_tun_icmp_t)(int, struct sockaddr *, void *, void *);
+
/*
* UDP control block; one per udp.
*/
struct udpcb {
udp_tun_func_t u_tun_func; /* UDP kernel tunneling callback. */
+ udp_tun_icmp_t u_icmp_func; /* UDP kernel tunneling icmp callback */
u_int u_flags; /* Generic UDP flags. */
uint16_t u_rxcslen; /* Coverage for incoming datagrams. */
uint16_t u_txcslen; /* Coverage for outgoing datagrams. */
@@ -179,7 +181,7 @@ struct inpcb *udp_notify(struct inpcb *inp, int errno);
int udp_shutdown(struct socket *so);
int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f,
- void *ctx);
+ udp_tun_icmp_t i, void *ctx);
#endif /* _KERNEL */