Forum Discussion
LB for SMPP / SMSCs in NFV environment
Hi all, We are trying to use the LMT F5 (installed on Openstack) to be SMSC Getaway (Short Message Service Center – Getaway) for external messages Our installation is based on minimum 2 SMSCs, and Maximum 8 SMSCs
So, if an external application will connect to the SMSCs, the F5 will get the connection request (bind) and will try to connect to all active SMSCs with the same bind connection For messages running on top the active connection (submit_sm), the F5 will do a round robin between all the active SMSCs.
Connection from Client & message from SMSC:
- 1:: Client1 ---(bind)---> F5
- 1-1:: F5 ----(bind)----> SMSC1
- 1-2:: F5 ----(bind)----> SMSC2.... (max of 8 SMSCs)
- 1-1':: SMSC1 -----(bind_resp1)----->F5
- 1-2':: SMSC2 -----(bind_resp2)----->F5.... (max of 8 SMSCs)
- 2:: If (bind_resp1 = OK) or (bind_resp2 = OK) or (max 8 SMSCs); respond back to Client1 with OK
- 2:: Else; respond back with NOK
- 3:: SMSC1 ----(deliver_sm1)---->F5 [store sequence, use internal sequence]
- 3-1:: F5 ----(deliver_sm1)---->Client1
- 4:: SMSC2 ----(deliver_sm2)---->F5 [store sequence, use internal sequence]
- 4-1:: F5 ----(deliver_sm2)---->Client1
- 4-1':: Client1 ----(deliver_sm_resp2)---->F5
- 3-1':: Client1 ----(deliver_sm_resp1)---->F5
- 4-1'':: F5 ----(deliver_sm_resp2)---->SMSC2 [use original sequence]
- 3-1'':: F5 ----(deliver_sm_resp1)---->SMSC1 [use original sequence]
Connection from Client & message from Client:
- 1:: Client1 ---(bind)---> F5
- 1-1:: F5 ----(bind)----> SMSC1
- 1-2:: F5 ----(bind)----> SMSC2.... (max of 8 SMSCs)
- 1-1':: SMSC1 -----(bind_resp1)----->F5
- 1-2':: SMSC2 -----(bind_resp2)----->F5.... (max of 8 SMSCs)
- 2:: If (bind_resp1 = OK) or (bind_resp2 = OK); respond back to Client1 with OK
- 2:: Else; respond back with NOK
- 3:: Client1 ----(deliver_sm1)---->F5 [store sequence, use internal sequence]
- 4-1:: F5 ----(deliver_sm1)---->SMSC using Round Robin [store sequence, use internal sequence]
- 4-1':: SMSC ----(deliver_sm_resp1)---->F5 [use original sequence]
- 3-1':: F5----(deliver_sm_resp1)---->Client1 [use original sequence]
- Segman_342030Nimbostratus
when CLIENT_ACCEPTED { set seq_index 1 set bind_context 0
set unbind_context 0TCP::collect
}
when CLIENT_DATA { while { [TCP::payload length] > 16 } { binary scan [TCP::payload] IH8IIa* RQTLen RQTOper RQTStatus RQTSeq p if { [TCP::payload length] < $RQTLen } { TCP::collect $RQTLen return }
switch -glob $RQTOper { 00000001 - 00000002 - 00000009 { bind log local0.info "SMPP:BindRequest Data: LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" set bind_message [TCP::payload $RQTLen] set bind_context 1 foreach smsc_node [active_members -list pool_smsc] { set node [lindex [split $smsc_node " "] 0]:[lindex [split $smsc_node " "] 1] set smsc($smsc_node) "0 0 0" foreach {smsc_node_1} [array get smsc] { log local0.info "ARRAY_ELEMENT_1 ==> $smsc_node_1" } } } 00000006 { unbind log local0.info "SMPP:UnbindRequest Data:LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" set unbind_message [TCP::payload $RQTLen] set unbind_context 1 } 00000015 { enquire_link log local0.info "SMPP:enquireLinkRequest Data:LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" set enquire_message [TCP::payload $RQTLen] foreach {smsc_node b_status u_status el_status} [array get smsc] { array set smsc {$smsc_node "$b_status $u_status 0"} } } 00000004 { submit_sm log local0.info "SMPP:SubmitSMRequest Data:LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" Load balance SMS AO LB::detach } 8* { Response from client (deliver_sm_resp, ...) log local0.info "SMPP:CommandResponse Data:LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" Rewrite RQTSeq and set the correct SMS-C to respond if { [info exists s_seq_map($RQTSeq)] } { set old_RQTSeq [lindex $s_seq_map($RQTSeq) 0] TCP::payload replace 12 4 [binary format I $seq_index] use pool or node command pool [LB::server pool] member [lindex $s_seq_map($RQTSeq) 1] [lindex $s_seq_map($RQTSeq) 2] unset s_seq_map($RQTSeq) } else { Cannot route response log local0.info "SMPP:Unkown sequence [$RQTSeq] Data:LEN:$RQTLen Command:$RQTOper Satus:$RQTStatus Seqence:$RQTSeq" } } } TCP::release $RQTLen TCP::notify request } TCP::collect
}
when SERVER_CONNECTED {
TCP::collect }when SERVER_DATA { while { [TCP::payload length] > 16 } { binary scan [TCP::payload] IH8II RQTLen RQTOper RQTStatus RQTSeq p if { [TCP::payload length] < $RQTLen } { TCP::collect $RQTLen return } switch -glob $RQTOper {
0* { Deliver_sm, ... Rewrite seq TCP::payload replace 12 4 [binary format I $seq_index] set s_seq_map($seq_index) "$RQTSeq [IP::remote_addr] [TCP::remote_port]" incr seq_index }80000001 - 80000002 - 80000009 { Bind_resp if { $bind_context } { switch -glob $RQTStatus { 00000000 - 0 - 00000005 { No Error or ESME Already in Bound State log local0.info "Bind:ResponseOK Data: Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] " Added by YOSSI set smsc("[IP::remote_addr]:[TCP::remote_port]") "1 0 0" foreach {smsc_node b_status} [array get smsc] { log local0.info "smsc_node_res $smsc_node" if { $b_status eq "0 0 0" } { log local0.info "Bind:OneMoreSMSCToBind Data:\[Node: $smsc_node \]" log local0. " node [lindex [split $smsc_node " "] 0] port [lindex [split $smsc_node " "] 1]" set a [lindex [split $smsc_node " "] 0]:[lindex [split $smsc_node " "] 1] log local0.info "a $a" pool pool_smsc member $a TCP::collect -all TCP::respond $bind_message set smsc("$a") "1 0 0" log local0.info "smsc("$a")" return } } log local0.info "Bind:NoMoreSMSCToBind Data:\[SMSC: $smsc_node \]" } * { Else - Respond back to client log local0.info "Bind:ResponseFailed Data: Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] ]" } } set bind_context 0 } else { log local0.info "Bind:UnknownContext Data:Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] " TCP::payload replace 0 [TCP::payload length] "" set RQTLen 0 } } 80000006 { Unbind_resp if { $unbind_context } { log local0.info "Unbind:Response Data: Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] " set memb "[IP::remote_addr] [TCP::remote_port]" array set smsc {$memb "1 1 0"} foreach {smsc_node b_status u_status el_status} [array get smsc] { if {$u_status eq 0} { log local0.info "Unbind:OneMoreSMSCToUnbind Data:\[Node: $smsc_node \]" pool pool_smsc member $smsc_node TCP::collect -all TCP::respond $unbind_message return } } log local0.info "Unbind:NoMoreSMSCToUnbind Data" } else { log local0.info "Unbind:UnknownContext Data:Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] " TCP::payload replace 0 [TCP::payload length] "" set RQTLen 0 } set unbind_context 0 unset smsc; } 80000015 { Enquire_link_resp log local0.info "Enquire_link:Response Data: Status:$RQTStatus Node: [IP::remote_addr] [TCP::remote_port] " set memb "[IP::remote_addr] [TCP::remote_port]" array set smsc {$memb "1 1 0"} foreach {smsc_node b_status u_status el_status} [array get smsc] { if {$el_status eq 0} { log local0.info "Enquire_link:OneMoreSMSCToEnquireLink Data:\[Node: $smsc_node \]" pool pool_smsc member $smsc_node TCP::collect -all TCP::respond $enquire_message return } } log local0.info "Enquire_link:NoMoreSMSCToEnquireLink Data" } } TCP::release $RQTLen TCP::notify response } TCP::collect
}
- Segman_342030Nimbostratus
Help....
help with what?
im afraid this will be a little beyond what you can expect from a community forum to help you with. if you have a specific issue sure, but this feels like a whole implementation that doesn't work out (and you fail to explain what doesn't work).
you might consider contacting your local f5 sales team and asking for a f5 partner or professional services if this is important.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com