// File: /workspace/github_c_makefile_star2_O2/open-mesh-mirror[P]batmand/hna.c
// Function: hna_global_add
static void _hna_global_add(struct orig_node *orig_node, struct hna_element *hna_element)
{
	struct hna_global_entry *hna_global_entry;
	struct hna_orig_ptr *hna_orig_ptr = NULL;
	struct orig_node *old_orig_node = NULL;
	struct hashtable_t *swaphash;
	int found = 0;

	hna_global_entry = ((struct hna_global_entry *)hash_find(hna_global_hash, hna_element));

	/* add the hna node if it does not exist */
	if (!hna_global_entry) {
		hna_global_entry = debugMalloc(sizeof(struct hna_global_entry), 703);

		if (!hna_global_entry)
			return;

		hna_global_entry->addr = hna_element->addr;
		hna_global_entry->netmask = hna_element->netmask;
		hna_global_entry->curr_orig_node = NULL;
		INIT_LIST_HEAD_FIRST(hna_global_entry->orig_list);

		hash_add(hna_global_hash, hna_global_entry);

		if (hna_global_hash->elements * 4 > hna_global_hash->size) {
			swaphash = hash_resize(hna_global_hash, hna_global_hash->size * 2);

			if (swaphash == NULL)
				debug_output(0, "Couldn't resize global hna hash table \n");
			else
				hna_global_hash = swaphash;
		}
	}

	/* the given orig_node already is the current orig node for this HNA */
	if (hna_global_entry->curr_orig_node == orig_node)
		return;

	list_for_each_entry(hna_orig_ptr, &hna_global_entry->orig_list, list) {
		if (hna_orig_ptr->orig_node == orig_node) {
			found = 1;
			break;
		}
	}

	/* append the given orig node to the list */
	if (!found) {
		hna_orig_ptr = debugMalloc(sizeof(struct hna_orig_ptr), 704);

		if (!hna_orig_ptr)
			return;

		hna_orig_ptr->orig_node = orig_node;
		INIT_LIST_HEAD(&hna_orig_ptr->list);

		list_add_tail(&hna_orig_ptr->list, &hna_global_entry->orig_list);
	}

	/* our TQ value towards the HNA is better */
	if ((!hna_global_entry->curr_orig_node) ||
		(orig_node->router->tq_avg > hna_global_entry->curr_orig_node->router->tq_avg)) {

		old_orig_node = hna_global_entry->curr_orig_node;
		hna_global_entry->curr_orig_node = orig_node;

		/**
		 * if we change the orig node towards the HNA we may still route via the same next hop
		 * which does not require any routing table changes
		 */
		if ((old_orig_node) &&
			(hna_global_entry->curr_orig_node->router->addr == old_orig_node->router->addr))
			return;

		add_del_route(hna_element->addr, hna_element->netmask, orig_node->router->addr,
					orig_node->router->if_incoming->addr.sin_addr.s_addr,
					orig_node->router->if_incoming->if_index,
					orig_node->router->if_incoming->dev,
					BATMAN_RT_TABLE_NETWORKS, ROUTE_TYPE_UNICAST, ROUTE_ADD);
	}

	/* delete previous route */
	if (old_orig_node) {
		add_del_route(hna_element->addr, hna_element->netmask, old_orig_node->router->addr,
					old_orig_node->router->if_incoming->addr.sin_addr.s_addr,
					old_orig_node->router->if_incoming->if_index,
					old_orig_node->router->if_incoming->dev,
					BATMAN_RT_TABLE_NETWORKS, ROUTE_TYPE_UNICAST, ROUTE_DEL);
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
movq 0x10a13(%rip), %rdi     # 0x17678
callq 0x61eb
movq %rax, %r15
testq %rax, %rax
je 0x6c9d
movq 0x8(%r15), %r13
cmpq %r14, %r13
je 0x6dcf
leaq 0x10(%r15), %r12
movq %r12, %rax
movq (%rax), %rax
cmpq %r12, %rax
je 0x6d19
cmpq %r14, 0x8(%rax)
jne 0x6c86
jmp 0x6d45
pushq $0x20
popq %rdi
movl $0x2bf, %esi            # imm = 0x2BF
callq 0x58c9
testq %rax, %rax
je 0x6dcf
movq %rax, %r15
movl (%rbx), %eax
movl %eax, (%r15)
movb 0x4(%rbx), %al
movb %al, 0x4(%r15)
andq $0x0, 0x8(%r15)
movq %r15, %rax
addq $0x10, %rax
movq %rax, 0x10(%r15)
movq %rax, 0x18(%r15)
movq 0x1099b(%rip), %rdi     # 0x17678
movq %r15, %rsi
callq 0x6102
movq 0x1098c(%rip), %rdi     # 0x17678
movl 0x8(%rdi), %eax
movl 0xc(%rdi), %esi
shll $0x2, %eax
cmpl %esi, %eax
jle 0x6c72
addl %esi, %esi
callq 0x6320
testq %rax, %rax
je 0x6dd9
movq %rax, 0x10964(%rip)     # 0x17678
jmp 0x6c72
pushq $0x10
popq %rdi
movl $0x2c0, %esi            # imm = 0x2C0
callq 0x58c9
testq %rax, %rax
je 0x6dcf
movq %r14, 0x8(%rax)
movq %rax, (%rax)
movq %rax, %rdi
movq %r12, %rsi
callq 0x574d
movq 0x8(%r15), %r13
testq %r13, %r13
je 0x6d68
movq 0x8(%r14), %rax
movb 0x19(%rax), %dl
movq 0x8(%r13), %rcx
cmpb 0x19(%rcx), %dl
jbe 0x6dcf
movq %r14, 0x8(%r15)
movl 0x8(%rax), %edx
cmpl 0x8(%rcx), %edx
jne 0x6d73
jmp 0x6dcf
movq %r14, 0x8(%r15)
movq 0x8(%r14), %rax
movl 0x8(%rax), %edx
movl (%rbx), %edi
movzbl 0x4(%rbx), %esi
movq 0x30(%rax), %rax
movl 0x34(%rax), %ecx
movl 0x20(%rax), %r8d
movq 0x8(%rax), %r9
subq $0x8, %rsp
pushq $0x0
pushq $0x0
pushq $0x41
callq 0x745c
addq $0x20, %rsp
testq %r13, %r13
je 0x6dcf
movl (%rbx), %edi
movzbl 0x4(%rbx), %esi
movq 0x8(%r13), %rax
movl 0x8(%rax), %edx
movq 0x30(%rax), %rax
movl 0x34(%rax), %ecx
movl 0x20(%rax), %r8d
movq 0x8(%rax), %r9
subq $0x8, %rsp
pushq $0x1
pushq $0x0
pushq $0x41
callq 0x745c
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x8fd4(%rip), %rsi      # 0xfdb4
xorl %edi, %edi
xorl %eax, %eax
callq 0xcb1c
jmp 0x6c72