+ s->neigh6reachabletime : os->neigh6reachabletime;
+ n->neigh4gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
+ s->neigh4gcstaletime : os->neigh4gcstaletime;
+ n->neigh6gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
+ s->neigh6gcstaletime : os->neigh6gcstaletime;
+ n->neigh4locktime = s->flags & DEV_OPT_NEIGHLOCKTIME ?
+ s->neigh4locktime : os->neigh4locktime;
+ n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ?
+ s->dadtransmits : os->dadtransmits;
+ n->multicast = s->flags & DEV_OPT_MULTICAST ?
+ s->multicast : os->multicast;
+ n->multicast_to_unicast = s->multicast_to_unicast;
+ n->multicast_router = s->multicast_router;
+ n->multicast_fast_leave = s->multicast_fast_leave;
+ n->learning = s->learning;
+ n->unicast_flood = s->unicast_flood;
+ n->sendredirects = s->flags & DEV_OPT_SENDREDIRECTS ?
+ s->sendredirects : os->sendredirects;
+ n->drop_v4_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST ?
+ s->drop_v4_unicast_in_l2_multicast : os->drop_v4_unicast_in_l2_multicast;
+ n->drop_v6_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST ?
+ s->drop_v6_unicast_in_l2_multicast : os->drop_v6_unicast_in_l2_multicast;
+ n->drop_gratuitous_arp = s->flags & DEV_OPT_DROP_GRATUITOUS_ARP ?
+ s->drop_gratuitous_arp : os->drop_gratuitous_arp;
+ n->drop_unsolicited_na = s->flags & DEV_OPT_DROP_UNSOLICITED_NA ?
+ s->drop_unsolicited_na : os->drop_unsolicited_na;
+ n->arp_accept = s->flags & DEV_OPT_ARP_ACCEPT ?
+ s->arp_accept : os->arp_accept;
+ n->auth = s->flags & DEV_OPT_AUTH ? s->auth : os->auth;
+ n->speed = s->flags & DEV_OPT_SPEED ? s->speed : os->speed;
+ n->duplex = s->flags & DEV_OPT_DUPLEX ? s->duplex : os->duplex;
+ n->pause = s->flags & DEV_OPT_PAUSE ? s->pause : os->pause;
+ n->asym_pause = s->flags & DEV_OPT_ASYM_PAUSE ? s->asym_pause : os->asym_pause;
+ n->rxpause = s->flags & DEV_OPT_RXPAUSE ? s->rxpause : os->rxpause;
+ n->txpause = s->flags & DEV_OPT_TXPAUSE ? s->txpause : os->txpause;
+ n->autoneg = s->flags & DEV_OPT_AUTONEG ? s->autoneg : os->autoneg;
+ n->gro = s->flags & DEV_OPT_GRO ? s->gro : os->gro;
+ n->eee = s->flags & DEV_OPT_EEE ? s->eee : os->eee;
+ n->master_ifindex = s->flags & DEV_OPT_MASTER ? s->master_ifindex : os->master_ifindex;
+ n->flags = s->flags | os->flags | os->valid_flags;
+}
+
+static bool device_fill_vlan_range(struct device_vlan_range *r, const char *val)
+{
+ unsigned long cur_start, cur_end;
+ char *sep;
+
+ cur_start = strtoul(val, &sep, 0);
+ cur_end = cur_start;
+
+ if (*sep == '-')
+ cur_end = strtoul(sep + 1, &sep, 0);
+ if (*sep || cur_end < cur_start)
+ return false;
+
+ r->start = cur_start;
+ r->end = cur_end;
+
+ return true;
+}
+
+static void
+device_set_extra_vlans(struct device *dev, struct blob_attr *data)
+{
+ struct blob_attr *cur;
+ int n_vlans;
+ size_t rem;
+
+ dev->n_extra_vlan = 0;
+ if (!data)
+ return;
+
+ n_vlans = blobmsg_check_array(data, BLOBMSG_TYPE_STRING);
+ if (n_vlans < 1)
+ return;
+
+ dev->extra_vlan = realloc(dev->extra_vlan, n_vlans * sizeof(*dev->extra_vlan));
+ blobmsg_for_each_attr(cur, data, rem)
+ if (device_fill_vlan_range(&dev->extra_vlan[dev->n_extra_vlan],
+ blobmsg_get_string(cur)))
+ dev->n_extra_vlan++;