Add support for multiple interfaces on one V5 instance

Previously only 0..1 interfaces were allowed, now 0..n interfaces are
allowed. The interface ID is unique for all interfaces, so false
connection can be detected. Other identifiers may be identical at
different interfaces.

User ports use (abstract) ph-socket names that include interface ID:

<interface id>-isdn-<port nr> (e.g. 1-isdn-9100)
<interface id>-pstn-<port nr> (e.g. 1-pstn-8888)
This commit is contained in:
Andreas Eversberg 2023-03-12 17:17:23 +01:00
parent e40523ad20
commit 8458f8baca
5 changed files with 313 additions and 278 deletions

View File

@ -206,6 +206,7 @@ static void sighandler(int sigset)
int main(int argc, char **argv)
{
struct v5x_interface *v5if;
int rc;
tall_v5le_ctx = talloc_named_const(NULL, 1, "v5le");
@ -288,11 +289,8 @@ int main(int argc, char **argv)
signal(SIGPIPE, sighandler);
/* start management state machine */
if (!llist_empty(&v5i->interfaces)) {
struct v5x_interface *v5if;
v5if = (struct v5x_interface *)v5i->interfaces.next;
llist_for_each_entry(v5if, &v5i->interfaces, list)
v5x_le_mgmt_start_delay(v5if, SOCKET_RETRY_TIMER + 1);
}
/* main loop */
while (!quit) {

View File

@ -15,20 +15,99 @@
extern struct v5x_instance *v5i;
static struct v5x_interface *get_interface(struct vty *vty)
{
struct v5x_interface *v5if = NULL;
enum v5_vty_node {
INTERFACE_NODE = _LAST_OSMOVTY_NODE + 1,
CONFIG_INTERFACE_NODE_V51,
CONFIG_INTERFACE_NODE_V52,
CONFIG_LINK_NODE,
CONFIG_PORT_NODE,
};
if (!llist_empty(&v5i->interfaces))
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
if (!v5if) {
vty_out(vty, "%%No interface created!%s", VTY_NEWLINE);
return NULL;
char if_prompt[64];
char conf_if_prompt[64];
char conf_link_prompt[64];
char conf_port_prompt[64];
static struct cmd_node interface_node = {
.node = INTERFACE_NODE,
.prompt = if_prompt,
.vtysh = 1,
};
static struct cmd_node config_interface_node_v51 = {
.node = CONFIG_INTERFACE_NODE_V51,
.prompt = conf_if_prompt,
.vtysh = 1,
};
static struct cmd_node config_interface_node_v52 = {
.node = CONFIG_INTERFACE_NODE_V52,
.prompt = conf_if_prompt,
.vtysh = 1,
};
static struct cmd_node config_link_node = {
.node = CONFIG_LINK_NODE,
.prompt = conf_link_prompt,
.vtysh = 1,
};
static struct cmd_node config_port_node = {
.node = CONFIG_PORT_NODE,
.prompt = conf_port_prompt,
.vtysh = 1,
};
static int v5le_vty_is_config_node(struct vty __attribute__((unused)) *vty, int node)
{
switch (node) {
case INTERFACE_NODE:
case CONFIG_NODE:
return 0;
default:
return 1;
}
}
static int v5le_vty_go_parent(struct vty *vty)
{
struct v5x_interface *v5if;
struct v5x_link *v5l;
struct v5x_user_port *v5up;
switch (vty->node) {
case CONFIG_PORT_NODE:
v5up = vty->index;
v5if = v5up->interface;
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52;
vty->index = v5if;
break;
case CONFIG_LINK_NODE:
v5l = vty->index;
v5if = v5l->interface;
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52;
vty->index = v5if;
break;
case CONFIG_INTERFACE_NODE_V51:
case CONFIG_INTERFACE_NODE_V52:
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
default:
vty->node = ENABLE_NODE;
vty->index = NULL;
}
return v5if;
return vty->node;
}
struct vty_app_info vty_info = {
.name = "OsmoV5LE",
.version = PACKAGE_VERSION,
.go_parent_cb = v5le_vty_go_parent,
.is_config_node = v5le_vty_is_config_node,
};
/*
* show
*/
@ -42,11 +121,40 @@ static const char *link_status(bool established, struct lapv5_instance *li)
return "up";
}
DEFUN(interface, interface_cmd,
"interface <0-16777215>",
"Select given interface\n" "Interface ID")
{
struct v5x_interface *v5if, *found = NULL;
uint32_t id = atoi(argv[0]);
if (llist_empty(&v5i->interfaces)) {
vty_out(vty, "%%No interface created!%s", VTY_NEWLINE);
return CMD_WARNING;
}
llist_for_each_entry(v5if, &v5i->interfaces, list) {
if (v5if->id == id)
found = v5if;
}
v5if = found;
if (!v5if) {
vty_out(vty, "Interface does not exist.%s", VTY_NEWLINE);
return CMD_WARNING;
}
sprintf(if_prompt, "%%s(interface-%d)# ", v5if->id);
vty->node = INTERFACE_NODE;
vty->index = v5if;
return CMD_SUCCESS;
}
DEFUN(show_interface, show_interface_cmd,
"show interface",
SHOW_STR "Show interface and states")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_link *v5l;
struct v5x_user_port *v5up;
int calls;
@ -56,7 +164,7 @@ DEFUN(show_interface, show_interface_cmd,
return CMD_WARNING;
}
vty_out(vty, "Interface %s:%s", (v5if->dialect == V5X_DIALECT_V51) ? "V5.1" : "V5.2", VTY_NEWLINE);
vty_out(vty, "Interface %d %s:%s", v5if->id, (v5if->dialect == V5X_DIALECT_V51) ? "V5.1" : "V5.2", VTY_NEWLINE);
vty_out(vty, " Trigger system restart: %s%s", (v5if->mgmt->auto_restart) ? "automatic" : "manual", VTY_NEWLINE);
vty_out(vty, " Trigger data links: %s%s", (v5if->mgmt->do_est) ? "yes" : "no", VTY_NEWLINE);
vty_out(vty, " Trigger user port alignment: %s%s", (v5if->mgmt->do_align) ? "yes" : "no", VTY_NEWLINE);
@ -94,15 +202,15 @@ DEFUN(show_interface, show_interface_cmd,
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[BLK_ALL_ISDN]), VTY_NEWLINE);
}
if (!v5if->id_remote_valid)
vty_out(vty, " ID: local: %d remote: unknown%s", v5if->id_local, VTY_NEWLINE);
vty_out(vty, " ID: local: %d remote: unknown%s", v5if->id, VTY_NEWLINE);
else
vty_out(vty, " ID: local: %d remote: %d%s%s", v5if->id_local, v5if->id_remote,
(v5if->id_local != v5if->id_remote) ? " (mismatching)" : "", VTY_NEWLINE);
vty_out(vty, " ID: local: %d remote: %d%s%s", v5if->id, v5if->id_remote,
(v5if->id != v5if->id_remote) ? " (mismatching)" : "", VTY_NEWLINE);
if (!v5if->variant_remote_valid)
vty_out(vty, " Variant: local: %d remote: unknown%s", v5if->variant_local, VTY_NEWLINE);
vty_out(vty, " Variant: local: %d remote: unknown%s", v5if->variant, VTY_NEWLINE);
else
vty_out(vty, " Variant: local: %d remote: %d%s%s", v5if->variant_local, v5if->variant_remote,
(v5if->variant_local != v5if->variant_remote) ? " (mismatching)" : "", VTY_NEWLINE);
vty_out(vty, " Variant: local: %d remote: %d%s%s", v5if->variant, v5if->variant_remote,
(v5if->variant != v5if->variant_remote) ? " (mismatching)" : "", VTY_NEWLINE);
if (v5if->dialect == V5X_DIALECT_V52) {
vty_out(vty, " Link IDs:");
llist_for_each_entry(v5l, &v5if->links, list)
@ -131,7 +239,7 @@ DEFUN(show_link, show_link_cmd,
"show link",
SHOW_STR "Show links and states")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_link *v5l;
struct v5x_user_port *v5up;
int t;
@ -140,7 +248,7 @@ DEFUN(show_link, show_link_cmd,
return CMD_WARNING;
if (llist_empty(&v5if->links)) {
vty_out(vty, "%%No links created!%s", VTY_NEWLINE);
vty_out(vty, "%%No link created!%s", VTY_NEWLINE);
return CMD_WARNING;
}
llist_for_each_entry(v5l, &v5if->links, list) {
@ -210,7 +318,7 @@ DEFUN(show_port_pstn, show_port_pstn_cmd,
"show port pstn <0-32767>",
SHOW_STR SHOW_PORT "Show given PSTN user port and states\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -231,7 +339,7 @@ DEFUN(show_port_isdn, show_port_isdn_cmd,
"show port isdn <0-8175>",
SHOW_STR SHOW_PORT "Show given ISDN user port and states\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -252,14 +360,14 @@ DEFUN(show_port, show_port_cmd,
"show port",
SHOW_STR "Show all user ports and states")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
return CMD_WARNING;
if (llist_empty(&v5if->user_ports)) {
vty_out(vty, "%%No user ports created!%s", VTY_NEWLINE);
vty_out(vty, "%%No user port created!%s", VTY_NEWLINE);
return CMD_WARNING;
}
@ -277,7 +385,7 @@ DEFUN(system_restart, system_restart_cmd,
"system-restart",
"Perform system startup/restart")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
int rc;
if (!v5if)
@ -296,7 +404,7 @@ DEFUN(pstn_restart, pstn_restart_cmd,
"pstn-restart",
"Perform PSTN protocol restart")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
int rc;
if (!v5if)
@ -315,7 +423,7 @@ DEFUN(align_ports, align_ports_cmd,
"align-ports [accelerated]",
"Perform alignment of all ports (sync (un)blocked state)")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
int accelerated = 0;
int rc;
@ -338,7 +446,7 @@ DEFUN(switchover, switchover_cmd,
"switch-over <0-255>",
"Perform switch-over to given link\n" "Link ID")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_link *v5l;
if (!v5if)
@ -370,7 +478,7 @@ DEFUN(unblock_link, unblock_link_cmd,
"unblock link <0-255>",
PERF_UBLK "Perform unblocking of link\n" "Link ID")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_link *v5l;
if (!v5if)
@ -395,7 +503,7 @@ DEFUN(block_link, block_link_cmd,
"block link <0-255>",
PERF_BLK "Perform blocking of link\n" "Link ID")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_link *v5l;
if (!v5if)
@ -420,7 +528,7 @@ DEFUN(unblock_pstn_port, unblock_pstn_port_cmd,
"unblock pstn <0-32767>",
PERF_UBLK "Perform unblocking of PSTN port\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -440,7 +548,7 @@ DEFUN(block_pstn_port, block_pstn_port_cmd,
"block pstn <0-32767>",
PERF_BLK "Perform blocking of PSTN port\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -460,7 +568,7 @@ DEFUN(unblock_isdn_port, unblock_isdn_port_cmd,
"unblock isdn <0-8175>",
PERF_UBLK "Perform unblocking of ISDN port\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -480,7 +588,7 @@ DEFUN(block_isdn_port, block_isdn_port_cmd,
"block isdn <0-8175>",
PERF_BLK "Perform blocking of ISDN port\n" "L3 address")
{
struct v5x_interface *v5if = get_interface(vty);
struct v5x_interface *v5if = vty->index;
struct v5x_user_port *v5up;
if (!v5if)
@ -500,109 +608,33 @@ DEFUN(block_isdn_port, block_isdn_port_cmd,
* configure
*/
enum v5_vty_node {
INTERFACE_NODE_V51 = _LAST_OSMOVTY_NODE + 1,
INTERFACE_NODE_V52,
LINK_NODE,
PORT_NODE,
};
static struct cmd_node interface_node_v51 = {
.node = INTERFACE_NODE_V51,
.prompt = "%s(config-v5.1-if)# ",
.vtysh = 1,
};
static struct cmd_node interface_node_v52 = {
.node = INTERFACE_NODE_V52,
.prompt = "%s(config-v5.2-if)# ",
.vtysh = 1,
};
static struct cmd_node link_node = {
.node = LINK_NODE,
.prompt = "%s(config-link)# ",
.vtysh = 1,
};
static struct cmd_node port_node = {
.node = PORT_NODE,
.prompt = "%s(config-port)# ",
.vtysh = 1,
};
static int v5le_vty_is_config_node(struct vty __attribute__((unused)) *vty, int node)
{
switch (node) {
case CONFIG_NODE:
return 0;
default:
return 1;
}
}
static int v5le_vty_go_parent(struct vty *vty)
{
struct v5x_interface *v5if;
struct v5x_link *v5l;
struct v5x_user_port *v5up;
switch (vty->node) {
case PORT_NODE:
v5up = vty->index;
v5if = v5up->interface;
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52;
vty->index = v5if;
break;
case LINK_NODE:
v5l = vty->index;
v5if = v5l->interface;
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52;
vty->index = v5if;
break;
case INTERFACE_NODE_V51:
case INTERFACE_NODE_V52:
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
default:
vty->node = ENABLE_NODE;
vty->index = NULL;
}
return vty->node;
}
struct vty_app_info vty_info = {
.name = "OsmoV5LE",
.version = PACKAGE_VERSION,
.go_parent_cb = v5le_vty_go_parent,
.is_config_node = v5le_vty_is_config_node,
};
DEFUN(cfg_interface, cfg_interface_cmd,
"interface [(v5.1|v5.2)]",
"Configure V5 interface\n" "Configure as V5.1 interface\n" "Configure as V5.2 interface")
"interface <0-16777215> [(v5.1|v5.2)]",
"Configure V5 interface\n" "Interface ID\n" "Configure as V5.1 interface\n" "Configure as V5.2 interface")
{
struct v5x_interface *v5if = NULL;
struct v5x_interface *v5if, *found = NULL;
enum v5x_dialect dialect = V5X_DIALECT_V51;
uint32_t id = atoi(argv[0]);
if (!llist_empty(&v5i->interfaces))
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
llist_for_each_entry(v5if, &v5i->interfaces, list) {
if (v5if->id == id)
found = v5if;
}
v5if = found;
if (argc < 1) {
if (argc < 2) {
if (!v5if) {
vty_out(vty, "%%No interface created, Add v5.1 or v5.2 after this command.%s", VTY_NEWLINE);
vty_out(vty, "%%Interface not created, Add v5.1 or v5.2 after this command.%s", VTY_NEWLINE);
return CMD_WARNING;
}
dialect = v5if->dialect;
} else {
if (!strcasecmp(argv[0], "v5.2"))
if (!strcasecmp(argv[1], "v5.2"))
dialect = V5X_DIALECT_V52;
}
if (!v5if) {
v5if = v5x_interface_alloc(v5i, dialect);
v5if = v5x_interface_alloc(v5i, id, dialect);
if (!v5if) {
vty_out(vty, "%%Failed to create interface. See logging output.%s", VTY_NEWLINE);
return CMD_WARNING;
@ -611,23 +643,31 @@ DEFUN(cfg_interface, cfg_interface_cmd,
vty_out(vty, "%%Different interface type already created. To change, remove first.%s", VTY_NEWLINE);
}
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52;
sprintf(conf_if_prompt, "%%s(config-interface-%d)# ", v5if->id);
vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52;
vty->index = v5if;
return CMD_SUCCESS;
}
DEFUN(cfg_no_interface, cfg_no_interface_cmd,
"no interface",
NO_STR "Remove V5 interface")
"no interface <0-16777215>",
NO_STR "Remove V5 interface\n" "Interface ID")
{
struct v5x_interface *v5if = NULL;
struct v5x_interface *v5if, *found = NULL;
uint32_t id = atoi(argv[0]);
if (!llist_empty(&v5i->interfaces))
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
if (v5if) {
v5x_interface_free(v5if);
llist_for_each_entry(v5if, &v5i->interfaces, list) {
if (v5if->id == id)
found = v5if;
}
v5if = found;
if (!v5if) {
vty_out(vty, "%%Interface does not exist.%s", VTY_NEWLINE);
return CMD_WARNING;
}
v5x_interface_free(v5if);
return CMD_SUCCESS;
}
@ -712,23 +752,13 @@ DEFUN(cfg_no_accelerated, cfg_no_accelerated_cmd,
return CMD_SUCCESS;
}
DEFUN(cfg_interface_id, cfg_interface_id_cmd,
"id <0-16777215>",
"Set interface ID\n" "Interface ID")
{
struct v5x_interface *v5if = vty->index;
v5if->id_local = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_interface_variant, cfg_interface_variant_cmd,
"variant <0-127>",
"Set interface provisioning variant\n" "Variant value")
{
struct v5x_interface *v5if = vty->index;
v5if->variant_local = atoi(argv[0]);
v5if->variant = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -772,7 +802,8 @@ DEFUN(cfg_link_v51, cfg_link_cmd_v51,
v5l = llist_first_entry(&v5if->links, struct v5x_link, list);
vty->node = LINK_NODE;
sprintf(conf_link_prompt, "%%s(config-link-%d)# ", v5l->id);
vty->node = CONFIG_LINK_NODE;
vty->index = v5l;
return CMD_SUCCESS;
}
@ -793,7 +824,8 @@ DEFUN(cfg_link_v52, cfg_link_cmd_v52,
}
}
vty->node = LINK_NODE;
sprintf(conf_link_prompt, "%%s(config-link-%d)# ", v5l->id);
vty->node = CONFIG_LINK_NODE;
vty->index = v5l;
return CMD_SUCCESS;
}
@ -825,6 +857,7 @@ DEFUN(cfg_e1_line, cfg_e1_line_cmd,
"e1 line <0-255>",
"E1 configuration\n" "E1 line configuration\n" "E1 line number to use for link")
{
struct v5x_interface *search_v5if;
struct v5x_link *v5l = vty->index, *search_v5l;
struct e1inp_line *e1_line;
unsigned int num = atoi(argv[0]);
@ -833,13 +866,16 @@ DEFUN(cfg_e1_line, cfg_e1_line_cmd,
if (v5l->e1_line && v5l->e1_line->num == num)
return CMD_SUCCESS;
/* is there someone using this line number already? only can happen with multi-link (V5.2) */
llist_for_each_entry(search_v5l, &v5l->interface->links, list) {
if (!search_v5l->e1_line)
continue;
if (search_v5l->e1_line->num == num) {
vty_out(vty, "%%E1 line %d already used by link ID %d.%s", num, search_v5l->id, VTY_NEWLINE);
return CMD_WARNING;
/* is there someone using this line already? */
llist_for_each_entry(search_v5if, &v5i->interfaces, list) {
llist_for_each_entry(search_v5l, &search_v5if->links, list) {
if (!search_v5l->e1_line)
continue;
if (search_v5l->e1_line->num == num) {
vty_out(vty, "%%E1 line %d already used by interface %d / link ID %d.%s", num,
search_v5if->id, search_v5l->id, VTY_NEWLINE);
return CMD_WARNING;
}
}
}
@ -888,7 +924,8 @@ DEFUN(cfg_port_pstn_v51, cfg_port_pstn_cmd_v51,
return CMD_WARNING;
}
vty->node = PORT_NODE;
sprintf(conf_port_prompt, "%%s(config-port-pstn-%d)# ", v5up->nr);
vty->node = CONFIG_PORT_NODE;
vty->index = v5up;
return CMD_SUCCESS;
}
@ -913,7 +950,8 @@ DEFUN(cfg_port_pstn, cfg_port_pstn_cmd,
return CMD_WARNING;
}
vty->node = PORT_NODE;
sprintf(conf_port_prompt, "%%s(config-port-pstn-%d)# ", v5up->nr);
vty->node = CONFIG_PORT_NODE;
vty->index = v5up;
return CMD_SUCCESS;
}
@ -952,7 +990,8 @@ DEFUN(cfg_port_isdn_v51, cfg_port_isdn_cmd_v51,
return CMD_WARNING;
}
vty->node = PORT_NODE;
sprintf(conf_port_prompt, "%%s(config-port-isdn-%d)# ", v5up->nr);
vty->node = CONFIG_PORT_NODE;
vty->index = v5up;
return CMD_SUCCESS;
}
@ -977,7 +1016,8 @@ DEFUN(cfg_port_isdn, cfg_port_isdn_cmd,
return CMD_WARNING;
}
vty->node = PORT_NODE;
sprintf(conf_port_prompt, "%%s(config-port-isdn-%d)# ", v5up->nr);
vty->node = CONFIG_PORT_NODE;
vty->index = v5up;
return CMD_SUCCESS;
}
@ -1085,70 +1125,66 @@ static void config_write_user_port(struct vty *vty, struct v5x_interface *v5if)
}
}
static int config_write_interface_v51(struct vty *vty)
static void config_write_interface_v51(struct vty *vty, struct v5x_interface *v5if)
{
struct v5x_interface *v5if = NULL;
struct v5x_link *v5l;
if (!llist_empty(&v5i->interfaces))
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
vty_out(vty, "!%s", VTY_NEWLINE);
v5l = llist_first_entry(&v5if->links, struct v5x_link, list);
vty_out(vty, "interface %d v5.1%s", v5if->id, VTY_NEWLINE);
vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE);
vty_out(vty, " link%s", VTY_NEWLINE);
if (!v5l->e1_line)
vty_out(vty, " no e1 line%s", VTY_NEWLINE);
else
vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE);
config_write_user_port(vty, v5if);
}
static void config_write_interface_v52(struct vty *vty, struct v5x_interface *v5if)
{
struct v5x_link *v5l;
vty_out(vty, "!%s", VTY_NEWLINE);
if (!v5if)
vty_out(vty, "no interface%s", VTY_NEWLINE);
if (v5if && v5if->dialect == V5X_DIALECT_V51) {
v5l = llist_first_entry(&v5if->links, struct v5x_link, list);
vty_out(vty, "interface v5.1%s", VTY_NEWLINE);
vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " id %d%s", v5if->id_local, VTY_NEWLINE);
vty_out(vty, " variant %d%s", v5if->variant_local, VTY_NEWLINE);
vty_out(vty, " link%s", VTY_NEWLINE);
vty_out(vty, "interface %d v5.2%s", v5if->id, VTY_NEWLINE);
vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %saccelerated-alignment%s", (v5if->mgmt->acc_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE);
vty_out(vty, " cc-id %d%s", v5if->protection.cc_id, VTY_NEWLINE);
if (v5if->use_capability)
vty_out(vty, " information-transfer-capability %d%s", v5if->capability, VTY_NEWLINE);
else
vty_out(vty, " no information-transfer-capability%s", VTY_NEWLINE);
llist_for_each_entry(v5l, &v5if->links, list) {
vty_out(vty, " link %d%s", v5l->id, VTY_NEWLINE);
if (v5l == v5if->primary_link)
vty_out(vty, " # primary%s", VTY_NEWLINE);
if (v5l == v5if->secondary_link)
vty_out(vty, " # secondary%s", VTY_NEWLINE);
if (!v5l->e1_line)
vty_out(vty, " no e1 line%s", VTY_NEWLINE);
else
vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE);
config_write_user_port(vty, v5if);
}
return CMD_SUCCESS;
config_write_user_port(vty, v5if);
}
static int config_write_interface_v52(struct vty *vty)
static int config_write_interfaces(struct vty *vty)
{
struct v5x_interface *v5if = NULL;
struct v5x_link *v5l;
if (!llist_empty(&v5i->interfaces))
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
vty_out(vty, "!%s", VTY_NEWLINE);
if (v5if && v5if->dialect == V5X_DIALECT_V52) {
vty_out(vty, "interface v5.2%s", VTY_NEWLINE);
vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %saccelerated-alignment%s", (v5if->mgmt->acc_align) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " id %d%s", v5if->id_local, VTY_NEWLINE);
vty_out(vty, " variant %d%s", v5if->variant_local, VTY_NEWLINE);
vty_out(vty, " cc-id %d%s", v5if->protection.cc_id, VTY_NEWLINE);
if (v5if->use_capability)
vty_out(vty, " information-transfer-capability %d%s", v5if->capability, VTY_NEWLINE);
llist_for_each_entry(v5if, &v5i->interfaces, list) {
if (v5if->dialect == V5X_DIALECT_V51)
config_write_interface_v51(vty, v5if);
else
vty_out(vty, " no information-transfer-capability%s", VTY_NEWLINE);
llist_for_each_entry(v5l, &v5if->links, list) {
vty_out(vty, " link %d%s", v5l->id, VTY_NEWLINE);
if (v5l == v5if->primary_link)
vty_out(vty, " # primary%s", VTY_NEWLINE);
if (v5l == v5if->secondary_link)
vty_out(vty, " # secondary%s", VTY_NEWLINE);
if (!v5l->e1_line)
vty_out(vty, " no e1 line%s", VTY_NEWLINE);
else
vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE);
}
config_write_user_port(vty, v5if);
config_write_interface_v52(vty, v5if);
}
return CMD_SUCCESS;
}
@ -1158,67 +1194,67 @@ static int config_write_interface_v52(struct vty *vty)
int v5le_vty_init(void)
{
install_element_ve(&show_interface_cmd);
install_element_ve(&show_link_cmd);
install_element_ve(&show_port_cmd);
install_element_ve(&show_port_pstn_cmd);
install_element_ve(&show_port_isdn_cmd);
install_element(ENABLE_NODE, &system_restart_cmd);
install_element(ENABLE_NODE, &pstn_restart_cmd);
install_element(ENABLE_NODE, &align_ports_cmd);
install_element(ENABLE_NODE, &switchover_cmd);
install_element(ENABLE_NODE, &unblock_link_cmd);
install_element(ENABLE_NODE, &block_link_cmd);
install_element(ENABLE_NODE, &unblock_pstn_port_cmd);
install_element(ENABLE_NODE, &block_pstn_port_cmd);
install_element(ENABLE_NODE, &unblock_isdn_port_cmd);
install_element(ENABLE_NODE, &block_isdn_port_cmd);
install_element(ENABLE_NODE, &interface_cmd);
install_node(&interface_node, NULL);
install_element(INTERFACE_NODE, &show_interface_cmd);
install_element(INTERFACE_NODE, &show_link_cmd);
install_element(INTERFACE_NODE, &show_port_cmd);
install_element(INTERFACE_NODE, &show_port_pstn_cmd);
install_element(INTERFACE_NODE, &show_port_isdn_cmd);
install_element(INTERFACE_NODE, &system_restart_cmd);
install_element(INTERFACE_NODE, &pstn_restart_cmd);
install_element(INTERFACE_NODE, &align_ports_cmd);
install_element(INTERFACE_NODE, &switchover_cmd);
install_element(INTERFACE_NODE, &unblock_link_cmd);
install_element(INTERFACE_NODE, &block_link_cmd);
install_element(INTERFACE_NODE, &unblock_pstn_port_cmd);
install_element(INTERFACE_NODE, &block_pstn_port_cmd);
install_element(INTERFACE_NODE, &unblock_isdn_port_cmd);
install_element(INTERFACE_NODE, &block_isdn_port_cmd);
install_element(CONFIG_NODE, &cfg_interface_cmd);
install_element(CONFIG_NODE, &cfg_no_interface_cmd);
install_node(&interface_node_v51, config_write_interface_v51);
install_node(&interface_node_v52, config_write_interface_v52);
install_element(INTERFACE_NODE_V51, &cfg_auto_restart_cmd);
install_element(INTERFACE_NODE_V51, &cfg_no_auto_restart_cmd);
install_element(INTERFACE_NODE_V51, &cfg_establish_cmd);
install_element(INTERFACE_NODE_V51, &cfg_no_establish_cmd);
install_element(INTERFACE_NODE_V51, &cfg_alignment_cmd);
install_element(INTERFACE_NODE_V51, &cfg_no_alignment_cmd);
install_element(INTERFACE_NODE_V51, &cfg_interface_id_cmd);
install_element(INTERFACE_NODE_V51, &cfg_interface_variant_cmd);
install_element(INTERFACE_NODE_V51, &cfg_link_cmd_v51);
install_element(INTERFACE_NODE_V51, &cfg_port_pstn_cmd_v51);
install_element(INTERFACE_NODE_V51, &cfg_port_pstn_cmd);
install_element(INTERFACE_NODE_V51, &cfg_no_port_pstn_cmd);
install_element(INTERFACE_NODE_V51, &cfg_port_isdn_cmd_v51);
install_element(INTERFACE_NODE_V51, &cfg_port_isdn_cmd);
install_element(INTERFACE_NODE_V51, &cfg_no_port_isdn_cmd);
install_element(INTERFACE_NODE_V52, &cfg_auto_restart_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_auto_restart_cmd);
install_element(INTERFACE_NODE_V52, &cfg_establish_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_establish_cmd);
install_element(INTERFACE_NODE_V52, &cfg_alignment_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_alignment_cmd);
install_element(INTERFACE_NODE_V52, &cfg_accelerated_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_accelerated_cmd);
install_element(INTERFACE_NODE_V52, &cfg_interface_id_cmd);
install_element(INTERFACE_NODE_V52, &cfg_interface_variant_cmd);
install_element(INTERFACE_NODE_V52, &cfg_interface_cc_id_cmd);
install_element(INTERFACE_NODE_V52, &cfg_interface_capability_cmd);
install_element(INTERFACE_NODE_V52, &cfg_interface_no_capability_cmd);
install_element(INTERFACE_NODE_V52, &cfg_link_cmd_v52);
install_element(INTERFACE_NODE_V52, &cfg_no_link_cmd_v52);
install_element(INTERFACE_NODE_V52, &cfg_port_pstn_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_port_pstn_cmd);
install_element(INTERFACE_NODE_V52, &cfg_port_isdn_cmd);
install_element(INTERFACE_NODE_V52, &cfg_no_port_isdn_cmd);
install_node(&link_node, NULL);
install_element(LINK_NODE, &cfg_e1_line_cmd);
install_element(LINK_NODE, &cfg_no_e1_line_cmd);
install_node(&port_node, NULL);
install_element(PORT_NODE, &cfg_echo_can_cmd);
install_element(PORT_NODE, &cfg_no_echo_can_cmd);
install_element(PORT_NODE, &cfg_echo_sup_cmd);
install_element(PORT_NODE, &cfg_no_echo_sup_cmd);
install_node(&config_interface_node_v51, config_write_interfaces);
install_node(&config_interface_node_v52, NULL);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_auto_restart_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_auto_restart_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_establish_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_establish_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_alignment_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_alignment_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_interface_variant_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_link_cmd_v51);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_pstn_cmd_v51);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_pstn_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_port_pstn_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_isdn_cmd_v51);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_isdn_cmd);
install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_port_isdn_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_auto_restart_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_auto_restart_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_establish_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_establish_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_alignment_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_alignment_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_accelerated_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_accelerated_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_variant_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_cc_id_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_capability_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_no_capability_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_link_cmd_v52);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_link_cmd_v52);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_port_pstn_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_port_pstn_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_port_isdn_cmd);
install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_port_isdn_cmd);
install_node(&config_link_node, NULL);
install_element(CONFIG_LINK_NODE, &cfg_e1_line_cmd);
install_element(CONFIG_LINK_NODE, &cfg_no_e1_line_cmd);
install_node(&config_port_node, NULL);
install_element(CONFIG_PORT_NODE, &cfg_echo_can_cmd);
install_element(CONFIG_PORT_NODE, &cfg_no_echo_can_cmd);
install_element(CONFIG_PORT_NODE, &cfg_echo_sup_cmd);
install_element(CONFIG_PORT_NODE, &cfg_no_echo_sup_cmd);
return 0;
}

View File

@ -218,7 +218,7 @@ int v5x_link_destroy(struct v5x_link *v5l)
return 0;
}
struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect)
struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, uint32_t id, enum v5x_dialect dialect)
{
struct v5x_interface *v5if;
struct v5x_link *v5l;
@ -235,6 +235,7 @@ struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dia
llist_add_tail(&v5if->list, &v5i->interfaces);
v5if->instance = v5i;
v5if->id = id;
v5if->dialect = dialect;
if (v5if->dialect == V5X_DIALECT_V51) {
@ -394,7 +395,7 @@ struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t
switch (type) {
case V5X_USER_TYPE_ISDN:
LOGP(DV5, LOGL_NOTICE, "Creating V5 ISDN user port with L3 addr %d\n", nr);
sprintf(v5up->ifname, "isdn-%d", nr);
sprintf(v5up->ifname, "%d-isdn-%d", v5if->id, nr);
OSMO_ASSERT(nr <= 8175);
v5up->port_fi = v5x_le_port_isdn_create(v5up, nr);
if (!v5up->port_fi) {
@ -404,7 +405,7 @@ struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t
break;
case V5X_USER_TYPE_PSTN:
LOGP(DV5, LOGL_NOTICE, "Creating V5 PSTN user port with L3 addr %d\n", nr);
sprintf(v5up->ifname, "pstn-%d", nr);
sprintf(v5up->ifname, "%d-pstn-%d", v5if->id, nr);
OSMO_ASSERT(nr <= 32767);
v5up->port_fi = v5x_le_port_pstn_create(v5up, nr);
if (!v5up->port_fi) {

View File

@ -203,8 +203,8 @@ struct v5x_interface {
struct llist_head list; /* instance.interfaces */
struct v5x_instance *instance; /* back-pointer */
enum v5x_dialect dialect;
uint32_t id_local, id_remote; /* interface id */
uint8_t variant_local, variant_remote; /* provitioning variant */
uint32_t id, id_remote; /* interface id */
uint8_t variant, variant_remote; /* provisioning variant */
bool id_remote_valid;
bool variant_remote_valid;
bool use_capability; /* use bearer transfer capability */
@ -384,7 +384,7 @@ struct v5x_instance {
struct v5x_instance *v5x_instance_alloc(void *ctx);
void v5x_instance_free(struct v5x_instance *v5i);
struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect);
struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, uint32_t id, enum v5x_dialect dialect);
struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t nr, enum v5x_user_type,
uint8_t ts1, uint8_t ts2);
void v5x_interface_free(struct v5x_interface *v5if);

View File

@ -677,15 +677,15 @@ static void system_lesys1_wait_variant_and_id(struct osmo_fsm_inst *fi, uint32_t
v5if->variant_remote_valid = true;
v5if->id_remote = vi->interface_id;
v5if->id_remote_valid = true;
if (v5if->variant_remote != v5if->variant_local) {
if (v5if->variant_remote != v5if->variant) {
LOGP(DV5MGMT, LOGL_ERROR, "Variant does not match: AN(%d) != LE(%d)\n",
v5if->variant_remote, v5if->variant_local);
v5if->variant_remote, v5if->variant);
}
if (v5if->id_remote != v5if->id_local) {
if (v5if->id_remote != v5if->id) {
LOGP(DV5MGMT, LOGL_ERROR, "Interface ID does not match: AN(%d) != LE(%d)\n",
v5if->id_remote, v5if->id_local);
v5if->id_remote, v5if->id);
}
if (v5if->variant_remote != v5if->variant_local || v5if->id_remote != v5if->id_local) {
if (v5if->variant_remote != v5if->variant || v5if->id_remote != v5if->id) {
LOGP(DV5MGMT, LOGL_ERROR, "************************************************************\n");
LOGP(DV5MGMT, LOGL_ERROR, "You must set matching Variant and Interface ID at AN and LE!\n");
LOGP(DV5MGMT, LOGL_ERROR, "************************************************************\n");
@ -1855,8 +1855,8 @@ void v5x_le_common_ctrl_rcv(struct v5x_interface *v5if, uint8_t cfi, uint8_t var
/* variant & interface ID */
case V5X_CTRL_ID_REQUEST_VARIANT_AND_INTERFACE_ID:
LOGP(DV5MGMT, LOGL_INFO, "AN requests variant and interface ID, replying.\n");
v5x_le_ctrl_common_snd(v5if, V5X_CTRL_ID_VARIANT_AND_INTERFACE_ID, NULL, &v5if->variant_local,
&v5if->id_local);
v5x_le_ctrl_common_snd(v5if, V5X_CTRL_ID_VARIANT_AND_INTERFACE_ID, NULL, &v5if->variant,
&v5if->id);
break;
case V5X_CTRL_ID_VARIANT_AND_INTERFACE_ID:
vi.variant = variant;