pespin has uploaded this change for review.

View Change

sccp_sap.h: Add APIs to insert and update addresses in address book

This will be used by applications to dynamically add addresses in the
address book, which later on libosmo-sigtran can make use of to eg. send
DAUD for intereting DPCs.

Change-Id: I9d2452d9cc8e443050927a047b7ebacd2b2f37e1
---
M include/osmocom/sigtran/sccp_sap.h
M src/ss7_instance.c
M src/ss7_vty.c
M tests/vty/osmo_stp_test.vty
M tests/vty/ss7_asp_test.vty
5 files changed, 93 insertions(+), 27 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/61/40561/1
diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h
index 98a48be..65eff74 100644
--- a/include/osmocom/sigtran/sccp_sap.h
+++ b/include/osmocom/sigtran/sccp_sap.h
@@ -330,12 +330,12 @@
int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph);
int osmo_sccp_user_sap_down_nofree(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph);

+int osmo_sccp_addr_create(struct osmo_ss7_instance *inst, const char *name, const struct osmo_sccp_addr *dest_addr);
+int osmo_sccp_addr_update(struct osmo_ss7_instance *inst, const char *name, const struct osmo_sccp_addr *dest_addr);
struct osmo_ss7_instance *osmo_sccp_addr_by_name(struct osmo_sccp_addr *dest_addr, const char *name);
int osmo_sccp_addr_by_name_local(struct osmo_sccp_addr *dest_addr, const char *name,
const struct osmo_ss7_instance *inst);
-
const char *osmo_sccp_name_by_addr(const struct osmo_sccp_addr *addr);
-
void osmo_sccp_local_addr_by_instance(struct osmo_sccp_addr *dest_addr,
const struct osmo_sccp_instance *inst,
uint32_t ssn);
diff --git a/src/ss7_instance.c b/src/ss7_instance.c
index ef0fbd8..b583b98 100644
--- a/src/ss7_instance.c
+++ b/src/ss7_instance.c
@@ -619,6 +619,74 @@
* (see also .cfg in struct osmo_ss7_instance) */
LLIST_HEAD(sccp_address_book_global);

+static struct osmo_sccp_addr_entry *addr_entry_alloc(struct osmo_ss7_instance *inst, const char *name,
+ const struct osmo_sccp_addr *addr)
+{
+ struct osmo_sccp_addr_entry *entry;
+
+ entry = talloc_zero(inst, struct osmo_sccp_addr_entry);
+ OSMO_STRLCPY_ARRAY(entry->name, name);
+ entry->inst = inst;
+ memcpy(&entry->addr, addr, sizeof(entry->addr));
+ llist_add_tail(&entry->list, &inst->cfg.sccp_address_book);
+ llist_add_tail(&entry->list_global, &sccp_address_book_global);
+ return entry;
+}
+
+/*! \brief Add an SCCP address entry to the addressbook.
+ * \param[int] inst cs7 instance where this address belongs
+ * \param[in] name of the address to create
+ * \param[in] dest_addr address value to add to the addressbook.
+ * \returns 0 on success, negative error code on error.
+ *
+ * Validates that the name is unique among all cs7 instances of the process, and
+ * that no such entry already exists. */
+int osmo_sccp_addr_create(struct osmo_ss7_instance *inst, const char *name,
+ const struct osmo_sccp_addr *dest_addr)
+{
+ struct osmo_sccp_addr_entry *entry;
+ if (strlen(name) >= sizeof(entry->name)) {
+ LOGSS7(inst, LOGL_ERROR, "%s: SCCP address name too long: '%s'\n",
+ __func__, name);
+ return -ENOSPC;
+ }
+
+ /* Ensure that we do not use address names that
+ * are already used in other ss7 instances. */
+ entry = addr_entry_by_name_global(name);
+ if (entry) {
+ LOGSS7(inst, LOGL_ERROR, "%s: SCCP address name already used in cs7 instance %u: '%s'\n",
+ __func__, entry->inst->cfg.id, entry->name);
+ return -EALREADY;
+ }
+
+ entry = addr_entry_alloc(inst, name, dest_addr);
+ OSMO_ASSERT(entry);
+ return 0;
+}
+
+/*! \brief Update the value of an SCCP address entry already present in the addressbook.
+ * \param[int] inst cs7 instance where this address belongs
+ * \param[in] name of the address to update
+ * \param[in] dest_addr address value to store in the addressbook.
+ * \returns 0 on success, negative error code on error.
+ */
+int osmo_sccp_addr_update(struct osmo_ss7_instance *inst, const char *name, const struct osmo_sccp_addr *dest_addr)
+{
+ struct osmo_sccp_addr_entry *entry;
+
+ /* Ensure that we do not use address names that
+ * are already used in other ss7 instances. */
+ entry = addr_entry_by_name_local(name, inst);
+ if (!entry) {
+ LOGSS7(inst, LOGL_ERROR, "%s: SCCP address '%s' not found in cs7 instance %u\n",
+ __func__, name, inst->cfg.id);
+ return -ENOKEY;
+ }
+ memcpy(&entry->addr, dest_addr, sizeof(entry->addr));
+ return 0;
+}
+
/* Pick an SCCP address entry from the addressbook list by its name */
struct osmo_sccp_addr_entry
*addr_entry_by_name_local(const char *name,
diff --git a/src/ss7_vty.c b/src/ss7_vty.c
index 9e9ceaa..a3f1a34 100644
--- a/src/ss7_vty.c
+++ b/src/ss7_vty.c
@@ -952,36 +952,34 @@
struct osmo_ss7_instance *inst = (struct osmo_ss7_instance *)vty->index;
struct osmo_sccp_addr_entry *entry;
const char *name = argv[0];
+ int rc;

- if (strlen(name) >= sizeof(entry->name)) {
- vty_out(vty, "Error: SCCP address name too long: '%s'%s",
- name, VTY_NEWLINE);
- return CMD_ERR_INCOMPLETE;
- }
-
- /* Ensure that we do not use address names that
- * are already used in other ss7 instances. */
- entry = addr_entry_by_name_global(name);
- if (entry != NULL) {
- vty_out(vty,
- "Error: SCCP address name already used in cs7 instance %u: '%s'%s",
- entry->inst->cfg.id, entry->name, VTY_NEWLINE);
- return CMD_ERR_INCOMPLETE;
+ entry = addr_entry_by_name_local(name, inst);
+ if (!entry) {
+ /* Create a new addressbook entry if we can not find an
+ * already existing entry */
+ struct osmo_sccp_addr sccp_addr = {
+ .ri = OSMO_SCCP_RI_SSN_PC,
+ };
+ rc = osmo_sccp_addr_create(inst, name, &sccp_addr);
+ if (rc < 0) {
+ if (rc == -ENOSPC)
+ vty_out(vty, "Error: SCCP address name too long: '%s'%s",
+ name, VTY_NEWLINE);
+ if (rc == -EALREADY)
+ vty_out(vty, "Error: SCCP address name already used in cs7 instance other than %u: '%s'%s",
+ inst->cfg.id, name, VTY_NEWLINE);
+ return CMD_ERR_INCOMPLETE;
+ }
}

entry = addr_entry_by_name_local(name, inst);
-
- /* Create a new addressbook entry if we can not find an
- * already existing entry */
if (!entry) {
- entry = talloc_zero(inst, struct osmo_sccp_addr_entry);
- osmo_strlcpy(entry->name, name, sizeof(entry->name));
- llist_add_tail(&entry->list, &inst->cfg.sccp_address_book);
- llist_add_tail(&entry->list_global, &sccp_address_book_global);
- entry->addr.ri = OSMO_SCCP_RI_SSN_PC;
+ vty_out(vty, "%% Error: Unable to find SCCP address '%s' just created in instance %u%s",
+ name, inst->cfg.id, VTY_NEWLINE);
+ return CMD_WARNING;
}

- entry->inst = (struct osmo_ss7_instance *)vty->index;
vty->node = L_CS7_SCCPADDR_NODE;
vty->index = entry;

diff --git a/tests/vty/osmo_stp_test.vty b/tests/vty/osmo_stp_test.vty
index 2c5b5d8..4502c74 100644
--- a/tests/vty/osmo_stp_test.vty
+++ b/tests/vty/osmo_stp_test.vty
@@ -259,7 +259,7 @@
OsmoSTP(config-cs7)# exit
OsmoSTP(config)# cs7 instance 1
OsmoSTP(config-cs7)# sccp-address foo
-Error: SCCP address name already used in cs7 instance 0: 'foo'
+Error: SCCP address name already used in cs7 instance other than 1: 'foo'
% Command incomplete.
OsmoSTP(config-cs7)# sccp-address bar
OsmoSTP(config-cs7-sccpaddr)# point-code 1.2.3
diff --git a/tests/vty/ss7_asp_test.vty b/tests/vty/ss7_asp_test.vty
index b565557..2bf753d 100644
--- a/tests/vty/ss7_asp_test.vty
+++ b/tests/vty/ss7_asp_test.vty
@@ -238,7 +238,7 @@
ss7_asp_vty_test(config-cs7)# exit
ss7_asp_vty_test(config)# cs7 instance 1
ss7_asp_vty_test(config-cs7)# sccp-address foo
-Error: SCCP address name already used in cs7 instance 0: 'foo'
+Error: SCCP address name already used in cs7 instance other than 1: 'foo'
% Command incomplete.
ss7_asp_vty_test(config-cs7)# sccp-address bar
ss7_asp_vty_test(config-cs7-sccpaddr)# point-code 1.2.3

To view, visit change 40561. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I9d2452d9cc8e443050927a047b7ebacd2b2f37e1
Gerrit-Change-Number: 40561
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>