| 293 | } |
| 294 | |
| 295 | static int |
| 296 | ipsec4_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) |
| 297 | { |
| 298 | struct secpolicy *sp; |
| 299 | int error; |
| 300 | |
| 301 | /* Lookup for the corresponding outbound security policy */ |
| 302 | sp = ipsec4_checkpolicy(m, inp, &error, !forwarding); |
| 303 | if (sp == NULL) { |
| 304 | if (error == -EINVAL) { |
| 305 | /* Discarded by policy. */ |
| 306 | m_freem(m); |
| 307 | return (EACCES); |
| 308 | } |
| 309 | return (0); /* No IPsec required. */ |
| 310 | } |
| 311 | |
| 312 | /* |
| 313 | * Usually we have to have tunnel mode IPsec security policy |
| 314 | * when we are forwarding a packet. Otherwise we could not handle |
| 315 | * encrypted replies, because they are not destined for us. But |
| 316 | * some users are doing source address translation for forwarded |
| 317 | * packets, and thus, even if they are forwarded, the replies will |
| 318 | * return back to us. |
| 319 | */ |
| 320 | if (!forwarding) { |
| 321 | /* |
| 322 | * Do delayed checksums now because we send before |
| 323 | * this is done in the normal processing path. |
| 324 | */ |
| 325 | if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { |
| 326 | m = mb_unmapped_to_ext(m); |
| 327 | if (m == NULL) { |
| 328 | IPSECSTAT_INC(ips_out_nomem); |
| 329 | key_freesp(&sp); |
| 330 | return (ENOBUFS); |
| 331 | } |
| 332 | in_delayed_cksum(m); |
| 333 | m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; |
| 334 | } |
| 335 | #if defined(SCTP) || defined(SCTP_SUPPORT) |
| 336 | if (m->m_pkthdr.csum_flags & CSUM_SCTP) { |
| 337 | struct ip *ip; |
| 338 | |
| 339 | m = mb_unmapped_to_ext(m); |
| 340 | if (m == NULL) { |
| 341 | IPSECSTAT_INC(ips_out_nomem); |
| 342 | key_freesp(&sp); |
| 343 | return (ENOBUFS); |
| 344 | } |
| 345 | ip = mtod(m, struct ip *); |
| 346 | sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); |
| 347 | m->m_pkthdr.csum_flags &= ~CSUM_SCTP; |
| 348 | } |
| 349 | #endif |
| 350 | } |
| 351 | /* NB: callee frees mbuf and releases reference to SP */ |
| 352 | error = ipsec4_process_packet(m, sp, inp); |
no test coverage detected