lynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ggsn/+/39237?usp=email )
Change subject: gtp: split gtp_req into 2 parts: transmit and fill header ......................................................................
gtp: split gtp_req into 2 parts: transmit and fill header
Split the preparing the data from the socket and queue handling into two functions: gtp_req(): preparing the data gtp_req_transmit(): selecting socket, port and adding it to the transmit queue. In a following commit gtp_req_transmit() can be used by gtpv1 function as well.
Change-Id: Icda0ef7b0ce3631e23da88827dd54cf019878b5d --- M gtp/gtp.c 1 file changed, 47 insertions(+), 29 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ggsn refs/changes/37/39237/1
diff --git a/gtp/gtp.c b/gtp/gtp.c index c40e767..3209a64 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -339,13 +339,12 @@ * a predefined timeout. *************************************************************/
-static int gtp_req(struct gsn_t *gsn, uint8_t version, struct pdp_t *pdp, - union gtp_packet *packet, int len, - const struct in_addr *inetaddr, void *cbp) +static int gtp_req_transmit(struct gsn_t *gsn, uint8_t version, const struct in_addr *inetaddr, + union gtp_packet *packet, int len, + struct pdp_t *pdp, void *cbp) { - uint8_t ver = GTPHDR_F_GET_VER(packet->flags); - struct sockaddr_in addr; struct qmsg_t *qmsg; + struct sockaddr_in addr; int fd;
memset(&addr, 0, sizeof(addr)); @@ -355,33 +354,18 @@ addr.sin_len = sizeof(addr); #endif
- if (ver == 0) { /* Version 0 */ - addr.sin_port = htons(GTP0_PORT); - packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); - packet->gtp0.h.seq = hton16(gsn->seq_next); - if (pdp) { - packet->gtp0.h.tid = - htobe64(pdp_gettid(pdp->imsi, pdp->nsapi)); - } - if (pdp && ((packet->gtp0.h.type == GTP_GPDU) - || (packet->gtp0.h.type == GTP_ERROR))) - packet->gtp0.h.flow = hton16(pdp->flru); - else if (pdp) - packet->gtp0.h.flow = hton16(pdp->flrc); + switch (version) { + case 0: fd = gsn->fd0; - } else if (ver == 1 && (packet->flags & GTP1HDR_F_SEQ)) { /* Version 1 with seq */ + addr.sin_port = htons(GTP0_PORT); + break; + case 1: addr.sin_port = htons(GTP1C_PORT); - packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT); - packet->gtp1l.h.seq = hton16(gsn->seq_next); - if (pdp && ((packet->gtp1l.h.type == GTP_GPDU) || - (packet->gtp1l.h.type == GTP_ERROR))) - packet->gtp1l.h.tei = hton32(pdp->teid_gn); - else if (pdp) - packet->gtp1l.h.tei = hton32(pdp->teic_gn); fd = gsn->fd1c; - } else { - LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags); - return -1; + break; + default: + LOGP(DLGTP, LOGL_ERROR, "Invalid GTP version %d\n", version); + return -EINVAL; }
if (sendto(fd, packet, len, 0, @@ -420,6 +404,40 @@ return 0; }
+static int gtp_req(struct gsn_t *gsn, uint8_t version, struct pdp_t *pdp, + union gtp_packet *packet, int len, + const struct in_addr *inetaddr, void *cbp) +{ + uint8_t ver = GTPHDR_F_GET_VER(packet->flags); + + if (ver == 0) { /* Version 0 */ + packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); + packet->gtp0.h.seq = hton16(gsn->seq_next); + if (pdp) { + packet->gtp0.h.tid = + htobe64(pdp_gettid(pdp->imsi, pdp->nsapi)); + } + if (pdp && ((packet->gtp0.h.type == GTP_GPDU) + || (packet->gtp0.h.type == GTP_ERROR))) + packet->gtp0.h.flow = hton16(pdp->flru); + else if (pdp) + packet->gtp0.h.flow = hton16(pdp->flrc); + } else if (ver == 1 && (packet->flags & GTP1HDR_F_SEQ)) { /* Version 1 with seq */ + packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT); + packet->gtp1l.h.seq = hton16(gsn->seq_next); + if (pdp && ((packet->gtp1l.h.type == GTP_GPDU) || + (packet->gtp1l.h.type == GTP_ERROR))) + packet->gtp1l.h.tei = hton32(pdp->teid_gn); + else if (pdp) + packet->gtp1l.h.tei = hton32(pdp->teic_gn); + } else { + LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags); + return -1; + } + + return gtp_req_transmit(gsn, version, inetaddr, packet, len, pdp, cbp); +} + /* gtp_conf * Remove signalling packet from retransmission queue. * return 0 on success, EOF if packet was not found */