diff options
-rw-r--r-- | ggsn/ggsn.c | 17 | ||||
-rw-r--r-- | ggsn/ggsn.h | 1 | ||||
-rw-r--r-- | ggsn/ggsn_vty.c | 20 |
3 files changed, 37 insertions, 1 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index ef2357b..3e095f0 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -241,13 +241,28 @@ int apn_start(struct apn_ctx *apn) } } + if (apn->v6.cfg.ll_prefix.addr.len) { + LOGPAPN(LOGL_INFO, apn, "Setting tun IPv6 link-local address %s\n", + in46p_ntoa(&apn->v6.cfg.ll_prefix)); + if (tun_addaddr(apn->tun.tun, &apn->v6.cfg.ll_prefix.addr, NULL, + apn->v6.cfg.ll_prefix.prefixlen)) { + LOGPAPN(LOGL_ERROR, apn, "Failed to set tun IPv6 link-local address %s: %s. " + "Ensure you have ipv6 support and not used the disable_ipv6 sysctl?\n", + in46p_ntoa(&apn->v6.cfg.ll_prefix), strerror(errno)); + apn_stop(apn, false); + return -1; + } + apn->v6_lladdr = apn->v6.cfg.ll_prefix.addr.v6; + } + 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 (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) { + if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6) && + apn->v6.cfg.ll_prefix.addr.len == 0) { rc = tun_ip_local_get(apn->tun.tun, &ipv6_tun_linklocal_ip, 1, IP_TYPE_IPv6_LINK); if (rc < 1) { LOGPAPN(LOGL_ERROR, apn, "Cannot obtain IPv6 link-local address of interface: %s\n", diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h index c0774c4..e252548 100644 --- a/ggsn/ggsn.h +++ b/ggsn/ggsn.h @@ -22,6 +22,7 @@ struct ggsn_ctx; struct apn_ctx_ip { struct { struct in46_prefix ifconfig_prefix; + struct in46_prefix ll_prefix; struct in46_prefix static_prefix; struct in46_prefix dynamic_prefix; /* v4 DNS server names */ diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c index 6e15ae4..db392fa 100644 --- a/ggsn/ggsn_vty.c +++ b/ggsn/ggsn_vty.c @@ -513,6 +513,24 @@ DEFUN(cfg_apn_no_ipv6_ifconfig, cfg_apn_no_ipv6_ifconfig_cmd, return CMD_SUCCESS; } +DEFUN(cfg_apn_ipv6_linklocal, cfg_apn_ipv6_linklocal_cmd, + "ipv6 link-local X:X::X:X/M", + IP6_STR IFCONFIG_STR "IPv6 Link-local Adress/Prefix-Length\n") +{ + struct apn_ctx *apn = (struct apn_ctx *) vty->index; + str2prefix(&apn->v6.cfg.ll_prefix, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_apn_no_ipv6_linklocal, cfg_apn_no_ipv6_linklocal_cmd, + "no ipv6 link-local", + NO_STR IP6_STR IFCONFIG_STR) +{ + struct apn_ctx *apn = (struct apn_ctx *) vty->index; + memset(&apn->v6.cfg.ll_prefix, 0, sizeof(apn->v6.cfg.ll_prefix)); + return CMD_SUCCESS; +} + #define DNS_STRINGS "Configure DNS Server\n" "primary/secondary DNS\n" "IP address of DNS Sever\n" DEFUN(cfg_apn_ip_dns, cfg_apn_ip_dns_cmd, @@ -893,6 +911,8 @@ int ggsn_vty_init(void) install_element(APN_NODE, &cfg_apn_no_ip_ifconfig_cmd); install_element(APN_NODE, &cfg_apn_ipv6_ifconfig_cmd); install_element(APN_NODE, &cfg_apn_no_ipv6_ifconfig_cmd); + install_element(APN_NODE, &cfg_apn_ipv6_linklocal_cmd); + install_element(APN_NODE, &cfg_apn_no_ipv6_linklocal_cmd); install_element(APN_NODE, &cfg_apn_gpdu_seq_cmd); install_element(APN_NODE, &cfg_apn_no_gpdu_seq_cmd); |