Browse Source

system-linux: add device options used by wpad

Add device options used by wpad in preparation of running hostapd and
wpa_supplicant non-root (and hence those options will need to be taken
care of by netifd as sysctl is root-only):
 * drop_v4_unicast_in_l2_multicast
 * drop_v6_unicast_in_l2_multicast
 * drop_gratuitous_arp
 * drop_unsolicited_na
 * arp_accept

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Daniel Golle 3 years ago
parent
commit
c84f3b02fc
3 changed files with 156 additions and 0 deletions
  1. 50 0
      device.c
  2. 15 0
      device.h
  3. 91 0
      system-linux.c

+ 50 - 0
device.c

@@ -54,6 +54,11 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
 	[DEV_ATTR_SENDREDIRECTS] = { .name = "sendredirects", .type = BLOBMSG_TYPE_BOOL },
 	[DEV_ATTR_NEIGHLOCKTIME] = { .name = "neighlocktime", .type = BLOBMSG_TYPE_INT32 },
 	[DEV_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v4_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v6_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_DROP_GRATUITOUS_ARP] = { .name = "drop_gratuitous_arp", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_DROP_UNSOLICITED_NA] = { .name = "drop_unsolicited_na", .type = BLOBMSG_TYPE_BOOL },
+	[DEV_ATTR_ARP_ACCEPT] = { .name = "arp_accept", .type = BLOBMSG_TYPE_BOOL },
 };
 
 const struct uci_blob_param_list device_attr_list = {
@@ -255,6 +260,16 @@ device_merge_settings(struct device *dev, struct device_settings *n)
 	n->unicast_flood = s->unicast_flood;
 	n->sendredirects = s->flags & DEV_OPT_SENDREDIRECTS ?
 		s->sendredirects : os->sendredirects;
+	n->drop_v4_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST ?
+		s->drop_v4_unicast_in_l2_multicast : os->drop_v4_unicast_in_l2_multicast;
+	n->drop_v6_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST ?
+		s->drop_v6_unicast_in_l2_multicast : os->drop_v6_unicast_in_l2_multicast;
+	n->drop_gratuitous_arp = s->flags & DEV_OPT_DROP_GRATUITOUS_ARP ?
+		s->drop_gratuitous_arp : os->drop_gratuitous_arp;
+	n->drop_unsolicited_na = s->flags & DEV_OPT_DROP_UNSOLICITED_NA ?
+		s->drop_unsolicited_na : os->drop_unsolicited_na;
+	n->arp_accept = s->flags & DEV_OPT_ARP_ACCEPT ?
+		s->arp_accept : os->arp_accept;
 	n->flags = s->flags | os->flags | os->valid_flags;
 }
 
@@ -399,6 +414,31 @@ device_init_settings(struct device *dev, struct blob_attr **tb)
 		s->flags |= DEV_OPT_ISOLATE;
 	}
 
+	if ((cur = tb[DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST])) {
+		s->drop_v4_unicast_in_l2_multicast = blobmsg_get_bool(cur);
+		s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST;
+	}
+
+	if ((cur = tb[DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST])) {
+		s->drop_v6_unicast_in_l2_multicast = blobmsg_get_bool(cur);
+		s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST;
+	}
+
+	if ((cur = tb[DEV_ATTR_DROP_GRATUITOUS_ARP])) {
+		s->drop_gratuitous_arp = blobmsg_get_bool(cur);
+		s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP;
+	}
+
+	if ((cur = tb[DEV_ATTR_DROP_UNSOLICITED_NA])) {
+		s->drop_unsolicited_na = blobmsg_get_bool(cur);
+		s->flags |= DEV_OPT_DROP_UNSOLICITED_NA;
+	}
+
+	if ((cur = tb[DEV_ATTR_ARP_ACCEPT])) {
+		s->arp_accept = blobmsg_get_bool(cur);
+		s->flags |= DEV_OPT_ARP_ACCEPT;
+	}
+
 	device_set_disabled(dev, disabled);
 }
 
@@ -1107,6 +1147,16 @@ device_dump_status(struct blob_buf *b, struct device *dev)
 			blobmsg_add_u8(b, "unicast_flood", st.unicast_flood);
 		if (st.flags & DEV_OPT_SENDREDIRECTS)
 			blobmsg_add_u8(b, "sendredirects", st.sendredirects);
+		if (st.flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST)
+			blobmsg_add_u8(b, "drop_v4_unicast_in_l2_multicast", st.drop_v4_unicast_in_l2_multicast);
+		if (st.flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST)
+			blobmsg_add_u8(b, "drop_v6_unicast_in_l2_multicast", st.drop_v6_unicast_in_l2_multicast);
+		if (st.flags & DEV_OPT_DROP_GRATUITOUS_ARP)
+			blobmsg_add_u8(b, "drop_gratuitous_arp", st.drop_gratuitous_arp);
+		if (st.flags & DEV_OPT_DROP_UNSOLICITED_NA)
+			blobmsg_add_u8(b, "drop_unsolicited_na", st.drop_unsolicited_na);
+		if (st.flags & DEV_OPT_ARP_ACCEPT)
+			blobmsg_add_u8(b, "arp_accept", st.arp_accept);
 	}
 
 	s = blobmsg_open_table(b, "statistics");

+ 15 - 0
device.h

@@ -54,6 +54,11 @@ enum {
 	DEV_ATTR_NEIGHLOCKTIME,
 	DEV_ATTR_ISOLATE,
 	DEV_ATTR_IP6SEGMENTROUTING,
+	DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST,
+	DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST,
+	DEV_ATTR_DROP_GRATUITOUS_ARP,
+	DEV_ATTR_DROP_UNSOLICITED_NA,
+	DEV_ATTR_ARP_ACCEPT,
 	__DEV_ATTR_MAX,
 };
 
@@ -109,6 +114,11 @@ enum {
 	DEV_OPT_NEIGHLOCKTIME		= (1 << 22),
 	DEV_OPT_ISOLATE			= (1 << 23),
 	DEV_OPT_IP6SEGMENTROUTING	= (1 << 24),
+	DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST = (1 << 25),
+	DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST = (1 << 26),
+	DEV_OPT_DROP_GRATUITOUS_ARP	= (1 << 27),
+	DEV_OPT_DROP_UNSOLICITED_NA	= (1 << 28),
+	DEV_OPT_ARP_ACCEPT		= (1 << 29),
 };
 
 /* events broadcasted to all users of a device */
@@ -177,6 +187,11 @@ struct device_settings {
 	bool sendredirects;
 	bool ip6segmentrouting;
 	bool isolate;
+	bool drop_v4_unicast_in_l2_multicast;
+	bool drop_v6_unicast_in_l2_multicast;
+	bool drop_gratuitous_arp;
+	bool drop_unsolicited_na;
+	bool arp_accept;
 };
 
 /*

+ 91 - 0
system-linux.c

@@ -364,6 +364,31 @@ static void system_set_sendredirects(struct device *dev, const char *val)
 	system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", dev->ifname, val);
 }
 
+static void system_set_drop_v4_unicast_in_l2_multicast(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/drop_unicast_in_l2_multicast", dev->ifname, val);
+}
+
+static void system_set_drop_v6_unicast_in_l2_multicast(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/drop_unicast_in_l2_multicast", dev->ifname, val);
+}
+
+static void system_set_drop_gratuitous_arp(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/drop_gratuitous_arp", dev->ifname, val);
+}
+
+static void system_set_drop_unsolicited_na(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/drop_unsolicited_na", dev->ifname, val);
+}
+
+static void system_set_arp_accept(struct device *dev, const char *val)
+{
+	system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/arp_accept", dev->ifname, val);
+}
+
 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
 {
 	system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val);
@@ -586,6 +611,37 @@ static int system_get_sendredirects(struct device *dev, char *buf, const size_t
 			dev->ifname, buf, buf_sz);
 }
 
+
+static int system_get_drop_v4_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/drop_unicast_in_l2_multicast",
+			dev->ifname, buf, buf_sz);
+}
+
+static int system_get_drop_v6_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/drop_unicast_in_l2_multicast",
+			dev->ifname, buf, buf_sz);
+}
+
+static int system_get_drop_gratuitous_arp(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/drop_gratuitous_arp",
+			dev->ifname, buf, buf_sz);
+}
+
+static int system_get_drop_unsolicited_na(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/drop_unsolicited_na",
+			dev->ifname, buf, buf_sz);
+}
+
+static int system_get_arp_accept(struct device *dev, char *buf, const size_t buf_sz)
+{
+	return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/arp_accept",
+			dev->ifname, buf, buf_sz);
+}
+
 /* Evaluate netlink messages */
 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
 {
@@ -1650,6 +1706,31 @@ system_if_get_settings(struct device *dev, struct device_settings *s)
 		s->sendredirects = strtoul(buf, NULL, 0);
 		s->flags |= DEV_OPT_SENDREDIRECTS;
 	}
+
+	if (!system_get_drop_v4_unicast_in_l2_multicast(dev, buf, sizeof(buf))) {
+		s->drop_v4_unicast_in_l2_multicast = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST;
+	}
+
+	if (!system_get_drop_v6_unicast_in_l2_multicast(dev, buf, sizeof(buf))) {
+		s->drop_v6_unicast_in_l2_multicast = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST;
+	}
+
+	if (!system_get_drop_gratuitous_arp(dev, buf, sizeof(buf))) {
+		s->drop_gratuitous_arp = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP;
+	}
+
+	if (!system_get_drop_unsolicited_na(dev, buf, sizeof(buf))) {
+		s->drop_unsolicited_na = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_DROP_UNSOLICITED_NA;
+	}
+
+	if (!system_get_arp_accept(dev, buf, sizeof(buf))) {
+		s->arp_accept = strtoul(buf, NULL, 0);
+		s->flags |= DEV_OPT_ARP_ACCEPT;
+	}
 }
 
 void
@@ -1738,6 +1819,16 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned
 	}
 	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)
+		system_set_drop_v4_unicast_in_l2_multicast(dev, s->drop_v4_unicast_in_l2_multicast ? "1" : "0");
+	if (apply_mask & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST)
+		system_set_drop_v6_unicast_in_l2_multicast(dev, s->drop_v6_unicast_in_l2_multicast ? "1" : "0");
+	if (apply_mask & DEV_OPT_DROP_GRATUITOUS_ARP)
+		system_set_drop_gratuitous_arp(dev, s->drop_gratuitous_arp ? "1" : "0");
+	if (apply_mask & DEV_OPT_DROP_UNSOLICITED_NA)
+		system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : "0");
+	if (apply_mask & DEV_OPT_ARP_ACCEPT)
+		system_set_arp_accept(dev, s->arp_accept ? "1" : "0");
 }
 
 int system_if_up(struct device *dev)