diff options
-rw-r--r-- | TODO-RELEASE | 1 | ||||
-rw-r--r-- | include/osmocom/sigtran/osmo_ss7.h | 6 | ||||
-rw-r--r-- | src/osmo_ss7.c | 257 | ||||
-rw-r--r-- | src/osmo_ss7_vty.c | 24 | ||||
-rw-r--r-- | tests/vty/ss7_asp_test.vty | 38 |
5 files changed, 296 insertions, 30 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE index 753e24a..306eed9 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -12,3 +12,4 @@ libosmo-netif > 1.3.0 uses osmo_stream_*_set_name() libosmo-sccp add API osmo_ss7_asp_get_name(), osmo_ss7_asp_get_proto() osmo_sccp_simple_client_on_ss7_id() behavior change: ASPs asp-clnt-* defined through VTY must explicitly configure "role" and "sctp-role" libosmo-netif > 1.3.0 flag OSMO_STREAM_SCTP_MSG_FLAGS_NOTIFICATION set by osmo_stream_cli_recv() +libosmo-sccp add API osmo_ss7_asp_peer_init(), osmo_ss7_asp_peer_set_hosts2(), osmo_ss7_asp_peer_add_host2() diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 1197ddf..ed3d409 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -366,6 +366,8 @@ struct osmo_ss7_asp_peer { char *host[OSMO_SOCK_MAX_ADDRS]; size_t host_cnt; uint16_t port; + /* index in "hosts" array marking the SCTP Primary Address, -1 if no explicit Primary Address set */ + int idx_primary; }; enum osmo_ss7_asp_admin_state { @@ -451,9 +453,13 @@ struct osmo_ss7_asp { #define OSMO_SS7_ASP_QUIRK_SNM_INACTIVE 0x00000004 int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_peer *peer); +void osmo_ss7_asp_peer_init(struct osmo_ss7_asp_peer *peer); int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt); +int osmo_ss7_asp_peer_set_hosts2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, + const char *const*hosts, size_t host_cnt, int idx_primary); int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *host); +int osmo_ss7_asp_peer_add_host2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *host, bool is_primary_addr); struct osmo_ss7_asp * osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 5befdee..7882bc2 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -125,6 +125,59 @@ static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst) return -1; } +static int _setsockopt_peer_primary_addr(int fd, const struct osmo_sockaddr *saddr) +{ + int rc; + + struct sctp_setpeerprim so_sctp_setpeerprim = {0}; + + /* rfc6458 sec 8: "For the one-to-one style sockets and branched-off one-to-many + * style sockets (see Section 9.2), this association ID parameter is ignored" + */ + + /* NOTE: Requires setting: + * - sysctl net.sctp.addip_enable = 1, otherwise EPERM is returned + * - sysctl net.sctp.auth_enable = 1, RFC 5061 4.2.7 "An implementation supporting this + * extension MUST list the ASCONF,the ASCONF-ACK, and the AUTH chunks in + * its INIT and INIT-ACK parameters." + */ + + so_sctp_setpeerprim.sspp_addr = saddr->u.sas; + rc = setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, + &so_sctp_setpeerprim, sizeof(so_sctp_setpeerprim)); + if (rc < 0) { + char buf[128]; + int err = errno; + strerror_r(err, (char *)buf, sizeof(buf)); + LOGP(DLSS7, LOGL_ERROR, "setsockopt(SCTP_SET_PEER_PRIMARY_ADDR, %s) failed: %s%s\n", + osmo_sockaddr_to_str(saddr), buf, + err == EPERM ? " (EPERM: Make sure you have sysctl 'net.sctp.auth_enable' " + "and 'net.sctp.addip_enable' set to 1)" : ""); + } + return rc; +} + +static int _setsockopt_primary_addr(int fd, const struct osmo_sockaddr *saddr) +{ + int rc; + + struct sctp_prim so_sctp_prim = {0}; + + /* rfc6458 sec 8: "For the one-to-one style sockets and branched-off one-to-many + * style sockets (see Section 9.2), this association ID parameter is ignored" + */ + + so_sctp_prim.ssp_addr = saddr->u.sas; + rc = setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, + &so_sctp_prim, sizeof(so_sctp_prim)); + if (rc < 0) { + char buf[128]; + strerror_r(errno, (char *)buf, sizeof(buf)); + LOGP(DLSS7, LOGL_ERROR, "setsockopt(SCTP_PRIMARY_ADDR, %s) failed: %s\n", + osmo_sockaddr_to_str(saddr), buf); + } + return rc; +} /*********************************************************************** * SS7 Point Code Parsing / Printing @@ -1179,11 +1232,18 @@ static const struct rate_ctr_group_desc ss7_asp_rcgd = { }; static unsigned int g_ss7_asp_rcg_idx; +void osmo_ss7_asp_peer_init(struct osmo_ss7_asp_peer *peer) +{ + memset(peer, 0, sizeof(*peer)); + peer->idx_primary = -1; +} + int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_peer *peer) { int len = 0, offset = 0, rem = buf_len; int ret, i; char *after; + char *primary; if (buf_len < 3) return -EINVAL; @@ -1195,11 +1255,12 @@ int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_pe OSMO_SNPRINTF_RET(ret, rem, offset, len); } for (i = 0; i < peer->host_cnt; i++) { + primary = (peer->idx_primary == i) ? "*" : ""; if (peer->host_cnt == 1) after = ""; else after = (i == (peer->host_cnt - 1)) ? ")" : "|"; - ret = snprintf(buf + offset, rem, "%s%s", peer->host[i] ? : "0.0.0.0", after); + ret = snprintf(buf + offset, rem, "%s%s%s", peer->host[i] ? : "0.0.0.0", primary, after); OSMO_SNPRINTF_RET(ret, rem, offset, len); } ret = snprintf(buf + offset, rem, ":%u", peer->port); @@ -1215,11 +1276,15 @@ int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_pe * \param[in] talloc_ctx talloc context used to allocate new addresses. * \param[in] hosts Array of strings containing IP addresses. * \param[in] host_cnt Number of strings in hosts + * \param[in] idx_primary Index in "hosts" array marking the SCTP Primary Address, -1 if no explicit Primary Address set * \returns 0 on success; negative otherwise */ -int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt) +int osmo_ss7_asp_peer_set_hosts2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt, int idx_primary) { int i = 0; + if (idx_primary >= (int)host_cnt || idx_primary < -1) + return -EINVAL; + if (host_cnt > ARRAY_SIZE(peer->host)) return -EINVAL; @@ -1231,9 +1296,21 @@ int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx } peer->host_cnt = host_cnt; + peer->idx_primary = idx_primary; return 0; } +/*! \brief Set (copy) addresses for a given ASP peer. Previous addresses are freed. + * \param[in] peer Application Server Process peer whose addresses are to be set. + * \param[in] talloc_ctx talloc context used to allocate new addresses. + * \param[in] hosts Array of strings containing IP addresses. + * \param[in] host_cnt Number of strings in hosts + * \returns 0 on success; negative otherwise */ +int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt) +{ + return osmo_ss7_asp_peer_set_hosts2(peer, talloc_ctx, hosts, host_cnt, -1); +} + /* Is string formatted IPv4/v6 addr considered IN(6)ADDR_ANY? */ static inline bool host_is_ip_anyaddr(const char *host, bool is_v6) { @@ -1247,38 +1324,160 @@ static inline bool host_is_ip_anyaddr(const char *host, bool is_v6) /*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept. * \param[in] peer Application Server Process peer the address is appended to. * \param[in] talloc_ctx talloc context used to allocate new address. - * \param[in] host string containing an IP addresses. + * \param[in] host string containing an IP address. + * \param[in] is_primary_addr whether this IP address is to be added as SCTP Primary Address * \returns 0 on success; negative otherwise */ -int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *host) +int osmo_ss7_asp_peer_add_host2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, + const char *host, bool is_primary_addr) { int i; bool new_is_v6 = osmo_ip_str_type(host) == AF_INET6; bool new_is_any = host_is_ip_anyaddr(host, new_is_v6); - bool iter_is_v6; + struct osmo_sockaddr_str addr_str; - if (peer->host_cnt >= ARRAY_SIZE(peer->host)) + if (osmo_sockaddr_str_from_str(&addr_str, host, 0) < 0) return -EINVAL; - /* Makes no sense to have INET(6)_ANY many times, or INET(6)_ANY - together with specific addresses, be it of same or different - IP version:*/ - if (new_is_any && peer->host_cnt != 0) - return -EINVAL; + if (new_is_any) { + /* Makes no sense to have INET(6)_ANY many times, or INET(6)_ANY + * together with specific addresses, be it of same or different + * IP version: */ + if (peer->host_cnt != 0) + return -EINVAL; + + /* Makes no sense to have INET(6)_ANY as primary: */ + if (is_primary_addr) + return -EINVAL; + + if (peer->host_cnt >= ARRAY_SIZE(peer->host)) + return -EINVAL; + osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host); + peer->host_cnt++; + return 0; + } + + /* Makes no sense to add specific address to set if INET(6)_ANY + * is already set, be it from same or different IP version: */ + for (i = 0; i < peer->host_cnt; i++) { + bool iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6; + if (host_is_ip_anyaddr(peer->host[i], iter_is_v6)) + return -EINVAL; + } + /* Reached this point, no INET(6)_ANY address is set nor we are adding an INET(6)_ANY address. */ + + /* Check if address already exists, and then if primary flags need to be changed: */ + for (i = 0; i < peer->host_cnt; i++) { + struct osmo_sockaddr_str it_addr_str; + bool it_is_primary; + osmo_sockaddr_str_from_str(&it_addr_str, peer->host[i], 0); - if (!new_is_any) { - /* Makes no sense to add specific address to set if INET(6)_ANY - is already set, be it from same or different IP version: */ - for (i = 0; i < peer->host_cnt; i++) { - iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6; - if (host_is_ip_anyaddr(peer->host[i], iter_is_v6)) - return -EINVAL; + if (osmo_sockaddr_str_cmp(&addr_str, &it_addr_str) != 0) + continue; + it_is_primary = (peer->idx_primary == i); + if (is_primary_addr == it_is_primary) { + /* Nothing to do, return below */ + } else if (is_primary_addr && !it_is_primary) { + /* Mark it as primary: */ + peer->idx_primary = i; + } else { /* if (!is_primary_addr && it_is_primary) { */ + /* mark it as non-primary: */ + peer->idx_primary = -1; } + return 0; } + + if (peer->host_cnt >= ARRAY_SIZE(peer->host)) + return -EINVAL; + osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host); + if (is_primary_addr) + peer->idx_primary = peer->host_cnt; peer->host_cnt++; return 0; } +/*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept. + * \param[in] peer Application Server Process peer the address is appended to. + * \param[in] talloc_ctx talloc context used to allocate new address. + * \param[in] host string containing an IP address. + * \returns 0 on success; negative otherwise */ +int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, + const char *host) +{ + return osmo_ss7_asp_peer_add_host2(peer, talloc_ctx, host, false); +} + +static int asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp) +{ + struct osmo_fd *ofd; + struct osmo_sockaddr_str addr_str; + struct osmo_sockaddr addr; + uint16_t local_port; + int rc; + + /* No SCTP Peer Primary Address explicitly configured, do nothing. */ + if (asp->cfg.local.idx_primary == -1) + return 0; + OSMO_ASSERT(asp->cfg.local.idx_primary < asp->cfg.local.host_cnt); + + if (asp->cfg.is_server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else + ofd = osmo_stream_cli_get_ofd(asp->client); + + if (asp->cfg.local.port == 0) { + char port_buf[16]; + osmo_sock_get_local_ip_port(ofd->fd, port_buf, sizeof(port_buf)); + local_port = atoi(port_buf); + } else { + local_port = asp->cfg.local.port; + } + rc = osmo_sockaddr_str_from_str(&addr_str, + asp->cfg.local.host[asp->cfg.local.idx_primary], + local_port); + if (rc < 0) + return rc; + rc = osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) + return rc; + LOGPASP(asp, DLSS7, LOGL_INFO, "Set Peer's Primary Address %s\n", + osmo_sockaddr_to_str(&addr)); + rc = _setsockopt_peer_primary_addr(ofd->fd, &addr); + + return rc; +} + +static int asp_apply_primary_address(const struct osmo_ss7_asp *asp) +{ + struct osmo_fd *ofd; + struct osmo_sockaddr_str addr_str; + struct osmo_sockaddr addr; + int rc; + + /* No SCTP Primary Address explicitly configured, do nothing. */ + if (asp->cfg.remote.idx_primary == -1) + return 0; + OSMO_ASSERT(asp->cfg.remote.idx_primary < asp->cfg.remote.host_cnt); + + if (asp->cfg.is_server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else + ofd = osmo_stream_cli_get_ofd(asp->client); + + rc = osmo_sockaddr_str_from_str(&addr_str, + asp->cfg.remote.host[asp->cfg.remote.idx_primary], + asp->cfg.remote.port); + if (rc < 0) + return rc; + rc = osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) + return rc; + LOGPASP(asp, DLSS7, LOGL_INFO, "Set Primary Address %s\n", + osmo_sockaddr_to_str(&addr)); + rc = _setsockopt_primary_addr(ofd->fd, &addr); + return rc; +} + static bool ipv6_sctp_supported(const char *host, bool bind) { int rc; @@ -1534,7 +1733,9 @@ osmo_ss7_asp_alloc(struct osmo_ss7_instance *inst, const char *name, } rate_ctr_group_set_name(asp->ctrg, name); asp->inst = inst; + osmo_ss7_asp_peer_init(&asp->cfg.remote); asp->cfg.remote.port = remote_port; + osmo_ss7_asp_peer_init(&asp->cfg.local); asp->cfg.local.port = local_port; asp->cfg.proto = proto; asp->cfg.name = talloc_strdup(asp, name); @@ -1849,6 +2050,7 @@ static int xua_cli_connect_cb(struct osmo_stream_cli *cli) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(cli); struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + int rc = 0; /* update the socket name */ talloc_free(asp->sock_name); @@ -1856,6 +2058,15 @@ static int xua_cli_connect_cb(struct osmo_stream_cli *cli) LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); + /* Now that we have the conn in place, the local/remote addresses are + * fed and the local port is known for sure. Apply SCTP Primary addresses + * if needed: + */ + if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) { + rc = asp_apply_peer_primary_address(asp); + rc = asp_apply_primary_address(asp); + } + if (asp->lm && asp->lm->prim_cb) { /* Notify layer manager that a connection has been * established */ @@ -1865,7 +2076,7 @@ static int xua_cli_connect_cb(struct osmo_stream_cli *cli) osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); } - return 0; + return rc; } static void xua_cli_close(struct osmo_stream_cli *cli) @@ -2016,6 +2227,7 @@ static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); const char *proto_name = get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto); + int rc = 0; LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", sock_name, proto_name); @@ -2105,11 +2317,16 @@ static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) * data */ osmo_stream_srv_set_data(srv, asp); + if (oxs->cfg.proto != OSMO_SS7_ASP_PROT_IPA) { + rc = asp_apply_peer_primary_address(asp); + rc = asp_apply_primary_address(asp); + } + /* send M-SCTP_ESTABLISH.ind to Layer Manager */ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_EST_IND, 0); xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); - return 0; + return rc; } /*! \brief send a fully encoded msgb via a given ASP diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 61f14cd..44ba780 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -656,14 +656,17 @@ DEFUN_ATTR(no_cs7_asp, no_cs7_asp_cmd, } DEFUN_ATTR(asp_local_ip, asp_local_ip_cmd, - "local-ip " VTY_IPV46_CMD, + "local-ip " VTY_IPV46_CMD " [primary]", "Specify Local IP Address from which to contact ASP\n" "Local IPv4 Address from which to contact of ASP\n" - "Local IPv6 Address from which to contact of ASP\n", + "Local IPv6 Address from which to contact of ASP\n" + "Signal the SCTP peer to use this address as Primary Address\n", CMD_ATTR_NODE_EXIT) { struct osmo_ss7_asp *asp = vty->index; - if (osmo_ss7_asp_peer_add_host(&asp->cfg.local, asp, argv[0]) != 0) { + bool is_primary = argc > 1; + + if (osmo_ss7_asp_peer_add_host2(&asp->cfg.local, asp, argv[0], is_primary) != 0) { vty_out(vty, "%% Failed adding host '%s' to set%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } @@ -671,14 +674,17 @@ DEFUN_ATTR(asp_local_ip, asp_local_ip_cmd, } DEFUN_ATTR(asp_remote_ip, asp_remote_ip_cmd, - "remote-ip " VTY_IPV46_CMD, + "remote-ip " VTY_IPV46_CMD " [primary]", "Specify Remote IP Address of ASP\n" "Remote IPv4 Address of ASP\n" - "Remote IPv6 Address of ASP\n", + "Remote IPv6 Address of ASP\n" + "Set remote address as SCTP Primary Address\n", CMD_ATTR_NODE_EXIT) { struct osmo_ss7_asp *asp = vty->index; - if (osmo_ss7_asp_peer_add_host(&asp->cfg.remote, asp, argv[0]) != 0) { + bool is_primary = argc > 1; + + if (osmo_ss7_asp_peer_add_host2(&asp->cfg.remote, asp, argv[0], is_primary) != 0) { vty_out(vty, "%% Failed adding host '%s' to set%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } @@ -937,11 +943,13 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp, bool show_d vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); for (i = 0; i < asp->cfg.local.host_cnt; i++) { if (asp->cfg.local.host[i]) - vty_out(vty, " local-ip %s%s", asp->cfg.local.host[i], VTY_NEWLINE); + vty_out(vty, " local-ip %s%s%s", asp->cfg.local.host[i], + asp->cfg.local.idx_primary == i ? " primary" : "", VTY_NEWLINE); } for (i = 0; i < asp->cfg.remote.host_cnt; i++) { if (asp->cfg.remote.host[i]) - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host[i], VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s%s", asp->cfg.remote.host[i], + asp->cfg.remote.idx_primary == i ? " primary" : "", VTY_NEWLINE); } if (asp->cfg.qos_class) vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); diff --git a/tests/vty/ss7_asp_test.vty b/tests/vty/ss7_asp_test.vty index 3296c65..d23f9c0 100644 --- a/tests/vty/ss7_asp_test.vty +++ b/tests/vty/ss7_asp_test.vty @@ -220,8 +220,8 @@ ss7_asp_vty_test(config-cs7)# asp my-asp 12345 54321 m3ua ss7_asp_vty_test(config-cs7-asp)# list ... description .TEXT - remote-ip (A.B.C.D|X:X::X:X) - local-ip (A.B.C.D|X:X::X:X) + remote-ip (A.B.C.D|X:X::X:X) [primary] + local-ip (A.B.C.D|X:X::X:X) [primary] qos-class <0-255> role (sg|asp|ipsp) sctp-role (client|server) @@ -255,6 +255,40 @@ ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp ASP Name AS Name State Type Role Remote IPaddr & Port SCTP Role ------------ ------------ ------------- ---- ---- ----------------------- --------- my-asp ? uninitialized m3ua sg (127.0.0.200|127.0.0.201):12345 server +ss7_asp_vty_test(config-cs7-asp)# ! Mark as primary: +ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.201 primary +ss7_asp_vty_test(config-cs7-asp)# ! 'local-ip 127.0.0.101 primary' cannot be tested here since output may be different based on sysctl available +ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.101 +... +ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp + Current Primary Link +ASP Name AS Name State Type Role Remote IPaddr & Port SCTP Role +------------ ------------ ------------- ---- ---- ----------------------- --------- +my-asp ? uninitialized m3ua sg (127.0.0.200|127.0.0.201*):12345 server +ss7_asp_vty_test(config-cs7-asp)# show running-config +... + local-ip 127.0.0.100 + local-ip 127.0.0.101 + remote-ip 127.0.0.200 + remote-ip 127.0.0.201 primary +... +end +ss7_asp_vty_test(config-cs7-asp)# ! Mark as non-primary: +ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.201 +ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.101 +ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp + Current Primary Link +ASP Name AS Name State Type Role Remote IPaddr & Port SCTP Role +------------ ------------ ------------- ---- ---- ----------------------- --------- +my-asp ? uninitialized m3ua sg (127.0.0.200|127.0.0.201):12345 server +ss7_asp_vty_test(config-cs7-asp)# show running-config +... + local-ip 127.0.0.100 + local-ip 127.0.0.101 + remote-ip 127.0.0.200 + remote-ip 127.0.0.201 +... +end ss7_asp_vty_test(config-cs7-asp)# exit ss7_asp_vty_test(config-cs7)# as my-ass m3ua |