STATUS ifFlagChange ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int flags, /* the flag to be changed */ BOOL on /* TRUE=turn on, FALSE=turn off */ ) { int oldFlags; if (ifFlagGet (interfaceName, &oldFlags) == ERROR) { return (ERROR); } if (on) oldFlags |= flags; else oldFlags &= ~flags; return (ifFlagSet (interfaceName, oldFlags)); }
/* 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); }