summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2013-08-24 19:51:18 +0000
committerandre <andre@FreeBSD.org>2013-08-24 19:51:18 +0000
commite3737c33e77ed583376ee2f2b90d7f232650d182 (patch)
tree800974ecd8993a32d93e99d748ceee7bdcc92f2b /sys
parent79d40bcf2d33796830bd39a0791e82ba2fc2b42c (diff)
downloadFreeBSD-src-e3737c33e77ed583376ee2f2b90d7f232650d182.zip
FreeBSD-src-e3737c33e77ed583376ee2f2b90d7f232650d182.tar.gz
Restructure the mbuf pkthdr to make it fit for upcoming capabilities and
features. The changes in particular are: o Remove rarely used "header" pointer and replace it with a 64bit protocol/ layer specific union PH_loc for local use. Protocols can flexibly overlay their own 8 to 64 bit fields to store information while the packet is worked on. o Mechanically convert IP reassembly, IGMP/MLD and ATM to use pkthdr.PH_loc instead of pkthdr.header. o Extend csum_flags to 64bits to allow for additional future offload information to be carried (e.g. iSCSI, IPsec offload, and others). o Move the RSS hash type enumerator from abusing m_flags to its own 8bit rsstype field. Adjust accessor macros. o Add cosqos field to store Class of Service / Quality of Service information with the packet. It is not yet supported in any drivers but allows us to get on par with Cisco/Juniper in routing applications (plus MPLS QoS) with a modernized ALTQ. o Add four 8 bit fields l[2-5]hlen to store the relative header offsets from the start of the packet. This is important for various offload capabilities and to relieve the drivers from having to parse the packet and protocol headers to find out location of checksums and other information. Header parsing in drivers is a lot of copy-paste and unhandled corner cases which we want to avoid. o Add another flexible 64bit union to map various additional persistent packet information, like ether_vtag, tso_segsz and csum fields. Depending on the csum_flags settings some fields may have different usage making it very flexible and adaptable to future capabilities. o Restructure the CSUM flags to better signify their outbound (down the stack) and inbound (up the stack) use. The CSUM flags used to be a bit chaotic and rather poorly documented leading to incorrect use in many places. Bring clarity into their use through better naming. Compatibility mappings are provided to preserve the API. The drivers can be corrected one by one and MFC'd without issue. o The size of pkthdr stays the same at 48/56bytes (32/64bit architectures). Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/cxgb/cxgb_sge.c4
-rw-r--r--sys/dev/e1000/if_igb.c2
-rw-r--r--sys/dev/ixgbe/ixgbe.c2
-rw-r--r--sys/dev/ixgbe/ixv.c2
-rw-r--r--sys/dev/patm/if_patm.c2
-rw-r--r--sys/dev/patm/if_patm_tx.c8
-rw-r--r--sys/dev/qlxgb/qla_hw.c4
-rw-r--r--sys/kern/kern_mbuf.c16
-rw-r--r--sys/kern/uipc_mbuf.c7
-rw-r--r--sys/net/if.h2
-rw-r--r--sys/netinet/igmp.c8
-rw-r--r--sys/netinet/ip_input.c4
-rw-r--r--sys/netinet6/ip6_output.c4
-rw-r--r--sys/netinet6/mld6.c6
-rw-r--r--sys/sys/mbuf.h204
15 files changed, 173 insertions, 102 deletions
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 76bfad4..bf669b9 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -1470,9 +1470,9 @@ t3_encap(struct sge_qset *qs, struct mbuf **m)
hdr->len = htonl(mlen | 0x80000000);
if (__predict_false(mlen < TCPPKTHDRSIZE)) {
- printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
+ printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%b,flags=%#x",
m0, mlen, m0->m_pkthdr.tso_segsz,
- m0->m_pkthdr.csum_flags, m0->m_flags);
+ (int)m0->m_pkthdr.csum_flags, CSUM_BITS, m0->m_flags);
panic("tx tso packet too small");
}
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 6887bcf..1c8e9bb 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -4981,7 +4981,7 @@ igb_rx_checksum(u32 staterr, struct mbuf *mp, u32 ptype)
}
if (status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) {
- u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
#if __FreeBSD_version >= 800000
if (sctp) /* reassign */
type = CSUM_SCTP_VALID;
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
index e6dc239..b65df72 100644
--- a/sys/dev/ixgbe/ixgbe.c
+++ b/sys/dev/ixgbe/ixgbe.c
@@ -4625,7 +4625,7 @@ ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype)
mp->m_pkthdr.csum_flags = 0;
}
if (status & IXGBE_RXD_STAT_L4CS) {
- u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
#if __FreeBSD_version >= 800000
if (sctp)
type = CSUM_SCTP_VALID;
diff --git a/sys/dev/ixgbe/ixv.c b/sys/dev/ixgbe/ixv.c
index d0f4e4c..a471da9 100644
--- a/sys/dev/ixgbe/ixv.c
+++ b/sys/dev/ixgbe/ixv.c
@@ -3544,7 +3544,7 @@ ixv_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype)
mp->m_pkthdr.csum_flags = 0;
}
if (status & IXGBE_RXD_STAT_L4CS) {
- u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
#if __FreeBSD_version >= 800000
if (sctp)
type = CSUM_SCTP_VALID;
diff --git a/sys/dev/patm/if_patm.c b/sys/dev/patm/if_patm.c
index 279afde..7c0eefa 100644
--- a/sys/dev/patm/if_patm.c
+++ b/sys/dev/patm/if_patm.c
@@ -319,7 +319,7 @@ patm_stop(struct patm_softc *sc)
for (i = 0; i < IDT_TSQE_TAG_SPACE; i++) {
if ((m = scd->on_card[i]) != NULL) {
scd->on_card[i] = 0;
- map = m->m_pkthdr.header;
+ map = m->m_pkthdr.PH_loc.ptr;
bus_dmamap_unload(sc->tx_tag, map->map);
SLIST_INSERT_HEAD(&sc->tx_maps_free, map, link);
diff --git a/sys/dev/patm/if_patm_tx.c b/sys/dev/patm/if_patm_tx.c
index 81a1efc..f17657d 100644
--- a/sys/dev/patm/if_patm_tx.c
+++ b/sys/dev/patm/if_patm_tx.c
@@ -373,7 +373,7 @@ patm_start(struct ifnet *ifp)
}
/* save data */
- m->m_pkthdr.header = vcc;
+ m->m_pkthdr.PH_loc.ptr = vcc;
/* try to put it on the channels queue */
if (_IF_QFULL(&vcc->scd->q)) {
@@ -473,7 +473,7 @@ patm_launch(struct patm_softc *sc, struct patm_scd *scd)
if (m == NULL)
break;
- a.vcc = m->m_pkthdr.header;
+ a.vcc = m->m_pkthdr.PH_loc.ptr;
/* we must know the number of segments beforehand - count
* this may actually give a wrong number of segments for
@@ -499,7 +499,7 @@ patm_launch(struct patm_softc *sc, struct patm_scd *scd)
}
/* load the map */
- m->m_pkthdr.header = map;
+ m->m_pkthdr.PH_loc.ptr = map;
a.mbuf = m;
/* handle AAL_RAW */
@@ -690,7 +690,7 @@ patm_tx(struct patm_softc *sc, u_int stamp, u_int status)
scd->on_card[last] = NULL;
patm_debug(sc, TX, "ok tag=%x", last);
- map = m->m_pkthdr.header;
+ map = m->m_pkthdr.PH_loc.ptr;
scd->space += m->m_pkthdr.csum_data;
bus_dmamap_sync(sc->tx_tag, map->map,
diff --git a/sys/dev/qlxgb/qla_hw.c b/sys/dev/qlxgb/qla_hw.c
index c866cf5..ea20b63 100644
--- a/sys/dev/qlxgb/qla_hw.c
+++ b/sys/dev/qlxgb/qla_hw.c
@@ -1000,9 +1000,9 @@ qla_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
(mp->m_pkthdr.len > ha->max_frame_size)){
/* TBD: copy into private buffer and send it */
device_printf(dev,
- "%s: (nsegs[%d, %d, 0x%x] > Q8_TX_MAX_SEGMENTS)\n",
+ "%s: (nsegs[%d, %d, 0x%b] > Q8_TX_MAX_SEGMENTS)\n",
__func__, nsegs, mp->m_pkthdr.len,
- mp->m_pkthdr.csum_flags);
+ (int)mp->m_pkthdr.csum_flags, CSUM_BITS);
qla_dump_buf8(ha, "qla_hw_send: wrong pkt",
mtod(mp, char *), mp->m_len);
return (EINVAL);
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index 85d62ea..a9777ef 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -650,16 +650,20 @@ m_pkthdr_init(struct mbuf *m, int how)
int error;
#endif
m->m_data = m->m_pktdat;
- SLIST_INIT(&m->m_pkthdr.tags);
m->m_pkthdr.rcvif = NULL;
- m->m_pkthdr.header = NULL;
+ SLIST_INIT(&m->m_pkthdr.tags);
m->m_pkthdr.len = 0;
m->m_pkthdr.flowid = 0;
- m->m_pkthdr.fibnum = 0;
m->m_pkthdr.csum_flags = 0;
- m->m_pkthdr.csum_data = 0;
- m->m_pkthdr.tso_segsz = 0;
- m->m_pkthdr.ether_vtag = 0;
+ m->m_pkthdr.fibnum = 0;
+ m->m_pkthdr.cosqos = 0;
+ m->m_pkthdr.rsstype = 0;
+ m->m_pkthdr.l2hlen = 0;
+ m->m_pkthdr.l3hlen = 0;
+ m->m_pkthdr.l4hlen = 0;
+ m->m_pkthdr.l5hlen = 0;
+ m->m_pkthdr.PH_per.sixtyfour[0] = 0;
+ m->m_pkthdr.PH_loc.sixtyfour[0] = 0;
#ifdef MAC
/* If the label init fails, fail the alloc */
error = mac_mbuf_init(m, how);
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 4b356b7..f18a2df 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -438,11 +438,6 @@ m_sanity(struct mbuf *m0, int sanitize)
M_SANITY_ACTION("m_data outside mbuf data range right");
if ((caddr_t)m->m_data + m->m_len > b)
M_SANITY_ACTION("m_data + m_len exeeds mbuf space");
- if ((m->m_flags & M_PKTHDR) && m->m_pkthdr.header) {
- if ((caddr_t)m->m_pkthdr.header < a ||
- (caddr_t)m->m_pkthdr.header > b)
- M_SANITY_ACTION("m_pkthdr.header outside mbuf data range");
- }
/* m->m_nextpkt may only be set on first mbuf in chain. */
if (m != m0 && m->m_nextpkt != NULL) {
@@ -746,7 +741,6 @@ m_copymdata(struct mbuf *m, struct mbuf *n, int off, int len,
return NULL;
bcopy(&buf, mm->m_ext.ext_buf, mm->m_len);
mm->m_data = mm->m_ext.ext_buf;
- mm->m_pkthdr.header = NULL;
}
if (prep && !(mm->m_flags & M_EXT) && len > M_LEADINGSPACE(mm)) {
bcopy(mm->m_data, &buf, mm->m_len);
@@ -757,7 +751,6 @@ m_copymdata(struct mbuf *m, struct mbuf *n, int off, int len,
mm->m_ext.ext_size - mm->m_len, mm->m_len);
mm->m_data = (caddr_t)mm->m_ext.ext_buf +
mm->m_ext.ext_size - mm->m_len;
- mm->m_pkthdr.header = NULL;
}
/* Append/prepend as many mbuf (clusters) as necessary to fit len. */
diff --git a/sys/net/if.h b/sys/net/if.h
index 7aca535..ab98ec0 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -103,7 +103,7 @@ struct if_data {
u_long ifi_omcasts; /* packets sent via multicast */
u_long ifi_iqdrops; /* dropped on input, this interface */
u_long ifi_noproto; /* destined for unsupported protocol */
- u_long ifi_hwassist; /* HW offload capabilities, see IFCAP */
+ uint64_t ifi_hwassist; /* HW offload capabilities, see IFCAP */
time_t ifi_epoch; /* uptime at attach or stat reset */
struct timeval ifi_lastchange; /* time of last administrative change */
};
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 9a43108..9f31a19 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -289,7 +289,7 @@ igmp_save_context(struct mbuf *m, struct ifnet *ifp)
{
#ifdef VIMAGE
- m->m_pkthdr.header = ifp->if_vnet;
+ m->m_pkthdr.PH_loc.ptr = ifp->if_vnet;
#endif /* VIMAGE */
m->m_pkthdr.flowid = ifp->if_index;
}
@@ -298,7 +298,7 @@ static __inline void
igmp_scrub_context(struct mbuf *m)
{
- m->m_pkthdr.header = NULL;
+ m->m_pkthdr.PH_loc.ptr = NULL;
m->m_pkthdr.flowid = 0;
}
@@ -326,7 +326,7 @@ igmp_restore_context(struct mbuf *m)
#ifdef notyet
#if defined(VIMAGE) && defined(INVARIANTS)
- KASSERT(curvnet == (m->m_pkthdr.header),
+ KASSERT(curvnet == (m->m_pkthdr.PH_loc.ptr),
("%s: called when curvnet was not restored", __func__));
#endif
#endif
@@ -3403,7 +3403,7 @@ igmp_intr(struct mbuf *m)
* indexes to guard against interface detach, they are
* unique to each VIMAGE and must be retrieved.
*/
- CURVNET_SET((struct vnet *)(m->m_pkthdr.header));
+ CURVNET_SET((struct vnet *)(m->m_pkthdr.PH_loc.ptr));
ifindex = igmp_restore_context(m);
/*
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 2d84f28..ca55c5e 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -921,7 +921,7 @@ found:
* ip_reass() will return a different mbuf.
*/
IPSTAT_INC(ips_fragments);
- m->m_pkthdr.header = ip;
+ m->m_pkthdr.PH_loc.ptr = ip;
/* Previous ip_reass() started here. */
/*
@@ -964,7 +964,7 @@ found:
#endif
}
-#define GETIP(m) ((struct ip*)((m)->m_pkthdr.header))
+#define GETIP(m) ((struct ip*)((m)->m_pkthdr.PH_loc.ptr))
/*
* Handle ECN by comparing this segment with the first one;
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 5df3572..0d55b66 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -196,8 +196,8 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset)
if (offset + sizeof(u_short) > m->m_len) {
printf("%s: delayed m_pullup, m->len: %d plen %u off %u "
- "csum_flags=0x%04x\n", __func__, m->m_len, plen, offset,
- m->m_pkthdr.csum_flags);
+ "csum_flags=%b\n", __func__, m->m_len, plen, offset,
+ (int)m->m_pkthdr.csum_flags, CSUM_BITS);
/*
* XXX this should not happen, but if it does, the correct
* behavior may be to insert the checksum in the appropriate
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index 683a0d5..77b19bf 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -275,7 +275,7 @@ mld_save_context(struct mbuf *m, struct ifnet *ifp)
{
#ifdef VIMAGE
- m->m_pkthdr.header = ifp->if_vnet;
+ m->m_pkthdr.PH_loc.ptr = ifp->if_vnet;
#endif /* VIMAGE */
m->m_pkthdr.flowid = ifp->if_index;
}
@@ -284,7 +284,7 @@ static __inline void
mld_scrub_context(struct mbuf *m)
{
- m->m_pkthdr.header = NULL;
+ m->m_pkthdr.PH_loc.ptr = NULL;
m->m_pkthdr.flowid = 0;
}
@@ -300,7 +300,7 @@ mld_restore_context(struct mbuf *m)
{
#if defined(VIMAGE) && defined(INVARIANTS)
- KASSERT(curvnet == m->m_pkthdr.header,
+ KASSERT(curvnet == m->m_pkthdr.PH_loc.ptr,
("%s: called when curvnet was not restored", __func__));
#endif
return (m->m_pkthdr.flowid);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index c250c87..fc5711d 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -112,28 +112,49 @@ struct m_tag {
/*
* Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
+ * Size ILP32: 48
+ * LP64: 56
*/
struct pkthdr {
struct ifnet *rcvif; /* rcv interface */
- /* variables for ip and tcp reassembly */
- void *header; /* pointer to packet header */
- int len; /* total packet length */
- uint32_t flowid; /* packet's 4-tuple system
- * flow identifier
- */
- /* variables for hardware checksum */
- int csum_flags; /* flags regarding checksum */
- int csum_data; /* data field used by csum routines */
- u_int16_t tso_segsz; /* TSO segment size */
- union {
- u_int16_t vt_vtag; /* Ethernet 802.1p+q vlan tag */
- u_int16_t vt_nrecs; /* # of IGMPv3 records in this chain */
- } PH_vt;
- u_int16_t fibnum; /* this packet should use this fib */
- u_int16_t pad2; /* align to 32 bits */
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
+ int32_t len; /* total packet length */
+
+ /* Layer crossing persistent information. */
+ uint32_t flowid; /* packet's 4-tuple system */
+ uint64_t csum_flags; /* checksum and offload features */
+ uint16_t fibnum; /* this packet should use this fib */
+ uint8_t cosqos; /* class/quality of service */
+ uint8_t rsstype; /* hash type */
+ uint8_t l2hlen; /* layer 2 header length */
+ uint8_t l3hlen; /* layer 3 header length */
+ uint8_t l4hlen; /* layer 4 header length */
+ uint8_t l5hlen; /* layer 5 header length */
+ union {
+ uint8_t eigth[8];
+ uint16_t sixteen[4];
+ uint32_t thirtytwo[2];
+ uint64_t sixtyfour[1];
+ uintptr_t unintptr[1];
+ void *ptr;
+ } PH_per;
+
+ /* Layer specific non-persistent local storage for reassembly, etc. */
+ union {
+ uint8_t eigth[8];
+ uint16_t sixteen[4];
+ uint32_t thirtytwo[2];
+ uint64_t sixtyfour[1];
+ uintptr_t unintptr[1];
+ void *ptr;
+ } PH_loc;
};
-#define ether_vtag PH_vt.vt_vtag
+#define ether_vtag PH_per.sixteen[0]
+#define PH_vt PH_per
+#define vt_nrecs sixteen[0]
+#define tso_segsz PH_per.sixteen[1]
+#define csum_phsum PH_per.sixteen[2]
+#define csum_data PH_per.thirtytwo[1]
/*
* Description of external storage mapped into mbuf; valid only if M_EXT is
@@ -209,8 +230,6 @@ struct mbuf {
#define M_PROTO11 0x00400000 /* protocol-specific */
#define M_PROTO12 0x00800000 /* protocol-specific */
-#define M_HASHTYPEBITS 0x0F000000 /* mask of bits holding flowid hash type */
-
/*
* Flags to purge when crossing layers.
*/
@@ -219,6 +238,13 @@ struct mbuf {
M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
/*
+ * Flags preserved when copying m_pkthdr.
+ */
+#define M_COPYFLAGS \
+ (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
+ M_PROTOFLAGS)
+
+/*
* Mbuf flag description for use with printf(9) %b identifier.
*/
#define M_FLAG_BITS \
@@ -245,31 +271,46 @@ struct mbuf {
* that provide an opaque flow identifier, allowing for ordering and
* distribution without explicit affinity.
*/
-#define M_HASHTYPE_SHIFT 24
-#define M_HASHTYPE_NONE 0x0
-#define M_HASHTYPE_RSS_IPV4 0x1 /* IPv4 2-tuple */
-#define M_HASHTYPE_RSS_TCP_IPV4 0x2 /* TCPv4 4-tuple */
-#define M_HASHTYPE_RSS_IPV6 0x3 /* IPv6 2-tuple */
-#define M_HASHTYPE_RSS_TCP_IPV6 0x4 /* TCPv6 4-tuple */
-#define M_HASHTYPE_RSS_IPV6_EX 0x5 /* IPv6 2-tuple + ext hdrs */
-#define M_HASHTYPE_RSS_TCP_IPV6_EX 0x6 /* TCPv6 4-tiple + ext hdrs */
-#define M_HASHTYPE_OPAQUE 0xf /* ordering, not affinity */
-
-#define M_HASHTYPE_CLEAR(m) (m)->m_flags &= ~(M_HASHTYPEBITS)
-#define M_HASHTYPE_GET(m) (((m)->m_flags & M_HASHTYPEBITS) >> \
- M_HASHTYPE_SHIFT)
-#define M_HASHTYPE_SET(m, v) do { \
- (m)->m_flags &= ~M_HASHTYPEBITS; \
- (m)->m_flags |= ((v) << M_HASHTYPE_SHIFT); \
-} while (0)
+#define M_HASHTYPE_NONE 0
+#define M_HASHTYPE_RSS_IPV4 1 /* IPv4 2-tuple */
+#define M_HASHTYPE_RSS_TCP_IPV4 2 /* TCPv4 4-tuple */
+#define M_HASHTYPE_RSS_IPV6 3 /* IPv6 2-tuple */
+#define M_HASHTYPE_RSS_TCP_IPV6 4 /* TCPv6 4-tuple */
+#define M_HASHTYPE_RSS_IPV6_EX 5 /* IPv6 2-tuple + ext hdrs */
+#define M_HASHTYPE_RSS_TCP_IPV6_EX 6 /* TCPv6 4-tiple + ext hdrs */
+#define M_HASHTYPE_OPAQUE 255 /* ordering, not affinity */
+
+#define M_HASHTYPE_CLEAR(m) ((m)->m_pkthdr.rsstype = 0)
+#define M_HASHTYPE_GET(m) ((m)->m_pkthdr.rsstype)
+#define M_HASHTYPE_SET(m, v) ((m)->m_pkthdr.rsstype = (v))
#define M_HASHTYPE_TEST(m, v) (M_HASHTYPE_GET(m) == (v))
/*
- * Flags preserved when copying m_pkthdr.
+ * COS/QOS class and quality of service tags.
+ * It uses DSCP code points as base.
*/
-#define M_COPYFLAGS \
- (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
- M_PROTOFLAGS|M_HASHTYPEBITS)
+#define QOS_DSCP_CS0 0x00
+#define QOS_DSCP_DEF QOS_DSCP_CS0
+#define QOS_DSCP_CS1 0x20
+#define QOS_DSCP_AF11 0x28
+#define QOS_DSCP_AF12 0x30
+#define QOS_DSCP_AF13 0x38
+#define QOS_DSCP_CS2 0x40
+#define QOS_DSCP_AF21 0x48
+#define QOS_DSCP_AF22 0x50
+#define QOS_DSCP_AF23 0x58
+#define QOS_DSCP_CS3 0x60
+#define QOS_DSCP_AF31 0x68
+#define QOS_DSCP_AF32 0x70
+#define QOS_DSCP_AF33 0x78
+#define QOS_DSCP_CS4 0x80
+#define QOS_DSCP_AF41 0x88
+#define QOS_DSCP_AF42 0x90
+#define QOS_DSCP_AF43 0x98
+#define QOS_DSCP_CS5 0xa0
+#define QOS_DSCP_EF 0xb8
+#define QOS_DSCP_CS6 0xc0
+#define QOS_DSCP_CS7 0xe0
/*
* External mbuf storage buffer types.
@@ -325,33 +366,66 @@ struct mbuf {
"\30EXT_FLAG_EXP4"
/*
- * Flags indicating hw checksum support and sw checksum requirements. This
- * field can be directly tested against if_data.ifi_hwassist.
+ * Flags indicating checksum, segmentation and other offload work to be
+ * done, or already done, by hardware or lower layers. It is split into
+ * separate inbound and outbound flags.
+ *
+ * Outbound flags that are set by upper protocol layers requesting lower
+ * layers, or ideally the hardware, to perform these offloading tasks.
+ * For outbound packets this field and its flags can be directly tested
+ * against if_data.ifi_hwassist.
+ */
+#define CSUM_IP 0x00000001 /* IP header checksum offload */
+#define CSUM_IP_UDP 0x00000002 /* UDP checksum offload */
+#define CSUM_IP_TCP 0x00000004 /* TCP checksum offload */
+#define CSUM_IP_SCTP 0x00000008 /* SCTP checksum offload */
+#define CSUM_IP_TSO 0x00000010 /* TCP segmentation offload */
+#define CSUM_IP_ISCSI 0x00000020 /* iSCSI checksum offload */
+
+#define CSUM_IP6_UDP 0x00000200 /* UDP checksum offload */
+#define CSUM_IP6_TCP 0x00000400 /* TCP checksum offload */
+#define CSUM_IP6_SCTP 0x00000800 /* SCTP checksum offload */
+#define CSUM_IP6_TSO 0x00001000 /* TCP segmentation offload */
+#define CSUM_IP6_ISCSI 0x00002000 /* iSCSI checksum offload */
+
+/* Inbound checksum support where the checksum was verified by hardware. */
+#define CSUM_L3_CALC 0x01000000 /* calculated layer 3 csum */
+#define CSUM_L3_VALID 0x02000000 /* checksum is correct */
+#define CSUM_L4_CALC 0x04000000 /* calculated layer 4 csum */
+#define CSUM_L4_VALID 0x08000000 /* checksum is correct */
+#define CSUM_L5_CALC 0x10000000 /* calculated layer 5 csum */
+#define CSUM_L5_VALID 0x20000000 /* checksum is correct */
+#define CSUM_COALESED 0x40000000 /* contains merged segments */
+
+/*
+ * CSUM flag description for use with printf(9) %b identifier.
*/
-#define CSUM_IP 0x0001 /* will csum IP */
-#define CSUM_TCP 0x0002 /* will csum TCP */
-#define CSUM_UDP 0x0004 /* will csum UDP */
-#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */
-#define CSUM_TSO 0x0020 /* will do TSO */
-#define CSUM_SCTP 0x0040 /* will csum SCTP */
-#define CSUM_SCTP_IPV6 0x0080 /* will csum IPv6/SCTP */
-
-#define CSUM_IP_CHECKED 0x0100 /* did csum IP */
-#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */
-#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */
-#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */
-#define CSUM_SCTP_VALID 0x1000 /* SCTP checksum is valid */
-#define CSUM_UDP_IPV6 0x2000 /* will csum IPv6/UDP */
-#define CSUM_TCP_IPV6 0x4000 /* will csum IPv6/TCP */
-/* CSUM_TSO_IPV6 0x8000 will do IPv6/TSO */
-
-/* CSUM_FRAGMENT_IPV6 0x10000 will do IPv6 fragementation */
-
-#define CSUM_DELAY_DATA_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
+#define CSUM_BITS \
+ "\20\1CSUM_IP\2CSUM_IP_UDP\3CSUM_IP_TCP\4CSUM_IP_SCTP\5CSUM_IP_TSO" \
+ "\6CSUM_IP_ISCSI" \
+ "\12CSUM_IP6_UDP\13CSUM_IP6_TCP\14CSUM_IP6_SCTP\15CSUM_IP6_TSO" \
+ "\16CSUM_IP6_ISCSI" \
+ "\31CSUM_L3_CALC\32CSUM_L3_VALID\33CSUM_L4_CALC\34CSUM_L4_VALID" \
+ "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESED"
+
+/* CSUM flags compatibility mappings. */
+#define CSUM_IP_CHECKED CSUM_L3_CALC
+#define CSUM_IP_VALID CSUM_L3_VALID
+#define CSUM_DATA_VALID CSUM_L4_VALID
+#define CSUM_PSEUDO_HDR CSUM_L4_CALC
+#define CSUM_SCTP_VALID CSUM_L3_VALID
+#define CSUM_DELAY_DATA (CSUM_TCP|CSUM_UDP)
+#define CSUM_DELAY_IP CSUM_IP /* Only v4, no v6 IP hdr csum */
+#define CSUM_DELAY_DATA_IPV6 (CSUM_TCP_IPV6|CSUM_UDP_IPV6)
#define CSUM_DATA_VALID_IPV6 CSUM_DATA_VALID
-
-#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
-#define CSUM_DELAY_IP (CSUM_IP) /* Only v4, no v6 IP hdr csum */
+#define CSUM_TCP CSUM_IP_TCP
+#define CSUM_UDP CSUM_IP_UDP
+#define CSUM_SCTP CSUM_IP_SCTP
+#define CSUM_TSO (CSUM_IP_TSO|CSUM_IP6_TSO)
+#define CSUM_UDP_IPV6 CSUM_IP6_UDP
+#define CSUM_TCP_IPV6 CSUM_IP6_TCP
+#define CSUM_SCTP_IPV6 CSUM_IP6_SCTP
+#define CSUM_FRAGMENT 0x0 /* Unused */
/*
* mbuf types.
OpenPOWER on IntegriCloud