2
0
Эх сурвалжийг харах

netifd: Reload proto on topology change

Introduce a new device event "topology change" that gets signaled
by bridges on adding/removing members.

On "topology changes" the proto handlers are requested to "renew"
which is most useful for DHCP.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Helmut Schaa 10 жил өмнө
parent
commit
3d317e90f1
9 өөрчлөгдсөн 40 нэмэгдсэн , 1 устгасан
  1. 4 0
      bridge.c
  2. 3 0
      device.h
  3. 5 0
      interface.c
  4. 8 0
      proto-shell.c
  5. 1 0
      proto-static.c
  6. 3 0
      proto.c
  7. 3 0
      proto.h
  8. 9 1
      scripts/netifd-proto.sh
  9. 4 0
      vlan.c

+ 4 - 0
bridge.c

@@ -140,6 +140,8 @@ bridge_disable_member(struct bridge_member *bm)
 	system_bridge_delif(&bst->dev, bm->dev.dev);
 	device_release(&bm->dev);
 
+	device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
 	return 0;
 }
 
@@ -162,6 +164,8 @@ bridge_enable_member(struct bridge_member *bm)
 		goto error;
 	}
 
+	device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
 	return 0;
 
 error:

+ 3 - 0
device.h

@@ -78,6 +78,9 @@ enum device_event {
 	DEV_EVENT_LINK_UP,
 	DEV_EVENT_LINK_DOWN,
 
+	/* Topology changed (i.e. bridge member added) */
+	DEV_EVENT_TOPO_CHANGE,
+
 	__DEV_EVENT_MAX
 };
 

+ 5 - 0
interface.c

@@ -328,6 +328,9 @@ interface_cb(struct device_user *dep, enum device_event ev)
         case DEV_EVENT_LINK_DOWN:
 		interface_set_link_state(iface, new_state);
 		break;
+	case DEV_EVENT_TOPO_CHANGE:
+		interface_proto_event(iface->proto, PROTO_CMD_RENEW, false);
+		return;
 	default:
 		break;
 	}
@@ -599,6 +602,8 @@ interface_proto_cb(struct interface_proto_state *state, enum interface_proto_eve
 		mark_interface_down(iface);
 		iface->state = IFS_SETUP;
 		break;
+	default:
+		return;
 	}
 
 	interface_write_resolv_conf();

+ 8 - 0
proto-shell.c

@@ -159,6 +159,10 @@ proto_shell_handler(struct interface_proto_state *proto,
 		state->last_error = -1;
 		proto_shell_clear_host_dep(state);
 		state->sm = S_SETUP;
+	} else if (cmd == PROTO_CMD_RENEW) {
+		if (!(handler->proto.flags & PROTO_FLAG_RENEW_AVAILABLE))
+			return 0;
+		action = "renew";
 	} else {
 		if (state->sm == S_TEARDOWN)
 			return 0;
@@ -761,6 +765,10 @@ proto_shell_add_handler(const char *script, const char *name, json_object *obj)
 	if (tmp && json_object_get_boolean(tmp))
 		handler->proto.flags |= PROTO_FLAG_INIT_AVAILABLE;
 
+	tmp = json_get_field(obj, "renew-handler", json_type_boolean);
+	if (tmp && json_object_get_boolean(tmp))
+		handler->proto.flags |= PROTO_FLAG_RENEW_AVAILABLE;
+
 	config = json_get_field(obj, "config", json_type_array);
 	if (config)
 		handler->config_buf = netifd_handler_parse_config(&handler->config, config);

+ 1 - 0
proto-static.c

@@ -52,6 +52,7 @@ static_handler(struct interface_proto_state *proto,
 
 		break;
 	case PROTO_CMD_TEARDOWN:
+	case PROTO_CMD_RENEW:
 		break;
 	}
 

+ 3 - 0
proto.c

@@ -615,6 +615,9 @@ interface_proto_event(struct interface_proto_state *proto,
 	case PROTO_CMD_TEARDOWN:
 		ev = IFPEV_DOWN;
 		break;
+	case PROTO_CMD_RENEW:
+		ev = IFPEV_RENEW;
+		break;
 	default:
 		return -EINVAL;
 	}

+ 3 - 0
proto.h

@@ -22,17 +22,20 @@ enum interface_proto_event {
 	IFPEV_UP,
 	IFPEV_DOWN,
 	IFPEV_LINK_LOST,
+	IFPEV_RENEW,
 };
 
 enum interface_proto_cmd {
 	PROTO_CMD_SETUP,
 	PROTO_CMD_TEARDOWN,
+	PROTO_CMD_RENEW,
 };
 
 enum {
 	PROTO_FLAG_IMMEDIATE = (1 << 0),
 	PROTO_FLAG_NODEV = (1 << 1),
 	PROTO_FLAG_INIT_AVAILABLE = (1 << 2),
+	PROTO_FLAG_RENEW_AVAILABLE = (1 << 3),
 };
 
 struct interface_proto_state {

+ 9 - 1
scripts/netifd-proto.sh

@@ -20,6 +20,11 @@ _proto_do_teardown() {
 	eval "proto_$1_teardown \"$interface\" \"$ifname\""
 }
 
+_proto_do_renew() {
+	json_load "$data"
+	eval "proto_$1_renew \"$interface\" \"$ifname\""
+}
+
 _proto_do_setup() {
 	json_load "$data"
 	_EXPORT_VAR=0
@@ -352,6 +357,7 @@ init_proto() {
 			add_protocol() {
 				no_device=0
 				available=0
+				renew_handler=0
 
 				add_default_handler "proto_$1_init_config"
 
@@ -362,10 +368,11 @@ init_proto() {
 				json_close_array
 				json_add_boolean no-device "$no_device"
 				json_add_boolean available "$available"
+				json_add_boolean renew-handler "$renew_handler"
 				json_dump
 			}
 		;;
-		setup|teardown)
+		setup|teardown|renew)
 			interface="$1"; shift
 			data="$1"; shift
 			ifname="$1"; shift
@@ -376,6 +383,7 @@ init_proto() {
 				case "$cmd" in
 					setup) _proto_do_setup "$1";;
 					teardown) _proto_do_teardown "$1" ;;
+					renew) _proto_do_renew "$1" ;;
 					*) return 1 ;;
 				esac
 			}

+ 4 - 0
vlan.c

@@ -88,6 +88,10 @@ static void vlan_dev_cb(struct device_user *dep, enum device_event ev)
 		vlan_dev_set_name(vldev, dep->dev);
 		device_broadcast_event(&vldev->dev, ev);
 		break;
+	case DEV_EVENT_TOPO_CHANGE:
+		/* Propagate topo changes */
+		device_broadcast_event(&vldev->dev, DEV_EVENT_TOPO_CHANGE);
+		break;
 	default:
 		break;
 	}