diff options
author | Harald Welte <laforge@gnumonks.org> | 2017-09-24 16:40:12 +0800 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-09-24 23:10:01 +0800 |
commit | 3c1cce245e6ed1746c0eacc6208b884871186d3d (patch) | |
tree | 69550dcaac59f82f4c66f0c722e7dad5325485d5 /gtp | |
parent | 00d346092be0b9d948f687efb4b20a0727019b71 (diff) |
libgtp: Allow each PDP context to specify if it transmits G-PDU sequence numbers
GTP sequence numbers on GTP-U are optional for G-PDU type messages (i.e.
user-ip messages). Let's allow the user to specify this behavior by
a new pdu_t.tx_gpdu_seq flag. The flag is enabled by default to stay
compatible with the prior behaviour.
Related: OS#2519
Change-Id: Icf22a2ddd5c4a968ef5bda7c202b921d93fb49e6
Diffstat (limited to 'gtp')
-rw-r--r-- | gtp/gtp.c | 22 | ||||
-rw-r--r-- | gtp/pdp.c | 2 | ||||
-rw-r--r-- | gtp/pdp.h | 4 |
3 files changed, 22 insertions, 6 deletions
@@ -3186,20 +3186,30 @@ int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len) get_default_gtp(0, GTP_GPDU, &packet); packet.gtp0.h.length = hton16(len); - packet.gtp0.h.seq = hton16(pdp->gtpsntx++); + if (pdp->tx_gpdu_seq) + packet.gtp0.h.seq = hton16(pdp->gtpsntx++); + else + packet.gtp0.h.seq = 0; packet.gtp0.h.flow = hton16(pdp->flru); packet.gtp0.h.tid = htobe64(pdp_gettid(pdp->imsi, pdp->nsapi)); } else if (pdp->version == 1) { - iov[0].iov_len = GTP1_HEADER_SIZE_LONG; addr.sin_port = htons(GTP1U_PORT); fd = gsn->fd1u; get_default_gtp(1, GTP_GPDU, &packet); - packet.gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT + - GTP1_HEADER_SIZE_LONG); - packet.gtp1l.h.seq = hton16(pdp->gtpsntx++); - packet.gtp1l.h.tei = hton32(pdp->teid_gn); + if (pdp->tx_gpdu_seq) { + packet.gtp1l.h.seq = hton16(pdp->gtpsntx++); + packet.gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT + + GTP1_HEADER_SIZE_LONG); + packet.gtp1l.h.tei = hton32(pdp->teid_gn); + iov[0].iov_len = GTP1_HEADER_SIZE_LONG; + } else { + packet.gtp1s.h.flags &= ~GTP1HDR_F_SEQ; + packet.gtp1s.h.length = hton16(len); + packet.gtp1s.h.tei = hton32(pdp->teid_gn); + iov[0].iov_len = GTP1_HEADER_SIZE_SHORT; + } } else { LOGP(DLGTP, LOGL_ERROR, "Unknown version: %d\n", pdp->version); return EOF; @@ -149,6 +149,8 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi, 1].secondary_tei[(*pdp)->nsapi & 0x0f] = (*pdp)->teid_own; } + /* Default: Generate G-PDU sequence numbers on Tx */ + (*pdp)->tx_gpdu_seq = true; return 0; } @@ -13,6 +13,8 @@ #ifndef _PDP_H #define _PDP_H +#include <stdbool.h> + struct gsn_t; #define PDP_MAX 1024 /* Max number of PDP contexts */ @@ -226,6 +228,8 @@ struct pdp_t { void *priv; struct gsn_t *gsn; + + bool tx_gpdu_seq; /* Transmit (true) or suppress G-PDU sequence numbers */ }; /* functions related to pdp_t management */ |