sgsn: Add PDP info to subscriber data

Currently the PDP info that is transmitted via GSUP is just parsed
and then discarded.

This commit adds a new data structure sgsn_subscriber_pdp_data and
maintains a list of those in sgsn_subscriber_data. The PDP data is
copied from an incoming GSUP UpdateLocationResult message. If that
message contains the PDPInfoComplete flag, the list is cleared before
new entries are added.  The 'show subscriber cache' output now also
shows the PDP data entries.

Note that the InsertSubscriberData message is still not supported.

[hfreyther: Added talloc_free in gprs_subscr_pdp_data_clear]

Sponsored-by: On-Waves ehf
diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
index 425cf63..7a14cde 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -383,6 +383,7 @@
 	struct sgsn_mm_ctx *ctx;
 	struct gprs_ra_id raid = { 0, };
 	uint32_t local_tlli = 0xffeeddcc;
+	struct sgsn_subscriber_pdp_data *pdpd;
 	int rc;
 
 	static const uint8_t send_auth_info_res[] = {
@@ -520,12 +521,19 @@
 	OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
 	OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
 
-	/* Inject UpdateLocReq GSUP message */
+	/* Inject UpdateLocRes GSUP message */
 	rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
 	OSMO_ASSERT(rc >= 0);
 	OSMO_ASSERT(last_updated_subscr == s1);
 	OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
 	OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
+	OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
+	pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
+		struct sgsn_subscriber_pdp_data, list);
+	OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
+	pdpd = llist_entry(pdpd->list.next,
+		struct sgsn_subscriber_pdp_data, list);
+	OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
 
 	/* Check authorization */
 	OSMO_ASSERT(s1->authorized == 1);