We need to decide which way to go with point codes, sccp- and ss7-instances. pmaier and I have reached different conclusions and wrote patches going in opposite directions, now we need to decide and cosolidate:
The MSC has various connections over SCCP: it serves BSSAP for several BSCs, and RANAP for several HNBGWs.
BSC - A MSC: BSC -}----------> BSSAP BSC - -----> RANAP / HNBGW -}-/ IuCS HNBGW -
1) I went for exactly one point code at the MSC (say PC=1). There is exactly one osmo_ss7_instance and one osmo_sccp_instance. The MSC has separate sccp_user_bind()s for the BSSAP and the RANAP SSNs. So PC=1,SSN=BSSAP goes to the A-interface sap_up(), and PC=1,SSN=RANAP goes to the IuCS sap_up().
When comparing to the TCP/IP model, the paradigm here is that a PC is like an IP address and the SSN like a port number. At the server, the MSC, I have one PC (IP address) and listen on one SSN (port) per protocol served, and clients all connect to the same PC+SSN, receiving separate connection IDs. I can also use the calling address to know which client I'm talking to.
Hence I moved the osmo_sccp_instance creation up to "the top" and created two sccp_user_bind()s, one for BSSAP and one for RANAP. This works in practice.
I can tear down and set up individual sccp_users (i.e. disable/enable IuCS or A separately), and handling different clients is done by the conn_ids and possibly keeping distinct osmo_sccp_addresses.
An pseudocode MSC VTY config for this scenario could look something like this:
msc sccp local-pc 0.0.1 ssn-iucs $OSMO_SSN_RANAP ! -> to IuCS rx cb ssn-a $OSMO_SSN_BSSAP ! -> to A rx cb remote-bsc 1 pc 1.0.1 remote-bsc 2 pc 1.0.2 remote-hnbgw 1 pc 2.0.2
i.e. one local PC is configured, each protocol has its separate SSN, each sccp_user_bind() serves all clients for that SSN.
This is the direction I took to add IuCS to AoIP.
2) pmaier added VTY configuration for various point codes, and went the other way: the MSC creates a separate osmo_sccp_instance per BSC connection. (The MSC is told the addresses of all known BSCs and) every time a BSC is configured via VTY, a new osmo_sccp_simple_client() is created. IIUC the MSC then has a distinct local PC for each BSC, and for each HNBGW.
In this model there still is a code problem I noticed while adding IuCS to AoIP in OsmoMSC: if I call osmo_sccp_simple_client() a second time with a different PC, the osmo_ss7_instance used is still the same (still id=1), and notes this second PC as its global local PC. The messages received for the first client's PC are then seen as remote and routed back out -> infinite message loop. A solution here would be to either a) use a separate osmo_ss7_instance per osmo_sccp_simpe_client() (simply add an ss7 instance id parameter to osmo_sccp_simpe_client() and increment by one each time) or b) implement the routing algorithm so that it notices the local PCs of several local SCCP clients.
A VTY config for this scenario so far looks like this:
! define some addresses, referenced below cs7 instance 1 sccp-address msc_local subsystem-number 254 point-code 0.0.1 routing-indicator PC sccp-address bsc_remote subsystem-number 254 point-code 0.0.2 routing-indicator PC sccp-address bsc_remote2 subsystem-number 254 point-code 0.0.3 routing-indicator PC
msc bsc cs7-instance 1 calling-addr msc_local called-addr bsc_remote bsc cs7-instance 1 calling-addr msc_local called-addr bsc_remote2
(I'm not sure whether it is possible to have several sccp_instances with the same msc_local address, but we would find solutions for these petty issues once we've decided which way to go.) (I also think 'calling-addr' and 'called-addr' should rather be named 'local-addr' and 'remote-addr': depending on who calls who, the calling-addr can be the remote or the local one. That's also besides the point for now.)
My personal idea is that 1) is simpler: we have one ss7 instance per program, no matter how many clients are served. I can still tear down and set up individual sccp_users (i.e. disable/enable IuCS or A separately), and handling different clients per SSN is done by the conn_ids and possibly keeping distinct osmo_sccp_addresses of the clients. 2) seems to me easier to misconfigure and it sounds to me like a paradigm of creating a whole new server for each client that connects, so instead of using an ss7_instance's routing, we create separate instances, each sending to only one counterpart.
But is 2) maybe the correct way to go for reasons I'm not aware of? I notice that what I wrote is biased towards 1) because that's my POV, but this is indended to be a neutral question.
We need a choice for 1) or 2) so that pmaier and I can adjust and merge our patches accordingly. Can you help us decide, hopefully with some background knowledge on how an SCCP network is intended to be set up?
Thanks!
~N
Hi Neels,
On Wed, Jun 28, 2017 at 06:27:36PM +0200, Neels Hofmeyr wrote:
I went for exactly one point code at the MSC (say PC=1). There is exactly one osmo_ss7_instance and one osmo_sccp_instance. The MSC has separate sccp_user_bind()s for the BSSAP and the RANAP SSNs. So PC=1,SSN=BSSAP goes to the A-interface sap_up(), and PC=1,SSN=RANAP goes to the IuCS sap_up().
This makes sense to me. If one wanted to do it even more flexible, then an option to use separate SS7 instances for each of the users (i.e. one for BSSAP and one for RANAP) makes sense. It could be conceived that the 2G/A/BSSAP and 3G/Iu/RANAP live in different SS7 networks with different point code spaces, or simply the fact that one wants to use different MTP-level signalling link(set)s for either of the two.
An pseudocode MSC VTY config for this scenario could look something like this:
msc sccp local-pc 0.0.1 ssn-iucs $OSMO_SSN_RANAP ! -> to IuCS rx cb ssn-a $OSMO_SSN_BSSAP ! -> to A rx cb remote-bsc 1 pc 1.0.1 remote-bsc 2 pc 1.0.2 remote-hnbgw 1 pc 2.0.2
I am not sure you generally want (to require) to manually configure each BSC on the MSC side. As the BSCs register to the MSC, I think by default, the MSC should simply allow any BSC to register to it, without having to manually create configuration for that. Manual config would serve no purpose other than as some kind of 'access control list' for security, and I think that's best kept out of the MSC and handled by some external STP or other device.
pmaier added VTY configuration for various point codes, and went the other way: the MSC creates a separate osmo_sccp_instance per BSC connection. (The MSC is told the addresses of all known BSCs and) every time a BSC is configured via VTY, a new osmo_sccp_simple_client() is created. IIUC the MSC then has a distinct local PC for each BSC, and for each HNBGW.
I don't think this makes sense, and I think it might be the result of a misunderstanding.
Configuring the MSC this way on the BSC makes sense. Configuring multiple MSCs on the BSC this way also makes sense (possible future multi-operator core network (MOCN), or the existing dual-MSC support in OsmoBSC).
However, on the MSC side, there is no reason why we would want to have one sccp_instance and/or ss7_instance for each BSC - nor for manually configuring each BSC (see above).
(I also think 'calling-addr' and 'called-addr' should rather be named 'local-addr' and 'remote-addr': depending on who calls who, the calling-addr can be the remote or the local one. That's also besides the point for now.)
yes, 'calling' and 'called' address can be quite confusing, as they change their meaning depending on the specific SCCP message you look at (in case of connection oriented SCCP). For the Connection Request, "Calling" is the sender, but for the Connection Confirm, "Calling" is the receiver.
My personal idea is that 1) is simpler: we have one ss7 instance per program, no matter how many clients are served.
I think this is sufficient. More elegant would though be (optionally) one ss7_instance + sccp_instance for each user, see above.
Thanks for the clarification.
If one wanted to do it even more flexible, then an option to use separate SS7 instances for each of the users (i.e. one for BSSAP and one for RANAP) makes sense. It could be conceived that the 2G/A/BSSAP and 3G/Iu/RANAP live in different SS7 networks with different point code spaces, or simply the fact that one wants to use different MTP-level signalling link(set)s for either of the two.
If we have separate ss7+sccp instances, we need to run each instance on its own IP address or port. And for routing both also need a separate point code. Have I got this correctly?
MSC BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4: PC=1,SSN=BSSAP BSC --/ ^ \ / ---> ss7-instance@5.6.7.8: PC=2,SSN=RANAP HNBGW ---PC=2,SSN=RANAP-/
Ah, or completely separate STP, then allowing the same PC:
MSC BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4: PC=1,SSN=BSSAP BSC --/ -> ss7-instance@5.6.7.8: PC=1,SSN=RANAP HNBGW ---PC=1,SSN=RANAP-> STP -/
One ss7+sccp instance means we have same IP address and PC:
MSC BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4:--> PC=1,SSN=BSSAP BSC --/ ^ -> PC=1,SSN=RANAP / HNBGW ---PC=1,SSN=RANAP-/
I imagine we could make this configurable in the way that pmaier has begun, like:
cs7-instance 1 bind addr 1.2.3.4 pc 0.0.1 cs7-instance 2 bind addr 5.6.7.8 pc 0.0.2 msc iface-a cs7-instance 1 ssn $BSSAP iface-iucs cs7-instance 2 ssn $RANAP ! instance 2 != 1
vs.
cs7-instance 1 bind addr 1.2.3.4 pc 0.0.1 msc iface-a cs7-instance 1 ssn $BSSAP iface-iucs cs7-instance 1 ssn $RANAP ! instance 1 again
Then we can allow entirely separate transports, but most "normal" users would simply use one instance and hence one IP address + port for receiving any SCCP connections at the MSC.
I believe the implementation to allow this duality is fairly trivial: have a list of sccp_instances each on a distinct ss7_instance; then pass a specific sccp_instance pointer when creating the osmo_sccp_user_bind().
I am not sure you generally want (to require) to manually configure each BSC on the MSC side. As the BSCs register to the MSC, I think by default, the MSC should simply allow any BSC to register to it, without having to manually create configuration for that.
That's how I imagined it, but it complicates the MSC-side BSSAP Reset, which the MSC sends to the BSCs to signal a restart. If the MSC knows which BSCs exist by config, it can right away send a BSSAP Reset when it (re)starts.
We can also decide to not tell the MSC about the BSCs, and send the BSSAP Reset whenever we first hear about a given BSC. But that means a BSC will not know that the MSC has restarted until it sends the next message to the MSC.
Upon receiving a Reset, a BSC can tear down ongoing calls. If the Reset comes late, it might be considered a feature that an ongoing call can still continue and conclude, but an operator that does billing may have a different opinion.
We could again have two modes configured by VTY, an "open access" that allows any BSC that might come along, with a "lazy" MSC side Reset; or an explicit list of BSCs that are allowed exclusively, and receive a Reset immediately.
This duality is not as trivial as above, I guess.
Planning of the network requires that no two BSCs share the same point code, so that replies to its requests are guaranteed to go back to the same. So one could argue that having to tell the MSC which BSCs exists might help there? I could also just put a list of BSCs in the MSC config whether they exist or not -- at least as soon as we ensure that a message to an unknown PC doesn't cause an endless message loop :P
I'm not sure how important MSC-side Reset vs. "open access" for BSCs are. I believe it makes sense to go with pmaier's code state and require explicit BSC config with the MSC until we see a need to change that.
~N
Hi Neels,
On Thu, Jun 29, 2017 at 02:45:21AM +0200, Neels Hofmeyr wrote:
If we have separate ss7+sccp instances, we need to run each instance on its own IP address or port. And for routing both also need a separate point code. Have I got this correctly?
MSC
BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4: PC=1,SSN=BSSAP BSC --/ ^ \ / ---> ss7-instance@5.6.7.8: PC=2,SSN=RANAP HNBGW ---PC=2,SSN=RANAP-/
this is a less likely configuration. The point of having different SS7 instances is that we want to participate in e.g. two separate signalling netwokrs, which have overlapping point code spaces (like two private IP networks that use the same IP addresses).
Ah, or completely separate STP, then allowing the same PC:
MSC
BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4: PC=1,SSN=BSSAP BSC --/ -> ss7-instance@5.6.7.8: PC=1,SSN=RANAP HNBGW ---PC=1,SSN=RANAP-> STP -/
yes, that's the more likely configuration.
One ss7+sccp instance means we have same IP address and PC:
MSC
BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4:--> PC=1,SSN=BSSAP BSC --/ ^ -> PC=1,SSN=RANAP / HNBGW ---PC=1,SSN=RANAP-/
corect.
I imagine we could make this configurable in the way that pmaier has begun, like:
cs7-instance 1 bind addr 1.2.3.4 pc 0.0.1 cs7-instance 2 bind addr 5.6.7.8 pc 0.0.2
It should use the sccp address book that pmaier implemented. * There we define the SCCP address of the MSC-side BSSAP or RANAP * There we define in which SCCP instance this address resides
The MSC code then simply refers to those "named sccp addresses" and uses them.
The MTP-level link(set), ASP, ... definition should not be mixed with the SCCP addresses. Both the VTY config of the link(sets) and the SCCP address book should come from libosmo-sigtran, while the MSC simply refers to certain named SCCP addresses.
msc iface-a cs7-instance 1 ssn $BSSAP iface-iucs cs7-instance 2 ssn $RANAP ! instance 2 != 1
The SSN should be hard-coded, I think allowing users to change it is just calling for them to shoot themselves in the foot.
I am not sure you generally want (to require) to manually configure each BSC on the MSC side. As the BSCs register to the MSC, I think by default, the MSC should simply allow any BSC to register to it, without having to manually create configuration for that.
We can also decide to not tell the MSC about the BSCs, and send the BSSAP Reset whenever we first hear about a given BSC.
I like that approach.
But that means a BSC will not know that the MSC has restarted until it sends the next message to the MSC.
I think that's fine. If there's no traffic ongoing, then the reset would serve no purpose. And if there is traffic, then the reset will be triggered by the first related message from BSC->MSC.
Pleae also note that sooner or later a disapparing MSC will trigger "destination unavailable" notifications via the N-NOTICE.ind primitive at the SCCP-User-SAP, so there will be notification to the BSC in this case.
Upon receiving a Reset, a BSC can tear down ongoing calls. If the Reset comes late, it might be considered a feature that an ongoing call can still continue and conclude, but an operator that does billing may have a different opinion.
I think we can ignore that. If really needed, you can make sure the call is unusable by terminating the MSC-side MGW when restating the MSC.
We could again have two modes configured by VTY, an "open access" that allows any BSC that might come along, with a "lazy" MSC side Reset; or an explicit list of BSCs that are allowed exclusively, and receive a Reset immediately.
seems a bit too complex for my taste. If we do this, then "open" should be the default.
I'm not worried about having complex configuration for the classic uperators who understand MTP, SIGTRAN and SCCP. But I'm worried about making it too difficult to set up a small network for those people who don't. So the default should be "make it easy for non-experts".
Planning of the network requires that no two BSCs share the same point code, so that replies to its requests are guaranteed to go back to the same.
People dealing with classic SS7 networks are used to that.
I'm still considering adding a "DHCP server Style" point code allocation to OsmoSTP to make it simple for people who lack that background, and who simply want to run a self-contained osmocom network.
I'm not sure how important MSC-side Reset vs. "open access" for BSCs are. I believe it makes sense to go with pmaier's code state and require explicit BSC config with the MSC until we see a need to change that.
Hello Harald and Neels,
I went for exactly one point code at the MSC (say PC=1). There is exactly one osmo_ss7_instance and one osmo_sccp_instance. The MSC has separate sccp_user_bind()s for the BSSAP and the RANAP SSNs. So PC=1,SSN=BSSAP goes to the A-interface sap_up(), and PC=1,SSN=RANAP goes to the IuCS sap_up().
This makes sense to me. If one wanted to do it even more flexible, then an option to use separate SS7 instances for each of the users (i.e. one for BSSAP and one for RANAP) makes sense. It could be conceived that the 2G/A/BSSAP and 3G/Iu/RANAP live in different SS7 networks with different point code spaces, or simply the fact that one wants to use different MTP-level signalling link(set)s for either of the two.
I think this makes sense too. Then we would call the osmo_sccp_simple_client() in some central place to get the sccp_instance. This would mean that we define one address for the MSC, that is then used by RANAP and BSSAP at the same time
Next an initalizer function would reserve exactly one sccp_user for the A-Interface using osmo_sccp_user_bind() and another one for for RANAP
After that we can add BSCs using a_init() (which I still think is necessary, see below)
I do not see any problems with that solution and I think it is also the simplest one. Having separate sccp_instance, or even separate ss7 instances would make the system more complicated for no good reason.
However, I see some problems with defining the sccp addresses in the VTY. An sccp address also gets an SSN. If we use one address for BSSAP and RANAP at the same time. We need to define the SSN separately, because we need two different ones. So I will have to define the ssn separately via another VTY command.
cs7 instance 1 sccp-address msc_local point-code 0.0.1 routing-indicator PC sccp-address bsc_remote point-code 0.0.2 routing-indicator PC
msc ssn-bssmap 254 ssn-ranap 142 calling-addr msc_local bsc cs7-instance 1 called-addr bsc_remote
But maybe we can also skip the SSN and leave it hardcoded. I do not know how hard the standard dictates those numbers. If it is "law" to use e.g. 254 only and always for BSSAP, we can leave it hardcoded for sure. This will eliminate the need for a separate VTY command here.
I don't think this makes sense, and I think it might be the result of a misunderstanding.
I am not sure about this. The specification (3GPP TS 48.008 3.1.4.1.2 Reset at the MSC) says: "In the event of a failure at the MSC which has resulted in the loss of transaction reference information, a RESET message is sent to the BSS. This message is used by the BSS to release affected calls and erase all affected references and to put all circuits into the idle state."
I do not know how that should work if the MSC has no configuration where to send the reset. Failure means crash/restart to me. The MSC has lost all knowledge about the BSS, so that needs to come from somewhere. Do we know how other vendors handle the problem?
regards, Philipp
On Thu, Jun 29, 2017 at 11:58:10AM +0200, Philipp Maier wrote:
I see some problems with defining the sccp addresses in the VTY. An sccp address also gets an SSN. So I will have to define the ssn separately via another VTY command.
Not necessarily. Your address book VTY code allows to set only a PC, omitting an SSN. Later on we can add an SSN according to which protocol is served, by taking the address book entry, copying the address and adding an SSN.
We can then of course not modify an SCCP address on-the-fly. I believe this anyway needs a restart of the sccp_user_bind, so I think we should not bother to support that. (restarting e.g. the BSSAP would allow changes on-the-fly.)
(I notice also that the VTY code "manually" sets the address parts like PC and SSN, placing presence flags. I guess it would make sense to have API functions that do this, in the sense of osmo_sccp_addr_set_{pc,ssn}(); and to copy.)
Then we would call the osmo_sccp_simple_client() in some central place to get the sccp_instance.
I understand the discussion to conclude differently: we use your SCCP address book, making it possible to use either a single osmo_sccp_simple_client() or separate ones, depending on the VTY config. We assign the addresses so defined to BSSAP and RANAP, with the SSNs hardcoded (by addr copy). That allows two scenarios depending on vty config, for example something like:
MSC BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4: PC=1,SSN=BSSAP BSC --/ 10.9.8.7 -> ss7-instance@5.6.7.8: PC=1,SSN=RANAP HNBGW ---PC=1,SSN=RANAP-> STP -/ 6.5.4.3
cs7 instance 1 sccp bind-addr 1.2.3.4 remote-stp 10.9.8.7 ! add simple_client? sccp-address msc_local_a point-code 0.0.1 routing-indicator PC
cs7 instance 2 sccp bind-addr 5.6.7.8 remote-stp 6.5.4.3 ! add simple_client? sccp-address msc_local_iucs point-code 0.0.1 routing-indicator PC
msc local-addr a ss7-instance 1 msc_local_a ! SSN added implicitly local-addr iu ss7-instance 2 msc_local_iucs ! by copying the address book entry
(Could we also omit the 'ss7-instance 1', instead implied by the address name?)
Or this: MSC BSC ---PC=1,SSN=BSSAP---> STP ---> ss7-instance@1.2.3.4:--> PC=1,SSN=BSSAP BSC --/ 10.9.8.7 -> PC=1,SSN=RANAP ^ / HNBGW ---PC=1,SSN=RANAP-/
cs7 instance 1 sccp bind-addr 1.2.3.4 remote-stp 10.9.8.7 ! add simple_client? sccp-address msc_local point-code 0.0.1 routing-indicator PC
msc local-addr a ss7-instance 1 msc_local ! same address for both, SSN added implicitly local-addr iu ss7-instance 1 msc_local ! by copying the address book entry
(Could we also omit the 'ss7-instance 1', instead implied by the address name?)
To allow the above, we need to add an id argument to osmo_sccp_simple_client() to indicate the ss7 instance id. Possibly, the ss7 instance could be created automatically by calling osmo_sccp_simple_client() with a before unused id.
Though, the only reason so far to have separate ss7 instances seems to me that the ss7 instance records its local PC "globally". It seems that an ss7 instance can have separate AS with separate local bind IP addresses and so forth. So I guess we will have one ss7 instance per osmo_sccp_simple_client(), but it seems that's not strictly necessary, besides our missing routing feature? Not sure.
Next an initalizer function would reserve exactly one sccp_user for the A-Interface using osmo_sccp_user_bind() and another one for for RANAP
yes.
After that we can add BSCs using a_init() (which I still think is necessary, see below)
a_init() should happen only once, e.g. upon above suggested:
msc local-addr a msc_local
We will not have separate SCCP clients per BSC.
MSC side BSSAP Reset:
I am not sure about this. The specification (3GPP TS 48.008 3.1.4.1.2 Reset at the MSC) says: "In the event of a failure at the MSC which has resulted in the loss of transaction reference information, a RESET message is sent to the BSS. This message is used by the BSS to release affected calls and erase all affected references and to put all circuits into the idle state."
I do not know how that should work if the MSC has no configuration where to send the reset. Failure means crash/restart to me. The MSC has lost all knowledge about the BSS, so that needs to come from somewhere. Do we know how other vendors handle the problem?
Send a Reset to each BSC that shows up for the first time. I'm also not sure about this, but Harald sounds pretty certain, so I'm willing to follow that lead.
~N