1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
--- sys/netinet6/ip6_output.c.orig
+++ sys/netinet6/ip6_output.c
@@ -205,6 +205,36 @@
*(u_short *)mtodo(m, offset) = csum;
}
+static int
+ip6_output_delayed_csum(struct mbuf *m, struct ifnet *ifp, int csum_flags,
+ int plen, int optlen, bool frag __unused)
+{
+
+ KASSERT((plen >= optlen), ("%s:%d: plen %d < optlen %d, m %p, ifp %p "
+ "csum_flags %#x frag %d\n",
+ __func__, __LINE__, plen, optlen, m, ifp, csum_flags, frag));
+
+ if ((csum_flags & CSUM_DELAY_DATA_IPV6) ||
+#ifdef SCTP
+ (csum_flags & CSUM_SCTP_IPV6) ||
+#endif
+ false) {
+ if (csum_flags & CSUM_DELAY_DATA_IPV6) {
+ in6_delayed_cksum(m, plen - optlen,
+ sizeof(struct ip6_hdr) + optlen);
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
+ }
+#ifdef SCTP
+ if (csum_flags & CSUM_SCTP_IPV6) {
+ sctp_delayed_cksum(m, sizeof(struct ip6_hdr) + optlen);
+ m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
+ }
+#endif
+ }
+
+ return (0);
+}
+
int
ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto,
int fraglen , uint32_t id)
@@ -908,17 +938,10 @@
* XXX-BZ Need a framework to know when the NIC can handle it, even
* with ext. hdrs.
*/
- if (sw_csum & CSUM_DELAY_DATA_IPV6) {
- sw_csum &= ~CSUM_DELAY_DATA_IPV6;
- in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr));
- }
-#ifdef SCTP
- if (sw_csum & CSUM_SCTP_IPV6) {
- sw_csum &= ~CSUM_SCTP_IPV6;
- sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
- }
-#endif
- m->m_pkthdr.csum_flags &= ifp->if_hwassist;
+ error = ip6_output_delayed_csum(m, ifp, sw_csum, plen, optlen, false);
+ if (error != 0)
+ goto bad;
+ /* XXX-BZ m->m_pkthdr.csum_flags &= ~ifp->if_hwassist; */
tlen = m->m_pkthdr.len;
if ((opt && (opt->ip6po_flags & IP6PO_DONTFRAG)) || tso)
@@ -1017,16 +1040,11 @@
* fragmented packets, then do it here.
* XXX-BZ handle the hw offloading case. Need flags.
*/
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
- in6_delayed_cksum(m, plen, hlen);
- m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
- }
-#ifdef SCTP
- if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) {
- sctp_delayed_cksum(m, hlen);
- m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
- }
-#endif
+ error = ip6_output_delayed_csum(m, ifp, m->m_pkthdr.csum_flags,
+ plen, optlen, true);
+ if (error != 0)
+ goto bad;
+
/*
* Change the next header field of the last header in the
* unfragmentable part.
|