Skip to content
Snippets Groups Projects
config.c 52.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
    		ifname = uci_lookup_option_string(ctx, wl_s, "ifname");
    		if (!ifname)
    			continue;
    
    		config_generate_bsta_agent(cfg, ctx, device, ifname, band);
    	}
    
    	blob_buf_free(&bb);
    	uci_unload(ctx, pkg);
    	uci_free_context(ctx);
    	return 0;
    }
    
    
    int agent_config_init(struct agent_config *cfg)
    {
    	INIT_LIST_HEAD(&cfg->fhlist);
    	INIT_LIST_HEAD(&cfg->bklist);
    
    	INIT_LIST_HEAD(&cfg->radiolist);
    
    	INIT_LIST_HEAD(&cfg->steer_excludelist);
    	INIT_LIST_HEAD(&cfg->steer_btm_excludelist);
    
    	agent_config_prepare(cfg);
    
    	agent_config_reload(cfg);
    	return 0;
    }
    
    void clean_bk(struct netif_bkcfg *p)
    {
    	list_del(&p->list);
    	free(p);
    }
    
    int clean_all_bk(struct agent_config *cfg)
    {
    	struct netif_bkcfg *p, *tmp;
    
    	list_for_each_entry_safe(p, tmp, &cfg->bklist, list)
    		clean_bk(p);
    
    	return 0;
    }
    
    void clean_fh(struct netif_fhcfg *p)
    {
    	list_del(&p->list);
    	free(p);
    }
    
    int clean_all_fh(struct agent_config *cfg)
    {
    	struct netif_fhcfg *p, *tmp;
    
    	list_for_each_entry_safe(p, tmp, &cfg->fhlist, list)
    		clean_fh(p);
    
    	return 0;
    }
    
    int agent_config_clean(struct agent_config *cfg)
    {
    	clean_all_fh(cfg);
    	clean_all_bk(cfg);
    
    	clean_steer_btm_excl(cfg);
    	clean_steer_excl(cfg);
    
    	if (cfg->pcfg)
    		free(cfg->pcfg);
    
    
    int wifi_reorder_interfaces_by_device(struct agent_config *a,
    		struct uci_context *ctx, struct uci_package *pkg, char *device)
    {
    	int i, j = 0;
    	char ifname[16] = {0};
    	enum {
    		W_IFNAME,
    		NUM_POLICIES
    	};
    	const struct uci_parse_option opts[] = {
    		{ .name = "ifname", .type = UCI_TYPE_STRING }
    	};
    	struct uci_option *tb[NUM_POLICIES];
    	struct uci_element *e;
    
    	trace("reordering interfaces for device %s\n", device);
    
    	strncpy(ifname, device, sizeof(ifname));
    
    	for (i = 1; i < 16; i++) {
    		trace("iterating in search of %s\n", ifname);
    		uci_foreach_element(&pkg->sections, e) {
    			struct uci_section *s = uci_to_section(e);
    
    			if (strncmp(s->type, UCI_WLAN_IFACE,
    					strlen(UCI_WLAN_IFACE)))
    				continue;
    
    			uci_parse_section(s, opts, NUM_POLICIES, tb);
    
    			if (!tb[W_IFNAME])
    				continue;
    
    			if (strncmp(tb[W_IFNAME]->v.string, ifname, sizeof(ifname)))
    				continue;
    			trace("found interface %s, reordering to %d\n", ifname, j);
    			uci_reorder_section(ctx, s, j);
    			j++;
    			break;
    		}
    
    		snprintf(ifname, sizeof(ifname), "%s%s%d",
    				device,
    				(a->brcm_setup ? "." : "_"),
    				i);
    	}
    
    	return 0;
    }
    
    int wifi_reorder_interfaces(struct agent_config *a)
    {
    
    	struct uci_context *ctx;
    	struct uci_package *pkg;
    	struct uci_element *e;
    
    	ctx = uci_alloc_context();
    	if (!ctx)
    		return -1;
    
    	if (uci_load(ctx, UCI_WIRELESS, &pkg)) {
    		uci_free_context(ctx);
    		return -1;
    	}
    
    	uci_foreach_element(&pkg->sections, e) {
    		struct uci_section *s = uci_to_section(e);
    
    		if (strncmp(s->type, UCI_WL_DEVICE, strlen(UCI_WL_DEVICE)))
    			continue;
    
    		wifi_reorder_interfaces_by_device(a, ctx, pkg, s->e.name);
    	}
    
    	uci_commit(ctx, &pkg, false);
    	uci_free_context(ctx);
    	return 0;
    
    }
    
    int uci_set_bridge(char *config, char *bridge, char *proto, char *ipaddress)
    {
    	struct uci_context *ctx = NULL;
    	struct uci_package *pkg;
    	struct uci_element *e;
    	struct uci_section *section = NULL;
    
    	/** if bridge starts with br prefix, step past */
    	if (!strncmp(bridge, "br-", 3))
    		bridge += 3;
    
    	pkg = uci_load_pkg(&ctx, "network");
    	if (!pkg)
    		return -1;
    
    	uci_foreach_element(&pkg->sections, e) {
    		struct uci_section *s = uci_to_section(e);
    
    		if (strncmp(s->e.name, bridge, 16))
    			continue;
    
    		section = s;
    		break;
    	}
    
    	if (!section) {
    		struct uci_ptr ptr = {0};
    
    		ptr.p = pkg;
    		ptr.section = bridge;
    		ptr.value = "interface";
    		ptr.option = NULL;
    		uci_set(ctx, &ptr);
    		section = ptr.s;
    	}
    
    	set_value(ctx, pkg, section, "type", "bridge", UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "is_lan", "1", UCI_TYPE_STRING);
    	if (strlen(proto))
    		set_value(ctx, pkg, section, "proto", proto, UCI_TYPE_STRING);
    	if (!strcmp(proto, "static")) {
    		set_value(ctx, pkg, section, "ipaddr", ipaddress,
    				UCI_TYPE_STRING);
    		set_value(ctx, pkg, section, "netmask", "255.255.255.0",
    				UCI_TYPE_STRING);
    	}
    
    	uci_commit(ctx, &pkg, false);
    	uci_unload(ctx, pkg);
    	uci_free_context(ctx);
    	return false;
    }
    
    
    int uci_add_dhcp(char *iface)
    {
    	struct uci_context *ctx = NULL;
    	struct uci_package *pkg;
    	struct uci_element *e;
    	struct uci_section *section = NULL;
    	struct uci_ptr ptr = {0};
    
    	/** if bridge starts with br prefix, step past */
    	if (!strncmp(iface, "br-", 3))
    		iface += 3;
    
    	pkg = uci_load_pkg(&ctx, "dhcp");
    	if (!pkg)
    		return -1;
    
    	uci_foreach_element(&pkg->sections, e) {
    		struct uci_section *s = uci_to_section(e);
    
    		if (strncmp(s->e.name, iface, 16))
    			continue;
    
    		trace("Existing section found for ifname %s\n", iface);
    		goto out;
    	}
    
    	trace("Adding DHCP section for ifname %s\n", iface);
    
    	ptr.p = pkg;
    	ptr.section = iface;
    	ptr.value = "dhcp";
    	ptr.option = NULL;
    	uci_set(ctx, &ptr);
    	section = ptr.s;
    
    	set_value(ctx, pkg, section, "interface", iface, UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "start", "100", UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "limit", "150", UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "leasetime", "1h", UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "dhcpv6", "server", UCI_TYPE_STRING);
    	set_value(ctx, pkg, section, "ra", "server", UCI_TYPE_STRING);
    
    	uci_commit(ctx, &pkg, false);
    out:
    	uci_unload(ctx, pkg);
    	uci_free_context(ctx);
    	return false;
    }
    
    int uci_add_fw(struct agent_config *cfg, char *iface)
    {
    	struct uci_context *ctx = NULL;
    	struct uci_package *pkg;
    	struct uci_element *e;
    	struct uci_section *section = NULL;
    	int rv;
    
    	/** if bridge starts with br prefix, step past */
    	if (!strncmp(iface, "br-", 3))
    		iface += 3;
    
    	pkg = uci_load_pkg(&ctx, "firewall");
    	if (!pkg)
    		return -1;
    
    	section = config_get_section(ctx, pkg, "zone", "name", iface);
    	if (!section) {
    		trace("No fw section found for %s\n", iface);
    		rv = uci_add_section(ctx, pkg, "zone", &section);
    		if (rv)
    			goto out_pkg;
    
    		set_value(ctx, pkg, section, "name", iface, UCI_TYPE_STRING);
    		set_value(ctx, pkg, section, "network", iface, UCI_TYPE_LIST);
    		set_value(ctx, pkg, section, "input", "ACCEPT", UCI_TYPE_STRING);
    		set_value(ctx, pkg, section, "output", "ACCEPT", UCI_TYPE_STRING);
    		set_value(ctx, pkg, section, "forward", "ACCEPT", UCI_TYPE_STRING);
    		rv = uci_save(ctx, pkg);
    		if (rv)
    			goto out_pkg;
    		uci_commit(ctx, &pkg, false);
    	}
    
    	section = config_get_section(ctx, pkg, "forwarding", "src", iface);
    	if (!section) {
    		//section = config_add_section(ctx, pkg, "firewall", "forwarding", "src", iface);
    		//if (!section)
    		//	goto out;
    		rv = uci_add_section(ctx, pkg, "forwarding", &section);
    		if (rv)
    			goto out_pkg;
    
    		set_value(ctx, pkg, section, "src", iface, UCI_TYPE_STRING);
    		set_value(ctx, pkg, section, "dest", cfg->al_bridge, UCI_TYPE_STRING);
    		uci_commit(ctx, &pkg, false);
    	}
    
    out_pkg:
    	uci_unload(ctx, pkg);
    	uci_free_context(ctx);
    	return false;
    }