aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ip.h5
-rw-r--r--include/linux/ipv6.h5
-rw-r--r--include/linux/netdevice.h6
-rw-r--r--include/linux/skbuff.h95
-rw-r--r--include/linux/tcp.h10
-rw-r--r--include/linux/udp.h5
-rw-r--r--net/core/skbuff.c9
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
28static inline struct iphdr *inner_ip_hdr(const struct sk_buff *skb)
29{
30 return (struct iphdr *)skb_inner_network_header(skb);
31}
32
28static inline struct iphdr *ipip_hdr(const struct sk_buff *skb) 33static 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
70static inline struct ipv6hdr *inner_ipv6_hdr(const struct sk_buff *skb)
71{
72 return (struct ipv6hdr *)skb_inner_network_header(skb);
73}
74
70static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb) 75static 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
1448static 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
1438static inline void skb_reset_mac_len(struct sk_buff *skb) 1454static 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
1460static inline unsigned char *skb_inner_transport_header(const struct sk_buff
1461 *skb)
1462{
1463 return skb->head + skb->inner_transport_header;
1464}
1465
1466static inline void skb_reset_inner_transport_header(struct sk_buff *skb)
1467{
1468 skb->inner_transport_header = skb->data - skb->head;
1469}
1470
1471static 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
1478static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
1479{
1480 return skb->head + skb->inner_network_header;
1481}
1482
1483static inline void skb_reset_inner_network_header(struct sk_buff *skb)
1484{
1485 skb->inner_network_header = skb->data - skb->head;
1486}
1487
1488static 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
1444static inline unsigned char *skb_transport_header(const struct sk_buff *skb) 1495static 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 */
1550static inline unsigned char *skb_inner_transport_header(const struct sk_buff
1551 *skb)
1552{
1553 return skb->inner_transport_header;
1554}
1555
1556static inline void skb_reset_inner_transport_header(struct sk_buff *skb)
1557{
1558 skb->inner_transport_header = skb->data;
1559}
1560
1561static 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
1567static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
1568{
1569 return skb->inner_network_header;
1570}
1571
1572static inline void skb_reset_inner_network_header(struct sk_buff *skb)
1573{
1574 skb->inner_network_header = skb->data;
1575}
1576
1577static 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
1500static inline unsigned char *skb_transport_header(const struct sk_buff *skb) 1583static 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
1660static 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
1577static inline int skb_network_offset(const struct sk_buff *skb) 1665static 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
1670static inline int skb_inner_network_offset(const struct sk_buff *skb)
1671{
1672 return skb_inner_network_header(skb) - skb->data;
1673}
1674
1582static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len) 1675static 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
38static inline struct tcphdr *inner_tcp_hdr(const struct sk_buff *skb)
39{
40 return (struct tcphdr *)skb_inner_transport_header(skb);
41}
42
43static inline unsigned int inner_tcp_hdrlen(const struct sk_buff *skb)
44{
45 return inner_tcp_hdr(skb)->doff * 4;
46}
47
38static inline unsigned int tcp_optlen(const struct sk_buff *skb) 48static 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
30static 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
32static inline int udp_hashfn(struct net *net, unsigned num, unsigned mask) 37static 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;