aboutsummaryrefslogtreecommitdiffstats
path: root/sgsnemu/sgsnemu.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-10-10 09:36:35 +0800
committerHarald Welte <laforge@gnumonks.org>2017-10-14 16:39:07 +0200
commit081f30cba4ff6c38f3a135e77856f49e4a0c6e0b (patch)
tree5b37b1a5c56f975dc736a8ff2b461a5113a32c28 /sgsnemu/sgsnemu.c
parent9d9d91b8e8cb291d5337a68c54654dcc40d2826a (diff)
sgsnemu: Print warnings on broken IPv6 configuration (acept_ra)
When sgsnemu is used for an IPv6 pdp context, we rely on the router discovery procedure and SLAAC to set the correct IPv6 address/prefix on the tun device. This requires the system to be configure to accept router-advertisements on the tun device. Let's print a warning if accept_ra for the specific tun device is set to a wrong value. We're leaving it up to the user to either set a system-wide /proc/sys/net/ipv6/conf/default/accept_ra or to configure this in an ip-up script used together with sgsnemu. Change-Id: I563092ca35bc74f035a5023e11256779aac46e11
Diffstat (limited to 'sgsnemu/sgsnemu.c')
-rw-r--r--sgsnemu/sgsnemu.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index c83aebd..a85c9cf 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -968,6 +968,42 @@ int encaps_printf(struct pdp_t *pdp, void *pack, unsigned len)
return 0;
}
+/* read a single value from a /procc file, up to 255 bytes, callee-allocated */
+static char *proc_read(const char *path)
+{
+ char *ret = NULL;
+ FILE *f;
+
+ f = fopen(path, "r");
+ if (!f)
+ return NULL;
+
+ ret = malloc(256);
+ if (!ret)
+ goto out;
+
+ if (!fgets(ret, 256, f)) {
+ free(ret);
+ ret = NULL;
+ goto out;
+ }
+ return ret;
+
+out:
+ fclose(f);
+ return ret;
+}
+
+/* Read value of a /proc/sys/net/ipv6/conf file for given device.
+ * Memory is dynamically allocated, caller must free it later. */
+static char *proc_ipv6_conf_read(const char *dev, const char *file)
+{
+ const char *fmt = "/proc/sys/net/ipv6/conf/%s/%s";
+ char path[strlen(fmt) + strlen(dev) + strlen(file)];
+ snprintf(path, sizeof(path), fmt, dev, file);
+ return proc_read(path);
+}
+
char *print_ipprot(int t)
{
switch (t) {
@@ -1425,6 +1461,27 @@ int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
tun_runscript(tun, options.ipup);
}
+ /* 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) {
+ char *accept_ra, *forwarding;
+
+ accept_ra = proc_ipv6_conf_read(tun->devname, "accept_ra");
+ forwarding = proc_ipv6_conf_read(tun->devname, "forwarding");
+ if (!accept_ra || !forwarding)
+ printf("Could not open proc file for %s ?!?\n", tun->devname);
+ else {
+ if (!strcmp(accept_ra, "0") ||
+ (!strcmp(forwarding, "1") && !strcmp(accept_ra, "1"))) {
+ printf("%s is %s, i.e. your tun device is not configured to accept "
+ "router advertisements; SLAAC will not suceed, please "
+ "fix your setup!\n");
+ }
+ free(accept_ra);
+ free(forwarding);
+ }
+ }
+
ipset((struct iphash_t *)pdp->peer, &addr);
state = 2; /* Connected */