From 5316d7f8bdcd8dd29286e98404a4f4fd2456500f Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Sun, 29 Apr 2018 22:30:00 +0200 Subject: [PATCH] ra: always trigger update in case of RA parameter change Always launch a ra-updated event in case the RA hoplimit/mtu/reachable/ retransmit parameters change Signed-off-by: Hans Dedecker --- src/odhcp6c.h | 8 +++--- src/ra.c | 74 ++++++++++++++++++++++++++++++++++----------------- src/script.c | 8 +++--- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/odhcp6c.h b/src/odhcp6c.h index e41aa3c..3abe7b7 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -349,10 +349,10 @@ int init_rtnetlink(void); int set_rtnetlink_addr(int ifindex, const struct in6_addr *addr, uint32_t pref, uint32_t valid); -int ra_conf_hoplimit(int newvalue); -int ra_conf_mtu(int newvalue); -int ra_conf_reachable(int newvalue); -int ra_conf_retransmit(int newvalue); +int ra_get_hoplimit(void); +int ra_get_mtu(void); +int ra_get_reachable(void); +int ra_get_retransmit(void); int script_init(const char *path, const char *ifname); ssize_t script_unhexlify(uint8_t *dst, size_t len, const char *src); diff --git a/src/ra.c b/src/ra.c index c1f3d03..898f449 100644 --- a/src/ra.c +++ b/src/ra.c @@ -58,6 +58,10 @@ static volatile int rs_attempt = 0; static struct in6_addr lladdr = IN6ADDR_ANY_INIT; static unsigned int ra_options = 0; static unsigned int ra_holdoff_interval = 0; +static int ra_hoplimit = 0; +static int ra_mtu = 0; +static int ra_reachable = 0; +static int ra_retransmit = 0; struct { struct icmp6_hdr hdr; @@ -272,44 +276,64 @@ static bool ra_icmpv6_valid(struct sockaddr_in6 *source, int hlim, uint8_t *data return opt == end; } -int ra_conf_hoplimit(int newvalue) +static bool ra_set_hoplimit(int val) { - static int value = 0; - - if (newvalue > 0) - value = newvalue; + if (val > 0 && val != ra_hoplimit) { + ra_hoplimit = val; + return true; + } - return value; + return false; } -int ra_conf_mtu(int newvalue) +static bool ra_set_mtu(int val) { - static int value = 0; + if (val >= 1280 && val <= 65535 && ra_mtu != val) { + ra_mtu = val; + return true; + } - if (newvalue >= 1280 && newvalue <= 65535) - value = newvalue; + return false; +} + +static bool ra_set_reachable(int val) +{ + if (val > 0 && val <= 3600000 && ra_reachable != val) { + ra_reachable = val; + return true; + } - return value; + return false; } -int ra_conf_reachable(int newvalue) +static bool ra_set_retransmit(int val) { - static int value = 0; + if (val > 0 && val <= 60000 && ra_retransmit != val) { + ra_retransmit = val; + return true; + } - if (newvalue > 0 && newvalue <= 3600000) - value = newvalue; + return false; +} - return value; +int ra_get_hoplimit(void) +{ + return ra_hoplimit; } -int ra_conf_retransmit(int newvalue) +int ra_get_mtu(void) { - static int value = 0; + return ra_mtu; +} - if (newvalue > 0 && newvalue <= 60000) - value = newvalue; +int ra_get_reachable(void) +{ + return ra_reachable; +} - return value; +int ra_get_retransmit(void) +{ + return ra_retransmit; } bool ra_process(void) @@ -397,18 +421,18 @@ bool ra_process(void) 0, ra_holdoff_interval); // Parse hoplimit - ra_conf_hoplimit(adv->nd_ra_curhoplimit); + changed |= ra_set_hoplimit(adv->nd_ra_curhoplimit); // Parse ND parameters - ra_conf_reachable(ntohl(adv->nd_ra_reachable)); - ra_conf_retransmit(ntohl(adv->nd_ra_retransmit)); + changed |= ra_set_reachable(ntohl(adv->nd_ra_reachable)); + changed |= ra_set_retransmit(ntohl(adv->nd_ra_retransmit)); // Evaluate options struct icmpv6_opt *opt; icmpv6_for_each_option(opt, &adv[1], &buf[len]) { if (opt->type == ND_OPT_MTU) { uint32_t *mtu = (uint32_t*)&opt->data[2]; - ra_conf_mtu(ntohl(*mtu)); + changed |= ra_set_mtu(ntohl(*mtu)); } else if (opt->type == ND_OPT_ROUTE_INFORMATION && opt->len <= 3) { struct icmpv6_opt_route_info *ri = (struct icmpv6_opt_route_info *)opt; diff --git a/src/script.c b/src/script.c index fcdbb27..f32d4e2 100644 --- a/src/script.c +++ b/src/script.c @@ -478,10 +478,10 @@ void script_call(const char *status, int delay, bool resume) entry_to_env("RA_DNS", ra_dns, ra_dns_len, ENTRY_HOST); search_to_env("RA_DOMAINS", ra_search, ra_search_len); - int_to_env("RA_HOPLIMIT", ra_conf_hoplimit(0)); - int_to_env("RA_MTU", ra_conf_mtu(0)); - int_to_env("RA_REACHABLE", ra_conf_reachable(0)); - int_to_env("RA_RETRANSMIT", ra_conf_retransmit(0)); + int_to_env("RA_HOPLIMIT", ra_get_hoplimit()); + int_to_env("RA_MTU", ra_get_mtu()); + int_to_env("RA_REACHABLE", ra_get_reachable()); + int_to_env("RA_RETRANSMIT", ra_get_retransmit()); char *buf = malloc(10 + passthru_len * 2); strncpy(buf, "PASSTHRU=", 10); -- 2.25.1