Projects
osmocom:master
libosmo-sigtran
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 69
View file
commit_5f212a4021bc2f4d582183f9e179f477b2dc64bf.txt
Deleted
View file
commit_6318ff83b45f089ab4592e59a5caf81755dc635e.txt
Added
View file
libosmo-sigtran_2.1.0.119.5f21.dsc -> libosmo-sigtran_2.1.0.126.6318.dsc
Changed
@@ -2,7 +2,7 @@ Source: libosmo-sigtran Binary: libosmo-sigtran11, libosmo-sigtran-dbg, libosmo-sigtran-doc, libosmo-sigtran-dev, osmo-stp, osmo-stp-dbg, osmo-stp-doc Architecture: any all -Version: 2.1.0.119.5f21 +Version: 2.1.0.126.6318 Maintainer: Osmocom team <openbsc@lists.osmocom.org> Homepage: https://projects.osmocom.org/projects/libosmo-sccp Standards-Version: 3.9.7 @@ -18,8 +18,8 @@ osmo-stp-dbg deb debug optional arch=any osmo-stp-doc deb doc optional arch=all Checksums-Sha1: - 6cd68afd7f0b5d75185e9fcc1badbcc6eed4fb08 247356 libosmo-sigtran_2.1.0.119.5f21.tar.xz + 5e408407c7fe52b8d3aeaf8c99a2879b08cb8f89 249196 libosmo-sigtran_2.1.0.126.6318.tar.xz Checksums-Sha256: - 455725f8bba06de98ec32c64a2ccfd8189b7da37566862d3da4000460977da94 247356 libosmo-sigtran_2.1.0.119.5f21.tar.xz + c902a46456e657b14cc6f259b47143af5518823659cd2daf0e57afd834c6c929 249196 libosmo-sigtran_2.1.0.126.6318.tar.xz Files: - 8769d4853775a27e0297326136ed6695 247356 libosmo-sigtran_2.1.0.119.5f21.tar.xz + 53dbe536496f8185c31a5dd7eee41c4e 249196 libosmo-sigtran_2.1.0.126.6318.tar.xz
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/.tarball-version -> libosmo-sigtran_2.1.0.126.6318.tar.xz/.tarball-version
Changed
@@ -1 +1 @@ -2.1.0.119-5f21 +2.1.0.126-6318
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/debian/changelog -> libosmo-sigtran_2.1.0.126.6318.tar.xz/debian/changelog
Changed
@@ -1,8 +1,8 @@ -libosmo-sigtran (2.1.0.119.5f21) unstable; urgency=medium +libosmo-sigtran (2.1.0.126.6318) unstable; urgency=medium * Automatically generated changelog entry for building the Osmocom master feed - -- Osmocom OBS scripts <info@osmocom.org> Wed, 02 Jul 2025 13:32:38 +0000 + -- Osmocom OBS scripts <info@osmocom.org> Thu, 03 Jul 2025 12:17:54 +0000 libosmo-sigtran (2.1.0) unstable; urgency=medium
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/include/osmocom/sigtran/sccp_sap.h -> libosmo-sigtran_2.1.0.126.6318.tar.xz/include/osmocom/sigtran/sccp_sap.h
Changed
@@ -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);
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/sccp_scrc.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/sccp_scrc.c
Changed
@@ -70,9 +70,8 @@ static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t dpc) { struct osmo_ss7_instance *ss7 = inst->ss7; - struct osmo_ss7_route *rt; - struct osmo_ss7_route_label rtlabel; char buf_dpcMAX_PC_STR_LEN; + bool found; if (osmo_ss7_pc_is_local(ss7, dpc)) { LOGPSCI(inst, LOGL_DEBUG, "dpc_accessible(DPC=%u=%s): true (local)\n", @@ -80,22 +79,14 @@ return true; } - rtlabel = (struct osmo_ss7_route_label){ - .opc = 0, - .dpc = dpc, - .sls = 0, - }; + found = ss7_route_table_dpc_is_accessible(ss7->rtable_system, dpc); - rt = ss7_instance_lookup_route(ss7, &rtlabel); - if (!rt) { - LOGPSCI(inst, LOGL_INFO, "dpc_accessible(DPC=%u=%s): false\n", - dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc)); - return false; - } + LOGPSCI(inst, found ? LOGL_DEBUG : LOGL_INFO, + "dpc_accessible(DPC=%u=%s): %s\n", + dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc), + found ? "true" : "false"); + return found; - LOGPSCI(inst, LOGL_DEBUG, "dpc_accessible(DPC=%u=%s): true\n", - dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc)); - return true; } static bool sccp_available(struct osmo_sccp_instance *inst,
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7.c
Changed
@@ -89,13 +89,18 @@ return pc_fmt->component_len0 + pc_fmt->component_len1 + pc_fmt->component_len2; } +/* Obtain a full-width mask matching a single DPC in this ss7_instance. */ +uint32_t ss7_pc_full_mask(const struct osmo_ss7_pc_fmt *pc_fmt) +{ + return (1 << osmo_ss7_pc_width(pc_fmt)) - 1; +} + /* truncate pc or mask to maximum permitted length. This solves * callers specifying arbitrary large masks which then evade duplicate * detection with longer mask lengths */ uint32_t osmo_ss7_pc_normalize(const struct osmo_ss7_pc_fmt *pc_fmt, uint32_t pc) { - uint32_t mask = (1 << osmo_ss7_pc_width(pc_fmt))-1; - return pc & mask; + return pc & ss7_pc_full_mask(pc_fmt); } /***********************************************************************
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_combined_linkset.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_combined_linkset.c
Changed
@@ -172,6 +172,20 @@ ss7_combined_linkset_free(clset); } +/* Whether any route in the combined linkset is available: */ +bool ss7_combined_linkset_is_available(const struct osmo_ss7_combined_linkset *clset) +{ + bool avail = false; + struct osmo_ss7_route *rt; + llist_for_each_entry(rt, &clset->routes, list) { + if (ss7_route_is_available(rt)) { + avail = true; + break; + } + } + return avail; +} + static ext_sls_t osmo_ss7_instance_calc_itu_ext_sls(const struct osmo_ss7_instance *inst, const struct osmo_ss7_route_label *rtlabel) { /* Take 6 bits from OPC and DPC according to config: */
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_combined_linkset.h -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_combined_linkset.h
Changed
@@ -57,6 +57,7 @@ ss7_combined_linkset_del_route(struct osmo_ss7_route *rt); struct osmo_ss7_route * ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, const struct osmo_ss7_route_label *rtlabel); +bool ss7_combined_linkset_is_available(const struct osmo_ss7_combined_linkset *clset); #define LOGPCLSET(clset, subsys, level, fmt, args ...) do { \ char _pc_strMAX_PC_STR_LEN; \
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_instance.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_instance.c
Changed
@@ -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. + * \paramint inst cs7 instance where this address belongs + * \paramin name of the address to create + * \paramin 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. + * \paramint inst cs7 instance where this address belongs + * \paramin name of the address to update + * \paramin 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,
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_internal.h -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_internal.h
Changed
@@ -15,6 +15,8 @@ bool ss7_ipv6_sctp_supported(const char *host, bool bind); +uint32_t ss7_pc_full_mask(const struct osmo_ss7_pc_fmt *pc_fmt); + struct osmo_ss7_asp *ss7_asp_find_by_socket_addr(int fd, int trans_proto); bool ss7_asp_protocol_check_trans_proto(enum osmo_ss7_asp_protocol proto, int trans_proto);
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_route.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_route.c
Changed
@@ -38,6 +38,14 @@ * SS7 Routes ***********************************************************************/ + /* ITU Q.704 3.4 Status of signalling routes */ +const struct value_string ss7_route_status_names = { + { OSMO_SS7_ROUTE_STATUS_UNAVAILABLE, "unavailable" }, + { OSMO_SS7_ROUTE_STATUS_AVAILABLE, "available" }, + { OSMO_SS7_ROUTE_STATUS_RESTRICTED, "restricted" }, + {} +}; + /*! \brief Allocate a route entry * \paramin rtbl Routing Table where the route belongs * \paramin pc Point Code of the destination of the route @@ -79,6 +87,7 @@ /* Mark it as not being inserted yet in rtbl */ INIT_LLIST_HEAD(&rt->list); rt->rtable = rtbl; + rt->status = OSMO_SS7_ROUTE_STATUS_AVAILABLE; /* truncate mask to maximum. Let's avoid callers specifying arbitrary large * masks to ensure we don't fail duplicate detection with longer mask lengths */ rt->cfg.mask = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, mask); @@ -262,7 +271,7 @@ const char *osmo_ss7_route_print(const struct osmo_ss7_route *rt) { - static char buf64; + static char bufMAX_PC_STR_LEN * 2 + 1; struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) }; char buf_pcMAX_PC_STR_LEN; const struct osmo_ss7_instance *inst = rt->rtable->inst; @@ -374,9 +383,29 @@ bool ss7_route_is_available(const struct osmo_ss7_route *rt) { OSMO_ASSERT(rt); + if (!ss7_route_dest_is_available(rt)) + return false; + return rt->status == OSMO_SS7_ROUTE_STATUS_AVAILABLE; +} + +bool ss7_route_dest_is_available(const struct osmo_ss7_route *rt) +{ + OSMO_ASSERT(rt); if (rt->dest.as) return osmo_ss7_as_active(rt->dest.as); if (rt->dest.linkset) return ss7_linkset_is_available(rt->dest.linkset); return false; } + +/* Whether route mask identifies a single DPC. */ +bool ss7_route_is_fully_qualified(const struct osmo_ss7_route *rt) +{ + return rt->cfg.mask == ss7_pc_full_mask(&rt->rtable->inst->cfg.pc_fmt); +} + +void ss7_route_update_route_status(struct osmo_ss7_route *rt, enum osmo_ss7_route_status status) +{ + LOGPRT(rt, DLSS7, LOGL_NOTICE, "changed to status '%s'\n", ss7_route_status_name(status)); + rt->status = status; +}
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_route.h -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_route.h
Changed
@@ -15,6 +15,16 @@ #define OSMO_SS7_ROUTE_PRIO_DEFAULT 5 +/* ITU Q.704 3.4 Status of signalling routes */ +enum osmo_ss7_route_status { + OSMO_SS7_ROUTE_STATUS_UNAVAILABLE, + OSMO_SS7_ROUTE_STATUS_AVAILABLE, + OSMO_SS7_ROUTE_STATUS_RESTRICTED, +}; +extern const struct value_string ss7_route_status_names; +static inline const char *ss7_route_status_name(enum osmo_ss7_route_status val) +{ return get_value_string(ss7_route_status_names, val); } + struct osmo_ss7_route { /*! member in \ref osmo_ss7_combined_linkset.routes */ struct llist_head list; @@ -23,6 +33,8 @@ /* Combined linkset this route is part of */ struct osmo_ss7_combined_linkset *clset; + enum osmo_ss7_route_status status; + struct { /*! pointer to linkset (destination) of route */ struct osmo_ss7_linkset *linkset; @@ -59,15 +71,26 @@ int ss7_route_set_linkset(struct osmo_ss7_route *rt, const char *linkset_name); int ss7_route_insert(struct osmo_ss7_route *rt); +bool ss7_route_dest_is_available(const struct osmo_ss7_route *rt); bool ss7_route_is_available(const struct osmo_ss7_route *rt); + +bool ss7_route_is_fully_qualified(const struct osmo_ss7_route *rt); +static inline bool ss7_route_is_summary(const struct osmo_ss7_route *rt) +{ + return !ss7_route_is_fully_qualified(rt); +} + +void ss7_route_update_route_status(struct osmo_ss7_route *rt, enum osmo_ss7_route_status status); + #define LOGPRT(rt, subsys, level, fmt, args ...) do { \ char _pc_strMAX_PC_STR_LEN; \ char _mask_strMAX_PC_STR_LEN; \ _LOGSS7((rt)->rtable->inst, subsys, level, \ - "RT(dpc=%u=%s,mask=0x%x=%s,prio=%u,via=%s) " fmt, \ + "RT(dpc=%u=%s,mask=0x%x=%s,prio=%u,via=%s,st=%s) " fmt, \ (rt)->cfg.pc, osmo_ss7_pointcode_print_buf(_pc_str, MAX_PC_STR_LEN, (rt)->rtable->inst, (rt)->cfg.pc), \ (rt)->cfg.mask, osmo_ss7_pointcode_print_buf(_mask_str, MAX_PC_STR_LEN, (rt)->rtable->inst, (rt)->cfg.mask), \ (rt)->cfg.priority, \ (rt)->cfg.linkset_name ? (rt)->cfg.linkset_name : "", \ + ss7_route_status_name((rt)->status), \ ## args); \ } while (0)
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_route_table.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_route_table.c
Changed
@@ -109,7 +109,7 @@ * This function is used for route management procedures, not for packet routing lookup procedures! */ struct osmo_ss7_route * -ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, +ss7_route_table_find_route_by_dpc_mask(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, bool dynamic) { struct osmo_ss7_combined_linkset *clset; @@ -137,8 +137,43 @@ return NULL; } +/*! \brief Find a SS7 route for given destination point code + mask in given table via given AS. + * + * This function is used for route management procedures, not for packet routing lookup procedures! + */ +struct osmo_ss7_route * +ss7_route_table_find_route_by_dpc_mask_as(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const struct osmo_ss7_as *as, bool dynamic) +{ + struct osmo_ss7_combined_linkset *clset; + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + + dpc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, dpc); + mask = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, mask); + + /* we assume the combined_links are sorted by mask length, i.e. more + * specific combined links first, and less specific combined links with shorter + * mask later */ + llist_for_each_entry(clset, &rtbl->combined_linksets, list) { + if ((dpc & clset->cfg.mask) != clset->cfg.pc) + continue; + if (mask != clset->cfg.mask) + continue; + llist_for_each_entry(rt, &clset->routes, list) { + if (rt->dest.as != as) + continue; + if (rt->cfg.dyn_allocated != dynamic) + continue; + return rt; + } + } + return NULL; +} + struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset_by_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc) +ss7_route_table_find_combined_linkset_by_dpc(const struct osmo_ss7_route_table *rtbl, uint32_t dpc) { struct osmo_ss7_combined_linkset *clset; @@ -157,7 +192,7 @@ } struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask) +ss7_route_table_find_combined_linkset_by_dpc_mask(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask) { struct osmo_ss7_combined_linkset *clset; @@ -178,7 +213,7 @@ } struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio) +ss7_route_table_find_combined_linkset(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio) { struct osmo_ss7_combined_linkset *clset; @@ -209,6 +244,25 @@ return clset; } +void ss7_route_table_update_route_status_by_as(const struct osmo_ss7_route_table *rtbl, enum osmo_ss7_route_status status, + const struct osmo_ss7_as *as, uint32_t dpc) +{ + struct osmo_ss7_combined_linkset *clset; + + llist_for_each_entry(clset, &rtbl->combined_linksets, list) { + struct osmo_ss7_route *rt; + llist_for_each_entry(rt, &clset->routes, list) { + if (rt->dest.as != as) + continue; + if (rt->cfg.pc != dpc) + continue; + if (ss7_route_is_summary(rt)) + continue; /* Only interested in fully qualified routes */ + ss7_route_update_route_status(rt, status); + } + } +} + /* find any routes pointing to this AS and remove them */ void ss7_route_table_del_routes_by_as(struct osmo_ss7_route_table *rtbl, struct osmo_ss7_as *as) { @@ -245,8 +299,10 @@ } } +/* Choose a specific route to transmit a packet. + * Note: This function potentially modifies loadsharing state context of chosen combined linkset. */ struct osmo_ss7_route * -ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel) +ss7_route_table_lookup_route(const struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel) { struct osmo_ss7_combined_linkset *clset; struct osmo_ss7_route *rt; @@ -268,3 +324,20 @@ } return NULL; } + +/* Figure out whether a remote PC is accessible over any route in the routing table. + * Note: Unlike ss7_route_table_lookup_route(), this function is read-only and doesn't modify any state. */ +bool ss7_route_table_dpc_is_accessible(const struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_combined_linkset *clset; + /* we assume the combined_links are sorted by mask length, i.e. more + * specific combined links first, and less specific combined links with shorter + * mask later */ + llist_for_each_entry(clset, &rtbl->combined_linksets, list) { + if ((dpc & clset->cfg.mask) != clset->cfg.pc) + continue; + if (ss7_combined_linkset_is_available(clset)) + return true; + } + return false; +}
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_route_table.h -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_route_table.h
Changed
@@ -9,6 +9,7 @@ ***********************************************************************/ struct osmo_ss7_instance; +enum osmo_ss7_route_status; struct osmo_ss7_route_label { uint32_t opc; @@ -38,21 +39,27 @@ void ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl); struct osmo_ss7_route * -ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, +ss7_route_table_find_route_by_dpc_mask(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, bool dynamic); struct osmo_ss7_route * -ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel); +ss7_route_table_find_route_by_dpc_mask_as(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const struct osmo_ss7_as *as, bool dynamic); +struct osmo_ss7_route * +ss7_route_table_lookup_route(const struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel); +bool ss7_route_table_dpc_is_accessible(const struct osmo_ss7_route_table *rtbl, uint32_t dpc); struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio); +ss7_route_table_find_combined_linkset(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio); struct osmo_ss7_combined_linkset * ss7_route_table_find_or_create_combined_linkset(struct osmo_ss7_route_table *rtbl, uint32_t pc, uint32_t mask, uint32_t prio); struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset_by_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc); +ss7_route_table_find_combined_linkset_by_dpc(const struct osmo_ss7_route_table *rtbl, uint32_t dpc); struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask); +ss7_route_table_find_combined_linkset_by_dpc_mask(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask); struct osmo_ss7_combined_linkset * -ss7_route_table_find_combined_linkset(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio); +ss7_route_table_find_combined_linkset(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio); +void ss7_route_table_update_route_status_by_as(const struct osmo_ss7_route_table *rtbl, enum osmo_ss7_route_status status, + const struct osmo_ss7_as *as, uint32_t dpc); void ss7_route_table_del_routes_by_as(struct osmo_ss7_route_table *rtbl, struct osmo_ss7_as *as); void ss7_route_table_del_routes_by_linkset(struct osmo_ss7_route_table *rtbl, struct osmo_ss7_linkset *lset);
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/ss7_vty.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/ss7_vty.c
Changed
@@ -515,23 +515,48 @@ if ((filter_pc != OSMO_SS7_PC_INVALID) && ((filter_pc & clset->cfg.mask) != clset->cfg.pc)) continue; /* Skip combined linksets not matching destination */ + bool clset_avail = ss7_combined_linkset_is_available(clset); llist_for_each_entry(rt, &clset->routes, list) { - bool rt_avail = ss7_route_is_available(rt); + bool dst_avail = ss7_route_dest_is_available(rt); bool first_rt_in_clset = (rt == llist_first_entry(&clset->routes, struct osmo_ss7_route, list)); + const char *nonadj_str, *rtavail_str; /* Print route str only in first rt in combined linkset. * This allows users to easily determine visually combined * linksets: */ - const char *rt_str = first_rt_in_clset ? osmo_ss7_route_print(rt) : ""; + const char *rt_str, *clsetavail_str; + if (first_rt_in_clset) { + rt_str = osmo_ss7_route_print(rt); + clsetavail_str = clset_avail ? "acces" : "INACC"; + } else { + rt_str = ""; + clsetavail_str = ""; + } + switch (rt->status) { + case OSMO_SS7_ROUTE_STATUS_UNAVAILABLE: + nonadj_str = "PROHIB"; + rtavail_str = "UNAVAIL"; + break; + case OSMO_SS7_ROUTE_STATUS_AVAILABLE: + nonadj_str = "allowed"; + rtavail_str = dst_avail ? "avail" : "UNAVAIL"; + break; + case OSMO_SS7_ROUTE_STATUS_RESTRICTED: + nonadj_str = "RESTRIC"; + rtavail_str = dst_avail ? "RESTRIC" : "UNAVAIL"; + break; + default: + OSMO_ASSERT(0); + } vty_out(vty, "%-16s %-5s %c %c %u %-19s %-7s %-7s %-7s %-3s%s", rt_str, - rt_avail ? "acces" : "INACC", + clsetavail_str, ' ', '0' + rt->cfg.qos_class, rt->cfg.priority, rt->cfg.linkset_name, - rt_avail ? "avail" : "UNAVAIL", - "?", - rt_avail ? "avail" : "UNAVAIL", + dst_avail ? "avail" : "UNAVAIL", + nonadj_str, + rtavail_str, rt->cfg.dyn_allocated ? "dyn" : "", VTY_NEWLINE); } @@ -927,36 +952,34 @@ struct osmo_ss7_instance *inst = (struct osmo_ss7_instance *)vty->index; struct osmo_sccp_addr_entry *entry; const char *name = argv0; + 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;
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/xua_as_fsm.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/xua_as_fsm.c
Changed
@@ -22,9 +22,11 @@ #include "xua_msg.h" #include <osmocom/sigtran/protocol/sua.h> #include <osmocom/sigtran/protocol/m3ua.h> +#include <sys/types.h> #include "ss7_as.h" #include "ss7_asp.h" +#include "ss7_combined_linkset.h" #include "ss7_route.h" #include "ss7_route_table.h" #include "xua_asp_fsm.h" @@ -417,12 +419,79 @@ } } +/* AS became inactive, trigger SNM PC unavailability for PCs it served: */ +static void as_snm_pc_unavailable(struct osmo_ss7_as *as) +{ + struct osmo_ss7_instance *s7i = as->inst; + struct osmo_ss7_route_table *rtbl = s7i->rtable_system; + struct osmo_ss7_combined_linkset *clset; + struct osmo_ss7_route *rt; + uint32_t aff_pc; + + LOGPAS(as, DLSS7, LOGL_INFO, "AS became inactive, some routes to remote PCs may have become unavailable\n"); + /* we assume the combined_links are sorted by mask length, i.e. more + * specific combined links first, and less specific combined links with shorter + * mask later */ + llist_for_each_entry(clset, &rtbl->combined_linksets, list) { + llist_for_each_entry(rt, &clset->routes, list) { + if (rt->dest.as != as) + continue; + if (rt->status == OSMO_SS7_ROUTE_STATUS_UNAVAILABLE) + continue; /* Route was not available before regardless of AS state... */ + if (ss7_route_is_summary(rt)) + continue; /* Only announce changes for fully qualified routes */ + /* We found a PC served by the AS which went down. If no + * alternative route is still in place now towards that PC, announce unavailability + * to upper layers. */ + if (ss7_route_table_dpc_is_accessible(rtbl, rt->cfg.pc)) + continue; + LOGPAS(as, DLSS7, LOGL_INFO, "AS became inactive => remote pc=%u=%s is now unavailable\n", + rt->cfg.pc, osmo_ss7_pointcode_print(s7i, rt->cfg.pc)); + aff_pc = htonl(rt->cfg.pc); + xua_snm_pc_available(as, &aff_pc, 1, NULL, false); + } + } +} + +/* AS became active, trigger SNM PC availability for PCs it served: */ +static void as_snm_pc_available(struct osmo_ss7_as *as) +{ + struct osmo_ss7_instance *s7i = as->inst; + struct osmo_ss7_route_table *rtbl = s7i->rtable_system; + struct osmo_ss7_combined_linkset *clset; + struct osmo_ss7_route *rt; + uint32_t aff_pc; + + LOGPAS(as, DLSS7, LOGL_INFO, "AS became active, some routes to remote PCs may have become available\n"); + /* we assume the combined_links are sorted by mask length, i.e. more + * specific combined links first, and less specific combined links with shorter + * mask later */ + llist_for_each_entry(clset, &rtbl->combined_linksets, list) { + llist_for_each_entry(rt, &clset->routes, list) { + if (rt->dest.as != as) + continue; + if (ss7_route_is_summary(rt)) + continue; /* Only announce changes for fully qualified routes */ + /* We found a PC served by the AS which went up. If there's + * a route now in place towards that PC, announce availability + * to upper layers. */ + if (!ss7_route_table_dpc_is_accessible(rtbl, rt->cfg.pc)) + continue; + LOGPAS(as, DLSS7, LOGL_INFO, "AS became active => remote pc=%u=%s is now available\n", + rt->cfg.pc, osmo_ss7_pointcode_print(s7i, rt->cfg.pc)); + aff_pc = htonl(rt->cfg.pc); + xua_snm_pc_available(as, &aff_pc, 1, NULL, true); + } + } +} + /* onenter call-back responsible of transmitting NTFY to all ASPs in * case of AS state changes */ static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; struct osmo_ss7_as *as = xafp->as; + struct osmo_ss7_instance *s7i = as->inst; struct osmo_xlm_prim_notify npar; switch (fi->state) { @@ -460,15 +529,31 @@ as_notify_all_asp(xafp->as, &npar); - /* only if we are the SG, we must start broadcasting availability information - * to everyone else */ - if (get_local_role(xafp->as) == OSMO_SS7_ASP_ROLE_SG) { + bool became_available = (old_state != XUA_AS_S_ACTIVE && fi->state == XUA_AS_S_ACTIVE); + bool became_unavailable = (old_state == XUA_AS_S_ACTIVE && fi->state != XUA_AS_S_ACTIVE); + int role = get_local_role(xafp->as); + + switch (role) { + case OSMO_SS7_ASP_ROLE_ASP: + if (s7i->sccp) { + if (became_available) + as_snm_pc_available(as); + else if (became_unavailable) + as_snm_pc_unavailable(as); + } + break; + case OSMO_SS7_ASP_ROLE_SG: + /* only if we are the SG, we must start broadcasting availability information + * to everyone else */ /* advertise availability of the routing key to others */ - uint32_t aff_pc = htonl(as->cfg.routing_key.pc); - if (old_state != XUA_AS_S_ACTIVE && fi->state == XUA_AS_S_ACTIVE) - xua_snm_pc_available(as, &aff_pc, 1, NULL, true); - else if (old_state == XUA_AS_S_ACTIVE && fi->state != XUA_AS_S_ACTIVE) - xua_snm_pc_available(as, &aff_pc, 1, NULL, false); + if (became_available || became_unavailable) { + uint32_t aff_pc = htonl(as->cfg.routing_key.pc); + xua_snm_pc_available(as, &aff_pc, 1, NULL, became_available); + } + break; + case OSMO_SS7_ASP_ROLE_IPSP: + /* TODO */ + break; } };
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/src/xua_snm.c -> libosmo-sigtran_2.1.0.126.6318.tar.xz/src/xua_snm.c
Changed
@@ -33,6 +33,7 @@ #include "ss7_as.h" #include "ss7_asp.h" +#include "ss7_route.h" #include "ss7_internal.h" #include "ss7_route_table.h" #include "xua_internal.h" @@ -149,6 +150,59 @@ } } +/* Figure 43/Q.704, Figure 44/Q.704 */ +/* RFC4666 1.4.2.5: "maintain a dynamic table of available SGP routes + * for the SS7 destinations, taking into account the SS7 destination + * availability/restricted/congestion status received from the SGP "*/ +static void xua_snm_srm_pc_available_single(struct osmo_ss7_as *as, uint32_t pc, bool available) +{ + struct osmo_ss7_instance *s7i = as->inst; + enum osmo_ss7_route_status new_status; + struct osmo_ss7_route *rt; + + new_status = available ? OSMO_SS7_ROUTE_STATUS_AVAILABLE : + OSMO_SS7_ROUTE_STATUS_UNAVAILABLE; + + /* Check if we already have a dynamic fully qualified route towards that AS: */ + rt = ss7_route_table_find_route_by_dpc_mask_as(s7i->rtable_system, pc, 0xffffff, as, true); + if (!rt) { + /* No dynamic fully qualified route found. Add dynamic fully + * squalified route and mark it as (un)available: */ + rt = ss7_route_create(s7i->rtable_system, pc, 0xffffff, true, as->cfg.name); + if (!rt) { + LOGPAS(as, DLSS7, LOGL_ERROR, "Unable to create dynamic route for pc=%u=%s status=%s\n", + pc, osmo_ss7_pointcode_print(s7i, pc), ss7_route_status_name(new_status)); + return; + } + ss7_route_update_route_status(rt, new_status); + /* No need to iterate over rtable below, since we know there was no route: */ + return; + } + ss7_route_table_update_route_status_by_as(s7i->rtable_system, new_status, as, pc); +} +static void xua_snm_srm_pc_available(struct osmo_ss7_as *as, + const uint32_t *aff_pc, unsigned int num_aff_pc, + bool available) +{ + for (unsigned int i = 0; i < num_aff_pc; i++) { + /* 32bit "Affected Point Code" consists of a 7-bit mask followed by 14/16/24-bit SS7 PC, + * see RFC 4666 3.4.1 */ + uint32_t _aff_pc = ntohl(aff_pci); + uint32_t pc = _aff_pc & 0xffffff; + uint8_t mask = _aff_pc >> 24; + + if (!mask) { + xua_snm_srm_pc_available_single(as, pc, available); + } else { + /* Update only full DPC routes. */ + uint32_t maskbits = (1 << mask) - 1; + uint32_t fullpc; + for (fullpc = (pc & ~maskbits); fullpc <= (pc | maskbits); fullpc++) + xua_snm_srm_pc_available_single(as, fullpc, available); + } + } +} + /* advertise availability of point codes (with masks) */ void xua_snm_pc_available(struct osmo_ss7_as *as, const uint32_t *aff_pc, unsigned int num_aff_pc, const char *info_str, bool available) @@ -158,6 +212,9 @@ uint32_t rctxOSMO_SS7_MAX_RCTX_COUNT; unsigned int num_rctx; + xua_snm_srm_pc_available(as, aff_pc, num_aff_pc, available); + + /* inform local users via a MTP-{PAUSE, RESUME} primitive */ if (s7i->sccp) xua_snm_pc_available_to_sccp(s7i->sccp, aff_pc, num_aff_pc, available); @@ -318,16 +375,10 @@ uint8_t mask = _aff_pc >> 24; bool is_available; - struct osmo_ss7_route_label rtlabel = { - .opc = xua->mtp.opc, /* Use OPC of received DAUD. */ - .dpc = pc, - .sls = 0, - }; - if (mask == 0) { /* one single point code */ /* Check if there's an "active" route available: */ - is_available = !!ss7_instance_lookup_route(s7i, &rtlabel); + is_available = ss7_route_table_dpc_is_accessible(s7i->rtable_system, pc); xua_tx_snm_available(asp, rctx, num_rctx, &aff_pci, 1, "Response to DAUD", is_available); @@ -340,8 +391,7 @@ uint32_t *aff_pc_avail = talloc_size(asp, sizeof(uint32_t)*(1 << mask)); uint32_t *aff_pc_unavail = talloc_size(asp, sizeof(uint32_t)*(1 << mask)); for (fullpc = (pc & ~maskbits); fullpc <= (pc | maskbits); fullpc++) { - rtlabel.dpc = fullpc; - is_available = !!ss7_instance_lookup_route(s7i, &rtlabel); + is_available = ss7_route_table_dpc_is_accessible(s7i->rtable_system, fullpc); if (is_available) aff_pc_availnum_aff_pc_avail++ = htonl(fullpc); /* mask = 0 */ else
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/tests/vty/osmo_stp_route_prio.vty -> libosmo-sigtran_2.1.0.126.6318.tar.xz/tests/vty/osmo_stp_route_prio.vty
Changed
@@ -92,9 +92,9 @@ Destination C Q P Linkset Name Linkset Non-adj Route ---------------------- - - - ------------------- ------- ------- ------- -3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 2 as3 UNAVAIL allowed UNAVAIL +3.2.1/14 INACC 0 5 as2 UNAVAIL allowed UNAVAIL +3.2.1/14 INACC 7 6 as1 UNAVAIL allowed UNAVAIL OsmoSTP(config-cs7-rt)# ! NOW ADD MORE GENERIC ROUTES (SMALLER BITMASK LENGTH) OsmoSTP(config-cs7-rt)# update route 3.2.0 7.255.0 linkset as3 priority 3 @@ -122,14 +122,14 @@ Destination C Q P Linkset Name Linkset Non-adj Route ---------------------- - - - ------------------- ------- ------- ------- -3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 1 as1 UNAVAIL ? UNAVAIL - INACC 0 1 as2 UNAVAIL ? UNAVAIL - INACC 0 1 as3 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 2 as3 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 3 as3 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 2 as3 UNAVAIL allowed UNAVAIL +3.2.1/14 INACC 0 5 as2 UNAVAIL allowed UNAVAIL +3.2.1/14 INACC 7 6 as1 UNAVAIL allowed UNAVAIL +3.2.0/11 INACC 0 1 as1 UNAVAIL allowed UNAVAIL + 0 1 as2 UNAVAIL allowed UNAVAIL + 0 1 as3 UNAVAIL allowed UNAVAIL +3.2.0/11 INACC 0 2 as3 UNAVAIL allowed UNAVAIL +3.2.0/11 INACC 0 3 as3 UNAVAIL allowed UNAVAIL OsmoSTP(config-cs7-rt)# do show cs7 instance 0 route binding-table 3.2.1
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/tests/vty/osmo_stp_test.vty -> libosmo-sigtran_2.1.0.126.6318.tar.xz/tests/vty/osmo_stp_test.vty
Changed
@@ -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
View file
libosmo-sigtran_2.1.0.119.5f21.tar.xz/tests/vty/ss7_asp_test.vty -> libosmo-sigtran_2.1.0.126.6318.tar.xz/tests/vty/ss7_asp_test.vty
Changed
@@ -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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.