diff options
-rw-r--r-- | include/linux/ip.h | 5 | ||||
-rw-r--r-- | include/linux/ipv6.h | 5 | ||||
-rw-r--r-- | include/linux/netdevice.h | 6 | ||||
-rw-r--r-- | include/linux/skbuff.h | 95 | ||||
-rw-r--r-- | include/linux/tcp.h | 10 | ||||
-rw-r--r-- | include/linux/udp.h | 5 | ||||
-rw-r--r-- | net/core/skbuff.c | 9 |
7 files changed, 134 insertions, 1 deletions
diff --git a/include/linux/ip.h b/include/linux/ip.h index 58b82a22a52b..492bc6513533 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h | |||
@@ -25,6 +25,11 @@ static inline struct iphdr *ip_hdr(const struct sk_buff *skb) | |||
25 | return (struct iphdr *)skb_network_header(skb); | 25 | return (struct iphdr *)skb_network_header(skb); |
26 | } | 26 | } |
27 | 27 | ||
28 | static inline struct iphdr *inner_ip_hdr(const struct sk_buff *skb) | ||
29 | { | ||
30 | return (struct iphdr *)skb_inner_network_header(skb); | ||
31 | } | ||
32 | |||
28 | static inline struct iphdr *ipip_hdr(const struct sk_buff *skb) | 33 | static inline struct iphdr *ipip_hdr(const struct sk_buff *skb) |
29 | { | 34 | { |
30 | return (struct iphdr *)skb_transport_header(skb); | 35 | return (struct iphdr *)skb_transport_header(skb); |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 12729e966dc9..faed1e357dd6 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -67,6 +67,11 @@ static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb) | |||
67 | return (struct ipv6hdr *)skb_network_header(skb); | 67 | return (struct ipv6hdr *)skb_network_header(skb); |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline struct ipv6hdr *inner_ipv6_hdr(const struct sk_buff *skb) | ||
71 | { | ||
72 | return (struct ipv6hdr *)skb_inner_network_header(skb); | ||
73 | } | ||
74 | |||
70 | static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb) | 75 | static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb) |
71 | { | 76 | { |
72 | return (struct ipv6hdr *)skb_transport_header(skb); | 77 | return (struct ipv6hdr *)skb_transport_header(skb); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 18c5dc98f6dc..c6a14d4d1396 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1063,6 +1063,12 @@ struct net_device { | |||
1063 | netdev_features_t wanted_features; | 1063 | netdev_features_t wanted_features; |
1064 | /* mask of features inheritable by VLAN devices */ | 1064 | /* mask of features inheritable by VLAN devices */ |
1065 | netdev_features_t vlan_features; | 1065 | netdev_features_t vlan_features; |
1066 | /* mask of features inherited by encapsulating devices | ||
1067 | * This field indicates what encapsulation offloads | ||
1068 | * the hardware is capable of doing, and drivers will | ||
1069 | * need to set them appropriately. | ||
1070 | */ | ||
1071 | netdev_features_t hw_enc_features; | ||
1066 | 1072 | ||
1067 | /* Interface index. Unique device identifier */ | 1073 | /* Interface index. Unique device identifier */ |
1068 | int ifindex; | 1074 | int ifindex; |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f2af494330ab..320e976d5ab8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -376,6 +376,8 @@ typedef unsigned char *sk_buff_data_t; | |||
376 | * @mark: Generic packet mark | 376 | * @mark: Generic packet mark |
377 | * @dropcount: total number of sk_receive_queue overflows | 377 | * @dropcount: total number of sk_receive_queue overflows |
378 | * @vlan_tci: vlan tag control information | 378 | * @vlan_tci: vlan tag control information |
379 | * @inner_transport_header: Inner transport layer header (encapsulation) | ||
380 | * @inner_network_header: Network layer header (encapsulation) | ||
379 | * @transport_header: Transport layer header | 381 | * @transport_header: Transport layer header |
380 | * @network_header: Network layer header | 382 | * @network_header: Network layer header |
381 | * @mac_header: Link layer header | 383 | * @mac_header: Link layer header |
@@ -471,7 +473,13 @@ struct sk_buff { | |||
471 | __u8 wifi_acked:1; | 473 | __u8 wifi_acked:1; |
472 | __u8 no_fcs:1; | 474 | __u8 no_fcs:1; |
473 | __u8 head_frag:1; | 475 | __u8 head_frag:1; |
474 | /* 8/10 bit hole (depending on ndisc_nodetype presence) */ | 476 | /* Encapsulation protocol and NIC drivers should use |
477 | * this flag to indicate to each other if the skb contains | ||
478 | * encapsulated packet or not and maybe use the inner packet | ||
479 | * headers if needed | ||
480 | */ | ||
481 | __u8 encapsulation:1; | ||
482 | /* 7/9 bit hole (depending on ndisc_nodetype presence) */ | ||
475 | kmemcheck_bitfield_end(flags2); | 483 | kmemcheck_bitfield_end(flags2); |
476 | 484 | ||
477 | #ifdef CONFIG_NET_DMA | 485 | #ifdef CONFIG_NET_DMA |
@@ -486,6 +494,8 @@ struct sk_buff { | |||
486 | __u32 avail_size; | 494 | __u32 avail_size; |
487 | }; | 495 | }; |
488 | 496 | ||
497 | sk_buff_data_t inner_transport_header; | ||
498 | sk_buff_data_t inner_network_header; | ||
489 | sk_buff_data_t transport_header; | 499 | sk_buff_data_t transport_header; |
490 | sk_buff_data_t network_header; | 500 | sk_buff_data_t network_header; |
491 | sk_buff_data_t mac_header; | 501 | sk_buff_data_t mac_header; |
@@ -1435,12 +1445,53 @@ static inline void skb_reserve(struct sk_buff *skb, int len) | |||
1435 | skb->tail += len; | 1445 | skb->tail += len; |
1436 | } | 1446 | } |
1437 | 1447 | ||
1448 | static inline void skb_reset_inner_headers(struct sk_buff *skb) | ||
1449 | { | ||
1450 | skb->inner_network_header = skb->network_header; | ||
1451 | skb->inner_transport_header = skb->transport_header; | ||
1452 | } | ||
1453 | |||
1438 | static inline void skb_reset_mac_len(struct sk_buff *skb) | 1454 | static inline void skb_reset_mac_len(struct sk_buff *skb) |
1439 | { | 1455 | { |
1440 | skb->mac_len = skb->network_header - skb->mac_header; | 1456 | skb->mac_len = skb->network_header - skb->mac_header; |
1441 | } | 1457 | } |
1442 | 1458 | ||
1443 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 1459 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
1460 | static inline unsigned char *skb_inner_transport_header(const struct sk_buff | ||
1461 | *skb) | ||
1462 | { | ||
1463 | return skb->head + skb->inner_transport_header; | ||
1464 | } | ||
1465 | |||
1466 | static inline void skb_reset_inner_transport_header(struct sk_buff *skb) | ||
1467 | { | ||
1468 | skb->inner_transport_header = skb->data - skb->head; | ||
1469 | } | ||
1470 | |||
1471 | static inline void skb_set_inner_transport_header(struct sk_buff *skb, | ||
1472 | const int offset) | ||
1473 | { | ||
1474 | skb_reset_inner_transport_header(skb); | ||
1475 | skb->inner_transport_header += offset; | ||
1476 | } | ||
1477 | |||
1478 | static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb) | ||
1479 | { | ||
1480 | return skb->head + skb->inner_network_header; | ||
1481 | } | ||
1482 | |||
1483 | static inline void skb_reset_inner_network_header(struct sk_buff *skb) | ||
1484 | { | ||
1485 | skb->inner_network_header = skb->data - skb->head; | ||
1486 | } | ||
1487 | |||
1488 | static inline void skb_set_inner_network_header(struct sk_buff *skb, | ||
1489 | const int offset) | ||
1490 | { | ||
1491 | skb_reset_inner_network_header(skb); | ||
1492 | skb->inner_network_header += offset; | ||
1493 | } | ||
1494 | |||
1444 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) | 1495 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) |
1445 | { | 1496 | { |
1446 | return skb->head + skb->transport_header; | 1497 | return skb->head + skb->transport_header; |
@@ -1496,6 +1547,38 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) | |||
1496 | } | 1547 | } |
1497 | 1548 | ||
1498 | #else /* NET_SKBUFF_DATA_USES_OFFSET */ | 1549 | #else /* NET_SKBUFF_DATA_USES_OFFSET */ |
1550 | static inline unsigned char *skb_inner_transport_header(const struct sk_buff | ||
1551 | *skb) | ||
1552 | { | ||
1553 | return skb->inner_transport_header; | ||
1554 | } | ||
1555 | |||
1556 | static inline void skb_reset_inner_transport_header(struct sk_buff *skb) | ||
1557 | { | ||
1558 | skb->inner_transport_header = skb->data; | ||
1559 | } | ||
1560 | |||
1561 | static inline void skb_set_inner_transport_header(struct sk_buff *skb, | ||
1562 | const int offset) | ||
1563 | { | ||
1564 | skb->inner_transport_header = skb->data + offset; | ||
1565 | } | ||
1566 | |||
1567 | static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb) | ||
1568 | { | ||
1569 | return skb->inner_network_header; | ||
1570 | } | ||
1571 | |||
1572 | static inline void skb_reset_inner_network_header(struct sk_buff *skb) | ||
1573 | { | ||
1574 | skb->inner_network_header = skb->data; | ||
1575 | } | ||
1576 | |||
1577 | static inline void skb_set_inner_network_header(struct sk_buff *skb, | ||
1578 | const int offset) | ||
1579 | { | ||
1580 | skb->inner_network_header = skb->data + offset; | ||
1581 | } | ||
1499 | 1582 | ||
1500 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) | 1583 | static inline unsigned char *skb_transport_header(const struct sk_buff *skb) |
1501 | { | 1584 | { |
@@ -1574,11 +1657,21 @@ static inline u32 skb_network_header_len(const struct sk_buff *skb) | |||
1574 | return skb->transport_header - skb->network_header; | 1657 | return skb->transport_header - skb->network_header; |
1575 | } | 1658 | } |
1576 | 1659 | ||
1660 | static inline u32 skb_inner_network_header_len(const struct sk_buff *skb) | ||
1661 | { | ||
1662 | return skb->inner_transport_header - skb->inner_network_header; | ||
1663 | } | ||
1664 | |||
1577 | static inline int skb_network_offset(const struct sk_buff *skb) | 1665 | static inline int skb_network_offset(const struct sk_buff *skb) |
1578 | { | 1666 | { |
1579 | return skb_network_header(skb) - skb->data; | 1667 | return skb_network_header(skb) - skb->data; |
1580 | } | 1668 | } |
1581 | 1669 | ||
1670 | static inline int skb_inner_network_offset(const struct sk_buff *skb) | ||
1671 | { | ||
1672 | return skb_inner_network_header(skb) - skb->data; | ||
1673 | } | ||
1674 | |||
1582 | static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len) | 1675 | static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len) |
1583 | { | 1676 | { |
1584 | return pskb_may_pull(skb, skb_network_offset(skb) + len); | 1677 | return pskb_may_pull(skb, skb_network_offset(skb) + len); |
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 60b7aac15e0e..4e1d2283e3cc 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -35,6 +35,16 @@ static inline unsigned int tcp_hdrlen(const struct sk_buff *skb) | |||
35 | return tcp_hdr(skb)->doff * 4; | 35 | return tcp_hdr(skb)->doff * 4; |
36 | } | 36 | } |
37 | 37 | ||
38 | static inline struct tcphdr *inner_tcp_hdr(const struct sk_buff *skb) | ||
39 | { | ||
40 | return (struct tcphdr *)skb_inner_transport_header(skb); | ||
41 | } | ||
42 | |||
43 | static inline unsigned int inner_tcp_hdrlen(const struct sk_buff *skb) | ||
44 | { | ||
45 | return inner_tcp_hdr(skb)->doff * 4; | ||
46 | } | ||
47 | |||
38 | static inline unsigned int tcp_optlen(const struct sk_buff *skb) | 48 | static inline unsigned int tcp_optlen(const struct sk_buff *skb) |
39 | { | 49 | { |
40 | return (tcp_hdr(skb)->doff - 5) * 4; | 50 | return (tcp_hdr(skb)->doff - 5) * 4; |
diff --git a/include/linux/udp.h b/include/linux/udp.h index 0b67d7793520..9d81de123c90 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h | |||
@@ -27,6 +27,11 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb) | |||
27 | return (struct udphdr *)skb_transport_header(skb); | 27 | return (struct udphdr *)skb_transport_header(skb); |
28 | } | 28 | } |
29 | 29 | ||
30 | static inline struct udphdr *inner_udp_hdr(const struct sk_buff *skb) | ||
31 | { | ||
32 | return (struct udphdr *)skb_inner_transport_header(skb); | ||
33 | } | ||
34 | |||
30 | #define UDP_HTABLE_SIZE_MIN (CONFIG_BASE_SMALL ? 128 : 256) | 35 | #define UDP_HTABLE_SIZE_MIN (CONFIG_BASE_SMALL ? 128 : 256) |
31 | 36 | ||
32 | static inline int udp_hashfn(struct net *net, unsigned num, unsigned mask) | 37 | static inline int udp_hashfn(struct net *net, unsigned num, unsigned mask) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 880722e22cc5..ccbabf565732 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -682,11 +682,14 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
682 | new->transport_header = old->transport_header; | 682 | new->transport_header = old->transport_header; |
683 | new->network_header = old->network_header; | 683 | new->network_header = old->network_header; |
684 | new->mac_header = old->mac_header; | 684 | new->mac_header = old->mac_header; |
685 | new->inner_transport_header = old->inner_transport_header; | ||
686 | new->inner_network_header = old->inner_transport_header; | ||
685 | skb_dst_copy(new, old); | 687 | skb_dst_copy(new, old); |
686 | new->rxhash = old->rxhash; | 688 | new->rxhash = old->rxhash; |
687 | new->ooo_okay = old->ooo_okay; | 689 | new->ooo_okay = old->ooo_okay; |
688 | new->l4_rxhash = old->l4_rxhash; | 690 | new->l4_rxhash = old->l4_rxhash; |
689 | new->no_fcs = old->no_fcs; | 691 | new->no_fcs = old->no_fcs; |
692 | new->encapsulation = old->encapsulation; | ||
690 | #ifdef CONFIG_XFRM | 693 | #ifdef CONFIG_XFRM |
691 | new->sp = secpath_get(old->sp); | 694 | new->sp = secpath_get(old->sp); |
692 | #endif | 695 | #endif |
@@ -892,6 +895,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
892 | new->network_header += offset; | 895 | new->network_header += offset; |
893 | if (skb_mac_header_was_set(new)) | 896 | if (skb_mac_header_was_set(new)) |
894 | new->mac_header += offset; | 897 | new->mac_header += offset; |
898 | new->inner_transport_header += offset; | ||
899 | new->inner_network_header += offset; | ||
895 | #endif | 900 | #endif |
896 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; | 901 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; |
897 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; | 902 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; |
@@ -1089,6 +1094,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
1089 | skb->network_header += off; | 1094 | skb->network_header += off; |
1090 | if (skb_mac_header_was_set(skb)) | 1095 | if (skb_mac_header_was_set(skb)) |
1091 | skb->mac_header += off; | 1096 | skb->mac_header += off; |
1097 | skb->inner_transport_header += off; | ||
1098 | skb->inner_network_header += off; | ||
1092 | /* Only adjust this if it actually is csum_start rather than csum */ | 1099 | /* Only adjust this if it actually is csum_start rather than csum */ |
1093 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 1100 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
1094 | skb->csum_start += nhead; | 1101 | skb->csum_start += nhead; |
@@ -1188,6 +1195,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
1188 | n->network_header += off; | 1195 | n->network_header += off; |
1189 | if (skb_mac_header_was_set(skb)) | 1196 | if (skb_mac_header_was_set(skb)) |
1190 | n->mac_header += off; | 1197 | n->mac_header += off; |
1198 | n->inner_transport_header += off; | ||
1199 | n->inner_network_header += off; | ||
1191 | #endif | 1200 | #endif |
1192 | 1201 | ||
1193 | return n; | 1202 | return n; |