From patchwork Thu Feb 4 14:38:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Willmann X-Patchwork-Id: 578976 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [IPv6:2a01:4f8:191:444b::2:7]) by ozlabs.org (Postfix) with ESMTP id 97C5A140BA0 for ; Fri, 5 Feb 2016 01:39:44 +1100 (AEDT) Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id 943C0147F6; Thu, 4 Feb 2016 14:39:42 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from isonoe.totalueberwachung.de (unknown [IPv6:2a01:198:210:100::1]) by lists.osmocom.org (Postfix) with ESMTP id EECC6147EA; Thu, 4 Feb 2016 14:39:40 +0000 (UTC) Received: from adrastea.totalueberwachung.de (ip5b418565.dynamic.kabel-deutschland.de [91.65.133.101]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by isonoe.totalueberwachung.de (Postfix) with ESMTPSA id A5F486007F; Thu, 4 Feb 2016 15:39:21 +0100 (CET) Received: by adrastea.totalueberwachung.de (Postfix, from userid 1000) id 63A8C4DB; Thu, 4 Feb 2016 15:38:35 +0100 (CET) From: Daniel Willmann To: openbsc@lists.osmocom.org, osmocom-net-gprs@lists.osmocom.org Subject: [PATCH 1/1] gtp: Handle gtpv1 in gtp_update_pdp_conf() correctly Date: Thu, 4 Feb 2016 15:38:12 +0100 Message-Id: <80cf42b077621bce0323cda270a8adfbe8a6098a.1454596571.git.daniel@totalueberwachung.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1454596518.856.105.camel@sysmocom.de> References: <1454596518.856.105.camel@sysmocom.de> X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Willmann Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" libgtp cannot understand its own update pdp request (in gtp v1) Only require the conditional and mandatory fields for gtpv1 and not others. Refer to 3GPP TS 29.060 Ch. 7.3.4 --- gtp/gtp.c | 120 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/gtp/gtp.c b/gtp/gtp.c index 2a6ecd7..12cb492 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -2187,9 +2187,8 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version, gsn->err_unknownpdp++; GTP_LOGPKG(LOGL_ERROR, peer, pack, len, "Unknown PDP context: %u\n", get_tei(pack)); - if (gsn->cb_conf) - gsn->cb_conf(type, EOF, NULL, cbp); - return EOF; + pdp = NULL; + goto err_out; } /* Register that we have received a valid teic from GGSN */ @@ -2200,23 +2199,12 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version, gsn->invalid++; GTP_LOGPKG(LOGL_ERROR, peer, pack, len, "Invalid message format\n"); - if (gsn->cb_conf) - gsn->cb_conf(type, EOF, pdp, cbp); - /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp); - pdp_freepdp(pdp); */ - return EOF; + goto err_out; } /* Extract cause value (mandatory) */ if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) { - gsn->missing++; - GTP_LOGPKG(LOGL_ERROR, peer, pack, len, - "Missing mandatory information field\n"); - if (gsn->cb_conf) - gsn->cb_conf(type, EOF, pdp, cbp); - /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp); - pdp_freepdp(pdp); */ - return EOF; + goto err_missing; } /* Extract recovery (optional) */ @@ -2226,51 +2214,69 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version, } /* Check all conditional information elements */ - if (GTPCAUSE_ACC_REQ != cause) { - if (gsn->cb_conf) - gsn->cb_conf(type, cause, pdp, cbp); - /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp); - pdp_freepdp(pdp); */ - return 0; - } else { - /* Check for missing conditionary information elements */ - if (!(gtpie_exist(ie, GTPIE_QOS_PROFILE0, 0) && - gtpie_exist(ie, GTPIE_REORDER, 0) && - gtpie_exist(ie, GTPIE_FL_DI, 0) && - gtpie_exist(ie, GTPIE_FL_C, 0) && - gtpie_exist(ie, GTPIE_CHARGING_ID, 0) && - gtpie_exist(ie, GTPIE_EUA, 0) && - gtpie_exist(ie, GTPIE_GSN_ADDR, 0) && - gtpie_exist(ie, GTPIE_GSN_ADDR, 1))) { - gsn->missing++; - GTP_LOGPKG(LOGL_ERROR, peer, pack, - len, - "Missing conditional information field\n"); - if (gsn->cb_conf) - gsn->cb_conf(type, EOF, pdp, cbp); - /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp); - pdp_freepdp(pdp); */ - return EOF; + /* TODO: This does not handle GGSN-initiated update responses */ + if (GTPCAUSE_ACC_REQ == cause) { + if (version == 0) { + if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, + &pdp->qos_neg0, + sizeof(pdp->qos_neg0))) { + goto err_missing; + } + + if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) { + goto err_missing; + } + + if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) { + goto err_missing; + } } - /* Update pdp with new values */ - gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, - pdp->qos_neg0, sizeof(pdp->qos_neg0)); - gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder); - gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru); - gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc); - gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid); - gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l, - &pdp->eua.v, sizeof(pdp->eua.v)); - gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l, - &pdp->gsnrc.v, sizeof(pdp->gsnrc.v)); - gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l, - &pdp->gsnru.v, sizeof(pdp->gsnru.v)); + if (version == 1) { + if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) { + goto err_missing; + } - if (gsn->cb_conf) - gsn->cb_conf(type, cause, pdp, cbp); - return 0; /* Succes */ + if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) { + goto err_missing; + } + } + + if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) { + goto err_missing; + } + + if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l, + &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) { + goto err_missing; + } + + if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l, + &pdp->gsnru.v, sizeof(pdp->gsnru.v))) { + goto err_missing; + } + + if (version == 1) { + if (gtpie_gettlv + (ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_neg.l, + &pdp->qos_neg.v, sizeof(pdp->qos_neg.v))) { + goto err_missing; + } + } } + + if (gsn->cb_conf) + gsn->cb_conf(type, cause, pdp, cbp); + return 0; /* Succes */ + +err_missing: + gsn->missing++; + GTP_LOGPKG(LOGL_ERROR, peer, pack, len, + "Missing information field\n"); +err_out: + if (gsn->cb_conf) + gsn->cb_conf(type, EOF, pdp, cbp); + return EOF; } /* API: Send Delete PDP Context Request */