SKB_GSO_TCPV6 = 1 << 4,
};
+#if BITS_PER_LONG > 32
+#define NET_SKBUFF_DATA_USES_OFFSET 1
+#endif
+
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+typedef unsigned int sk_buff_data_t;
+#else
+typedef unsigned char *sk_buff_data_t;
+#endif
+
/**
* struct sk_buff - socket buffer
* @next: Next buffer in list
int iif;
/* 4 byte hole on 64 bit*/
- unsigned char *transport_header;
- unsigned char *network_header;
- unsigned char *mac_header;
+ sk_buff_data_t transport_header;
+ sk_buff_data_t network_header;
+ sk_buff_data_t mac_header;
struct dst_entry *dst;
struct sec_path *sp;
skb->tail += len;
}
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
{
- return skb->transport_header;
+ return skb->head + skb->transport_header;
}
static inline void skb_reset_transport_header(struct sk_buff *skb)
{
- skb->transport_header = skb->data;
+ skb->transport_header = skb->data - skb->head;
}
static inline void skb_set_transport_header(struct sk_buff *skb,
const int offset)
{
- skb->transport_header = skb->data + offset;
-}
-
-static inline int skb_transport_offset(const struct sk_buff *skb)
-{
- return skb->transport_header - skb->data;
+ skb_reset_transport_header(skb);
+ skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
- return skb->network_header;
+ return skb->head + skb->network_header;
}
static inline void skb_reset_network_header(struct sk_buff *skb)
{
- skb->network_header = skb->data;
+ skb->network_header = skb->data - skb->head;
}
static inline void skb_set_network_header(struct sk_buff *skb, const int offset)
{
- skb->network_header = skb->data + offset;
+ skb_reset_network_header(skb);
+ skb->network_header += offset;
}
-static inline int skb_network_offset(const struct sk_buff *skb)
+static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
- return skb->network_header - skb->data;
+ return skb->head + skb->mac_header;
}
-static inline u32 skb_network_header_len(const struct sk_buff *skb)
+static inline int skb_mac_header_was_set(const struct sk_buff *skb)
{
- return skb->transport_header - skb->network_header;
+ return skb->mac_header != ~0U;
+}
+
+static inline void skb_reset_mac_header(struct sk_buff *skb)
+{
+ skb->mac_header = skb->data - skb->head;
+}
+
+static inline void skb_set_mac_header(struct sk_buff *skb, const int offset)
+{
+ skb_reset_mac_header(skb);
+ skb->mac_header += offset;
+}
+
+#else /* NET_SKBUFF_DATA_USES_OFFSET */
+
+static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
+{
+ return skb->transport_header;
+}
+
+static inline void skb_reset_transport_header(struct sk_buff *skb)
+{
+ skb->transport_header = skb->data;
+}
+
+static inline void skb_set_transport_header(struct sk_buff *skb,
+ const int offset)
+{
+ skb->transport_header = skb->data + offset;
+}
+
+static inline unsigned char *skb_network_header(const struct sk_buff *skb)
+{
+ return skb->network_header;
+}
+
+static inline void skb_reset_network_header(struct sk_buff *skb)
+{
+ skb->network_header = skb->data;
+}
+
+static inline void skb_set_network_header(struct sk_buff *skb, const int offset)
+{
+ skb->network_header = skb->data + offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
skb->mac_header = skb->data + offset;
}
+#endif /* NET_SKBUFF_DATA_USES_OFFSET */
+
+static inline int skb_transport_offset(const struct sk_buff *skb)
+{
+ return skb_transport_header(skb) - skb->data;
+}
+
+static inline u32 skb_network_header_len(const struct sk_buff *skb)
+{
+ return skb->transport_header - skb->network_header;
+}
+
+static inline int skb_network_offset(const struct sk_buff *skb)
+{
+ return skb_network_header(skb) - skb->data;
+}
/*
* CPUs often take a performance hit when accessing unaligned memory
static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
{
+#ifndef NET_SKBUFF_DATA_USES_OFFSET
/*
* Shift between the two data areas in bytes
*/
unsigned long offset = new->data - old->data;
-
+#endif
new->sk = NULL;
new->dev = old->dev;
new->priority = old->priority;
#ifdef CONFIG_INET
new->sp = secpath_get(old->sp);
#endif
- new->transport_header = old->transport_header + offset;
- new->network_header = old->network_header + offset;
- new->mac_header = old->mac_header + offset;
+ new->transport_header = old->transport_header;
+ new->network_header = old->network_header;
+ new->mac_header = old->mac_header;
+#ifndef NET_SKBUFF_DATA_USES_OFFSET
+ /* {transport,network,mac}_header are relative to skb->head */
+ new->transport_header += offset;
+ new->network_header += offset;
+ new->mac_header += offset;
+#endif
memcpy(new->cb, old->cb, sizeof(old->cb));
new->local_df = old->local_df;
new->fclone = SKB_FCLONE_UNAVAILABLE;
skb->end = data + size;
skb->data += off;
skb->tail += off;
+#ifndef NET_SKBUFF_DATA_USES_OFFSET
+ /* {transport,network,mac}_header are relative to skb->head */
skb->transport_header += off;
skb->network_header += off;
skb->mac_header += off;
+#endif
skb->cloned = 0;
skb->nohdr = 0;
atomic_set(&skb_shinfo(skb)->dataref, 1);
struct sctp_association *asoc = NULL;
struct sctp_transport *transport;
struct inet_sock *inet;
- char *saveip, *savesctp;
+ sk_buff_data_t saveip, savesctp;
int err;
if (skb->len < ihlen + 8) {
skb_reset_network_header(skb);
skb_set_transport_header(skb, ihlen);
sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport);
- /* Put back, the original pointers. */
+ /* Put back, the original values. */
skb->network_header = saveip;
skb->transport_header = savesctp;
if (!sk) {