// File: /workspace/github_c_makefile_star2_O2/open-mesh-mirror[P]batmand/hna.c
// Function: hna_global_update
void hna_global_update(struct orig_node *orig_node, unsigned char *new_hna,
				int16_t new_hna_len, struct neigh_node *old_router)
{
	struct hna_element *e, *buff;
	struct hna_global_entry *hna_global_entry;
	int i, num_elements, old_hna_len;
	unsigned char *old_hna;

	/* orig node stopped announcing any networks */
	if ((orig_node->hna_buff) && ((new_hna == NULL) || (new_hna_len == 0))) {
		hna_global_del(orig_node);
		return;
	}

	/* orig node started to announce networks */
	if ((!orig_node->hna_buff) && ((new_hna != NULL) || (new_hna_len != 0))) {
		hna_global_add(orig_node, new_hna, new_hna_len);
		return;
	}

	/**
	 * next hop router changed - no need to change the global hna hash
	 * we just have to make sure that the best orig node is still in place
	 * NOTE: we may miss a changed HNA here which we will update with the next packet
	 */
	if (old_router != orig_node->router) {
		num_elements = orig_node->hna_buff_len / sizeof(struct hna_element);
		buff = (struct hna_element *)orig_node->hna_buff;

		for (i = 0; i < num_elements; i++) {
			e = &buff[i];

			if ((e->netmask < 1) || (e->netmask > 32))
				continue;

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

			if (!hna_global_entry)
				continue;

			/* if the given orig node is not in use no routes need to change */
			if (hna_global_entry->curr_orig_node != orig_node)
				continue;

			add_del_route(e->addr, e->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);

			add_del_route(e->addr, e->netmask, old_router->addr,
				old_router->if_incoming->addr.sin_addr.s_addr,
				old_router->if_incoming->if_index,
				old_router->if_incoming->dev,
				BATMAN_RT_TABLE_NETWORKS, ROUTE_TYPE_UNICAST, ROUTE_DEL);
		}

		return;
	}

	/**
	 * check if the buffers even changed. if its still the same, there is no need to
	 * update the routes. if the router changed, then we have to update all the routes
	 * NOTE: no NULL pointer checking here because memcmp() just returns if n == 0
	 */
	if ((orig_node->hna_buff_len == new_hna_len) && (memcmp(orig_node->hna_buff, new_hna, new_hna_len) == 0))
		return;	/* nothing to do */

	/* changed HNA */
	old_hna = orig_node->hna_buff;
	old_hna_len = orig_node->hna_buff_len;

	orig_node->hna_buff = debugMalloc(new_hna_len, 706);
	orig_node->hna_buff_len = new_hna_len;
	memcpy(orig_node->hna_buff, new_hna, new_hna_len);

	/* add new routes and keep old routes */
	num_elements = orig_node->hna_buff_len / sizeof(struct hna_element);
	buff = (struct hna_element *)orig_node->hna_buff;

	for (i = 0; i < num_elements; i++) {
		e = &buff[i];

		/**
		 * if the router is the same, and the announcement was already in the old
		 * buffer, we can keep the route.
		 */
		if (hna_buff_delete((struct hna_element *)old_hna, &old_hna_len, e) == 0) {
			/* not found / deleted, need to add this new route */
			if ((e->netmask > 0) && (e->netmask <= 32))
				_hna_global_add(orig_node, e);
		}
	}

	/* old routes which are not to be kept are deleted now. */
	num_elements = old_hna_len / sizeof(struct hna_element);
	buff = (struct hna_element *)old_hna;

	for (i = 0; i < num_elements; i++) {
		e = &buff[i];

		if ((e->netmask > 0) && (e->netmask <= 32))
			_hna_global_del(orig_node, e);
	}

	/* dispose old hna buffer now. */
	if (old_hna != NULL)
		debugFree(old_hna, 1704);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %r12
movl %edx, %ebp
movq %rsi, %r13
movq %rdi, (%rsp)
movq 0x38(%rdi), %r14
testq %r14, %r14
je 0x6e38
testq %r13, %r13
setne %al
testw %bp, %bp
setne %cl
testb %cl, %al
jne 0x6e65
movq (%rsp), %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x70b9
testq %r13, %r13
sete %al
testw %bp, %bp
sete %cl
testb %cl, %al
jne 0x6e65
movswl %bp, %edx
movq (%rsp), %rdi
movq %r13, %rsi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6b32
movq (%rsp), %rax
movswq 0x40(%rax), %r15
cmpq %r12, 0x8(%rax)
je 0x6f32
xorl %ebx, %ebx
pushq $0x5
popq %rcx
movq %r15, %rax
xorl %edx, %edx
divq %rcx
testl %eax, %eax
cmovgl %eax, %ebx
pushq $0x41
popq %r15
subq $0x1, %rbx
jb 0x70aa
movb 0x4(%r14), %al
addb $-0x21, %al
cmpb $-0x20, %al
jb 0x6f29
movq 0x107cb(%rip), %rdi     # 0x17678
movq %r14, %rsi
callq 0x61eb
testq %rax, %rax
je 0x6f29
movq (%rsp), %rcx
cmpq %rcx, 0x8(%rax)
jne 0x6f29
movl (%r14), %edi
movzbl 0x4(%r14), %esi
movq (%rsp), %rax
movq 0x8(%rax), %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 $0x0
pushq $0x0
pushq %r15
callq 0x745c
addq $0x20, %rsp
movl (%r14), %edi
movzbl 0x4(%r14), %esi
movl 0x8(%r12), %edx
movq 0x30(%r12), %rax
movl 0x34(%rax), %ecx
movl 0x20(%rax), %r8d
movq 0x8(%rax), %r9
subq $0x8, %rsp
pushq $0x1
pushq $0x0
pushq %r15
callq 0x745c
addq $0x20, %rsp
addq $0x5, %r14
jmp 0x6e8e
movswq %bp, %rbx
cmpw %bp, %r15w
jne 0x6f52
movq %r14, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2340
testl %eax, %eax
je 0x70aa
movswl %bp, %edi
movl $0x2c2, %esi            # imm = 0x2C2
callq 0x58c9
movq %r15, 0x8(%rsp)
movq (%rsp), %r15
movq %rax, 0x38(%r15)
movw %bp, 0x40(%r15)
movq %rax, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2290
movswq 0x40(%r15), %rax
xorl %esi, %esi
pushq $0x5
popq %r12
xorl %edx, %edx
divq %r12
movq 0x38(%r15), %rcx
movq %rcx, 0x18(%rsp)
movq 0x8(%rsp), %rcx
testl %eax, %eax
cmovlel %esi, %eax
movq %rax, 0x20(%rsp)
xorl %edx, %edx
movslq %ecx, %rax
cmpq 0x20(%rsp), %rdx
je 0x7052
movq %rcx, 0x8(%rsp)
movq %rdx, 0x10(%rsp)
leaq (%rdx,%rdx,4), %rbp
addq 0x18(%rsp), %rbp
testq %r14, %r14
je 0x702b
xorl %edx, %edx
divq %r12
movq %rax, %r15
testl %r15d, %r15d
movl %r15d, %ebx
movl $0x0, %eax
cmovlel %eax, %ebx
incq %rbx
movq %r14, %rdi
decq %rbx
je 0x702b
leaq 0x5(%rdi), %r13
movq %rbp, %rsi
movq %r12, %rdx
callq 0x2340
movq %r13, %rdi
testl %eax, %eax
jne 0x6feb
leal -0x1(%r15), %eax
cltq
leaq (%rax,%rax,4), %rax
movl (%r14,%rax), %ecx
movb 0x4(%r14,%rax), %al
movb %al, -0x1(%r13)
movl %ecx, -0x5(%r13)
movq 0x8(%rsp), %rcx
addl $-0x5, %ecx
jmp 0x7045
movb 0x4(%rbp), %al
decb %al
cmpb $0x1f, %al
ja 0x7040
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x6c4f
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rdx
incq %rdx
jmp 0x6fa9
xorl %ebx, %ebx
xorl %edx, %edx
divq %r12
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
leaq (%rcx,%rcx,4), %r15
cmpq %rbx, %r15
je 0x708a
movb 0x4(%r14,%rbx), %al
decb %al
cmpb $0x1f, %al
ja 0x7084
leaq (%r14,%rbx), %rsi
movq (%rsp), %rdi
callq 0x7124
addq $0x5, %rbx
jmp 0x7067
testq %r14, %r14
je 0x70aa
movq %r14, %rdi
movl $0x6a8, %esi            # imm = 0x6A8
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5b1a
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq