diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_vxlan.c | 2 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 4 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 21 | ||||
-rw-r--r-- | sys/netinet/udp_var.h | 8 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 23 |
5 files changed, 50 insertions, 8 deletions
diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c index 59c76eb..a5631fc 100644 --- a/sys/net/if_vxlan.c +++ b/sys/net/if_vxlan.c @@ -930,7 +930,7 @@ vxlan_socket_init(struct vxlan_socket *vso, struct ifnet *ifp) } error = udp_set_kernel_tunneling(vso->vxlso_sock, - vxlan_rcv_udp_packet, vso); + vxlan_rcv_udp_packet, NULL, vso); if (error) { if_printf(ifp, "cannot set tunneling function: %d\n", error); return (error); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 77c62a1..b39d66a 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 fdc2e76..503f059 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 40d35ef..6d19dee 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 */ diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 03479fd..f6f4d58 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -553,6 +553,29 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d, bzero(&uh, sizeof(uh)); m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh); + if (!PRC_IS_REDIRECT(cmd)) { + /* Check to see if its tunneled */ + struct inpcb *inp; + inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src, + uh.uh_sport, &ip6->ip6_dst, uh.uh_dport, + INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, + m->m_pkthdr.rcvif, m); + if (inp != NULL) { + struct udpcb *up; + + up = intoudpcb(inp); + if (up->u_icmp_func) { + /* Yes it is. */ + INP_RUNLOCK(inp); + (*up->u_icmp_func)(cmd, (struct sockaddr *)ip6cp->ip6c_src, + d, up->u_tun_ctx); + return; + } else { + /* Can't find it. */ + INP_RUNLOCK(inp); + } + } + } (void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport, (struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd, cmdarg, notify); |