summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2019-05-17 21:29:25 +0200
committerHans Dedecker <dedeckeh@gmail.com>2019-05-17 21:29:25 +0200
commitd11180932b2fb8784aaad0830c032e42b8bb64ac (patch)
tree0f0cc379a264e7bb2c903067785f0d16069ab19a
parent41a74cba1bec349d1e1c5be4442e7fddb2d4adf7 (diff)
router: make RA flags configurable (FS#2019)
Replace the config option ra_management by the config options ra_flags and ra_slaac. The latter allows to configure the autonomous-address config flag used for stateless address configuration while the former allows to configure the RA flags in the form of a list. The list can hold the following values : managed-config other-config home-agent none Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--README6
-rw-r--r--src/config.c55
-rw-r--r--src/dhcpv6-ia.c2
-rw-r--r--src/odhcpd.h15
-rw-r--r--src/router.c9
5 files changed, 64 insertions, 23 deletions
diff --git a/README b/README
index a379c4c..a5ed319 100644
--- a/README
+++ b/README
@@ -111,8 +111,10 @@ limit integer 150 DHCPv4 pool size
ra_default integer 0 Override default route
0: default, 1: ignore no public address, 2: ignore all
-ra_management integer 1 RA management mode
- 0: no M-Flag but A-Flag, 1: both M and A, 2: M but not A
+ra_flags list other-config List of RA flags to be
+ advertised in RA messages
+ [managed-config other-config home-agent none]
+ra_slaac bool 1 Announce slaac for a prefix
ra_offlink bool 0 Announce prefixes off-link
ra_preference string medium Route(r) preference
[medium|high|low]
diff --git a/src/config.c b/src/config.c
index 3f64d16..53528a0 100644
--- a/src/config.c
+++ b/src/config.c
@@ -59,7 +59,8 @@ enum {
IFACE_ATTR_DHCPV6_PD,
IFACE_ATTR_DHCPV6_NA,
IFACE_ATTR_RA_DEFAULT,
- IFACE_ATTR_RA_MANAGEMENT,
+ IFACE_ATTR_RA_FLAGS,
+ IFACE_ATTR_RA_SLAAC,
IFACE_ATTR_RA_OFFLINK,
IFACE_ATTR_RA_PREFERENCE,
IFACE_ATTR_RA_ADVROUTER,
@@ -106,7 +107,8 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
[IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 },
- [IFACE_ATTR_RA_MANAGEMENT] = { .name = "ra_management", .type = BLOBMSG_TYPE_INT32 },
+ [IFACE_ATTR_RA_FLAGS] = { .name = "ra_flags", . type = BLOBMSG_TYPE_ARRAY },
+ [IFACE_ATTR_RA_SLAAC] = { .name = "ra_slaac", .type = BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_RA_OFFLINK] = { .name = "ra_offlink", .type = BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_RA_PREFERENCE] = { .name = "ra_preference", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_RA_ADVROUTER] = { .name = "ra_advrouter", .type = BLOBMSG_TYPE_BOOL },
@@ -182,6 +184,14 @@ const struct uci_blob_param_list odhcpd_attr_list = {
.params = odhcpd_attrs,
};
+static const struct { const char *name; uint8_t flag; } ra_flags[] = {
+ { .name = "managed-config", .flag = ND_RA_FLAG_MANAGED },
+ { .name = "other-config", .flag = ND_RA_FLAG_OTHER },
+ { .name = "home-agent", .flag = ND_RA_FLAG_HOME_AGENT },
+ { .name = "none", . flag = 0 },
+ { .name = NULL, },
+};
+
static int mkdir_p(char *dir, mode_t mask)
{
char *l = strrchr(dir, '/');
@@ -221,7 +231,8 @@ static void set_interface_defaults(struct interface *iface)
iface->dhcpv6_assignall = true;
iface->dhcpv6_pd = true;
iface->dhcpv6_na = true;
- iface->ra_managed = RA_MANAGED_MFLAG;
+ iface->ra_flags = ND_RA_FLAG_OTHER;
+ iface->ra_slaac = true;
iface->ra_maxinterval = 600;
iface->ra_mininterval = iface->ra_maxinterval/3;
iface->ra_lifetime = -1;
@@ -273,6 +284,34 @@ static int parse_mode(const char *mode)
return -1;
}
+static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr)
+{
+ struct blob_attr *cur;
+ unsigned rem;
+
+ blobmsg_for_each_attr(cur, attr, rem) {
+ int i;
+
+ if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
+ continue;
+
+ if (!blobmsg_check_attr(cur, false))
+ continue;
+
+ for (i = 0; ra_flags[i].name; i++) {
+ if (!strcmp(ra_flags[i].name, blobmsg_get_string(cur))) {
+ *flags |= ra_flags[i].flag;
+ break;
+ }
+ }
+
+ if (!ra_flags[i].name)
+ return -1;
+ }
+
+ return 0;
+}
+
static void set_config(struct uci_section *s)
{
struct blob_attr *tb[ODHCPD_ATTR_MAX], *c;
@@ -695,8 +734,11 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
if ((c = tb[IFACE_ATTR_RA_DEFAULT]))
iface->default_router = blobmsg_get_u32(c);
- if ((c = tb[IFACE_ATTR_RA_MANAGEMENT]))
- iface->ra_managed = blobmsg_get_u32(c);
+ if ((c = tb[IFACE_ATTR_RA_FLAGS])) {
+ iface->ra_flags = 0;
+ if (parse_ra_flags(&iface->ra_flags, c) < 0)
+ goto err;
+ }
if ((c = tb[IFACE_ATTR_RA_REACHABLETIME])) {
uint32_t ra_reachabletime = blobmsg_get_u32(c);
@@ -730,6 +772,9 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
iface->ra_mtu = ra_mtu;
}
+ if ((c = tb[IFACE_ATTR_RA_SLAAC]))
+ iface->ra_slaac = blobmsg_get_bool(c);
+
if ((c = tb[IFACE_ATTR_RA_OFFLINK]))
iface->ra_not_onlink = blobmsg_get_bool(c);
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index c0dfa2d..55b3cd4 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -687,7 +687,7 @@ static void handle_addrlist_change(struct netevent_handler_info *info)
time_t now = odhcpd_time();
list_for_each_entry(c, &iface->ia_assignments, head) {
- if (c != border && iface->ra_managed == RA_MANAGED_NO_MFLAG
+ if (c != border && !(iface->ra_flags & ND_RA_FLAG_MANAGED)
&& (c->flags & OAF_BOUND))
__apply_lease(iface, c, info->addrs_old.addrs,
info->addrs_old.len, false);
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 37a5a4a..8715ca7 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -246,6 +246,13 @@ struct interface {
bool master;
bool ignore;
bool always_rewrite_dns;
+
+ // NDP
+ int learn_routes;
+
+ // RA
+ uint8_t ra_flags;
+ bool ra_slaac;
bool ra_not_onlink;
bool ra_advrouter;
bool ra_useleasetime;
@@ -253,11 +260,7 @@ struct interface {
bool no_dynamic_dhcp;
uint8_t pio_filter_length;
struct in6_addr pio_filter_addr;
-
- // RA
- int learn_routes;
int default_router;
- int ra_managed;
int route_preference;
int ra_maxinterval;
int ra_mininterval;
@@ -303,10 +306,6 @@ struct interface {
extern struct avl_tree interfaces;
-#define RA_MANAGED_NO_MFLAG 0
-#define RA_MANAGED_MFLAG 1
-#define RA_MANAGED_NO_AFLAG 2
-
inline static void free_assignment(struct dhcp_assignment *a)
{
list_del(&a->head);
diff --git a/src/router.c b/src/router.c
index 63571a3..5032428 100644
--- a/src/router.c
+++ b/src/router.c
@@ -436,12 +436,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
if (hlim > 0)
adv.h.nd_ra_curhoplimit = hlim;
- if (iface->dhcpv6 != MODE_DISABLED) {
- adv.h.nd_ra_flags_reserved = ND_RA_FLAG_OTHER;
-
- if (iface->ra_managed >= RA_MANAGED_MFLAG)
- adv.h.nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
- }
+ adv.h.nd_ra_flags_reserved = iface->ra_flags;
if (iface->route_preference < 0)
adv.h.nd_ra_flags_reserved |= ND_RA_PREF_LOW;
@@ -558,7 +553,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
p->nd_opt_pi_flags_reserved = 0;
if (!iface->ra_not_onlink)
p->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
- if (iface->ra_managed < RA_MANAGED_NO_AFLAG && addr->prefix <= 64)
+ if (iface->ra_slaac && addr->prefix <= 64)
p->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
if (iface->ra_advrouter)
p->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;