| 52 | }; |
| 53 | |
| 54 | void EtherEncap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { |
| 55 | int cnt = batch->cnt(); |
| 56 | |
| 57 | for (int i = 0; i < cnt; i++) { |
| 58 | bess::Packet *pkt = batch->pkts()[i]; |
| 59 | |
| 60 | Ethernet::Address ether_src; |
| 61 | Ethernet::Address ether_dst; |
| 62 | bess::utils::be16_t ether_type; |
| 63 | |
| 64 | ether_src = get_attr<Ethernet::Address>(this, ATTR_R_ETHER_SRC, pkt); |
| 65 | ether_dst = get_attr<Ethernet::Address>(this, ATTR_R_ETHER_DST, pkt); |
| 66 | ether_type = get_attr<bess::utils::be16_t>(this, ATTR_R_ETHER_TYPE, pkt); |
| 67 | |
| 68 | Ethernet *eth = static_cast<Ethernet *>(pkt->prepend(sizeof(*eth))); |
| 69 | |
| 70 | // not enough headroom? |
| 71 | if (unlikely(!eth)) { |
| 72 | continue; |
| 73 | } |
| 74 | |
| 75 | eth->dst_addr = ether_dst; |
| 76 | eth->src_addr = ether_src; |
| 77 | eth->ether_type = ether_type; |
| 78 | } |
| 79 | |
| 80 | RunNextModule(ctx, batch); |
| 81 | } |
| 82 | |
| 83 | ADD_MODULE(EtherEncap, "ether_encap", |
| 84 | "encapsulates packets with an Ethernet header") |