コード例 #1
0
static int
linux_if_rx(struct vr_interface *vif, struct vr_packet *pkt)
{
    int rc;
    struct net_device *dev = (struct net_device *)vif->vif_os;
    struct sk_buff *skb = vp_os_packet(pkt);
    struct vr_ip *ip;
    unsigned short network_off, transport_off, cksum_off = 0;

    skb->data = pkt->vp_head + pkt->vp_data;
    skb->len = pkt_len(pkt);
    skb_set_tail_pointer(skb, pkt_head_len(pkt));

    if (!dev) {
        kfree_skb(skb);
        goto exit_rx;
    }

    (void)__sync_fetch_and_add(&dev->stats.rx_bytes, skb->len);
    (void)__sync_fetch_and_add(&dev->stats.rx_packets, 1);

    /* this is only needed for mirroring */
    if ((pkt->vp_flags & VP_FLAG_FROM_DP) &&
            (pkt->vp_flags & VP_FLAG_CSUM_PARTIAL)) {
    	network_off = pkt_get_network_header_off(pkt);
    	ip = (struct vr_ip *)(pkt_data_at_offset(pkt, network_off));
    	transport_off = network_off + (ip->ip_hl * 4);

        if (ip->ip_proto == VR_IP_PROTO_TCP)
            cksum_off = offsetof(struct vr_tcp, tcp_csum);
        else if (ip->ip_proto == VR_IP_PROTO_UDP)
コード例 #2
0
/*
 * This funciton parses the ethernet packet and assigns the
 * pkt->vp_type, network protocol of the packet. The ethernet header can
 * start from an offset from vp_data
 */
int
vr_pkt_type(struct vr_packet *pkt, unsigned short offset,
            struct vr_forwarding_md *fmd)
{
    unsigned char *eth = pkt_data(pkt) + offset;
    unsigned short eth_proto;
    int pull_len, pkt_len = pkt_head_len(pkt) - offset;
    struct vr_vlan_hdr *vlan;

    pull_len = VR_ETHER_HLEN;
    if (pkt_len < pull_len)
        return -1;

    pkt->vp_flags &= ~(VP_FLAG_MULTICAST);

    /* L2 broadcast/multicast packets are multicast packets */
    if (IS_MAC_BMCAST(eth))
        pkt->vp_flags |= VP_FLAG_MULTICAST;

    eth_proto = ntohs(*(unsigned short *)(eth + VR_ETHER_PROTO_OFF));
    while (eth_proto == VR_ETH_PROTO_VLAN) {
        if (pkt_len < (pull_len + sizeof(*vlan)))
            return -1;
        vlan = (struct vr_vlan_hdr *)(eth + pull_len);
        if (fmd && (fmd->fmd_vlan == VLAN_ID_INVALID))
            fmd->fmd_vlan = vlan->vlan_tag & 0xFFF;
        eth_proto = ntohs(vlan->vlan_proto);
        pull_len += sizeof(*vlan);
    }


    pkt_set_network_header(pkt, pkt->vp_data + offset + pull_len);
    pkt_set_inner_network_header(pkt, pkt->vp_data + offset + pull_len);
    pkt->vp_type = vr_eth_proto_to_pkt_type(eth_proto);

    return 0;
}