aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO-RELEASE1
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h6
-rw-r--r--src/osmo_ss7.c257
-rw-r--r--src/osmo_ss7_vty.c24
-rw-r--r--tests/vty/ss7_asp_test.vty38
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