FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
udp_inlines.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SRC_VNET_UDP_UDP_INLINES_H_
17 #define SRC_VNET_UDP_UDP_INLINES_H_
18 
19 #include <vnet/vnet.h>
20 #include <vnet/ip/ip4.h>
21 #include <vnet/ip/ip6.h>
22 #include <vnet/udp/udp_packet.h>
23 #include <vnet/interface_output.h>
24 
25 always_inline void *
26 vlib_buffer_push_udp (vlib_buffer_t * b, u16 sp, u16 dp, u8 offload_csum)
27 {
28  udp_header_t *uh;
29  u16 udp_len = sizeof (udp_header_t) + b->current_length;
30  if (PREDICT_FALSE (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID))
32 
33  uh = vlib_buffer_push_uninit (b, sizeof (udp_header_t));
34  uh->src_port = sp;
35  uh->dst_port = dp;
36  uh->checksum = 0;
37  uh->length = clib_host_to_net_u16 (udp_len);
38  if (offload_csum)
39  vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_UDP_CKSUM);
40  vnet_buffer (b)->l4_hdr_offset = (u8 *) uh - b->data;
41  b->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID;
42  return uh;
43 }
44 
45 always_inline void
47 {
48  u16 new_l0;
49  udp_header_t *udp0;
50 
51  if (is_ip4)
52  {
53  ip4_header_t *ip0;
54  ip_csum_t sum0;
55  u16 old_l0 = 0;
56 
57  ip0 = vlib_buffer_get_current (b0);
58 
59  /* fix the <bleep>ing outer-IP checksum */
60  sum0 = ip0->checksum;
61  /* old_l0 always 0, see the rewrite setup */
62  new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
63 
64  sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
65  length /* changed member */ );
66  ip0->checksum = ip_csum_fold (sum0);
67  ip0->length = new_l0;
68 
69  /* Fix UDP length */
70  udp0 = (udp_header_t *) (ip0 + 1);
71  new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)
72  - sizeof (*ip0));
73  udp0->length = new_l0;
74  }
75  else
76  {
77  ip6_header_t *ip0;
78  int bogus0;
79 
80  ip0 = vlib_buffer_get_current (b0);
81 
82  new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)
83  - sizeof (*ip0));
84  ip0->payload_length = new_l0;
85 
86  /* Fix UDP length */
87  udp0 = (udp_header_t *) (ip0 + 1);
88  udp0->length = new_l0;
89 
90  udp0->checksum =
91  ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0, &bogus0);
92  ASSERT (bogus0 == 0);
93 
94  if (udp0->checksum == 0)
95  udp0->checksum = 0xffff;
96  }
97 }
98 
99 always_inline void
101  u8 is_ip4)
102 {
103  vnet_calc_checksums_inline (vm, b0, is_ip4, !is_ip4);
104 
105  vlib_buffer_advance (b0, -ec_len);
106 
107  if (is_ip4)
108  {
109  ip4_header_t *ip0;
110 
111  ip0 = vlib_buffer_get_current (b0);
112 
113  /* Apply the encap string. */
114  clib_memcpy_fast (ip0, ec0, ec_len);
115  ip_udp_fixup_one (vm, b0, 1);
116  }
117  else
118  {
119  ip6_header_t *ip0;
120 
121  ip0 = vlib_buffer_get_current (b0);
122 
123  /* Apply the encap string. */
124  clib_memcpy_fast (ip0, ec0, ec_len);
125  ip_udp_fixup_one (vm, b0, 0);
126  }
127 }
128 
129 always_inline void
131  u8 * ec0, u8 * ec1, word ec_len, u8 is_v4)
132 {
133  u16 new_l0, new_l1;
134  udp_header_t *udp0, *udp1;
135 
136  ASSERT (_vec_len (ec0) == _vec_len (ec1));
137 
138  vnet_calc_checksums_inline (vm, b0, is_v4, !is_v4);
139  vnet_calc_checksums_inline (vm, b1, is_v4, !is_v4);
140 
141  vlib_buffer_advance (b0, -ec_len);
142  vlib_buffer_advance (b1, -ec_len);
143 
144  if (is_v4)
145  {
146  ip4_header_t *ip0, *ip1;
147  ip_csum_t sum0, sum1;
148  u16 old_l0 = 0, old_l1 = 0;
149 
150  ip0 = vlib_buffer_get_current (b0);
151  ip1 = vlib_buffer_get_current (b1);
152 
153  /* Apply the encap string */
154  clib_memcpy_fast (ip0, ec0, ec_len);
155  clib_memcpy_fast (ip1, ec1, ec_len);
156 
157  /* fix the <bleep>ing outer-IP checksum */
158  sum0 = ip0->checksum;
159  sum1 = ip1->checksum;
160 
161  /* old_l0 always 0, see the rewrite setup */
162  new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
163  new_l1 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b1));
164 
165  sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
166  length /* changed member */ );
167  sum1 = ip_csum_update (sum1, old_l1, new_l1, ip4_header_t,
168  length /* changed member */ );
169 
170  ip0->checksum = ip_csum_fold (sum0);
171  ip1->checksum = ip_csum_fold (sum1);
172 
173  ip0->length = new_l0;
174  ip1->length = new_l1;
175 
176  /* Fix UDP length */
177  udp0 = (udp_header_t *) (ip0 + 1);
178  udp1 = (udp_header_t *) (ip1 + 1);
179 
180  new_l0 =
181  clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
182  sizeof (*ip0));
183  new_l1 =
184  clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b1) -
185  sizeof (*ip1));
186  udp0->length = new_l0;
187  udp1->length = new_l1;
188  }
189  else
190  {
191  ip6_header_t *ip0, *ip1;
192  int bogus0, bogus1;
193 
194  ip0 = vlib_buffer_get_current (b0);
195  ip1 = vlib_buffer_get_current (b1);
196 
197  /* Apply the encap string. */
198  clib_memcpy_fast (ip0, ec0, ec_len);
199  clib_memcpy_fast (ip1, ec1, ec_len);
200 
201  new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)
202  - sizeof (*ip0));
203  new_l1 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b1)
204  - sizeof (*ip1));
205  ip0->payload_length = new_l0;
206  ip1->payload_length = new_l1;
207 
208  /* Fix UDP length */
209  udp0 = (udp_header_t *) (ip0 + 1);
210  udp1 = (udp_header_t *) (ip1 + 1);
211 
212  udp0->length = new_l0;
213  udp1->length = new_l1;
214 
215  udp0->checksum =
216  ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0, &bogus0);
217  udp1->checksum =
218  ip6_tcp_udp_icmp_compute_checksum (vm, b1, ip1, &bogus1);
219  ASSERT (bogus0 == 0);
220  ASSERT (bogus1 == 0);
221 
222  if (udp0->checksum == 0)
223  udp0->checksum = 0xffff;
224  if (udp1->checksum == 0)
225  udp1->checksum = 0xffff;
226  }
227 }
228 
229 #endif /* SRC_VNET_UDP_UDP_INLINES_H_ */
230 
231 /*
232  * fd.io coding-style-patch-verification: ON
233  *
234  * Local Variables:
235  * eval: (c-set-style "gnu")
236  * End:
237  */
udp_header_t::src_port
u16 src_port
Definition: udp_packet.h:48
udp_header_t::length
u16 length
Definition: udp_packet.h:51
ip6_tcp_udp_icmp_compute_checksum
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
Definition: ip6_forward.c:1096
vlib_buffer_push_udp
static void * vlib_buffer_push_udp(vlib_buffer_t *b, u16 sp, u16 dp, u8 offload_csum)
Definition: udp_inlines.h:26
vnet_buffer_offload_flags_set
static_always_inline void vnet_buffer_offload_flags_set(vlib_buffer_t *b, vnet_buffer_oflags_t oflags)
Definition: buffer.h:528
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vnet_calc_checksums_inline
static_always_inline void vnet_calc_checksums_inline(vlib_main_t *vm, vlib_buffer_t *b, int is_ip4, int is_ip6)
Definition: interface_output.h:83
vlib_buffer_length_in_chain
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:433
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
ip_udp_encap_one
static void ip_udp_encap_one(vlib_main_t *vm, vlib_buffer_t *b0, u8 *ec0, word ec_len, u8 is_ip4)
Definition: udp_inlines.h:100
udp_header_t
Definition: udp_packet.h:45
ip4_header_t
Definition: ip4_packet.h:87
ip4_header_t::length
u16 length
Definition: ip4_packet.h:99
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ip_udp_encap_two
static void ip_udp_encap_two(vlib_main_t *vm, vlib_buffer_t *b0, vlib_buffer_t *b1, u8 *ec0, u8 *ec1, word ec_len, u8 is_v4)
Definition: udp_inlines.h:130
interface_output.h
udp_packet.h
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
ip4_header_t::checksum
u16 checksum
Definition: ip4_packet.h:118
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
udp_header_t::checksum
u16 checksum
Definition: udp_packet.h:55
vlib_buffer_push_uninit
static void * vlib_buffer_push_uninit(vlib_buffer_t *b, u8 size)
Prepend uninitialized data to buffer.
Definition: buffer.h:363
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
udp_header_t::dst_port
u16 dst_port
Definition: udp_packet.h:48
ip_udp_fixup_one
static void ip_udp_fixup_one(vlib_main_t *vm, vlib_buffer_t *b0, u8 is_ip4)
Definition: udp_inlines.h:46
ip6_header_t
Definition: ip6_packet.h:294
ip4.h
length
char const int length
Definition: cJSON.h:163
vlib_main_t
Definition: main.h:102
ip_csum_update
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:295
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip_csum_t
uword ip_csum_t
Definition: ip_packet.h:245
vlib_buffer_t::data
u8 data[]
Packet data.
Definition: buffer.h:204
word
i64 word
Definition: types.h:111
vnet.h
ip6_header_t::payload_length
u16 payload_length
Definition: ip6_packet.h:301
vlib_buffer_t::total_length_not_including_first_buffer
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
Definition: buffer.h:176
ip6.h
ip_csum_fold
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:301
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111