diff -aur openbsc_current/openbsc/openbsc/src/gprs/gb_proxy.c openbsc/openbsc/openbsc/src/gprs/gb_proxy.c
--- openbsc_current/openbsc/openbsc/src/gprs/gb_proxy.c 2012-04-30 15:42:58.957824510 +0200
+++ openbsc/openbsc/openbsc/src/gprs/gb_proxy.c 2012-04-25 11:49:51.219837862 +0200
@@ -172,6 +172,7 @@
        /* create a copy of the message so the old one can
         * be free()d safely when we return from gbprox_rcvmsg() */
        struct msgb *msg = msgb_copy(old_msg, "msgb_relay2sgsn");
+        int rc;

        DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
                msgb_nsei(msg), ns_bvci, gbcfg.nsip_sgsn_nsei);
@@ -181,7 +182,9 @@

        strip_ns_hdr(msg);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        msgb_free(msg);
+        return rc;
 }

 /* feed a message down the NS-VC associated with the specified peer */
@@ -191,6 +194,7 @@
        /* create a copy of the message so the old one can
         * be free()d safely when we return from gbprox_rcvmsg() */
        struct msgb *msg = msgb_copy(old_msg, "msgb_relay2peer");
+        int rc;

        DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n",
                msgb_nsei(msg), ns_bvci, peer->nsvc->nsei);
@@ -201,7 +205,9 @@
        /* Strip the old NS header, it will be replaced with a new one */
        strip_ns_hdr(msg);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        msgb_free(msg);
+        return rc;
 }

 static int block_unblock_peer(uint16_t ptp_bvci, uint8_t pdu_type)
diff -aur openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp_bss.c openbsc/openbsc/openbsc/src/libgb/gprs_bssgp_bss.c
--- openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp_bss.c  2012-04-30 15:42:58.980823391 +0200
+++ openbsc/openbsc/openbsc/src/libgb/gprs_bssgp_bss.c  2012-04-25 11:45:16.492838573 +0200
@@ -48,6 +48,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint8_t ra[6];
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=0) Tx SUSPEND (TLLI=0x%04x)\n",
                tlli);
@@ -60,7 +61,9 @@
        gsm48_construct_ra(ra, ra_id);
        msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, 6, ra);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief GMM-RESUME.req (Chapter 10.3.9) */
@@ -71,6 +74,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint8_t ra[6];
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=0) Tx RESUME (TLLI=0x%04x)\n",
                tlli);
@@ -85,7 +89,9 @@

        msgb_tvlv_put(msg, BSSGP_IE_SUSPEND_REF_NR, 1, &suspend_ref);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit RA-CAPABILITY-UPDATE (10.3.3) */
@@ -94,6 +100,7 @@
        struct msgb *msg = bssgp_msgb_alloc();
        struct bssgp_normal_hdr *bgph =
                (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx RA-CAPA-UPD (TLLI=0x%04x)\n",
                bctx->bvci, tlli);
@@ -107,7 +114,9 @@

        msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* first common part of RADIO-STATUS */
@@ -143,13 +152,16 @@
                                uint32_t tlli)
 {
        struct msgb *msg = common_tx_radio_status(bctx);
+        int rc;

        if (!msg)
                return -ENOMEM;
        bssgp_msgb_tlli_put(msg, tlli);
        LOGPC(DBSSGP, LOGL_NOTICE, "TLLI=0x%08x ", tlli);

-       return common_tx_radio_status2(msg, cause);
+       rc = common_tx_radio_status2(msg, cause);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit RADIO-STATUS for TMSI (10.3.5) */
@@ -158,13 +170,16 @@
 {
        struct msgb *msg = common_tx_radio_status(bctx);
        uint32_t _tmsi = htonl(tmsi);
+        int rc;

        if (!msg)
                return -ENOMEM;
        msgb_tvlv_put(msg, BSSGP_IE_TMSI, 4, (uint8_t *)&_tmsi);
        LOGPC(DBSSGP, LOGL_NOTICE, "TMSI=0x%08x ", tmsi);

-       return common_tx_radio_status2(msg, cause);
+       rc = common_tx_radio_status2(msg, cause);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit RADIO-STATUS for IMSI (10.3.5) */
@@ -174,6 +189,7 @@
        struct msgb *msg = common_tx_radio_status(bctx);
        uint8_t mi[10];
        int imsi_len = gsm48_generate_mid_from_imsi(mi, imsi);
+        int rc;

        if (!msg)
                return -ENOMEM;
@@ -183,7 +199,9 @@
                msgb_tvlv_put(msg, BSSGP_IE_IMSI, imsi_len-2, mi+2);
        LOGPC(DBSSGP, LOGL_NOTICE, "IMSI=%s ", imsi);

-       return common_tx_radio_status2(msg, cause);
+       rc = common_tx_radio_status2(msg, cause);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit FLUSH-LL-ACK (Chapter 10.4.2) */
@@ -196,6 +214,7 @@
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci_new = htons(bvci_new);
        uint32_t _oct_aff = htonl(num_octets & 0xFFFFFF);
+        int rc;

        msgb_nsei(msg) = bctx->nsei;
        msgb_bvci(msg) = 0; /* Signalling */
@@ -207,7 +226,9 @@
                msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci_new);
        msgb_tvlv_put(msg, BSSGP_IE_NUM_OCT_AFF, 3, (uint8_t *) &_oct_aff);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit LLC-DISCARDED (Chapter 10.4.3) */
@@ -219,6 +240,7 @@
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci = htons(bctx->bvci);
        uint32_t _oct_aff = htonl(num_octets & 0xFFFFFF);
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx LLC-DISCARDED "
             "TLLI=0x%04x, FRAMES=%u, OCTETS=%u\n", bctx->bvci, tlli,
@@ -233,7 +255,9 @@
        msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
        msgb_tvlv_put(msg, BSSGP_IE_NUM_OCT_AFF, 3, (uint8_t *) &_oct_aff);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit a BVC-BLOCK message (Chapter 10.4.8) */
@@ -243,6 +267,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci = htons(bctx->bvci);
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-BLOCK "
             "CAUSE=%u\n", bctx->bvci, cause);
@@ -254,7 +279,9 @@
        msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
        msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit a BVC-UNBLOCK message (Chapter 10.4.10) */
@@ -264,6 +291,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci = htons(bctx->bvci);
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-BLOCK\n", bctx->bvci);

@@ -273,7 +301,9 @@

        msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /*! \brief Transmit a BVC-RESET message (Chapter 10.4.12) */
@@ -283,6 +313,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci = htons(bvci);
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-RESET "
             "CAUSE=%u\n", bvci, cause);
@@ -300,7 +331,9 @@
        }
        /* Optional: Feature Bitmap */

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }


diff -aur openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp.c openbsc/openbsc/openbsc/src/libgb/gprs_bssgp.c
--- openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp.c      2012-04-30 15:42:58.980823391 +0200
+++ openbsc/openbsc/openbsc/src/libgb/gprs_bssgp.c      2012-04-25 11:39:21.109837037 +0200
@@ -109,6 +109,7 @@
        struct msgb *msg = bssgp_msgb_alloc();
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = ns_bvci;
@@ -116,7 +117,9 @@
        bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC_ACK;
        msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* 10.3.7 SUSPEND-ACK PDU */
@@ -128,6 +131,7 @@
                (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint32_t _tlli;
        uint8_t ra[6];
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = 0; /* Signalling */
@@ -139,7 +143,9 @@
        msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, 6, ra);
        msgb_tvlv_put(msg, BSSGP_IE_SUSPEND_REF_NR, 1, &suspend_ref);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* 10.3.8 SUSPEND-NACK PDU */
@@ -152,6 +158,7 @@
                (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint32_t _tlli;
        uint8_t ra[6];
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = 0; /* Signalling */
@@ -164,7 +171,9 @@
        if (cause)
                msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, cause);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* 10.3.10 RESUME-ACK PDU */
@@ -176,6 +185,7 @@
                (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint32_t _tlli;
        uint8_t ra[6];
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = 0; /* Signalling */
@@ -186,7 +196,9 @@
        gsm48_construct_ra(ra, ra_id);
        msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, 6, ra);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* 10.3.11 RESUME-NACK PDU */
@@ -198,6 +210,7 @@
                (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint32_t _tlli;
        uint8_t ra[6];
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = 0; /* Signalling */
@@ -210,7 +223,9 @@
        if (cause)
                msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, cause);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf)
@@ -804,6 +819,7 @@
        uint8_t mi[10];
        int imsi_len = gsm48_generate_mid_from_imsi(mi, pinfo->imsi);
        uint8_t ra[6];
+        int rc;

        if (imsi_len < 2)
                return -EINVAL;
@@ -853,5 +869,7 @@
                msgb_tvlv_put(msg, BSSGP_IE_TMSI, 4, (uint8_t *) &ptmsi);
        }

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }
diff -aur openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp_util.c openbsc/openbsc/openbsc/src/libgb/gprs_bssgp_util.c
--- openbsc_current/openbsc/openbsc/src/libgb/gprs_bssgp_util.c 2012-04-30 15:42:58.980823391 +0200
+++ openbsc/openbsc/openbsc/src/libgb/gprs_bssgp_util.c 2012-04-25 11:41:04.702838334 +0200
@@ -82,6 +82,7 @@
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
        uint16_t _bvci;
+        int rc;

        msgb_nsei(msg) = nsei;
        msgb_bvci(msg) = ns_bvci;
@@ -90,7 +91,9 @@
        _bvci = htons(bvci);
        msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }

 /* Chapter 10.4.14: Status */
@@ -99,6 +102,7 @@
        struct msgb *msg = bssgp_msgb_alloc();
        struct bssgp_normal_hdr *bgph =
                        (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+        int rc;

        LOGP(DBSSGP, LOGL_NOTICE, "BSSGP BVCI=%u Tx STATUS, cause=%s\n",
                bvci ? *bvci : 0, bssgp_cause_str(cause));
@@ -114,5 +118,7 @@
        msgb_tvlv_put(msg, BSSGP_IE_PDU_IN_ERROR,
                      msgb_bssgp_len(orig_msg), msgb_bssgph(orig_msg));

-       return gprs_ns_sendmsg(bssgp_nsi, msg);
+       rc = gprs_ns_sendmsg(bssgp_nsi, msg);
+        if (rc < 0) msgb_free(msg);
+        return rc;
 }
diff -aur openbsc_current/openbsc/openbsc/src/libgb/gprs_ns.c openbsc/openbsc/openbsc/src/libgb/gprs_ns.c
--- openbsc_current/openbsc/openbsc/src/libgb/gprs_ns.c 2012-04-30 15:42:58.981823278 +0200
+++ openbsc/openbsc/openbsc/src/libgb/gprs_ns.c 2012-04-25 11:51:06.043834581 +0200
@@ -561,7 +561,6 @@
        if (!nsvc) {
                LOGP(DNS, LOGL_ERROR, "Unable to resolve NSEI %u "
                        "to NS-VC!\n", msgb_nsei(msg));
-               msgb_free(msg);
                return -EINVAL;
        }
        log_set_context(BSC_CTX_NSVC, nsvc);
@@ -569,13 +568,11 @@
        if (!(nsvc->state & NSE_S_ALIVE)) {
                LOGP(DNS, LOGL_ERROR, "NSEI=%u is not alive, cannot send\n",
                        nsvc->nsei);
-               msgb_free(msg);
                return -EBUSY;
        }
        if (nsvc->state & NSE_S_BLOCKED) {
                LOGP(DNS, LOGL_ERROR, "NSEI=%u is blocked, cannot send\n",
                        nsvc->nsei);
-               msgb_free(msg);
                return -EBUSY;
        }

@@ -583,7 +580,6 @@
        nsh = (struct gprs_ns_hdr *) msg->l2h;
        if (!nsh) {
                LOGP(DNS, LOGL_ERROR, "Not enough headroom for NS header\n");
-               msgb_free(msg);
                return -EIO;
        }
