From 310ea1db10fcbe1658ddeb16dc3c4454070d9092 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Tue, 20 Aug 2019 14:15:25 +0200 Subject: [PATCH] ggsn_vty.c: Avoid printing duplicates for pdp context with v4v6 EUAs Fixes potential duplicates when calling following VTY cmd: show pdp-context ggsn NAME show pdp-context ggsn NAME apn APN Related: OS#4154 Change-Id: I98db39a710a72a1438d71aabaf4f8227984643e3 --- ggsn/ggsn_vty.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c index b85df77..a649173 100644 --- a/ggsn/ggsn_vty.c +++ b/ggsn/ggsn_vty.c @@ -734,13 +734,22 @@ static const char *print_gsnaddr(const struct ul16_t *in) return in46a_ntoa(&in46); } -static void show_one_pdp(struct vty *vty, struct pdp_t *pdp) +/* Useful for v4v6 APNs, where we first iterate over v4 pool and then over v6 + pool. param v4only can be used to avoid printing duplicates for pdp context + containing both IPv4 and IPv6 addresses. */ +static void show_one_pdp_v4only(struct vty *vty, struct pdp_t *pdp, bool v4only) { - struct ippoolm_t *peer; + struct ippoolm_t *peer4, *peer6; char name_buf[256]; char *apn_name; int rc; + peer4 = pdp_get_peer_ipv(pdp, false); + peer6 = pdp_get_peer_ipv(pdp, true); + + if (v4only && peer6) + return; + /* Attempt to decode MSISDN */ rc = gsm48_decode_bcd_number2(name_buf, sizeof(name_buf), pdp->msisdn.v, pdp->msisdn.l, 0); @@ -759,16 +768,21 @@ static void show_one_pdp(struct vty *vty, struct pdp_t *pdp) apn_name = osmo_apn_to_str(name_buf, pdp->apn_use.v, pdp->apn_use.l); vty_out(vty, " APN in use: %s%s", apn_name ? name_buf : "(NONE)", VTY_NEWLINE); - if ((peer = pdp_get_peer_ipv(pdp, false))) + if (peer4) vty_out(vty, " End-User Address (IPv4): %s%s", - in46a_ntop(&peer->addr, name_buf, sizeof(name_buf)), VTY_NEWLINE); - if ((peer = pdp_get_peer_ipv(pdp, true))) + in46a_ntop(&peer4->addr, name_buf, sizeof(name_buf)), VTY_NEWLINE); + if (peer6) vty_out(vty, " End-User Address (IPv6): %s%s", - in46a_ntop(&peer->addr, name_buf, sizeof(name_buf)), VTY_NEWLINE); + in46a_ntop(&peer6->addr, name_buf, sizeof(name_buf)), VTY_NEWLINE); vty_out(vty, " Transmit GTP Sequence Number for G-PDU: %s%s", pdp->tx_gpdu_seq ? "Yes" : "No", VTY_NEWLINE); } +static void show_one_pdp(struct vty *vty, struct pdp_t *pdp) +{ + show_one_pdp_v4only(vty, pdp, false); +} + DEFUN(show_pdpctx_imsi, show_pdpctx_imsi_cmd, "show pdp-context ggsn NAME imsi IMSI [<0-15>]", SHOW_STR "Display information on PDP Context\n" @@ -853,7 +867,7 @@ DEFUN(show_pdpctx_ip, show_pdpctx_ip_cmd, } /* show all (active) PDP contexts within a pool */ -static void ippool_show_pdp_contexts(struct vty *vty, struct ippool_t *pool) +static void ippool_show_pdp_contexts(struct vty *vty, struct ippool_t *pool, bool pdp_v4only) { unsigned int i; @@ -864,15 +878,15 @@ static void ippool_show_pdp_contexts(struct vty *vty, struct ippool_t *pool) struct ippoolm_t *member = &pool->member[i]; if (member->inuse == 0) continue; - show_one_pdp(vty, member->peer); + show_one_pdp_v4only(vty, member->peer, pdp_v4only); } } /* show all (active) PDP contexts within an APN */ static void apn_show_pdp_contexts(struct vty *vty, struct apn_ctx *apn) { - ippool_show_pdp_contexts(vty, apn->v4.pool); - ippool_show_pdp_contexts(vty, apn->v6.pool); + ippool_show_pdp_contexts(vty, apn->v4.pool, true); + ippool_show_pdp_contexts(vty, apn->v6.pool, false); } DEFUN(show_pdpctx, show_pdpctx_cmd,