Exemplo n.º 1
0
Arquivo: if.c Projeto: ariavie/bcm
static int
sal_if_do_deconfig(char *pfx, END_OBJ *eo, char *if_name, int if_unit)
/*
 * Function: 
 * Purpose:
 * Parameters:
 * Returns:
 */
{
#if VX_VERSION == 66 || VX_VERSION == 68
    char ifconfigstr[32];
#endif /* VX_VERSION == 66 || VX_VERSION == 68 */

    LOG_INFO(BSL_LS_APPL_END,
             (BSL_META("%s: Stopping %s %d %08x \n"),
              pfx, if_name, if_unit, (uint32)eo));
    if (OK != muxDevStop(eo)) {
	cli_out("%s: Error: muxDevStop failed: %s%d\n", 
                pfx, if_name, if_unit);
	return(-1);
    }

#if VX_VERSION == 66 || VX_VERSION == 68
    sprintf(ifconfigstr, "%s%d down", if_name, if_unit);
    if (ERROR == ifconfig(ifconfigstr)) {
        cli_out("%s: ifconfig down failed: %s%d <-- %s\n", pfx, if_name, if_unit, ifconfigstr);
        return(-1);
    }

    sprintf(ifconfigstr, "%s%d detach", if_name, if_unit);
    if (ERROR == ifconfig(ifconfigstr)) {
        cli_out("%s: ifconfig down failed: %s%d <-- %s\n", pfx, if_name, if_unit, ifconfigstr);
        return(-1);
    }
#else /* VX_VERSION == 66 || VX_VERSION == 68 */

    LOG_INFO(BSL_LS_APPL_END,
             (BSL_META("%s: Clearing Routes\n"), pfx));

#ifdef VXWORKS_NETWORK_STACK_6_5
#ifdef VXWORKS_NETWORK_STACK_FIXME_SHOW
#error VXWORKS_NETWORK_STACK_FIXME_SHOW
#endif 
#else
    ifRouteDelete(if_name, if_unit);
#endif /* VXWORKS_NETWORK_STACK_6_5 */

    LOG_INFO(BSL_LS_APPL_END,
             (BSL_META("%s: Unloading\n"), pfx));
    if (OK != muxDevUnload(if_name, if_unit)) {
	cli_out("%s: Error: muxDevUnload failed: %s%d\n",
                pfx, if_name, if_unit);
	return(-1);
    }
    LOG_INFO(BSL_LS_APPL_END,
             (BSL_META("%s: Stopped and Unloaded: %s%d\n"), 
              pfx, if_name, if_unit));
#endif /* VX_VERSION == 66 || VX_VERSION == 68 */
    return(0);
}
/* Configure a virtual IP interface. */
void ssh_virtual_adapter_configure(
  SshInterceptor interceptor,
  SshInterceptorIfnum adapter_ifnum,
  SshVirtualAdapterState adapter_state,
  SshUInt32 num_addresses,
  SshIpAddr addresses,
  SshVirtualAdapterParams params,
  SshVirtualAdapterStatusCB callback,
  void *context)
{
  VxWorksVa *va;
  char *addrstr;
  SshIpAddr ipaddr;
  int i, addrlen, mask, oldflags, newflags;
  int inet_up = 0;
#if defined(WITH_IPV6) && defined(INET6)
  int inet6_up = 0;
#endif /* defined(WITH_IPV6) && defined(INET6) */

  SSH_DEBUG(SSH_D_HIGHOK, ("configure ifnum %d", (int)adapter_ifnum));

  if (!(va = vxworks_va_find_va(adapter_ifnum)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to get status of a nonexistent ifnum %d",
         (int)adapter_ifnum));

      if (callback)
        callback(
          SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
          adapter_ifnum,
          NULL, 
          SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
          NULL,
          context);
      return;
    }

  /* Check addresses to determine IFF_INET_UP and IFF_INET6_UP status */
  if (adapter_state != SSH_VIRTUAL_ADAPTER_STATE_DOWN && addresses)
    {
      for (i = 0; i < num_addresses; i++)
        {
          ipaddr = &addresses[i];
          if (SSH_IP_IS4(ipaddr))
            inet_up = 1;
#if defined(WITH_IPV6) && defined(INET6)
          else if (SSH_IP_IS6(ipaddr))
            inet6_up = 1;
#endif /* defined(WITH_IPV6) && defined(INET6) */
        }          
    }

  /* Clear addresses if new addresses are being configured or
     interface is being turned off */
  if (addresses || adapter_state == SSH_VIRTUAL_ADAPTER_STATE_DOWN)
    {
      for (i = 0; i < va->ip4addr_num; i++)
        {
          addrstr = va->ip4addr_tab[i];

          SSH_DEBUG(
            SSH_D_MIDOK,
            ("deleting IPv4 address %s on %s, ifnum %d",
             addrstr, va->name, (int)va->ifnum));

          if (ifAddrDelete(va->name, addrstr) != OK)
            SSH_TRACE(
              SSH_D_ERROR,
              ("%s: deleting IPv4 address %s failed", va->name, addrstr));
        }
      va->ip4addr_num = 0;

      if (ifRouteDelete(vxworks_va_devname, va->end.devObject.unit) ==
          ERROR)
        SSH_TRACE(SSH_D_ERROR, ("%s: deleting IPv4 routes failed", va->name));

#if defined(WITH_IPV6) && defined(INET6)
      for (i = 0; i < va->ip6addr_num; i++)
        {
          addrstr = va->ip6addr_tab[i];

          SSH_DEBUG(
            SSH_D_MIDOK,
            ("deleting IPv6 address %s on %s, ifnum %d",
             addrstr, va->name, (int)va->ifnum));

          if (if6AddrDelete(va->name, addrstr) != OK)
            SSH_TRACE(
              SSH_D_ERROR,
              ("%s: deleting IPv6 address %s failed", va->name, addrstr));
        }
      va->ip6addr_num = 0;
#endif /* defined(WITH_IPV6) && defined(INET6) */
    }

  /* Set interface status. */
  if (ifFlagGet(va->name, &oldflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot get interface flags"));
      return;
    }
  newflags = oldflags;
  if (inet_up
#if defined(WITH_IPV6) && defined(INET6)
      || inet6_up
#endif /* defined(WITH_IPV6) && defined(INET6) */
      )
    newflags |= IFF_UP;
  else
    newflags &= ~IFF_UP;
#if VXWORKS_NETVER >= 55122
  if (inet_up)
    newflags |= IFF_INET_UP;
  else
    newflags &= ~IFF_INET_UP;
#if defined(WITH_IPV6) && defined(INET6)
  if (inet6_up)
    newflags |= IFF_INET6_UP;
  else
    newflags &= ~IFF_INET6_UP;
#endif /* defined(WITH_IPV6) && defined(INET6) */
#endif /* VXWORKS_NETVER >= 55122 */
  if (newflags != oldflags && ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      return;
    }

  /* Add addresses if the addresses parameter is non-NULL and
     interface is not being turned off */
  if (addresses && adapter_state != SSH_VIRTUAL_ADAPTER_STATE_DOWN)
    {
      for (i = 0; i < num_addresses; i++)
        {
          ipaddr = &addresses[i];

          if (SSH_IP_IS4(ipaddr))
            {
              if (va->ip4addr_num >=
                  sizeof va->ip4addr_tab / sizeof va->ip4addr_tab[0])
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: too many IPv4 addresses, ignoring some", va->name));
                  break;
                }

              addrstr = va->ip4addr_tab[va->ip4addr_num];
              addrlen = sizeof va->ip4addr_tab[va->ip4addr_num];

              ssh_ipaddr_print(ipaddr, addrstr, addrlen);

              SSH_DEBUG(
                SSH_D_MIDOK,
                ("adding IPv4 address %s on %s, ifnum %d",
                 addrstr, va->name, (int)va->ifnum));

              mask = ~((1 << (32 - SSH_IP_MASK_LEN(ipaddr))) - 1) & 0xffffffff;

              if (ifAddrAdd(va->name, addrstr, NULL, mask) != OK)
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: adding IPv4 address %s failed", va->name, addrstr));
                  continue;
                }
              va->ip4addr_num++;
            }
#if defined(WITH_IPV6) && defined(INET6)
          else if (SSH_IP_IS6(ipaddr))
            {
              if (va->ip6addr_num >=
                  sizeof va->ip6addr_tab / sizeof va->ip6addr_tab[0])
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: too many IPv6 addresses, ignoring some", va->name));
                  break;
                }

              addrstr = va->ip6addr_tab[va->ip6addr_num];
              addrlen = sizeof va->ip6addr_tab[va->ip6addr_num];

              ssh_ipaddr_print(ipaddr, addrstr, addrlen);

              SSH_DEBUG(
                SSH_D_MIDOK,
                ("adding IPv6 address %s on %s, ifnum %d",
                 addrstr, va->name, (int)va->ifnum));

              if (if6AddrAdd(va->name, addrstr, SSH_IP_MASK_LEN(ipaddr), 0)
                  != OK)
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: adding IPv6 address %s failed", va->name, addrstr));
                  continue;
                }
              va->ip6addr_num++;
            }
#endif /* defined(WITH_IPV6) && defined(INET6) */
        }
    }

  /* Change MTU */
  if (params && params->mtu > 0)
    MIB_VAR_UPDATE(va->end.pMib2Tbl, M2_varId_ifMtu, (ULONG)params->mtu);

  /* Toggle IFF_UP twice to cause an interface event with up-to-date
     addresses in effect. */
  if (ifFlagGet(va->name, &oldflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot get interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }
  newflags = oldflags ^ IFF_UP;
  if (ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }
  newflags ^= IFF_UP;
  if (ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }

  SSH_DEBUG(
    SSH_D_HIGHOK, ("configured %s, ifnum %d", va->name, (int)va->ifnum));

  vxworks_va_report(va, SSH_VIRTUAL_ADAPTER_ERROR_OK, callback, context);
}