Browse Source

wireless: fix passing bridge name for vlan hotplug pass-through

When preparing the interface for hotplug add, pass the bridge
device back to the caller, since it may not match the original device

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau 3 years ago
parent
commit
351d690f1a
6 changed files with 26 additions and 12 deletions
  1. 4 1
      bridge.c
  2. 1 1
      device.h
  3. 12 4
      ubus.c
  4. 2 2
      vlan.c
  5. 2 2
      vlandev.c
  6. 5 2
      wireless.c

+ 4 - 1
bridge.c

@@ -733,10 +733,13 @@ bridge_hotplug_del(struct device *dev, struct device *member)
 }
 
 static int
-bridge_hotplug_prepare(struct device *dev)
+bridge_hotplug_prepare(struct device *dev, struct device **bridge_dev)
 {
 	struct bridge_state *bst;
 
+	if (bridge_dev)
+		*bridge_dev = dev;
+
 	bst = container_of(dev, struct bridge_state, dev);
 	bst->force_active = true;
 	device_set_present(&bst->dev, true);

+ 1 - 1
device.h

@@ -226,7 +226,7 @@ struct device {
 };
 
 struct device_hotplug_ops {
-	int (*prepare)(struct device *dev);
+	int (*prepare)(struct device *dev, struct device **bridge_dev);
 	int (*add)(struct device *main, struct device *member, struct blob_attr *vlan);
 	int (*del)(struct device *main, struct device *member);
 };

+ 12 - 4
ubus.c

@@ -986,19 +986,27 @@ netifd_handle_iface_prepare(struct ubus_context *ctx, struct ubus_object *obj,
 			    struct blob_attr *msg)
 {
 	struct interface *iface;
-	struct device *dev;
+	struct device *dev, *bridge_dev = NULL;
 	const struct device_hotplug_ops *ops;
 
 	iface = container_of(obj, struct interface, ubus);
 	dev = iface->main_dev.dev;
 	if (!dev)
-		return 0;
+		goto out;
 
 	ops = dev->hotplug_ops;
 	if (!ops)
-		return 0;
+		goto out;
+
+	ops->prepare(dev, &bridge_dev);
+
+out:
+	blob_buf_init(&b, 0);
+	if (bridge_dev)
+		blobmsg_add_string(&b, "bridge", bridge_dev->ifname);
+	ubus_send_reply(ctx, req, b.head);
 
-	return ops->prepare(dev);
+	return 0;
 }
 
 static int

+ 2 - 2
vlan.c

@@ -69,7 +69,7 @@ vlan_hotplug_del(struct device *dev, struct device *member)
 }
 
 static int
-vlan_hotplug_prepare(struct device *dev)
+vlan_hotplug_prepare(struct device *dev, struct device **bridge_dev)
 {
 	struct vlan_device *vldev = container_of(dev, struct vlan_device, dev);
 
@@ -77,7 +77,7 @@ vlan_hotplug_prepare(struct device *dev)
 	if (!dev || !dev->hotplug_ops)
 		return UBUS_STATUS_NOT_SUPPORTED;
 
-	return dev->hotplug_ops->prepare(dev);
+	return dev->hotplug_ops->prepare(dev, bridge_dev);
 }
 
 static void vlan_hotplug_check(struct vlan_device *vldev, struct device *dev)

+ 2 - 2
vlandev.c

@@ -89,7 +89,7 @@ vlandev_hotplug_del(struct device *dev, struct device *member)
 }
 
 static int
-vlandev_hotplug_prepare(struct device *dev)
+vlandev_hotplug_prepare(struct device *dev, struct device **bridge_dev)
 {
 	struct vlandev_device *mvdev = container_of(dev, struct vlandev_device, dev);
 
@@ -97,7 +97,7 @@ vlandev_hotplug_prepare(struct device *dev)
 	if (!dev || !dev->hotplug_ops)
 		return UBUS_STATUS_NOT_SUPPORTED;
 
-	return dev->hotplug_ops->prepare(dev);
+	return dev->hotplug_ops->prepare(dev, bridge_dev);
 }
 
 static void vlandev_hotplug_check(struct vlandev_device *mvdev)

+ 5 - 2
wireless.c

@@ -136,7 +136,7 @@ vif_config_add_bridge(struct blob_buf *buf, struct blob_attr *networks, bool pre
 		if (!dev)
 			return;
 
-		if (!dev->type->bridge_capability)
+		if (!dev->hotplug_ops)
 			return;
 	}
 
@@ -144,7 +144,10 @@ vif_config_add_bridge(struct blob_buf *buf, struct blob_attr *networks, bool pre
 		return;
 
 	if (dev->hotplug_ops && dev->hotplug_ops->prepare)
-		dev->hotplug_ops->prepare(dev);
+		dev->hotplug_ops->prepare(dev, &dev);
+
+	if (!dev || !dev->type->bridge_capability)
+		return;
 
 	blobmsg_add_string(buf, "bridge", dev->ifname);