Use rate_ctr for gsn_t available_counters

This way they can be inspected with regular osmocom means.

Change-Id: I529305b4f824600c6e733a3c0d2c2c6673f99faf
This commit is contained in:
Pau Espin 2022-11-02 18:17:56 +01:00
parent 724ecc6680
commit b9036af7ca
3 changed files with 172 additions and 132 deletions

View File

@ -25,6 +25,8 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/rate_ctr.h>
#if defined(__FreeBSD__)
#include <sys/endian.h>
@ -72,6 +74,37 @@
inet_ntoa((addr).sin_addr), htons((addr).sin_port), \
##args);
static const struct rate_ctr_desc gsn_ctr_description[] = {
[GSN_CTR_ERR_SOCKET] = { "err:socket", "Socket error" },
[GSN_CTR_ERR_READFROM] = { "err:readfrom", "readfrom() errors" },
[GSN_CTR_ERR_SENDTO] = { "err:sendto", "sendto() errors" },
[GSN_CTR_ERR_QUEUEFULL] = { "err:queuefull", "Failed to queue message because queue is full" },
[GSN_CTR_ERR_SEQ] = { "err:seq", "Sequence number out of range" },
[GSN_CTR_ERR_ADDRESS] = { "err:address", "GSN address conversion failed" },
[GSN_CTR_ERR_UNKNOWN_PDP] = { "err:unknown_pdp", "Failed looking up PDP context" },
[GSN_CTR_ERR_UNEXPECTED_CAUSE] = { "err:unexpected_cause", "Unexpected cause value received" },
[GSN_CTR_ERR_OUT_OF_PDP] = { "err:out_of_pdp", "Out of storage for PDP contexts" },
[GSN_CTR_PKT_EMPTY] = { "pkt:empty", "Empty packet received" },
[GSN_CTR_PKT_UNSUP] = { "pkt:unsupported", "Unsupported GTP version received" },
[GSN_CTR_PKT_TOOSHORT] = { "pkt:too_short", "Packet too short received" },
[GSN_CTR_PKT_UNKNOWN] = { "pkt:unknown", "Unknown packet type received" },
[GSN_CTR_PKT_UNEXPECT] = { "pkt:unexpected", "Unexpected packet type received" },
[GSN_CTR_PKT_DUPLICATE] = { "pkt:duplicate", "Duplicate or unsolicited packet received" },
[GSN_CTR_PKT_MISSING] = { "pkt:missing", "Missing IE in packet received" },
[GSN_CTR_PKT_INCORRECT] = { "pkt:incorrect", "Incorrect IE in packet received" },
[GSN_CTR_PKT_INVALID] = { "pkt:invalid", "Invalid format in packet received" },
};
static const struct rate_ctr_group_desc gsn_ctrg_desc = {
"gsn",
"GSN Statistics",
OSMO_STATS_CLASS_PEER,
ARRAY_SIZE(gsn_ctr_description),
gsn_ctr_description,
};
static unsigned int gsn_ctr_next_idx = 0;
/* API Functions */
/* Deprecated, use gtp_pdp_newpdp() instead */
@ -226,7 +259,7 @@ static int queue_timer_retrans(struct gsn_t *gsn)
if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
(struct sockaddr *)&qmsg->peer,
sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"Sendto(fd0=%d, msg=%lx, len=%d) failed: Error = %s\n",
gsn->fd0, (unsigned long)&qmsg->p,
@ -401,6 +434,9 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
/* Initialize internal queue timer */
osmo_timer_setup(&(*gsn)->queue_timer, queue_timer_cb, *gsn);
/* Initialize counter group: */
(*gsn)->ctrg = rate_ctr_group_alloc(NULL, &gsn_ctrg_desc, gsn_ctr_next_idx++);
/* Initialise call back functions */
(*gsn)->cb_create_context_ind = 0;
(*gsn)->cb_delete_context = 0;
@ -415,7 +451,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
/* Create GTP version 0 socket */
if (((*gsn)->fd0 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP(DLGTP, LOGL_ERROR,
"GTPv0 socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
AF_INET, SOCK_DGRAM, 0, strerror(errno));
@ -431,7 +467,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
#endif
if (bind((*gsn)->fd0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
"bind(fd0=%d) failed: Error = %s\n",
(*gsn)->fd0, strerror(errno));
@ -440,7 +476,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
/* Create GTP version 1 control plane socket */
if (((*gsn)->fd1c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP(DLGTP, LOGL_ERROR,
"GTPv1 control plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
AF_INET, SOCK_DGRAM, 0, strerror(errno));
@ -456,7 +492,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
#endif
if (bind((*gsn)->fd1c, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
"bind(fd1c=%d) failed: Error = %s\n",
(*gsn)->fd1c, strerror(errno));
@ -465,7 +501,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
/* Create GTP version 1 user plane socket */
if (((*gsn)->fd1u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP(DLGTP, LOGL_ERROR,
"GTPv1 user plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
AF_INET, SOCK_DGRAM, 0, strerror(errno));
@ -481,7 +517,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
#endif
if (bind((*gsn)->fd1u, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
(*gsn)->err_socket++;
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
"bind(fd1u=%d) failed: Error = %s\n",
(*gsn)->fd1u, strerror(errno));
@ -508,6 +544,8 @@ int gtp_free(struct gsn_t *gsn)
close(gsn->fd1c);
close(gsn->fd1u);
rate_ctr_group_free(gsn->ctrg);
free(gsn);
return 0;
}

View File

@ -15,6 +15,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
#include "pdp.h"
@ -38,6 +39,27 @@
* each pdp context. This is stored in another struct.
*************************************************************/
enum gsn_rate_ctr_keys {
GSN_CTR_ERR_SOCKET,
GSN_CTR_ERR_READFROM, /* Number of readfrom errors */
GSN_CTR_ERR_SENDTO, /* Number of sendto errors */
GSN_CTR_ERR_QUEUEFULL, /* Number of times queue was full */
GSN_CTR_ERR_SEQ, /* Number of seq out of range */
GSN_CTR_ERR_ADDRESS, /* GSN address conversion failed */
GSN_CTR_ERR_UNKNOWN_PDP, /* GSN address conversion failed */
GSN_CTR_ERR_UNEXPECTED_CAUSE, /* Unexpected cause value received */
GSN_CTR_ERR_OUT_OF_PDP, /* Out of storage for PDP contexts */
GSN_CTR_PKT_EMPTY, /* Number of empty packets */
GSN_CTR_PKT_UNSUP, /* Number of unsupported version 29.60 11.1.1 */
GSN_CTR_PKT_TOOSHORT, /* Number of too short headers 29.60 11.1.2 */
GSN_CTR_PKT_UNKNOWN, /* Number of unknown messages 29.60 11.1.3 */
GSN_CTR_PKT_UNEXPECT, /* Number of unexpected messages 29.60 11.1.4 */
GSN_CTR_PKT_DUPLICATE, /* Number of duplicate or unsolicited replies */
GSN_CTR_PKT_MISSING, /* Number of missing information field messages */
GSN_CTR_PKT_INCORRECT, /* Number of incorrect information field messages */
GSN_CTR_PKT_INVALID, /* Number of invalid message format messages */
};
struct gsn_t {
/* Parameters related to the network interface */
@ -77,28 +99,7 @@ struct gsn_t {
int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
/* Counters */
uint64_t err_socket; /* Number of socket errors */
uint64_t err_readfrom; /* Number of readfrom errors */
uint64_t err_sendto; /* Number of sendto errors */
uint64_t err_memcpy; /* Number of memcpy */
uint64_t err_queuefull; /* Number of times queue was full */
uint64_t err_seq; /* Number of seq out of range */
uint64_t err_address; /* GSN address conversion failed */
uint64_t err_unknownpdp; /* GSN address conversion failed */
uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */
uint64_t err_cause; /* Unexpected cause value received */
uint64_t err_outofpdp; /* Out of storage for PDP contexts */
uint64_t empty; /* Number of empty packets */
uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */
uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */
uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */
uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */
uint64_t duplicate; /* Number of duplicate or unsolicited replies */
uint64_t missing; /* Number of missing information field messages */
uint64_t incorrect; /* Number of incorrect information field messages */
uint64_t invalid; /* Number of invalid message format messages */
struct rate_ctr_group *ctrg;
};
/* External API functions */

207
gtp/gtp.c
View File

@ -388,7 +388,7 @@ static int gtp_req(struct gsn_t *gsn, uint8_t version, struct pdp_t *pdp,
if (sendto(fd, packet, len, 0,
(struct sockaddr *)&addr, sizeof(addr)) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR, "Sendto(fd=%d, msg=%lx, len=%d, dst=%s) failed: Error = %s\n", fd,
(unsigned long)&packet, len, inet_ntoa(addr.sin_addr), strerror(errno));
return -1;
@ -396,7 +396,7 @@ static int gtp_req(struct gsn_t *gsn, uint8_t version, struct pdp_t *pdp,
/* Use new queue structure */
if (queue_newmsg(gsn->queue_req, &qmsg, &addr, gsn->seq_next)) {
gsn->err_queuefull++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_QUEUEFULL);
LOGP(DLGTP, LOGL_ERROR, "Retransmit req queue is full (seq=%" PRIu16 ")\n",
gsn->seq_next);
} else {
@ -444,7 +444,7 @@ static int gtp_conf(struct gsn_t *gsn, uint8_t version, struct sockaddr_in *peer
"Freeing seq=%" PRIu16 " from retransmit req queue\n",
seq);
if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, cbp)) {
gsn->err_seq++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SEQ);
GTP_LOGPKG(LOGL_ERROR, peer, packet, len,
"Confirmation packet not found in retransmit req queue (seq=%"
PRIu16 ")\n", seq);
@ -489,7 +489,7 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
if (sendto(fd, packet, len, 0,
(struct sockaddr *)peer, sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
(unsigned long)&packet, len, strerror(errno));
@ -498,7 +498,7 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
/* Use new queue structure */
if (queue_newmsg(gsn->queue_resp, &qmsg, peer, seq)) {
gsn->err_queuefull++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_QUEUEFULL);
LOGP(DLGTP, LOGL_ERROR, "Retransmit resp queue is full (seq=%" PRIu16 ")\n",
seq);
} else {
@ -558,7 +558,7 @@ static int gtp_notification(struct gsn_t *gsn, uint8_t version,
if (sendto(fd, packet, len, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
(unsigned long)&packet, len, strerror(errno));
@ -582,6 +582,7 @@ static int gtp_duplicate(struct gsn_t *gsn, uint8_t version,
inet_ntop(AF_INET, &peer->sin_addr, buf, sizeof(buf));
LOGP(DLGTP, LOGL_INFO,
"Rx duplicate seq=%" PRIu16 " from %s, retrans resp\n", seq, buf);
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_DUPLICATE);
if (fcntl(qmsg->fd, F_SETFL, 0)) {
LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
@ -590,7 +591,7 @@ static int gtp_duplicate(struct gsn_t *gsn, uint8_t version,
if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
(struct sockaddr *)peer, sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n",
qmsg->fd, (unsigned long)&qmsg->p, qmsg->l,
@ -678,7 +679,7 @@ int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
/* Extract information elements into a pointer array */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (gsn->cb_conf)
@ -687,7 +688,7 @@ int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
}
if (gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory field\n");
if (gsn->cb_conf)
@ -785,7 +786,7 @@ static int gtp_ran_info_relay_ind(struct gsn_t *gsn, int version, struct sockadd
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format (AN Information Relay)\n");
return -EINVAL;
@ -1097,7 +1098,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (0 == version)
@ -1117,7 +1118,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* Find the primary PDP context */
if (gtp_pdp_getgtp1(gsn, &linked_pdp, get_tei(pack))) {
gsn->incorrect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INCORRECT);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Incorrect optional information field\n");
@ -1127,7 +1128,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* Check that the primary PDP context matches linked nsapi */
if (linked_pdp->nsapi != linked_nsapi) {
gsn->incorrect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INCORRECT);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Incorrect optional information field\n");
@ -1152,7 +1153,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
included in the message. */
if (gtpie_gettv0
(ie, GTPIE_IMSI, 0, &pdp->imsi, sizeof(pdp->imsi))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing IMSI not supported\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1162,7 +1163,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* TEID (mandatory) */
if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1171,7 +1172,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* TEIC (conditional) */
if (!linked_pdp) { /* Not Secondary PDP Context Activation Procedure */
if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing mandatory information field\n");
@ -1181,7 +1182,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
}
/* NSAPI (mandatory) */
if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1190,7 +1191,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* QoS (mandatory) */
if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
&pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1205,21 +1206,21 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
case 0:
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
pdp->qos_req0, sizeof(pdp->qos_req0))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1231,7 +1232,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* SGSN address for signalling (mandatory) */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
&pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1241,7 +1242,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* SGSN address for user traffic (mandatory) */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
&pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1257,7 +1258,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* Selection mode (conditional) */
if (gtpie_gettv0(ie, GTPIE_SELECTION_MODE, 0,
&pdp->selmode, sizeof(pdp->selmode))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1266,7 +1267,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* End User Address (conditional) */
if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
&pdp->eua.v, sizeof(pdp->eua.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1275,7 +1276,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* APN */
if (gtpie_gettlv(ie, GTPIE_APN, 0, &pdp->apn_req.l,
&pdp->apn_req.v, sizeof(pdp->apn_req.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1288,7 +1289,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
/* MSISDN (conditional) */
if (gtpie_gettlv(ie, GTPIE_MSISDN, 0, &pdp->msisdn.l,
&pdp->msisdn.v, sizeof(pdp->msisdn.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_create_pdp_resp(gsn, version, pdp,
@ -1406,7 +1407,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: %u\n", get_tei(pack));
if (gsn->cb_conf)
@ -1416,7 +1417,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (gsn->cb_conf)
@ -1426,7 +1427,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
/* Extract cause value (mandatory) */
if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
if (gsn->cb_conf)
@ -1451,7 +1452,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
&pdp->qos_neg0,
sizeof(pdp->qos_neg0))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1462,7 +1463,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
}
if (gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len,
"Missing conditional information field\n");
@ -1473,7 +1474,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (version == 0) {
if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1483,7 +1484,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
}
if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1495,7 +1496,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (version == 1) {
if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1505,7 +1506,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
}
if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1518,7 +1519,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
}
if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len,
"Missing conditional information field\n");
@ -1528,7 +1529,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
&pdp->eua.v, sizeof(pdp->eua.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len,
"Missing conditional information field\n");
@ -1539,7 +1540,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
&pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len,
"Missing conditional information field\n");
@ -1550,7 +1551,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
&pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len,
"Missing conditional information field\n");
@ -1563,7 +1564,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
if (gtpie_gettlv
(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_neg.l,
&pdp->qos_neg.v, sizeof(pdp->qos_neg.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len,
"Missing conditional information field\n");
@ -1739,7 +1740,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (0 == version)
@ -1757,7 +1758,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
if (version == 0) {
/* Find the context in question */
if (gtp_pdp_tidget(gsn, &pdp, get_tid(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TID=0x%" PRIx64 "\n",
get_tid(pack));
@ -1771,7 +1772,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
} else if (version == 1) {
/* NSAPI (mandatory) */
if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
@ -1783,7 +1784,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
if (gtpie_gettv0(ie, GTPIE_IMSI, 0, &imsi, sizeof(imsi))) {
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
@ -1794,7 +1795,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
} else {
/* Find the context in question */
if (gtp_pdp_getimsi(gsn, &pdp, imsi, nsapi)) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: IMSI=0x%" PRIx64
" NSAPI=%" PRIu8 "\n", imsi, nsapi);
@ -1814,7 +1815,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
if (version == 0) {
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
pdp->qos_req0, sizeof(pdp->qos_req0))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1831,7 +1832,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
if (version == 0) {
if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1841,7 +1842,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
}
if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1854,7 +1855,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
if (version == 1) {
/* TEID (mandatory) */
if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1871,7 +1872,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* NSAPI (mandatory) */
if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1887,7 +1888,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* End User Address (conditional) TODO: GGSN Initiated
if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
&pdp->eua.v, sizeof(pdp->eua.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1899,7 +1900,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* It is weird that this is mandatory when TEIC is conditional */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
&pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1910,7 +1911,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* SGSN address for user traffic (mandatory) */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
&pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1922,7 +1923,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* QoS (mandatory) */
if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
&pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
@ -1964,7 +1965,7 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
goto err_out;
@ -1988,7 +1989,7 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
if (cause != GTPCAUSE_NON_EXIST && cause != GTPCAUSE_CONTEXT_NOT_FOUND) {
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n", get_tei(pack));
goto err_out;
@ -2057,7 +2058,7 @@ generic_ret:
return rc; /* Succes */
err_missing:
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing information field\n");
err_out:
@ -2123,7 +2124,7 @@ int gtp_delete_context_req2(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
int count;
if (gsna2in_addr(&addr, &pdp->gsnrc)) {
gsn->err_address++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_ADDRESS);
LOGP(DLGTP, LOGL_ERROR, "GSN address (len=%u) conversion failed\n", pdp->gsnrc.l);
return EOF;
}
@ -2225,7 +2226,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
/* Find the linked context in question */
if (gtp_pdp_getgtp1(gsn, &linked_pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n", get_tei(pack));
return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
@ -2239,7 +2240,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (0 == version)
@ -2254,7 +2255,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
if (version == 1) {
/* NSAPI (mandatory) */
if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
@ -2265,7 +2266,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, linked_pdp->secondary_tei[nsapi & 0x0f])) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: Secondary TEI=0x%" PRIx32 "\n",
linked_pdp->secondary_tei[nsapi & 0x0f]);
@ -2319,7 +2320,7 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
/* Find the context in question. It may not be available if gtp_delete_context_req
* was used and as a result the PDP ctx was already freed */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_NOTICE, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 " (expected if "
"gtp_delete_context_req is used or pdp ctx was freed "
@ -2331,7 +2332,7 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
if (gsn->cb_conf)
@ -2341,7 +2342,7 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
/* Extract cause value (mandatory) */
if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
if (gsn->cb_conf)
@ -2351,7 +2352,7 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
/* Check the cause value (again) */
if ((GTPCAUSE_ACC_REQ != cause) && (GTPCAUSE_NON_EXIST != cause)) {
gsn->err_cause++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNEXPECTED_CAUSE);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unexpected cause value received: %d\n", cause);
if (gsn->cb_conf)
@ -2398,7 +2399,7 @@ static int gtp_error_ind_conf(struct gsn_t *gsn, uint8_t version,
/* Find the context in question */
if (version == 0) {
if (gtp_pdp_tidget(gsn, &pdp, get_tid(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TID=0x%" PRIx64 "\n",
get_tid(pack));
@ -2411,21 +2412,21 @@ static int gtp_error_ind_conf(struct gsn_t *gsn, uint8_t version,
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_INVALID);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format\n");
return EOF;
}
if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &teid_gn)) {
gsn->missing++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing mandatory information field\n");
return EOF;
}
if (gtp_pdp_getgtp1_peer_d(gsn, &pdp, peer, teid_gn)) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: Peer TEID=0x%" PRIx32 "\n",
teid_gn);
@ -2460,7 +2461,7 @@ static int gtp_gpdu_ind(struct gsn_t *gsn, uint8_t version,
switch (version) {
case 0:
if (gtp_pdp_getgtp0(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
@ -2471,7 +2472,7 @@ static int gtp_gpdu_ind(struct gsn_t *gsn, uint8_t version,
break;
case 1:
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
@ -2493,7 +2494,7 @@ static int gtp_gpdu_ind(struct gsn_t *gsn, uint8_t version,
/* If the GPDU was not from the peer GSN tell him to delete context */
if (memcmp(&peer->sin_addr, pdp->gsnru.v, pdp->gsnru.l)) { /* TODO Range? */
gsn->err_unknownpdp++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNKNOWN_PDP);
GTP_LOGPKG(LOGL_ERROR, peer, pack, len, "Unknown GSN peer %s\n", inet_ntoa(peer->sin_addr));
return gtp_error_ind_resp(gsn, version, peer, fd, pack, len);
}
@ -2535,7 +2536,7 @@ int gtp_decaps0(struct gsn_t *gsn)
(struct sockaddr *)&peer, &peerlen)) < 0) {
if (errno == EAGAIN)
return 0;
gsn->err_readfrom++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_READFROM);
LOGP(DLGTP, LOGL_ERROR,
"recvfrom(fd0=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
gsn->fd0, (unsigned long)buffer, sizeof(buffer),
@ -2545,7 +2546,7 @@ int gtp_decaps0(struct gsn_t *gsn)
/* Need at least 1 byte in order to check version */
if (status < (1)) {
gsn->empty++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_EMPTY);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Discarding packet - too small\n");
continue;
@ -2561,7 +2562,7 @@ int gtp_decaps0(struct gsn_t *gsn)
/* only support version 0, implying that this is the only version */
/* supported on this port */
if (version > 0) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unsupported GTP version %"PRIu8"\n", version);
gtp_unsup_req(gsn, 0, &peer, gsn->fd0, buffer, status); /* 29.60: 11.1.1 */
@ -2570,7 +2571,7 @@ int gtp_decaps0(struct gsn_t *gsn)
/* Check length of gtp0 packet */
if (status < GTP0_HEADER_SIZE) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "GTP0 packet too short\n");
continue; /* Silently discard 29.60: 11.1.2 */
@ -2578,7 +2579,7 @@ int gtp_decaps0(struct gsn_t *gsn)
/* Check packet length field versus length of packet */
if (status != (ntoh16(pheader->length) + GTP0_HEADER_SIZE)) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"GTP packet length field does not match actual length\n");
@ -2588,7 +2589,7 @@ int gtp_decaps0(struct gsn_t *gsn)
if ((gsn->mode == GTP_MODE_GGSN) &&
((pheader->type == GTP_CREATE_PDP_RSP) ||
(pheader->type == GTP_UPDATE_PDP_RSP))) {
gsn->unexpect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNEXPECT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"Unexpected GTPv0 Signalling Message '%s'\n",
@ -2599,7 +2600,7 @@ int gtp_decaps0(struct gsn_t *gsn)
if ((gsn->mode == GTP_MODE_SGSN) &&
((pheader->type == GTP_CREATE_PDP_REQ) ||
(pheader->type == GTP_UPDATE_PDP_REQ))) {
gsn->unexpect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNEXPECT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"Unexpected GTPv0 Signalling Message '%s'\n",
@ -2648,7 +2649,7 @@ int gtp_decaps0(struct gsn_t *gsn)
gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
break;
default:
gsn->unknown++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNKNOWN);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unknown GTP message type received: %d\n",
pheader->type);
@ -2682,7 +2683,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
(struct sockaddr *)&peer, &peerlen)) < 0) {
if (errno == EAGAIN)
return 0;
gsn->err_readfrom++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_READFROM);
LOGP(DLGTP, LOGL_ERROR,
"recvfrom(fd=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
fd, (unsigned long)buffer, sizeof(buffer),
@ -2692,7 +2693,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* Need at least 1 byte in order to check version */
if (status < (1)) {
gsn->empty++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_EMPTY);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Discarding packet - too small\n");
continue;
@ -2704,7 +2705,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* Version must be no larger than GTP 1 */
if (version > 1) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unsupported GTP version %"PRIu8"\n", version);
gtp_unsup_req(gsn, version, &peer, fd, buffer, status);
@ -2717,7 +2718,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* GTP 1 messages. If GTP 0 message is received we silently discard */
/* the message */
if (version < 1) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unsupported GTP version %"PRIu8"\n", version);
continue;
@ -2725,7 +2726,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* Check packet flag field */
if (((pheader->flags & 0xf7) != 0x32)) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Unsupported packet flags: 0x%02x\n", pheader->flags);
continue;
@ -2733,7 +2734,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* Check length of packet */
if (status < GTP1_HEADER_SIZE_LONG) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "GTP packet too short\n");
continue; /* Silently discard 29.60: 11.1.2 */
@ -2742,7 +2743,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* Check packet length field versus length of packet */
if (status !=
(ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"GTP packet length field does not match actual length\n");
@ -2753,7 +2754,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
/* TODO: We really should cycle through the headers and determine */
/* if any have the comprehension required flag set */
if (((pheader->flags & GTP1HDR_F_EXT) != 0x00)) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Unsupported extension header\n");
gtp_extheader_req(gsn, version, &peer, fd, buffer,
@ -2765,7 +2766,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
if ((gsn->mode == GTP_MODE_GGSN) &&
((pheader->type == GTP_CREATE_PDP_RSP) ||
(pheader->type == GTP_UPDATE_PDP_RSP))) {
gsn->unexpect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNEXPECT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"Unexpected GTPv1 Signalling Message '%s'\n",
@ -2776,7 +2777,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
if ((gsn->mode == GTP_MODE_SGSN) &&
((pheader->type == GTP_CREATE_PDP_REQ) ||
(pheader->type == GTP_UPDATE_PDP_REQ))) {
gsn->unexpect++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNEXPECT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"Unexpected GTPv1 Signalling Message '%s'\n",
@ -2828,7 +2829,7 @@ int gtp_decaps1c(struct gsn_t *gsn)
gtp_ran_info_relay_ind(gsn, version, &peer, buffer, status);
break;
default:
gsn->unknown++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNKNOWN);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unknown GTP message type received: %u\n",
pheader->type);
@ -2862,7 +2863,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
(struct sockaddr *)&peer, &peerlen)) < 0) {
if (errno == EAGAIN)
return 0;
gsn->err_readfrom++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_READFROM);
LOGP(DLGTP, LOGL_ERROR,
"recvfrom(fd1u=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
gsn->fd1u, (unsigned long)buffer,
@ -2873,7 +2874,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* Need at least 1 byte in order to check version */
if (status < (1)) {
gsn->empty++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_EMPTY);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Discarding packet - too small\n");
continue;
@ -2885,7 +2886,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* Version must be no larger than GTP 1 */
if (version > 1) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unsupported GTP version %"PRIu8"\n", version);
gtp_unsup_req(gsn, 1, &peer, gsn->fd1c, buffer, status); /*29.60: 11.1.1 */
@ -2897,7 +2898,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* GTP 1 messages. If GTP 0 message is received we silently discard */
/* the message */
if (version < 1) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unsupported GTP version %"PRIu8"\n", version);
continue;
@ -2905,7 +2906,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* Check packet flag field (allow both with and without sequence number) */
if (((pheader->flags & 0xf5) != 0x30)) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Unsupported packet flags 0x%02x\n", pheader->flags);
continue;
@ -2913,7 +2914,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* Check length of packet */
if (status < GTP1_HEADER_SIZE_SHORT) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "GTP packet too short\n");
continue; /* Silently discard 29.60: 11.1.2 */
@ -2922,7 +2923,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* Check packet length field versus length of packet */
if (status !=
(ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
gsn->tooshort++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_TOOSHORT);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status,
"GTP packet length field does not match actual length\n");
@ -2933,7 +2934,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
/* TODO: We really should cycle through the headers and determine */
/* if any have the comprehension required flag set */
if (((pheader->flags & GTP1HDR_F_EXT) != 0x00)) {
gsn->unsup++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNSUP);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
status, "Unsupported extension header\n");
gtp_extheader_req(gsn, version, &peer, fd, buffer,
@ -2960,7 +2961,7 @@ int gtp_decaps1u(struct gsn_t *gsn)
gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
break;
default:
gsn->unknown++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_UNKNOWN);
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
"Unknown GTP message type received: %u\n",
pheader->type);
@ -3041,7 +3042,7 @@ int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len)
}
if (sendmsg(fd, &msgh, 0) < 0) {
gsn->err_sendto++;
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"sendmsg(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
(unsigned long)&packet, GTP0_HEADER_SIZE + len,