diff options
-rw-r--r-- | include/linux/skbuff.h | 104 | ||||
-rw-r--r-- | net/core/skbuff.c | 18 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_xmit.c | 2 | ||||
-rw-r--r-- | net/sctp/input.c | 4 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 2 |
5 files changed, 104 insertions, 26 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c45ad1263271..2e7405500626 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -179,6 +179,16 @@ enum { | |||
179 | SKB_GSO_TCPV6 = 1 << 4, | 179 | SKB_GSO_TCPV6 = 1 << 4, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | #if BITS_PER_LONG > 32 | ||
183 | #define NET_SKBUFF_DATA_USES_OFFSET 1 | ||
184 | #endif | ||
185 | |||
186 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
187 | typedef unsigned int sk_buff_data_t; | ||
188 | #else | ||
189 | typedef unsigned char *sk_buff_data_t; | ||
190 | #endif | ||
191 | |||
182 | /** | 192 | /** |
183 | * struct sk_buff - socket buffer | 193 | * struct sk_buff - socket buffer |
184 | * @next: Next buffer in list | 194 | * @next: Next buffer in list |
@@ -236,9 +246,9 @@ struct sk_buff { | |||
236 | int iif; | 246 | int iif; |
237 | /* 4 byte hole on 64 bit*/ | 247 | /* 4 byte hole on 64 bit*/ |
238 | 248 | ||
239 | unsigned char *transport_header; | 249 | sk_buff_data_t transport_header; |
240 | unsigned char *network_header; | 250 | sk_buff_data_t network_header; |
241 | unsigned char *mac_header; | 251 | sk_buff_data_t mac_header; |
242 | struct dst_entry *dst; | 252 | struct dst_entry *dst; |
243 | struct sec_path *sp; | 253 | struct sec_path *sp; |
244 | 254 | ||
@@ -942,50 +952,92 @@ static inline void skb_reserve(struct sk_buff *skb, int len) | |||
942 | skb->tail += len; | 952 | skb->tail += len; |
943 | } | 953 | } |
944 | 954 | ||
955 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
945 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) | 956 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) |
946 | { | 957 | { |
947 | return skb->transport_header; | 958 | return skb->head + skb->transport_header; |
948 | } | 959 | } |
949 | 960 | ||
950 | static inline void skb_reset_transport_header(struct sk_buff *skb) | 961 | static inline void skb_reset_transport_header(struct sk_buff *skb) |
951 | { | 962 | { |
952 | skb->transport_header = skb->data; | 963 | skb->transport_header = skb->data - skb->head; |
953 | } | 964 | } |
954 | 965 | ||
955 | static inline void skb_set_transport_header(struct sk_buff *skb, | 966 | static inline void skb_set_transport_header(struct sk_buff *skb, |
956 | const int offset) | 967 | const int offset) |
957 | { | 968 | { |
958 | skb->transport_header = skb->data + offset; | 969 | skb_reset_transport_header(skb); |
959 | } | 970 | skb->transport_header += offset; |
960 | |||
961 | static inline int skb_transport_offset(const struct sk_buff *skb) | ||
962 | { | ||
963 | return skb->transport_header - skb->data; | ||
964 | } | 971 | } |
965 | 972 | ||
966 | static inline unsigned char *skb_network_header(const struct sk_buff *skb) | 973 | static inline unsigned char *skb_network_header(const struct sk_buff *skb) |
967 | { | 974 | { |
968 | return skb->network_header; | 975 | return skb->head + skb->network_header; |
969 | } | 976 | } |
970 | 977 | ||
971 | static inline void skb_reset_network_header(struct sk_buff *skb) | 978 | static inline void skb_reset_network_header(struct sk_buff *skb) |
972 | { | 979 | { |
973 | skb->network_header = skb->data; | 980 | skb->network_header = skb->data - skb->head; |
974 | } | 981 | } |
975 | 982 | ||
976 | static inline void skb_set_network_header(struct sk_buff *skb, const int offset) | 983 | static inline void skb_set_network_header(struct sk_buff *skb, const int offset) |
977 | { | 984 | { |
978 | skb->network_header = skb->data + offset; | 985 | skb_reset_network_header(skb); |
986 | skb->network_header += offset; | ||
979 | } | 987 | } |
980 | 988 | ||
981 | static inline int skb_network_offset(const struct sk_buff *skb) | 989 | static inline unsigned char *skb_mac_header(const struct sk_buff *skb) |
982 | { | 990 | { |
983 | return skb->network_header - skb->data; | 991 | return skb->head + skb->mac_header; |
984 | } | 992 | } |
985 | 993 | ||
986 | static inline u32 skb_network_header_len(const struct sk_buff *skb) | 994 | static inline int skb_mac_header_was_set(const struct sk_buff *skb) |
987 | { | 995 | { |
988 | return skb->transport_header - skb->network_header; | 996 | return skb->mac_header != ~0U; |
997 | } | ||
998 | |||
999 | static inline void skb_reset_mac_header(struct sk_buff *skb) | ||
1000 | { | ||
1001 | skb->mac_header = skb->data - skb->head; | ||
1002 | } | ||
1003 | |||
1004 | static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) | ||
1005 | { | ||
1006 | skb_reset_mac_header(skb); | ||
1007 | skb->mac_header += offset; | ||
1008 | } | ||
1009 | |||
1010 | #else /* NET_SKBUFF_DATA_USES_OFFSET */ | ||
1011 | |||
1012 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) | ||
1013 | { | ||
1014 | return skb->transport_header; | ||
1015 | } | ||
1016 | |||
1017 | static inline void skb_reset_transport_header(struct sk_buff *skb) | ||
1018 | { | ||
1019 | skb->transport_header = skb->data; | ||
1020 | } | ||
1021 | |||
1022 | static inline void skb_set_transport_header(struct sk_buff *skb, | ||
1023 | const int offset) | ||
1024 | { | ||
1025 | skb->transport_header = skb->data + offset; | ||
1026 | } | ||
1027 | |||
1028 | static inline unsigned char *skb_network_header(const struct sk_buff *skb) | ||
1029 | { | ||
1030 | return skb->network_header; | ||
1031 | } | ||
1032 | |||
1033 | static inline void skb_reset_network_header(struct sk_buff *skb) | ||
1034 | { | ||
1035 | skb->network_header = skb->data; | ||
1036 | } | ||
1037 | |||
1038 | static inline void skb_set_network_header(struct sk_buff *skb, const int offset) | ||
1039 | { | ||
1040 | skb->network_header = skb->data + offset; | ||
989 | } | 1041 | } |
990 | 1042 | ||
991 | static inline unsigned char *skb_mac_header(const struct sk_buff *skb) | 1043 | static inline unsigned char *skb_mac_header(const struct sk_buff *skb) |
@@ -1007,6 +1059,22 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) | |||
1007 | { | 1059 | { |
1008 | skb->mac_header = skb->data + offset; | 1060 | skb->mac_header = skb->data + offset; |
1009 | } | 1061 | } |
1062 | #endif /* NET_SKBUFF_DATA_USES_OFFSET */ | ||
1063 | |||
1064 | static inline int skb_transport_offset(const struct sk_buff *skb) | ||
1065 | { | ||
1066 | return skb_transport_header(skb) - skb->data; | ||
1067 | } | ||
1068 | |||
1069 | static inline u32 skb_network_header_len(const struct sk_buff *skb) | ||
1070 | { | ||
1071 | return skb->transport_header - skb->network_header; | ||
1072 | } | ||
1073 | |||
1074 | static inline int skb_network_offset(const struct sk_buff *skb) | ||
1075 | { | ||
1076 | return skb_network_header(skb) - skb->data; | ||
1077 | } | ||
1010 | 1078 | ||
1011 | /* | 1079 | /* |
1012 | * CPUs often take a performance hit when accessing unaligned memory | 1080 | * CPUs often take a performance hit when accessing unaligned memory |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1e71764be4a4..a48b08681261 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -448,11 +448,12 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) | |||
448 | 448 | ||
449 | static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | 449 | static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) |
450 | { | 450 | { |
451 | #ifndef NET_SKBUFF_DATA_USES_OFFSET | ||
451 | /* | 452 | /* |
452 | * Shift between the two data areas in bytes | 453 | * Shift between the two data areas in bytes |
453 | */ | 454 | */ |
454 | unsigned long offset = new->data - old->data; | 455 | unsigned long offset = new->data - old->data; |
455 | 456 | #endif | |
456 | new->sk = NULL; | 457 | new->sk = NULL; |
457 | new->dev = old->dev; | 458 | new->dev = old->dev; |
458 | new->priority = old->priority; | 459 | new->priority = old->priority; |
@@ -461,9 +462,15 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
461 | #ifdef CONFIG_INET | 462 | #ifdef CONFIG_INET |
462 | new->sp = secpath_get(old->sp); | 463 | new->sp = secpath_get(old->sp); |
463 | #endif | 464 | #endif |
464 | new->transport_header = old->transport_header + offset; | 465 | new->transport_header = old->transport_header; |
465 | new->network_header = old->network_header + offset; | 466 | new->network_header = old->network_header; |
466 | new->mac_header = old->mac_header + offset; | 467 | new->mac_header = old->mac_header; |
468 | #ifndef NET_SKBUFF_DATA_USES_OFFSET | ||
469 | /* {transport,network,mac}_header are relative to skb->head */ | ||
470 | new->transport_header += offset; | ||
471 | new->network_header += offset; | ||
472 | new->mac_header += offset; | ||
473 | #endif | ||
467 | memcpy(new->cb, old->cb, sizeof(old->cb)); | 474 | memcpy(new->cb, old->cb, sizeof(old->cb)); |
468 | new->local_df = old->local_df; | 475 | new->local_df = old->local_df; |
469 | new->fclone = SKB_FCLONE_UNAVAILABLE; | 476 | new->fclone = SKB_FCLONE_UNAVAILABLE; |
@@ -639,9 +646,12 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
639 | skb->end = data + size; | 646 | skb->end = data + size; |
640 | skb->data += off; | 647 | skb->data += off; |
641 | skb->tail += off; | 648 | skb->tail += off; |
649 | #ifndef NET_SKBUFF_DATA_USES_OFFSET | ||
650 | /* {transport,network,mac}_header are relative to skb->head */ | ||
642 | skb->transport_header += off; | 651 | skb->transport_header += off; |
643 | skb->network_header += off; | 652 | skb->network_header += off; |
644 | skb->mac_header += off; | 653 | skb->mac_header += off; |
654 | #endif | ||
645 | skb->cloned = 0; | 655 | skb->cloned = 0; |
646 | skb->nohdr = 0; | 656 | skb->nohdr = 0; |
647 | atomic_set(&skb_shinfo(skb)->dataref, 1); | 657 | atomic_set(&skb_shinfo(skb)->dataref, 1); |
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index fded9b2f227c..900ce29db382 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
@@ -323,7 +323,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
323 | struct iphdr *old_iph = ip_hdr(skb); | 323 | struct iphdr *old_iph = ip_hdr(skb); |
324 | u8 tos = old_iph->tos; | 324 | u8 tos = old_iph->tos; |
325 | __be16 df = old_iph->frag_off; | 325 | __be16 df = old_iph->frag_off; |
326 | unsigned char *old_transport_header = skb->transport_header; | 326 | sk_buff_data_t old_transport_header = skb->transport_header; |
327 | struct iphdr *iph; /* Our new IP header */ | 327 | struct iphdr *iph; /* Our new IP header */ |
328 | int max_headroom; /* The extra header space needed */ | 328 | int max_headroom; /* The extra header space needed */ |
329 | int mtu; | 329 | int mtu; |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 87feee166da9..1ff47b18724a 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -513,7 +513,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
513 | struct sctp_association *asoc = NULL; | 513 | struct sctp_association *asoc = NULL; |
514 | struct sctp_transport *transport; | 514 | struct sctp_transport *transport; |
515 | struct inet_sock *inet; | 515 | struct inet_sock *inet; |
516 | char *saveip, *savesctp; | 516 | sk_buff_data_t saveip, savesctp; |
517 | int err; | 517 | int err; |
518 | 518 | ||
519 | if (skb->len < ihlen + 8) { | 519 | if (skb->len < ihlen + 8) { |
@@ -527,7 +527,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
527 | skb_reset_network_header(skb); | 527 | skb_reset_network_header(skb); |
528 | skb_set_transport_header(skb, ihlen); | 528 | skb_set_transport_header(skb, ihlen); |
529 | sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport); | 529 | sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport); |
530 | /* Put back, the original pointers. */ | 530 | /* Put back, the original values. */ |
531 | skb->network_header = saveip; | 531 | skb->network_header = saveip; |
532 | skb->transport_header = savesctp; | 532 | skb->transport_header = savesctp; |
533 | if (!sk) { | 533 | if (!sk) { |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index afcb0093c290..5b0cdda4b449 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -126,7 +126,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
126 | struct sctp_association *asoc; | 126 | struct sctp_association *asoc; |
127 | struct sctp_transport *transport; | 127 | struct sctp_transport *transport; |
128 | struct ipv6_pinfo *np; | 128 | struct ipv6_pinfo *np; |
129 | char *saveip, *savesctp; | 129 | sk_buff_data_t saveip, savesctp; |
130 | int err; | 130 | int err; |
131 | 131 | ||
132 | idev = in6_dev_get(skb->dev); | 132 | idev = in6_dev_get(skb->dev); |