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
This commit is contained in:
Harald Welte 2017-09-24 16:40:12 +08:00
parent 00d346092b
commit 3c1cce245e
4 changed files with 23 additions and 6 deletions

View File

@ -7,3 +7,4 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
libgtp pdp.h Addition of new tx_gpdu_seq struct member member

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */