Adding the ability to set the interface local link IPv6 address.
This commit is contained in:
parent
25108e2e2b
commit
ac1c300126
|
@ -105,6 +105,7 @@ class gw_interface_nas
|
|||
{
|
||||
public:
|
||||
virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0;
|
||||
virtual srslte::error_t setup_if_addr6(uint8_t *ipv6_if_id, char *err_str) = 0;
|
||||
};
|
||||
|
||||
// GW interface for RRC
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
// NAS interface
|
||||
srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str);
|
||||
srslte::error_t setup_if_addr6(uint8_t *ipv6_if_id, char *err_str);
|
||||
|
||||
// RRC interface
|
||||
void add_mch_port(uint32_t lcid, uint32_t port);
|
||||
|
@ -88,6 +89,7 @@ private:
|
|||
bool if_up;
|
||||
|
||||
uint32_t current_ip_addr;
|
||||
uint8_t current_if_id[8];
|
||||
|
||||
long ul_tput_bytes;
|
||||
long dl_tput_bytes;
|
||||
|
|
|
@ -134,6 +134,7 @@ private:
|
|||
bool auth_request;
|
||||
|
||||
uint32_t ip_addr;
|
||||
uint8_t ipv6_if_id[8];
|
||||
uint8_t eps_bearer_id;
|
||||
|
||||
uint8_t chap_id;
|
||||
|
|
|
@ -86,7 +86,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
|
|||
("rrc.ue_category", bpo::value<string>(&args->ue_category_str)->default_value("4"), "UE Category (1 to 5)")
|
||||
|
||||
("nas.apn", bpo::value<string>(&args->nas.apn_name)->default_value(""), "Set Access Point Name (APN) for data services")
|
||||
("nas.apn_protocol", bpo::value<string>(&args->nas.apn_protocol)->default_value("ipv4"), "Set Access Point Name (APN) protocol for data services")
|
||||
("nas.apn_protocol", bpo::value<string>(&args->nas.apn_protocol)->default_value(""), "Set Access Point Name (APN) protocol for data services")
|
||||
("nas.user", bpo::value<string>(&args->nas.apn_user)->default_value(""), "Username for CHAP authentication")
|
||||
("nas.pass", bpo::value<string>(&args->nas.apn_pass)->default_value(""), "Password for CHAP authentication")
|
||||
("nas.force_imsi_attach", bpo::value<bool>(&args->nas.force_imsi_attach)->default_value(false), "Whether to always perform an IMSI attach")
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct in6_ifreq {
|
||||
struct in6_addr ifr6_addr;
|
||||
__u32 ifr6_prefixlen;
|
||||
unsigned int ifr6_ifindex;
|
||||
};
|
||||
|
||||
namespace srsue {
|
||||
|
||||
|
@ -165,29 +170,14 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu)
|
|||
struct in_addr dst_addr;
|
||||
memcpy(&dst_addr.s_addr, &pdu->msg[16],4);
|
||||
|
||||
if(!if_up)
|
||||
{
|
||||
if (!if_up) {
|
||||
gw_log->warning("TUN/TAP not up - dropping gw RX message\n");
|
||||
}else{
|
||||
} else {
|
||||
int n = write(tun_fd, pdu->msg, pdu->N_bytes);
|
||||
if(n > 0 && (pdu->N_bytes != (uint32_t)n))
|
||||
{
|
||||
if(n > 0 && (pdu->N_bytes != (uint32_t) n) ) {
|
||||
gw_log->warning("DL TUN/TAP write failure\n");
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Strip IP/UDP header
|
||||
pdu->msg += 28;
|
||||
pdu->N_bytes -= 28;
|
||||
|
||||
if(mbsfn_sock_fd) {
|
||||
if(lcid > 0 && lcid < SRSLTE_N_MCH_LCIDS) {
|
||||
mbsfn_sock_addr.sin_port = htons(mbsfn_ports[lcid]);
|
||||
if(sendto(mbsfn_sock_fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&mbsfn_sock_addr, sizeof(struct sockaddr_in))<0) {
|
||||
gw_log->error("Failed to send MCH PDU to port %d\n", mbsfn_ports[lcid]);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
pool->deallocate(pdu);
|
||||
}
|
||||
|
@ -241,6 +231,63 @@ srslte::error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
|||
return(srslte::ERROR_NONE);
|
||||
}
|
||||
|
||||
srslte::error_t gw::setup_if_addr6(uint8_t *ipv6_if_id, char *err_str)
|
||||
{
|
||||
struct sockaddr_in6 sai;
|
||||
struct in6_ifreq ifr6;
|
||||
bool match = true;
|
||||
|
||||
for (int i=0; i<8; i++){
|
||||
if(ipv6_if_id[i] != current_if_id[i]){
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
if (!if_up) {
|
||||
if( init_if(err_str) ) {
|
||||
gw_log->error("init_if failed\n");
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the IP address
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
ifr.ifr_addr.sa_family = AF_INET6;
|
||||
|
||||
if(inet_pton(AF_INET6, "fe80::", (void *)&sai.sin6_addr) <= 0) {
|
||||
gw_log->error("Bad address\n");
|
||||
return srslte::ERROR_CANT_START;
|
||||
}
|
||||
|
||||
memcpy(&sai.sin6_addr.s6_addr[8], ipv6_if_id, 8);
|
||||
if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
|
||||
perror("SIOGIFINDEX");
|
||||
return srslte::ERROR_CANT_START;
|
||||
}
|
||||
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
|
||||
ifr6.ifr6_prefixlen = 64;
|
||||
memcpy((char *) &ifr6.ifr6_addr, (char *) &sai.sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
|
||||
if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) {
|
||||
err_str = strerror(errno);
|
||||
gw_log->error("Could not set IPv6 Link local address. Error %s\n", err_str);
|
||||
return srslte::ERROR_CANT_START;
|
||||
}
|
||||
|
||||
for (int i=0; i<8; i++){
|
||||
current_if_id[i] = ipv6_if_id[i];
|
||||
}
|
||||
|
||||
// Setup a thread to receive packets from the TUN device
|
||||
start(GW_THREAD_PRIO);
|
||||
}
|
||||
|
||||
return(srslte::ERROR_NONE);
|
||||
}
|
||||
|
||||
srslte::error_t gw::init_if(char *err_str)
|
||||
{
|
||||
if(if_up)
|
||||
|
|
|
@ -653,6 +653,35 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
if (gw->setup_if_addr(ip_addr, err_str)) {
|
||||
nas_log->error("Failed to set gateway address - %s\n", err_str);
|
||||
}
|
||||
} else if (LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){
|
||||
memcpy(ipv6_if_id, act_def_eps_bearer_context_req.pdn_addr.addr, 8);
|
||||
nas_log->info("Network attach successful. APN: %s, IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
act_def_eps_bearer_context_req.apn.apn,
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[0],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[1],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[2],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[3],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[4],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[5],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[6],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[7]);
|
||||
|
||||
nas_log->console("Network attach successful. IPv6 interface Id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[0],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[1],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[2],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[3],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[4],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[5],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[6],
|
||||
act_def_eps_bearer_context_req.pdn_addr.addr[7]);
|
||||
// Setup GW
|
||||
char *err_str = NULL;
|
||||
if (gw->setup_if_addr6(ipv6_if_id, err_str)) {
|
||||
nas_log->error("Failed to set gateway address - %s\n", err_str);
|
||||
}
|
||||
pool->deallocate(pdu);
|
||||
return;
|
||||
} else {
|
||||
nas_log->error("Not handling IPV6 or IPV4V6\n");
|
||||
pool->deallocate(pdu);
|
||||
|
@ -1128,7 +1157,7 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) {
|
|||
pdn_con_req.apn_present = false;
|
||||
|
||||
//Set PDN protocol type
|
||||
if (cfg.apn_protocol == "ipv4"){
|
||||
if (cfg.apn_protocol == "ipv4" || cfg.apn_protocol == ""){
|
||||
nas_log->console("Setting PDN protocol to IPv4\n");
|
||||
pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4;
|
||||
} else if (cfg.apn_protocol == "ipv6") {
|
||||
|
|
|
@ -127,6 +127,7 @@ private:
|
|||
class gw_dummy : public gw_interface_nas, public gw_interface_pdcp
|
||||
{
|
||||
error_t setup_if_addr(uint32_t ip_addr, char *err_str) { return ERROR_NONE; }
|
||||
error_t setup_if_addr6(uint8_t *ipv6_if_id, char *err_str) { return ERROR_NONE; }
|
||||
void write_pdu(uint32_t lcid, byte_buffer_t *pdu) {}
|
||||
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue