Fri Aug 28 17:01:48 2020 UTC ()
Don't cache the sa, because we are dealing with multiple mbufs (from ozaki-r)


(christos)
diff -r1.318 -r1.319 src/sys/netinet/ip_output.c

cvs diff -r1.318 -r1.319 src/sys/netinet/ip_output.c (expand / switch to unified diff)

--- src/sys/netinet/ip_output.c 2020/08/28 06:31:42 1.318
+++ src/sys/netinet/ip_output.c 2020/08/28 17:01:48 1.319
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ip_output.c,v 1.318 2020/08/28 06:31:42 ozaki-r Exp $ */ 1/* $NetBSD: ip_output.c,v 1.319 2020/08/28 17:01:48 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -81,27 +81,27 @@ @@ -81,27 +81,27 @@
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE. 88 * SUCH DAMAGE.
89 * 89 *
90 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 90 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
91 */ 91 */
92 92
93#include <sys/cdefs.h> 93#include <sys/cdefs.h>
94__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.318 2020/08/28 06:31:42 ozaki-r Exp $"); 94__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.319 2020/08/28 17:01:48 christos Exp $");
95 95
96#ifdef _KERNEL_OPT 96#ifdef _KERNEL_OPT
97#include "opt_inet.h" 97#include "opt_inet.h"
98#include "opt_ipsec.h" 98#include "opt_ipsec.h"
99#include "opt_mrouting.h" 99#include "opt_mrouting.h"
100#include "opt_net_mpsafe.h" 100#include "opt_net_mpsafe.h"
101#include "opt_mpls.h" 101#include "opt_mpls.h"
102#endif 102#endif
103 103
104#include "arp.h" 104#include "arp.h"
105 105
106#include <sys/param.h> 106#include <sys/param.h>
107#include <sys/kmem.h> 107#include <sys/kmem.h>
@@ -680,28 +680,26 @@ sendit: @@ -680,28 +680,26 @@ sendit:
680 */ 680 */
681 error = 0; 681 error = 0;
682 else 682 else
683 error = EADDRNOTAVAIL; 683 error = EADDRNOTAVAIL;
684 goto bad; 684 goto bad;
685 } 685 }
686 686
687 /* Maybe skip checksums on loopback interfaces. */ 687 /* Maybe skip checksums on loopback interfaces. */
688 if (IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4)) { 688 if (IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4)) {
689 m->m_pkthdr.csum_flags |= M_CSUM_IPv4; 689 m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
690 } 690 }
691 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx; 691 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
692 692
693 sa = (m->m_flags & M_MCAST) ? sintocsa(rdst) : sintocsa(dst); 
694 
695 /* Need to fragment the packet */ 693 /* Need to fragment the packet */
696 if (ntohs(ip->ip_len) > mtu && 694 if (ntohs(ip->ip_len) > mtu &&
697 (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0) { 695 (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0) {
698 goto fragment; 696 goto fragment;
699 } 697 }
700 698
701#if IFA_STATS 699#if IFA_STATS
702 if (ia) 700 if (ia)
703 ia->ia_ifa.ifa_data.ifad_outbytes += ntohs(ip->ip_len); 701 ia->ia_ifa.ifa_data.ifad_outbytes += ntohs(ip->ip_len);
704#endif 702#endif
705 /* 703 /*
706 * Always initialize the sum to 0! Some HW assisted 704 * Always initialize the sum to 0! Some HW assisted
707 * checksumming requires this. 705 * checksumming requires this.
@@ -721,26 +719,28 @@ sendit: @@ -721,26 +719,28 @@ sendit:
721 ip->ip_sum = in_cksum(m, hlen); 719 ip->ip_sum = in_cksum(m, hlen);
722 m->m_pkthdr.csum_flags &= ~M_CSUM_IPv4; 720 m->m_pkthdr.csum_flags &= ~M_CSUM_IPv4;
723 } 721 }
724 if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) { 722 if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
725 if (IN_NEED_CHECKSUM(ifp, 723 if (IN_NEED_CHECKSUM(ifp,
726 sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4))) { 724 sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4))) {
727 in_undefer_cksum_tcpudp(m); 725 in_undefer_cksum_tcpudp(m);
728 } 726 }
729 m->m_pkthdr.csum_flags &= 727 m->m_pkthdr.csum_flags &=
730 ~(M_CSUM_TCPv4|M_CSUM_UDPv4); 728 ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
731 } 729 }
732 } 730 }
733 731
 732 sa = (m->m_flags & M_MCAST) ? sintocsa(rdst) : sintocsa(dst);
 733
734 /* Send it */ 734 /* Send it */
735 if (__predict_false(sw_csum & M_CSUM_TSOv4)) { 735 if (__predict_false(sw_csum & M_CSUM_TSOv4)) {
736 /* 736 /*
737 * TSO4 is required by a packet, but disabled for 737 * TSO4 is required by a packet, but disabled for
738 * the interface. 738 * the interface.
739 */ 739 */
740 error = ip_tso_output(ifp, m, sa, rt); 740 error = ip_tso_output(ifp, m, sa, rt);
741 } else 741 } else
742 error = ip_if_output(ifp, m, sa, rt); 742 error = ip_if_output(ifp, m, sa, rt);
743 goto done; 743 goto done;
744 744
745fragment: 745fragment:
746 /* 746 /*
@@ -790,27 +790,28 @@ fragment: @@ -790,27 +790,28 @@ fragment:
790 /* 790 /*
791 * If we get there, the packet has not been handled by 791 * If we get there, the packet has not been handled by
792 * IPsec whereas it should have. Now that it has been 792 * IPsec whereas it should have. Now that it has been
793 * fragmented, re-inject it in ip_output so that IPsec 793 * fragmented, re-inject it in ip_output so that IPsec
794 * processing can occur. 794 * processing can occur.
795 */ 795 */
796 if (natt_frag) { 796 if (natt_frag) {
797 error = ip_output(m, opt, NULL, 797 error = ip_output(m, opt, NULL,
798 flags | IP_RAWOUTPUT | IP_NOIPNEWID, 798 flags | IP_RAWOUTPUT | IP_NOIPNEWID,
799 imo, inp); 799 imo, inp);
800 } else { 800 } else {
801 KASSERT((m->m_pkthdr.csum_flags & 801 KASSERT((m->m_pkthdr.csum_flags &
802 (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0); 802 (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0);
803 error = ip_if_output(ifp, m, sa, rt); 803 error = ip_if_output(ifp, m, (m->m_flags & M_MCAST) ?
 804 sintocsa(rdst) : sintocsa(dst), rt);
804 } 805 }
805 } 806 }
806 if (error == 0) { 807 if (error == 0) {
807 IP_STATINC(IP_STAT_FRAGMENTED); 808 IP_STATINC(IP_STAT_FRAGMENTED);
808 } 809 }
809 810
810done: 811done:
811 ia4_release(ia, &psref_ia); 812 ia4_release(ia, &psref_ia);
812 rtcache_unref(rt, ro); 813 rtcache_unref(rt, ro);
813 if (ro == &iproute) { 814 if (ro == &iproute) {
814 rtcache_free(&iproute); 815 rtcache_free(&iproute);
815 } 816 }
816 if (mifp != NULL) { 817 if (mifp != NULL) {