Ejemplo n.º 1
0
/*
 *===========================================================================
 *                      ipnet_vrrp_add_addr
 *===========================================================================
 * Description: Adds a virtual router address.
 * Parameters:  netif - The network interface the VRIP will be assigned to.
 *              vrid - The VRID the address will be assigned to.
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_vrrp_add_addr(Ipnet_netif *netif, Ip_u8 vrid, struct Ip_in_addr addr)
{
    Ipnet_vrrp_addr_t *addr_entry;

    if (ipnet->vrrp_addrs == IP_NULL)
    {
        ipnet->vrrp_addrs = ipcom_hash_new((Ipcom_hash_obj_func) ipnet_vrrp_obj_hash,
                                           (Ipcom_hash_key_func) ipnet_vrrp_obj_hash,
                                           (Ipcom_hash_cmp_func) ipnet_vrrp_hash_cmp);
        if (ipnet->vrrp_addrs == IP_NULL)
            return -IP_ERRNO_ENOMEM;
    }

    addr_entry = ipnet_vrrp_get_addr_entry(netif, vrid);
    if (addr_entry == IP_NULL)
    {
        addr_entry = ipcom_malloc(sizeof(Ipnet_vrrp_addr_t));
        if (addr_entry == IP_NULL)
            return -IP_ERRNO_ENOMEM;
        IPNET_IF_LOCK(netif);
        addr_entry->netif     = netif;
        addr_entry->vrid      = vrid;
        addr_entry->num_addrs = 1;
        addr_entry->addrs[0]  = addr;
    }
    else
    {
        Ipnet_vrrp_addr_t *a;
        int                i;

        i = ipnet_vrrp_addr_index(addr_entry, addr);
        if (i >= 0)
            return -IP_ERRNO_EEXIST;

        (void)ipcom_hash_remove(ipnet->vrrp_addrs, addr_entry);
        a = ipcom_realloc(addr_entry,
                          sizeof(Ipnet_vrrp_addr_t) + addr_entry->num_addrs * sizeof(Ipnet_vrrp_addr_t));
        if (a == IP_NULL)
            return -IP_ERRNO_ENOMEM;
        a->addrs[a->num_addrs++] = addr;
        addr_entry = a;
    }

    if (ipcom_hash_add(ipnet->vrrp_addrs, addr_entry) != IPCOM_SUCCESS)
    {
        ipcom_free(addr_entry);
        return -IP_ERRNO_ENOMEM;
    }

    IPCOM_LOG2(INFO, "VRRP: added address %s on %s",
               ipcom_inet_ntop(IP_AF_INET, &addr, ipnet->log_buf, sizeof(ipnet->log_buf)),
               netif->ipcom.name);

    return 0;
}
Ejemplo n.º 2
0
/*
 *===========================================================================
 *                    ipcom_hash_resize
 *===========================================================================
 * Description:   Doubles the size or cuts the size in half.
 * Parameters:    head - The head of the hash table.
 *                increase - Set to IP_TRUE to double the size, IP_FALSE
 *                to half the size.
 * Returns:       IPCOM_SUCCESS or IPCOM_ERR_NO_MEMORY if not enough memory
 *                could be allocated.
 *
 */
IP_STATIC Ip_err
ipcom_hash_resize(Ipcom_hash *head, Ip_bool increase)
{
    void **old_hash_table;
    int    old_size;
    int    i;
    Ip_err err;

    old_hash_table = head->table;
    old_size = head->size;

    /* Keep the size odd since that will increase the chance of the high
       bits of the hash value to affect the low bits which is used as
       index in the hash table */
    if (increase)
        head->size = (head->size << 1) + 3;
    else
        head->size = (head->size >> 1) - 1;

    head->table = IPCOM_CALLOC_STATIC(head->size, sizeof(*head->table));
    if (head->table == IP_NULL)
    {
        IPCOM_LOG2(ERR, "ipcom_hash_resize :: ipcom_calloc(%d, %d) failed",
                   head->size,
                   sizeof(*head->table));
        head->size = old_size;
        head->table = old_hash_table;
        return IPCOM_ERR_NO_MEMORY;
    }

    head->elem = 0;
    for (i = 0; i < old_size; i++)
        if (old_hash_table[i] != IP_NULL)
        {
            err = ipcom_hash_add(head, old_hash_table[i]);
            ip_assert(err == IPCOM_SUCCESS);
            (void)err;
        }

    IPCOM_FREE_STATIC(old_hash_table);
    return IPCOM_SUCCESS;
}
Ejemplo n.º 3
0
/*
 *===========================================================================
 *                    ipcom_sysvar_set_internal
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_GLOBAL Ip_err
ipcom_sysvar_set_tree(const char *name, const char *value, int flags, Ipcom_sysvar_tree *tree)
{
    Ip_size_t           name_length;
    Ip_size_t           value_length;
    Ipcom_sysvar_entry  *sysvar;
    Ip_err              retval = IPCOM_SUCCESS;

    /* Check for duplicate. */
    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if (IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY))
        {
            retval = IPCOM_ERR_READONLY;
            goto leave;
        }
        else if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_OVERWRITE))
        {
            retval = IPCOM_ERR_DUPLICATE;
            goto leave;
        }
        else
        {
            flags |= sysvar->flags & IPCOM_SYSVAR_FLAG_KERNEL;
            ipcom_hash_remove(tree->sysvars, sysvar);
            ipcom_free(sysvar);
            goto set;
        }
    }

    /* No current entry found and not allowed to create a new entry. */
    if(IP_BIT_ISSET(flags, IPCOM_SYSVAR_FLAG_NOCREATE))
    {
        retval = IPCOM_ERR_FAILED;
        goto leave;
    }

    /* Add the new sysvar. */
 set:
     name_length = ipcom_strlen(name) + 1;
     value_length = ipcom_strlen(value) + 1;
     sysvar = ipcom_malloc(sizeof(Ipcom_sysvar_entry) + name_length + value_length);

     if(sysvar == IP_NULL)
     {
         retval = IPCOM_ERR_NO_MEMORY;
         goto leave;
     }

     sysvar->refcount = 1;
     sysvar->flags    = flags;
     if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_INIT))
     {
         tree->modified = IP_TRUE;
         sysvar->flags |= IPCOM_SYSVAR_FLAG_MODIFIED;
     }
     sysvar->name     = (const char *)sysvar + sizeof(Ipcom_sysvar_entry);
     ipcom_memcpy((void *)sysvar->name, name, name_length);
     sysvar->value    = sysvar->name + name_length;
     ipcom_memcpy((void *)sysvar->value, value, value_length);

     retval = ipcom_hash_add(tree->sysvars, sysvar);

 leave:
    return retval; /*lint !e429 Custodial pointer 'sysvar' has not been freed or returned */
}
/*
 *===========================================================================
 *                    ipcom_setenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_setenv(const char *name, const char *value, int rewrite)
{
#if IPCOM_USE_ENV == IPCOM_ENV_IPCOM
    Ip_err           retval;
    Ipcom_proc      *proc;
    Ipcom_env_entry *env;

    proc = ipcom_proc_self();
    ip_assert(proc != IP_NULL);

    retval = ipcom_once(&proc->env_once, ipcom_env_init, proc);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return -1;
    }

    ipcom_mutex_lock(proc->env_mutex);

    /* Check for duplicate. */
    env = ipcom_hash_get(proc->env_tree, name);
    if (env != IP_NULL)
    {
        if (rewrite == 0)
            goto leave;
        ipcom_env_delete(env, proc->env_tree);
    }

    /* Create environment variable. */
    env = ipcom_env_create(name, value);
    if (env == IP_NULL)
    {
        ipcom_mutex_unlock(proc->env_mutex);
        return -1;
    }
    (void)ipcom_hash_add(proc->env_tree, env);

 leave:
    ipcom_mutex_unlock(proc->env_mutex);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5))
    (void)rewrite;

    set_env(current_process(), name, value);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && defined(IP_PORT_VXWORKS)
    char buf[256];
    int  ret;

    (void)rewrite;

    ipcom_snprintf(buf, sizeof(buf), "%s=%s", name, value);
    ret = (int)putenv(buf);
    return ret == 0 ? 0 : -1;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE
    return setenv(name, value, rewrite);

#elif defined(IPCOM_USE_SYSVAR) && IPCOM_VR_MAX == 1
    (void)ipcom_sysvar_set(name, value, rewrite ? IPCOM_SYSVAR_FLAG_OVERWRITE : 0);
    return 0;

#else
    (void)name;
    (void)value;
    (void)rewrite;
    return -1;

#endif /* #if IPCOM_USE_ENV == IPCOM_ENV_IPCOM */
}
/*
 *===========================================================================
 *                           ipcom_env_clone
 *===========================================================================
 * Description: Clones an env entry and adds it to the specified hash table.
 * Parameters:  env - entry to clone
 *              hash - hash table the cloned entry should be added to.
 * Returns:
 *
 */
IP_STATIC void
ipcom_env_clone(Ipcom_env_entry *env, Ipcom_hash *hash)
{
    Ipcom_env_entry *clone = ipcom_env_create(env->name, env->value);
    ipcom_hash_add(hash, clone);
}