Add bssgp_ns_send callback() to set the transmission path into the
NS library. This allows to use the Gb implementation with
the old NS and the new upcoming NS implementation.
Users of the old NS implementation don't have to set the callback as
the default is the old NS implementation.
Only users of the new NS implementation need to set the callback and
the callback data.
Change-Id: I3a498e6a0d68b87fed80c64199b22395796761b4
We cannot just set sockaddr_in.sin_addr + sin_port, we also must
initializa sin_family. The reason this has worked so far is
because we probably always first received a NS packet from the
peer, rather than being the first one to send.
Change-Id: I6cefc2cd5516c7a4c01a2cc040afca454e59dd57
Related: OS#4629
If a BVC-RESET is sent from SGSN, there must not be a cell ID IE
included. See "Note 1" of TS 48.018 Section 10.4.12.
Change-Id: I11d4e70d510265b9c09dffccdab10b3f0816715a
This reverts commit d1ceca9d48, as it
introduces regressions in both osmo-msc and osmo-nitb which have been
causing failing builds for several days now.
Change-Id: I4bd958d0cd2ab4b0c4725e6d114f4404d725fcf7
Implement better API around 3GPP TS 24.008 Mobile Identity coding.
struct osmo_mobile_identity is a decoded representation of the raw Mobile
Identity, with a string representation as well as dedicated raw uint32_t TMSI.
The aim is to remove all uncertainty about decoded buffer sizes / data types.
I have patches ready for all osmo programs, completely replacing the Mobile
Identity coding with this new API. Hence deprecate the old MI API.
New API functions provide properly size-checking implementations of:
- decoding a raw MI from a bunch of MI octets;
- locating and decoding MI from a full 3GPP TS 24.008 Complete Layer 3 msgb;
- encoding to a buffer;
- encoding to the end of a msgb.
Other than the old gsm48_generate_mid(), omit a TLV tag and length from
encoding. Many callers manually stripped the tag and value after calling
gsm48_generate_mid(). The aim is to leave writing a TL to the caller entirely,
especially since some callers need to use a TvL, i.e. support a variable-size
length of 8 or 16 bit.
New validity checks so far not implemented anywhere else:
- stricter validation of number of digits of IMSI, IMEI, IMEI-SV MI.
- stricter on filler nibbles to be 0xf.
Rationale:
While implementing osmo-bsc's MSC pooling feature in osmo-bsc, this API will be
used to reduce the number of times a Mobile Identity is extracted from a raw
RSL message.
Extracting the Mobile Identity from messages has numerous duplicate
implementations across our code with various levels of specialization.
https://xkcd.com/927/
To name a few:
- libosmocore: gsm48_mi_to_string(), osmo_mi_name_buf()
- osmo-bsc: extract_sub()
- osmo-msc: mm_rx_loc_upd_req(), cm_serv_reuse_conn(), gsm48_rx_mm_serv_req(),
vlr_proc_acc_req()
We have existing functions to produce a human readable string from a Mobile
Identity, more or less awkward:
- gsm48_mi_to_string() decodes a TMSI as a decimal number. These days we use
hexadecimal TMSI everywhere.
- osmo_mi_name_buf() decodes the BCD digits from a raw MI every time, so we'd
need to pass around the raw message bytes. Also, osmo_mi_name_buf() has the
wrong signature, it should return a length like snprintf().
- osmo-bsc's extract_sub() first uses gsm48_mi_to_string() which encodes the
raw uint32_t TMSI to a string, and then calls strtoul() via
tmsi_from_string() to code those back to a raw uint32_t.
Each of the above implementations employ their own size overflow checks, each
invoke osmo_bcd2str() and implement their own TMSI osmo_load32be() handling.
Too much code dup, let's hope that each and every one is correct.
In osmo-bsc, I am now implementing MSC pooling, and need to extract NRI bits
from a TMSI Mobile Identity. Since none of the above functions are general
enough to be re-used, I found myself again copy-pasting Mobile Identity code:
locating the MI in a 24.008 message with proper size checks, decoding MI
octets.
This time I would like it to become a generally re-usable API.
Change-Id: Ic3f969e739654c1e8c387aedeeba5cce07fe2307
3GPP TS 48.016 is quite clear in that no NS-{RESET,BLOCK,UNBLOCK}
procedures shall be used over an IP based transport. They are only
for use in Frame Relay based transport.
However, as libosmogb was first developed against ip.access nanoBTS,
and their Gb implementation mandates those procedures, we
unconditionally implemented those procedures back then. Let's
give the user the option of disabling this behavior to become
more spec compliant (and interoperate with more other vendors out
there).
Change-Id: Ic4eba1b4dcbeac00f5879db295e0a9f1a50f71d8
gcc-9.2.1 issues the following errror when compiling with -Werror:
In function ‘tl16v_put’,
inlined from ‘tvlv_put’ at ../../include/osmocom/gsm/tlv.h:156:9,
inlined from ‘tvlv_put’ at ../../include/osmocom/gsm/tlv.h:147:24,
inlined from ‘msgb_tvlv_put’ at ../../include/osmocom/gsm/tlv.h:223:9,
inlined from ‘bssgp_tx_paging’ at gprs_bssgp.c:1250:2:
../../include/osmocom/gsm/tlv.h:131:2: error: ‘memcpy’ reading between 128 and 65535 bytes from a region of size 9 [-Werror=stringop-overflow=]
131 | memcpy(buf, val, len);
| ^~~~~~~~~~~~~~~~~~~~~
Unfortunately I've not been able to work around it with some nice GCC
#pragma GCC diagnostic ignored "-Wstringop-overflow"
Change-Id: I22a0c399c6c00eaf87277002096a82844c9e198e
So far we had a function to allocate a new bssgp_bvc_ctx, but not
the opposite one. Let's finally introduce it, so it will be used
at least in OsmoPCU.
Please note that the new symbol has 'bssgp_' prefix, not 'btsctx_'.
Change-Id: Ia78979379dbdccd6e4628c16f00d0c06d9212172
Do not return a warning and therefore fail parsing the config when the
"encapsulation framerelay-gre local-ip" command is used and FR/GRE is
disabled. Having this in the config does no harm and allows keeping the
same config if it is enabled later.
This fixes the currently failing vty tests for osmo-sgsn.
Fixes: a0c8195ad3 ("vty: Return error if cmd returns CMD_WARNING while reading cfg file")
Change-Id: Ic225232fbfca49ba868427eaf898e1f6e34e1ca8
log_enable_multithread() enables use of locks inside the
implementation. Lock use is disabled by default, this way only
multi-thread processes need to enable it and suffer related
complexity/performance penalties.
Locks are required around osmo_log_target_list and items inside it,
since targets can be used, modified and deleted by different threads
concurrently (for instance, user writing "logging disable" in VTY while
another thread is willing to write into that target).
Multithread apps and libraries aiming at being used in multithread apps
should update their code to use the locks introduced here when
containing code iterating over osmo_log_target_list explictly or
implicitly by obtaining a log_target (eg. osmo_log_vty2tgt()).
Related: OS#4088
Change-Id: Id7711893b34263baacac6caf4d489467053131bb
We have a number of library-internal static global buffers which are
mainly used for various stringification functions. This worked as
all of the related Osmocom programs were strictly single-threaded.
Let's make those buffers at least thread-local. This way every thread
gets their own set of buffers, and it's safe for multiple threads to
execute the same functions once. They're of course still not
re-entrant. If you need re-entrancy, you will need to use the _c()
or _buf() suffix version of those functions and work with your own
(stack or heap) buffers.
Change-Id: I50eb2436a7c1261d79a9d2955584dce92780ca07
Calling sizeof() on a pointer would result in getting size of the
pointer (usually 4 or 8 bytes) itself, but not the size of the
memory it points to.
Change-Id: I83f55a9638b75d9097d37992f7c84707791f10f6
Fixes: CID#194266
We have a habit of returning static buffers from some functions,
particularly when generating some kind of string values. This is
convenient in terms of memory management, but it comes at the expense
of not being thread-safe, and not allowing for two calls of the
related function within one printf() statement.
Let's introduce _c suffix versions of those functions where the
caller passes in a talloc context from which the output buffer shall
be allocated.
Change-Id: I8481c19b68ff67cfa22abb93c405ebcfcb0ab19b
We have a number of static buffers in use in libosmo*. This means
the related functions are not usable in a thread-safe way. While
we so far don't have many multi-threaded programs in the osmocom
universe, the static buffers also prevent us from calling the same
e.g. string-ify function twice within a single printf() call.
Let's make sure there's an alternative function in all those cases,
where the user can pass in a caller-allocated buffer + size, and make
the 'classic' function with the static buffer a wrapper around that
_buf() variant.
Change-Id: Ibf85f79e93244f53b2684ff6f1095c5b41203e05
Handle NSEI the same way as BVCI is handled: assign it to variable
instead of repetitive calls to msgb_nsei() - this simplifies log update
in follow-up patches and makes code slightly easier to read.
Change-Id: I919a717ca22646849d6ec7f62c677c536db0ed31
The naming of these constants dates back to when the code was private
within OpenBSC. Everything else was renamed (bsc_fd -> osmo_fd) at
the time, but somehow the BSC_FD_* defines have been missed at the
time.
Keep compatibility #defines around, but allow us to migrate the
applications to a less confusing naming meanwhile.
Change-Id: Ifae33ed61a7cf0ae54ad487399e7dd2489986436
When putting together a sockaddr_in, we must not only set the IP
address and port, but also set the address family to AF_INET. And
while at it, let's zero-initialize the entire 'struct sockdadr_in'.
Change-Id: I1c8d8fe7f79a2ec737baa7800247269c3271983e
we cannot use "nsi->nsip.remote_ip", as this address is not set
when SNS is in use. We can only have a valid nsi->nsip.remote_ip
if there's only a single NS-VC inside the NS Instance, as this would
connect() the UDP socket to the remote IP/port, breaking any possibility
to have multiple NS-VCs to different SGNS-side IP addresses.
Closes: OS#3845
Change-Id: Ic094621eb01d7458063f531289d5eeadf52bf330
Section 6.2.1 of 3GPP TS 48.016 states:
> A pre-configured endpoint shall not be used for NSE data or signalling
> traffic (with the exception of Size and Configuration procedures) unless
> it is configured by the SGSN using the auto-configuration procedures.
However, in the current SNS implementation, the initial IP/Port over
which we perform the SNS-SIZE + SNS-CONFIG are treated as one of the
normal NS-VCs. Specifically, we also perform the NS-ALIVE procedure on
it, which is clearly wrong.
Let's explicitly create the "initial" NS-VC with data and signalling
weight of 0, and ensure we never start the alive timer or send any
non-SNS PDUs on this connection as long as SNS was not used to change
either of the two weights to non-zero.
While at it, also safeguard against processing any incoming non-SNS
messages on such a all-zero-weight connection.
Change-Id: I16a91a07e5914d123b2ea2f8413b94e7cd518628
Closes: OS#3844
The NS implementation part of the Gb implementation libosmogb
so far implemented a rather classic dialect of Gb, with lots of
heritage to FR (Frame Relay) transports. At least since Release 6
of the NS specification, there's an IP Sub-Network Service (SNS),
which
* permits for dynamic configuration of IP endpoints and their NS-VCs
* abandons the concept of a NSVCI on IP transport
* forbids the use of RESET/BLOCK/UNBLOCK procedures on IP transport
This commit introduces BSS-side IP-SNS support to libosmogb in a
minimally invasive way. It adds a corresponding SNS FSM to each NS
instance, and implements the new SIZE/CONFIG/ADD/DELETE/CHANGE_WEIGHT
procedures very closely aligned with the spec.
In order to use the SNS flavor (rather than the classic one),
a BSS implementation should use gprs_ns_nsip_connect_sns() instead
of the existing gprs_ns_nsip_connect().
This implementation comes with a set of TTCN-3 tests in
PCU_Tests_RAW_SNS.ttcn, see Change-ID
I0fe3d4579960bab0494c294ec7ab8032feed4fb2 of osmo-ttcn3-hacks.git
Closes: OS#3372
Closes: OS#3617
Change-Id: I84786c3b43a8ae34ef3b3ba84b33c90042d234ea
This function performs sending a NS-ALIVE PDU and starting Tns-Test,
let's use it in all places where we used to do that.
As part of this, also fix a bug where the sendto() return value (number
of bytes sent) would actually propagate up all the way to
gprs_ns_rx_reset() return value, which in turn affects the test results
on stdout.
Change-Id: I4d303117f77fabb74bbb91887b9914a81c2a084a
Modern NS specifications contain a SNS (Sub Network Service) for
negotiating IP/port/weight parameters of NS-over-IP links dynamically.
This patch adds message encoding routines for SNS-CONFIG, SNS-SIZE
and their respective acknowledgements.
Related: OS#3372
Change-Id: I5c47e1c3c10deb89a7470ee2c03adfc174accc93
When I added the definitions for the IP-SNS in commit
f030b210e8 back in 2010, I forgot to update
the string definitions in ns_cause_str[]. Let's fix that
Change-Id: I419ccc482d99b01263a60aede83dacd2d9de56ab
According to Section 9.2.4 of 3GPP TS 48.016, the NS-BLOCK-ACK PDU has a
mandatory NSVCI IE which we so far were missing.
Change-Id: Ie7205e99d57f1e42d941f1be2460d8c9f46aadfe
Closes: OS#3808
gcc-8.2 is printing the following warning, which is an error
when used -Werror like our --enable-werror:
In file included from gprs_bssgp.c:34:
In function ‘tl16v_put’,
inlined from ‘tvlv_put.part.3’ at ../../include/osmocom/gsm/tlv.h:156:9,
inlined from ‘tvlv_put’ at ../../include/osmocom/gsm/tlv.h:147:24,
inlined from ‘msgb_tvlv_push’ at ../../include/osmocom/gsm/tlv.h:386:2,
inlined from ‘bssgp_tx_dl_ud’ at gprs_bssgp.c:1162:4:
../../include/osmocom/gsm/tlv.h:131:2: error: ‘memcpy’ forming offset [12, 130] is out of the bounds [0, 11] of object ‘mi’ with type ‘uint8_t[11]’ {aka ‘unsigned char[11]’} [-Werror=array-bounds]
memcpy(buf, val, len);
Where "130" seems to be the maximum value of uint8_t, shifted right one +
2. But even as we use strnlen() with "16" as maximum upper bound, gcc
still believes there's a way that the return value of gsm48_generate_mid_from_imsi()
could be 130. In fact, even the newly-added OSMO_ASSERT() inside
gsm48_generate_mid() doesn't help and gcc still insists there is a problem :(
Change-Id: I0a06daa19b7b5b5badbb8b3d81a54c45b88a60ec
The longest BCd-digit type identity is the IMEISV with 16, so there's
no point in trying to parse up to 255 decimal digits, which will do
nothing but to overflow the caller-provided output buffer.
Let's also clearly define the required minimum size of the output
buffer and add a reltead #define for it.
Change-Id: Ic8488bc7f77dc9182e372741b88f0f06100dddc9
Since commit 797558ea17 we send the
NS_UNBLOCK_ACK message before dispatching the NS_UNBLOCK signal,
instead of afterwards.
Add comments which explain the intended order of events.
Suggested-by: Pau
Related: OS#2388
Change-Id: I4b93853c952a97302f8afc14f462f22c3e487564
In gprs_ns_process_msg(), we were dispatching the S_NS_UNBLOCK
signal before sending out the NS_POUT_UNBLOCK_ACK message.
Signal handlers might send messages to the other side, assuming
that NS is now unblocked. However, since such messages will arrive
before the UNBLOCK_ACK message the receiver might discard them.
This problem has been observed with our TTCN3 BSSGP_Emulation
as a peer to osmo-pcu.
This patch makes TTCN3 PCU TC_paging() test pass regardless of
whether the test or osmo-pcu is started first. Before this patch,
this test would only pass if the test was started before osmo-pcu.
A remaining problem is that the test does not yet keep passing
reliably unless osmo-pcu is restarted between test runs.
Change-Id: I3af54a14bb6bcfa167c9a9d9f67835e7f5b9f1bb
Related: OS#2890
Related: OS#2388
If we cannot bind the listening socket, reset related fields in
the osmo fd structure to NULL again. Otherwise our caller might
eventually try to use an uninitialized osmo fd.
Change-Id: Ia953b2eff54cac0bd980944291f75db14df09a34
Related: OS#3643
The intention was to use the file's basename, but __BASE_FILE__ means "the root
file that is being parsed and contains #include statements".
If we had a function using __BASE_FILE__ and that was defined in an #included
file, __BASE_FILE__ would indicate the first file where the #include is, and
not the file where the function is defined. __BASE_FILE__ works for us because
we don't ever include function definitions that log something, so __BASE_FILE__
always coincides with __FILE__ for our logging; but still __BASE_FILE__ is
semantically the wrong constant.
Related: OS#2740
Change-Id: Ibc1d3746f1876ac42d6b1faf0e5f83bd2283cdcc
To reset the state of BSSGP allow to flush the BSSGP queues.
When testing (with TTCN3) the test object should be resetted between
each test.
Introduce the functions:
bssgp_fc_flush_queue() - flushs a single flow control object
bssgp_flush_all_queues() - flushs queues of all BSSGP connections
Change-Id: I29b6ad6742ddf9b0b58b4af37d9a1cf18e019325