static void test_send_frame_vlan_to_vlan(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; uint8_t check_buf[144]; int res; if (create_odp_packet_ip4(&pkt, test_frame_vlan, sizeof(test_frame_vlan), 0)) { CU_FAIL("Fail to create packet"); return; } memcpy(check_buf, test_frame_vlan, sizeof(test_frame_vlan)); check_buf[15] = dev_vlan->vlan; res = ofp_send_frame(dev_vlan, pkt); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt), sizeof(test_frame_vlan)); if (memcmp(odp_packet_l2_ptr(pkt, NULL), check_buf, sizeof(test_frame_vlan))) CU_FAIL("Frame data mismatch."); }
static void test_ofp_packet_input_to_sp(void) { odp_packet_t pkt; odp_event_t ev; int res; my_test_val = TEST_FORWARD_HOOK; /* Call ofp_packet_input using a pkt with destination ip * that does NOT match the local ip on ifnet and NO route is found. * The packet is forwarded to slow path queue. */ if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), 0, 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); CU_ASSERT_NOT_EQUAL(ev = odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); if (memcmp(odp_packet_data(odp_packet_from_event(ev)), in_pkt_data, sizeof(test_frame))) CU_FAIL("corrupt data sent to slow path"); odp_packet_free(odp_packet_from_event(ev)); CU_PASS("ofp_packet_input_to_sp"); }
static void test_packet_output_gre_no_nexthop(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; int res; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), tun_p2p + 1)) { CU_FAIL("Fail to create packet"); return; } /* * Packet's destination is GRE tunnel's p2p address, no next hop * is found for tunnel destination address, packet is dropped. */ res = ofp_ip_output(pkt, NULL); CU_ASSERT_EQUAL(res, OFP_PKT_DROP); res = ofp_send_pending_pkt(); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); }
static void test_ofp_packet_input_local_UDPv4_hook(void) { odp_packet_t pkt; int res; /* Call ofp_packet_input with a pkt with destination ip * that matches the local ip on ifnet. * The packet is terminated in local UDPv4 hook */ my_test_val = TEST_LOCAL_UDPv4_HOOK; ifnet->ip_addr = dst_ipaddr; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), dst_ipaddr, 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_TEST_LOCAL_UDPv4_HOOK); #ifdef SP CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); #endif /* SP */ CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); ifnet->ip_addr = 0; CU_PASS("ofp_packet_input_local_UDPv4_hook"); }
/* * Tests */ static void test_packet_output_gre(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; int res; struct ofp_ether_header *eth; struct ofp_ip *ip; struct ofp_ip *ip_orig; struct ofp_greip *greip; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), tun_p2p)) { CU_FAIL("Fail to create packet"); return; } /* * Packet's destination is GRE tunnel's p2p address, next hop is GRE * interface. GRE+IP header is prepended. Packet's new destination is * link local. Packet is put into output queue. */ res = ofp_ip_output(pkt, NULL); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); res = ofp_send_pending_pkt(); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt), sizeof(test_frame) + 20 + 4); eth = odp_packet_l2_ptr(pkt, NULL); if (memcmp(eth->ether_dhost, tun_rem_mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); ip = odp_packet_l3_ptr(pkt, NULL); CU_ASSERT_EQUAL(ip->ip_src.s_addr, dev_ip); CU_ASSERT_EQUAL(ip->ip_dst.s_addr, tun_rem_ip); CU_ASSERT_EQUAL(ip->ip_p, OFP_IPPROTO_GRE); greip = (struct ofp_greip *)ip; CU_ASSERT_EQUAL(greip->gi_g.flags, 0); CU_ASSERT_EQUAL(greip->gi_g.ptype, odp_cpu_to_be_16(OFP_ETHERTYPE_IP)); /* inner ip */ ip = (struct ofp_ip *)(greip + 1); ip_orig = (struct ofp_ip *)(&orig_pkt_data[OFP_ETHER_HDR_LEN]); if (memcmp(ip, ip_orig, odp_be_to_cpu_16(ip_orig->ip_len))) CU_FAIL("Inner IP packet error."); }
static void test_ofp_packet_input_gre_orig_pkt_to_sp(void) { odp_packet_t pkt; int res; #ifdef SP odp_event_t ev; #endif my_test_val = TEST_LOCAL_HOOK_GRE_APP; /* Call ofp_packet_input using a GRE pkt with destination ip * that matches the local ip on ifnet, tunnel not found, * packet offered to GRE hook, returns continue. * Full packet sent to slowpath */ ifnet->ip_addr = local_ip; if (create_odp_packet_ip4(&pkt, gre_frame, sizeof(gre_frame), local_ip, tun_rem_ip + 1)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); #ifdef SP CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); CU_ASSERT_NOT_EQUAL_FATAL(ev = odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); if (memcmp(odp_packet_data(odp_packet_from_event(ev)), in_pkt_data, sizeof(gre_frame))) CU_FAIL("corrupt data sent to slow path"); odp_packet_free(odp_packet_from_event(ev)); ifnet->ip_addr = 0; CU_PASS("ofp_packet_input_gre_orig_pkt_to_sp"); #else CU_ASSERT_EQUAL(res, OFP_PKT_DROP); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); #endif }
static void test_ofp_packet_input_send_arp(void) { odp_packet_t pkt; odp_event_t ev; int res; /* Call ofp_packet_input using a pkt with destination ip * that does NOT match the local ip on ifnet and a route is found. * No ARP is found for gateway IP so an ARP req is sent. * Function returns OFP_PKT_DROP and packet can be reused.*/ my_test_val = TEST_FORWARD_HOOK; test_ofp_add_route(port, vrf, vlan, dst_ipaddr, 24, 4, dst_ipaddr + 1); if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), dst_ipaddr, 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); odp_packet_free(pkt); CU_ASSERT_NOT_EQUAL(ev = odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); #ifdef SP CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); #endif /* SP */ pkt = odp_packet_from_event(ev); CU_ASSERT_NOT_EQUAL(pkt, ODP_PACKET_INVALID); CU_ASSERT_EQUAL(odp_packet_has_arp(pkt), 1); CU_ASSERT_EQUAL(odp_packet_has_vlan(pkt), 0); CU_ASSERT_EQUAL(odp_packet_len(pkt), sizeof(struct ofp_arphdr) + sizeof(struct ofp_ether_header)); odp_packet_free(odp_packet_from_event(ev)); ofp_arp_init_tables(); /* to clean saved packet */ CU_PASS("ofp_packet_input_send_arp"); }
static void test_hook_out_ipv4(void) { int res; odp_packet_t pkt = ODP_PACKET_INVALID; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), tun_p2p)) { CU_FAIL("Fail to create packet"); return; } my_test_val = TEST_HOOK_OUT_IPv4; res = ofp_ip_output(pkt, NULL); my_test_val = 0; CU_ASSERT_EQUAL(res, TEST_HOOK_OUT_IPv4_VALUE); CU_PASS("test_hook_out_ipv4"); }
static void test_packet_size_is_less_then_mtu(void) { odp_packet_t pkt_orig, pkt_sent; odp_event_t ev; int res; struct ofp_ether_header *eth; if (create_odp_packet_ip4(&pkt_orig, pkt1_frag1, sizeof(pkt1_frag1), 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_ip_output(pkt_orig, &nexthop); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); res = ofp_send_pending_pkt(); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); CU_ASSERT_EQUAL_FATAL(odp_queue_deq(dev->outq_def), ODP_EVENT_INVALID); pkt_sent = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt_sent), sizeof(pkt1_frag1)); eth = odp_packet_l2_ptr(pkt_sent, NULL); if (memcmp(eth->ether_dhost, dst_mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); if (memcmp(odp_packet_l3_ptr(pkt_sent, NULL), &orig_pkt_data[OFP_ETHER_HDR_LEN], sizeof(pkt1_frag1) - OFP_ETHER_HDR_LEN)) CU_FAIL("corrupt l3 + data forwarded"); CU_PASS("Correct packet"); odp_packet_free(pkt_sent); }
static void test_send_frame_novlan_to_vlan(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; struct ofp_ether_vlan_header *eth_vlan; uint8_t *buf; int res; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_send_frame(dev_vlan, pkt); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt), sizeof(test_frame) + 4); eth_vlan = odp_packet_l2_ptr(pkt, NULL); if (memcmp(eth_vlan, test_frame, 2 * OFP_ETHER_ADDR_LEN)) CU_FAIL("Frame data mismatch."); CU_ASSERT_EQUAL(eth_vlan->evl_encap_proto, odp_cpu_to_be_16(OFP_ETHERTYPE_VLAN)); CU_ASSERT_EQUAL(eth_vlan->evl_tag, odp_cpu_to_be_16(dev_vlan->vlan)); buf = (uint8_t *)eth_vlan; if (memcmp(&buf[16], &test_frame[12], sizeof(test_frame) - 2 * OFP_ETHER_ADDR_LEN)) CU_FAIL("Frame data mismatch."); }
static void test_send_frame_packet_len_bigger_than_mtu(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; uint32_t old_mtu; int res; if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), 0)) { CU_FAIL("Fail to create packet"); return; } old_mtu = dev->if_mtu; dev->if_mtu = 120; res = ofp_send_frame(dev, pkt); CU_ASSERT_EQUAL(res, OFP_PKT_DROP); dev->if_mtu = old_mtu; ev = odp_queue_deq(dev->outq_def); CU_ASSERT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); }
static void test_dont_fragment_set_pkt_dropped(void) { odp_packet_t pkt; odp_event_t ev; int res; struct ofp_ip *ip; if (create_odp_packet_ip4(&pkt, pkt1_full, sizeof(pkt1_full), 0)) { CU_FAIL("Fail to create packet"); return; } ip = odp_packet_l3_ptr(pkt, NULL); ip->ip_off |= odp_cpu_to_be_16(OFP_IP_DF); res = ofp_ip_output(pkt, &nexthop); CU_ASSERT_EQUAL(res, OFP_PKT_DROP); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_EQUAL(ev, ODP_EVENT_INVALID); odp_packet_free(pkt); }
static void test_fragment_fragmented_to_two(void) { odp_packet_t pkt_orig, pkt_sent; odp_event_t ev; int res; struct ofp_ether_header *eth; struct ofp_ip *ip; struct ofp_ip *ip_orig; uint16_t pl_pos, pl_len, orig_pl_len, pktlen, start_offset; dev->if_mtu = 620; if (create_odp_packet_ip4(&pkt_orig, pkt1_frag2, sizeof(pkt1_frag2), 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_ip_output(pkt_orig, &nexthop); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); res = ofp_send_pending_pkt(); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); /* ASSERT 1st fragment */ ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt_sent = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt_sent), dev->if_mtu + OFP_ETHER_HDR_LEN); eth = odp_packet_l2_ptr(pkt_sent, NULL); if (memcmp(eth->ether_dhost, dst_mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); ip = odp_packet_l3_ptr(pkt_sent, NULL); ip_orig = (struct ofp_ip *)(&orig_pkt_data[OFP_ETHER_HDR_LEN]); orig_pl_len = odp_be_to_cpu_16(ip_orig->ip_len) - (ip_orig->ip_hl<<2); start_offset = odp_be_to_cpu_16(ip_orig->ip_off) & OFP_IP_OFFMASK; assert_ip_header(ip, ip_orig, dev->if_mtu, 1, start_offset); pl_len = dev->if_mtu - (ip->ip_hl<<2); if (memcmp((uint8_t *)ip + (ip->ip_hl<<2), (uint8_t *)ip_orig + (ip_orig->ip_hl<<2), pl_len)) CU_FAIL("corrupt l3 + data forwarded"); pl_pos = pl_len; CU_PASS("Correct packet"); odp_packet_free(pkt_sent); /* ASSERT 2nd fragment */ ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt_sent = odp_packet_from_event(ev); pl_len = orig_pl_len - pl_pos; pktlen = pl_len + OFP_ETHER_HDR_LEN + sizeof(struct ofp_ip); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt_sent), pktlen); eth = odp_packet_l2_ptr(pkt_sent, NULL); if (memcmp(eth->ether_dhost, dst_mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); ip = odp_packet_l3_ptr(pkt_sent, NULL); assert_ip_header(ip, ip_orig, pl_len + sizeof(struct ofp_ip), 0, start_offset + pl_pos/8); if (memcmp((uint8_t *)ip + (ip->ip_hl<<2), (uint8_t *)ip_orig + (ip_orig->ip_hl<<2) + pl_pos, pl_len)) CU_FAIL("corrupt l3 + data forwarded"); CU_PASS("Correct packet"); odp_packet_free(pkt_sent); /* no more fragments */ ev = odp_queue_deq(dev->outq_def); CU_ASSERT_EQUAL(ev, ODP_EVENT_INVALID); dev->if_mtu = def_mtu; }
static void test_ofp_packet_input_gre_processed_inner_pkt_forwarded(void) { odp_packet_t pkt; odp_event_t ev; int res; struct ofp_ether_header *eth; struct ofp_ip *ip; struct ofp_ip *ip_encap; uint32_t dst_ip; uint8_t dst_mac_addr[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; my_test_val = TEST_LOCAL_HOOK_GRE; /* Call ofp_packet_input using a GRE pkt with destination ip * that matches the local ip on ifnet, tunnel found, GRE processed. * Inner packet does not match local ip, route found, * packet forwarded */ ifnet->ip_addr = local_ip; if (create_odp_packet_ip4(&pkt, gre_frame, sizeof(gre_frame), local_ip, tun_rem_ip)) { CU_FAIL("Fail to create packet"); return; } ip_encap = (struct ofp_ip *)&in_pkt_data[38]; dst_ip = local_ip + 10; test_ofp_add_route(port, vrf, vlan, ip_encap->ip_dst.s_addr, 24, 4, dst_ip); ofp_arp_ipv4_insert(dst_ip, dst_mac_addr, ifnet); res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); CU_ASSERT_NOT_EQUAL_FATAL(ev = odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); #ifdef SP CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); #endif CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); pkt = odp_packet_from_event(ev); eth = odp_packet_data(pkt); ip = odp_packet_l3_ptr(pkt, NULL); if (memcmp(eth->ether_dhost, dst_mac_addr, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, ifnet->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); CU_ASSERT_EQUAL(ip->ip_src.s_addr, ip_encap->ip_src.s_addr); CU_ASSERT_EQUAL(ip->ip_dst.s_addr, ip_encap->ip_dst.s_addr); if (memcmp(ip + (ip->ip_hl << 2), ip_encap + (ip->ip_hl << 2), odp_be_to_cpu_16(ip_encap->ip_len) - (ip->ip_hl << 2))) CU_FAIL("corrupt l3 + data"); odp_packet_free(odp_packet_from_event(ev)); ifnet->ip_addr = 0; CU_PASS("ofp_packet_input_gre_processed_inner_pkt_to_sp"); }
static void test_ofp_packet_input_forwarding_to_output(void) { odp_packet_t pkt; odp_event_t ev; int res; /* Call ofp_packet_input using a pkt with destination ip * that does NOT match the local ip on ifnet and a route is found. * ARP is found for gateway IP. * Function returns OFP_PKT_PROCESSED and * packet is forwarded to ofp_ip_output.*/ unsigned char ll_addr[13] = "123456789012"; my_test_val = TEST_FORWARD_HOOK; CU_ASSERT_EQUAL( ofp_ipv4_lookup_mac(dst_ipaddr + 1, ll_addr, ifnet), -1); CU_ASSERT_EQUAL( ofp_arp_ipv4_insert(dst_ipaddr + 1, ll_addr, ifnet), 0); if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), dst_ipaddr, 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); CU_ASSERT_NOT_EQUAL(ev = odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); #ifdef SP CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); #endif /* SP */ CU_ASSERT_EQUAL(odp_packet_len(pkt), sizeof(test_frame)); pkt = odp_packet_from_event(ev); struct ofp_ip *ip_in_pkt_data = (struct ofp_ip *)(in_pkt_data + OFP_ETHER_HDR_LEN); ip_in_pkt_data->ip_ttl--; #ifdef OFP_PERFORMANCE /*checksum is not filled on ip_output*/ ip_in_pkt_data->ip_sum = ((struct ofp_ip *)odp_packet_l3_ptr(pkt, NULL))->ip_sum; #else ip_in_pkt_data->ip_sum = 0; ip_in_pkt_data->ip_sum = ofp_cksum_buffer((uint16_t *)ip_in_pkt_data, ip_in_pkt_data->ip_hl<<2); #endif if (memcmp((uint8_t *)odp_packet_data(pkt) + odp_packet_l3_offset(pkt), in_pkt_data + OFP_ETHER_HDR_LEN, sizeof(test_frame) - OFP_ETHER_HDR_LEN)) CU_FAIL("corrupt l3 + data forwarded"); struct ofp_ether_header *eth = (struct ofp_ether_header *)odp_packet_l2_ptr(pkt, NULL); if (memcmp(eth->ether_dhost, ll_addr, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address on the forwarded packet"); CU_ASSERT_EQUAL(eth->ether_type, odp_cpu_to_be_16(OFP_ETHERTYPE_IP)); CU_PASS("ofp_packet_input_forwarding_to_output"); }