Index: sys/netinet/sctputil.c =================================================================== --- sys/netinet/sctputil.c +++ sys/netinet/sctputil.c @@ -6808,7 +6808,8 @@ #endif static void -sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored) +sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored, + const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED) { struct ip *iph; @@ -6944,7 +6945,7 @@ } /* Call the special UDP hook. */ if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket), - sctp_recv_udp_tunneled_packet))) { + sctp_recv_udp_tunneled_packet, NULL))) { sctp_over_udp_stop(); return (ret); } @@ -6968,7 +6969,7 @@ } /* Call the special UDP hook. */ if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket), - sctp_recv_udp_tunneled_packet))) { + sctp_recv_udp_tunneled_packet, NULL))) { sctp_over_udp_stop(); return (ret); } Index: sys/netinet/udp_usrreq.c =================================================================== --- sys/netinet/udp_usrreq.c +++ sys/netinet/udp_usrreq.c @@ -303,7 +303,8 @@ */ up = intoudpcb(inp); if (up->u_tun_func != NULL) { - (*up->u_tun_func)(n, off, inp); + (*up->u_tun_func)(n, off, inp, (struct sockaddr *) udp_in, + up->u_tun_func_ctx); return; } @@ -1613,7 +1614,7 @@ #endif /* INET */ int -udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f) +udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, void *ctx) { struct inpcb *inp; struct udpcb *up; @@ -1629,6 +1630,7 @@ return (EBUSY); } up->u_tun_func = f; + up->u_tun_func_ctx = ctx; INP_WUNLOCK(inp); return (0); } Index: sys/netinet/udp_var.h =================================================================== --- sys/netinet/udp_var.h +++ sys/netinet/udp_var.h @@ -55,13 +55,15 @@ 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 off, struct inpcb *, + const struct sockaddr *, void *); /* * UDP control block; one per udp. */ struct udpcb { udp_tun_func_t u_tun_func; /* UDP kernel tunneling callback. */ + void *u_tun_func_ctx;/* Tunneling callback context. */ u_int u_flags; /* Generic UDP flags. */ uint16_t u_rxcslen; /* Coverage for incoming datagrams. */ uint16_t u_txcslen; /* Coverage for outgoing datagrams. */ @@ -176,7 +178,8 @@ 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); +int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, + void *ctx); #endif /* _KERNEL */ Index: sys/netinet6/udp6_usrreq.c =================================================================== --- sys/netinet6/udp6_usrreq.c +++ sys/netinet6/udp6_usrreq.c @@ -139,9 +139,19 @@ { struct socket *so; struct mbuf *opts; + struct udpcb *up; INP_LOCK_ASSERT(inp); + /* + * Engage the tunneling protocol. + */ + up = intoudpcb(inp); + if (up->u_tun_func != NULL) { + (*up->u_tun_func)(n, off, inp, (struct sockaddr *) fromsa, + up->u_tun_func_ctx); + return; + } #ifdef IPSEC /* Check AH/ESP integrity. */ if (ipsec6_in_reject(n, inp)) { @@ -354,20 +364,7 @@ if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { INP_RLOCK(last); - up = intoudpcb(last); - if (up->u_tun_func == NULL) { - udp6_append(last, n, off, &fromsa); - } else { - /* - * Engage the tunneling - * protocol we will have to - * leave the info_lock up, - * since we are hunting - * through multiple UDP's. - * - */ - (*up->u_tun_func)(n, off, last); - } + udp6_append(last, n, off, &fromsa); INP_RUNLOCK(last); } } @@ -399,14 +396,7 @@ INP_INFO_RUNLOCK(pcbinfo); up = intoudpcb(last); UDP_PROBE(receive, NULL, last, ip6, last, uh); - if (up->u_tun_func == NULL) { - udp6_append(last, m, off, &fromsa); - } else { - /* - * Engage the tunneling protocol. - */ - (*up->u_tun_func)(m, off, last); - } + udp6_append(last, m, off, &fromsa); INP_RUNLOCK(last); return (IPPROTO_DONE); } @@ -485,15 +475,7 @@ } } UDP_PROBE(receive, NULL, inp, ip6, inp, uh); - if (up->u_tun_func == NULL) { - udp6_append(inp, m, off, &fromsa); - } else { - /* - * Engage the tunneling protocol. - */ - - (*up->u_tun_func)(m, off, inp); - } + udp6_append(inp, m, off, &fromsa); INP_RUNLOCK(inp); return (IPPROTO_DONE);