+static void
+interface_set_route_info(struct interface *iface, struct device_route *route)
+{
+ bool v6 = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET6);
+
+ if (!iface)
+ return;
+
+ if (!(route->flags & DEVROUTE_METRIC))
+ route->metric = iface->metric;
+
+ if (!(route->flags & DEVROUTE_TABLE)) {
+ route->table = (v6) ? iface->ip6table : iface->ip4table;
+ if (route->table)
+ route->flags |= DEVROUTE_SRCTABLE;
+ }
+}
+
+void
+interface_ip_add_neighbor(struct interface *iface, struct blob_attr *attr, bool v6)
+{
+ struct interface_ip_settings *ip;
+ struct blob_attr *tb[__NEIGHBOR_MAX], *cur;
+ struct device_neighbor *neighbor;
+ int af = v6 ? AF_INET6: AF_INET;
+ struct ether_addr *ea;
+
+ blobmsg_parse(neighbor_attr, __NEIGHBOR_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));
+
+ if (!iface) {
+ if ((cur = tb[NEIGHBOR_INTERFACE]) == NULL)
+ return;
+
+ iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
+
+ if (!iface)
+ return;
+
+ ip = &iface->config_ip;
+ } else
+ ip = &iface->proto_ip;
+
+ neighbor = calloc(1,sizeof(*neighbor));
+ if (!neighbor)
+ return;
+
+ neighbor->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4;
+
+ if ((cur = tb[NEIGHBOR_ADDRESS]) != NULL){
+ if (!inet_pton(af, blobmsg_data(cur), &neighbor->addr))
+ goto error;
+ } else
+ goto error;
+
+ if ((cur = tb[NEIGHBOR_MAC]) != NULL) {
+ neighbor->flags |= DEVNEIGH_MAC;
+ ea = ether_aton(blobmsg_data(cur));
+ if (!ea)
+ goto error;
+
+ memcpy(neighbor->macaddr, ea, 6);
+ }
+
+ if ((cur = tb[NEIGHBOR_PROXY]) != NULL)
+ neighbor->proxy = blobmsg_get_bool(cur);
+
+ if ((cur = tb[NEIGHBOR_ROUTER]) != NULL)
+ neighbor->router = blobmsg_get_bool(cur);
+
+ vlist_add(&ip->neighbor, &neighbor->node, neighbor);
+ return;
+
+error:
+ free(neighbor);
+}
+