@@ -178,6 +178,7 @@ VLIB_NODE_FN (srv6_end_m_gtp4_e) (vlib_main_t * vm,
178178 u32 bi0 ;
179179 vlib_buffer_t * b0 ;
180180 ip6_sr_localsid_t * ls0 ;
181+ srv6_end_gtp4_param_t * ls_param ;
181182
182183 ip6srv_combo_header_t * ip6srv0 ;
183184 ip6_address_t src0 , dst0 ;
@@ -200,6 +201,8 @@ VLIB_NODE_FN (srv6_end_m_gtp4_e) (vlib_main_t * vm,
200201 pool_elt_at_index (sm2 -> localsids ,
201202 vnet_buffer (b0 )-> ip .adj_index [VLIB_TX ]);
202203
204+ ls_param = (srv6_end_gtp4_param_t * )ls0 -> plugin_mem ;
205+
203206 ip6srv0 = vlib_buffer_get_current (b0 );
204207 src0 = ip6srv0 -> ip .src_address ;
205208 dst0 = ip6srv0 -> ip .dst_address ;
@@ -245,37 +248,70 @@ VLIB_NODE_FN (srv6_end_m_gtp4_e) (vlib_main_t * vm,
245248
246249 u32 teid ;
247250 u8 * teid8p = (u8 * )& teid ;
248- u16 index ;
249- u16 offset , shift ;
251+ u32 index ;
252+ u32 offset , shift ;
250253
251- index = ls0 -> localsid_len ;
252- index += 8 ;
253-
254- offset = index / 8 ;
255- shift = index % 8 ;
254+ offset = ls0 -> localsid_len / 8 ;
255+ shift = ls0 -> localsid_len % 8 ;
256256
257257 if (PREDICT_TRUE (shift == 0 )) {
258- teid8p [0 ] = dst0 .as_u8 [offset ];
259- teid8p [1 ] = dst0 .as_u8 [offset + 1 ];
260- teid8p [2 ] = dst0 .as_u8 [offset + 2 ];
261- teid8p [3 ] = dst0 .as_u8 [offset + 3 ];
258+ for (index = 0 ; index < 4 ; index ++ ) {
259+ hdr0 -> ip4 .dst_address .as_u8 [index ] = dst0 .as_u8 [offset + index ];
260+ }
261+
262+ teid8p [0 ] = dst0 .as_u8 [offset + 5 ];
263+ teid8p [1 ] = dst0 .as_u8 [offset + 6 ];
264+ teid8p [2 ] = dst0 .as_u8 [offset + 7 ];
265+ teid8p [3 ] = dst0 .as_u8 [offset + 8 ];
262266 } else {
263- for (index = offset ; index < offset + 4 ; index ++ ) {
264- * teid8p = dst0 .as_u8 [index ] << shift ;
265- * teid8p |= dst0 .as_u8 [index + 1 ] >> (8 - shift );
267+ for (index = 0 ; index < 4 ; index ++ ) {
268+ hdr0 -> ip4 .dst_address .as_u8 [index ] = dst0 .as_u8 [offset + index ] << shift ;
269+ hdr0 -> ip4 .dst_address .as_u8 [index ] |= dst0 .as_u8 [offset + index + 1 ] >> (8 - shift );
270+ }
271+
272+ for (index = 0 ; index < 4 ; index ++ ) {
273+ * teid8p = dst0 .as_u8 [offset + 5 + index ] << shift ;
274+ * teid8p |= dst0 .as_u8 [offset + 6 + index ] >> (8 - shift );
266275 teid8p ++ ;
267276 }
268277 }
269278
270279 hdr0 -> gtpu .teid = teid ;
271280 hdr0 -> gtpu .length = clib_host_to_net_u16 (len0 );
272281
273- hdr0 -> udp .src_port = src0 .as_u16 [6 ];
282+ offset = ls_param -> local_prefixlen / 8 ;
283+ shift = ls_param -> local_prefixlen % 8 ;
284+
285+ if (PREDICT_TRUE (shift == 0 )) {
286+ u8 * pp ;
287+
288+ pp = (u8 * ) & hdr0 -> udp .src_port ;
289+
290+ for (index = 0 ; index < 4 ; index ++ ) {
291+ hdr0 -> ip4 .src_address .as_u8 [index ] = src0 .as_u8 [offset + index ];
292+ }
293+
294+ for (index = 0 ; index < 2 ; index ++ ) {
295+ pp [index ] = src0 .as_u8 [offset + 4 + index ];
296+ }
297+ } else {
298+ u8 * pp ;
299+
300+ pp = (u8 * ) & hdr0 -> udp .src_port ;
301+ for (index = 0 ; index < 4 ; index ++ ) {
302+ hdr0 -> ip4 .src_address .as_u8 [index ] = src0 .as_u8 [offset + index ] << shift ;
303+ hdr0 -> ip4 .src_address .as_u8 [index ] |= src0 .as_u8 [offset + index + 1 ] >> (8 - shift );
304+ }
305+
306+ for (index = 0 ; index < 2 ; index ++ ) {
307+ pp [index ] = src0 .as_u8 [offset + index + 4 ] << shift ;
308+ pp [index ] |= src0 .as_u8 [offset + index + 5 ] >> (8 - shift );
309+ }
310+ }
311+
274312 hdr0 -> udp .length = clib_host_to_net_u16 (len0 +
275313 sizeof (udp_header_t ) + sizeof (gtpu_header_t ));
276314
277- hdr0 -> ip4 .src_address .as_u32 = src0 .as_u32 [2 ];
278- hdr0 -> ip4 .dst_address .as_u32 = dst0 .as_u32 [1 ];
279315 hdr0 -> ip4 .length = clib_host_to_net_u16 (len0 +
280316 sizeof (ip4_gtpu_header_t ));
281317
0 commit comments