struct blob_attr *msg)
{
if (netifd_reload())
- return UBUS_STATUS_UNKNOWN_ERROR;
+ return UBUS_STATUS_NOT_FOUND;
return UBUS_STATUS_OK;
}
const char *name = blobmsg_get_string(tb[DI_NAME]);
- iface = interface_alloc(name, msg);
+ iface = interface_alloc(name, msg, true);
if (!iface)
return UBUS_STATUS_UNKNOWN_ERROR;
if (!config)
goto error;
- interface_add(iface, config);
-
- // need to look up the interface name again, in case of config update
- // the pointer will have changed
- iface = vlist_find(&interfaces, name, iface, node);
- if (!iface)
- return UBUS_STATUS_UNKNOWN_ERROR;
-
- // Set interface as dynamic
- interface_set_dynamic(iface);
+ if (!interface_add(iface, config))
+ goto error_free_config;
return UBUS_STATUS_OK;
+error_free_config:
+ free(config);
error:
free(iface);
return UBUS_STATUS_UNKNOWN_ERROR;
}
+enum {
+ NETNS_UPDOWN_JAIL,
+ NETNS_UPDOWN_PID,
+ NETNS_UPDOWN_START,
+ __NETNS_UPDOWN_MAX
+};
+
+static const struct blobmsg_policy netns_updown_policy[__NETNS_UPDOWN_MAX] = {
+ [NETNS_UPDOWN_JAIL] = { .name = "jail", .type = BLOBMSG_TYPE_STRING },
+ [NETNS_UPDOWN_PID] = { .name = "pid", .type = BLOBMSG_TYPE_INT32 },
+ [NETNS_UPDOWN_START] = { .name = "start", .type = BLOBMSG_TYPE_BOOL },
+};
+
+static int
+netifd_netns_updown(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct blob_attr *tb[__NETNS_UPDOWN_MAX];
+ char *jail;
+ pid_t netns_pid;
+ bool start;
+
+ blobmsg_parse(netns_updown_policy, __NETNS_UPDOWN_MAX, tb, blob_data(msg), blob_len(msg));
+ if (!tb[NETNS_UPDOWN_JAIL] || !tb[NETNS_UPDOWN_PID])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ start = tb[NETNS_UPDOWN_START] && blobmsg_get_bool(tb[NETNS_UPDOWN_START]);
+ jail = blobmsg_get_string(tb[NETNS_UPDOWN_JAIL]);
+ netns_pid = blobmsg_get_u32(tb[NETNS_UPDOWN_PID]);
+
+ if (start)
+ interface_start_jail(jail, netns_pid);
+ else
+ interface_stop_jail(jail, netns_pid);
+
+ return UBUS_STATUS_OK;
+}
+
static struct ubus_method main_object_methods[] = {
{ .name = "restart", .handler = netifd_handle_restart },
{ .name = "reload", .handler = netifd_handle_reload },
UBUS_METHOD("add_host_route", netifd_add_host_route, route_policy),
{ .name = "get_proto_handlers", .handler = netifd_get_proto_handlers },
UBUS_METHOD("add_dynamic", netifd_add_dynamic, dynamic_policy),
+ UBUS_METHOD("netns_updown", netifd_netns_updown, netns_updown_policy),
};
static struct ubus_object_type main_object_type =
if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
goto error;
- if (!blobmsg_check_attr(cur, NULL))
+ if (!blobmsg_check_attr(cur, false))
goto error;
alias_notify_device(blobmsg_data(cur), dev);
blobmsg_add_u32(&b, "mask", addr->mask);
+ if (addr->point_to_point) {
+ buf = blobmsg_alloc_string_buffer(&b, "ptpaddress", buflen);
+ inet_ntop(af, &addr->point_to_point, buf, buflen);
+ blobmsg_add_string_buffer(&b);
+ }
+
if (addr->preferred_until) {
int preferred = addr->preferred_until - now;
if (preferred < 0)
}
}
+static void
+interface_ip_dump_neighbor_list(struct interface_ip_settings *ip, bool enabled)
+{
+ struct device_neighbor *neighbor;
+ int buflen = 128;
+ char *buf;
+ void *r;
+ int af;
+
+ vlist_for_each_element(&ip->neighbor, neighbor, node) {
+ if (neighbor->enabled != enabled)
+ continue;
+
+ if ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
+ af = AF_INET;
+ else
+ af = AF_INET6;
+
+ r = blobmsg_open_table(&b, NULL);
+
+ if (neighbor->flags & DEVNEIGH_MAC)
+ blobmsg_add_string(&b, "mac", format_macaddr(neighbor->macaddr));
+
+ buf = blobmsg_alloc_string_buffer(&b , "address", buflen);
+ inet_ntop(af, &neighbor->addr, buf, buflen);
+ blobmsg_add_string_buffer(&b);
+
+ if (neighbor->proxy)
+ blobmsg_add_u32(&b, "proxy", neighbor->proxy);
+
+ if (neighbor->router)
+ blobmsg_add_u32(&b, "router", neighbor->router);
+
+ blobmsg_close_table(&b, r);
+ }
+}
+
static void
interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled)
{
inet_ntop(AF_INET6, &assign->addr, buf, buflen);
blobmsg_add_string_buffer(&b);
- blobmsg_add_u32(&b, "mask", assign->length < 64 ? 64 : assign->length);
+ blobmsg_add_u32(&b, "mask", assign->length);
}
blobmsg_close_table(&b, c);
!(iface->proto_handler->flags & PROTO_FLAG_NODEV))
blobmsg_add_string(&b, "device", dev->ifname);
+ if (iface->jail)
+ blobmsg_add_string(&b, "jail", iface->jail);
+
+ if (iface->jail_ifname)
+ blobmsg_add_string(&b, "jail_ifname", iface->jail_ifname);
+
if (iface->state == IFS_UP) {
if (iface->updated) {
a = blobmsg_open_array(&b, "updated");
interface_ip_dump_dns_search_list(&iface->config_ip, true);
interface_ip_dump_dns_search_list(&iface->proto_ip, true);
blobmsg_close_array(&b, a);
+ a = blobmsg_open_array(&b, "neighbors");
+ interface_ip_dump_neighbor_list(&iface->config_ip, true);
+ interface_ip_dump_neighbor_list(&iface->proto_ip, true);
+ blobmsg_close_array(&b, a);
inactive = blobmsg_open_table(&b, "inactive");
a = blobmsg_open_array(&b, "ipv4-address");
interface_ip_dump_dns_search_list(&iface->config_ip, false);
interface_ip_dump_dns_search_list(&iface->proto_ip, false);
blobmsg_close_array(&b, a);
+ a = blobmsg_open_array(&b, "neighbors");
+ interface_ip_dump_neighbor_list(&iface->config_ip, false);
+ interface_ip_dump_neighbor_list(&iface->proto_ip, false);
+ blobmsg_close_array(&b, a);
blobmsg_close_table(&b, inactive);
}
return wdev;
}
+static int
+netifd_handle_wdev_reconf(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct wireless_device *wdev;
+ int ret;
+
+ wdev = get_wdev(msg, &ret);
+ if (ret == UBUS_STATUS_NOT_FOUND)
+ return ret;
+
+ if (wdev) {
+ wireless_device_reconf(wdev);
+ } else {
+ vlist_for_each_element(&wireless_devices, wdev, node)
+ wireless_device_reconf(wdev);
+ }
+
+ return 0;
+}
+
static int
netifd_handle_wdev_up(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
static struct ubus_method wireless_object_methods[] = {
{ .name = "up", .handler = netifd_handle_wdev_up },
{ .name = "down", .handler = netifd_handle_wdev_down },
+ { .name = "reconf", .handler = netifd_handle_wdev_reconf },
{ .name = "status", .handler = netifd_handle_wdev_status },
{ .name = "notify", .handler = netifd_handle_wdev_notify },
{ .name = "get_validate", .handler = netifd_handle_wdev_get_validate },