[PATCH] netifd: add accept_ra support

Nick Hainke vincent at systemli.org
Sun Oct 9 11:12:42 PDT 2022


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 at systemli.org>
---
 device.c       |  9 +++++++++
 device.h       |  3 +++
 system-linux.c | 20 ++++++++++++++++++++
 3 files changed, 32 insertions(+)

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)
-- 
2.38.0




More information about the openwrt-devel mailing list