mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 01:52:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			117 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "udevmand.h"
 | |
| 
 | |
| enum {
 | |
| 	INTERFACE_DEVICE,
 | |
| 	INTERFACE_IFACE,
 | |
| 	__INTERFACE_MAX
 | |
| };
 | |
| 
 | |
| static const struct blobmsg_policy interface_policy[__INTERFACE_MAX] = {
 | |
| 	[INTERFACE_DEVICE] = { .name = "device", .type = BLOBMSG_TYPE_STRING },
 | |
| 	[INTERFACE_IFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
 | |
| };
 | |
| 
 | |
| static struct avl_tree interface_tree = AVL_TREE_INIT(interface_tree, avl_strcmp, false, NULL);
 | |
| 
 | |
| void
 | |
| interface_update(struct blob_attr *msg, int raw)
 | |
| {
 | |
| 	struct blob_attr *tb[__INTERFACE_MAX];
 | |
| 	struct interface *interface;
 | |
| 	char *device, *iface, *device_buf, *iface_buf;
 | |
| 
 | |
| 	if (raw)
 | |
| 		blobmsg_parse(interface_policy, __INTERFACE_MAX, tb, blob_data(msg), blob_len(msg));
 | |
| 	else
 | |
| 		blobmsg_parse(interface_policy, __INTERFACE_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg));
 | |
| 
 | |
| 	if (!tb[INTERFACE_DEVICE] || !tb[INTERFACE_IFACE])
 | |
| 		return;
 | |
| 
 | |
| 	iface = blobmsg_get_string(tb[INTERFACE_IFACE]);
 | |
| 	device = blobmsg_get_string(tb[INTERFACE_DEVICE]);
 | |
| 
 | |
| 	interface = avl_find_element(&interface_tree, iface, interface, avl);
 | |
| 	if (interface) {
 | |
| 		avl_delete(&interface_tree, &interface->avl);
 | |
| 		free(interface);
 | |
| 	}
 | |
| 
 | |
| 	interface = calloc_a(sizeof(struct neigh),
 | |
| 			     &iface_buf, strlen(iface) + 1,
 | |
| 			     &device_buf, strlen(device) + 1);
 | |
|         if (!interface)
 | |
|                 return;
 | |
| 	interface->iface = strcpy(iface_buf, iface);
 | |
| 	interface->device = strcpy(device_buf, device);
 | |
| 	interface->avl.key = interface->iface;
 | |
| 
 | |
| 	avl_insert(&interface_tree, &interface->avl);
 | |
| 
 | |
| 	ULOG_INFO("new interface %s:%s\n", iface, device);
 | |
| }
 | |
| 
 | |
| void
 | |
| interface_down(struct blob_attr *msg)
 | |
| {
 | |
| 	struct blob_attr *tb[__INTERFACE_MAX];
 | |
| 	struct interface *interface;
 | |
| 	char *iface;
 | |
| 
 | |
| 	blobmsg_parse(interface_policy, __INTERFACE_MAX, tb, blob_data(msg), blob_len(msg));
 | |
| 
 | |
| 	if (!tb[INTERFACE_IFACE])
 | |
| 		return;
 | |
| 
 | |
| 	iface = blobmsg_get_string(tb[INTERFACE_IFACE]);
 | |
| 
 | |
| 	interface = avl_find_element(&interface_tree, iface, interface, avl);
 | |
| 	if (!interface)
 | |
| 		return;
 | |
| 
 | |
| 	ULOG_INFO("del interface %s\n", interface->iface);
 | |
| 	avl_delete(&interface_tree, &interface->avl);
 | |
| 	free(interface);
 | |
| }
 | |
| 
 | |
| char*
 | |
| interface_resolve(char *ifname)
 | |
| {
 | |
| 	struct interface *interface;
 | |
| 
 | |
| 	avl_for_each_element(&interface_tree, interface, avl)
 | |
| 		if (!strcmp(interface->device, ifname))
 | |
| 			return interface->iface;
 | |
| 	return ifname;
 | |
| }
 | |
| 
 | |
| int
 | |
| interface_dump(void)
 | |
| {
 | |
| 	struct interface *interface;
 | |
| 	struct mac *mac;
 | |
| 
 | |
| 	blob_buf_init(&b, 0);
 | |
| 
 | |
| 	avl_for_each_element(&interface_tree, interface, avl) {
 | |
| 		void *c;
 | |
| 
 | |
| 		c = blobmsg_open_table(&b, interface->iface);
 | |
| 		avl_for_each_element(&mac_tree, mac, avl)
 | |
| 			if (!strcmp(interface->iface, mac->interface))
 | |
| 				mac_dump(mac, 0);
 | |
| 		blobmsg_close_table(&b, c);
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| interface_done(void)
 | |
| {
 | |
| 	struct interface *i, *t;
 | |
| 
 | |
| 	avl_for_each_element_safe(&interface_tree, i, avl, t)
 | |
| 		free(i);
 | |
| }
 | |
| 
 | 
