| 140 | static void udp6_detach(struct socket *so); |
| 141 | |
| 142 | static int |
| 143 | udp6_append(struct inpcb *inp, struct mbuf *n, int off, |
| 144 | struct sockaddr_in6 *fromsa) |
| 145 | { |
| 146 | struct socket *so; |
| 147 | struct mbuf *opts = NULL, *tmp_opts; |
| 148 | struct udpcb *up; |
| 149 | |
| 150 | INP_LOCK_ASSERT(inp); |
| 151 | |
| 152 | /* |
| 153 | * Engage the tunneling protocol. |
| 154 | */ |
| 155 | up = intoudpcb(inp); |
| 156 | if (up->u_tun_func != NULL) { |
| 157 | in_pcbref(inp); |
| 158 | INP_RUNLOCK(inp); |
| 159 | (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&fromsa[0], |
| 160 | up->u_tun_ctx); |
| 161 | INP_RLOCK(inp); |
| 162 | return (in_pcbrele_rlocked(inp)); |
| 163 | } |
| 164 | #if defined(IPSEC) || defined(IPSEC_SUPPORT) |
| 165 | /* Check AH/ESP integrity. */ |
| 166 | if (IPSEC_ENABLED(ipv6)) { |
| 167 | if (IPSEC_CHECK_POLICY(ipv6, n, inp) != 0) { |
| 168 | m_freem(n); |
| 169 | return (0); |
| 170 | } |
| 171 | } |
| 172 | #endif /* IPSEC */ |
| 173 | #ifdef MAC |
| 174 | if (mac_inpcb_check_deliver(inp, n) != 0) { |
| 175 | m_freem(n); |
| 176 | return (0); |
| 177 | } |
| 178 | #endif |
| 179 | opts = NULL; |
| 180 | if (inp->inp_flags & INP_CONTROLOPTS || |
| 181 | inp->inp_socket->so_options & SO_TIMESTAMP) |
| 182 | ip6_savecontrol(inp, n, &opts); |
| 183 | if ((inp->inp_vflag & INP_IPV6) && (inp->inp_flags2 & INP_ORIGDSTADDR)) { |
| 184 | tmp_opts = sbcreatecontrol((caddr_t)&fromsa[1], |
| 185 | sizeof(struct sockaddr_in6), IPV6_ORIGDSTADDR, IPPROTO_IPV6); |
| 186 | if (tmp_opts) { |
| 187 | if (opts) { |
| 188 | tmp_opts->m_next = opts; |
| 189 | opts = tmp_opts; |
| 190 | } else |
| 191 | opts = tmp_opts; |
| 192 | } |
| 193 | } |
| 194 | m_adj(n, off + sizeof(struct udphdr)); |
| 195 | |
| 196 | so = inp->inp_socket; |
| 197 | SOCKBUF_LOCK(&so->so_rcv); |
| 198 | if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n, |
| 199 | opts) == 0) { |
no test coverage detected