Find link-local address in SMF-All address (#1291)

This commit is contained in:
Sukchan Lee 2021-12-17 11:33:54 +09:00
parent 232c387276
commit a3166ab537
4 changed files with 36 additions and 47 deletions

View File

@ -252,14 +252,12 @@ int ogs_sortaddrinfo(ogs_sockaddr_t **sa_list, int family)
return OGS_OK;
}
ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev)
ogs_sockaddr_t *ogs_link_local_addr(const char *dev, const ogs_sockaddr_t *sa)
{
#if defined(HAVE_GETIFADDRS)
struct ifaddrs *iflist, *cur;
int rc;
ogs_assert(dev);
rc = getifaddrs(&iflist);
if (rc != 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "getifaddrs failed");
@ -267,19 +265,25 @@ ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev)
}
for (cur = iflist; cur != NULL; cur = cur->ifa_next) {
ogs_sockaddr_t *ifa_addr = NULL;
ogs_sockaddr_t *addr = NULL;
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
ifa_addr = (ogs_sockaddr_t *)cur->ifa_addr;
if (ifa_addr == NULL) /* may happen with ppp interfaces */
continue;
if (strcmp(dev, cur->ifa_name) != 0)
if (ifa_addr->ogs_sa_family == AF_INET)
continue;
if (cur->ifa_addr->sa_family == AF_INET)
if (!IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6.sin6_addr))
continue;
addr = (ogs_sockaddr_t *)cur->ifa_addr;
if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr))
if (dev && strcmp(dev, cur->ifa_name) != 0)
continue;
if (sa && memcmp(&sa->sin6.sin6_addr,
&ifa_addr->sin6.sin6_addr, sizeof(struct in6_addr)) != 0)
continue;
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
@ -297,41 +301,16 @@ ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev)
return NULL;
}
ogs_sockaddr_t *ogs_link_local_addr_by_addr(const ogs_sockaddr_t *sa)
ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev)
{
#if defined(HAVE_GETIFADDRS)
struct ifaddrs *iflist, *cur;
int rc;
ogs_sockaddr_t *ifaddr;
ogs_assert(dev);
return ogs_link_local_addr(dev, NULL);
}
ogs_sockaddr_t *ogs_link_local_addr_by_sa(const ogs_sockaddr_t *sa)
{
ogs_assert(sa);
rc = getifaddrs(&iflist);
if (rc != 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "getifaddrs failed");
return NULL;
}
for (cur = iflist; cur != NULL; cur = cur->ifa_next) {
ifaddr = (ogs_sockaddr_t *)cur->ifa_addr;
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
continue;
if (cur->ifa_addr->sa_family == AF_INET)
continue;
if (memcmp(&sa->sin6.sin6_addr,
&ifaddr->sin6.sin6_addr, sizeof(struct in6_addr)) == 0) {
freeifaddrs(iflist);
return ogs_link_local_addr_by_dev(cur->ifa_name);
}
}
freeifaddrs(iflist);
#endif
ogs_error("ogs_link_local_addr_by_addr() failed");
return NULL;
return ogs_link_local_addr(NULL, sa);
}
int ogs_filter_ip_version(ogs_sockaddr_t **addr,

View File

@ -88,8 +88,9 @@ int ogs_copyaddrinfo(
int ogs_filteraddrinfo(ogs_sockaddr_t **sa_list, int family);
int ogs_sortaddrinfo(ogs_sockaddr_t **sa_list, int family);
ogs_sockaddr_t *ogs_link_local_addr(const char *dev, const ogs_sockaddr_t *sa);
ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev);
ogs_sockaddr_t *ogs_link_local_addr_by_addr(const ogs_sockaddr_t *sa);
ogs_sockaddr_t *ogs_link_local_addr_by_sa(const ogs_sockaddr_t *sa);
int ogs_filter_ip_version(ogs_sockaddr_t **addr,
int no_ipv4, int no_ipv6, int prefer_ipv4);

View File

@ -49,6 +49,8 @@ typedef struct ogs_gtp_context_s {
ogs_list_t gtpu_peer_list; /* GTPU Node List */
ogs_list_t gtpu_resource_list; /* UP IP Resource List */
ogs_sockaddr_t *link_local_addr;
} ogs_gtp_context_t;
#define OGS_SETUP_GTP_NODE(__cTX, __gNODE) \

View File

@ -266,11 +266,23 @@ int smf_gtp_open(void)
OGS_SETUP_GTPU_SERVER;
/* Fetch link-local address for router advertisement */
if (ogs_gtp_self()->link_local_addr)
ogs_freeaddrinfo(ogs_gtp_self()->link_local_addr);
ogs_gtp_self()->link_local_addr = ogs_link_local_addr(NULL, NULL);
if (!ogs_gtp_self()->link_local_addr) {
ogs_error("No link-local address for router advertisement");
return OGS_ERROR;
}
return OGS_OK;
}
void smf_gtp_close(void)
{
if (ogs_gtp_self()->link_local_addr)
ogs_freeaddrinfo(ogs_gtp_self()->link_local_addr);
ogs_socknode_remove_all(&ogs_gtp_self()->gtpc_list);
ogs_socknode_remove_all(&ogs_gtp_self()->gtpc_list6);
@ -395,7 +407,6 @@ static void send_router_advertisement(smf_sess_t *sess, uint8_t *ip6_dst)
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_ue_ip_t *ue_ip = NULL;
ogs_pfcp_subnet_t *subnet = NULL;
ogs_sockaddr_t *link_local_addr = NULL;
char ipstr[OGS_ADDRSTRLEN];
ogs_ipsubnet_t src_ipsub;
@ -413,11 +424,7 @@ static void send_router_advertisement(smf_sess_t *sess, uint8_t *ip6_dst)
ogs_assert(subnet);
/* Fetch link-local address for router advertisement */
ogs_expect_or_return(ogs_gtp_self()->gtpu_addr6);
link_local_addr = ogs_link_local_addr_by_addr(ogs_gtp_self()->gtpu_addr6);
ogs_expect_or_return(link_local_addr);
OGS_ADDR(link_local_addr, ipstr);
ogs_freeaddrinfo(link_local_addr);
OGS_ADDR(ogs_gtp_self()->link_local_addr, ipstr);
rv = ogs_ipsubnet(&src_ipsub, ipstr, NULL);
ogs_expect_or_return(rv == OGS_OK);