diff --git a/src/bts.cpp b/src/bts.cpp
index 8489431..5bf139d 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -461,7 +461,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
 			return -EBUSY;
 		}
 		/* set class to 0, since we don't know the multislot class yet */
-		tbf = (gprs_rlcmac_ul_tbf *)tbf_alloc(&m_bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 1);
+		tbf = tbf_alloc_ul_tbf(&m_bts, NULL, tfi, trx_no, 0, 1);
 		if (!tbf) {
 			LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 			/* FIXME: send reject */
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 15301a1..1201642 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -165,7 +165,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
 		return -EBUSY;
 	}
 	/* set number of downlink slots according to multislot class */
-	tbf = tbf_alloc(bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, ss);
+	tbf = tbf_alloc_dl_tbf(bts, tbf, tfi, trx, ms_class, ss);
 	if (!tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 		/* FIXME: send reject */
@@ -231,7 +231,7 @@ gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
 		return NULL;
 	}
 	/* use multislot class of downlink TBF */
-	tbf = (gprs_rlcmac_ul_tbf *)tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx, ms_class, 0);
+	tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx, ms_class, 0);
 	if (!tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 		/* FIXME: send reject */
@@ -479,33 +479,20 @@ void gprs_rlcmac_tbf::poll_timeout()
 		LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
 }
 
-struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir,
-	uint8_t tfi, uint8_t trx,
+static int setup_tbf(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_bts *bts,
+	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot)
 {
-	struct gprs_rlcmac_tbf *tbf;
 	int rc;
 
-	LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
-	LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d "
-		"MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL",
-		tfi, trx, ms_class);
-
 	if (trx >= 8 || tfi >= 32)
-		return NULL;
-
-	if (dir == GPRS_RLCMAC_UL_TBF)
-		tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	else
-		tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
+		return -1;
 
 	if (!tbf)
-		return NULL;
+		return -1;
 
 	tbf->m_created_ts = time(NULL);
 	tbf->bts = bts->bts;
-	tbf->direction = dir;
 	tbf->m_tfi = tfi;
 	tbf->trx = &bts->trx[trx];
 	tbf->ms_class = ms_class;
@@ -514,16 +501,14 @@ struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
 		single_slot);
 	/* if no resource */
 	if (rc < 0) {
-		talloc_free(tbf);
-		return NULL;
+		return -1;
 	}
 	/* assign control ts */
 	tbf->control_ts = 0xff;
 	rc = tbf_assign_control_ts(tbf);
 	/* if no resource */
 	if (rc < 0) {
-		talloc_free(tbf);
-		return NULL;
+		return -1;
 	}
 
 	/* set timestamp */
@@ -532,14 +517,73 @@ struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
 	gettimeofday(&tbf->meas.dl_loss_tv, NULL);
 
 	tbf->m_llc.init();
-	if (dir == GPRS_RLCMAC_UL_TBF) {
-		llist_add(&tbf->list, &bts->ul_tbfs);
-		tbf->bts->tbf_ul_created();
-	} else {
-		llist_add(&tbf->list, &bts->dl_tbfs);
-		tbf->bts->tbf_dl_created();
+	return 0;
+}
+
+
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
+	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
+	uint8_t ms_class, uint8_t single_slot)
+{
+	struct gprs_rlcmac_ul_tbf *tbf;
+	int rc;
+
+	LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
+	LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d "
+		"MS_CLASS=%d\n", "UL", tfi, trx, ms_class);
+
+	if (trx >= 8 || tfi >= 32)
+		return NULL;
+
+	tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
+
+	if (!tbf)
+		return NULL;
+
+	tbf->direction = GPRS_RLCMAC_UL_TBF;
+	rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
+	/* if no resource */
+	if (rc < 0) {
+		talloc_free(tbf);
+		return NULL;
+	}
+
+	llist_add(&tbf->list, &bts->ul_tbfs);
+	tbf->bts->tbf_ul_created();
+
+	return tbf;
+}
+
+struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
+	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
+	uint8_t ms_class, uint8_t single_slot)
+{
+	struct gprs_rlcmac_dl_tbf *tbf;
+	int rc;
+
+	LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
+	LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d "
+		"MS_CLASS=%d\n", "DL", tfi, trx, ms_class);
+
+	if (trx >= 8 || tfi >= 32)
+		return NULL;
+
+	tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
+
+	if (!tbf)
+		return NULL;
+
+	tbf->direction = GPRS_RLCMAC_DL_TBF;
+	rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
+	/* if no resource */
+	if (rc < 0) {
+		talloc_free(tbf);
+		return NULL;
 	}
 
+	llist_add(&tbf->list, &bts->dl_tbfs);
+	tbf->bts->tbf_dl_created();
+
 	return tbf;
 }
 
diff --git a/src/tbf.h b/src/tbf.h
index d650021..4d20987 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -263,9 +263,14 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
 	int8_t use_trx, uint8_t ms_class,
 	uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf);
 
-struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
 	struct gprs_rlcmac_tbf *old_tbf,
-	enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx,
+	uint8_t tfi, uint8_t trx,
+	uint8_t ms_class, uint8_t single_slot);
+
+struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
+	struct gprs_rlcmac_tbf *old_tbf,
+	uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot);
 
 void tbf_free(struct gprs_rlcmac_tbf *tbf);
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index 80e8c34..830ca90 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -36,6 +36,17 @@ extern "C" {
 void *tall_pcu_ctx;
 int16_t spoof_mnc = 0, spoof_mcc = 0;
 
+static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
+		struct gprs_rlcmac_tbf *old_tbf, gprs_rlcmac_tbf_direction dir,
+		uint8_t tfi, uint8_t trx,
+		uint8_t ms_class, uint8_t single_slot)
+{
+	if (dir == GPRS_RLCMAC_UL_TBF)
+		return tbf_alloc_ul_tbf(bts, old_tbf, tfi, trx, ms_class, single_slot);
+	else
+		return tbf_alloc_dl_tbf(bts, old_tbf, tfi, trx, ms_class, single_slot);
+}
+
 static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count)
 {
 	int tfi;
@@ -136,14 +147,14 @@ static void test_alloc_b(int ms_class)
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 1);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, tfi, trx_no, ms_class, 1);
 		OSMO_ASSERT(ul_tbf);
 		dump_assignment(ul_tbf, "UL");
 
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -177,7 +188,7 @@ static void test_alloc_b(int ms_class)
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 1);
+		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, tfi, trx_no, ms_class, 1);
 		dl_tbf->m_tlli = 0x23;
 		dl_tbf->m_tlli_valid = true;
 		OSMO_ASSERT(dl_tbf);
@@ -185,7 +196,7 @@ static void test_alloc_b(int ms_class)
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
 		ul_tbf->m_tlli = 0x23;
 		ul_tbf->m_tlli_valid = true;
 		ul_tbf->dir.ul.contention_resolution_done = 1;
@@ -226,14 +237,14 @@ static void test_alloc_b(int ms_class)
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(ul_tbf);
 		dump_assignment(ul_tbf, "UL");
 
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -290,13 +301,13 @@ static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 1);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, tfi, trx_no, ms_class, 1);
 		OSMO_ASSERT(ul_tbf);
 
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 
 		/* verify that both are on the same ts */
@@ -333,14 +344,14 @@ static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 1);
+		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, tfi, trx_no, ms_class, 1);
 		OSMO_ASSERT(dl_tbf);
 		dl_tbf->m_tlli = 0x23;
 		dl_tbf->m_tlli_valid = true;
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(ul_tbf);
 		ul_tbf->m_tlli = 0x23;
 		ul_tbf->m_tlli_valid = true;
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 38975f9..decf4d9 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -44,16 +44,16 @@ static void test_tbf_tlli_update()
 	/*
 	 * Make a uplink and downlink allocation
 	 */
-	gprs_rlcmac_tbf *dl_tbf = tbf_alloc(the_bts.bts_data(),
-						NULL, GPRS_RLCMAC_DL_TBF, 0,
+	gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(),
+						NULL, 0,
 						0, 0, 0);
 	dl_tbf->update_tlli(0x2342);
 	dl_tbf->tlli_mark_valid();
 	dl_tbf->ta = 4;
 	the_bts.timing_advance()->remember(0x2342, dl_tbf->ta);
 
-	gprs_rlcmac_tbf *ul_tbf = tbf_alloc(the_bts.bts_data(),
-						ul_tbf, GPRS_RLCMAC_UL_TBF, 0,
+	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
+						ul_tbf, 0,
 						0, 0, 0);
 	ul_tbf->update_tlli(0x2342);
 	ul_tbf->tlli_mark_valid();
