Added intial support for IPv4v6. Ping and ping6 seem to work (simultaneously).

master
Pedro Alvarez 6 years ago committed by Andre Puschmann
parent 685898b323
commit 6b5aec5735

@ -335,6 +335,9 @@ srslte::error_t gw::init_if(char *err_str)
char addr_str[INET6_ADDRSTRLEN];
if(find_ipv6_addr(&in6p)){
gw_log->debug("Found link-local IPv6 address: %s\n",inet_ntop(AF_INET6, &in6p, addr_str,INET6_ADDRSTRLEN) );
del_ipv6_addr(&in6p);
} else {
gw_log->warning("Could not find link-local IPv6 address.\n");
}
if_up = true;
@ -562,5 +565,59 @@ out:
return true;
}
void gw::del_ipv6_addr(struct in6_addr *in6p) {}
void gw::del_ipv6_addr(struct in6_addr *in6p)
{
int status, fd =-1;
unsigned int if_index;
struct {
struct nlmsghdr n;
struct ifaddrmsg ifa;
char buf[1024];
} req;
//Get Interface Index
if_index = if_nametoindex(tundevname.c_str());
if(if_index == 0){
gw_log->error("Could not find interface index\n");
goto out;
}
// Open netlink socket
fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if (fd < 0) {
gw_log->error("Error openning NETLINK socket -- %s\n", strerror(errno));
goto out;
}
// We use RTM_DELADDR to delete the ip address from the interface
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
req.n.nlmsg_type = RTM_DELADDR;
req.n.nlmsg_flags = NLM_F_REQUEST;
req.ifa.ifa_family = AF_INET6;
req.ifa.ifa_prefixlen = 64;
req.ifa.ifa_index = if_index; // set the tun_srsue index
req.ifa.ifa_scope = 0;
//Add RT atribute
struct rtattr *rta;
rta = (struct rtattr *)(((char *)&req.n) + NLMSG_ALIGN(req.n.nlmsg_len));
rta->rta_type = IFA_LOCAL;
rta->rta_len = RTA_LENGTH(16);
memcpy(RTA_DATA(rta), in6p, 16);
req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + rta->rta_len;
status = send(fd, &req, req.n.nlmsg_len, 0);
if (status < 0) {
gw_log->error("Error sending NETLINK message\n");
goto out;
}
out:
if (fd<0){
close(fd);
}
return;
}
} // namespace srsue

@ -641,7 +641,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
nas_log->warning("Requested IPv4v6, but only received a single PDN address.\n");
nas_log->warning("EMM Cause: %d\n", attach_accept.emm_cause );
}
if (LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type || LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) {
if (LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) {
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[0] << 24;
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[1] << 16;
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[2] << 8;
@ -665,7 +665,7 @@ 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 || LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){
} 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,
@ -692,6 +692,54 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
if (gw->setup_if_addr6(ipv6_if_id, err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str);
}
} else if (LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){
memcpy(ipv6_if_id, act_def_eps_bearer_context_req.pdn_addr.addr, 8);
//IPv6
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]);
//IPv4
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[8] << 24;
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[9] << 16;
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[10] << 8;
ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[11];
nas_log->info("Network attach successful. APN: %s, IP: %u.%u.%u.%u\n",
act_def_eps_bearer_context_req.apn.apn,
act_def_eps_bearer_context_req.pdn_addr.addr[8],
act_def_eps_bearer_context_req.pdn_addr.addr[9],
act_def_eps_bearer_context_req.pdn_addr.addr[10],
act_def_eps_bearer_context_req.pdn_addr.addr[11]);
nas_log->console("Network attach successful. IP: %u.%u.%u.%u\n",
act_def_eps_bearer_context_req.pdn_addr.addr[8],
act_def_eps_bearer_context_req.pdn_addr.addr[9],
act_def_eps_bearer_context_req.pdn_addr.addr[10],
act_def_eps_bearer_context_req.pdn_addr.addr[11]);
char *err_str = NULL;
if (gw->setup_if_addr(ip_addr, err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str);
}
if (gw->setup_if_addr6(ipv6_if_id, err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str);
}
} else {
nas_log->error("PDN type not IPv4, IPv6 nor IPv4v6\n");
pool->deallocate(pdu);

Loading…
Cancel
Save