pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40561?usp=email )
Change subject: sccp_sap.h: Add APIs to insert and update addresses in address book ...................................................................... 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(-) Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved laforge: Looks good to me, but someone else must approve daniel: Looks good to me, but someone else must approve 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 https://gerrit.osmocom.org/c/libosmo-sigtran/+/40561?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: libosmo-sigtran Gerrit-Branch: master Gerrit-Change-Id: I9d2452d9cc8e443050927a047b7ebacd2b2f37e1 Gerrit-Change-Number: 40561 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillm...@sysmocom.de> Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: pespin <pes...@sysmocom.de>