/*
 *===========================================================================
 *                         ipnet_sockdev_ioevent
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_sockdev_ioevent(Ipcom_netif *ipcomif, int command, void *data, int fcflags)
{
    int ret = 0;

    IPCOM_UNUSED_ARG(ipcomif);
    IPCOM_UNUSED_ARG(data);

    if (IP_BIT_ISFALSE(fcflags, IP_FLAG_FC_ISRCONTEXT | IP_FLAG_FC_STACKCONTEXT))
        IPNET_CODE_LOCK_WRITE();

    switch (command)
    {
    case IP_EIOXUP:
        break;
    case IP_EIOXDOWN:
        break;
    default:
        ret = -1;
        break;
    }

    if (IP_BIT_ISFALSE(fcflags, IP_FLAG_FC_ISRCONTEXT | IP_FLAG_FC_STACKCONTEXT))
        IPNET_CODE_UNLOCK();

    return ret;
}
/*
 *===========================================================================
 *                    ipnet_loopback_get_frame_info
 *===========================================================================
 * Description: Extracts frame information from a packet sent on the loopback
 *              device.
 * Parameters:  netif - Loopback interface
 *              pkt - The packet to extract information from
 *              pkt_type - Will contain the packet type if != IP_NULL
 *              frame_type - Will contain the frame type if != IP_NULL
 *              src - Unused since the loopback does not have a link layer address.
 *              dst - Unused since the loopback does not use link layer address.
 * Returns:
 *
 */
IP_STATIC int
ipnet_loopback_get_frame_info(struct Ipnet_netif_struct *netif,
                              Ipcom_pkt *pkt,
                              Ip_u8 *pkt_type,
                              Ip_u16 *frame_type,
                              Ip_u8 *src,
                              Ip_u8 *dst)
{
    IPCOM_UNUSED_ARG(src);
    IPCOM_UNUSED_ARG(dst);

    if (frame_type != IP_NULL)
    {
        Ip_u8 network_type = pkt->data[pkt->start + netif->ipcom.link_hdr_size];

        if ((network_type & 0xf0) == 0x40)
            *frame_type = ip_htons(IP_IPPROTO_IPV4);
        else if ((network_type & 0xf0) == 0x60)
            *frame_type = ip_htons(IP_IPPROTO_IPV6);
        else
            return -IP_ERRNO_EINVAL;
    }

    if (pkt_type != IP_NULL)
        *pkt_type = IP_PACKET_HOST;

    return 0;
}
/*
 *===========================================================================
 *                    ipnet_sockdev_init
 *===========================================================================
 * Description: Create and attach application device interface.
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_sockdev_init(Ipnet_socket *s, Ip_bool user_context)
{
    Ipcom_netif *sockdev_if;
    int          ret = -IP_ERRNO_ENOMEM;

    IPCOM_UNUSED_ARG(user_context);

    /* Allocate loopback interface */
    sockdev_if = ipcom_if_malloc(IP_IFT_SOCKDEV);
    if (sockdev_if == IP_NULL)
        goto errout;

    ipcom_sprintf(sockdev_if->name, "%s%d", IPNET_SOCKDEV_IF_NAME_BASE, s->proto);

    /* Attach loopback interface */
    ret = ipcom_if_attach(sockdev_if);
    if (ret < 0)
        goto errout;

    s->bind_to_ifindex = sockdev_if->ifindex;
    sockdev_if->plink = s;

    ret = ipnet_if_link_ioctl((Ipnet_netif *)sockdev_if, IP_SIOCXOPEN, IP_NULL);

errout:
    return ret;
}
Ejemplo n.º 4
0
/*
 *===========================================================================
 *                    ipcom_sysvar_init
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_STATIC Ip_err
ipcom_sysvar_init(void *ununsed)
{
    IPCOM_UNUSED_ARG(ununsed);

    ipcom_memset(&ipcom_sysvar, 0, sizeof(Ipcom_sysvar_data));
    return ipcom_mutex_create(&ipcom_sysvar.lock);
}
/*
 *===========================================================================
 *                         ipnet_loopback_ioevent
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_loopback_ioevent(Ipcom_netif *ipcomif,
                       int command,
                       void *data,
                       int fcflags)
{
    IPCOM_UNUSED_ARG(ipcomif);
    IPCOM_UNUSED_ARG(data);
    IPCOM_UNUSED_ARG(fcflags);

    switch (command)
    {
    case IP_EIOXUP:
        break;
    case IP_EIOXDOWN:
        break;
    default:
        return -1;
    }

    return 0;
}
Ejemplo n.º 6
0
/*
 *===========================================================================
 *                       ipppp_work_init
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_err
ipppp_work_init(void *unused)
{
    IPCOM_UNUSED_ARG(unused);

    ipcom_list_init(&ipppp_work_queue);
    ipcom_mutex_create(&ipppp_work_lock);
    ipcom_sem_create(&ipppp_work_sem, 0);

    return ipcom_proc_create("ipppp_work",
                             (Ipcom_proc_func)ipppp_work,
                             IPCOM_PROC_STACK_DEFAULT,
                             IP_NULL);
}
/*
 *===========================================================================
 *                    ipcom_spinlock_unlock
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_FASTTEXT IP_PUBLIC void
ipcom_spinlock_unlock(Ipcom_spinlock sl_handle)
{
#ifdef IPCOM_USE_SMP
    Ipcom_vxworks_spinlock_t *sl = (Ipcom_vxworks_spinlock_t*) sl_handle;

    VX_MEM_BARRIER_RW();  /* build a memory fence for load and store */

    if (vxAtomicInc(&sl->count) < 0)
        /* Contention for this lock, let's wakeup one of the tasks
           that is blocked on this lock */
        semGive(sl->sem);
#else
    IPCOM_UNUSED_ARG(sl_handle);
    ip_assert(sl_handle == IPCOM_SPINLOCK_TAG);
    taskUnlock();
#endif
}
IP_FASTTEXT IP_PUBLIC void
ipcom_spinlock_lock(Ipcom_spinlock sl_handle)
{
#ifdef IPCOM_USE_SMP
    Ipcom_vxworks_spinlock_t *sl = (Ipcom_vxworks_spinlock_t*) sl_handle;
#ifdef IPCOM_SPINLOCK_BUSY_PERSIST
    int i;
    atomicVal_t count;

 try_again:

    if (vxCas(&sl->count, 1, 0))
        goto got_it;

    for (i = IPCOM_SPINLOCK_BUSY_PERSIST; i > 0; --i)
    {
        count = vxAtomicGet(&sl->count);
        if (count < 0)
            break;
        if (count == 1)
            goto try_again;
    }
#endif /* IPCOM_SPINLOCK_BUSY_PERSIST */
    if (vxAtomicDec(&sl->count) <= 0)
        /* Contention for this lock, let's sleep until the lock gets
           available */
        semTake(sl->sem, WAIT_FOREVER);
    else
    {
#ifdef IPCOM_SPINLOCK_BUSY_PERSIST
    got_it:
#endif
        /* prevent load/store re-ordering beyond this point */
        VX_MEM_BARRIER_RW();
    }
#else
    IPCOM_UNUSED_ARG(sl_handle);
    ip_assert(sl_handle == IPCOM_SPINLOCK_TAG);
    taskLock();
#endif
}
/*
 *===========================================================================
 *                    ipnet_loopback_ip_output
 *===========================================================================
 * Description: Updates statistics counter and add the link trailer.
 * Parameters:  netif - The interface the packet was sent to.
 *              rt - The route followed (ignored).
 *              pkt - The packet to loopback. pkt->start is the offset to the
 *              IP header.
 * Returns:     0 = success, 0< = error code.
 *
 */
IP_STATIC int
ipnet_loopback_ip_output(Ipnet_netif *netif, Ipnet_route_entry *rt, Ipcom_pkt *pkt)
{
    Ipnet_loopback_trailer_t *tr;

    IPCOM_UNUSED_ARG(rt);

    if (IP_UNLIKELY(IP_BIT_ISFALSE(netif->ipcom.flags, IP_IFF_UP)))
    {
        ipcom_pkt_free(pkt);
        return -IP_ERRNO_EHOSTDOWN;
    }

#ifdef IPCOM_ZEROCOPY
    pkt = ipcom_pkt_make_linear(pkt);
    if (IP_UNLIKELY(pkt == IP_NULL))
        /* Not enough packets to make this packet linear, not much to
           about it */
        return 0;
#endif /* IPCOM_ZEROCOPY */

    IP_BIT_CLR(pkt->flags, IPCOM_PKT_FLAG_OUTPUT);

#if defined(IPCOM_USE_INET) || defined(IPCOM_USE_INET6)
    ip_assert2((pkt->data[pkt->start] & 0xf0) == 0x40 || (pkt->data[pkt->start] & 0xf0) == 0x60);
#elif defined(IPCOM_USE_INET)
    ip_assert2((pkt->data[pkt->start] & 0xf0) == 0x40);
#else
    ip_assert2((pkt->data[pkt->start] & 0xf0) == 0x60);
#endif

    tr = (Ipnet_loopback_trailer_t *) &pkt->data[pkt->end];
    IP_SET_32ON8(&tr->scope_id, pkt->ifindex);
    pkt->ifindex = netif->ipcom.ifindex;

    return ipnet_if_output(netif, pkt);
}
Ejemplo n.º 10
0
/*
 *===========================================================================
 *                    ipnet_gre_setup
 *===========================================================================
 * Description: Setup the GRE tunnel.
 * Parameters:  netif - A GRE tunnel interface.
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_gre_setup(Ipnet_netif *netif)
{
#ifdef IPNET_USE_RFC2890
    Ipnet_gre_t *gre;

    gre = netif->ipcom.pdrv = ipcom_calloc(1, sizeof(Ipnet_gre_t));
    if (gre == IP_NULL)
        goto errout;

    gre->reassembly_queue
        = ipcom_pqueue_new((Ipcom_pqueue_cmp_func) ipnet_gre_seq_cmp,
                           ipcom_pqueue_nop_store_index);

    return 0;
 errout:
    ipnet_gre_destroy(netif);
    IPCOM_LOG0(CRIT, "Failed to create GRE tunnel due to unsifficient memory");
    return -IP_ERRNO_ENOMEM;
#else
    IPCOM_UNUSED_ARG(netif);
    return 0;
#endif /* IPNET_USE_RFC2890 */
}
/*
 *===========================================================================
 *                    ipnet_sockdev_ip_output
 *===========================================================================
 * Description: Updates statistics counter and add the link header (i.e.
 *              sets the LOOPED_BACK flag).
 * Parameters:  netif - The interface the packet was sent to.
 *              rt - The route followed (ignored).
 *              pkt - The packet to loopback. pkt->start is the offset to the
 *              IP header.
 * Returns:     0 = success, 0< = error code.
 *
 */
IP_STATIC int
ipnet_sockdev_ip_output(Ipnet_netif *netif, Ipnet_route_entry *rt, Ipcom_pkt *pkt)
{
    IPCOM_UNUSED_ARG(rt);
    return ipnet_if_output(netif, pkt);
}