From: Alin Năstac Date: Tue, 17 Jan 2017 15:16:04 +0000 (+0100) Subject: netifd: Add option to configure locktime for each device X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=commitdiff_plain;h=f1076561f4cd4e391ca654d76498b0429413c61e netifd: Add option to configure locktime for each device The UCI parameter neighlocktime allows to control the hardware address to IP mapping lock time in the IPv4 neighbour table. The IPv6 lock time was not set because it is not used at all in any kernel versions, hardware address override being controlled in this case by the override flag present in the NA packet. Signed-off-by: Alin Nastac --- diff --git a/device.c b/device.c index 43881e5..306496c 100644 --- a/device.c +++ b/device.c @@ -59,6 +59,7 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { [DEV_ATTR_LEARNING] = { .name ="learning", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_UNICAST_FLOOD] = { .name ="unicast_flood", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_SENDREDIRECTS] = { .name = "sendredirects", .type = BLOBMSG_TYPE_BOOL }, + [DEV_ATTR_NEIGHLOCKTIME] = { .name = "neighlocktime", .type = BLOBMSG_TYPE_INT32 }, }; const struct uci_blob_param_list device_attr_list = { @@ -217,6 +218,8 @@ device_merge_settings(struct device *dev, struct device_settings *n) s->neigh4gcstaletime : os->neigh4gcstaletime; n->neigh6gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ? s->neigh6gcstaletime : os->neigh6gcstaletime; + n->neigh4locktime = s->flags & DEV_OPT_NEIGHLOCKTIME ? + s->neigh4locktime : os->neigh4locktime; n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ? s->dadtransmits : os->dadtransmits; n->multicast = s->flags & DEV_OPT_MULTICAST ? @@ -314,6 +317,11 @@ device_init_settings(struct device *dev, struct blob_attr **tb) s->flags |= DEV_OPT_NEIGHGCSTALETIME; } + if ((cur = tb[DEV_ATTR_NEIGHLOCKTIME])) { + s->neigh4locktime = blobmsg_get_u32(cur); + s->flags |= DEV_OPT_NEIGHLOCKTIME; + } + if ((cur = tb[DEV_ATTR_RPS])) { s->rps = blobmsg_get_bool(cur); s->flags |= DEV_OPT_RPS; @@ -1044,6 +1052,8 @@ device_dump_status(struct blob_buf *b, struct device *dev) blobmsg_add_u32(b, "neigh4gcstaletime", st.neigh4gcstaletime); blobmsg_add_u32(b, "neigh6gcstaletime", st.neigh6gcstaletime); } + if (st.flags & DEV_OPT_NEIGHLOCKTIME) + blobmsg_add_u32(b, "neigh4locktime", st.neigh4locktime); if (st.flags & DEV_OPT_DADTRANSMITS) blobmsg_add_u32(b, "dadtransmits", st.dadtransmits); if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST) diff --git a/device.h b/device.h index 87236d4..feb865f 100644 --- a/device.h +++ b/device.h @@ -51,6 +51,7 @@ enum { DEV_ATTR_UNICAST_FLOOD, DEV_ATTR_NEIGHGCSTALETIME, DEV_ATTR_SENDREDIRECTS, + DEV_ATTR_NEIGHLOCKTIME, __DEV_ATTR_MAX, }; @@ -103,6 +104,7 @@ enum { DEV_OPT_NEIGHGCSTALETIME = (1 << 19), DEV_OPT_MULTICAST_FAST_LEAVE = (1 << 20), DEV_OPT_SENDREDIRECTS = (1 << 21), + DEV_OPT_NEIGHLOCKTIME = (1 << 22), }; /* events broadcasted to all users of a device */ @@ -160,6 +162,7 @@ struct device_settings { unsigned int neigh6reachabletime; unsigned int neigh4gcstaletime; unsigned int neigh6gcstaletime; + unsigned int neigh4locktime; bool rps; bool xps; unsigned int dadtransmits; diff --git a/system-linux.c b/system-linux.c index e0cb5bc..f4d6c25 100644 --- a/system-linux.c +++ b/system-linux.c @@ -316,6 +316,11 @@ static void system_set_neigh6gcstaletime(struct device *dev, const char *val) system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time", dev->ifname, val); } +static void system_set_neigh4locktime(struct device *dev, const char *val) +{ + system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime", dev->ifname, val); +} + static void system_set_dadtransmits(struct device *dev, const char *val) { system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", dev->ifname, val); @@ -484,6 +489,12 @@ static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const siz dev->ifname, buf, buf_sz); } +static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz) +{ + return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime", + dev->ifname, buf, buf_sz); +} + static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz) { return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", @@ -1345,6 +1356,11 @@ system_if_get_settings(struct device *dev, struct device_settings *s) s->flags |= DEV_OPT_NEIGHREACHABLETIME; } + if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) { + s->neigh4locktime = strtoul(buf, NULL, 0); + s->flags |= DEV_OPT_NEIGHLOCKTIME; + } + if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) { s->neigh4gcstaletime = strtoul(buf, NULL, 0); s->flags |= DEV_OPT_NEIGHGCSTALETIME; @@ -1454,6 +1470,10 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned snprintf(buf, sizeof(buf), "%d", s->neigh6reachabletime); system_set_neigh6reachabletime(dev, buf); } + if (s->flags & DEV_OPT_NEIGHLOCKTIME & apply_mask) { + snprintf(buf, sizeof(buf), "%d", s->neigh4locktime); + system_set_neigh4locktime(dev, buf); + } if (s->flags & DEV_OPT_NEIGHGCSTALETIME & apply_mask) { snprintf(buf, sizeof(buf), "%d", s->neigh4gcstaletime); system_set_neigh4gcstaletime(dev, buf);