forked from acouzens/open5gs
router advertisement use link-local-address in source ip
This commit is contained in:
parent
a102864428
commit
cdaf1c0468
|
@ -155,6 +155,7 @@ CORE_DECLARE(status_t) core_copyaddrinfo(
|
||||||
c_sockaddr_t **dst, const c_sockaddr_t *src);
|
c_sockaddr_t **dst, const c_sockaddr_t *src);
|
||||||
CORE_DECLARE(status_t) core_filteraddrinfo(c_sockaddr_t **sa_list, int family);
|
CORE_DECLARE(status_t) core_filteraddrinfo(c_sockaddr_t **sa_list, int family);
|
||||||
CORE_DECLARE(status_t) core_sortaddrinfo(c_sockaddr_t **sa_list, int family);
|
CORE_DECLARE(status_t) core_sortaddrinfo(c_sockaddr_t **sa_list, int family);
|
||||||
|
CORE_DECLARE(c_sockaddr_t *) core_link_local_addr_by_dev(const char *dev);
|
||||||
|
|
||||||
#define CORE_ADDRSTRLEN INET6_ADDRSTRLEN
|
#define CORE_ADDRSTRLEN INET6_ADDRSTRLEN
|
||||||
#define CORE_ADDR(__aDDR, __bUF) \
|
#define CORE_ADDR(__aDDR, __bUF) \
|
||||||
|
|
|
@ -179,6 +179,49 @@ status_t core_sortaddrinfo(c_sockaddr_t **sa_list, int family)
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c_sockaddr_t *core_link_local_addr_by_dev(const char *dev)
|
||||||
|
{
|
||||||
|
struct ifaddrs *iflist, *cur;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
d_assert(dev, return NULL,);
|
||||||
|
|
||||||
|
rc = getifaddrs(&iflist);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
d_error("getifaddrs failed(%d:%s)", errno, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cur = iflist; cur != NULL; cur = cur->ifa_next)
|
||||||
|
{
|
||||||
|
c_sockaddr_t *addr = NULL;
|
||||||
|
|
||||||
|
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(dev, cur->ifa_name) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cur->ifa_addr->sa_family == AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addr = (c_sockaddr_t *)cur->ifa_addr;
|
||||||
|
if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||||
|
d_assert(addr, return NULL,);
|
||||||
|
memcpy(&addr->sa, cur->ifa_addr, sockaddr_len(cur->ifa_addr));
|
||||||
|
|
||||||
|
freeifaddrs(iflist);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(iflist);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const char *core_inet_ntop(void *sa, char *buf, int buflen)
|
const char *core_inet_ntop(void *sa, char *buf, int buflen)
|
||||||
{
|
{
|
||||||
int family;
|
int family;
|
||||||
|
|
|
@ -1294,6 +1294,10 @@ status_t pgw_dev_remove(pgw_dev_t *dev)
|
||||||
d_assert(dev, return CORE_ERROR, "Null param");
|
d_assert(dev, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
list_remove(&self.dev_list, dev);
|
list_remove(&self.dev_list, dev);
|
||||||
|
|
||||||
|
if (dev->link_local_addr)
|
||||||
|
core_freeaddrinfo(dev->link_local_addr);
|
||||||
|
|
||||||
pool_free_node(&pgw_dev_pool, dev);
|
pool_free_node(&pgw_dev_pool, dev);
|
||||||
|
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
|
|
|
@ -69,7 +69,7 @@ typedef struct _pgw_dev_t {
|
||||||
c_int8_t ifname[IFNAMSIZ];
|
c_int8_t ifname[IFNAMSIZ];
|
||||||
sock_id sock;
|
sock_id sock;
|
||||||
|
|
||||||
c_uint8_t link_local_addr[IPV6_LEN];
|
c_sockaddr_t *link_local_addr;
|
||||||
} pgw_dev_t;
|
} pgw_dev_t;
|
||||||
|
|
||||||
typedef struct _pgw_subnet_t {
|
typedef struct _pgw_subnet_t {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
c_uint16_t in_cksum(c_uint16_t *addr, int len);
|
c_uint16_t in_cksum(c_uint16_t *addr, int len);
|
||||||
static status_t pgw_gtp_handle_multicast(pkbuf_t *recvbuf);
|
static status_t pgw_gtp_handle_multicast(pkbuf_t *recvbuf);
|
||||||
static status_t pgw_gtp_handle_slacc(pgw_sess_t *sess, pkbuf_t *recvbuf);
|
static status_t pgw_gtp_handle_slaac(pgw_sess_t *sess, pkbuf_t *recvbuf);
|
||||||
static status_t pgw_gtp_send_to_bearer(pgw_bearer_t *bearer, pkbuf_t *sendbuf);
|
static status_t pgw_gtp_send_to_bearer(pgw_bearer_t *bearer, pkbuf_t *sendbuf);
|
||||||
static status_t pgw_gtp_send_router_advertisement(pgw_sess_t *sess);
|
static status_t pgw_gtp_send_router_advertisement(pgw_sess_t *sess);
|
||||||
|
|
||||||
|
@ -151,13 +151,13 @@ static int _gtpv1_u_recv_cb(sock_id sock, void *data)
|
||||||
/* Check IPv6 */
|
/* Check IPv6 */
|
||||||
if (context_self()->parameter.no_slaac == 0 && ip_h->ip_v == 6)
|
if (context_self()->parameter.no_slaac == 0 && ip_h->ip_v == 6)
|
||||||
{
|
{
|
||||||
rv = pgw_gtp_handle_slacc(sess, pkbuf);
|
rv = pgw_gtp_handle_slaac(sess, pkbuf);
|
||||||
if (rv == PGW_GTP_HANDLED)
|
if (rv == PGW_GTP_HANDLED)
|
||||||
{
|
{
|
||||||
pkbuf_free(pkbuf);
|
pkbuf_free(pkbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
d_assert(rv == CORE_OK,, "pgw_gtp_handle_slacc() failed");
|
d_assert(rv == CORE_OK,, "pgw_gtp_handle_slaac() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = subnet->dev;
|
dev = subnet->dev;
|
||||||
|
@ -251,6 +251,10 @@ status_t pgw_gtp_open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Link-Local Address for PGW_TUN */
|
||||||
|
for (dev = pgw_dev_first(); dev; dev = pgw_dev_next(dev))
|
||||||
|
dev->link_local_addr = core_link_local_addr_by_dev(dev->ifname);
|
||||||
|
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +312,7 @@ static status_t pgw_gtp_handle_multicast(pkbuf_t *recvbuf)
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t pgw_gtp_handle_slacc(pgw_sess_t *sess, pkbuf_t *recvbuf)
|
static status_t pgw_gtp_handle_slaac(pgw_sess_t *sess, pkbuf_t *recvbuf)
|
||||||
{
|
{
|
||||||
status_t rv;
|
status_t rv;
|
||||||
struct ip *ip_h = NULL;
|
struct ip *ip_h = NULL;
|
||||||
|
@ -377,8 +381,14 @@ static status_t pgw_gtp_send_router_advertisement(pgw_sess_t *sess)
|
||||||
{
|
{
|
||||||
status_t rv;
|
status_t rv;
|
||||||
pkbuf_t *pkbuf = NULL;
|
pkbuf_t *pkbuf = NULL;
|
||||||
|
|
||||||
pgw_bearer_t *bearer = NULL;
|
pgw_bearer_t *bearer = NULL;
|
||||||
ipsubnet_t src_ipsub, dst_ipsub;
|
pgw_ue_ip_t *ue_ip = NULL;
|
||||||
|
pgw_subnet_t *subnet = NULL;
|
||||||
|
pgw_dev_t *dev = NULL;
|
||||||
|
|
||||||
|
ipsubnet_t src_ipsub;
|
||||||
|
ipsubnet_t dst_ipsub;
|
||||||
c_uint16_t plen = 0;
|
c_uint16_t plen = 0;
|
||||||
c_uint8_t nxt = 0;
|
c_uint8_t nxt = 0;
|
||||||
c_uint8_t *p = NULL;
|
c_uint8_t *p = NULL;
|
||||||
|
@ -389,6 +399,12 @@ static status_t pgw_gtp_send_router_advertisement(pgw_sess_t *sess)
|
||||||
d_assert(sess, return CORE_ERROR,);
|
d_assert(sess, return CORE_ERROR,);
|
||||||
bearer = pgw_default_bearer_in_sess(sess);
|
bearer = pgw_default_bearer_in_sess(sess);
|
||||||
d_assert(bearer, return CORE_ERROR,);
|
d_assert(bearer, return CORE_ERROR,);
|
||||||
|
ue_ip = sess->ipv6;
|
||||||
|
d_assert(ue_ip, return CORE_ERROR,);
|
||||||
|
subnet = ue_ip->subnet;
|
||||||
|
d_assert(subnet, return CORE_ERROR,);
|
||||||
|
dev = subnet->dev;
|
||||||
|
d_assert(dev, return CORE_ERROR,);
|
||||||
|
|
||||||
pkbuf = pkbuf_alloc(GTPV1U_HEADER_LEN, 200);
|
pkbuf = pkbuf_alloc(GTPV1U_HEADER_LEN, 200);
|
||||||
d_assert(pkbuf, return CORE_ERROR,);
|
d_assert(pkbuf, return CORE_ERROR,);
|
||||||
|
@ -403,6 +419,10 @@ static status_t pgw_gtp_send_router_advertisement(pgw_sess_t *sess)
|
||||||
|
|
||||||
rv = core_ipsubnet(&src_ipsub, "fe80::1", NULL);
|
rv = core_ipsubnet(&src_ipsub, "fe80::1", NULL);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR,);
|
d_assert(rv == CORE_OK, return CORE_ERROR,);
|
||||||
|
if (dev->link_local_addr)
|
||||||
|
memcpy(src_ipsub.sub, dev->link_local_addr->sin6.sin6_addr.s6_addr,
|
||||||
|
sizeof src_ipsub.sub);
|
||||||
|
|
||||||
rv = core_ipsubnet(&dst_ipsub, "ff02::1", NULL);
|
rv = core_ipsubnet(&dst_ipsub, "ff02::1", NULL);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR,);
|
d_assert(rv == CORE_OK, return CORE_ERROR,);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue