/*** * rt_packet_rcv */ int rt_packet_rcv(struct rtskb *skb, struct rtpacket_type *pt) { struct rtsocket *sock = (struct rtsocket *)(((u8 *)pt) - ((u8 *)&((struct rtsocket *)0)->prot.packet)); int ifindex = sock->prot.packet.ifindex; void (*callback_func)(struct rtdm_dev_context *, void *); void *callback_arg; unsigned long flags; if (((ifindex != 0) && (ifindex != skb->rtdev->ifindex)) || (rtskb_acquire(skb, &sock->skb_pool) != 0)) kfree_rtskb(skb); else { rtdev_reference(skb->rtdev); rtskb_queue_tail(&sock->incoming, skb); rtos_event_sem_signal(&sock->wakeup_event); rtos_spin_lock_irqsave(&sock->param_lock, flags); callback_func = sock->callback_func; callback_arg = sock->callback_arg; rtos_spin_unlock_irqrestore(&sock->param_lock, flags); if (callback_func) callback_func(rt_socket_context(sock), callback_arg); } return 0; }
/*** * rt_packet_rcv */ int rt_packet_rcv(struct rtskb *skb, struct rtpacket_type *pt) { struct rtsocket *sock = (struct rtsocket *)(((u8 *)pt) - ((u8 *)&((struct rtsocket *)0)->prot.packet)); int ifindex = sock->prot.packet.ifindex; void (*callback_func)(struct rtdm_dev_context *, void *); void *callback_arg; rtdm_lockctx_t context; if (((ifindex != 0) && (ifindex != skb->rtdev->ifindex)) || (rtskb_acquire(skb, &sock->skb_pool) != 0)) kfree_rtskb(skb); else { rtdev_reference(skb->rtdev); rtskb_queue_tail(&sock->incoming, skb); rtdm_sem_up(&sock->pending_sem); rtdm_lock_get_irqsave(&sock->param_lock, context); callback_func = sock->callback_func; callback_arg = sock->callback_arg; rtdm_lock_put_irqrestore(&sock->param_lock, context); if (callback_func) callback_func(rt_socket_context(sock), callback_arg); } return 0; }
/*** * rt_loopback_xmit - begin packet transmission * @skb: packet to be sent * @dev: network device to which packet is sent * */ static int rt_loopback_xmit(struct rtskb *skb, struct rtnet_device *rtdev) { unsigned short hash; struct rtpacket_type *pt_entry; unsigned long flags; rtos_time_t time; /* write transmission stamp - in case any protocol ever gets the idea to ask the lookback device for this service... */ if (skb->xmit_stamp) { rtos_get_time(&time); *skb->xmit_stamp = cpu_to_be64(rtos_time_to_nanosecs(&time) + *skb->xmit_stamp); } /* make sure that critical fields are re-intialised */ skb->chain_end = skb; /* parse the Ethernet header as usual */ skb->protocol = rt_eth_type_trans(skb, rtdev); skb->nh.raw = skb->data; rtdev_reference(rtdev); rtcap_report_incoming(skb); hash = ntohs(skb->protocol) & RTPACKET_HASH_KEY_MASK; rtos_spin_lock_irqsave(&rt_packets_lock, flags); list_for_each_entry(pt_entry, &rt_packets[hash], list_entry) if (pt_entry->type == skb->protocol) { pt_entry->refcount++; rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); pt_entry->handler(skb, pt_entry); rtos_spin_lock_irqsave(&rt_packets_lock, flags); pt_entry->refcount--; rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); goto out; } rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); /* don't warn if running in promiscuous mode (RTcap...?) */ if ((rtdev->flags & IFF_PROMISC) == 0) rtos_print("RTnet: unknown layer-3 protocol\n"); kfree_rtskb(skb); out: rtdev_dereference(rtdev); return 0; }
static int rt_host_route_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { struct host_route *entry_ptr; struct dest_route dest_host; unsigned int key; unsigned int index; unsigned int i; rtdm_lockctx_t context; int res; RTNET_PROC_PRINT_VARS_EX(80); if (!RTNET_PROC_PRINT_EX("Hash\tDestination\tHW Address\t\tDevice\n")) goto done; for (key = 0; key < HOST_HASH_TBL_SIZE; key++) { index = 0; while (1) { rtdm_lock_get_irqsave(&host_table_lock, context); entry_ptr = host_hash_tbl[key]; for (i = 0; (i < index) && (entry_ptr != NULL); i++) entry_ptr = entry_ptr->next; if (entry_ptr == NULL) { rtdm_lock_put_irqrestore(&host_table_lock, context); break; } memcpy(&dest_host, &entry_ptr->dest_host, sizeof(struct dest_route)); rtdev_reference(dest_host.rtdev); rtdm_lock_put_irqrestore(&host_table_lock, context); res = RTNET_PROC_PRINT_EX("%02X\t%u.%u.%u.%-3u\t" "%02X:%02X:%02X:%02X:%02X:%02X\t%s\n", key, NIPQUAD(dest_host.ip), dest_host.dev_addr[0], dest_host.dev_addr[1], dest_host.dev_addr[2], dest_host.dev_addr[3], dest_host.dev_addr[4], dest_host.dev_addr[5], dest_host.rtdev->name); rtdev_dereference(dest_host.rtdev); if (!res) goto done; index++; } } done: RTNET_PROC_PRINT_DONE_EX; }
static int rtcfg_rx_handler(struct rtskb *rtskb, struct rtpacket_type *pt) { if (rtskb_acquire(rtskb, &rtcfg_pool) == 0) { rtdev_reference(rtskb->rtdev); rtskb_queue_tail(&rx_queue, rtskb); rtos_event_sem_signal(&rx_event); } else kfree_rtskb(rtskb); return 0; }
/*** * rt_loopback_xmit - begin packet transmission * @skb: packet to be sent * @dev: network device to which packet is sent * */ static int rt_loopback_xmit(struct rtskb *skb, struct rtnet_device *rtdev) { unsigned short hash; struct rtpacket_type *pt; unsigned long flags; rtos_time_t time; /* write transmission stamp - in case any protocol ever gets the idea to ask the lookback device for this service... */ if (skb->xmit_stamp) { rtos_get_time(&time); *skb->xmit_stamp = cpu_to_be64(rtos_time_to_nanosecs(&time) + *skb->xmit_stamp); } /* make sure that critical fields are re-intialised */ skb->chain_end = skb; /* parse the Ethernet header as usual */ skb->protocol = rt_eth_type_trans(skb, rtdev); skb->nh.raw = skb->data; rtdev_reference(rtdev); rtcap_report_incoming(skb); hash = ntohs(skb->protocol) & (MAX_RT_PROTOCOLS-1); rtos_spin_lock_irqsave(&rt_packets_lock, flags); pt = rt_packets[hash]; if ((pt != NULL) && (pt->type == skb->protocol)) { pt->refcount++; rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); pt->handler(skb, pt); rtos_spin_lock_irqsave(&rt_packets_lock, flags); pt->refcount--; rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); } else { rtos_spin_unlock_irqrestore(&rt_packets_lock, flags); rtos_print("RTnet: unknown layer-3 protocol\n"); kfree_rtskb(skb); } rtdev_dereference(rtdev); return 0; }
static int rt_host_route_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { RTNET_PROC_PRINT_VARS; struct host_route *entry_ptr; struct dest_route dest_host; unsigned int key; unsigned int index; unsigned int i; unsigned long flags; RTNET_PROC_PRINT("Hash\tDestination\tHW Address\t\tDevice\n"); for (key = 0; key < HOST_HASH_TBL_SIZE; key++) { index = 0; while (1) { rtos_spin_lock_irqsave(&host_table_lock, flags); entry_ptr = host_table[key]; for (i = 0; (i < index) && (entry_ptr != NULL); i++) entry_ptr = entry_ptr->next; if (entry_ptr == NULL) { rtos_spin_unlock_irqrestore(&host_table_lock, flags); break; } memcpy(&dest_host, &entry_ptr->dest_host, sizeof(struct dest_route)); rtdev_reference(dest_host.rtdev); rtos_spin_unlock_irqrestore(&host_table_lock, flags); RTNET_PROC_PRINT("%02X\t%u.%u.%u.%-3u\t" "%02X:%02X:%02X:%02X:%02X:%02X\t%s\n", key, NIPQUAD(dest_host.ip), dest_host.dev_addr[0], dest_host.dev_addr[1], dest_host.dev_addr[2], dest_host.dev_addr[3], dest_host.dev_addr[4], dest_host.dev_addr[5], dest_host.rtdev->name); rtdev_dereference(dest_host.rtdev); index++; } } RTNET_PROC_PRINT_DONE; }
/*** * rt_packet_rcv */ int rt_packet_rcv(struct rtskb *skb, struct rtpacket_type *pt) { struct rtsocket *sock = (struct rtsocket *)(((u8 *)pt) - ((u8 *)&((struct rtsocket *)0)->prot.packet)); if (((sock->prot.packet.ifindex != 0) && (sock->prot.packet.ifindex != skb->rtdev->ifindex)) || (rtskb_acquire(skb, &sock->skb_pool) != 0)) kfree_rtskb(skb); else { rtdev_reference(skb->rtdev); rtskb_queue_tail(&sock->incoming, skb); rtos_event_signal(&sock->wakeup_event); if (sock->wakeup != NULL) sock->wakeup(sock->fd, sock->wakeup_arg); } return 0; }
int rtmac_vnic_rx(struct rtskb *rtskb, u16 type) { struct rtmac_priv *mac_priv = rtskb->rtdev->mac_priv; struct rtskb_queue *pool = &mac_priv->vnic_skb_pool; if (rtskb_acquire(rtskb, pool) != 0) { mac_priv->vnic_stats.rx_dropped++; kfree_rtskb(rtskb); return -1; } rtskb->protocol = type; rtdev_reference(rtskb->rtdev); rtskb_queue_tail(&rx_queue, rtskb); rtdm_nrtsig_pend(&vnic_signal); return 0; }