#include <sys/types.h>
#include <sys/socket.h>
-#include <net/ethernet.h>
-
-#ifdef linux
-#include <netinet/ether.h>
-#endif
#include <libubox/list.h>
[DEV_ATTR_TXQUEUELEN] = { .name = "txqueuelen", .type = BLOBMSG_TYPE_INT32 },
[DEV_ATTR_ENABLED] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL },
[DEV_ATTR_IPV6] = { .name = "ipv6", .type = BLOBMSG_TYPE_BOOL },
+ [DEV_ATTR_IP6SEGMENTROUTING] = { .name = "ip6segmentrouting", .type = BLOBMSG_TYPE_BOOL },
[DEV_ATTR_PROMISC] = { .name = "promisc", .type = BLOBMSG_TYPE_BOOL },
[DEV_ATTR_RPFILTER] = { .name = "rpfilter", .type = BLOBMSG_TYPE_STRING },
[DEV_ATTR_ACCEPTLOCAL] = { .name = "acceptlocal", .type = BLOBMSG_TYPE_BOOL },
device_free_unused(NULL);
}
+static int device_vlan_len(struct kvlist *kv, const void *data)
+{
+ return sizeof(unsigned int);
+}
+
+void device_vlan_update(bool done)
+{
+ struct device *dev;
+
+ avl_for_each_element(&devices, dev, avl) {
+ if (!dev->vlans.update)
+ continue;
+
+ if (!done) {
+ if (dev->vlan_aliases.get_len)
+ kvlist_free(&dev->vlan_aliases);
+ else
+ kvlist_init(&dev->vlan_aliases, device_vlan_len);
+ vlist_update(&dev->vlans);
+ } else {
+ vlist_flush(&dev->vlans);
+ }
+ }
+}
+
static int set_device_state(struct device *dev, bool state)
{
if (state) {
if (!dev->ifindex)
return -1;
+ system_if_get_settings(dev, &dev->orig_settings);
+ /* Only keep orig settings based on what needs to be set */
+ dev->orig_settings.valid_flags = dev->orig_settings.flags;
+ dev->orig_settings.flags &= dev->settings.flags;
+ system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
+
system_if_up(dev);
- }
- else
+ } else {
system_if_down(dev);
+ system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
+ }
return 0;
}
n->txqueuelen = s->flags & DEV_OPT_TXQUEUELEN ?
s->txqueuelen : os->txqueuelen;
memcpy(n->macaddr,
- (s->flags & DEV_OPT_MACADDR ? s->macaddr : os->macaddr),
+ (s->flags & (DEV_OPT_MACADDR|DEV_OPT_DEFAULT_MACADDR) ? s->macaddr : os->macaddr),
sizeof(n->macaddr));
n->ipv6 = s->flags & DEV_OPT_IPV6 ? s->ipv6 : os->ipv6;
+ n->ip6segmentrouting = s->flags & DEV_OPT_IP6SEGMENTROUTING ? s->ip6segmentrouting : os->ip6segmentrouting;
n->promisc = s->flags & DEV_OPT_PROMISC ? s->promisc : os->promisc;
n->rpfilter = s->flags & DEV_OPT_RPFILTER ? s->rpfilter : os->rpfilter;
n->acceptlocal = s->flags & DEV_OPT_ACCEPTLOCAL ? s->acceptlocal : os->acceptlocal;
s->flags |= DEV_OPT_IPV6;
}
+ if ((cur = tb[DEV_ATTR_IP6SEGMENTROUTING])) {
+ s->ip6segmentrouting = blobmsg_get_bool(cur);
+ s->flags |= DEV_OPT_IP6SEGMENTROUTING;
+ }
+
if ((cur = tb[DEV_ATTR_PROMISC])) {
s->promisc = blobmsg_get_bool(cur);
s->flags |= DEV_OPT_PROMISC;
safe_list_for_each(&dev->users, device_broadcast_cb, &dev_ev);
}
+static void
+device_fill_default_settings(struct device *dev)
+{
+ struct device_settings *s = &dev->settings;
+ struct ether_addr *ea;
+
+ if (!(s->flags & DEV_OPT_MACADDR)) {
+ ea = config_get_default_macaddr(dev->ifname);
+ if (ea) {
+ memcpy(s->macaddr, ea, 6);
+ s->flags |= DEV_OPT_DEFAULT_MACADDR;
+ }
+ }
+}
+
int device_claim(struct device_user *dep)
{
struct device *dev = dep->dev;
return 0;
device_broadcast_event(dev, DEV_EVENT_SETUP);
+ device_fill_default_settings(dev);
if (dev->external) {
/* Get ifindex for external claimed devices so a valid */
/* ifindex is in place avoiding possible race conditions */
{
struct device *dev;
- if (strchr(name, '.'))
+ dev = avl_find_element(&devices, name, dev, avl);
+
+ if (!dev && strchr(name, '.'))
return get_vlan_device_chain(name, create);
if (name[0] == '@')
return device_alias_get(name + 1);
- dev = avl_find_element(&devices, name, dev, avl);
if (dev) {
if (create > 1 && !dev->external) {
system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
}
}
+bool
+device_check_ip6segmentrouting(void)
+{
+ struct device *dev;
+ bool ip6segmentrouting = false;
+
+ avl_for_each_element(&devices, dev, avl)
+ ip6segmentrouting |= dev->settings.ip6segmentrouting;
+
+ return ip6segmentrouting;
+}
+
static enum dev_change_type
device_set_config(struct device *dev, struct device_type *type,
struct blob_attr *attr)
blobmsg_add_u32(b, "txqueuelen", st.txqueuelen);
if (st.flags & DEV_OPT_IPV6)
blobmsg_add_u8(b, "ipv6", st.ipv6);
+ if (st.flags & DEV_OPT_IP6SEGMENTROUTING)
+ blobmsg_add_u8(b, "ip6segmentrouting", st.ip6segmentrouting);
if (st.flags & DEV_OPT_PROMISC)
blobmsg_add_u8(b, "promisc", st.promisc);
if (st.flags & DEV_OPT_RPFILTER)