ipsec_output.c (8e9313caa6725f8c65fcacb147ce88a9ba6f6f2a) ipsec_output.c (6b66194bcb7e43ef40b11005618544081c6e30ea)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
5 * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 47 unchanged lines hidden (view full) ---

56#include <netinet/in_systm.h>
57#include <netinet/ip.h>
58#include <netinet/ip_var.h>
59#include <netinet/in_var.h>
60#include <netinet/ip_ecn.h>
61#ifdef INET6
62#include <netinet6/ip6_ecn.h>
63#endif
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
5 * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 47 unchanged lines hidden (view full) ---

56#include <netinet/in_systm.h>
57#include <netinet/ip.h>
58#include <netinet/ip_var.h>
59#include <netinet/in_var.h>
60#include <netinet/ip_ecn.h>
61#ifdef INET6
62#include <netinet6/ip6_ecn.h>
63#endif
64#include <netinet/ip_icmp.h>
65#include <netinet/tcp_var.h>
64
65#include <netinet/ip6.h>
66#ifdef INET6
67#include <netinet6/ip6_var.h>
68#include <netinet6/scope6_var.h>
69#endif
70#include <netinet/in_pcb.h>
71#ifdef INET6

--- 215 unchanged lines hidden (view full) ---

287int
288ipsec4_process_packet(struct mbuf *m, struct secpolicy *sp,
289 struct inpcb *inp)
290{
291
292 return (ipsec4_perform_request(m, sp, inp, 0));
293}
294
66
67#include <netinet/ip6.h>
68#ifdef INET6
69#include <netinet6/ip6_var.h>
70#include <netinet6/scope6_var.h>
71#endif
72#include <netinet/in_pcb.h>
73#ifdef INET6

--- 215 unchanged lines hidden (view full) ---

289int
290ipsec4_process_packet(struct mbuf *m, struct secpolicy *sp,
291 struct inpcb *inp)
292{
293
294 return (ipsec4_perform_request(m, sp, inp, 0));
295}
296
297int
298ipsec4_check_pmtu(struct mbuf *m, struct secpolicy *sp, int forwarding)
299{
300 union sockaddr_union *dst;
301 struct in_conninfo inc;
302 struct secasvar *sav;
303 struct ip *ip;
304 size_t hlen, pmtu;
305 uint32_t idx;
306 int error;
307
308
309 /* Don't check PMTU if the frame won't have DF bit set. */
310 if (!V_ip4_ipsec_dfbit)
311 return (0);
312 if (V_ip4_ipsec_dfbit == 1)
313 goto setdf;
314
315 /* V_ip4_ipsec_dfbit > 1 - we will copy it from inner header. */
316 ip = mtod(m, struct ip *);
317 if (!(ip->ip_off & htons(IP_DF)))
318 return (0);
319
320setdf:
321 idx = sp->tcount - 1;
322 sav = ipsec4_allocsa(m, sp, &idx, &error);
323 if (sav == NULL) {
324 key_freesp(&sp);
325 if (error != EJUSTRETURN)
326 m_freem(m);
327
328 return (error);
329 }
330
331 dst = &sav->sah->saidx.dst;
332
333 /* Final header is not ipv4. */
334 if (dst->sa.sa_family != AF_INET) {
335 key_freesav(&sav);
336 return (0);
337 }
338
339 memset(&inc, 0, sizeof(inc));
340 inc.inc_faddr = satosin(&dst->sa)->sin_addr;
341 key_freesav(&sav);
342 pmtu = tcp_hc_getmtu(&inc);
343 /* No entry in hostcache. */
344 if (pmtu == 0)
345 return (0);
346
347 hlen = ipsec_hdrsiz_internal(sp);
348 if (m_length(m, NULL) + hlen > pmtu) {
349 /*
350 * If we're forwarding generate ICMP message here,
351 * so that it contains pmtu and not link mtu.
352 * Set error to EINPROGRESS, in order for the frame
353 * to be dropped silently.
354 */
355 if (forwarding) {
356 if (pmtu > hlen)
357 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
358 0, pmtu - hlen);
359 else
360 m_freem(m);
361
362 key_freesp(&sp);
363 return (EINPROGRESS); /* Pretend that we consumed it. */
364 } else {
365 m_freem(m);
366 key_freesp(&sp);
367 return (EMSGSIZE);
368 }
369 }
370
371 return (0);
372}
373
295static int
296ipsec4_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);

--- 41 unchanged lines hidden (view full) ---

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 */
374static int
375ipsec4_common_output(struct mbuf *m, struct inpcb *inp, int forwarding)
376{
377 struct secpolicy *sp;
378 int error;
379
380 /* Lookup for the corresponding outbound security policy */
381 sp = ipsec4_checkpolicy(m, inp, &error, !forwarding);

--- 41 unchanged lines hidden (view full) ---

423 }
424 ip = mtod(m, struct ip *);
425 sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
426 m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
427 }
428#endif
429 }
430 /* NB: callee frees mbuf and releases reference to SP */
431 error = ipsec4_check_pmtu(m, sp, forwarding);
432 if (error != 0) {
433 if (error == EJUSTRETURN)
434 return (0);
435
436 return (error);
437 }
438
352 error = ipsec4_process_packet(m, sp, inp);
353 if (error == EJUSTRETURN) {
354 /*
355 * We had a SP with a level of 'use' and no SA. We
356 * will just continue to process the packet without
357 * IPsec processing and return without error.
358 */
359 return (0);

--- 633 unchanged lines hidden ---
439 error = ipsec4_process_packet(m, sp, inp);
440 if (error == EJUSTRETURN) {
441 /*
442 * We had a SP with a level of 'use' and no SA. We
443 * will just continue to process the packet without
444 * IPsec processing and return without error.
445 */
446 return (0);

--- 633 unchanged lines hidden ---