コード例 #1
0
enum ofp_return_code ofp_ipv6_processing(odp_packet_t *pkt)
{
	int res;
	int protocol = IS_IPV6;
	uint32_t flags;
	struct ofp_ip6_hdr *ipv6;
	struct ofp_nh6_entry *nh;
	struct ofp_ifnet *dev = odp_packet_user_ptr(*pkt);
	int is_ours = 0;

	ipv6 = (struct ofp_ip6_hdr *)odp_packet_l3_ptr(*pkt, NULL);

	if (odp_unlikely(ipv6 == NULL))
		return OFP_PKT_DROP;

	/* is ipv6->dst_addr one of my IPv6 addresses from this interface*/
	if (ofp_ip6_equal(dev->ip6_addr, ipv6->ip6_dst.ofp_s6_addr) ||
		OFP_IN6_IS_SOLICITED_NODE_MC(ipv6->ip6_dst, dev->ip6_addr) ||
		(memcmp((const void *)((uintptr_t)dev->link_local + 8),
		(const void *)((uintptr_t)ipv6->ip6_dst.ofp_s6_addr + 8),
			2 * sizeof(uint32_t)) == 0)) {

			is_ours = 1;
	}
	/* check if it's ours for another ipv6 address */
	if (!is_ours) {
		nh = ofp_get_next_hop6(dev->vrf, ipv6->ip6_dst.ofp_s6_addr, &flags);
		if (nh && (nh->flags & OFP_RTF_LOCAL))
			is_ours = 1;
	}

	if (is_ours) {
		OFP_HOOK(OFP_HOOK_LOCAL, *pkt, &protocol, &res);
		if (res != OFP_PKT_CONTINUE) {
			OFP_DBG("OFP_HOOK_LOCAL returned %d", res);
			return res;
		}

		OFP_HOOK(OFP_HOOK_LOCAL_IPv6, *pkt, NULL, &res);
		if (res != OFP_PKT_CONTINUE) {
			OFP_DBG("OFP_HOOK_LOCAL_IPv6 returned %d", res);
			return res;
		}

		return ipv6_transport_classifier(pkt, ipv6->ofp_ip6_nxt);

	}

	OFP_HOOK(OFP_HOOK_FWD_IPv6, *pkt, NULL, &res);
	if (res != OFP_PKT_CONTINUE) {
		OFP_DBG("OFP_HOOK_FWD_IPv6 returned %d", res);
		return res;
	}

	nh = ofp_get_next_hop6(dev->vrf, ipv6->ip6_dst.ofp_s6_addr, &flags);
	if (nh == NULL)
		return OFP_PKT_CONTINUE;

	return ofp_ip6_output(*pkt, nh);
}
コード例 #2
0
ファイル: ofp_test_packet_output.c プロジェクト: fboudra/ofp
static void
test_hook_out_ipv6(void)
{
	int res;
	odp_packet_t pkt = ODP_PACKET_INVALID;

	if (create_odp_packet_ip6(&pkt, ip6udp_frame, sizeof(ip6udp_frame))) {
		CU_FAIL("Fail to create packet");
		return;
	}

	my_test_val = TEST_HOOK_OUT_IPv6;
	res = ofp_ip6_output(pkt, NULL);
	my_test_val = 0;

	CU_ASSERT_EQUAL(res, TEST_HOOK_OUT_IPv6_VALUE);
	CU_PASS("test_hook_out_ipv6");
}
コード例 #3
0
ファイル: ofp_test_packet_output.c プロジェクト: fboudra/ofp
static void
test_packet_output_ipv6_to_gre(void)
{
	odp_packet_t pkt = ODP_PACKET_INVALID;
	odp_event_t ev;
	int res;
	struct ofp_ether_header *eth;
	struct ofp_ip6_hdr *ip6, *ip6_orig;
	struct ofp_ip *ip;
	struct ofp_greip *greip;

	(void)tcp_frame;
	(void)icmp_frame;
	(void)arp_frame;
	(void)icmp6_frame;

	if (create_odp_packet_ip6(&pkt, ip6udp_frame, sizeof(ip6udp_frame))) {
		CU_FAIL("Fail to create packet");
		return;
	}

	ip6 = odp_packet_l3_ptr(pkt, NULL);

	ofp_set_route6_params(OFP_ROUTE6_ADD, 0 /*vrf*/, 100 /*vlan*/, GRE_PORTS,
			      ip6->ip6_dst.__u6_addr.__u6_addr8, 64 /*masklen*/,
			      0 /*gw*/, OFP_RTF_NET /* flags */);

	res = ofp_ip6_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(ip6udp_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_IPV6));

	/* inner ip */
	ip6 = (struct ofp_ip6_hdr *)(greip + 1);
	ip6_orig = (struct ofp_ip6_hdr *)
		(&orig_pkt_data[OFP_ETHER_HDR_LEN]);
	if (memcmp(ip6, ip6_orig,
		   odp_be_to_cpu_16(ip6_orig->ofp_ip6_plen) + sizeof(*ip6)))
		CU_FAIL("Inner IP packet error.");
}