[SK_BUFF]: Introduce skb_network_header()
For the places where we need a pointer to the network header, it is still legal
to touch skb->nh.raw directly if just adding to, subtracting from or setting it
to another layer header.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 1163c4f..8a56d89 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -374,7 +374,8 @@
{
unsigned char *raw = (u8 *) (skb->nh.ipv6h + 1);
u32 pkt_len;
- int off = raw - skb->nh.raw;
+ const unsigned char *nh = skb_network_header(skb);
+ int off = raw - nh;
int len = (raw[1] + 1) << 3;
if ((raw + len) - skb->data > skb_headlen(skb))
@@ -384,9 +385,9 @@
len -= 2;
while (len > 0) {
- int optlen = skb->nh.raw[off + 1] + 2;
+ int optlen = nh[off + 1] + 2;
- switch (skb->nh.raw[off]) {
+ switch (nh[off]) {
case IPV6_TLV_PAD0:
optlen = 1;
break;
@@ -395,9 +396,9 @@
break;
case IPV6_TLV_JUMBO:
- if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2)
+ if (nh[off + 1] != 4 || (off & 3) != 2)
goto bad;
- pkt_len = ntohl(*(__be32 *) (skb->nh.raw + off + 2));
+ pkt_len = ntohl(*(__be32 *) (nh + off + 2));
if (pkt_len <= IPV6_MAXPLEN ||
skb->nh.ipv6h->payload_len)
goto bad;
@@ -406,6 +407,7 @@
if (pskb_trim_rcsum(skb,
pkt_len + sizeof(struct ipv6hdr)))
goto bad;
+ nh = skb_network_header(skb);
break;
default:
if (optlen > len)
diff --git a/net/core/dev.c b/net/core/dev.c
index 1b07582..54ffe9d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1068,8 +1068,8 @@
*/
skb_reset_mac_header(skb2);
- if (skb2->nh.raw < skb2->data ||
- skb2->nh.raw > skb2->tail) {
+ if (skb_network_header(skb2) < skb2->data ||
+ skb_network_header(skb2) > skb2->tail) {
if (net_ratelimit())
printk(KERN_CRIT "protocol %04x is "
"buggy, dev %s\n",
@@ -1207,7 +1207,7 @@
BUG_ON(skb_shinfo(skb)->frag_list);
skb_reset_mac_header(skb);
- skb->mac_len = skb->nh.raw - skb->data;
+ skb->mac_len = skb->nh.raw - skb->mac.raw;
__skb_pull(skb, skb->mac_len);
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
@@ -1224,7 +1224,8 @@
segs = ERR_PTR(err);
if (err || skb_gso_ok(skb, features))
break;
- __skb_push(skb, skb->data - skb->nh.raw);
+ __skb_push(skb, (skb->data -
+ skb_network_header(skb)));
}
segs = ptype->gso_segment(skb, features);
break;
diff --git a/net/core/filter.c b/net/core/filter.c
index 1cc128d..d2358a5 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -42,7 +42,7 @@
u8 *ptr = NULL;
if (k >= SKF_NET_OFF)
- ptr = skb->nh.raw + k - SKF_NET_OFF;
+ ptr = skb_network_header(skb) + k - SKF_NET_OFF;
else if (k >= SKF_LL_OFF)
ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 7f51e8d..627d0c3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -261,8 +261,8 @@
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk,
- (struct ipv6_rt_hdr *)(pktopts->nh.raw +
- rxopt->srcrt));
+ (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
+ rxopt->srcrt));
}
if (opt != NULL && opt->srcrt != NULL) {
@@ -573,8 +573,8 @@
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk,
- (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
- rxopt->srcrt));
+ (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
+ rxopt->srcrt));
}
if (dst == NULL) {
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 34079b7..32a7db3 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -386,7 +386,7 @@
__le16 tmp;
/* Add back headers */
- skb_push(skb, skb->data - skb->nh.raw);
+ skb_push(skb, skb->data - skb_network_header(skb));
if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
return NET_RX_DROP;
@@ -425,7 +425,7 @@
unsigned char tmp[ETH_ALEN];
/* Add back all headers */
- skb_push(skb, skb->data - skb->nh.raw);
+ skb_push(skb, skb->data - skb_network_header(skb));
if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
return NET_RX_DROP;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 6e5575b..ab552a6 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1184,7 +1184,7 @@
iph->id = htons(id++);
iph->tot_len = htons(skb->len - skb->mac_len);
iph->check = 0;
- iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+ iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
} while ((skb = skb->next));
out:
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 7194eb4..95ddbbd 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -154,7 +154,7 @@
ah = (struct ip_auth_hdr*)skb->data;
iph = skb->nh.iph;
- ihl = skb->data - skb->nh.raw;
+ ihl = skb->data - skb_network_header(skb);
memcpy(work_buf, iph, ihl);
iph->ttl = 0;
@@ -181,7 +181,8 @@
}
}
((struct iphdr*)work_buf)->protocol = ah->nexthdr;
- skb->h.raw = memcpy(skb->nh.raw += ah_hlen, work_buf, ihl);
+ skb->nh.raw += ah_hlen;
+ skb->h.raw = memcpy(skb_network_header(skb), work_buf, ihl);
__skb_pull(skb, ah_hlen + ihl);
return 0;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 3104112..222d21e 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -57,9 +57,10 @@
*(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
pskb_put(skb, trailer, clen - skb->len);
- __skb_push(skb, skb->data - skb->nh.raw);
+ __skb_push(skb, skb->data - skb_network_header(skb));
top_iph = skb->nh.iph;
- esph = (struct ip_esp_hdr *)(skb->nh.raw + top_iph->ihl*4);
+ esph = (struct ip_esp_hdr *)(skb_network_header(skb) +
+ top_iph->ihl * 4);
top_iph->tot_len = htons(skb->len + alen);
*(u8*)(trailer->tail - 1) = top_iph->protocol;
@@ -222,7 +223,7 @@
if (x->encap) {
struct xfrm_encap_tmpl *encap = x->encap;
- struct udphdr *uh = (void *)(skb->nh.raw + ihl);
+ struct udphdr *uh = (void *)(skb_network_header(skb) + ihl);
/*
* 1) if the NAT-T peer's IP or port changed then
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 4b7a0d9..ff124d4 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -484,7 +484,7 @@
u8 _inner_type, *itp;
itp = skb_header_pointer(skb_in,
- skb_in->nh.raw +
+ skb_network_header(skb_in) +
(iph->ihl << 2) +
offsetof(struct icmphdr,
type) -
@@ -536,7 +536,7 @@
icmp_param.data.icmph.un.gateway = info;
icmp_param.data.icmph.checksum = 0;
icmp_param.skb = skb_in;
- icmp_param.offset = skb_in->nh.raw - skb_in->data;
+ icmp_param.offset = skb_network_offset(skb_in);
icmp_out_count(icmp_param.data.icmph.type);
inet_sk(icmp_socket->sk)->tos = tos;
ipc.addr = iph->saddr;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 3dfd758..268a6c7 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -658,7 +658,7 @@
}
skb_shinfo(head)->frag_list = head->next;
- skb_push(head, head->data - head->nh.raw);
+ skb_push(head, head->data - skb_network_header(head));
atomic_sub(head->truesize, &ip_frag_mem);
for (fp=head->next; fp; fp = fp->next) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f906a80..f7e9db6 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -40,7 +40,7 @@
void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
__be32 daddr, struct rtable *rt, int is_frag)
{
- unsigned char * iph = skb->nh.raw;
+ unsigned char *iph = skb_network_header(skb);
memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options));
memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);
@@ -104,7 +104,7 @@
return 0;
}
- sptr = skb->nh.raw;
+ sptr = skb_network_header(skb);
dptr = dopt->__data;
if (skb->dst)
@@ -217,7 +217,7 @@
void ip_options_fragment(struct sk_buff * skb)
{
- unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr);
+ unsigned char *optptr = skb_network_header(skb) + sizeof(struct iphdr);
struct ip_options * opt = &(IPCB(skb)->opt);
int l = opt->optlen;
int optlen;
@@ -264,7 +264,7 @@
if (!opt) {
opt = &(IPCB(skb)->opt);
- iph = skb->nh.raw;
+ iph = skb_network_header(skb);
opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
optptr = iph + sizeof(struct iphdr);
opt->is_data = 0;
@@ -563,7 +563,7 @@
struct ip_options * opt = &(IPCB(skb)->opt);
unsigned char * optptr;
struct rtable *rt = (struct rtable*)skb->dst;
- unsigned char *raw = skb->nh.raw;
+ unsigned char *raw = skb_network_header(skb);
if (opt->rr_needaddr) {
optptr = (unsigned char *)raw + opt->rr;
@@ -609,7 +609,7 @@
int srrspace, srrptr;
__be32 nexthop;
struct iphdr *iph = skb->nh.iph;
- unsigned char * optptr = skb->nh.raw + opt->srr;
+ unsigned char *optptr = skb_network_header(skb) + opt->srr;
struct rtable *rt = (struct rtable*)skb->dst;
struct rtable *rt2;
int err;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 669f5d9..eae2284 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -503,7 +503,7 @@
frag->h.raw = frag->data;
__skb_push(frag, hlen);
skb_reset_network_header(frag);
- memcpy(frag->nh.raw, iph, hlen);
+ memcpy(skb_network_header(frag), iph, hlen);
iph = frag->nh.iph;
iph->tot_len = htons(frag->len);
ip_copy_metadata(frag, skb);
@@ -607,7 +607,7 @@
* Copy the packet header into the new buffer.
*/
- memcpy(skb2->nh.raw, skb->data, hlen);
+ memcpy(skb_network_header(skb2), skb->data, hlen);
/*
* Copy a block of the IP datagram.
@@ -1198,7 +1198,7 @@
tail_skb = &(skb_shinfo(skb)->frag_list);
/* move skb->data to ip header from ext header */
- if (skb->data < skb->nh.raw)
+ if (skb->data < skb_network_header(skb))
__skb_pull(skb, skb_network_offset(skb));
while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
__skb_pull(tmp_skb, skb->h.raw - skb->nh.raw);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index f8ab654..70888e1 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -273,7 +273,8 @@
serr->ee.ee_pad = 0;
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
- serr->addr_offset = (u8*)&(((struct iphdr*)(skb->h.icmph+1))->daddr) - skb->nh.raw;
+ serr->addr_offset = (u8 *)&(((struct iphdr *)(skb->h.icmph + 1))->daddr) -
+ skb_network_header(skb);
serr->port = port;
skb->h.raw = payload;
@@ -309,7 +310,7 @@
serr->ee.ee_pad = 0;
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
- serr->addr_offset = (u8*)&iph->daddr - skb->nh.raw;
+ serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
serr->port = port;
skb->h.raw = skb->tail;
@@ -355,7 +356,8 @@
sin = (struct sockaddr_in *)msg->msg_name;
if (sin) {
sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = *(__be32*)(skb->nh.raw + serr->addr_offset);
+ sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
+ serr->addr_offset);
sin->sin_port = serr->port;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 51528d3..4a8d99b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -563,7 +563,7 @@
*/
msg = (struct igmpmsg*)skb_push(skb, sizeof(struct iphdr));
skb->nh.raw = skb->h.raw = (u8*)msg;
- memcpy(msg, pkt->nh.raw, sizeof(struct iphdr));
+ memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr));
msg->im_msgtype = IGMPMSG_WHOLEPKT;
msg->im_mbz = 0;
msg->im_vif = reg_vif_num;
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 22e104c..f29d3a2 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -338,7 +338,7 @@
if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
return 0;
- th = (struct tcphdr *)((*pskb)->nh.raw + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
/*
* Remember seq number in case this pkt gets resized
@@ -413,7 +413,7 @@
if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
return 0;
- th = (struct tcphdr *)((*pskb)->nh.raw + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
/*
* Remember seq number in case this pkt gets resized
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 858686d..5d54dd2 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -559,7 +559,8 @@
{
struct iphdr *iph = skb->nh.iph;
unsigned int icmp_offset = iph->ihl*4;
- struct icmphdr *icmph = (struct icmphdr *)(skb->nh.raw + icmp_offset);
+ struct icmphdr *icmph = (struct icmphdr *)(skb_network_header(skb) +
+ icmp_offset);
struct iphdr *ciph = (struct iphdr *)(icmph + 1);
if (inout) {
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 709db4d..af1c859 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -31,7 +31,7 @@
}
arp = (*pskb)->nh.arph;
- arpptr = (*pskb)->nh.raw + sizeof(*arp);
+ arpptr = skb_network_header(*pskb) + sizeof(*arp);
pln = arp->ar_pln;
hln = arp->ar_hln;
/* We assume that pln and hln were checked in the match */
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8f3e92d..7cebbff 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -105,7 +105,7 @@
return -NF_DROP;
}
- *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
+ *dataoff = skb_network_offset(*pskb) + (*pskb)->nh.iph->ihl * 4;
*protonum = (*pskb)->nh.iph->protocol;
return NF_ACCEPT;
@@ -151,10 +151,9 @@
if (!help || !help->helper)
return NF_ACCEPT;
- return help->helper->help(pskb,
- (*pskb)->nh.raw - (*pskb)->data
- + (*pskb)->nh.iph->ihl*4,
- ct, ctinfo);
+ return help->helper->help(pskb, (skb_network_offset(*pskb) +
+ (*pskb)->nh.iph->ihl * 4),
+ ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 67e5e3c..a3d02fd 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -256,7 +256,7 @@
}
nf_reset(skb);
- skb_push(skb, skb->data - skb->nh.raw);
+ skb_push(skb, skb->data - skb_network_header(skb));
raw_rcv_skb(sk, skb);
return 0;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f5e019c..0019083 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3634,7 +3634,7 @@
return;
skb_set_mac_header(nskb, skb_mac_header(skb) - skb->head);
- nskb->nh.raw = nskb->data + (skb->nh.raw - skb->head);
+ nskb->nh.raw = nskb->data + (skb_network_header(skb) - skb->head);
nskb->h.raw = nskb->data + (skb->h.raw - skb->head);
skb_reserve(nskb, header);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 78e80de..d89969c 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -146,7 +146,7 @@
return 0;
} else {
#ifdef CONFIG_NETFILTER
- __skb_push(skb, skb->data - skb->nh.raw);
+ __skb_push(skb, skb->data - skb_network_header(skb));
skb->nh.iph->tot_len = htons(skb->len);
ip_send_check(skb->nh.iph);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index eaaf356..505fca0 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -98,7 +98,7 @@
}
skb->nh.raw = skb->data + (phlen - sizeof(*iph));
- memmove(skb->nh.raw, iph, sizeof(*iph));
+ memmove(skb_network_header(skb), iph, sizeof(*iph));
skb->h.raw = skb->data + (phlen + optlen);
skb->data = skb->h.raw;
@@ -112,7 +112,7 @@
else
iph->protocol = protocol;
iph->check = 0;
- iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+ iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
err = 0;
out:
return err;
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c
index a820dde..b198087 100644
--- a/net/ipv4/xfrm4_mode_transport.c
+++ b/net/ipv4/xfrm4_mode_transport.c
@@ -34,7 +34,7 @@
skb_push(skb, x->props.header_len);
skb_reset_network_header(skb);
- memmove(skb->nh.raw, iph, ihl);
+ memmove(skb_network_header(skb), iph, ihl);
return 0;
}
@@ -51,7 +51,7 @@
int ihl = skb->data - skb->h.raw;
if (skb->h.raw != skb->nh.raw) {
- memmove(skb->h.raw, skb->nh.raw, ihl);
+ memmove(skb->h.raw, skb_network_header(skb), ihl);
skb->nh.raw = skb->h.raw;
}
skb->nh.iph->tot_len = htons(skb->len + ihl);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 98a833ce..fbb1d3d 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -210,7 +210,7 @@
_decode_session4(struct sk_buff *skb, struct flowi *fl)
{
struct iphdr *iph = skb->nh.iph;
- u8 *xprth = skb->nh.raw + iph->ihl*4;
+ u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
memset(fl, 0, sizeof(struct flowi));
if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2ff0704..7b917f8 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -693,7 +693,8 @@
if (np->rxopt.all) {
if ((opt->hop && (np->rxopt.bits.hopopts ||
np->rxopt.bits.ohopopts)) ||
- ((IPV6_FLOWINFO_MASK & *(__be32*)skb->nh.raw) &&
+ ((IPV6_FLOWINFO_MASK &
+ *(__be32 *)skb_network_header(skb)) &&
np->rxopt.bits.rxflow) ||
(opt->srcrt && (np->rxopt.bits.srcrt ||
np->rxopt.bits.osrcrt)) ||
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index dc68b72..1c91438 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -238,8 +238,8 @@
top_iph = (struct ipv6hdr *)skb->data;
top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
- nexthdr = *skb->nh.raw;
- *skb->nh.raw = IPPROTO_AH;
+ nexthdr = *skb_network_header(skb);
+ *skb_network_header(skb) = IPPROTO_AH;
/* When there are no extension headers, we only need to save the first
* 8 bytes of the base IP header.
@@ -341,7 +341,7 @@
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out;
- hdr_len = skb->data - skb->nh.raw;
+ hdr_len = skb->data - skb_network_header(skb);
ah = (struct ipv6_auth_hdr*)skb->data;
ahp = x->data;
nexthdr = ah->nexthdr;
@@ -354,7 +354,7 @@
if (!pskb_may_pull(skb, ah_hlen))
goto out;
- tmp_hdr = kmemdup(skb->nh.raw, hdr_len, GFP_ATOMIC);
+ tmp_hdr = kmemdup(skb_network_header(skb), hdr_len, GFP_ATOMIC);
if (!tmp_hdr)
goto out;
if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
@@ -382,7 +382,9 @@
}
}
- skb->h.raw = memcpy(skb->nh.raw += ah_hlen, tmp_hdr, hdr_len);
+ skb->nh.raw += ah_hlen;
+ memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
+ skb->h.raw = skb->nh.raw;
__skb_pull(skb, ah_hlen + hdr_len);
kfree(tmp_hdr);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 31a20f1..7a86db6 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -227,7 +227,8 @@
serr->ee.ee_pad = 0;
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
- serr->addr_offset = (u8*)&(((struct ipv6hdr*)(icmph+1))->daddr) - skb->nh.raw;
+ serr->addr_offset = (u8 *)&(((struct ipv6hdr *)(icmph + 1))->daddr) -
+ skb_network_header(skb);
serr->port = port;
skb->h.raw = payload;
@@ -264,7 +265,7 @@
serr->ee.ee_pad = 0;
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
- serr->addr_offset = (u8*)&iph->daddr - skb->nh.raw;
+ serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
serr->port = fl->fl_ip_dport;
skb->h.raw = skb->tail;
@@ -310,21 +311,24 @@
sin = (struct sockaddr_in6 *)msg->msg_name;
if (sin) {
+ const unsigned char *nh = skb_network_header(skb);
sin->sin6_family = AF_INET6;
sin->sin6_flowinfo = 0;
sin->sin6_port = serr->port;
sin->sin6_scope_id = 0;
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
ipv6_addr_copy(&sin->sin6_addr,
- (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
+ (struct in6_addr *)(nh + serr->addr_offset));
if (np->sndflow)
- sin->sin6_flowinfo = *(__be32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
+ sin->sin6_flowinfo =
+ (*(__be32 *)(nh + serr->addr_offset - 24) &
+ IPV6_FLOWINFO_MASK);
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
ipv6_addr_set(&sin->sin6_addr, 0, 0,
htonl(0xffff),
- *(__be32*)(skb->nh.raw + serr->addr_offset));
+ *(__be32 *)(nh + serr->addr_offset));
}
}
@@ -382,6 +386,7 @@
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct inet6_skb_parm *opt = IP6CB(skb);
+ unsigned char *nh = skb_network_header(skb);
if (np->rxopt.bits.rxinfo) {
struct in6_pktinfo src_info;
@@ -401,14 +406,14 @@
put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
}
- if (np->rxopt.bits.rxflow && (*(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
- __be32 flowinfo = *(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
+ if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
+ __be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
}
/* HbH is allowed only once */
if (np->rxopt.bits.hopopts && opt->hop) {
- u8 *ptr = skb->nh.raw + opt->hop;
+ u8 *ptr = nh + opt->hop;
put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
}
@@ -428,7 +433,7 @@
while (off <= opt->lastopt) {
unsigned len;
- u8 *ptr = skb->nh.raw + off;
+ u8 *ptr = nh + off;
switch(nexthdr) {
case IPPROTO_DSTOPTS:
@@ -470,19 +475,19 @@
put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
}
if (np->rxopt.bits.ohopopts && opt->hop) {
- u8 *ptr = skb->nh.raw + opt->hop;
+ u8 *ptr = nh + opt->hop;
put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
}
if (np->rxopt.bits.odstopts && opt->dst0) {
- u8 *ptr = skb->nh.raw + opt->dst0;
+ u8 *ptr = nh + opt->dst0;
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
if (np->rxopt.bits.osrcrt && opt->srcrt) {
- struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
+ struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
}
if (np->rxopt.bits.odstopts && opt->dst1) {
- u8 *ptr = skb->nh.raw + opt->dst1;
+ u8 *ptr = nh + opt->dst1;
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
return 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 363e63f..6e6b57a 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -92,8 +92,8 @@
top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len);
esph = (struct ipv6_esp_hdr *)skb->h.raw;
top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
- *(u8*)(trailer->tail - 1) = *skb->nh.raw;
- *skb->nh.raw = IPPROTO_ESP;
+ *(u8 *)(trailer->tail - 1) = *skb_network_header(skb);
+ *skb_network_header(skb) = IPPROTO_ESP;
esph->spi = x->id.spi;
esph->seq_no = htonl(++x->replay.oseq);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index fce5abd..9ebf120 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -50,13 +50,14 @@
int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
{
- int packet_len = skb->tail - skb->nh.raw;
+ const unsigned char *nh = skb_network_header(skb);
+ int packet_len = skb->tail - nh;
struct ipv6_opt_hdr *hdr;
int len;
if (offset + 2 > packet_len)
goto bad;
- hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ hdr = (struct ipv6_opt_hdr *)(nh + offset);
len = ((hdr->hdrlen + 1) << 3);
if (offset + len > packet_len)
@@ -66,7 +67,7 @@
len -= 2;
while (len > 0) {
- int opttype = skb->nh.raw[offset];
+ int opttype = nh[offset];
int optlen;
if (opttype == type)
@@ -77,7 +78,7 @@
optlen = 1;
break;
default:
- optlen = skb->nh.raw[offset + 1] + 2;
+ optlen = nh[offset + 1] + 2;
if (optlen > len)
goto bad;
break;
@@ -113,7 +114,7 @@
{
struct sk_buff *skb = *skbp;
- switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
+ switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
case 0: /* ignore */
return 1;
@@ -141,6 +142,7 @@
{
struct sk_buff *skb = *skbp;
struct tlvtype_proc *curr;
+ const unsigned char *nh = skb_network_header(skb);
int off = skb->h.raw - skb->nh.raw;
int len = ((skb->h.raw[1]+1)<<3);
@@ -151,9 +153,9 @@
len -= 2;
while (len > 0) {
- int optlen = skb->nh.raw[off+1]+2;
+ int optlen = nh[off + 1] + 2;
- switch (skb->nh.raw[off]) {
+ switch (nh[off]) {
case IPV6_TLV_PAD0:
optlen = 1;
break;
@@ -165,7 +167,7 @@
if (optlen > len)
goto bad;
for (curr=procs; curr->type >= 0; curr++) {
- if (curr->type == skb->nh.raw[off]) {
+ if (curr->type == nh[off]) {
/* type specific length/alignment
checks will be performed in the
func(). */
@@ -211,7 +213,7 @@
opt->dsthao = opt->dst1;
opt->dst1 = 0;
- hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
+ hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
if (hao->length != 16) {
LIMIT_NETDEBUG(
@@ -244,8 +246,9 @@
/* update all variable using below by copied skbuff */
*skbp = skb = skb2;
- hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
- ipv6h = (struct ipv6hdr *)skb2->nh.raw;
+ hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
+ optoff);
+ ipv6h = skb2->nh.ipv6h;
}
if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -406,7 +409,8 @@
default:
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+ (&hdr->type) - skb_network_header(skb));
return -1;
}
@@ -443,7 +447,7 @@
skb->h.raw += (hdr->hdrlen + 1) << 3;
opt->dst0 = opt->dst1;
opt->dst1 = 0;
- opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
+ opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
return 1;
}
@@ -452,7 +456,9 @@
if (hdr->hdrlen & 0x01) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+ ((&hdr->hdrlen) -
+ skb_network_header(skb)));
return -1;
}
break;
@@ -479,7 +485,9 @@
if (hdr->segments_left > n) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+ ((&hdr->segments_left) -
+ skb_network_header(skb)));
return -1;
}
@@ -547,7 +555,7 @@
dst_release(xchg(&skb->dst, NULL));
ip6_route_input(skb);
if (skb->dst->error) {
- skb_push(skb, skb->data - skb->nh.raw);
+ skb_push(skb, skb->data - skb_network_header(skb));
dst_input(skb);
return -1;
}
@@ -565,7 +573,7 @@
goto looped_back;
}
- skb_push(skb, skb->data - skb->nh.raw);
+ skb_push(skb, skb->data - skb_network_header(skb));
dst_input(skb);
return -1;
}
@@ -656,13 +664,14 @@
static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
{
struct sk_buff *skb = *skbp;
+ const unsigned char *nh = skb_network_header(skb);
- if (skb->nh.raw[optoff+1] == 2) {
+ if (nh[optoff + 1] == 2) {
IP6CB(skb)->ra = optoff;
return 1;
}
LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
- skb->nh.raw[optoff+1]);
+ nh[optoff + 1]);
kfree_skb(skb);
return 0;
}
@@ -672,17 +681,18 @@
static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
{
struct sk_buff *skb = *skbp;
+ const unsigned char *nh = skb_network_header(skb);
u32 pkt_len;
- if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
+ if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
- skb->nh.raw[optoff+1]);
+ nh[optoff+1]);
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
goto drop;
}
- pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
+ pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
if (pkt_len <= IPV6_MAXPLEN) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
@@ -727,7 +737,7 @@
struct inet6_skb_parm *opt = IP6CB(skb);
/*
- * skb->nh.raw is equal to skb->data, and
+ * skb_network_header(skb) is equal to skb->data, and
* skb->h.raw - skb->nh.raw is always equal to
* sizeof(struct ipv6hdr) by definition of
* hop-by-hop options.
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index aa4a0a5..e5293b3 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -284,7 +284,8 @@
if (opt->dsthao) {
off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
if (likely(off >= 0)) {
- hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off);
+ hao = (struct ipv6_destopt_hao *)
+ (skb_network_header(skb) + off);
ipv6_addr_copy(&tmp, &iph->saddr);
ipv6_addr_copy(&iph->saddr, &hao->addr);
ipv6_addr_copy(&hao->addr, &tmp);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 61e7a6c..aecc74d 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -163,7 +163,7 @@
if (!pskb_pull(skb, skb->h.raw - skb->data))
goto discard;
nhoff = IP6CB(skb)->nhoff;
- nexthdr = skb->nh.raw[nhoff];
+ nexthdr = skb_network_header(skb)[nhoff];
raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
@@ -181,7 +181,7 @@
indefinitely. */
nf_reset(skb);
- skb_postpull_rcsum(skb, skb->nh.raw,
+ skb_postpull_rcsum(skb, skb_network_header(skb),
skb->h.raw - skb->nh.raw);
hdr = skb->nh.ipv6h;
if (ipv6_addr_is_multicast(&hdr->daddr) &&
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 47d0021..f1dfcc3 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -323,10 +323,11 @@
if (nexthdr == IPPROTO_ICMPV6) {
struct icmp6hdr *icmp6;
- if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data))
+ if (!pskb_may_pull(skb, (skb_network_header(skb) +
+ offset + 1 - skb->data)))
return 0;
- icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset);
+ icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
switch (icmp6->icmp6_type) {
case NDISC_ROUTER_SOLICITATION:
@@ -392,7 +393,7 @@
* that different fragments will go along one path. --ANK
*/
if (opt->ra) {
- u8 *ptr = skb->nh.raw + opt->ra;
+ u8 *ptr = skb_network_header(skb) + opt->ra;
if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
return 0;
}
@@ -527,7 +528,7 @@
{
u16 offset = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
- unsigned int packet_len = skb->tail - skb->nh.raw;
+ unsigned int packet_len = skb->tail - skb_network_header(skb);
int found_rhdr = 0;
*nexthdr = &skb->nh.ipv6h->nexthdr;
@@ -554,7 +555,8 @@
offset += ipv6_optlen(exthdr);
*nexthdr = &exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
+ offset);
}
return offset;
@@ -620,7 +622,7 @@
/* BUILD HEADER */
*prevhdr = NEXTHDR_FRAGMENT;
- tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC);
+ tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
if (!tmp_hdr) {
IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
return -ENOMEM;
@@ -630,7 +632,7 @@
fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
__skb_push(skb, hlen);
skb_reset_network_header(skb);
- memcpy(skb->nh.raw, tmp_hdr, hlen);
+ memcpy(skb_network_header(skb), tmp_hdr, hlen);
ipv6_select_ident(skb, fh);
fh->nexthdr = nexthdr;
@@ -654,7 +656,8 @@
fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
__skb_push(frag, hlen);
skb_reset_network_header(frag);
- memcpy(frag->nh.raw, tmp_hdr, hlen);
+ memcpy(skb_network_header(frag), tmp_hdr,
+ hlen);
offset += skb->len - hlen - sizeof(struct frag_hdr);
fh->nexthdr = nexthdr;
fh->reserved = 0;
@@ -753,7 +756,7 @@
/*
* Copy the packet header into the new buffer.
*/
- memcpy(frag->nh.raw, skb->data, hlen);
+ memcpy(skb_network_header(frag), skb->data, hlen);
/*
* Build fragment header.
@@ -1329,7 +1332,7 @@
tail_skb = &(skb_shinfo(skb)->frag_list);
/* move skb->data to ip header from ext header */
- if (skb->data < skb->nh.raw)
+ if (skb->data < skb_network_header(skb))
__skb_pull(skb, skb_network_offset(skb));
while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
__skb_pull(tmp_skb, skb->h.raw - skb->nh.raw);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a1e4f39..aafbdfa 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -995,9 +995,10 @@
!ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h))
return -1;
- if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
+ offset = parse_tlv_tnl_enc_lim(skb, skb_network_header(skb));
+ if (offset > 0) {
struct ipv6_tlv_tnl_enc_lim *tel;
- tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
+ tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
if (tel->encap_limit == 0) {
icmpv6_send(skb, ICMPV6_PARAMPROB,
ICMPV6_HDR_FIELD, offset + 2, skb->dev);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 5724ba9..3e71d16 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -166,10 +166,10 @@
top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
ipch = (struct ipv6_comp_hdr *)start;
- ipch->nexthdr = *skb->nh.raw;
+ ipch->nexthdr = *skb_network_header(skb);
ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi));
- *skb->nh.raw = IPPROTO_COMP;
+ *skb_network_header(skb) = IPPROTO_COMP;
out_ok:
return 0;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 0afcabd..bb40335 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -99,14 +99,16 @@
if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
- mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw);
+ mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
+ skb_network_header(skb)));
return -1;
}
if (mh->ip6mh_proto != IPPROTO_NONE) {
LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
mh->ip6mh_proto);
- mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw);
+ mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
+ skb_network_header(skb)));
return -1;
}
@@ -152,8 +154,8 @@
iph = (struct ipv6hdr *)skb->data;
iph->payload_len = htons(skb->len - sizeof(*iph));
- nexthdr = *skb->nh.raw;
- *skb->nh.raw = IPPROTO_DSTOPTS;
+ nexthdr = *skb_network_header(skb);
+ *skb_network_header(skb) = IPPROTO_DSTOPTS;
dstopt = (struct ipv6_destopt_hdr *)skb->h.raw;
dstopt->nexthdr = nexthdr;
@@ -215,7 +217,8 @@
if (likely(opt->dsthao)) {
offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
if (likely(offset >= 0))
- hao = (struct ipv6_destopt_hao *)(skb->nh.raw + offset);
+ hao = (struct ipv6_destopt_hao *)
+ (skb_network_header(skb) + offset);
}
skb_get_timestamp(skb, &stamp);
@@ -254,7 +257,8 @@
{
u16 offset = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
- unsigned int packet_len = skb->tail - skb->nh.raw;
+ const unsigned char *nh = skb_network_header(skb);
+ unsigned int packet_len = skb->tail - nh;
int found_rhdr = 0;
*nexthdr = &skb->nh.ipv6h->nexthdr;
@@ -288,7 +292,7 @@
offset += ipv6_optlen(exthdr);
*nexthdr = &exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ exthdr = (struct ipv6_opt_hdr *)(nh + offset);
}
return offset;
@@ -361,8 +365,8 @@
iph = (struct ipv6hdr *)skb->data;
iph->payload_len = htons(skb->len - sizeof(*iph));
- nexthdr = *skb->nh.raw;
- *skb->nh.raw = IPPROTO_ROUTING;
+ nexthdr = *skb_network_header(skb);
+ *skb_network_header(skb) = IPPROTO_ROUTING;
rt2 = (struct rt2_hdr *)skb->h.raw;
rt2->rt_hdr.nexthdr = nexthdr;
@@ -384,7 +388,8 @@
{
u16 offset = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
- unsigned int packet_len = skb->tail - skb->nh.raw;
+ const unsigned char *nh = skb_network_header(skb);
+ unsigned int packet_len = skb->tail - nh;
int found_rhdr = 0;
*nexthdr = &skb->nh.ipv6h->nexthdr;
@@ -397,7 +402,7 @@
case NEXTHDR_ROUTING:
if (offset + 3 <= packet_len) {
struct ipv6_rt_hdr *rt;
- rt = (struct ipv6_rt_hdr *)(skb->nh.raw + offset);
+ rt = (struct ipv6_rt_hdr *)(nh + offset);
if (rt->type != 0)
return offset;
}
@@ -417,7 +422,7 @@
offset += ipv6_optlen(exthdr);
*nexthdr = &exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ exthdr = (struct ipv6_opt_hdr *)(nh + offset);
}
return offset;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c311b9a..bc1d095 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -408,11 +408,12 @@
return -1;
}
- if (skb->ip_summed == CHECKSUM_COMPLETE)
+ if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ const unsigned char *nh = skb_network_header(skb);
skb->csum = csum_sub(skb->csum,
- csum_partial(skb->nh.raw,
- (u8*)(fhdr + 1) - skb->nh.raw,
+ csum_partial(nh, (u8 *)(fhdr + 1) - nh,
0));
+ }
/* Is this the final fragment? */
if (!(fhdr->frag_off & htons(IP6_MF))) {
@@ -583,7 +584,9 @@
BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
/* Unfragmented part is taken from the first segment. */
- payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
+ payload_len = ((head->data - skb_network_header(head)) -
+ sizeof(struct ipv6hdr) + fq->len -
+ sizeof(struct frag_hdr));
if (payload_len > IPV6_MAXPLEN) {
DEBUGP("payload len is too large.\n");
goto out_oversize;
@@ -624,7 +627,7 @@
/* We have to remove fragment header from datagram and to relocate
* header in order to calculate ICV correctly. */
- head->nh.raw[fq->nhoffset] = head->h.raw[0];
+ skb_network_header(head)[fq->nhoffset] = head->h.raw[0];
memmove(head->head + sizeof(struct frag_hdr), head->head,
(head->data - head->head) - sizeof(struct frag_hdr));
head->mac.raw += sizeof(struct frag_hdr);
@@ -632,7 +635,7 @@
skb_shinfo(head)->frag_list = head->next;
head->h.raw = head->data;
- skb_push(head, head->data - head->nh.raw);
+ skb_push(head, head->data - skb_network_header(head));
atomic_sub(head->truesize, &nf_ct_frag6_mem);
for (fp=head->next; fp; fp = fp->next) {
@@ -653,7 +656,9 @@
/* Yes, and fold redundant checksum back. 8) */
if (head->ip_summed == CHECKSUM_COMPLETE)
- head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
+ head->csum = csum_partial(skb_network_header(head),
+ head->h.raw - head->nh.raw,
+ head->csum);
fq->fragments = NULL;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 5f26645..9b2bcde 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -361,7 +361,7 @@
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (skb->ip_summed == CHECKSUM_COMPLETE) {
- skb_postpull_rcsum(skb, skb->nh.raw,
+ skb_postpull_rcsum(skb, skb_network_header(skb),
skb->h.raw - skb->nh.raw);
if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
&skb->nh.ipv6h->daddr,
@@ -488,7 +488,8 @@
goto out;
offset = rp->offset;
- total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data);
+ total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) -
+ skb->data);
if (offset >= total_len - 1) {
err = -EINVAL;
ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 1dde449..f85e49a 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -436,13 +436,18 @@
if ((unsigned int)end > IPV6_MAXPLEN) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+ ((u8 *)&fhdr->frag_off -
+ skb_network_header(skb)));
return;
}
- if (skb->ip_summed == CHECKSUM_COMPLETE)
+ if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ const unsigned char *nh = skb_network_header(skb);
skb->csum = csum_sub(skb->csum,
- csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0));
+ csum_partial(nh, (u8 *)(fhdr + 1) - nh,
+ 0));
+ }
/* Is this the final fragment? */
if (!(fhdr->frag_off & htons(IP6_MF))) {
@@ -605,7 +610,9 @@
BUG_TRAP(FRAG6_CB(head)->offset == 0);
/* Unfragmented part is taken from the first segment. */
- payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
+ payload_len = ((head->data - skb_network_header(head)) -
+ sizeof(struct ipv6hdr) + fq->len -
+ sizeof(struct frag_hdr));
if (payload_len > IPV6_MAXPLEN)
goto out_oversize;
@@ -639,7 +646,7 @@
/* We have to remove fragment header from datagram and to relocate
* header in order to calculate ICV correctly. */
nhoff = fq->nhoffset;
- head->nh.raw[nhoff] = head->h.raw[0];
+ skb_network_header(head)[nhoff] = head->h.raw[0];
memmove(head->head + sizeof(struct frag_hdr), head->head,
(head->data - head->head) - sizeof(struct frag_hdr));
head->mac.raw += sizeof(struct frag_hdr);
@@ -647,7 +654,7 @@
skb_shinfo(head)->frag_list = head->next;
head->h.raw = head->data;
- skb_push(head, head->data - head->nh.raw);
+ skb_push(head, head->data - skb_network_header(head));
atomic_sub(head->truesize, &ip6_frag_mem);
for (fp=head->next; fp; fp = fp->next) {
@@ -671,7 +678,9 @@
/* Yes, and fold redundant checksum back. 8) */
if (head->ip_summed == CHECKSUM_COMPLETE)
- head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
+ head->csum = csum_partial(skb_network_header(head),
+ head->h.raw - head->nh.raw,
+ head->csum);
rcu_read_lock();
IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
@@ -725,7 +734,7 @@
skb->h.raw += sizeof(struct frag_hdr);
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
- IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
+ IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
return 1;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 92f9992..80a52ab 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -486,7 +486,9 @@
struct sk_buff *pktopts = treq->pktopts;
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
if (rxopt->srcrt)
- opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
+ opt = ipv6_invert_rthdr(sk,
+ (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
+ rxopt->srcrt));
}
if (opt && opt->srcrt) {
@@ -1389,7 +1391,9 @@
opt == NULL && treq->pktopts) {
struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
if (rxopt->srcrt)
- opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr *)(treq->pktopts->nh.raw + rxopt->srcrt));
+ opt = ipv6_invert_rthdr(sk,
+ (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
+ rxopt->srcrt));
}
if (dst == NULL) {
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 33a1b92..5c929f8 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -28,7 +28,7 @@
unsigned int nhoff;
nhoff = IP6CB(skb)->nhoff;
- nexthdr = skb->nh.raw[nhoff];
+ nexthdr = skb_network_header(skb)[nhoff];
seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -58,7 +58,7 @@
if (nexthdr <= 0)
goto drop_unlock;
- skb->nh.raw[nhoff] = nexthdr;
+ skb_network_header(skb)[nhoff] = nexthdr;
if (x->props.replay_window)
xfrm_replay_advance(x, seq);
@@ -113,7 +113,7 @@
} else {
#ifdef CONFIG_NETFILTER
skb->nh.ipv6h->payload_len = htons(skb->len);
- __skb_push(skb, skb->data - skb->nh.raw);
+ __skb_push(skb, skb->data - skb_network_header(skb));
NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
ip6_rcv_finish);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index c015bfd..247e2d5 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -67,7 +67,7 @@
goto out;
skb_push(skb, size);
- memmove(skb->data, skb->nh.raw, size);
+ memmove(skb->data, skb_network_header(skb), size);
skb_reset_network_header(skb);
old_mac = skb_mac_header(skb);
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
index 3a4b39b..ace0bbf 100644
--- a/net/ipv6/xfrm6_mode_transport.c
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -53,8 +53,10 @@
{
int ihl = skb->data - skb->h.raw;
- if (skb->h.raw != skb->nh.raw)
- skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl);
+ if (skb->h.raw != skb->nh.raw) {
+ memmove(skb->h.raw, skb_network_header(skb), ihl);
+ skb->nh.raw = skb->h.raw;
+ }
skb->nh.ipv6h->payload_len = htons(skb->len + ihl -
sizeof(struct ipv6hdr));
skb->h.raw = skb->data;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 8ce5ef2..498f17b 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -87,9 +87,10 @@
{
int err = -EINVAL;
const unsigned char *old_mac;
+ const unsigned char *nh = skb_network_header(skb);
- if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6
- && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
+ if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
+ nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
goto out;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto out;
@@ -98,7 +99,8 @@
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
goto out;
- if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
+ nh = skb_network_header(skb);
+ if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
if (x->props.flags & XFRM_STATE_DECAP_DSCP)
ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
if (!(x->props.flags & XFRM_STATE_NOECN))
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d8a585b..cb5a723 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -273,14 +273,16 @@
u16 offset = skb->h.raw - skb->nh.raw;
struct ipv6hdr *hdr = skb->nh.ipv6h;
struct ipv6_opt_hdr *exthdr;
- u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff];
+ const unsigned char *nh = skb_network_header(skb);
+ u8 nexthdr = nh[IP6CB(skb)->nhoff];
memset(fl, 0, sizeof(struct flowi));
ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
- while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
- exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
+ nh = skb_network_header(skb);
+ exthdr = (struct ipv6_opt_hdr *)(nh + offset);
switch (nexthdr) {
case NEXTHDR_ROUTING:
@@ -288,7 +290,7 @@
case NEXTHDR_DEST:
offset += ipv6_optlen(exthdr);
nexthdr = exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+ exthdr = (struct ipv6_opt_hdr *)(nh + offset);
break;
case IPPROTO_UDP:
@@ -296,7 +298,7 @@
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
- if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
+ if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
__be16 *ports = (__be16 *)exthdr;
fl->fl_ip_sport = ports[0];
@@ -306,7 +308,7 @@
return;
case IPPROTO_ICMPV6:
- if (pskb_may_pull(skb, skb->nh.raw + offset + 2 - skb->data)) {
+ if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
u8 *icmp = (u8 *)exthdr;
fl->fl_icmp_type = icmp[0];
@@ -317,7 +319,7 @@
#ifdef CONFIG_IPV6_MIP6
case IPPROTO_MH:
- if (pskb_may_pull(skb, skb->nh.raw + offset + 3 - skb->data)) {
+ if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
struct ip6_mh *mh;
mh = (struct ip6_mh *)exthdr;
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index db7e38c..afc0c60e 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -54,7 +54,7 @@
return -1;
tcplen = (*pskb)->len - tcphoff;
- tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+ tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
/* Since it passed flags test in tcp match, we know it is is
not a fragment, and has data >= tcp header length. SYN
@@ -113,7 +113,7 @@
return -1;
kfree_skb(*pskb);
*pskb = newskb;
- tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+ tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
}
skb_put((*pskb), TCPOLEN_MSS);
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 3d6a2fc..20813ee 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -136,7 +136,7 @@
}
}
- pptr = skb->nh.raw;
+ pptr = skb_network_header(skb);
spin_lock(&p->tcf_lock);
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 0bcb169..695b340 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -119,7 +119,7 @@
} stack[TC_U32_MAXDEPTH];
struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
- u8 *ptr = skb->nh.raw;
+ u8 *ptr = skb_network_header(skb);
struct tc_u_knode *n;
int sdepth = 0;
int off2 = 0;
diff --git a/net/sched/em_u32.c b/net/sched/em_u32.c
index cd0600c..0a2a7fe 100644
--- a/net/sched/em_u32.c
+++ b/net/sched/em_u32.c
@@ -22,7 +22,7 @@
struct tcf_pkt_info *info)
{
struct tc_u32_key *key = (struct tc_u32_key *) em->data;
- unsigned char *ptr = skb->nh.raw;
+ const unsigned char *ptr = skb_network_header(skb);
if (info) {
if (info->ptr)