This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Pau Espin Pedrol gerrit-no-reply at lists.osmocom.orgHello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/5121
to look at the new patch set (#2).
Add configure flag to disable ipv6 support
Some users may want to disable ipv6 related features in case they are
not needed. It can also be used as a workaround to build libgtp and
osmo-ggsn in systems where ipv6 supports fails to build due to header
struct definition conflicts between kernel and libc.
Related: SYS#3815
Change-Id: I651a12d63d025bde61dcbc3c6b949cd0fed43580
---
M configure.ac
M ggsn/Makefile.am
M ggsn/ggsn.c
M ggsn/ggsn.h
M ggsn/ggsn_vty.c
M lib/in46_addr.c
M lib/in46_addr.h
M lib/ippool.c
M lib/tun.c
M sgsnemu/sgsnemu.c
M tests/lib/in46a_test.c
M tests/lib/ippool_test.c
M tests/testsuite.at
13 files changed, 180 insertions(+), 30 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ggsn refs/changes/21/5121/2
diff --git a/configure.ac b/configure.ac
index 4fd0132..b835f7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,6 +71,15 @@
AM_CONDITIONAL([ENABLE_GTP_KERNEL], [test "$enable_gtp_linux" = "yes"])
+# Enable/disable IPv6 support
+AC_ARG_ENABLE([ipv6], [AS_HELP_STRING([--enable-ipv6], [Build IPv6 support])],
+ [enable_ipv6="$enableval"],[enable_ipv6="yes"])
+if test "x$enable_ipv6" = "xyes" ; then
+ AC_DEFINE(BUILD_IPv6, 1, [Define if we want to build IPv6 support])
+fi
+AM_CONDITIONAL(BUILD_IPv6, test "x$enable_ipv6" = "xyes")
+#AC_SUBST(enable_ipv6)
+
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
@@ -170,4 +179,5 @@
echo "
osmo-ggsn Configuration:
- GTP Linux kernel support: ${enable_gtp_linux}"
+ GTP Linux kernel support: ${enable_gtp_linux}
+ IPv6 support: ${enable_ipv6}"
diff --git a/ggsn/Makefile.am b/ggsn/Makefile.am
index 8a468a9..07adf80 100644
--- a/ggsn/Makefile.am
+++ b/ggsn/Makefile.am
@@ -12,7 +12,10 @@
endif
osmo_ggsn_DEPENDENCIES = ../gtp/libgtp.la ../lib/libmisc.a
-osmo_ggsn_SOURCES = ggsn_vty.c ggsn.c ggsn.h gtp-kernel.h icmpv6.c icmpv6.h checksum.c checksum.h
+osmo_ggsn_SOURCES = ggsn_vty.c ggsn.c ggsn.h gtp-kernel.h checksum.c checksum.h
+if BUILD_IPv6
+osmo_ggsn_SOURCES += icmpv6.c icmpv6.h
+endif
if ENABLE_GTP_KERNEL
osmo_ggsn_SOURCES += gtp-kernel.c
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 763a2c5..6a206a2 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -65,7 +65,9 @@
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include "gtp-kernel.h"
+#if defined(BUILD_IPv6)
#include "icmpv6.h"
+#endif
#include "ggsn.h"
void *tall_ggsn_ctx;
@@ -115,7 +117,9 @@
LOGPAPN(LOGL_NOTICE, apn, "%sStopping\n", force ? "FORCED " : "");
/* check if pools have any active PDP contexts and bail out */
pool_close_all_pdp(apn->v4.pool);
+#if defined(BUILD_IPv6)
pool_close_all_pdp(apn->v6.pool);
+#endif
/* shutdown whatever old state might be left */
if (apn->tun.tun) {
@@ -137,12 +141,13 @@
ippool_free(apn->v4.pool);
apn->v4.pool = NULL;
}
+#if defined(BUILD_IPv6)
if (apn->v6.pool) {
LOGPAPN(LOGL_INFO, apn, "Releasing IPv6 pool\n");
ippool_free(apn->v6.pool);
apn->v6.pool = NULL;
}
-
+#endif
apn->started = false;
return 0;
}
@@ -155,9 +160,11 @@
*blacklist = NULL;
+#if defined(BUILD_IPv6)
if (ipv6)
flags = IP_TYPE_IPv6_NONLINK;
else
+#endif
flags = IP_TYPE_IPv4;
while (1) {
@@ -191,7 +198,9 @@
int apn_start(struct apn_ctx *apn)
{
int ippool_flags = IPPOOL_NONETWORK | IPPOOL_NOBROADCAST;
+#if defined(BUILD_IPv6)
struct in46_prefix ipv6_tun_linklocal_ip;
+#endif
struct in46_prefix *blacklist;
int blacklist_size;
@@ -226,7 +235,7 @@
return -1;
}
}
-
+#if defined(BUILD_IPv6)
if (apn->v6.cfg.ifconfig_prefix.addr.len) {
LOGPAPN(LOGL_INFO, apn, "Setting tun IPv6 address %s\n",
in46p_ntoa(&apn->v6.cfg.ifconfig_prefix));
@@ -239,13 +248,13 @@
return -1;
}
}
-
+#endif
if (apn->tun.cfg.ipup_script) {
LOGPAPN(LOGL_INFO, apn, "Running ip-up script %s\n",
apn->tun.cfg.ipup_script);
tun_runscript(apn->tun.tun, apn->tun.cfg.ipup_script);
}
-
+#if defined(BUILD_IPv6)
if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) {
if (tun_ip_local_get(apn->tun.tun, &ipv6_tun_linklocal_ip, 1, IP_TYPE_IPv6_LINK) < 1) {
LOGPAPN(LOGL_ERROR, apn, "Cannot obtain IPv6 link-local address of "
@@ -255,17 +264,20 @@
}
apn->v6_lladdr = ipv6_tun_linklocal_ip.addr.v6;
}
+#endif
/* set back-pointer from TUN device to APN */
apn->tun.tun->priv = apn;
break;
case APN_GTPU_MODE_KERNEL_GTP:
LOGPAPN(LOGL_INFO, apn, "Opening Kernel GTP device %s\n", apn->tun.cfg.dev_name);
+#if defined(BUILD_IPv6)
if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) {
LOGPAPN(LOGL_ERROR, apn, "Kernel GTP currently supports only IPv4\n");
apn_stop(apn, false);
return -1;
}
+#endif
/* use GTP kernel module for data packet encapsulation */
if (gtp_kernel_init(apn->ggsn->gsn, apn->tun.cfg.dev_name,
&apn->v4.cfg.ifconfig_prefix, apn->tun.cfg.ipup_script) < 0) {
@@ -294,6 +306,7 @@
talloc_free(blacklist);
}
+#if defined(BUILD_IPv6)
/* Create IPv6 pool */
if (apn->v6.cfg.dynamic_prefix.addr.len) {
LOGPAPN(LOGL_INFO, apn, "Creating IPv6 pool %s\n",
@@ -310,6 +323,7 @@
}
talloc_free(blacklist);
}
+#endif
LOGPAPN(LOGL_NOTICE, apn, "Successfully started\n");
apn->started = true;
@@ -468,6 +482,7 @@
build_ipcp_pco(msg, 0, &apn->v4.cfg.dns[0], &apn->v4.cfg.dns[1]);
}
+#if defined(BUILD_IPv6)
if (pco_contains_proto(&pdp->pco_req, PCO_P_DNS_IPv6_ADDR)) {
for (i = 0; i < ARRAY_SIZE(apn->v6.cfg.dns); i++) {
struct in46_addr *i46a = &apn->v6.cfg.dns[i];
@@ -476,6 +491,7 @@
msgb_t16lv_put(msg, PCO_P_DNS_IPv6_ADDR, i46a->len, i46a->v6.s6_addr);
}
}
+#endif
if (pco_contains_proto(&pdp->pco_req, PCO_P_DNS_IPv4_ADDR)) {
for (i = 0; i < ARRAY_SIZE(apn->v4.cfg.dns); i++) {
@@ -502,12 +518,14 @@
return false;
}
+#if defined(BUILD_IPv6)
static bool apn_supports_ipv6(const struct apn_ctx *apn)
{
if (apn->v6.cfg.static_prefix.addr.len || apn->v6.cfg.dynamic_prefix.addr.len)
return true;
return false;
}
+#endif
int create_context_ind(struct pdp_t *pdp)
{
@@ -575,6 +593,7 @@
gtp_create_context_resp(gsn, pdp, GTPCAUSE_SYS_FAIL);
return 0;
}
+#if defined(BUILD_IPv6)
} else if (addr.len == sizeof(struct in6_addr)) {
struct in46_addr tmp;
@@ -594,6 +613,7 @@
/* use allocated 64bit prefix as lower 64bit, used as link id by MS */
memcpy(tmp.v6.s6_addr+8, &member->addr.v6, 8);
in46a_to_eua(&tmp, &pdp->eua);
+#endif
} else
OSMO_ASSERT(0);
@@ -635,7 +655,9 @@
struct ippoolm_t *ipm;
struct in46_addr dst;
struct iphdr *iph = (struct iphdr *)pack;
+#if defined(BUILD_IPv6)
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
+#endif
struct ippool_t *pool;
if (iph->version == 4) {
@@ -644,6 +666,7 @@
dst.len = 4;
dst.v4.s_addr = iph->daddr;
pool = apn->v4.pool;
+#if defined(BUILD_IPv6)
} else if (iph->version == 6) {
/* Due to the fact that 3GPP requires an allocation of a
* /64 prefix to each MS, we must instruct
@@ -652,6 +675,7 @@
dst.len = 8;
dst.v6 = ip6h->ip6_dst;
pool = apn->v6.pool;
+#endif
} else {
LOGP(DTUN, LOGL_NOTICE, "non-IPv%u packet received from tun\n", iph->version);
return -1;
@@ -673,16 +697,20 @@
return 0;
}
+#if defined(BUILD_IPv6)
/* RFC3307 link-local scope multicast address */
static const struct in6_addr all_router_mcast_addr = {
.s6_addr = { 0xff,0x02,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,2 }
};
+#endif
/* MS-originated GTP1-U packet, needs to be sent via TUN device */
static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
{
struct iphdr *iph = (struct iphdr *)pack;
+#if defined(BUILD_IPv6)
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
+#endif
struct tun_t *tun = (struct tun_t *)pdp->ipif;
struct apn_ctx *apn = tun->priv;
@@ -692,11 +720,13 @@
LOGPPDP(LOGL_DEBUG, pdp, "Packet received: forwarding to tun\n");
switch (iph->version) {
+#if defined(BUILD_IPv6)
case 6:
/* daddr: all-routers multicast addr */
if (IN6_ARE_ADDR_EQUAL(&ip6h->ip6_dst, &all_router_mcast_addr))
return handle_router_mcast(pdp->gsn, pdp, &apn->v6_lladdr, pack, len);
break;
+#endif
case 4:
break;
default:
diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h
index c0774c4..ca0013f 100644
--- a/ggsn/ggsn.h
+++ b/ggsn/ggsn.h
@@ -80,11 +80,12 @@
struct osmo_fd fd;
} tun;
+ struct apn_ctx_ip v4;
+#if defined(BUILD_IPv6)
+ struct apn_ctx_ip v6;
/* ipv6 link-local address */
struct in6_addr v6_lladdr;
-
- struct apn_ctx_ip v4;
- struct apn_ctx_ip v6;
+#endif
};
struct ggsn_ctx {
diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c
index 6e15ae4..4932c20 100644
--- a/ggsn/ggsn_vty.c
+++ b/ggsn/ggsn_vty.c
@@ -334,8 +334,10 @@
static const struct value_string pdp_type_names[] = {
{ APN_TYPE_IPv4, "v4" },
+#if defined(BUILD_IPv6)
{ APN_TYPE_IPv6, "v6" },
{ APN_TYPE_IPv4v6, "v4v6" },
+#endif
{ 0, NULL }
};
@@ -345,13 +347,17 @@
{ 0, NULL }
};
-
+#if defined(BUILD_IPv6)
+#define V4V6V46_ARGS "(v4|v6|v4v6)"
#define V4V6V46_STRING "IPv4(-only) PDP Type\n" \
"IPv6(-only) PDP Type\n" \
"IPv4v6 (dual-stack) PDP Type\n"
-
+#else
+#define V4V6V46_ARGS "(v4)"
+#define V4V6V46_STRING "IPv4(-only) PDP Type\n"
+#endif
DEFUN(cfg_apn_type_support, cfg_apn_type_support_cmd,
- "type-support (v4|v6|v4v6)",
+ "type-support " V4V6V46_ARGS,
"Enable support for PDP Type\n"
V4V6V46_STRING)
{
@@ -363,7 +369,7 @@
}
DEFUN(cfg_apn_no_type_support, cfg_apn_no_type_support_cmd,
- "no type-support (v4|v6|v4v6)",
+ "no type-support " V4V6V46_ARGS,
NO_STR "Disable support for PDP Type\n"
V4V6V46_STRING)
{
@@ -480,6 +486,7 @@
return CMD_SUCCESS;
}
+#if defined(BUILD_IPv6)
DEFUN(cfg_apn_ipv6_prefix, cfg_apn_ipv6_prefix_cmd,
"ipv6 prefix (static|dynamic) X:X::X:X/M",
IP6_STR PREFIX_STR "IPv6 Address/Prefix-Length\n")
@@ -512,6 +519,7 @@
memset(&apn->v6.cfg.ifconfig_prefix, 0, sizeof(apn->v6.cfg.ifconfig_prefix));
return CMD_SUCCESS;
}
+#endif
#define DNS_STRINGS "Configure DNS Server\n" "primary/secondary DNS\n" "IP address of DNS Sever\n"
@@ -528,6 +536,7 @@
return CMD_SUCCESS;
}
+#if defined(BUILD_IPv6)
DEFUN(cfg_apn_ipv6_dns, cfg_apn_ipv6_dns_cmd,
"ipv6 dns <0-1> X:X::X:X",
IP6_STR DNS_STRINGS)
@@ -540,20 +549,27 @@
return CMD_SUCCESS;
}
+#endif
+#if defined(BUILD_IPv6)
+#define IPV46_ARGS "(ip|ipv6)"
+#else
+#define IPV46_ARGS "(ip)"
+#endif
DEFUN(cfg_apn_no_dns, cfg_apn_no_dns_cmd,
- "no (ip|ipv6) dns <0-1>",
+ "no " IPV46_ARGS " dns <0-1>",
NO_STR IP_STR IP6_STR "Disable DNS Server\n" "primary/secondary DNS\n")
{
struct apn_ctx *apn = (struct apn_ctx *) vty->index;
- struct in46_addr *a;
+ struct in46_addr *a = NULL;
int idx = atoi(argv[1]);
if (!strcmp(argv[0], "ip"))
a = &apn->v4.cfg.dns[idx];
+#if defined(BUILD_IPv6)
else
a = &apn->v6.cfg.dns[idx];
-
+#endif
memset(a, 0, sizeof(*a));
return CMD_SUCCESS;
@@ -656,6 +672,7 @@
if (apn->v4.cfg.ifconfig_prefix.addr.len)
vty_dump_prefix(vty, " ip ifconfig", &apn->v4.cfg.ifconfig_prefix);
+#if defined(BUILD_IPv6)
/* IPv6 prefixes + DNS */
if (apn->v6.cfg.static_prefix.addr.len)
vty_dump_prefix(vty, " ipv6 prefix static", &apn->v6.cfg.static_prefix);
@@ -668,7 +685,7 @@
}
if (apn->v6.cfg.ifconfig_prefix.addr.len)
vty_dump_prefix(vty, " ipv6 ifconfig", &apn->v6.cfg.ifconfig_prefix);
-
+#endif
/* must be last */
vty_out(vty, " %sshutdown%s", apn->cfg.shutdown ? "" : "no ", VTY_NEWLINE);
}
@@ -704,8 +721,12 @@
struct in46_addr in46;
in46.len = in->l;
+#if defined(BUILD_IPv6)
OSMO_ASSERT(in->l <= sizeof(in46.v6));
- memcpy(&in46.v6, in->v, in->l);
+#else
+ OSMO_ASSERT(in->l <= sizeof(in46.v4));
+#endif
+ memcpy(&in46.v4, in->v, in->l);
return in46a_ntoa(&in46);
}
@@ -781,7 +802,9 @@
static void apn_show_pdp_contexts(struct vty *vty, struct apn_ctx *apn)
{
ippool_show_pdp_contexts(vty, apn->v4.pool);
+#if defined(BUILD_IPv6)
ippool_show_pdp_contexts(vty, apn->v6.pool);
+#endif
}
DEFUN(show_pdpctx, show_pdpctx_cmd,
@@ -885,14 +908,16 @@
install_element(APN_NODE, &cfg_apn_ipdown_script_cmd);
install_element(APN_NODE, &cfg_apn_no_ipdown_script_cmd);
install_element(APN_NODE, &cfg_apn_ip_prefix_cmd);
- install_element(APN_NODE, &cfg_apn_ipv6_prefix_cmd);
install_element(APN_NODE, &cfg_apn_ip_dns_cmd);
- install_element(APN_NODE, &cfg_apn_ipv6_dns_cmd);
install_element(APN_NODE, &cfg_apn_no_dns_cmd);
install_element(APN_NODE, &cfg_apn_ip_ifconfig_cmd);
install_element(APN_NODE, &cfg_apn_no_ip_ifconfig_cmd);
+#if defined(BUILD_IPv6)
+ install_element(APN_NODE, &cfg_apn_ipv6_prefix_cmd);
+ install_element(APN_NODE, &cfg_apn_ipv6_dns_cmd);
install_element(APN_NODE, &cfg_apn_ipv6_ifconfig_cmd);
install_element(APN_NODE, &cfg_apn_no_ipv6_ifconfig_cmd);
+#endif
install_element(APN_NODE, &cfg_apn_gpdu_seq_cmd);
install_element(APN_NODE, &cfg_apn_no_gpdu_seq_cmd);
diff --git a/lib/in46_addr.c b/lib/in46_addr.c
index 36ad6af..79123b5 100644
--- a/lib/in46_addr.c
+++ b/lib/in46_addr.c
@@ -28,9 +28,11 @@
switch (in->len) {
case 4:
return AF_INET;
+#if defined(BUILD_IPv6)
case 8:
case 16:
return AF_INET6;
+#endif
default:
OSMO_ASSERT(0);
return -1;
@@ -41,17 +43,21 @@
int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in)
{
struct sockaddr_in *sin = (struct sockaddr_in *)out;
+#if defined(BUILD_IPv6)
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)out;
+#endif
switch (in->len) {
case 4:
sin->sin_family = AF_INET;
sin->sin_addr = in->v4;
break;
+#if defined(BUILD_IPv6)
case 16:
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = in->v6;
break;
+#endif
default:
OSMO_ASSERT(0);
return -1;
@@ -98,7 +104,7 @@
* \returns 1 in case they are equal; 0 otherwise */
int in46a_equal(const struct in46_addr *a, const struct in46_addr *b)
{
- if (a->len == b->len && !memcmp(&a->v6, &b->v6, a->len))
+ if (a->len == b->len && !memcmp(&a->v4, &b->v4, a->len))
return 1;
else
return 0;
@@ -115,12 +121,13 @@
else
len = a->len;
- if (!memcmp(&a->v6, &b->v6, len))
+ if (!memcmp(&a->v4, &b->v4, len))
return 1;
else
return 0;
}
+#if defined(BUILD_IPv6)
/*! Match if IPv6 addr1 + addr2 are within same \a mask */
static int ipv6_within_mask(const struct in6_addr *addr1, const struct in6_addr *addr2,
const struct in6_addr *mask)
@@ -167,6 +174,7 @@
*p_netmask = htonl(0xFFFFFFFF << (32 - prefixlen));
}
}
+#endif
/*! Determine if given \a addr is within given \a net + \a prefixlen
* Builds the netmask from \a net + \a prefixlen and matches it to \a addr
@@ -174,7 +182,9 @@
int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, size_t prefixlen)
{
struct in_addr netmask;
+#if defined(BUILD_IPv6)
struct in6_addr netmask6;
+#endif
if (addr->len != net->len)
return 0;
@@ -186,9 +196,11 @@
return 1;
else
return 0;
+#if defined(BUILD_IPv6)
case 16:
create_ipv6_netmask(&netmask6, prefixlen);
return ipv6_within_mask(&addr->v6, &net->v6, &netmask6);
+#endif
default:
OSMO_ASSERT(0);
return 0;
@@ -210,6 +222,7 @@
return prefix;
}
+#if defined(BUILD_IPv6)
static unsigned int ipv6_netmasklen(const struct in6_addr *netmask)
{
#if defined(__linux__)
@@ -235,6 +248,7 @@
return prefix;
}
+#endif
/*! Convert netmask to prefix length representation
* \param[in] netmask in46_addr containing a netmask (consecutive list of 1-bit followed by consecutive list of 0-bit)
@@ -245,8 +259,10 @@
switch (netmask->len) {
case 4:
return ipv4_netmasklen(&netmask->v4);
+#if defined(BUILD_IPv6)
case 16:
return ipv6_netmasklen(&netmask->v6);
+#endif
default:
OSMO_ASSERT(0);
return 0;
@@ -264,6 +280,7 @@
eua->v[1] = PDP_EUA_TYPE_v4;
memcpy(&eua->v[2], &src->v4, 4); /* Copy a 4 byte address */
break;
+#if defined(BUILD_IPv6)
case 8:
case 16:
eua->l = 18;
@@ -271,6 +288,7 @@
eua->v[1] = PDP_EUA_TYPE_v6;
memcpy(&eua->v[2], &src->v6, 16); /* Copy a 16 byte address */
break;
+#endif
default:
OSMO_ASSERT(0);
return -1;
@@ -296,6 +314,7 @@
else
dst->v4.s_addr = 0;
break;
+#if defined(BUILD_IPv6)
case PDP_EUA_TYPE_v6:
dst->len = 16;
if (eua->l >= 18)
@@ -303,6 +322,7 @@
else
memset(&dst->v6, 0, 16);
break;
+#endif
default:
return -1;
}
diff --git a/lib/in46_addr.h b/lib/in46_addr.h
index ff26521..2b3755b 100644
--- a/lib/in46_addr.h
+++ b/lib/in46_addr.h
@@ -4,13 +4,17 @@
#include "../gtp/pdp.h"
+#include "config.h"
+
/* a simple wrapper around an in6_addr to also contain the length of the address,
* thereby implicitly indicating the address family of the address */
struct in46_addr {
uint8_t len;
union {
struct in_addr v4;
+#if defined(BUILD_IPv6)
struct in6_addr v6;
+#endif
};
};
diff --git a/lib/ippool.c b/lib/ippool.c
index a9a64be..ffc4388 100644
--- a/lib/ippool.c
+++ b/lib/ippool.c
@@ -22,6 +22,8 @@
#include "ippool.h"
#include "lookup.h"
+#include "config.h"
+
int ippool_printaddr(struct ippool_t *this)
{
unsigned int n;
@@ -96,18 +98,24 @@
return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0);
}
+#if defined(BUILD_IPv6)
static unsigned long int ippool_hash6(struct in6_addr *addr, unsigned int len)
{
/* TODO: Review hash spread for IPv6 */
return lookup((unsigned char *)addr->s6_addr, len, 0);
}
+#endif
unsigned long int ippool_hash(struct in46_addr *addr)
{
+#if defined(BUILD_IPv6)
if (addr->len == 4)
return ippool_hash4(&addr->v4);
else
return ippool_hash6(&addr->v6, addr->len);
+#else
+ return ippool_hash4(&addr->v4);
+#endif
}
/* Get IP address and mask */
@@ -148,11 +156,14 @@
*prefixlen = 32;
addr->len = sizeof(struct in_addr);
addr->v4 = ((struct sockaddr_in*)ai->ai_addr)->sin_addr;
- } else {
+ }
+#if defined(BUILD_IPv6)
+ else {
*prefixlen = 128;
addr->len = sizeof(struct in6_addr);
addr->v6 = ((struct sockaddr_in6*)ai->ai_addr)->sin6_addr;
}
+#endif
freeaddrinfo(ai);
/* parse prefixlen */
@@ -177,7 +188,7 @@
void in46a_inc(struct in46_addr *addr)
{
size_t addrlen;
- uint8_t *a = (uint8_t *)&addr->v6;
+ uint8_t *a = (uint8_t *)&addr->v4;
for (addrlen = addr->len; addrlen > 0; addrlen--) {
if (++a[addrlen-1])
break;
@@ -215,11 +226,12 @@
} else {
addr = dyn->addr;
addrprefixlen = dyn->prefixlen;
+#if defined(BUILD_IPv6)
/* we want to work with /64 prefixes, i.e. allocate /64 prefixes rather
* than /128 (single IPv6 addresses) */
if (addr.len == sizeof(struct in6_addr))
addr.len = 64/8;
-
+#endif
dynsize = (1 << (addr.len*8 - addrprefixlen));
if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */
dynsize--;
@@ -404,8 +416,10 @@
if (addr) {
if (addr->len == 4 && addr->v4.s_addr)
specified = 1;
+#if defined(BUILD_IPv6)
if (addr->len == 16 && !IN6_IS_ADDR_UNSPECIFIED(&addr->v6))
specified = 1;
+#endif
}
/* First check to see if this type of address is allowed */
diff --git a/lib/tun.c b/lib/tun.c
index d8e4b62..ce3eced 100644
--- a/lib/tun.c
+++ b/lib/tun.c
@@ -62,7 +62,9 @@
#if defined(__linux__)
+#if defined(BUILD_IPv6)
#include <linux/ipv6.h>
+#endif
static int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen)
{
@@ -197,6 +199,7 @@
return 0;
}
+#if defined(BUILD_IPv6)
static int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_addr *dstaddr,
size_t prefixlen)
{
@@ -280,6 +283,7 @@
return 0;
}
+#endif /* BUILD_IPv6 */
int tun_setaddr(struct tun_t *this, struct in46_addr *addr, struct in46_addr *dstaddr, size_t prefixlen)
{
@@ -288,8 +292,10 @@
case 4:
netmask.s_addr = htonl(0xffffffff << (32 - prefixlen));
return tun_setaddr4(this, &addr->v4, dstaddr ? &dstaddr->v4 : NULL, &netmask);
+#if defined(BUILD_IPv6)
case 16:
return tun_setaddr6(this, &addr->v6, dstaddr ? &dstaddr->v6 : NULL, prefixlen);
+#endif
default:
return -1;
}
@@ -762,11 +768,13 @@
*/
int netdev_ip_local_get(const char *devname, struct in46_prefix *prefix_list, size_t prefix_size, int flags)
{
+#if defined(BUILD_IPv6)
static const uint8_t ll_prefix[] = { 0xfe,0x80, 0,0, 0,0, 0,0 };
+ bool is_ipv6_ll;
+#endif
struct ifaddrs *ifaddr, *ifa;
struct in46_addr netmask;
size_t count = 0;
- bool is_ipv6_ll;
if (getifaddrs(&ifaddr) == -1) {
return -1;
@@ -792,7 +800,7 @@
}
count++;
}
-
+#if defined(BUILD_IPv6)
if (ifa->ifa_addr->sa_family == AF_INET6 && (flags & IP_TYPE_IPv6)) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
struct sockaddr_in6 *netmask6 = (struct sockaddr_in6 *) ifa->ifa_netmask;
@@ -812,6 +820,7 @@
}
count++;
}
+#endif
}
freeifaddrs(ifaddr);
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index c31f875..10075d7 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -936,10 +936,12 @@
options.tx_gpdu_seq = 1;
/* PDP Type */
- if (!strcmp(args_info.pdp_type_arg, "v6"))
- options.pdp_type = PDP_EUA_TYPE_v6;
- else if (!strcmp(args_info.pdp_type_arg, "v4"))
+ if (!strcmp(args_info.pdp_type_arg, "v4"))
options.pdp_type = PDP_EUA_TYPE_v4;
+#if defined(BUILD_IPv6)
+ else if (!strcmp(args_info.pdp_type_arg, "v6"))
+ options.pdp_type = PDP_EUA_TYPE_v6;
+#endif
else {
SYS_ERR(DSGSN, LOGL_ERROR, 0, "Unsupported/unknown PDP Type '%s'\n",
args_info.pdp_type_arg);
@@ -955,6 +957,7 @@
}
+#if defined(BUILD_IPv6)
/* read a single value from a /procc file, up to 255 bytes, callee-allocated */
static char *proc_read(const char *path)
{
@@ -989,6 +992,7 @@
snprintf(path, sizeof(path), fmt, dev, file);
return proc_read(path);
}
+#endif
static char *print_ipprot(int t)
{
@@ -1323,8 +1327,10 @@
return 0;
}
+#if defined(BUILD_IPv6)
/* Link-Local address prefix fe80::/64 */
static const uint8_t ll_prefix[] = { 0xfe,0x80, 0,0, 0,0, 0,0 };
+#endif
/* Callback for receiving messages from tun */
static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
@@ -1332,7 +1338,9 @@
struct iphash_t *ipm;
struct in46_addr src;
struct iphdr *iph = (struct iphdr *)pack;
+#if defined(BUILD_IPv6)
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
+#endif
if (iph->version == 4) {
if (len < sizeof(*iph) || len < 4*iph->ihl) {
@@ -1341,6 +1349,7 @@
}
src.len = 4;
src.v4.s_addr = iph->saddr;
+#if defined(BUILD_IPv6)
} else if (iph->version == 6) {
/* We only have a single entry in the hash table, and it consists of the link-local
* address "fe80::prefix". So we need to make sure to convert non-link-local source
@@ -1355,6 +1364,7 @@
memcpy(&src.v6.s6_addr[0], ll_prefix, sizeof(ll_prefix));
memcpy(&src.v6.s6_addr[sizeof(ll_prefix)], ip6h->ip6_src.s6_addr, 16-sizeof(ll_prefix));
}
+#endif
} else {
printf("Dropping packet with invalid IP version %u\n", iph->version);
return 0;
@@ -1416,6 +1426,7 @@
in46a_ntoa(&addr));
switch (addr.len) {
+#if defined(BUILD_IPv6)
case 16: /* IPv6 */
/* we have to enable the kernel to perform stateless autoconfiguration,
* i.e. send a router solicitation using the lover 64bits of the allocated
@@ -1423,6 +1434,7 @@
memcpy(addr.v6.s6_addr, ll_prefix, sizeof(ll_prefix));
printf("Derived IPv6 link-local address: %s\n", in46a_ntoa(&addr));
break;
+#endif
case 4: /* IPv4 */
break;
}
@@ -1443,6 +1455,7 @@
tun_runscript(tun, options.ipup);
}
+#if defined(BUILD_IPv6)
/* now that ip-up has been executed, check if we are configured to
* accept router advertisements */
if (options.createif && options.pdp_type == PDP_EUA_TYPE_v6) {
@@ -1463,6 +1476,7 @@
free(accept_ra);
free(forwarding);
}
+#endif
ipset((struct iphash_t *)pdp->peer, &addr);
diff --git a/tests/lib/in46a_test.c b/tests/lib/in46a_test.c
index c0bb670..991c164 100644
--- a/tests/lib/in46a_test.c
+++ b/tests/lib/in46a_test.c
@@ -15,6 +15,8 @@
#include "../../lib/in46_addr.h"
#include "../../lib/syserr.h"
+#include "config.h"
+
static const struct in46_addr g_ia4 = {
.len = 4,
.v4.s_addr = 0x0d0c0b0a,
@@ -214,6 +216,8 @@
OSMO_ASSERT(len == 0);
}
+#if defined(BUILD_IPv6)
+
/* IPv6 specific tests */
static const struct in46_addr g_ia6 = {
@@ -353,6 +357,8 @@
OSMO_ASSERT(len == 0);
}
+#endif /* BUILD_IPv6 */
+
int main(int argc, char **argv)
{
osmo_init_logging(&log_info);
@@ -372,6 +378,7 @@
test_in46a_from_eua();
test_in46a_netmasklen();
} else {
+#if defined(BUILD_IPv6)
test_in46a_to_af_v6();
test_in46a_to_sas_v6();
test_in46a_ntop_v6();
@@ -379,6 +386,9 @@
test_in46a_to_eua_v6();
test_in46a_from_eua_v6();
test_in46a_netmasklen_v6();
+#else
+ return EXIT_FAILURE;
+#endif
}
return 0;
}
diff --git a/tests/lib/ippool_test.c b/tests/lib/ippool_test.c
index 8d3f46c..f55494b 100644
--- a/tests/lib/ippool_test.c
+++ b/tests/lib/ippool_test.c
@@ -12,6 +12,8 @@
#include "../../lib/ippool.h"
#include "../../lib/syserr.h"
+#include "config.h"
+
static struct ippool_t *create_pool(const char *prefix_str, unsigned int flags, char **blacklist, size_t blacklist_size)
{
@@ -118,11 +120,13 @@
test_pool_size("192.168.23.0/24", IPPOOL_NONETWORK | IPPOOL_NOBROADCAST, blacklist, 3, 253);
}
+#if defined(BUILD_IPv6)
static void test_pool_sizes_v6(void)
{
/* 256 prefixes of /64 each */
test_pool_size("2001:DB8::/56", 0, NULL, 0, 256);
}
+#endif /* BUILD_IPv6 */
int main(int argc, char **argv)
{
@@ -135,7 +139,11 @@
if (argc < 2 || strcmp(argv[1], "-v6")) {
test_pool_sizes();
} else {
+#if defined(BUILD_IPv6)
test_pool_sizes_v6();
+#else
+ return EXIT_FAILURE;
+#endif
}
return 0;
}
diff --git a/tests/testsuite.at b/tests/testsuite.at
index fa94db3..464a6e5 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -10,6 +10,7 @@
AT_SETUP([ippool_v6])
AT_KEYWORDS([ippool_v6])
+AT_SKIP_IF([! grep "#define BUILD_IPv6" $abs_top_builddir/config.h])
cat $abs_srcdir/lib/ippool_v6_test.ok > expout
cat $abs_srcdir/lib/ippool_v6_test.err > experr
AT_CHECK([$abs_top_builddir/tests/lib/ippool_test -v6], [], [expout], [experr])
@@ -23,6 +24,7 @@
AT_SETUP([in46a_v6])
AT_KEYWORDS([in46a_v6])
+AT_SKIP_IF([! grep "#define BUILD_IPv6" $abs_top_builddir/config.h])
cat $abs_srcdir/lib/in46a_v6_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/lib/in46a_test -v6], [], [expout], [])
AT_CLEANUP
--
To view, visit https://gerrit.osmocom.org/5121
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I651a12d63d025bde61dcbc3c6b949cd0fed43580
Gerrit-PatchSet: 2
Gerrit-Project: osmo-ggsn
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>