[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>
This commit is contained in:
committed by
David S. Miller
parent
bbe735e424
commit
d56f90a7c9
@ -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 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
|
||||
len -= 2;
|
||||
|
||||
while (len > 0) {
|
||||
int opttype = skb->nh.raw[offset];
|
||||
int opttype = nh[offset];
|
||||
int optlen;
|
||||
|
||||
if (opttype == type)
|
||||
@ -77,7 +78,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
|
||||
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 @@ static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
|
||||
{
|
||||
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 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
|
||||
{
|
||||
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 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
|
||||
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 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
|
||||
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 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
|
||||
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 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
|
||||
|
||||
/* 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 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
|
||||
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 @@ looped_back:
|
||||
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 @@ looped_back:
|
||||
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 @@ looped_back:
|
||||
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 @@ looped_back:
|
||||
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 @@ looped_back:
|
||||
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 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
|
||||
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_ra(struct sk_buff **skbp, int optoff)
|
||||
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 @@ int ipv6_parse_hopopts(struct sk_buff **skbp)
|
||||
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.
|
||||
|
Reference in New Issue
Block a user