]>
git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/examples/ipsec-secgw/ipip.h
4 * Copyright(c) 2016 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <netinet/ip6.h>
45 ipip_outbound(struct rte_mbuf
*m
, uint32_t offset
, uint32_t is_ipv6
,
46 struct ip_addr
*src
, struct ip_addr
*dst
)
48 struct ip
*inip4
, *outip4
;
49 struct ip6_hdr
*inip6
, *outip6
;
52 inip4
= rte_pktmbuf_mtod(m
, struct ip
*);
54 RTE_ASSERT(inip4
->ip_v
== IPVERSION
|| inip4
->ip_v
== IP6_VERSION
);
56 if (inip4
->ip_v
== IPVERSION
) {
57 /* XXX This should be done by the forwarding engine instead */
59 ds_ecn
= inip4
->ip_tos
;
61 inip6
= (struct ip6_hdr
*)inip4
;
62 /* XXX This should be done by the forwarding engine instead */
64 ds_ecn
= ntohl(inip6
->ip6_flow
) >> 20;
68 offset
+= sizeof(struct ip6_hdr
);
69 outip6
= (struct ip6_hdr
*)rte_pktmbuf_prepend(m
, offset
);
71 RTE_ASSERT(outip6
!= NULL
);
73 /* Per RFC4301 5.1.2.1 */
74 outip6
->ip6_flow
= htonl(IP6_VERSION
<< 28 | ds_ecn
<< 20);
75 outip6
->ip6_plen
= htons(rte_pktmbuf_data_len(m
));
77 outip6
->ip6_nxt
= IPPROTO_ESP
;
78 outip6
->ip6_hops
= IPDEFTTL
;
80 memcpy(&outip6
->ip6_src
.s6_addr
, src
, 16);
81 memcpy(&outip6
->ip6_dst
.s6_addr
, dst
, 16);
86 offset
+= sizeof(struct ip
);
87 outip4
= (struct ip
*)rte_pktmbuf_prepend(m
, offset
);
89 RTE_ASSERT(outip4
!= NULL
);
91 /* Per RFC4301 5.1.2.1 */
92 outip4
->ip_v
= IPVERSION
;
94 outip4
->ip_tos
= ds_ecn
;
95 outip4
->ip_len
= htons(rte_pktmbuf_data_len(m
));
100 outip4
->ip_ttl
= IPDEFTTL
;
101 outip4
->ip_p
= IPPROTO_ESP
;
103 outip4
->ip_src
.s_addr
= src
->ip
.ip4
;
104 outip4
->ip_dst
.s_addr
= dst
->ip
.ip4
;
109 static inline struct ip
*
110 ip4ip_outbound(struct rte_mbuf
*m
, uint32_t offset
,
111 struct ip_addr
*src
, struct ip_addr
*dst
)
113 return ipip_outbound(m
, offset
, 0, src
, dst
);
116 static inline struct ip6_hdr
*
117 ip6ip_outbound(struct rte_mbuf
*m
, uint32_t offset
,
118 struct ip_addr
*src
, struct ip_addr
*dst
)
120 return ipip_outbound(m
, offset
, 1, src
, dst
);
124 ip4_ecn_setup(struct ip
*ip4
)
126 if (ip4
->ip_tos
& IPTOS_ECN_MASK
)
127 ip4
->ip_tos
|= IPTOS_ECN_CE
;
131 ip6_ecn_setup(struct ip6_hdr
*ip6
)
133 if ((ntohl(ip6
->ip6_flow
) >> 20) & IPTOS_ECN_MASK
)
134 ip6
->ip6_flow
= htonl(ntohl(ip6
->ip6_flow
) |
135 (IPTOS_ECN_CE
<< 20));
139 ipip_inbound(struct rte_mbuf
*m
, uint32_t offset
)
141 struct ip
*inip4
, *outip4
;
142 struct ip6_hdr
*inip6
, *outip6
;
143 uint32_t ip_len
, set_ecn
;
145 outip4
= rte_pktmbuf_mtod(m
, struct ip
*);
147 RTE_ASSERT(outip4
->ip_v
== IPVERSION
|| outip4
->ip_v
== IP6_VERSION
);
149 if (outip4
->ip_v
== IPVERSION
) {
150 ip_len
= sizeof(struct ip
);
151 set_ecn
= ((outip4
->ip_tos
& IPTOS_ECN_CE
) == IPTOS_ECN_CE
);
153 outip6
= (struct ip6_hdr
*)outip4
;
154 ip_len
= sizeof(struct ip6_hdr
);
155 set_ecn
= ntohl(outip6
->ip6_flow
) >> 20;
156 set_ecn
= ((set_ecn
& IPTOS_ECN_CE
) == IPTOS_ECN_CE
);
159 inip4
= (struct ip
*)rte_pktmbuf_adj(m
, offset
+ ip_len
);
160 RTE_ASSERT(inip4
->ip_v
== IPVERSION
|| inip4
->ip_v
== IP6_VERSION
);
162 /* Check packet is still bigger than IP header (inner) */
163 RTE_ASSERT(rte_pktmbuf_pkt_len(m
) > ip_len
);
165 /* RFC4301 5.1.2.1 Note 6 */
166 if (inip4
->ip_v
== IPVERSION
) {
168 ip4_ecn_setup(inip4
);
169 /* XXX This should be done by the forwarding engine instead */
172 inip6
= (struct ip6_hdr
*)inip4
;
174 ip6_ecn_setup(inip6
);
175 /* XXX This should be done by the forwarding engine instead */
176 inip6
->ip6_hops
-= 1;
180 #endif /* __IPIP_H__ */