X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=device.c;h=6cdfb494d9baedd7346ed1c6d7a6fd362c6255d7;hb=19c53807d9dc62782d03c5564630ed1bcb953cd8;hp=f484c289e2c47311e272e408f63c555d2f835d03;hpb=98ca67469da70accd710b14c28e77be2126170a8;p=project%2Fnetifd.git diff --git a/device.c b/device.c index f484c28..6cdfb49 100644 --- a/device.c +++ b/device.c @@ -38,6 +38,10 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { [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_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 }, + [DEV_ATTR_IGMPVERSION] = { .name = "igmpversion", .type = BLOBMSG_TYPE_INT32 }, }; const struct uci_blob_param_list device_attr_list = { @@ -61,6 +65,17 @@ void device_unlock(void) static int set_device_state(struct device *dev, bool state) { + if (state) { + /* Set ifindex for all devices being enabled so a valid */ + /* ifindex is in place avoiding possible race conditions */ + device_set_ifindex(dev, system_if_resolve(dev)); + if (!dev->ifindex) + return -1; + } + + if (dev->external) + return 0; + if (state) system_if_up(dev); else @@ -141,6 +156,10 @@ device_merge_settings(struct device *dev, struct device_settings *n) (s->flags & DEV_OPT_MACADDR ? s->macaddr : os->macaddr), sizeof(n->macaddr)); n->ipv6 = s->flags & DEV_OPT_IPV6 ? s->ipv6 : os->ipv6; + 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; + n->igmpversion = s->flags & DEV_OPT_IGMPVERSION ? s->igmpversion : os->igmpversion; n->flags = s->flags | os->flags; } @@ -179,6 +198,30 @@ device_init_settings(struct device *dev, struct blob_attr **tb) s->flags |= DEV_OPT_IPV6; } + if ((cur = tb[DEV_ATTR_PROMISC])) { + s->promisc = blobmsg_get_bool(cur); + s->flags |= DEV_OPT_PROMISC; + } + + if ((cur = tb[DEV_ATTR_RPFILTER])) { + if (system_resolve_rpfilter(blobmsg_data(cur), &s->rpfilter)) + s->flags |= DEV_OPT_RPFILTER; + else + DPRINTF("Failed to resolve rpfilter: %s\n", (char *) blobmsg_data(cur)); + } + + if ((cur = tb[DEV_ATTR_ACCEPTLOCAL])) { + s->acceptlocal = blobmsg_get_bool(cur); + s->flags |= DEV_OPT_ACCEPTLOCAL; + } + + if ((cur = tb[DEV_ATTR_IGMPVERSION])) { + if (system_resolve_igmpversion(blobmsg_get_u32(cur), &s->igmpversion)) + s->flags |= DEV_OPT_IGMPVERSION; + else + DPRINTF("Failed to resolve igmpversion: %d\n", blobmsg_get_u32(cur)); + } + device_set_disabled(dev, disabled); } @@ -251,7 +294,7 @@ void device_release(struct device_user *dep) return; device_broadcast_event(dev, DEV_EVENT_TEARDOWN); - if (!dep->hotplug) + if (!dev->external) dev->set_state(dev, false); device_broadcast_event(dev, DEV_EVENT_DOWN); } @@ -259,7 +302,7 @@ void device_release(struct device_user *dep) int device_check_state(struct device *dev) { if (!dev->type->check_state) - return 0; + return simple_device_type.check_state(dev); return dev->type->check_state(dev); } @@ -714,6 +757,14 @@ device_dump_status(struct blob_buf *b, struct device *dev) 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_PROMISC) + blobmsg_add_u8(b, "promisc", st.promisc); + if (st.flags & DEV_OPT_RPFILTER) + blobmsg_add_u32(b, "rpfilter", st.rpfilter); + if (st.flags & DEV_OPT_ACCEPTLOCAL) + blobmsg_add_u8(b, "acceptlocal", st.acceptlocal); + if (st.flags & DEV_OPT_IGMPVERSION) + blobmsg_add_u32(b, "igmpversion", st.igmpversion); } s = blobmsg_open_table(b, "statistics");