On Tue, Jul 30, 2013 at 09:20:38AM +0200, Holger Hans Peter Freyther wrote:
Or shall we do this... "oh we know this
subscriber already" at a
higher level in GMM? E.g. notice that it is a routing area update...
and then free the new llme and do a tlli assignment for the foreign
tlli?
The patch is not enough.. I ran into the newly added ASSERT about the
TLLI.
1.) E71 attach to a network and create a PDP context..
2.) Restart SGSN/GGSN
3.) Phone tries Activate/Deactivate PDP Context.. we send a GMM status
with impl. detached.. E71 sends a SM Status for protocol error
4.) Re-open the browser app... it tries GPRS Attach for a foreign tlli
(based on the old one).. we find it.. the state doesn't match so
there is re-transmission going on.. once we have the righ seq. number
the RX will find the 'right' LLME.. but on TX for the foreign TLLI
we create a LLME on the fly and run into the assert...
I can now extend the second phase of look-ups and soften the assert a
bit but I do wonder if that is the correct thing to do.
I added the below diff.. but it is probably better to check if one could
combine these llme's at a higher level? Or at least free the old LLME
and use the new one? My last problem right now is that LLC data is not
sent to the GGSN.. :}
<0012> gprs_llc.c:543 LLC SAPI=1 C FCS=0xd85a2cCMD=UI DATA
<0012> gprs_llc.c:194 TLLI 0xa44240f7 is foreign, converting to local TLLI
0xe44240f7
<0012> gprs_llc.c:409 LLC TX: unknown TLLI 0xa44240f7, creating LLME on the fly
Assert failed msgb_tlli(msg) == mmctx->llme->tlli || msgb_tlli(msg) ==
mmctx->llme->old_tlli gprs_llc.c:106
backtrace() returned 20 addresses
/home/ich/install/openbsc/lib/libosmocore.so.4(osmo_generate_backtrace+0x16) [0xb7bb6a36]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8049dc5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8052085]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804a326]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804a8ff]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804ac42]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804b3e5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804bd9f]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804d23c]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8052a24]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn(bssgp_prim_cb+0x55) [0x804f5d4]
/home/ich/install/openbsc/lib/libosmogb.so.2(bssgp_rcvmsg+0x3b8) [0xb7b626b8]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804f521]
/home/ich/install/openbsc/lib/libosmogb.so.2(gprs_ns_rcvmsg+0x8c7) [0xb7b5ecf7]
/home/ich/install/openbsc/lib/libosmogb.so.2(+0x4311) [0xb7b5f311]
/home/ich/install/openbsc/lib/libosmocore.so.4(osmo_select_main+0x192) [0xb7bb2ed2]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804fbfd]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5) [0xb796a8f5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8049ded]
Program received signal SIGABRT, Aborted.
0xb7fde424 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7fde424 in __kernel_vsyscall ()
#1 0xb797f83f in __GI_raise (sig=sig@entry=6) at
../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2 0xb7982cf3 in __GI_abort () at abort.c:90
#3 0x08049dca in _bssgp_tx_dl_ud (mmctx=<optimized out>, msg=<optimized
out>)
at gprs_llc.c:105
#4 0x08052085 in gprs_llc_tx_ui (msg=0x8092ba8, sapi=1 '\001', command=1,
mmctx=0x8092700)
at gprs_llc.c:417
#5 0x0804a326 in gsm48_gmm_sendmsg (msg=0x8092ba8, command=1, mm=0x8092700) at
gprs_gmm.c:241
#6 0x0804a8ff in gsm48_tx_gmm_id_req (mm=0x8092700, id_type=2 '\002') at
gprs_gmm.c:454
#7 0x0804ac42 in gsm48_gmm_authorize (ctx=0x8092700, t3350_mode=GMM_T3350_MODE_ATT)
at gprs_gmm.c:560
#8 0x0804b3e5 in gsm48_rx_gmm_att_req (ctx=0x8092700, msg=0x8090f98, llme=0x8091ce8)
at gprs_gmm.c:765
#9 0x0804bd9f in gsm0408_rcv_gmm (mmctx=0x0, msg=0x8090f98, llme=0x8091ce8)
at gprs_gmm.c:1039
#10 0x0804d23c in gsm0408_gprs_rcvmsg (msg=msg@entry=0x8090f98, llme=0x8091ce8)
at gprs_gmm.c:1566
#11 0x08052a24 in gprs_llc_rcvmsg (msg=0x8090f98, tv=0xbfffdcb0) at gprs_llc.c:874
#12 0x0804f5d4 in bssgp_prim_cb (oph=oph@entry=0xbfffdc8c, ctx=ctx@entry=0x0)
at sgsn_main.c:114
#13 0xb7b626b8 in bssgp_rx_ul_ud (tp=0xbfffdcb0, msg=0x8090f98, ctx=<optimized
out>)
at gprs_bssgp.c:398
#14 bssgp_rx_ptp (bctx=0x8091a08, tp=0xbfffdcb0, msg=0x8090f98) at gprs_bssgp.c:820
#15 bssgp_rcvmsg (msg=0x8090f98) at gprs_bssgp.c:1016
#16 0x0804f521 in sgsn_ns_cb (event=GPRS_NS_EVT_UNIT_DATA, nsvc=0x8090740, msg=0x8090f98,
bvci=1801) at sgsn_main.c:92
#17 0xb7b5ecf7 in gprs_ns_rx_unitdata (msg=0x8090f98, nsvc=0x8090740) at gprs_ns.c:616
#18 gprs_ns_rcvmsg (nsi=nsi@entry=0x807fd38, msg=msg@entry=0x8090f98,
saddr=saddr@entry=0xbfffedc0, ll=ll@entry=GPRS_NS_LL_UDP) at gprs_ns.c:841
#19 0xb7b5f311 in handle_nsip_read (bfd=0x807fd58) at gprs_ns.c:991
diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index b637acb..f0930f6 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -84,6 +84,22 @@ struct gprs_llc_hdr_parsed {
static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
+/* If the TLLI is foreign, return its local version */
+static inline uint32_t tlli_foreign2local(uint32_t tlli)
+{
+ uint32_t new_tlli;
+
+ if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
+ new_tlli = tlli | 0x40000000;
+ DEBUGP(DLLC, "TLLI 0x%08x is foreign, converting to "
+ "local TLLI 0x%08x\n", tlli, new_tlli);
+ } else
+ new_tlli = tlli;
+
+ return new_tlli;
+}
+
+
/* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU
* to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */
static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
@@ -103,7 +119,8 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx
*mmctx)
/* make sure we only send it to the right llme */
OSMO_ASSERT(msgb_tlli(msg) == mmctx->llme->tlli
- || msgb_tlli(msg) == mmctx->llme->old_tlli);
+ || msgb_tlli(msg) == mmctx->llme->old_tlli
+ || tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->tlli);
}
memcpy(&dup.qos_profile, qos_profile_default,
sizeof(qos_profile_default));
@@ -183,21 +200,6 @@ static const struct gprs_llc_params llc_default_params[] = {
LLIST_HEAD(gprs_llc_llmes);
void *llc_tall_ctx;
-/* If the TLLI is foreign, return its local version */
-static inline uint32_t tlli_foreign2local(uint32_t tlli)
-{
- uint32_t new_tlli;
-
- if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
- new_tlli = tlli | 0x40000000;
- DEBUGP(DLLC, "TLLI 0x%08x is foreign, converting to "
- "local TLLI 0x%08x\n", tlli, new_tlli);
- } else
- new_tlli = tlli;
-
- return new_tlli;
-}
-
/* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */
static struct gprs_llc_lle *lle_by_tlli_sapi(const uint32_t tlli, uint8_t sapi)
{
@@ -224,8 +226,12 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t
tlli,
/* Maybe it is a routing area update but we already know this sapi? */
if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
- if (lle)
+ if (lle) {
+ LOGP(DLLC, LOGL_NOTICE,
+ "LLC RX: Found a local entry for TLLI 0x%08x\n",
+ tlli);
return lle;
+ }
}
/* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded,
@@ -403,6 +409,8 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
/* look-up or create the LL Entity for this (TLLI, SAPI) tuple */
lle = lle_by_tlli_sapi(msgb_tlli(msg), sapi);
+ if (!lle)
+ lle = lle_by_tlli_sapi(tlli_foreign2local(msgb_tlli(msg)), sapi);
if (!lle) {
struct gprs_llc_llme *llme;
LOGP(DLLC, LOGL_ERROR, "LLC TX: unknown TLLI 0x%08x, "