diff options
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6.c | 106 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6_output.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/io/mac/mac_util.c | 286 | ||||
-rw-r--r-- | usr/src/uts/common/os/ip_cksum.c | 108 | ||||
-rw-r--r-- | usr/src/uts/common/sys/stream.h | 5 | ||||
-rw-r--r-- | usr/src/uts/common/sys/strsubr.h | 1 |
6 files changed, 188 insertions, 332 deletions
diff --git a/usr/src/uts/common/inet/ip/ip6.c b/usr/src/uts/common/inet/ip/ip6.c index 20056edfad..7f30aaa81d 100644 --- a/usr/src/uts/common/inet/ip/ip6.c +++ b/usr/src/uts/common/inet/ip/ip6.c @@ -2730,6 +2730,112 @@ done: } /* + * Try to determine where and what are the IPv6 header length and + * pointer to nexthdr value for the upper layer protocol (or an + * unknown next hdr). + * + * Parameters returns a pointer to the nexthdr value; + * Must handle malformed packets of various sorts. + * Function returns failure for malformed cases. + */ +boolean_t +ip_hdr_length_nexthdr_v6(mblk_t *mp, ip6_t *ip6h, uint16_t *hdr_length_ptr, + uint8_t **nexthdrpp) +{ + uint16_t length; + uint_t ehdrlen; + uint8_t *nexthdrp; + uint8_t *whereptr; + uint8_t *endptr; + ip6_dest_t *desthdr; + ip6_rthdr_t *rthdr; + ip6_frag_t *fraghdr; + + ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION); + length = IPV6_HDR_LEN; + whereptr = ((uint8_t *)&ip6h[1]); /* point to next hdr */ + endptr = mp->b_wptr; + + nexthdrp = &ip6h->ip6_nxt; + while (whereptr < endptr) { + /* Is there enough left for len + nexthdr? */ + if (whereptr + MIN_EHDR_LEN > endptr) + break; + + switch (*nexthdrp) { + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + /* Assumes the headers are identical for hbh and dst */ + desthdr = (ip6_dest_t *)whereptr; + ehdrlen = 8 * (desthdr->ip6d_len + 1); + if ((uchar_t *)desthdr + ehdrlen > endptr) + return (B_FALSE); + nexthdrp = &desthdr->ip6d_nxt; + break; + case IPPROTO_ROUTING: + rthdr = (ip6_rthdr_t *)whereptr; + ehdrlen = 8 * (rthdr->ip6r_len + 1); + if ((uchar_t *)rthdr + ehdrlen > endptr) + return (B_FALSE); + nexthdrp = &rthdr->ip6r_nxt; + break; + case IPPROTO_FRAGMENT: + fraghdr = (ip6_frag_t *)whereptr; + ehdrlen = sizeof (ip6_frag_t); + if ((uchar_t *)&fraghdr[1] > endptr) + return (B_FALSE); + nexthdrp = &fraghdr->ip6f_nxt; + break; + case IPPROTO_NONE: + /* No next header means we're finished */ + default: + *hdr_length_ptr = length; + *nexthdrpp = nexthdrp; + return (B_TRUE); + } + length += ehdrlen; + whereptr += ehdrlen; + *hdr_length_ptr = length; + *nexthdrpp = nexthdrp; + } + switch (*nexthdrp) { + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + case IPPROTO_FRAGMENT: + /* + * If any know extension headers are still to be processed, + * the packet's malformed (or at least all the IP header(s) are + * not in the same mblk - and that should never happen. + */ + return (B_FALSE); + + default: + /* + * If we get here, we know that all of the IP headers were in + * the same mblk, even if the ULP header is in the next mblk. + */ + *hdr_length_ptr = length; + *nexthdrpp = nexthdrp; + return (B_TRUE); + } +} + +/* + * Return the length of the IPv6 related headers (including extension headers) + * Returns a length even if the packet is malformed. + */ +int +ip_hdr_length_v6(mblk_t *mp, ip6_t *ip6h) +{ + uint16_t hdr_len; + uint8_t *nexthdrp; + + (void) ip_hdr_length_nexthdr_v6(mp, ip6h, &hdr_len, &nexthdrp); + return (hdr_len); +} + +/* * Parse and process any hop-by-hop or destination options. * * Assumes that q is an ill read queue so that ICMP errors for link-local diff --git a/usr/src/uts/common/inet/ip/ip6_output.c b/usr/src/uts/common/inet/ip/ip6_output.c index 23484af98c..dc074454e3 100644 --- a/usr/src/uts/common/inet/ip/ip6_output.c +++ b/usr/src/uts/common/inet/ip/ip6_output.c @@ -773,8 +773,6 @@ ip_output_sw_cksum_v6(mblk_t *mp, ip6_t *ip6h, ip_xmit_attr_t *ixa) /* ULP puts the checksum field is in the first mblk */ ASSERT(((uchar_t *)cksump) + sizeof (uint16_t) <= mp->b_wptr); - DB_CKSUMOCSUM(mp) = *cksump; - /* * We accumulate the pseudo header checksum in cksum. * This is pretty hairy code, so watch close. One @@ -806,11 +804,7 @@ ip_output_sw_cksum_v6(mblk_t *mp, ip6_t *ip6h, ip_xmit_attr_t *ixa) #undef iphs } -/* - * Sadly, removing this unused global variable will actually break the build. - * Compiling the "ip" module explicitly checks that no global variables - * are added or removed. - */ +/* There are drivers that can't do partial checksum for ICMPv6 */ int nxge_cksum_workaround = 1; /* @@ -892,9 +886,6 @@ ip_output_cksum_v6(iaflags_t ixaflags, mblk_t *mp, ip6_t *ip6h, /* ULP puts the checksum field is in the first mblk */ ASSERT(((uchar_t *)cksump) + sizeof (uint16_t) <= mp->b_wptr); - /* Record original checksum field in case needed within MAC */ - DB_CKSUMOCSUM(mp) = *cksump; - /* * Underlying interface supports hardware checksum offload for * the payload; leave the payload checksum for the hardware to @@ -914,7 +905,8 @@ ip_output_cksum_v6(iaflags_t ixaflags, mblk_t *mp, ip6_t *ip6h, DB_CKSUMFLAGS(mp) |= HCK_FULLCKSUM; return (B_TRUE); } - if (hck_flags & HCKSUM_INET_PARTIAL) { + if (((hck_flags) & HCKSUM_INET_PARTIAL) && + (protocol != IPPROTO_ICMPV6 || !nxge_cksum_workaround)) { /* * Partial checksum offload has been enabled. Fill * the checksum field in the protocol header with the diff --git a/usr/src/uts/common/io/mac/mac_util.c b/usr/src/uts/common/io/mac/mac_util.c index 814fbecfd1..a877ca258c 100644 --- a/usr/src/uts/common/io/mac/mac_util.c +++ b/usr/src/uts/common/io/mac/mac_util.c @@ -48,7 +48,6 @@ #include <inet/sadb.h> #include <inet/ipsecesp.h> #include <inet/ipsecah.h> -#include <inet/sctp_ip.h> /* * Copy an mblk, preserving its hardware checksum flags. @@ -89,164 +88,10 @@ mac_copymsgchain_cksum(mblk_t *mp) return (nmp); } -static void -mac_ipv4_chksum(mblk_t *mp, uint32_t offset, ipha_t *ipha) -{ - uint8_t proto; - ipaddr_t src, dst; - uint16_t len; - uint32_t cksum; - uint16_t *up; - - /* - * Pointer to checksum field in ULP header. - */ - proto = ipha->ipha_protocol; - ASSERT(ipha->ipha_version_and_hdr_length == IP_SIMPLE_HDR_VERSION); - - switch (proto) { - case IPPROTO_TCP: - /* LINTED: improper alignment cast */ - up = IPH_TCPH_CHECKSUMP(ipha, IP_SIMPLE_HDR_LENGTH); - cksum = IP_TCP_CSUM_COMP; - break; - case IPPROTO_UDP: - /* LINTED: improper alignment cast */ - up = IPH_UDPH_CHECKSUMP(ipha, IP_SIMPLE_HDR_LENGTH); - cksum = IP_UDP_CSUM_COMP; - break; - case IPPROTO_SCTP: { - sctp_hdr_t *sctph; - - ASSERT(MBLKL(mp) >= (IP_SIMPLE_HDR_LENGTH + sizeof (*sctph))); - sctph = (sctp_hdr_t *)(mp->b_rptr + IP_SIMPLE_HDR_LENGTH); - /* - * Zero out the checksum field to ensure proper checksum - * calculation. - */ - sctph->sh_chksum = 0; - sctph->sh_chksum = sctp_cksum(mp, IP_SIMPLE_HDR_LENGTH); - return; - } - default: - return; - } - - /* - * Pseudo-header checksum. - */ - src = ipha->ipha_src; - dst = ipha->ipha_dst; - len = ntohs(ipha->ipha_length) - IP_SIMPLE_HDR_LENGTH; - - cksum += (dst >> 16) + (dst & 0xFFFF) + (src >> 16) + (src & 0xFFFF); - cksum += htons(len); - - /* - * The checksum value stored in the packet needs to be correct. Compute - * it here. - */ - *up = 0; - cksum = IP_CSUM(mp, IP_SIMPLE_HDR_LENGTH + offset, cksum); - *up = (uint16_t)(cksum ? cksum : ~cksum); -} - -static void -mac_ipv6_chksum(mblk_t *mp, uint32_t offset, ip6_t *ip6h) -{ - uint8_t proto; - uint32_t cksum; - uint16_t *up; - uint16_t ip_hdr_length = ip_hdr_length_v6(mp, ip6h); - -#define iphs ((uint16_t *)ip6h) - - /* - * Pointer to checksum field in ULP header. - */ - proto = ip6h->ip6_nxt; - - /* - * The IPv6 SW checksum code calculation (ip_output_cksum_v6) handles - * IXAF_SET_RAW_CKSUM, but that is never a factor when full HW checksum - * offload is in use, so we can't worry about it here either. We have - * to calculate the noraml ICMPv6 checksum. - */ - - switch (proto) { - case IPPROTO_TCP: - /* LINTED: improper alignment cast */ - up = IPH_TCPH_CHECKSUMP(ip6h, ip_hdr_length); - cksum = IP_TCP_CSUM_COMP; - break; - - case IPPROTO_UDP: - /* LINTED: improper alignment cast */ - up = IPH_UDPH_CHECKSUMP(ip6h, ip_hdr_length); - cksum = IP_UDP_CSUM_COMP; - break; - - case IPPROTO_SCTP: { - sctp_hdr_t *sctph; - - ASSERT(MBLKL(mp) >= (ip_hdr_length + sizeof (*sctph))); - sctph = (sctp_hdr_t *)(mp->b_rptr + ip_hdr_length); - /* - * Zero out the checksum field to ensure proper - * checksum calculation. - */ - sctph->sh_chksum = 0; - sctph->sh_chksum = sctp_cksum(mp, ip_hdr_length); - return; - } - - case IPPROTO_ICMPV6: - up = IPH_ICMPV6_CHECKSUMP(ip6h, ip_hdr_length); - cksum = IP_ICMPV6_CSUM_COMP; /* Pseudo-header cksum */ - break; - - default: - return; - } - - /* ULP assumes the checksum field is in the first mblk */ - ASSERT(((uchar_t *)up) + sizeof (uint16_t) <= mp->b_wptr); - - /* - * Restore the original entry in the checksum field so that we can - * properly calculate the checksum. - */ - *up = DB_CKSUMOCSUM(mp); - - /* - * We accumulate the pseudo header checksum in cksum. This is pretty - * hairy code, so watch close. One thing to keep in mind is that UDP - * and TCP have stored their respective datagram lengths in their - * checksum fields. This lines things up real nice. - */ - cksum += iphs[4] + iphs[5] + iphs[6] + iphs[7] + iphs[8] + iphs[9] + - iphs[10] + iphs[11] + iphs[12] + iphs[13] + iphs[14] + iphs[15] + - iphs[16] + iphs[17] + iphs[18] + iphs[19]; - cksum = IP_CSUM(mp, ip_hdr_length + offset, cksum); - - /* For UDP/IPv6 a zero UDP checksum is not allowed. Change to 0xffff */ - if (proto == IPPROTO_UDP && cksum == 0) - cksum = ~cksum; - *up = cksum; - -#undef iphs - /* No IP header checksum for IPv6 */ -} - /* * Process the specified mblk chain for proper handling of hardware * checksum offload. This routine is invoked for loopback traffic - * between MAC clients. The specific issue is that the upstack code (IP) may - * not calculate any checksums, or perhaps a partial checksum, based on the - * advertised HW checksum offload features of the underlying NIC below the - * netstack, but since we're looping back the packet without ever hitting the - * NIC, we may have to calculate the checksums ourselves at this point. - * + * between MAC clients. * The function handles a NULL mblk chain passed as argument. */ mblk_t * @@ -277,7 +122,6 @@ mac_fix_cksum(mblk_t *mp_chain) continue; mp1->b_next = mp->b_next; mp->b_next = NULL; - DB_CKSUMOCSUM(mp1) = DB_CKSUMOCSUM(mp); freemsg(mp); if (prev != NULL) prev->b_next = mp1; @@ -329,67 +173,98 @@ mac_fix_cksum(mblk_t *mp_chain) } if (flags & (HCK_FULLCKSUM | HCK_IPV4_HDRCKSUM)) { + ipha_t *ipha = NULL; + /* * In order to compute the full and header * checksums, we need to find and parse - * the IP/IPv6 and/or ULP headers. + * the IP and/or ULP headers. */ sap = (sap < ETHERTYPE_802_MIN) ? 0 : sap; - if (sap == ETHERTYPE_IP) { + /* + * IP header. + */ + if (sap != ETHERTYPE_IP) + continue; + + ASSERT(MBLKL(mp) >= offset + sizeof (ipha_t)); + /* LINTED: improper alignment cast */ + ipha = (ipha_t *)(mp->b_rptr + offset); + + if (flags & HCK_FULLCKSUM) { + ipaddr_t src, dst; + uint32_t cksum; + uint16_t *up; + uint8_t proto; + /* - * IP header. + * Pointer to checksum field in ULP header. */ - ipha_t *ipha; + proto = ipha->ipha_protocol; + ASSERT(ipha->ipha_version_and_hdr_length == + IP_SIMPLE_HDR_VERSION); + + switch (proto) { + case IPPROTO_TCP: + /* LINTED: improper alignment cast */ + up = IPH_TCPH_CHECKSUMP(ipha, + IP_SIMPLE_HDR_LENGTH); + break; + + case IPPROTO_UDP: + /* LINTED: improper alignment cast */ + up = IPH_UDPH_CHECKSUMP(ipha, + IP_SIMPLE_HDR_LENGTH); + break; + + default: + cmn_err(CE_WARN, "mac_fix_cksum: " + "unexpected protocol: %d", proto); + continue; + } - ASSERT(MBLKL(mp) >= offset + sizeof (ipha_t)); - /* LINTED: improper alignment cast */ - ipha = (ipha_t *)(mp->b_rptr + offset); + /* + * Pseudo-header checksum. + */ + src = ipha->ipha_src; + dst = ipha->ipha_dst; + len = ntohs(ipha->ipha_length) - + IP_SIMPLE_HDR_LENGTH; - if (flags & HCK_FULLCKSUM) { - mac_ipv4_chksum(mp, offset, ipha); - /* - * Flag the packet so that it appears - * that the checksum has already been - * verified by the hardware. - */ - flags &= ~HCK_FULLCKSUM; - flags |= HCK_FULLCKSUM_OK; - value = 0; - } + cksum = (dst >> 16) + (dst & 0xFFFF) + + (src >> 16) + (src & 0xFFFF); + cksum += htons(len); - if (flags & HCK_IPV4_HDRCKSUM) { - ASSERT(ipha != NULL); - ipha->ipha_hdr_checksum = 0; - ipha->ipha_hdr_checksum = - (uint16_t)ip_csum_hdr(ipha); - flags &= ~HCK_IPV4_HDRCKSUM; - flags |= HCK_IPV4_HDRCKSUM_OK; - } - } else if (sap == ETHERTYPE_IPV6) { /* - * IPv6 header. + * The checksum value stored in the packet needs + * to be correct. Compute it here. */ - ip6_t *ip6ha; + *up = 0; + cksum += (((proto) == IPPROTO_UDP) ? + IP_UDP_CSUM_COMP : IP_TCP_CSUM_COMP); + cksum = IP_CSUM(mp, IP_SIMPLE_HDR_LENGTH + + offset, cksum); + *(up) = (uint16_t)(cksum ? cksum : ~cksum); - ASSERT(MBLKL(mp) >= offset + sizeof (ip6_t)); - /* LINTED: improper alignment cast */ - ip6ha = (ip6_t *)(mp->b_rptr + offset); + /* + * Flag the packet so that it appears + * that the checksum has already been + * verified by the hardware. + */ + flags &= ~HCK_FULLCKSUM; + flags |= HCK_FULLCKSUM_OK; + value = 0; + } + + if (flags & HCK_IPV4_HDRCKSUM) { + ASSERT(ipha != NULL); + ipha->ipha_hdr_checksum = + (uint16_t)ip_csum_hdr(ipha); + flags &= ~HCK_IPV4_HDRCKSUM; + flags |= HCK_IPV4_HDRCKSUM_OK; - if (flags & HCK_FULLCKSUM) { - mac_ipv6_chksum(mp, offset, ip6ha); - /* - * Flag the packet so that it appears - * that the checksum has already been - * verified by the hardware. - */ - flags &= ~HCK_FULLCKSUM; - flags |= HCK_FULLCKSUM_OK; - value = 0; - } - } else { - continue; } } @@ -409,13 +284,6 @@ mac_fix_cksum(mblk_t *mp_chain) mp = new_mp; } - /* - * Note: this code properly handles a partial checksum - * for either IPv4 or IPv6. The "stuff", "start" and - * "end" returned from mac_hcksum_get() is correct for - * both protocols. - */ - ipp = mp->b_rptr + offset; /* LINTED: cast may result in improper alignment */ up = (uint16_t *)((uchar_t *)ipp + stuff); diff --git a/usr/src/uts/common/os/ip_cksum.c b/usr/src/uts/common/os/ip_cksum.c index ab5bf4f5ee..1fa1c9425b 100644 --- a/usr/src/uts/common/os/ip_cksum.c +++ b/usr/src/uts/common/os/ip_cksum.c @@ -21,7 +21,6 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2018 Joyent, Inc. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -35,7 +34,6 @@ #include <sys/vtrace.h> #include <inet/sctp_crc32.h> #include <inet/ip.h> -#include <inet/ip6.h> #include <sys/multidata.h> #include <sys/multidata_impl.h> @@ -383,112 +381,6 @@ done: return (sum); } -/* - * Try to determine where and what are the IPv6 header length and - * pointer to nexthdr value for the upper layer protocol (or an - * unknown next hdr). - * - * Parameters returns a pointer to the nexthdr value; - * Must handle malformed packets of various sorts. - * Function returns failure for malformed cases. - */ -boolean_t -ip_hdr_length_nexthdr_v6(mblk_t *mp, ip6_t *ip6h, uint16_t *hdr_length_ptr, - uint8_t **nexthdrpp) -{ - uint16_t length; - uint_t ehdrlen; - uint8_t *nexthdrp; - uint8_t *whereptr; - uint8_t *endptr; - ip6_dest_t *desthdr; - ip6_rthdr_t *rthdr; - ip6_frag_t *fraghdr; - - ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION); - length = IPV6_HDR_LEN; - whereptr = ((uint8_t *)&ip6h[1]); /* point to next hdr */ - endptr = mp->b_wptr; - - nexthdrp = &ip6h->ip6_nxt; - while (whereptr < endptr) { - /* Is there enough left for len + nexthdr? */ - if (whereptr + MIN_EHDR_LEN > endptr) - break; - - switch (*nexthdrp) { - case IPPROTO_HOPOPTS: - case IPPROTO_DSTOPTS: - /* Assumes the headers are identical for hbh and dst */ - desthdr = (ip6_dest_t *)whereptr; - ehdrlen = 8 * (desthdr->ip6d_len + 1); - if ((uchar_t *)desthdr + ehdrlen > endptr) - return (B_FALSE); - nexthdrp = &desthdr->ip6d_nxt; - break; - case IPPROTO_ROUTING: - rthdr = (ip6_rthdr_t *)whereptr; - ehdrlen = 8 * (rthdr->ip6r_len + 1); - if ((uchar_t *)rthdr + ehdrlen > endptr) - return (B_FALSE); - nexthdrp = &rthdr->ip6r_nxt; - break; - case IPPROTO_FRAGMENT: - fraghdr = (ip6_frag_t *)whereptr; - ehdrlen = sizeof (ip6_frag_t); - if ((uchar_t *)&fraghdr[1] > endptr) - return (B_FALSE); - nexthdrp = &fraghdr->ip6f_nxt; - break; - case IPPROTO_NONE: - /* No next header means we're finished */ - default: - *hdr_length_ptr = length; - *nexthdrpp = nexthdrp; - return (B_TRUE); - } - length += ehdrlen; - whereptr += ehdrlen; - *hdr_length_ptr = length; - *nexthdrpp = nexthdrp; - } - switch (*nexthdrp) { - case IPPROTO_HOPOPTS: - case IPPROTO_DSTOPTS: - case IPPROTO_ROUTING: - case IPPROTO_FRAGMENT: - /* - * If any know extension headers are still to be processed, - * the packet's malformed (or at least all the IP header(s) are - * not in the same mblk - and that should never happen. - */ - return (B_FALSE); - - default: - /* - * If we get here, we know that all of the IP headers were in - * the same mblk, even if the ULP header is in the next mblk. - */ - *hdr_length_ptr = length; - *nexthdrpp = nexthdrp; - return (B_TRUE); - } -} - -/* - * Return the length of the IPv6 related headers (including extension headers) - * Returns a length even if the packet is malformed. - */ -int -ip_hdr_length_v6(mblk_t *mp, ip6_t *ip6h) -{ - uint16_t hdr_len; - uint8_t *nexthdrp; - - (void) ip_hdr_length_nexthdr_v6(mp, ip6h, &hdr_len, &nexthdrp); - return (hdr_len); -} - uint32_t sctp_cksum(mblk_t *mp, int offset) { diff --git a/usr/src/uts/common/sys/stream.h b/usr/src/uts/common/sys/stream.h index 72c561a8f9..a45030ff7e 100644 --- a/usr/src/uts/common/sys/stream.h +++ b/usr/src/uts/common/sys/stream.h @@ -21,7 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2018 Joyent, Inc. All rights reserved. + * Copyright 2015 Joyent, Inc. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -338,8 +338,7 @@ typedef struct datab { uint16_t u16; } cksum_val; /* used to store calculated cksum */ uint16_t flags; - uint16_t pad; /* not padding, see DB_LSOMSS, DB_TCI */ - uint32_t ocsum; /* original cksum field value */ + uint16_t pad; } cksum; /* * Union used for future extensions (pointer to data ?). diff --git a/usr/src/uts/common/sys/strsubr.h b/usr/src/uts/common/sys/strsubr.h index 6e1baa9ef2..0f29dd3675 100644 --- a/usr/src/uts/common/sys/strsubr.h +++ b/usr/src/uts/common/sys/strsubr.h @@ -1341,7 +1341,6 @@ extern int SAMESTR(queue_t *); #define DB_CKSUMEND(mp) ((mp)->b_datap->db_cksumend) #define DB_CKSUMSTUFF(mp) ((mp)->b_datap->db_cksumstuff) #define DB_CKSUMFLAGS(mp) ((mp)->b_datap->db_struioun.cksum.flags) -#define DB_CKSUMOCSUM(mp) ((mp)->b_datap->db_struioun.cksum.ocsum) #define DB_CKSUM16(mp) ((mp)->b_datap->db_cksum16) #define DB_CKSUM32(mp) ((mp)->b_datap->db_cksum32) #define DB_LSOFLAGS(mp) ((mp)->b_datap->db_struioun.cksum.flags) |