/* *=========================================================================== * 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; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * 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); }
/* *=========================================================================== * 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); }