From 4baa947f30eb3c222eb89d45f641cb89ee09d54b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 10 Mar 2007 23:00:36 -0300 Subject: [PATCH 16/18] [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 --- drivers/isdn/i4l/isdn_net.c | 5 +- drivers/net/bonding/bond_alb.c | 2 +- drivers/net/loopback.c | 7 ++- drivers/net/pasemi_mac.c | 6 ++- drivers/s390/net/qeth_main.c | 6 ++- include/linux/if_pppox.h | 2 +- include/linux/skbuff.h | 5 ++ include/net/cipso_ipv4.h | 2 +- include/net/inet_ecn.h | 6 ++- include/net/llc_pdu.h | 4 +- include/net/pkt_cls.h | 2 +- net/bridge/br_netfilter.c | 12 +++-- net/core/dev.c | 9 ++-- net/core/filter.c | 2 +- net/dccp/ipv6.c | 8 ++-- net/decnet/dn_route.c | 4 +- net/ipv4/af_inet.c | 2 +- net/ipv4/ah4.c | 5 +- net/ipv4/esp4.c | 7 ++- net/ipv4/icmp.c | 4 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_options.c | 12 +++--- net/ipv4/ip_output.c | 6 +- net/ipv4/ip_sockglue.c | 8 ++- net/ipv4/ipmr.c | 2 +- net/ipv4/ipvs/ip_vs_app.c | 4 +- net/ipv4/ipvs/ip_vs_core.c | 3 +- net/ipv4/netfilter/arpt_mangle.c | 2 +- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 9 ++-- net/ipv4/raw.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/xfrm4_input.c | 2 +- net/ipv4/xfrm4_mode_beet.c | 4 +- net/ipv4/xfrm4_mode_transport.c | 4 +- net/ipv4/xfrm4_policy.c | 2 +- net/ipv6/af_inet6.c | 3 +- net/ipv6/ah6.c | 12 +++-- net/ipv6/datagram.c | 31 ++++++++------ net/ipv6/esp6.c | 4 +- net/ipv6/exthdrs.c | 56 ++++++++++++++---------- net/ipv6/icmp.c | 3 +- net/ipv6/ip6_input.c | 4 +- net/ipv6/ip6_output.c | 23 ++++++---- net/ipv6/ip6_tunnel.c | 5 +- net/ipv6/ipcomp6.c | 4 +- net/ipv6/mip6.c | 29 +++++++----- net/ipv6/netfilter/nf_conntrack_reasm.c | 19 +++++--- net/ipv6/raw.c | 5 +- net/ipv6/reassembly.c | 25 +++++++--- net/ipv6/tcp_ipv6.c | 8 +++- net/ipv6/xfrm6_input.c | 6 +- net/ipv6/xfrm6_mode_beet.c | 2 +- net/ipv6/xfrm6_mode_transport.c | 6 ++- net/ipv6/xfrm6_mode_tunnel.c | 8 ++- net/ipv6/xfrm6_policy.c | 16 ++++--- net/netfilter/xt_TCPMSS.c | 4 +- net/sched/act_pedit.c | 2 +- net/sched/cls_u32.c | 2 +- net/sched/em_u32.c | 2 +- 59 files changed, 258 insertions(+), 185 deletions(-) diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 0c2b375..cd3b1fa 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -872,7 +872,8 @@ typedef struct { static void isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) { - u_char *p = skb->nh.raw; /* hopefully, this was set correctly */ + /* hopefully, this was set correctly */ + const u_char *p = skb_network_header(skb); unsigned short proto = ntohs(skb->protocol); int data_ofs; ip_ports *ipp; @@ -880,7 +881,7 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) addinfo[0] = '\0'; /* This check stolen from 2.1.72 dev_queue_xmit_nit() */ - if (skb->nh.raw < skb->data || skb->nh.raw >= skb->tail) { + if (p < skb->data || p >= skb->tail) { /* fall back to old isdn_net_log_packet method() */ char * buf = skb->data; diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5c2a12c..86cfcb3 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -106,7 +106,7 @@ struct arp_pkt { static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) { - return (struct arp_pkt *)skb->nh.raw; + return (struct arp_pkt *)skb_network_header(skb); } /* Forward declaration */ diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index af476d2..9265c27 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -76,7 +76,8 @@ static DEFINE_PER_CPU(struct pcpu_lstats, pcpu_lstats); static void emulate_large_send_offload(struct sk_buff *skb) { struct iphdr *iph = skb->nh.iph; - struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); + struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) + + (iph->ihl * 4)); unsigned int doffset = (iph->ihl + th->doff) * 4; unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; unsigned int offset = 0; @@ -93,7 +94,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) skb_set_mac_header(nskb, -ETH_HLEN); skb_reset_network_header(nskb); iph = nskb->nh.iph; - memcpy(nskb->data, skb->nh.raw, doffset); + memcpy(nskb->data, skb_network_header(skb), doffset); if (skb_copy_bits(skb, doffset + offset, nskb->data + doffset, @@ -108,7 +109,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); nskb->pkt_type = skb->pkt_type; - th = (struct tcphdr*)(nskb->nh.raw + iph->ihl*4); + th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4); iph->tot_len = htons(frag_size + doffset); iph->id = htons(id); iph->check = 0; diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 3f4213f..8221872 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -729,16 +729,18 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD; if (skb->ip_summed == CHECKSUM_PARTIAL) { + const unsigned char *nh = skb_network_header(skb); + switch (skb->nh.iph->protocol) { case IPPROTO_TCP: dflags |= XCT_MACTX_CSUM_TCP; dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2); - dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data); + dflags |= XCT_MACTX_IPO(nh - skb->data); break; case IPPROTO_UDP: dflags |= XCT_MACTX_CSUM_UDP; dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2); - dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data); + dflags |= XCT_MACTX_IPO(nh - skb->data); break; } } diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index c0ee6d9..0ff29e0 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -3778,9 +3778,11 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb) } /* try something else */ if (skb->protocol == ETH_P_IPV6) - return (skb->nh.raw[24] == 0xff) ? RTN_MULTICAST : 0; + return (skb_network_header(skb)[24] == 0xff) ? + RTN_MULTICAST : 0; else if (skb->protocol == ETH_P_IP) - return ((skb->nh.raw[16] & 0xf0) == 0xe0) ? RTN_MULTICAST : 0; + return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ? + RTN_MULTICAST : 0; /* ... */ if (!memcmp(skb->data, skb->dev->broadcast, 6)) return RTN_BROADCAST; diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 7044f8a..29d6579 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -116,7 +116,7 @@ struct pppoe_hdr { static inline struct pppoe_hdr *pppoe_hdr(const struct sk_buff *skb) { - return (struct pppoe_hdr *)skb->nh.raw; + return (struct pppoe_hdr *)skb_network_header(skb); } struct pppoe_opt { diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 0903cbe..52e8307 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -958,6 +958,11 @@ static inline void skb_reserve(struct sk_buff *skb, int len) skb->tail += len; } +static inline unsigned char *skb_network_header(const struct sk_buff *skb) +{ + return skb->nh.raw; +} + static inline void skb_reset_network_header(struct sk_buff *skb) { skb->nh.raw = skb->data; diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index 4c9522c..4f90f55 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -120,7 +120,7 @@ extern int cipso_v4_rbm_strictvalid; */ #define CIPSO_V4_OPTEXIST(x) (IPCB(x)->opt.cipso != 0) -#define CIPSO_V4_OPTPTR(x) ((x)->nh.raw + IPCB(x)->opt.cipso) +#define CIPSO_V4_OPTPTR(x) (skb_network_header(x) + IPCB(x)->opt.cipso) /* * DOI List Functions diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 10117c8..b9ed389 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -114,12 +114,14 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) { switch (skb->protocol) { case __constant_htons(ETH_P_IP): - if (skb->nh.raw + sizeof(struct iphdr) <= skb->tail) + if (skb_network_header(skb) + sizeof(struct iphdr) <= + skb->tail) return IP_ECN_set_ce(skb->nh.iph); break; case __constant_htons(ETH_P_IPV6): - if (skb->nh.raw + sizeof(struct ipv6hdr) <= skb->tail) + if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= + skb->tail) return IP6_ECN_set_ce(skb->nh.ipv6h); break; } diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h index 778f75a..4a8f58b 100644 --- a/include/net/llc_pdu.h +++ b/include/net/llc_pdu.h @@ -203,7 +203,7 @@ struct llc_pdu_sn { static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb) { - return (struct llc_pdu_sn *)skb->nh.raw; + return (struct llc_pdu_sn *)skb_network_header(skb); } /* Un-numbered PDU format (3 bytes in length) */ @@ -215,7 +215,7 @@ struct llc_pdu_un { static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb) { - return (struct llc_pdu_un *)skb->nh.raw; + return (struct llc_pdu_un *)skb_network_header(skb); } /** diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index b902d24..6a06e53 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -326,7 +326,7 @@ static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) case TCF_LAYER_LINK: return skb->data; case TCF_LAYER_NETWORK: - return skb->nh.raw; + return skb_network_header(skb); case TCF_LAYER_TRANSPORT: return skb->h.raw; } diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 22a32fb..b32b3cd 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -374,7 +374,8 @@ static int check_hbh_len(struct sk_buff *skb) { 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 @@ static int check_hbh_len(struct sk_buff *skb) 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 @@ static int check_hbh_len(struct sk_buff *skb) 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 @@ static int check_hbh_len(struct sk_buff *skb) 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 0c8d9b1..de3cf33 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1071,8 +1071,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) */ 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", @@ -1210,7 +1210,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) 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)) { @@ -1227,7 +1227,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) 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 @@ static void *__load_pointer(struct sk_buff *skb, int k) 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 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, 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 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, 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 @@ static int dn_return_short(struct sk_buff *skb) __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 @@ static int dn_return_long(struct sk_buff *skb) 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 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) 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 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) } } ((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 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) *(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 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) 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 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) 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 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev) } 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 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) return 0; } - sptr = skb->nh.raw; + sptr = skb_network_header(skb); dptr = dopt->__data; if (skb->dst) @@ -217,7 +217,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) 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 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) 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 @@ void ip_forward_options(struct sk_buff *skb) 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 ip_options_rcv_srr(struct sk_buff *skb) 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 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) 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 @@ slow_path: * 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 @@ int ip_push_pending_frames(struct sock *sk) 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 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 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 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf 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 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) 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 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) */ 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 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb, 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 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb, 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 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, { 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 @@ target(struct sk_buff **pskb, } 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 @@ ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, 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 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, 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 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) } 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 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, 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 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 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 19c31be..9a9b91d 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -95,7 +95,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) } skb_push(skb, sizeof(*iph) - phlen + optlen); - memmove(skb->data, skb->nh.raw, sizeof(*iph)); + memmove(skb->data, skb_network_header(skb), sizeof(*iph)); skb_reset_network_header(skb); iph = skb->nh.iph; @@ -108,7 +108,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) 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 98a833c..fbb1d3d 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -210,7 +210,7 @@ static void _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 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) 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 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) } } - 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 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 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 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) 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 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) 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 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) { 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 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) 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 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) 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 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) 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 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) 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 32b5560..efef1fd 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 @@ 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) @@ -410,7 +413,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; } @@ -419,7 +422,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; @@ -437,7 +442,8 @@ looped_back: 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; } @@ -451,7 +457,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; } @@ -519,7 +527,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; } @@ -537,7 +545,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; } @@ -628,13 +636,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; } @@ -644,17 +653,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); @@ -699,7 +709,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. 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 @@ static void mip6_addr_swap(struct sk_buff *skb) 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 11bfc7c..b684b78 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -163,7 +163,7 @@ resubmit: 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 @@ resubmit: 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 @@ static int ip6_forward_proxy_check(struct sk_buff *skb) 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 @@ int ip6_forward(struct sk_buff *skb) * 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 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) { 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 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) 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 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* 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 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 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 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 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 @@ slow_path: /* * 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 @@ int ip6_push_pending_frames(struct sock *sk) 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 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) !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 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) 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 @@ int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) 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 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct 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 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb, { 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 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb, 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 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb, { 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 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb, 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 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb, 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 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, 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 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) 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 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* 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 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) 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 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* 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 f2b09a7..d484d4c 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -361,7 +361,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) 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 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, 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 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, 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 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, 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 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, /* 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 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, 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 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, /* 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 @@ static int ipv6_frag_rcv(struct sk_buff **skbp) 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 21706a1..c537a9e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -486,7 +486,9 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, 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 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, 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 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) 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 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) 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 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) } 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 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) 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 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) { 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 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { 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 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) (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 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) 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 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) 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 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) 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 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) 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 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) #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..afc0c60 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -54,7 +54,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb, 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 @@ tcpmss_mangle_packet(struct sk_buff **pskb, 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 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a, } } - 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 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re } 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 @@ static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em, 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) -- 1.5.0.2