mirror of https://gerrit.osmocom.org/libosmocore
gprs_ns2: fr: setup the device to correct FR/LMI settings
A hdlc can be used in different modes. Also a FR device can be used with lmi and certain settings as without it. ns2 will use FR with no lmi in the kernel. Related: SYS#5169 Change-Id: I04786d2b864860b08c2e1afdb199470f4b80cc3b
This commit is contained in:
parent
60021a46ce
commit
5c96f5dbc6
|
@ -36,12 +36,14 @@
|
|||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/hdlc.h>
|
||||
#include <linux/hdlc/ioctl.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
#include <osmocom/gprs/frame_relay.h>
|
||||
#include <osmocom/core/byteswap.h>
|
||||
|
@ -84,7 +86,7 @@ struct gprs_ns2_vc_driver vc_driver_fr = {
|
|||
};
|
||||
|
||||
struct priv_bind {
|
||||
char netif[IF_NAMESIZE];
|
||||
char netif[IFNAMSIZ];
|
||||
struct osmo_fr_link *link;
|
||||
struct osmo_wqueue wqueue;
|
||||
int ifindex;
|
||||
|
@ -433,6 +435,103 @@ static void linkmon_initial_dump(struct osmo_mnl *omnl)
|
|||
}
|
||||
#endif /* LIBMNL */
|
||||
|
||||
static int set_ifupdown(const char *netif, bool up)
|
||||
{
|
||||
int sock, rc;
|
||||
struct ifreq req;
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
return sock;
|
||||
|
||||
memset(&req, 0, sizeof req);
|
||||
strncpy(req.ifr_name, netif, IFNAMSIZ);
|
||||
|
||||
if (up)
|
||||
req.ifr_flags |= IFF_UP;
|
||||
|
||||
rc = ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
close(sock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int setup_device(const char *netif)
|
||||
{
|
||||
int sock, rc;
|
||||
char buffer[128];
|
||||
fr_proto *fr = (void*)buffer;
|
||||
struct ifreq req;
|
||||
|
||||
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (sock < 0) {
|
||||
LOGP(DLNS, LOGL_ERROR, "%s: Unable to create socket: %s\n",
|
||||
netif, strerror(errno));
|
||||
return sock;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(struct ifreq));
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
osmo_strlcpy(req.ifr_name, netif, IFNAMSIZ);
|
||||
req.ifr_settings.ifs_ifsu.sync = (void*)buffer;
|
||||
req.ifr_settings.size = sizeof(buffer);
|
||||
req.ifr_settings.type = IF_GET_PROTO;
|
||||
|
||||
rc = ioctl(sock, SIOCWANDEV, &req);
|
||||
if (rc < 0) {
|
||||
LOGP(DLNS, LOGL_ERROR, "%s: Unable to get FR protocol information: %s\n",
|
||||
netif, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check if the device is good */
|
||||
if (req.ifr_settings.type != IF_PROTO_FR && fr->lmi != LMI_NONE) {
|
||||
LOGP(DLNS, LOGL_INFO, "%s: has correct frame relay mode and lmi\n", netif);
|
||||
goto ifup;
|
||||
}
|
||||
|
||||
/* modify the device to match */
|
||||
rc = set_ifupdown(netif, false);
|
||||
if (rc) {
|
||||
LOGP(DLNS, LOGL_ERROR, "Unable to bring up the device %s: %s\n",
|
||||
netif, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(struct ifreq));
|
||||
memset(fr, 0, sizeof(fr_proto));
|
||||
osmo_strlcpy(req.ifr_name, netif, IFNAMSIZ);
|
||||
req.ifr_settings.type = IF_PROTO_FR;
|
||||
req.ifr_settings.size = sizeof(fr_proto);
|
||||
req.ifr_settings.ifs_ifsu.fr = fr;
|
||||
fr->lmi = LMI_NONE;
|
||||
/* even those settings aren't used, they must be in the range */
|
||||
/* polling verification timer*/
|
||||
fr->t391 = 10;
|
||||
/* link integrity verification polling timer */
|
||||
fr->t392 = 15;
|
||||
/* full status polling counter*/
|
||||
fr->n391 = 6;
|
||||
/* error threshold */
|
||||
fr->n392 = 3;
|
||||
/* monitored events count */
|
||||
fr->n393 = 4;
|
||||
|
||||
rc = ioctl(sock, SIOCWANDEV, &req);
|
||||
if (rc) {
|
||||
LOGP(DLNS, LOGL_ERROR, "%s: Unable to set FR protocol on information: %s\n",
|
||||
netif, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
ifup:
|
||||
rc = set_ifupdown(netif, true);
|
||||
if (rc)
|
||||
LOGP(DLNS, LOGL_ERROR, "Unable to bring up the device %s: %s\n",
|
||||
netif, strerror(errno));
|
||||
err:
|
||||
close(sock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! Create a new bind for NS over FR.
|
||||
* \param[in] nsi NS instance in which to create the bind
|
||||
|
@ -481,7 +580,7 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
|
|||
goto err_name;
|
||||
}
|
||||
|
||||
if (strlen(netif) > IF_NAMESIZE) {
|
||||
if (strlen(netif) > IFNAMSIZ) {
|
||||
rc = -EINVAL;
|
||||
goto err_priv;
|
||||
}
|
||||
|
@ -507,6 +606,13 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
|
|||
goto err_fr;
|
||||
}
|
||||
|
||||
/* set protocol frame relay and lmi */
|
||||
rc = setup_device(priv->netif);
|
||||
if(rc < 0) {
|
||||
LOGP(DLNS, LOGL_ERROR, "Failed to setup the interface %s for frame relay and lmi\n", netif);
|
||||
goto err_fr;
|
||||
}
|
||||
|
||||
rc = open_socket(priv->ifindex);
|
||||
if (rc < 0)
|
||||
goto err_fr;
|
||||
|
@ -597,7 +703,7 @@ struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
|
|||
continue;
|
||||
|
||||
_netif = gprs_ns2_fr_bind_netif(bind);
|
||||
if (!strncmp(_netif, netif, IF_NAMESIZE))
|
||||
if (!strncmp(_netif, netif, IFNAMSIZ))
|
||||
return bind;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue