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; }
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; }
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; }
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; }
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; }