aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schultz <andreas.schultz@travelping.com>2018-07-17 11:34:20 +0200
committerFlorin Coras <florin.coras@gmail.com>2018-07-18 04:39:56 +0000
commitd6dfd002328676eddda3b90bf46af0128a119b75 (patch)
treed31469567aa4a7394df630c7490e8b83beda1e44
parent96cc67dd80e7fbf56071925afff056929965af6d (diff)
Fix GTP-U length header field in encoding
The length in the GTPU header does not specify the length of the payload. It does specify the number of bytes following the fixed part (the first 8 bytes) of the GTPU header (see 3GPP TS 29.060, Sect. 9.3.1). Change-Id: I8ce73df015e1cf1f38d306666962c0058756111c Signed-off-by: Andreas Schultz <andreas.schultz@travelping.com>
-rw-r--r--src/plugins/gtpu/gtpu.h4
-rw-r--r--src/plugins/gtpu/gtpu_encap.c30
2 files changed, 23 insertions, 11 deletions
diff --git a/src/plugins/gtpu/gtpu.h b/src/plugins/gtpu/gtpu.h
index 6331aa31890..05208755d8c 100644
--- a/src/plugins/gtpu/gtpu.h
+++ b/src/plugins/gtpu/gtpu.h
@@ -55,13 +55,15 @@ typedef struct
{
u8 ver_flags;
u8 type;
- u16 length; /* length in octets of the payload */
+ u16 length; /* length in octets of the data following the fixed part of the header */
u32 teid;
u16 sequence;
u8 pdu_number;
u8 next_ext_type;
} gtpu_header_t;
+#define GTPU_V1_HDR_LEN 8
+
#define GTPU_VER_MASK (7<<5)
#define GTPU_PT_BIT (1<<4)
#define GTPU_E_BIT (1<<2)
diff --git a/src/plugins/gtpu/gtpu_encap.c b/src/plugins/gtpu/gtpu_encap.c
index 5c37f4db306..4442c42ad66 100644
--- a/src/plugins/gtpu/gtpu_encap.c
+++ b/src/plugins/gtpu/gtpu_encap.c
@@ -298,19 +298,23 @@ gtpu_encap_inline (vlib_main_t * vm,
/* Fix GTPU length */
gtpu0 = (gtpu_header_t *)(udp0+1);
new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b0)
- - sizeof (*ip4_0) - sizeof(*udp0));
+ - sizeof (*ip4_0) - sizeof(*udp0)
+ - GTPU_V1_HDR_LEN);
gtpu0->length = new_l0;
gtpu1 = (gtpu_header_t *)(udp1+1);
new_l1 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b1)
- - sizeof (*ip4_1) - sizeof(*udp1));
+ - sizeof (*ip4_1) - sizeof(*udp1)
+ - GTPU_V1_HDR_LEN);
gtpu1->length = new_l1;
gtpu2 = (gtpu_header_t *)(udp2+1);
new_l2 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b2)
- - sizeof (*ip4_2) - sizeof(*udp2));
+ - sizeof (*ip4_2) - sizeof(*udp2)
+ - GTPU_V1_HDR_LEN);
gtpu2->length = new_l2;
gtpu3 = (gtpu_header_t *)(udp3+1);
new_l3 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b3)
- - sizeof (*ip4_3) - sizeof(*udp3));
+ - sizeof (*ip4_3) - sizeof(*udp3)
+ - GTPU_V1_HDR_LEN);
gtpu3->length = new_l3;
}
else /* ipv6 */
@@ -397,19 +401,23 @@ gtpu_encap_inline (vlib_main_t * vm,
/* Fix GTPU length */
gtpu0 = (gtpu_header_t *)(udp0+1);
new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b0)
- - sizeof (*ip4_0) - sizeof(*udp0));
+ - sizeof (*ip6_0) - sizeof(*udp0)
+ - GTPU_V1_HDR_LEN);
gtpu0->length = new_l0;
gtpu1 = (gtpu_header_t *)(udp1+1);
new_l1 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b1)
- - sizeof (*ip4_1) - sizeof(*udp1));
+ - sizeof (*ip6_1) - sizeof(*udp1)
+ - GTPU_V1_HDR_LEN);
gtpu1->length = new_l1;
gtpu2 = (gtpu_header_t *)(udp2+1);
new_l2 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b2)
- - sizeof (*ip4_2) - sizeof(*udp2));
+ - sizeof (*ip6_2) - sizeof(*udp2)
+ - GTPU_V1_HDR_LEN);
gtpu2->length = new_l2;
gtpu3 = (gtpu_header_t *)(udp3+1);
new_l3 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b3)
- - sizeof (*ip4_3) - sizeof(*udp3));
+ - sizeof (*ip6_3) - sizeof(*udp3)
+ - GTPU_V1_HDR_LEN);
gtpu3->length = new_l3;
}
@@ -556,7 +564,8 @@ gtpu_encap_inline (vlib_main_t * vm,
/* Fix GTPU length */
gtpu0 = (gtpu_header_t *)(udp0+1);
new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b0)
- - sizeof (*ip4_0) - sizeof(*udp0));
+ - sizeof (*ip4_0) - sizeof(*udp0)
+ - GTPU_V1_HDR_LEN);
gtpu0->length = new_l0;
}
@@ -592,7 +601,8 @@ gtpu_encap_inline (vlib_main_t * vm,
/* Fix GTPU length */
gtpu0 = (gtpu_header_t *)(udp0+1);
new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain(vm, b0)
- - sizeof (*ip4_0) - sizeof(*udp0));
+ - sizeof (*ip4_0) - sizeof(*udp0)
+ - GTPU_V1_HDR_LEN);
gtpu0->length = new_l0;
}