Loading...
Searching...
No Matches
gprs_ns2_udp.c File Reference

NS-over-UDP implementation. More...

`#include <errno.h>`
`#include <osmocom/core/osmo_io.h>`
`#include <osmocom/core/select.h>`
`#include <osmocom/core/sockaddr_str.h>`
`#include <osmocom/core/socket.h>`
`#include <osmocom/gprs/gprs_ns2.h>`
`#include "common_vty.h"`
`#include "gprs_ns2_internal.h"`

## Data Structures

struct | priv_bind
struct | priv_vc

## Functions

static void | free_bind (struct gprs_ns2_vc_bind *bind)
| clean up all private driver state.
static void | free_vc (struct gprs_ns2_vc *nsvc)
static void | dump_vty (const struct gprs_ns2_vc_bind *bind, struct vty *vty, bool stats)
struct gprs_ns2_vc * | gprs_ns2_nsvc_by_sockaddr_bind (struct gprs_ns2_vc_bind *bind, const struct osmo_sockaddr *rem_addr)
| Find a NS-VC by its remote socket address.
static int | nsip_sendmsg (struct gprs_ns2_vc_bind *bind, struct msgb *msg, const struct osmo_sockaddr *dest)
static int | nsip_vc_sendmsg (struct gprs_ns2_vc *nsvc, struct msgb *msg)
| send the msg and free it afterwards.
static struct priv_vc * | ns2_driver_alloc_vc (struct gprs_ns2_vc_bind *bind, struct gprs_ns2_vc *nsvc, const struct osmo_sockaddr *remote)
static void | handle_nsip_recvfrom (struct osmo_io_fd *iofd, int error, struct msgb *msg, const struct osmo_sockaddr *saddr)
static void | handle_nsip_sendto (struct osmo_io_fd *iofd, int res, struct msgb *msg, const struct osmo_sockaddr *daddr)
struct gprs_ns2_vc_bind * | gprs_ns2_ip_bind_by_sockaddr (struct gprs_ns2_inst *nsi, const struct osmo_sockaddr *sockaddr)
| Find NS bind for a given socket address.
int | gprs_ns2_ip_bind (struct gprs_ns2_inst *nsi, const char *name, const struct osmo_sockaddr *local, int dscp, struct gprs_ns2_vc_bind **result)
| Bind to an IPv4/IPv6 address.
struct gprs_ns2_vc * | ns2_ip_bind_connect (struct gprs_ns2_vc_bind *bind, struct gprs_ns2_nse *nse, const struct osmo_sockaddr *remote)
| Create new NS-VC to a given remote address.
const struct osmo_sockaddr * | gprs_ns2_ip_vc_local (const struct gprs_ns2_vc *nsvc)
| Return the socket address of the local peer of a NS-VC.
const struct osmo_sockaddr * | gprs_ns2_ip_vc_remote (const struct gprs_ns2_vc *nsvc)
| Return the socket address of the remote peer of a NS-VC.
bool | gprs_ns2_ip_vc_equal (const struct gprs_ns2_vc *nsvc, const struct osmo_sockaddr *local, const struct osmo_sockaddr *remote, uint16_t nsvci)
| Compare the NS-VC with the given parameter.
const struct osmo_sockaddr * | gprs_ns2_ip_bind_sockaddr (struct gprs_ns2_vc_bind *bind)
| Return the locally bound socket address of the bind.
int | gprs_ns2_is_ip_bind (struct gprs_ns2_vc_bind *bind)
| Is the given bind an IP bind?
int | gprs_ns2_ip_bind_set_dscp (struct gprs_ns2_vc_bind *bind, int dscp)
| Set the DSCP (TOS) bit value of the given bind.
int | gprs_ns2_ip_bind_set_priority (struct gprs_ns2_vc_bind *bind, uint8_t priority)
| Set the socket priority of the given bind.
int | ns2_ip_count_bind (struct gprs_ns2_inst *nsi, struct osmo_sockaddr *remote)
| Count UDP binds compatible with remote.
struct gprs_ns2_vc_bind * | ns2_ip_get_bind_by_index (struct gprs_ns2_inst *nsi, struct osmo_sockaddr *remote, int index)
void | ns2_ip_set_txqueue_max_length (struct gprs_ns2_vc_bind *bind, unsigned int max_length)
void | gprs_ns2_ip_bind_set_sns_weight (struct gprs_ns2_vc_bind *bind, uint8_t signalling, uint8_t data)
| set the signalling and data weight for this bind

## Variables

struct gprs_ns2_vc_driver | vc_driver_ip

## Detailed Description

NS-over-UDP implementation.

GPRS Networks Service (NS) messages on the Gb interface. 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05) as well as its successor 3GPP TS 48.016

## Function Documentation

## dump_vty()

static void dump_vty | ( | const struct gprs_ns2_vc_bind * | bind,
|  | struct vty * | vty,
|  | bool | stats
| ) |  |

static

References priv_bind::addr, priv_bind::dscp, osmo_sockaddr_str::ip, llist_for_each_entry, ns2_vty_dump_nsvc(), gprs_ns2_vc_bind::nsvc, osmo_sockaddr_str_from_sockaddr(), osmo_sockaddr_str::port, priv_bind::priority, gprs_ns2_vc_bind::priv, osmo_sockaddr::sas, gprs_ns2_vc_bind::sns_data_weight, gprs_ns2_vc_bind::sns_sig_weight, osmo_sockaddr::u, VTY_NEWLINE, and vty_out().

Referenced by gprs_ns2_ip_bind().

## free_bind()

static void free_bind | ( | struct gprs_ns2_vc_bind * | bind | ) |

static

clean up all private driver state.

Should be only called by gprs_ns2_free_bind()

References gprs_ns2_is_ip_bind(), priv_bind::iofd, OSMO_ASSERT, osmo_iofd_free(), and gprs_ns2_vc_bind::priv.

## free_vc()

static void free_vc | ( | struct gprs_ns2_vc * | nsvc | ) |

static

References gprs_ns2_vc::bind, gprs_ns2_is_ip_bind(), OSMO_ASSERT, and gprs_ns2_vc::priv.

Referenced by gprs_ns2_ip_bind().

## gprs_ns2_ip_bind()

int gprs_ns2_ip_bind | ( | struct gprs_ns2_inst * | nsi,
|  | const char * | name,
|  | const struct osmo_sockaddr * | local,
|  | int | dscp,
|  | struct gprs_ns2_vc_bind ** | result
| ) |  |

Bind to an IPv4/IPv6 address.

Parameters

  [in] | nsi | NS Instance in which to create the NSVC
  [in] | local | the local address to bind to
  [in] | dscp | the DSCP/TOS bits used for transmitted data
  [out] | result | pointer to the created bind or if a bind with the name exists return the bind.

Returns
  0 on success; negative on error. -EALREADY returned in case a bind with the name exists

References priv_bind::addr, gprs_ns2_vc_bind::driver, priv_bind::dscp, dump_vty(), gprs_ns2_vc_bind::dump_vty, free_vc(), gprs_ns2_vc_bind::free_vc, gprs_ns2_free_bind(), gprs_ns2_ip_bind_by_sockaddr(), GPRS_NS2_LL_UDP, handle_nsip_recvfrom(), handle_nsip_sendto(), priv_bind::iofd, gprs_ns2_vc_bind::ll, gprs_ns2_vc_bind::mtu, name, ns2_bind_alloc(), nsip_vc_sendmsg(), OSMO_IO_FD_MODE_RECVFROM_SENDTO, osmo_iofd_register(), osmo_iofd_set_alloc_info(), osmo_iofd_set_txqueue_max_length(), osmo_iofd_setup(), OSMO_SOCK_F_BIND, OSMO_SOCK_F_DSCP, osmo_sock_init_osa(), gprs_ns2_vc_bind::priv, osmo_sockaddr::sa, gprs_ns2_vc_bind::send_vc, osmo_io_ops::sendto_cb, gprs_ns2_vc_bind::transfer_capability, gprs_ns2_inst::txqueue_max_length, osmo_sockaddr::u, and vc_driver_ip.

Referenced by DEFUN().

## gprs_ns2_ip_bind_by_sockaddr()

struct gprs_ns2_vc_bind * gprs_ns2_ip_bind_by_sockaddr | ( | struct gprs_ns2_inst * | nsi,
|  | const struct osmo_sockaddr * | sockaddr
| ) |  |

Find NS bind for a given socket address.

Parameters

  [in] | nsi | NS instance
  [in] | sockaddr | socket address to search for

Returns

References gprs_ns2_inst::binding, gprs_ns2_ip_bind_sockaddr(), gprs_ns2_is_ip_bind(), llist_for_each_entry, OSMO_ASSERT, and osmo_sockaddr_cmp().

Referenced by DEFUN(), and gprs_ns2_ip_bind().

## gprs_ns2_ip_bind_set_dscp()

int gprs_ns2_ip_bind_set_dscp | ( | struct gprs_ns2_vc_bind * | bind,
|  | int | dscp
| ) |  |

Set the DSCP (TOS) bit value of the given bind.

References priv_bind::dscp, gprs_ns2_is_ip_bind(), priv_bind::iofd, LOGBIND, LOGL_ERROR, OSMO_ASSERT, osmo_iofd_get_fd(), osmo_sock_set_dscp(), and gprs_ns2_vc_bind::priv.

Referenced by DEFUN(), and DEFUN().

## gprs_ns2_ip_bind_set_priority()

int gprs_ns2_ip_bind_set_priority | ( | struct gprs_ns2_vc_bind * | bind,
|  | uint8_t | priority
| ) |  |

Set the socket priority of the given bind.

References gprs_ns2_is_ip_bind(), priv_bind::iofd, LOGBIND, LOGL_ERROR, OSMO_ASSERT, osmo_iofd_get_fd(), osmo_sock_set_priority(), priv_bind::priority, and gprs_ns2_vc_bind::priv.

Referenced by DEFUN().

## gprs_ns2_ip_bind_set_sns_weight()

void gprs_ns2_ip_bind_set_sns_weight | ( | struct gprs_ns2_vc_bind * | bind,
|  | uint8_t | signalling,
|  | uint8_t | data
| ) |  |

set the signalling and data weight for this bind

Parameters

  [in] | bind |
  [in] | signalling | the signalling weight
  [in] | data | the data weight

References data, gprs_ns2_is_ip_bind(), ns2_sns_update_weights(), OSMO_ASSERT, gprs_ns2_vc_bind::sns_data_weight, and gprs_ns2_vc_bind::sns_sig_weight.

Referenced by DEFUN().

## gprs_ns2_ip_bind_sockaddr()

const struct osmo_sockaddr * gprs_ns2_ip_bind_sockaddr | ( | struct gprs_ns2_vc_bind * | bind | ) |

Return the locally bound socket address of the bind.

Parameters

  [in] | bind | The bind whose local address we want to know

Returns
  address of the local bind

References priv_bind::addr, gprs_ns2_is_ip_bind(), OSMO_ASSERT, and gprs_ns2_vc_bind::priv.

Referenced by config_write_vbind(), gprs_ns2_ip_bind_by_sockaddr(), gprs_ns2_ll_str_buf(), ns2_add_procedure(), ns2_create_vc(), ns2_get_sbind_ip4_entry(), ns2_get_sbind_ip6_entry(), ns2_ip_bind_connect(), ns2_ip_count_bind(), ns2_ip_get_bind_by_index(), ns2_sns_add_elements(), ns2_sns_bss_valid_configuration(), ns2_sns_compute_local_ep_from_binds(), ns2_sns_count_num_local_ep(), ns2_sns_update_weights(), and remove_bind_elem().

## gprs_ns2_ip_vc_equal()

bool gprs_ns2_ip_vc_equal | ( | const struct gprs_ns2_vc * | nsvc,
|  | const struct osmo_sockaddr * | local,
|  | const struct osmo_sockaddr * | remote,
|  | uint16_t | nsvci
| ) |  |

Compare the NS-VC with the given parameter.

Parameters

  [in] | nsvc | NS-VC to compare with
  [in] | local | The local address
  [in] | remote | The remote address
  [in] | nsvci | NS-VCI will only be used if the NS-VC in BLOCKRESET mode otherwise NS-VCI isn't applicable.

Returns
  true if the NS-VC has the same properties as given

References priv_bind::addr, gprs_ns2_vc::bind, gprs_ns2_vc_bind::driver, GPRS_NS2_VC_MODE_BLOCKRESET, gprs_ns2_vc::mode, gprs_ns2_vc::nsvci, osmo_sockaddr_cmp(), gprs_ns2_vc::priv, gprs_ns2_vc_bind::priv, priv_vc::remote, and vc_driver_ip.

## gprs_ns2_ip_vc_local()

const struct osmo_sockaddr * gprs_ns2_ip_vc_local | ( | const struct gprs_ns2_vc * | nsvc | ) |

Return the socket address of the local peer of a NS-VC.

Parameters

  [in] | nsvc | NS-VC whose local peer we want to know

Returns
  address of the local peer; NULL in case of error

References priv_bind::addr, gprs_ns2_vc::bind, gprs_ns2_vc_bind::driver, gprs_ns2_vc_bind::priv, and vc_driver_ip.

## gprs_ns2_ip_vc_remote()

const struct osmo_sockaddr * gprs_ns2_ip_vc_remote | ( | const struct gprs_ns2_vc * | nsvc | ) |

Return the socket address of the remote peer of a NS-VC.

Parameters

  [in] | nsvc | NS-VC whose remote peer we want to know

Returns
  address of the remote peer; NULL in case of error

References gprs_ns2_vc::bind, gprs_ns2_vc_bind::driver, gprs_ns2_vc::priv, priv_vc::remote, and vc_driver_ip.

Referenced by config_write_nsvc(), do_sns_change_weight(), do_sns_delete(), gprs_ns2_ll_str_buf(), gprs_ns2_nsvc_by_sockaddr_nse(), ns2_sns_compute_local_ep_from_binds(), and nsvc_for_bind_and_remote().

## gprs_ns2_is_ip_bind()

int gprs_ns2_is_ip_bind | ( | struct gprs_ns2_vc_bind * | bind | ) |

Is the given bind an IP bind?

References gprs_ns2_vc_bind::driver, and vc_driver_ip.

Referenced by DEFUN(), free_bind(), free_vc(), gprs_ns2_free_bind(), gprs_ns2_ip_bind_by_sockaddr(), gprs_ns2_ip_bind_set_dscp(), gprs_ns2_ip_bind_set_priority(), gprs_ns2_ip_bind_set_sns_weight(), gprs_ns2_ip_bind_sockaddr(), gprs_ns2_ll_str_buf(), gprs_ns2_nsvc_by_sockaddr_bind(), gprs_ns2_sns_add_bind(), ns2_ip_bind_connect(), ns2_ip_count_bind(), ns2_ip_get_bind_by_index(), and ns2_ip_set_txqueue_max_length().

## gprs_ns2_nsvc_by_sockaddr_bind()

struct gprs_ns2_vc * gprs_ns2_nsvc_by_sockaddr_bind | ( | struct gprs_ns2_vc_bind * | bind,
|  | const struct osmo_sockaddr * | rem_addr
| ) |  |

Find a NS-VC by its remote socket address.

Parameters

  [in] | bind | in which to search
  [in] | rem_addr | remote peer socket address to search

Returns
  NS-VC matching sockaddr; NULL if none found

References gprs_ns2_is_ip_bind(), llist_for_each_entry, gprs_ns2_vc_bind::nsvc, OSMO_ASSERT, osmo_sockaddr_cmp(), gprs_ns2_vc::priv, priv_vc::remote, osmo_sockaddr::sa, and osmo_sockaddr::u.

Referenced by DEFUN(), DEFUN(), handle_nsip_recvfrom(), handle_nsip_sendto(), ns2_create_vc_sns(), ns2_ip_bind_connect(), and ns_nse_nsvc_udp_cmds().

## handle_nsip_recvfrom()

static void handle_nsip_recvfrom | ( | struct osmo_io_fd * | iofd,
|  | int | error,
|  | struct msgb * | msg,
|  | const struct osmo_sockaddr * | saddr
| ) |  |

static

References gprs_ns2_nse::dialect, GPRS_NS2_DIALECT_SNS, gprs_ns2_nsvc_by_sockaddr_bind(), msg, msgb_data(), msgb_free(), ns2_create_vc(), NS2_CS_CREATED, NS2_CS_ERROR, NS2_CS_FOUND, NS2_CS_REJECTED, NS2_CS_SKIPPED, ns2_driver_alloc_vc(), ns2_recv_vc(), ns2_vc_fsm_start(), gprs_ns2_vc::nse, nsip_sendmsg(), and osmo_iofd_get_data().

Referenced by gprs_ns2_ip_bind().

## handle_nsip_sendto()

static void handle_nsip_sendto | ( | struct osmo_io_fd * | iofd,
|  | int | res,
|  | struct msgb * | msg,
|  | const struct osmo_sockaddr * | daddr
| ) |  |

static

References gprs_ns2_vc::bind, gprs_ns2_nsvc_by_sockaddr_bind(), msg, msgb_length(), NS_CTR_BYTES_OUT, NS_CTR_BYTES_OUT_DROP, NS_CTR_PKTS_OUT, NS_CTR_PKTS_OUT_DROP, osmo_iofd_get_data(), OSMO_LIKELY, RATE_CTR_ADD_NS, RATE_CTR_INC_NS, and res.

Referenced by gprs_ns2_ip_bind().

## ns2_driver_alloc_vc()

static struct priv_vc * ns2_driver_alloc_vc | ( | struct gprs_ns2_vc_bind * | bind,
|  | struct gprs_ns2_vc * | nsvc,
|  | const struct osmo_sockaddr * | remote
| ) |  |

static

References gprs_ns2_vc::priv, and priv_vc::remote.

Referenced by handle_nsip_recvfrom().

## ns2_ip_bind_connect()

struct gprs_ns2_vc * ns2_ip_bind_connect | ( | struct gprs_ns2_vc_bind * | bind,
|  | struct gprs_ns2_nse * | nse,
|  | const struct osmo_sockaddr * | remote
| ) |  |

Create new NS-VC to a given remote address.

Parameters

  [in] | bind | the bind we want to connect
  [in] | nse | NS entity to be used for the new NS-VC
  [in] | remote | remote address to connect to

Returns
  pointer to newly-allocated and connected NS-VC; NULL on error

References gprs_ns2_nse::dialect, gprs_ns2_free_nsvc(), gprs_ns2_ip_bind_sockaddr(), gprs_ns2_is_ip_bind(), gprs_ns2_lltype_str(), gprs_ns2_nsvc_by_sockaddr_bind(), gprs_ns2_nse::ll, LOGL_ERROR, LOGNSE, ns2_dialect_to_vc_mode(), ns2_vc_alloc(), gprs_ns2_nse::nsei, OSMO_ASSERT, osmo_identifier_sanitize_buf(), osmo_sockaddr_to_str(), osmo_sockaddr_to_str_buf(), gprs_ns2_vc::priv, and priv_vc::remote.

Referenced by gprs_ns2_ip_connect_inactive(), ns2_create_vc_sns(), and ns2_sns_st_bss_size_onenter().

## ns2_ip_count_bind()

int ns2_ip_count_bind | ( | struct gprs_ns2_inst * | nsi,
|  | struct osmo_sockaddr * | remote
| ) |  |

Count UDP binds compatible with remote.

References gprs_ns2_inst::binding, gprs_ns2_ip_bind_sockaddr(), gprs_ns2_is_ip_bind(), llist_for_each_entry, osmo_sockaddr::sa, and osmo_sockaddr::u.

## ns2_ip_get_bind_by_index()

struct gprs_ns2_vc_bind * ns2_ip_get_bind_by_index | ( | struct gprs_ns2_inst * | nsi,
|  | struct osmo_sockaddr * | remote,
|  | int | index
| ) |  |

References gprs_ns2_inst::binding, gprs_ns2_ip_bind_sockaddr(), gprs_ns2_is_ip_bind(), llist_for_each_entry, osmo_sockaddr::sa, and osmo_sockaddr::u.

## ns2_ip_set_txqueue_max_length()

void ns2_ip_set_txqueue_max_length | ( | struct gprs_ns2_vc_bind * | bind,
|  | unsigned int | max_length
| ) |  |

References gprs_ns2_is_ip_bind(), priv_bind::iofd, OSMO_ASSERT, osmo_iofd_set_txqueue_max_length(), and gprs_ns2_vc_bind::priv.

Referenced by DEFUN().

## nsip_sendmsg()

static int nsip_sendmsg | ( | struct gprs_ns2_vc_bind * | bind,
|  | struct msgb * | msg,
|  | const struct osmo_sockaddr * | dest
| ) |  |

inline static

References priv_bind::iofd, msg, osmo_iofd_sendto_msgb(), and gprs_ns2_vc_bind::priv.

Referenced by handle_nsip_recvfrom(), and nsip_vc_sendmsg().

## nsip_vc_sendmsg()

static int nsip_vc_sendmsg | ( | struct gprs_ns2_vc * | nsvc,
|  | struct msgb * | msg
| ) |  |

static

send the msg and free it afterwards.

Parameters

  nsvc | NS-VC on which the message shall be sent
  msg | message to be sent

Returns
  number of bytes transmitted; negative on error

References msg, nsip_sendmsg(), gprs_ns2_vc_bind::nsvc, gprs_ns2_vc::priv, and priv_vc::remote.

Referenced by gprs_ns2_ip_bind().

## Variable Documentation

## vc_driver_ip

struct gprs_ns2_vc_driver vc_driver_ip

Initial value:
= {
.name = "GB UDP IPv4/IPv6",
.free_bind = free_bind,
}
free_bind
static void free_bind(struct gprs_ns2_vc_bind *bind)
clean up all private driver state.
Definition gprs_ns2_udp.c:61

Referenced by gprs_ns2_ip_bind(), gprs_ns2_ip_vc_equal(), gprs_ns2_ip_vc_local(), gprs_ns2_ip_vc_remote(), and gprs_ns2_is_ip_bind().