mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
synced 2025-10-23 08:22:07 +00:00
gtp: Rework gtp_resp() into gtp_resp_pdp()
gtp_resp() requires a PDP context. To support more generic messages without a PDP context, rename gtp_resp() into gtp_resp_pdp() and create a more generic function to transmit a GTP response. Will be used by the SGSN Context Req/Resp/Ack code. Change-Id: Id9ff95e0e2a10a22e65ecf42b2a2b06a0f2d1a45
This commit is contained in:
committed by
Alexander Couzens
parent
446dd65de1
commit
4b8ebcd784
57
gtp/gtp.c
57
gtp/gtp.c
@@ -131,8 +131,6 @@ const struct value_string gtp_type_names[] = {
|
|||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void emit_cb_recovery(struct gsn_t *gsn, struct sockaddr_in * peer,
|
static void emit_cb_recovery(struct gsn_t *gsn, struct sockaddr_in * peer,
|
||||||
struct pdp_t * pdp, uint8_t recovery)
|
struct pdp_t * pdp, uint8_t recovery)
|
||||||
{
|
{
|
||||||
@@ -456,9 +454,9 @@ static int gtp_conf(struct gsn_t *gsn, uint8_t version, struct sockaddr_in *peer
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
|
/* Send a GTP Response (generic call) */
|
||||||
union gtp_packet *packet, int len,
|
static int gtp_resp(struct gsn_t *gsn, union gtp_packet *packet, int len, struct sockaddr_in *peer, int fd,
|
||||||
struct sockaddr_in *peer, int fd, uint16_t seq, uint64_t tid)
|
uint16_t seq, uint64_t tid, uint16_t flow, uint32_t teidc)
|
||||||
{
|
{
|
||||||
uint8_t ver = GTPHDR_F_GET_VER(packet->flags);
|
uint8_t ver = GTPHDR_F_GET_VER(packet->flags);
|
||||||
struct qmsg_t *qmsg;
|
struct qmsg_t *qmsg;
|
||||||
@@ -467,18 +465,11 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
|
|||||||
packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
|
packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
|
||||||
packet->gtp0.h.seq = hton16(seq);
|
packet->gtp0.h.seq = hton16(seq);
|
||||||
packet->gtp0.h.tid = htobe64(tid);
|
packet->gtp0.h.tid = htobe64(tid);
|
||||||
if (pdp && ((packet->gtp0.h.type == GTP_GPDU) ||
|
packet->gtp0.h.flow = hton16(flow);
|
||||||
(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 */
|
} 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.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
|
||||||
packet->gtp1l.h.seq = hton16(seq);
|
packet->gtp1l.h.seq = hton16(seq);
|
||||||
if (pdp && (fd == gsn->fd1u))
|
packet->gtp1l.h.tei = hton32(teidc);
|
||||||
packet->gtp1l.h.tei = hton32(pdp->teid_gn);
|
|
||||||
else if (pdp)
|
|
||||||
packet->gtp1l.h.tei = hton32(pdp->teic_gn);
|
|
||||||
} else {
|
} else {
|
||||||
LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
|
LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -526,6 +517,34 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send a GTP Response which relates to a PDP Context. See gtp_resp for a more generic function */
|
||||||
|
static int gtp_resp_pdp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
|
||||||
|
union gtp_packet *packet, int len,
|
||||||
|
struct sockaddr_in *peer, int fd, uint16_t seq, uint64_t tid)
|
||||||
|
{
|
||||||
|
uint8_t ver = GTPHDR_F_GET_VER(packet->flags);
|
||||||
|
uint16_t flow = 0;
|
||||||
|
uint32_t tei = 0;
|
||||||
|
|
||||||
|
if (ver == 0) { /* Version 0 */
|
||||||
|
if (pdp && ((packet->gtp0.h.type == GTP_GPDU) ||
|
||||||
|
(packet->gtp0.h.type == GTP_ERROR)))
|
||||||
|
flow = pdp->flru;
|
||||||
|
else if (pdp)
|
||||||
|
flow = pdp->flrc;
|
||||||
|
} else if (ver == 1 && (packet->flags & GTP1HDR_F_SEQ)) { /* Version 1 with seq */
|
||||||
|
if (pdp && (fd == gsn->fd1u))
|
||||||
|
tei = pdp->teid_gn;
|
||||||
|
else if (pdp)
|
||||||
|
tei = pdp->teic_gn;
|
||||||
|
} else {
|
||||||
|
LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gtp_resp(gsn, packet, len, peer, fd, seq, tid, flow, tei);
|
||||||
|
}
|
||||||
|
|
||||||
static int gtp_notification(struct gsn_t *gsn, uint8_t version,
|
static int gtp_notification(struct gsn_t *gsn, uint8_t version,
|
||||||
union gtp_packet *packet, int len,
|
union gtp_packet *packet, int len,
|
||||||
const struct sockaddr_in *peer, int fd, uint16_t seq)
|
const struct sockaddr_in *peer, int fd, uint16_t seq)
|
||||||
@@ -650,7 +669,7 @@ static int gtp_echo_resp(struct gsn_t *gsn, int version,
|
|||||||
unsigned int length = get_default_gtp(version, GTP_ECHO_RSP, &packet);
|
unsigned int length = get_default_gtp(version, GTP_ECHO_RSP, &packet);
|
||||||
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
|
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
|
||||||
gsn->restart_counter);
|
gsn->restart_counter);
|
||||||
return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
|
return gtp_resp_pdp(version, gsn, NULL, &packet, length, peer, fd,
|
||||||
get_seq(pack), get_tid(pack));
|
get_seq(pack), get_tid(pack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1086,7 +1105,7 @@ static int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp
|
|||||||
/* TODO: Charging gateway address */
|
/* TODO: Charging gateway address */
|
||||||
}
|
}
|
||||||
|
|
||||||
return gtp_resp(version, gsn, pdp, &packet, length, &pdp->sa_peer,
|
return gtp_resp_pdp(version, gsn, pdp, &packet, length, &pdp->sa_peer,
|
||||||
pdp->fd, pdp->seq, pdp->tid);
|
pdp->fd, pdp->seq, pdp->tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1762,7 +1781,7 @@ static int gtp_update_pdp_resp(struct gsn_t *gsn, uint8_t version,
|
|||||||
pdp->dir_tun_flags.l, pdp->dir_tun_flags.v);
|
pdp->dir_tun_flags.l, pdp->dir_tun_flags.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gtp_resp(version, gsn, pdp, &packet, length, peer,
|
return gtp_resp_pdp(version, gsn, pdp, &packet, length, peer,
|
||||||
fd, seq, tid);
|
fd, seq, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2263,7 +2282,7 @@ static int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
|||||||
|
|
||||||
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
|
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
|
||||||
|
|
||||||
gtp_resp(version, gsn, pdp, &packet, length, peer, fd,
|
gtp_resp_pdp(version, gsn, pdp, &packet, length, peer, fd,
|
||||||
get_seq(pack), get_tid(pack));
|
get_seq(pack), get_tid(pack));
|
||||||
|
|
||||||
if (gtp_cause_successful(cause)) {
|
if (gtp_cause_successful(cause)) {
|
||||||
@@ -2477,7 +2496,7 @@ static int gtp_error_ind_resp(struct gsn_t *gsn, uint8_t version,
|
|||||||
sizeof(gsn->gsnu), &gsn->gsnu);
|
sizeof(gsn->gsnu), &gsn->gsnu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
|
return gtp_resp_pdp(version, gsn, NULL, &packet, length, peer, fd,
|
||||||
get_seq(pack), get_tid(pack));
|
get_seq(pack), get_tid(pack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user