system_bridge_delif(&bst->dev, bm->dev.dev);
device_release(&bm->dev);
+ device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
return 0;
}
goto error;
}
+ device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
return 0;
error:
DEV_EVENT_LINK_UP,
DEV_EVENT_LINK_DOWN,
+ /* Topology changed (i.e. bridge member added) */
+ DEV_EVENT_TOPO_CHANGE,
+
__DEV_EVENT_MAX
};
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;
}
mark_interface_down(iface);
iface->state = IFS_SETUP;
break;
+ default:
+ return;
}
interface_write_resolv_conf();
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;
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);
break;
case PROTO_CMD_TEARDOWN:
+ case PROTO_CMD_RENEW:
break;
}
case PROTO_CMD_TEARDOWN:
ev = IFPEV_DOWN;
break;
+ case PROTO_CMD_RENEW:
+ ev = IFPEV_RENEW;
+ break;
default:
return -EINVAL;
}
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 {
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
add_protocol() {
no_device=0
available=0
+ renew_handler=0
add_default_handler "proto_$1_init_config"
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
case "$cmd" in
setup) _proto_do_setup "$1";;
teardown) _proto_do_teardown "$1" ;;
+ renew) _proto_do_renew "$1" ;;
*) return 1 ;;
esac
}
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;
}