aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/sgsn_libgtp.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-06-03 06:38:38 +0200
committerHarald Welte <laforge@gnumonks.org>2010-06-03 06:38:38 +0200
commitbb1c8057180a56ecf0d7a22f20aeed767d2ca286 (patch)
treeb5ff7d78fe3ef7dea7794e3011f4cf7ae298c141 /openbsc/src/gprs/sgsn_libgtp.c
parent96df60637a97c3467a394e46534fda43e29814fd (diff)
[GPRS] implement GTP->SNDCP->LLC downlink user-data path
This only works for packets that are small enough to not need fragmentation at the SNDCP layer (dns queries, ntp and the like). It requires libgtp built from OpenGGSN dc3744fda045f9fca83de6881176987335a309a8 or later. Plain 0.90 will NOT work. Using this version, I could see bi-directional traffic from various phones going all the way through BTS, OsmoSGSN, OpenGGSN and being routed to and from the real internet. Time to celebrate...
Diffstat (limited to 'openbsc/src/gprs/sgsn_libgtp.c')
-rw-r--r--openbsc/src/gprs/sgsn_libgtp.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c
index 37ffd8985..6de3c3d1f 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -113,6 +113,7 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
LOGP(DGPRS, LOGL_ERROR, "Out of libgtp PDP Contexts\n");
return NULL;
}
+ pdp->priv = pctx;
pctx->lib = pdp;
pctx->ggsn = ggsn;
@@ -354,12 +355,29 @@ static int cb_extheader_ind(struct sockaddr_in *peer)
}
/* Called whenever we recive a DATA packet */
-static int cb_data_ind(struct pdp_t *pdp, void *packet, unsigned int len)
+static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
{
+ struct sgsn_pdp_ctx *pdp;
+ struct msgb *msg = msgb_alloc_headroom(len+128, 128, "GTP->SNDCP");
+ uint8_t *ud;
+
DEBUGP(DGPRS, "GTP DATA IND from GGSN, length=%u\n", len);
/* FIXME: resolve PDP/MM context, forward to SNDCP layer */
- return 0;
+ pdp = lib->priv;
+ if (!pdp) {
+ DEBUGP(DGPRS, "GTP DATA IND from GGSN for unknown PDP\n");
+ return -EIO;
+ }
+
+ ud = msgb_put(msg, len);
+ memcpy(ud, packet, len);
+
+ msgb_tlli(msg) = pdp->mm->tlli;
+ msgb_bvci(msg) = pdp->mm->bvci;
+ msgb_nsei(msg) = pdp->mm->nsei;
+
+ return sndcp_unitdata_req(msg, &pdp->mm->llme->lle[pdp->sapi], pdp->nsapi, pdp->mm);
}
/* Called by SNDCP when it has received/re-assembled a N-PDU */