diff mbox series

netifd: add accept_ra support

Message ID 20221009181242.35944-1-vincent@systemli.org
State Rejected, archived
Headers show
Series netifd: add accept_ra support | expand

Commit Message

Nick Oct. 9, 2022, 6:12 p.m. UTC
Make the "Accept Router Advertisements" configurable. This is needed if
you do not want to use odhcp6c and let the kernel handle the RAs. This
can save some diskspace.

Possible values are:
  0: Do not accept RA
  1: Accept RA if forwarding is disabled
  2: Accept RA even if forwarding is enabled

Signed-off-by: Nick Hainke <vincent@systemli.org>
---
 device.c       |  9 +++++++++
 device.h       |  3 +++
 system-linux.c | 20 ++++++++++++++++++++
 3 files changed, 32 insertions(+)

Comments

Jo-Philipp Wich Oct. 9, 2022, 6:23 p.m. UTC | #1
Hi,

> Make the "Accept Router Advertisements" configurable. This is needed if
> you do not want to use odhcp6c and let the kernel handle the RAs. This
> can save some diskspace.

NACK from me. As it will interfere with odhcp6c operation in the default setup
I don't think that it is a good idea to expose this in uci. Given that this is
a nonstandard setup anyway you can as well set this value in sysctl directly.

~ Jo
diff mbox series

Patch

diff --git a/device.c b/device.c
index b3d0e85..88a192f 100644
--- a/device.c
+++ b/device.c
@@ -63,6 +63,7 @@  static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
 	[DEV_ATTR_AUTH] = { .name = "auth", .type = BLOBMSG_TYPE_BOOL },
 	[DEV_ATTR_SPEED] = { .name = "speed", .type = BLOBMSG_TYPE_INT32 },
 	[DEV_ATTR_DUPLEX] = { .name = "duplex", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_ACCEPT_RA] = { .name = "accept_ra", .type = BLOBMSG_TYPE_INT32 },
 };
 
 const struct uci_blob_param_list device_attr_list = {
@@ -280,6 +281,7 @@  device_merge_settings(struct device *dev, struct device_settings *n)
 	n->auth = s->flags & DEV_OPT_AUTH ? s->auth : os->auth;
 	n->speed = s->flags & DEV_OPT_SPEED ? s->speed : os->speed;
 	n->duplex = s->flags & DEV_OPT_DUPLEX ? s->duplex : os->duplex;
+	n->accept_ra = s->flags & DEV_OPT_ACCEPT_RA ? s->accept_ra : os->accept_ra;
 	n->flags = s->flags | os->flags | os->valid_flags;
 }
 
@@ -464,6 +466,11 @@  device_init_settings(struct device *dev, struct blob_attr **tb)
 		s->flags |= DEV_OPT_DUPLEX;
 	}
 
+	if ((cur = tb[DEV_ATTR_ACCEPT_RA])) {
+		s->accept_ra = blobmsg_get_u32(cur);
+		s->flags |= DEV_OPT_ACCEPT_RA;
+	}
+
 	device_set_disabled(dev, disabled);
 }
 
@@ -1210,6 +1217,8 @@  device_dump_status(struct blob_buf *b, struct device *dev)
 			blobmsg_add_u8(b, "arp_accept", st.arp_accept);
 		if (st.flags & DEV_OPT_AUTH)
 			blobmsg_add_u8(b, "auth", st.auth);
+		if (st.flags & DEV_OPT_ACCEPT_RA)
+			blobmsg_add_u32(b, "accept_ra", st.accept_ra);
 	}
 
 	s = blobmsg_open_table(b, "statistics");
diff --git a/device.h b/device.h
index 37f8c37..dc0d57b 100644
--- a/device.h
+++ b/device.h
@@ -62,6 +62,7 @@  enum {
 	DEV_ATTR_AUTH,
 	DEV_ATTR_SPEED,
 	DEV_ATTR_DUPLEX,
+	DEV_ATTR_ACCEPT_RA,
 	__DEV_ATTR_MAX,
 };
 
@@ -126,6 +127,7 @@  enum {
 	DEV_OPT_ARP_ACCEPT		= (1ULL << 29),
 	DEV_OPT_SPEED			= (1ULL << 30),
 	DEV_OPT_DUPLEX			= (1ULL << 31),
+	DEV_OPT_ACCEPT_RA		= (1ULL << 32),
 };
 
 /* events broadcasted to all users of a device */
@@ -203,6 +205,7 @@  struct device_settings {
 	bool auth;
 	unsigned int speed;
 	bool duplex;
+	unsigned int accept_ra;
 };
 
 /*
diff --git a/system-linux.c b/system-linux.c
index 0f13a99..1697f1f 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -390,6 +390,11 @@  static void system_set_acceptlocal(struct device *dev, const char *val)
 	system_set_dev_sysctl("ipv4/conf", "accept_local", dev->ifname, val);
 }
 
+static void system_set_accept_ra(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("ipv6/conf", "accept_ra", dev->ifname, val);
+}
+
 static void system_set_igmpversion(struct device *dev, const char *val)
 {
 	system_set_dev_sysctl("ipv4/conf", "force_igmp_version", dev->ifname, val);
@@ -621,6 +626,12 @@  static int system_get_arp_accept(struct device *dev, char *buf, const size_t buf
 			dev->ifname, buf, buf_sz);
 }
 
+static int system_get_accept_ra(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("ipv6/conf", "accept_ra",
+				     dev->ifname, buf, buf_sz);
+}
+
 /* Evaluate netlink messages */
 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
 {
@@ -1795,6 +1806,11 @@  system_if_get_settings(struct device *dev, struct device_settings *s)
 		s->arp_accept = strtoul(buf, NULL, 0);
 		s->flags |= DEV_OPT_ARP_ACCEPT;
 	}
+
+	if (!system_get_accept_ra(dev, buf, sizeof(buf))) {
+		s->accept_ra = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_ACCEPT_RA;
+	}
 }
 
 void
@@ -1881,6 +1897,10 @@  system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t
 				    !s->multicast ? IFF_MULTICAST : 0) < 0)
 			s->flags &= ~DEV_OPT_MULTICAST;
 	}
+	if (apply_mask & DEV_OPT_ACCEPT_RA) {
+		snprintf(buf, sizeof(buf), "%u", s->accept_ra);
+		system_set_accept_ra(dev, buf);
+	}
 	if (apply_mask & DEV_OPT_SENDREDIRECTS)
 		system_set_sendredirects(dev, s->sendredirects ? "1" : "0");
 	if (apply_mask & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST)