summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2007-04-19 20:29:13 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-25 22:26:28 -0700
commit27a884dc3cb63b93c2b3b643f5b31eed5f8a4d26 (patch)
tree5a267e40f9b94014be38dad5de0a52b6628834e0 /net/ipv4
parentbe8bd86321fa7f06359d866ef61fb4d2f3e9dce9 (diff)
[SK_BUFF]: Convert skb->tail to sk_buff_data_t
So that it is also an offset from skb->head, reduces its size from 8 to 4 bytes on 64bit architectures, allowing us to combine the 4 bytes hole left by the layer headers conversion, reducing struct sk_buff size to 256 bytes, i.e. 4 64byte cachelines, and since the sk_buff slab cache is SLAB_HWCACHE_ALIGN... :-) Many calculations that previously required that skb->{transport,network, mac}_header be first converted to a pointer now can be done directly, being meaningful as offsets or pointers. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/esp4.c8
-rw-r--r--net/ipv4/icmp.c3
-rw-r--r--net/ipv4/igmp.c4
-rw-r--r--net/ipv4/inet_diag.c12
-rw-r--r--net/ipv4/ip_sockglue.c2
-rw-r--r--net/ipv4/ipmr.c9
-rw-r--r--net/ipv4/ipvs/ip_vs_ftp.c4
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c8
-rw-r--r--net/ipv4/netfilter/ip_queue.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c3
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_output.c2
12 files changed, 33 insertions, 28 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index de019f9fbfe1..5e5613930ffb 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -21,6 +21,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
struct blkcipher_desc desc;
struct esp_data *esp;
struct sk_buff *trailer;
+ u8 *tail;
int blksize;
int clen;
int alen;
@@ -49,12 +50,13 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
goto error;
/* Fill padding... */
+ tail = skb_tail_pointer(trailer);
do {
int i;
for (i=0; i<clen-skb->len - 2; i++)
- *(u8*)(trailer->tail + i) = i+1;
+ tail[i] = i + 1;
} while (0);
- *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
+ tail[clen - skb->len - 2] = (clen - skb->len) - 2;
pskb_put(skb, trailer, clen - skb->len);
__skb_push(skb, skb->data - skb_network_header(skb));
@@ -62,7 +64,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
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;
+ *(skb_tail_pointer(skb) - 1) = top_iph->protocol;
/* this is non-NULL only with UDP Encapsulation */
if (x->encap) {
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 8372f8b8f0cd..d38cbba92a4d 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -450,7 +450,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
*/
iph = ip_hdr(skb_in);
- if ((u8 *)iph < skb_in->head || (u8 *)(iph + 1) > skb_in->tail)
+ if ((u8 *)iph < skb_in->head ||
+ (skb_in->network_header + sizeof(*iph)) > skb_in->tail)
goto out;
/*
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 1fc637fb6750..2506021c2935 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -348,8 +348,8 @@ static int igmpv3_sendpack(struct sk_buff *skb)
{
struct iphdr *pip = ip_hdr(skb);
struct igmphdr *pig = igmp_hdr(skb);
- const int iplen = skb->tail - skb_network_header(skb);
- const int igmplen = skb->tail - skb_transport_header(skb);
+ const int iplen = skb->tail - skb->network_header;
+ const int igmplen = skb->tail - skb->transport_header;
pip->tot_len = htons(iplen);
ip_send_check(pip);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 5df71cd08da8..37362cd1d07f 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -60,7 +60,7 @@ static int inet_csk_diag_fill(struct sock *sk,
struct nlmsghdr *nlh;
void *info = NULL;
struct inet_diag_meminfo *minfo = NULL;
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
const struct inet_diag_handler *handler;
handler = inet_diag_table[unlh->nlmsg_type];
@@ -147,7 +147,7 @@ static int inet_csk_diag_fill(struct sock *sk,
icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
icsk->icsk_ca_ops->get_info(sk, ext, skb);
- nlh->nlmsg_len = skb->tail - b;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
rtattr_failure:
@@ -163,7 +163,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
{
long tmo;
struct inet_diag_msg *r;
- const unsigned char *previous_tail = skb->tail;
+ const unsigned char *previous_tail = skb_tail_pointer(skb);
struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq,
unlh->nlmsg_type, sizeof(*r));
@@ -205,7 +205,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
&tw6->tw_v6_daddr);
}
#endif
- nlh->nlmsg_len = skb->tail - previous_tail;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail;
return skb->len;
nlmsg_failure:
skb_trim(skb, previous_tail - skb->data);
@@ -535,7 +535,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
{
const struct inet_request_sock *ireq = inet_rsk(req);
struct inet_sock *inet = inet_sk(sk);
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct inet_diag_msg *r;
struct nlmsghdr *nlh;
long tmo;
@@ -574,7 +574,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
&inet6_rsk(req)->rmt_addr);
}
#endif
- nlh->nlmsg_len = skb->tail - b;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index fcb35cd5ccfd..c199d2311731 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -316,7 +316,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
serr->port = port;
- __skb_pull(skb, skb->tail - skb->data);
+ __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
skb_reset_transport_header(skb);
if (sock_queue_err_skb(sk, skb))
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 50d0b301380e..ea0a491dce92 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -513,7 +513,8 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
if (ipmr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) {
- nlh->nlmsg_len = skb->tail - (u8*)nlh;
+ nlh->nlmsg_len = (skb_tail_pointer(skb) -
+ (u8 *)nlh);
} else {
nlh->nlmsg_type = NLMSG_ERROR;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
@@ -580,7 +581,7 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
* Copy the IP header
*/
- skb_set_network_header(skb, skb->tail - skb->data);
+ skb->network_header = skb->tail;
skb_put(skb, ihl);
memcpy(skb->data,pkt->data,ihl);
ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */
@@ -1544,7 +1545,7 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
int ct;
struct rtnexthop *nhp;
struct net_device *dev = vif_table[c->mfc_parent].dev;
- u8 *b = skb->tail;
+ u8 *b = skb_tail_pointer(skb);
struct rtattr *mp_head;
if (dev)
@@ -1564,7 +1565,7 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
}
}
mp_head->rta_type = RTA_MULTIPATH;
- mp_head->rta_len = skb->tail - (u8*)mp_head;
+ mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head;
rtm->rtm_type = RTN_MULTICAST;
return 1;
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 25bd68967305..344ddbbdc756 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -162,7 +162,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
iph = ip_hdr(*pskb);
th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
data = (char *)th + (th->doff << 2);
- data_limit = (*pskb)->tail;
+ data_limit = skb_tail_pointer(*pskb);
if (ip_vs_ftp_get_addrport(data, data_limit,
SERVER_STRING,
@@ -269,7 +269,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
the length of the header in 32-bit multiples, it is accurate
to calculate data address by th+HLEN*4 */
data = data_start = (char *)th + (th->doff << 2);
- data_limit = (*pskb)->tail;
+ data_limit = skb_tail_pointer(*pskb);
while (data <= data_limit - 6) {
if (strnicmp(data, "PASV\r\n", 6) == 0) {
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index b4450f1ccc1b..6298d404e7c7 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -37,28 +37,28 @@ target(struct sk_buff **pskb,
/* We assume that pln and hln were checked in the match */
if (mangle->flags & ARPT_MANGLE_SDEV) {
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
- (arpptr + hln > (**pskb).tail))
+ (arpptr + hln > skb_tail_pointer(*pskb)))
return NF_DROP;
memcpy(arpptr, mangle->src_devaddr, hln);
}
arpptr += hln;
if (mangle->flags & ARPT_MANGLE_SIP) {
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
- (arpptr + pln > (**pskb).tail))
+ (arpptr + pln > skb_tail_pointer(*pskb)))
return NF_DROP;
memcpy(arpptr, &mangle->u_s.src_ip, pln);
}
arpptr += pln;
if (mangle->flags & ARPT_MANGLE_TDEV) {
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
- (arpptr + hln > (**pskb).tail))
+ (arpptr + hln > skb_tail_pointer(*pskb)))
return NF_DROP;
memcpy(arpptr, mangle->tgt_devaddr, hln);
}
arpptr += hln;
if (mangle->flags & ARPT_MANGLE_TIP) {
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
- (arpptr + pln > (**pskb).tail))
+ (arpptr + pln > skb_tail_pointer(*pskb)))
return NF_DROP;
memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
}
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 5842f1aa973a..15e0d2002235 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -191,7 +191,7 @@ ipq_flush(int verdict)
static struct sk_buff *
ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
{
- unsigned char *old_tail;
+ sk_buff_data_t old_tail;
size_t size = 0;
size_t data_len = 0;
struct sk_buff *skb;
@@ -235,7 +235,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
if (!skb)
goto nlmsg_failure;
- old_tail= skb->tail;
+ old_tail = skb->tail;
nlh = NLMSG_PUT(skb, 0, 0, IPQM_PACKET, size - sizeof(*nlh));
pmsg = NLMSG_DATA(nlh);
memset(pmsg, 0, sizeof(*pmsg));
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index c2c92ff12781..8a40fbe842b7 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -92,7 +92,8 @@ static void mangle_contents(struct sk_buff *skb,
/* move post-replacement */
memmove(data + match_offset + rep_len,
data + match_offset + match_len,
- skb->tail - (data + match_offset + match_len));
+ skb->tail - (skb->network_header + dataoff +
+ match_offset + match_len));
/* insert data from buffer */
memcpy(data + match_offset, rep_buffer, rep_len);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2b214cc3724c..18a09a78ca0b 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2231,7 +2231,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
th->cwr = 0;
} while (skb->next);
- delta = htonl(oldlen + (skb->tail - skb_transport_header(skb)) +
+ delta = htonl(oldlen + (skb->tail - skb->transport_header) +
skb->data_len);
th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
(__force u32)delta));
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 29c53fbb2204..c22cdcd84320 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -733,7 +733,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
}
skb_shinfo(skb)->nr_frags = k;
- skb->tail = skb->data;
+ skb_reset_tail_pointer(skb);
skb->data_len -= len;
skb->len = skb->data_len;
}