示例#1
0
static int fb_udp_netrx_out(const struct fblock * const fb,
			    struct sk_buff * const skb)
{
	int fdrop = 0;
	idp_t next_fb;
	unsigned int seq;
	struct udphdr *hdr;
	struct fb_udp_priv *fb_priv;

	fb_priv = rcu_dereference_raw(fb->private_data);
	do {
		seq = read_seqbegin(&fb_priv->lock);
		next_fb = fb_priv->port[TYPE_EGRESS];
		if (next_fb == IDP_UNKNOWN)
			fdrop = 1;
	} while (read_seqretry(&fb_priv->lock, seq));
	if (fdrop)
		goto drop;

	hdr = (struct udphdr *) skb_push(skb, sizeof(*hdr));
	if (!hdr)
		goto drop;

	hdr->source = htons(fb_priv->own_port);
	hdr->dest = htons(fb_priv->rem_port);
	hdr->len = htons(skb->len);
	hdr->check = 0;

	write_next_idp_to_skb(skb, fb->idp, next_fb);
	return PPE_SUCCESS;
drop:
	kfree_skb(skb);
	return PPE_DROPPED;
}
示例#2
0
static int fb_counter_netrx(const struct fblock * const fb,
			    struct sk_buff * const skb,
			    enum path_type * const dir)
{
	int drop = 0;
	unsigned int seq;
	struct fb_counter_priv __percpu *fb_priv_cpu;

	fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(fb->private_data));
	prefetchw(skb->cb);
	do {
		seq = read_seqbegin(&fb_priv_cpu->lock);
		write_next_idp_to_skb(skb, fb->idp, fb_priv_cpu->port[*dir]);
		if (fb_priv_cpu->port[*dir] == IDP_UNKNOWN)
			drop = 1;
	} while (read_seqretry(&fb_priv_cpu->lock, seq));

	u64_stats_update_begin(&fb_priv_cpu->syncp);
	fb_priv_cpu->packets++;
	fb_priv_cpu->bytes += skb->len;
	u64_stats_update_end(&fb_priv_cpu->syncp);

	if (drop) {
		kfree_skb(skb);
		return PPE_DROPPED;
	}
	return PPE_SUCCESS;
}
示例#3
0
文件: fb_bpf.c 项目: digideskio/lana
static int fb_bpf_netrx(const struct fblock * const fb,
			struct sk_buff * const skb,
			enum path_type * const dir)
{
	int drop = 0;
	unsigned int pkt_len;
	unsigned long flags;
	struct fb_bpf_priv __percpu *fb_priv_cpu;

	fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(fb->private_data));

	spin_lock_irqsave(&fb_priv_cpu->flock, flags);
	if (fb_priv_cpu->filter) {
		pkt_len = SK_RUN_FILTER(fb_priv_cpu->filter, skb);
		if (pkt_len < skb->len) {
			spin_unlock_irqrestore(&fb_priv_cpu->flock, flags);
			kfree_skb(skb);
			return PPE_DROPPED;
		}
	}
	write_next_idp_to_skb(skb, fb->idp, fb_priv_cpu->port[*dir]);
	if (fb_priv_cpu->port[*dir] == IDP_UNKNOWN)
		drop = 1;
	spin_unlock_irqrestore(&fb_priv_cpu->flock, flags);
	if (drop) {
		kfree_skb(skb);
		return PPE_DROPPED;
	}
	return PPE_SUCCESS;
}
示例#4
0
static int fb_huf_netrx(const struct fblock * const fb,
			  struct sk_buff * const skb,
			  enum path_type * const dir)
{
	unsigned int seq;
//	unsigned int padding;
	struct fb_huf_priv *fb_priv;
//	size_t i = 0;
//	unsigned char ciphertext[16];

	fb_priv = rcu_dereference_raw(fb->private_data);
	do {
		seq = read_seqbegin(&fb_priv->lock);
		write_next_idp_to_skb(skb, fb->idp, fb_priv->port[*dir]);
		if (fb_priv->port[*dir] == IDP_UNKNOWN)
			goto drop;
	} while (read_seqretry(&fb_priv->lock, seq));

	read_lock(&fb_priv->klock);

	//send it trough compression
	compress(skb);	

	read_unlock(&fb_priv->klock);

	return PPE_SUCCESS;
drop:
	printk(KERN_INFO "[fb_aes] drop packet. Out of key material?\n");
	kfree_skb(skb);
	return PPE_DROPPED;
}
示例#5
0
static int fb_crr_rx_netrx(const struct fblock * const fb,
			  struct sk_buff * const skb,
			  enum path_type * const dir)
{
	int drop = 0;
	unsigned int i, queue_len;
	unsigned char mac_src[6];
	unsigned char mac_dst[6];
	unsigned char seq, win_nr;
	struct sk_buff *skb_last, *cloned_skb;
	struct fb_crr_rx_priv __percpu *fb_priv_cpu;

	fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(fb->private_data));
#ifdef __DEBUG
	printk("Got skb on %p on ppe%d!\n", fb, smp_processor_id());
#endif
	prefetchw(skb->cb);
	do {
		seq = read_seqbegin(&fb_priv_cpu->lock);			// LOCK
		write_next_idp_to_skb(skb, fb->idp, fb_priv_cpu->port[*dir]);
		if (fb_priv_cpu->port[*dir] == IDP_UNKNOWN)
			drop = 1;
	} while (read_seqretry(&fb_priv_cpu->lock, seq));			// UNLOCK
	/* Send */
	if (*dir == TYPE_EGRESS && ntohs(eth_hdr(skb)->h_proto) == 0xabba) {

	}
	/* Receive */
	else if (*dir == TYPE_INGRESS && ntohs(eth_hdr(skb)->h_proto) == 0xabba) {
		cloned_skb = NULL;
		seq = *(skb->data + ETH_HDR_LEN);
		win_nr = *(skb->data + ETH_HDR_LEN+1);
		printk(KERN_ERR "Received packet %d\n", *(skb->data + ETH_HDR_LEN+2));
		write_lock(fb_priv_cpu->rx_lock);
		if (win_nr != *fb_priv_cpu->rx_win_nr) {			// new window
			*fb_priv_cpu->rx_bitstream = 0;				// Reset bitstream for new window
			*fb_priv_cpu->rx_win_nr = win_nr;
			printk(KERN_ERR "New window detected\n");	
		}				
		printk(KERN_ERR "Expected: %d\t Received: %d\n", *fb_priv_cpu->rx_seq_nr, seq);	
		if (likely(seq == *fb_priv_cpu->rx_seq_nr)) {
			//printk(KERN_ERR "Correct Seqnr: %d\n", seq);		/* R Correct sequence number: */
			*fb_priv_cpu->rx_seq_nr = (*fb_priv_cpu->rx_seq_nr % (2*WIN_SZ)) + 1;
			queue_len = skb_queue_len(fb_priv_cpu->list);
			printk(KERN_ERR "Qlen: %d\n", queue_len);
			if(unlikely(!set_bit_pos(fb_priv_cpu->rx_bitstream, seq)))
				printk(KERN_ERR "There is a Bug!\n");		
			for (i = 1; i <= queue_len; i++) { 			/* R iterate over nr elements in queue */
				printk(KERN_ERR "%d\n", i);
				skb_last = skb_peek(fb_priv_cpu->list);
				printk(KERN_ERR "First Seqnr in Queue: %d\n", *(skb_last->data + ETH_HDR_LEN));
				if (*(skb_last->data + ETH_HDR_LEN) == (seq % 2*WIN_SZ) + i) {
					printk(KERN_ERR "Send following Seqnr: %d\n", (seq % 2*WIN_SZ) + i);
					skb_last = skb_dequeue(fb_priv_cpu->list);/* Remove first element in list */
					rcu_read_lock();
					process_packet(skb_last, *dir);		/* Send towards user space */
					rcu_read_unlock();
					*fb_priv_cpu->rx_seq_nr = (*fb_priv_cpu->rx_seq_nr % (2*WIN_SZ)) + 1;
				}
				else {
					printk(KERN_ERR "Following Seqnr not found: %d\n", (seq % 2*WIN_SZ) + i);	/* if next missing -> break */
					break;
				}	
			}
			//printk(KERN_ERR "Next Seqnr expected: %d\n", *fb_priv_cpu->rx_seq_nr);
			write_unlock(fb_priv_cpu->rx_lock);			// UNLOCK
		}
		else {
			//printk(KERN_ERR "Wrong Seqnr: %d\n", seq);		/* Wrong Seq number -> keep in buffer */
			if (likely(set_bit_pos(fb_priv_cpu->rx_bitstream, seq))) {	/* New packet -> pass */
				if (!(skb_last = skb_get_pos(seq, fb_priv_cpu->list))) {
					write_unlock(fb_priv_cpu->rx_lock);		// UNLOCK
					drop = 1;
					goto ACK;
				}
				skb_insert(skb_last, skb, fb_priv_cpu->list); 	/* W insert to position */
				queue_len = skb_queue_len(fb_priv_cpu->list);
				printk(KERN_ERR "Added New Qlen: %d\n", queue_len);
				write_unlock(fb_priv_cpu->rx_lock);		// UNLOCK
				drop = 2;
			}
			else {							/* Old packet -> drop */
				write_unlock(fb_priv_cpu->rx_lock);		// UNLOCK
				drop = 1;					/* Received packet for second time */
			}
		}
		//printk(KERN_ERR "Send ACK!\n");
		goto ACK;
	}
back:	
	if (drop == 1) {
		kfree_skb(skb);
		//printk(KERN_ERR "Freed and dropped!\n");
		return PPE_DROPPED;
	}
	else if (drop == 2) {
		//printk(KERN_ERR "Dropped!\n");
		return PPE_DROPPED;
	}
	//printk(KERN_ERR "Passed on!\n");
	return PPE_SUCCESS;
ACK:
	if ((cloned_skb = skb_copy(skb, GFP_ATOMIC))) {				// skb_copy_expand(skb, 14, 0, GFP_ATOMIC)

		skb_push(cloned_skb, 14);
		//skb_set_mac_header(cloned_skb, -14);

		/*for (i = 0; i < 20; i++)
			printk(KERN_ERR "%d\t0x%2x\n", i, *(skb->data-14+i));	
		
		for (i = 0; i < 20; i++)
			printk(KERN_ERR "%d\t0x%2x\n", i, *(cloned_skb->data-14+i));*/
							
		memcpy(mac_src, eth_hdr(cloned_skb)->h_source, 6);		/* Swap MAC Addresses */
		memcpy(mac_dst, eth_hdr(cloned_skb)->h_dest, 6);
		memcpy(eth_hdr(cloned_skb)->h_source, mac_dst, 6);
		memcpy(eth_hdr(cloned_skb)->h_dest, mac_src, 6);
										
		*(cloned_skb->data + ETH_HDR_LEN + 14) = seq;
		*(cloned_skb->data + ETH_HDR_LEN + 14+1) = 0xFF;
										/* change idp order */
		read_lock(fb_priv_cpu->rx_lock);				// LOCK		
		write_next_idp_to_skb(cloned_skb, fb_priv_cpu->port[TYPE_EGRESS], fb->idp); /* R on port */
		read_unlock(fb_priv_cpu->rx_lock);				// UNLOCK
		rcu_read_lock();		
		process_packet(cloned_skb, TYPE_EGRESS);			/* schedule packet */
		rcu_read_unlock();
		printk(KERN_ERR "Send ACK done!\n");	
	}
	goto back;

}