9
0
Fork 0

mtp: Attempt to implement the MTP Restart properly

For the SSP functionatilty we will need to have the timers T18
and T20. In the period of T18 we will collect TFP/TFR/TFA for the
reachable nodes of the system. Each of this node will send us a TRA
when it is finished. Right now we assume to only have one node and
stop the T18 after the TRA of this node. Then we would need to send
the TFP/TFR we have collected. On the expiry of the T20 timer we
will need to send our TRA and notify local users.

For more complex routing we will need to have a shared routing
cache and remember which SSNs and OPCs are reachable and have inter
linkset notifications.
This commit is contained in:
Holger Hans Peter Freyther 2011-02-23 11:25:45 +01:00
parent d77008bc7f
commit f2fecba20e
3 changed files with 101 additions and 20 deletions

View File

@ -83,6 +83,12 @@ struct mtp_link_set {
/* statistics */
struct rate_ctr_group *ctrg;
/* statistics for routing */
int timeout_t18;
int timeout_t20;
struct timer_list T18;
struct timer_list T20;
/* custom data */
struct bsc_data *bsc;
struct ss7_application *app;

View File

@ -189,6 +189,9 @@ void mtp_link_set_stop(struct mtp_link_set *link)
llist_for_each_entry(lnk, &link->links, entry)
mtp_link_stop_link_test(lnk);
bsc_del_timer(&link->T18);
bsc_del_timer(&link->T20);
link->sccp_up = 0;
link->running = 0;
link->linkset_up = 0;
@ -204,7 +207,8 @@ void mtp_link_set_reset(struct mtp_link_set *link)
mtp_link_start_link_test(lnk);
}
static int send_tfp(struct mtp_link *link, int apoc)
/* unused right now but we want to use it again */
int send_tfp(struct mtp_link *link, int apoc)
{
struct msgb *msg;
msg = mtp_tfp_alloc(link, apoc);
@ -243,31 +247,63 @@ static int linkset_up(struct mtp_link *link)
if (set->linkset_up)
return 0;
if (send_tfp(link, 0) != 0)
return -1;
if (send_tfp(link, set->opc) != 0)
return -1;
set->linkset_up = 1;
bsc_schedule_timer(&set->T18, set->timeout_t18, 0);
bsc_schedule_timer(&set->T20, set->timeout_t20, 0);
/* More the functionality of a SSP here... */
if (set->sccp_opc != set->opc &&
send_tfp(link, set->sccp_opc) != 0)
return -1;
send_tfa(link, set->sccp_opc) != 0) {
LOGP(DINP, LOGL_ERROR,
"Failed to send TFA for OPC %d on linkset %d.\n", set->sccp_opc, set->nr);
}
if (set->isup_opc != set->opc &&
send_tfp(link, set->isup_opc) != 0)
return -1;
send_tfa(link, set->isup_opc) != 0) {
LOGP(DINP, LOGL_ERROR,
"Failed to send TFA for OPC %d on linkset %d.\n", set->sccp_opc, set->nr);
}
return 0;
}
static void linkset_t18_cb(void *_set)
{
struct mtp_link_set *set = _set;
struct mtp_link *link = set->slc[0];
if (!link) {
LOGP(DINP, LOGL_ERROR,
"Linkset restart but no link available on linkset %d\n", set->nr);
bsc_del_timer(&set->T20);
set->linkset_up = 0;
return;
}
/* TODO: now send out routing states */
LOGP(DINP, LOGL_NOTICE, "The linkset %d has collected routing data.\n", set->nr);
}
static void linkset_t20_cb(void *_set)
{
struct mtp_link_set *set = _set;
struct mtp_link *link = set->slc[0];
if (!link) {
LOGP(DINP, LOGL_ERROR,
"Linkset restart but no link available on linkset %d\n", set->nr);
bsc_del_timer(&set->T20);
set->linkset_up = 0;
return;
}
/* Send the TRA for all PCs */
if (send_tra(link, set->opc) != 0)
return -1;
if (set->sccp_opc != set->opc &&
send_tfa(link, set->sccp_opc) != 0)
return -1;
if (set->isup_opc != set->opc &&
send_tfa(link, set->isup_opc) != 0)
return -1;
return;
set->linkset_up = 1;
LOGP(DINP, LOGL_NOTICE,
"The linkset %d/%s is considered running.\n", set->nr, set->name);
return 0;
return;
}
static int mtp_link_sign_msg(struct mtp_link_set *link, struct mtp_level_3_hdr *hdr, int l3_len)
@ -289,9 +325,14 @@ static int mtp_link_sign_msg(struct mtp_link_set *link, struct mtp_level_3_hdr *
case MTP_TRF_RESTR_MSG_GRP:
switch (cmn->h1) {
case MTP_RESTR_MSG_ALLWED:
LOGP(DINP, LOGL_INFO, "Received Restart Allowed. SST could be next on %d/%s.\n", link->nr, link->name);
LOGP(DINP, LOGL_INFO,
"Received TRA on linkset %d/%s.\n", link->nr, link->name);
/* TODO: routing should be done on a higher level */
bsc_del_timer(&link->T18);
bsc_del_timer(&link->T20);
linkset_t18_cb(&link->T18);
linkset_t20_cb(&link->T20);
link->sccp_up = 1;
LOGP(DINP, LOGL_INFO, "SCCP traffic allowed on %d/%s.\n", link->nr, link->name);
return 0;
break;
}
@ -612,6 +653,16 @@ struct mtp_link_set *mtp_link_set_alloc(struct bsc_data *bsc)
link->sccp_opc = link->isup_opc = -1;
link->pcap_fd = bsc->pcap_fd;
link->bsc = bsc;
/* timeout code */
link->timeout_t18 = 10;
link->timeout_t20 = 11;
link->T18.cb = linkset_t18_cb;
link->T18.data = link;
link->T20.cb = linkset_t20_cb;
link->T20.data = link;
llist_add_tail(&link->entry, &bsc->linksets);
return link;

View File

@ -202,6 +202,10 @@ static void write_linkset(struct vty *vty, struct mtp_link_set *set)
vty_out(vty, " mtp3 ni %d%s", set->ni, VTY_NEWLINE);
vty_out(vty, " mtp3 spare %d%s", set->spare, VTY_NEWLINE);
vty_out(vty, " mtp3 sltm-once %d%s", set->sltm_once, VTY_NEWLINE);
vty_out(vty, " mtp3 timeout t18 %d%s",
set->timeout_t18, VTY_NEWLINE);
vty_out(vty, " mtp3 timeout t20 %d%s",
set->timeout_t20, VTY_NEWLINE);
for (i = 0; i < ARRAY_SIZE(set->supported_ssn); ++i) {
if (!set->supported_ssn[i])
@ -425,6 +429,24 @@ DEFUN(cfg_linkset_sltm_once, cfg_linkset_sltm_once_cmd,
return CMD_SUCCESS;
}
DEFUN(cfg_linkset_t18, cfg_linkset_t18_cmd,
"mtp3 timeout t18 <0-1000>",
"MTP Level3\n" "Timeouts\n" "T18 link restart timeout\n" "Seconds\n")
{
struct mtp_link_set *set = vty->index;
set->timeout_t18 = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_linkset_t20, cfg_linkset_t20_cmd,
"mtp3 timeout t20 <0-1000>",
"MTP Level3\n" "Timeouts\n" "T20 link restart timeout\n" "Seconds\n")
{
struct mtp_link_set *set = vty->index;
set->timeout_t20 = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_linkset_link, cfg_linkset_link_cmd,
"link <0-100>",
"Link\n" "Link number\n")
@ -876,6 +898,8 @@ void cell_vty_init(void)
install_element(LINKSETS_NODE, &cfg_linkset_mtp3_ssn_cmd);
install_element(LINKSETS_NODE, &cfg_linkset_no_mtp3_ssn_cmd);
install_element(LINKSETS_NODE, &cfg_linkset_sltm_once_cmd);
install_element(LINKSETS_NODE, &cfg_linkset_t18_cmd);
install_element(LINKSETS_NODE, &cfg_linkset_t20_cmd);
install_element(LINKSETS_NODE, &cfg_linkset_link_cmd);
install_node(&link_node, dummy_write);