// File: /workspace/github_c_makefile_star2_O3/FH0[P]tun_direct/lwip-2.1.2/src/core/ipv6/nd6.c
// Function: nd6_select_router
static s8_t
nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
{
  struct netif *router_netif;
  s8_t i, j, valid_router;
  static s8_t last_router;

  LWIP_UNUSED_ARG(ip6addr); /* @todo match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */

  /* @todo: implement default router preference */

  /* Look for valid routers. A reachable router is preferred. */
  valid_router = -1;
  for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) {
    /* Is the router netif both set and apppropriate? */
    if (default_router_list[i].neighbor_entry != NULL) {
      router_netif = default_router_list[i].neighbor_entry->netif;
      if ((router_netif != NULL) && (netif != NULL ? netif == router_netif :
          (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
        /* Is the router valid, i.e., reachable or probably reachable as per
         * RFC 4861 Sec. 6.3.6? Note that we will never return a router that
         * has no neighbor cache entry, due to the netif association tests. */
        if (default_router_list[i].neighbor_entry->state != ND6_INCOMPLETE) {
          /* Is the router known to be reachable? */
          if (default_router_list[i].neighbor_entry->state == ND6_REACHABLE) {
            return i; /* valid and reachable - done! */
          } else if (valid_router < 0) {
            valid_router = i; /* valid but not known to be reachable */
          }
        }
      }
    }
  }
  if (valid_router >= 0) {
    return valid_router;
  }

  /* Look for any router for which we have any information at all. */
  /* last_router is used for round-robin selection of incomplete routers, as
   * recommended in RFC 4861 Sec. 6.3.6 point (2). Advance only when picking a
   * route, to select the same router as next-hop target in the common case. */
  if ((netif == NULL) && (++last_router >= LWIP_ND6_NUM_ROUTERS)) {
    last_router = 0;
  }
  i = last_router;
  for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) {
    if (default_router_list[i].neighbor_entry != NULL) {
      router_netif = default_router_list[i].neighbor_entry->netif;
      if ((router_netif != NULL) && (netif != NULL ? netif == router_netif :
          (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
        return i;
      }
    }
    if (++i >= LWIP_ND6_NUM_ROUTERS) {
      i = 0;
    }
  }

  /* no suitable router found. */
  return -1;
}

// Assembly:
movb $-0x1, %al
leaq 0x9f33(%rip), %rdx      # 0x1cc40
xorl %ecx, %ecx
movq (%rdx), %rsi
testq %rsi, %rsi
je 0x12d56
movq 0x18(%rsi), %r8
testq %r8, %r8
je 0x12d56
testq %rdi, %rdi
je 0x12d2c
cmpq %rdi, %r8
jne 0x12d56
jmp 0x12d3c
movb 0xeb(%r8), %r8b
notb %r8b
testb $0x5, %r8b
jne 0x12d56
movzbl 0x30(%rsi), %esi
cmpl $0x1, %esi
je 0x12d56
cmpl $0x2, %esi
je 0x12dd7
testb %al, %al
movzbl %al, %eax
cmovsl %ecx, %eax
incq %rcx
addq $0x10, %rdx
cmpq $0x3, %rcx
jne 0x12d0f
testb %al, %al
js 0x12d68
retq
movb 0xa1f6(%rip), %al       # 0x1cf64
testq %rdi, %rdi
jne 0x12d85
incb %al
xorl %ecx, %ecx
cmpb $0x3, %al
movzbl %al, %eax
cmovgel %ecx, %eax
movb %al, 0xa1df(%rip)       # 0x1cf64
movb $0x3, %cl
leaq 0x9eb2(%rip), %rdx      # 0x1cc40
xorl %esi, %esi
movsbq %al, %r8
shlq $0x4, %r8
movq (%r8,%rdx), %r8
testq %r8, %r8
je 0x12dc6
movq 0x18(%r8), %r8
testq %r8, %r8
je 0x12dc6
testq %rdi, %rdi
je 0x12db6
cmpq %rdi, %r8
jne 0x12dc6
jmp 0x12d67
movb 0xeb(%r8), %r8b
notb %r8b
testb $0x5, %r8b
je 0x12d67
incb %al
cmpb $0x3, %al
movzbl %al, %eax
cmovgel %esi, %eax
decb %cl
jne 0x12d90
movb $-0x1, %al
retq
movl %ecx, %eax
retq