diff options
author | Alexander Couzens <lynxis@fe80.eu> | 2020-11-19 00:41:29 +0100 |
---|---|---|
committer | Alexander Couzens <lynxis@fe80.eu> | 2020-11-24 03:53:22 +0100 |
commit | 841817ec52186029ca01f0c082ed84f2dc5ffcc5 (patch) | |
tree | 19aba9c6d3dd9f5b6e9bac61d10aaaef307deb20 /src/gb/gprs_ns2_vty.c | |
parent | 595908aab1985f987abac9c1706bf284468665f7 (diff) |
ns2: add support for frame relay
Add support for frame relay over dahdi hdlc device.
It's supporting lmi by q933 and supports both
SGSN and BSS.
Change-Id: Id3b49f93d33c271f77cd9c9db03cde6b727a4d30
Diffstat (limited to 'src/gb/gprs_ns2_vty.c')
-rw-r--r-- | src/gb/gprs_ns2_vty.c | 137 |
1 files changed, 117 insertions, 20 deletions
diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c index 63331b95..4eb9d37a 100644 --- a/src/gb/gprs_ns2_vty.c +++ b/src/gb/gprs_ns2_vty.c @@ -31,6 +31,7 @@ #include <stdint.h> #include <arpa/inet.h> +#include <net/if.h> #include <osmocom/core/msgb.h> #include <osmocom/core/byteswap.h> @@ -42,6 +43,7 @@ #include <osmocom/core/sockaddr_str.h> #include <osmocom/core/linuxlist.h> #include <osmocom/core/socket.h> +#include <osmocom/gprs/frame_relay.h> #include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gsm/tlv.h> #include <osmocom/vty/vty.h> @@ -78,12 +80,19 @@ struct ns2_vty_vc { uint16_t nsvci; uint16_t frdlci; + struct { + enum osmo_fr_role role; + } fr; + + char netif[IF_NAMESIZE]; + bool remote_end_is_sgsn; bool configured; }; static struct gprs_ns2_inst *vty_nsi = NULL; static struct ns2_vty_priv priv; +static struct osmo_fr_network *vty_fr_network = NULL; /* FIXME: this should go to some common file as it is copied * in vty_interface.c of the BSC */ @@ -223,6 +232,11 @@ static int config_write_ns(struct vty *vty) vtyvc->nsei, vtyvc->frdlci, VTY_NEWLINE); break; + case GPRS_NS_LL_FR: + vty_out(vty, " nse %u fr %s dlci %u%s", + vtyvc->nsei, vtyvc->netif, vtyvc->frdlci, + VTY_NEWLINE); + break; default: break; } @@ -387,6 +401,44 @@ DEFUN_HIDDEN(nsvc_force_unconf, nsvc_force_unconf_cmd, #define NSE_CMD_STR "Persistent NS Entity\n" "NS Entity ID (NSEI)\n" +DEFUN(cfg_nse_fr, cfg_nse_fr_cmd, + "nse <0-65535> nsvci <0-65535> (fr|frnet) NETIF dlci <0-1023>", + NSE_CMD_STR + "NS Virtual Connection\n" + "NS Virtual Connection ID (NSVCI)\n" + "frame relay\n" + IFNAME_STR + "Data Link connection identifier\n" + "Data Link connection identifier\n" + ) +{ + struct ns2_vty_vc *vtyvc; + + uint16_t nsei = atoi(argv[0]); + uint16_t nsvci = atoi(argv[1]); + const char *role = argv[2]; + const char *name = argv[3]; + uint16_t dlci = atoi(argv[4]); + + vtyvc = vtyvc_by_nsei(nsei, true); + if (!vtyvc) { + vty_out(vty, "Can not allocate space %s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (!strcmp(role, "fr")) + vtyvc->fr.role = FR_ROLE_USER_EQUIPMENT; + else if (!strcmp(role, "frnet")) + vtyvc->fr.role = FR_ROLE_NETWORK_EQUIPMENT; + + osmo_strlcpy(vtyvc->netif, name, sizeof(vtyvc->netif)); + vtyvc->frdlci = dlci; + vtyvc->nsvci = nsvci; + vtyvc->ll = GPRS_NS_LL_FR; + + return CMD_SUCCESS; +} + DEFUN(cfg_nse_nsvc, cfg_nse_nsvci_cmd, "nse <0-65535> nsvci <0-65535>", NSE_CMD_STR @@ -453,13 +505,14 @@ DEFUN(cfg_nse_remoteport, cfg_nse_remoteport_cmd, } DEFUN(cfg_nse_fr_dlci, cfg_nse_fr_dlci_cmd, - "nse <0-65535> fr-dlci <16-1007>", + "nse <0-65535> nsvci <0-65535> fr-dlci <16-1007>", NSE_CMD_STR "Frame Relay DLCI\n" "Frame Relay DLCI Number\n") { uint16_t nsei = atoi(argv[0]); - uint16_t dlci = atoi(argv[1]); + uint16_t nsvci = atoi(argv[1]); + uint16_t dlci = atoi(argv[2]); struct ns2_vty_vc *vtyvc; vtyvc = vtyvc_by_nsei(nsei, true); @@ -474,6 +527,7 @@ DEFUN(cfg_nse_fr_dlci, cfg_nse_fr_dlci_cmd, } vtyvc->frdlci = dlci; + vtyvc->nsvci = nsvci; return CMD_SUCCESS; } @@ -736,6 +790,7 @@ int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi, install_lib_element(CONFIG_NODE, &cfg_ns_cmd); install_node(&ns_node, config_write_ns); + install_lib_element(L_NS_NODE, &cfg_nse_fr_cmd); install_lib_element(L_NS_NODE, &cfg_nse_nsvci_cmd); install_lib_element(L_NS_NODE, &cfg_nse_remoteip_cmd); install_lib_element(L_NS_NODE, &cfg_nse_remoteport_cmd); @@ -763,10 +818,11 @@ int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi, */ int gprs_ns2_vty_create() { struct ns2_vty_vc *vtyvc; - struct gprs_ns2_vc_bind *bind; + struct gprs_ns2_vc_bind *bind, *fr; struct gprs_ns2_nse *nse; struct gprs_ns2_vc *nsvc; struct osmo_sockaddr sockaddr; + int rc = 0; if (!vty_nsi) return -1; @@ -787,18 +843,28 @@ int gprs_ns2_vty_create() { /* create vcs */ llist_for_each_entry(vtyvc, &priv.vtyvc, list) { - if (strlen(vtyvc->remote.ip) == 0) { - /* Invalid IP for VC */ - continue; - } + /* validate settings */ + switch (vtyvc->ll) { + case GPRS_NS_LL_UDP: + if (strlen(vtyvc->remote.ip) == 0) { + /* Invalid IP for VC */ + continue; + } - if (!vtyvc->remote.port) { - /* Invalid port for VC */ - continue; - } + if (!vtyvc->remote.port) { + /* Invalid port for VC */ + continue; + } - if (osmo_sockaddr_str_to_sockaddr(&vtyvc->remote, &sockaddr.u.sas)) { - /* Invalid sockaddr for VC */ + if (osmo_sockaddr_str_to_sockaddr(&vtyvc->remote, &sockaddr.u.sas)) { + /* Invalid sockaddr for VC */ + continue; + } + break; + case GPRS_NS_LL_FR: + break; + case GPRS_NS_LL_FR_GRE: + case GPRS_NS_LL_E1: continue; } @@ -812,15 +878,46 @@ int gprs_ns2_vty_create() { } nse->persistent = true; - nsvc = gprs_ns2_ip_connect(bind, - &sockaddr, - nse, - vtyvc->nsvci); - if (!nsvc) { - /* Could not create NSVC, connect failed */ + switch (vtyvc->ll) { + case GPRS_NS_LL_UDP: + nsvc = gprs_ns2_ip_connect(bind, + &sockaddr, + nse, + vtyvc->nsvci); + if (!nsvc) { + /* Could not create NSVC, connect failed */ + continue; + } + nsvc->persistent = true; + break; + case GPRS_NS_LL_FR: { + if (vty_fr_network == NULL) { + /* TODO: add a switch for BSS/SGSN/gbproxy */ + vty_fr_network = osmo_fr_network_alloc(vty_nsi); + } + fr = gprs_ns2_fr_bind_by_netif( + vty_nsi, + vtyvc->netif); + if (!fr) { + rc = gprs_ns2_fr_bind(vty_nsi, vtyvc->netif, vty_fr_network, vtyvc->fr.role, &fr); + if (rc < 0) { + LOGP(DLNS, LOGL_ERROR, "Can not create fr bind on device %s err: %d\n", vtyvc->netif, rc); + return rc; + } + } + + nsvc = gprs_ns2_fr_connect(fr, vtyvc->nsei, vtyvc->nsvci, vtyvc->frdlci); + if (!nsvc) { + /* Could not create NSVC, connect failed */ + continue; + } + nsvc->persistent = true; + break; + } + case GPRS_NS_LL_FR_GRE: + case GPRS_NS_LL_E1: continue; } - nsvc->persistent = true; } |