Line data Source code
1 : /*
2 : * tunnel_dp.h: data-plane functions tunnels.
3 : *
4 : * Copyright (c) 2019 Cisco and/or its affiliates.
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at:
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #ifndef __TUNNEL_DP_H__
19 : #define __TUNNEL_DP_H__
20 :
21 : #include <vnet/tunnel/tunnel.h>
22 : #include <vnet/mpls/mpls_lookup.h>
23 :
24 : static_always_inline void
25 16636 : tunnel_encap_fixup_4o4 (tunnel_encap_decap_flags_t flags,
26 : const ip4_header_t * inner, ip4_header_t * outer)
27 : {
28 16636 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
29 791 : ip4_header_set_dscp (outer, ip4_header_get_dscp (inner));
30 16636 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
31 761 : ip4_header_set_ecn (outer, ip4_header_get_ecn (inner));
32 16636 : if (PREDICT_FALSE ((flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DF) &&
33 : ip4_header_get_df (inner)))
34 63 : ip4_header_set_df (outer);
35 16636 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT))
36 0 : ip4_header_set_ttl (outer, ip4_header_get_ttl (inner));
37 16636 : }
38 :
39 : static_always_inline void
40 37431 : tunnel_encap_fixup_4o4_w_chksum (tunnel_encap_decap_flags_t flags,
41 : const ip4_header_t * inner,
42 : ip4_header_t * outer)
43 : {
44 37431 : if (PREDICT_FALSE (flags & (TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP |
45 : TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)))
46 : {
47 130 : ip_csum_t sum = outer->checksum;
48 130 : u8 tos = outer->tos;
49 :
50 130 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
51 130 : ip4_header_set_dscp (outer, ip4_header_get_dscp (inner));
52 130 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)
53 0 : ip4_header_set_ecn (outer, ip4_header_get_ecn (inner));
54 :
55 : sum =
56 130 : ip_csum_update (outer->checksum, tos, outer->tos, ip4_header_t, tos);
57 130 : outer->checksum = ip_csum_fold (sum);
58 : }
59 37431 : if (PREDICT_FALSE ((flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DF) &&
60 : ip4_header_get_df (inner)))
61 : {
62 0 : ip_csum_t sum = outer->checksum;
63 0 : u16 tos = outer->flags_and_fragment_offset;
64 :
65 0 : ip4_header_set_df (outer);
66 :
67 : sum =
68 0 : ip_csum_update (outer->checksum, tos, outer->tos, ip4_header_t,
69 : flags_and_fragment_offset);
70 0 : outer->checksum = ip_csum_fold (sum);
71 : }
72 37431 : }
73 :
74 : static_always_inline void
75 127 : tunnel_encap_fixup_mplso4_w_chksum (tunnel_encap_decap_flags_t flags,
76 : const mpls_unicast_header_t *inner,
77 : ip4_header_t *outer)
78 : {
79 127 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
80 : {
81 0 : ip_csum_t sum = outer->checksum;
82 0 : u8 tos = outer->tos;
83 :
84 0 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
85 0 : ip4_header_set_dscp (outer,
86 0 : vnet_mpls_uc_get_exp (inner->label_exp_s_ttl));
87 :
88 : sum =
89 0 : ip_csum_update (outer->checksum, tos, outer->tos, ip4_header_t, tos);
90 0 : outer->checksum = ip_csum_fold (sum);
91 : }
92 127 : }
93 :
94 : static_always_inline void
95 1829 : tunnel_encap_fixup_6o4 (tunnel_encap_decap_flags_t flags,
96 : const ip6_header_t * inner, ip4_header_t * outer)
97 : {
98 1829 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
99 504 : ip4_header_set_dscp (outer, ip6_dscp_network_order (inner));
100 1829 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
101 504 : ip4_header_set_ecn (outer, ip6_ecn_network_order ((inner)));
102 1829 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT))
103 0 : ip4_header_set_ttl (outer, ip6_hop_limit_network_order (inner));
104 1829 : }
105 :
106 : static_always_inline void
107 190 : tunnel_encap_fixup_6o4_w_chksum (tunnel_encap_decap_flags_t flags,
108 : const ip6_header_t * inner,
109 : ip4_header_t * outer)
110 : {
111 190 : if (PREDICT_FALSE (flags & (TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP |
112 : TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)))
113 : {
114 0 : ip_csum_t sum = outer->checksum;
115 0 : u8 tos = outer->tos;
116 :
117 0 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
118 0 : ip4_header_set_dscp (outer, ip6_dscp_network_order (inner));
119 0 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)
120 0 : ip4_header_set_ecn (outer, ip6_ecn_network_order ((inner)));
121 :
122 : sum =
123 0 : ip_csum_update (outer->checksum, tos, outer->tos, ip4_header_t, tos);
124 0 : outer->checksum = ip_csum_fold (sum);
125 : }
126 190 : }
127 :
128 : static_always_inline void
129 41228 : tunnel_encap_fixup_6o6 (tunnel_encap_decap_flags_t flags,
130 : const ip6_header_t * inner, ip6_header_t * outer)
131 : {
132 41228 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
133 5648 : ip6_set_dscp_network_order (outer, ip6_dscp_network_order (inner));
134 41228 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
135 1022 : ip6_set_ecn_network_order (outer, ip6_ecn_network_order (inner));
136 41228 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_FLOW_LABEL))
137 127 : ip6_set_flow_label_network_order (outer,
138 : ip6_flow_label_network_order (inner));
139 41228 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT))
140 508 : ip6_set_hop_limit_network_order (outer,
141 508 : ip6_hop_limit_network_order (inner));
142 41228 : }
143 :
144 : static_always_inline void
145 1902 : tunnel_encap_fixup_4o6 (tunnel_encap_decap_flags_t flags,
146 : const vlib_buffer_t *b, const ip4_header_t *inner,
147 : ip6_header_t *outer)
148 : {
149 1902 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
150 504 : ip6_set_dscp_network_order (outer, ip4_header_get_dscp (inner));
151 1902 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
152 504 : ip6_set_ecn_network_order (outer, ip4_header_get_ecn (inner));
153 1902 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT))
154 127 : ip6_set_hop_limit_network_order (outer, ip4_header_get_ttl (inner));
155 1902 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_FLOW_LABEL))
156 0 : ip6_set_flow_label_network_order (
157 0 : outer, (0 != vnet_buffer (b)->ip.flow_hash ?
158 0 : vnet_buffer (b)->ip.flow_hash :
159 0 : ip4_compute_flow_hash (inner, IP_FLOW_HASH_DEFAULT)));
160 1902 : }
161 :
162 : static_always_inline void
163 190 : tunnel_encap_fixup_mplso6 (tunnel_encap_decap_flags_t flags,
164 : const vlib_buffer_t *b,
165 : const mpls_unicast_header_t *inner,
166 : ip6_header_t *outer)
167 : {
168 190 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
169 0 : ip6_set_dscp_network_order (outer,
170 0 : vnet_mpls_uc_get_exp (inner->label_exp_s_ttl));
171 190 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_FLOW_LABEL))
172 0 : ip6_set_flow_label_network_order (
173 0 : outer, (0 != vnet_buffer (b)->ip.flow_hash ?
174 0 : vnet_buffer (b)->ip.flow_hash :
175 0 : mpls_compute_flow_hash (inner, IP_FLOW_HASH_DEFAULT)));
176 190 : }
177 :
178 : static_always_inline void
179 63 : tunnel_encap_fixup_mplso4 (tunnel_encap_decap_flags_t flags,
180 : const mpls_unicast_header_t *inner,
181 : ip4_header_t *outer)
182 : {
183 63 : if (flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
184 0 : ip4_header_set_dscp (outer, vnet_mpls_uc_get_exp (inner->label_exp_s_ttl));
185 63 : }
186 :
187 : static_always_inline void
188 515 : tunnel_decap_fixup_4o6 (tunnel_encap_decap_flags_t flags,
189 : ip4_header_t * inner, const ip6_header_t * outer)
190 : {
191 515 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_DECAP_COPY_ECN))
192 252 : ip4_header_set_ecn_w_chksum (inner, ip6_ecn_network_order (outer));
193 515 : }
194 :
195 : static_always_inline void
196 1881 : tunnel_decap_fixup_6o6 (tunnel_encap_decap_flags_t flags,
197 : ip6_header_t * inner, const ip6_header_t * outer)
198 : {
199 1881 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_DECAP_COPY_ECN))
200 252 : ip6_set_ecn_network_order (inner, ip6_ecn_network_order (outer));
201 1881 : }
202 :
203 : static_always_inline void
204 584 : tunnel_decap_fixup_6o4 (tunnel_encap_decap_flags_t flags,
205 : ip6_header_t * inner, const ip4_header_t * outer)
206 : {
207 584 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_DECAP_COPY_ECN))
208 252 : ip6_set_ecn_network_order (inner, ip4_header_get_ecn (outer));
209 584 : }
210 :
211 : static_always_inline void
212 2636 : tunnel_decap_fixup_4o4 (tunnel_encap_decap_flags_t flags,
213 : ip4_header_t * inner, const ip4_header_t * outer)
214 : {
215 2636 : if (PREDICT_FALSE (flags & TUNNEL_ENCAP_DECAP_FLAG_DECAP_COPY_ECN))
216 252 : ip4_header_set_ecn_w_chksum (inner, ip4_header_get_ecn (outer));
217 2636 : }
218 :
219 : static_always_inline void
220 63 : tunnel_decap_fixup_mplso6 (tunnel_encap_decap_flags_t flags,
221 : mpls_unicast_header_t *inner,
222 : const ip6_header_t *outer)
223 : {
224 63 : }
225 :
226 : static_always_inline void
227 63 : tunnel_decap_fixup_mplso4 (tunnel_encap_decap_flags_t flags,
228 : mpls_unicast_header_t *inner,
229 : const ip4_header_t *outer)
230 : {
231 63 : }
232 :
233 : #endif
234 :
235 : /*
236 : * fd.io coding-style-patch-verification: ON
237 : *
238 : * Local Variables:
239 : * eval: (c-set-style "gnu")
240 : * End:
241 : */
|