Пример #1
0
static enum ofp_return_code ofp_output_ipv4_to_gre(
	odp_packet_t pkt, struct ofp_ifnet *dev_gre,
	uint16_t vrfid,	struct ofp_nh_entry **nh_new)
{
	struct ofp_ip	*ip;
	struct ofp_greip *greip;
	uint32_t flags;
	uint8_t	l2_size = 0;
	int32_t	offset;

	*nh_new = ofp_get_next_hop(vrfid, dev_gre->ip_remote, &flags);

	if (*nh_new == NULL)
		return OFP_PKT_DROP;

	ip = odp_packet_l3_ptr(pkt, NULL);

	/* Remove eth header, prepend gre + ip */
	if (odp_packet_has_l2(pkt))
		l2_size = odp_packet_l3_offset(pkt) - odp_packet_l2_offset(pkt);

	offset = sizeof(*greip) - l2_size;
	if (offset >= 0)
		greip = odp_packet_push_head(pkt, offset);
	else
		greip = odp_packet_pull_head(pkt, -offset);

	odp_packet_has_l2_set(pkt, 0);
	odp_packet_l3_offset_set(pkt, 0);

	if (!greip)
		return OFP_PKT_DROP;

	greip->gi_flags = 0;
	greip->gi_ptype = odp_cpu_to_be_16(OFP_GREPROTO_IP);

	greip->gi_i.ip_hl = 5;
	greip->gi_i.ip_v = 4;
	greip->gi_i.ip_tos = ip->ip_tos;
	greip->gi_i.ip_len =
		odp_cpu_to_be_16(odp_be_to_cpu_16(ip->ip_len) +
				 sizeof(*greip));
	greip->gi_i.ip_id = ip->ip_id;
	greip->gi_i.ip_off = 0;
	greip->gi_i.ip_ttl = ip->ip_ttl;
	greip->gi_i.ip_p = OFP_IPPROTO_GRE;
	greip->gi_i.ip_sum = 0;
	greip->gi_i.ip_src.s_addr = dev_gre->ip_local;
	greip->gi_i.ip_dst.s_addr = dev_gre->ip_remote;

	return OFP_PKT_CONTINUE;
}
Пример #2
0
static int
create_odp_packet_ip6(odp_packet_t *opkt, uint8_t *pkt_data, int plen)
{
	odp_pool_t pool;
	odp_packet_t pkt = ODP_PACKET_INVALID;

	memset(orig_pkt_data, 0x0, sizeof(orig_pkt_data));

	pool = odp_pool_lookup("packet_pool");
	if (pool == ODP_POOL_INVALID) {
		fail_with_odp("ODP packet_pool not found\n");
		return -1;
	}

	pkt = odp_packet_alloc(pool, plen);
	if (pkt == ODP_PACKET_INVALID) {
		fail_with_odp("ODP packet alloc failed");
		return -1;
	}

	if (odp_packet_copy_from_mem(pkt, 0, plen, pkt_data) < 0) {
		fail_with_odp("Packet data copy failed\n");
		return -1;
	};

	odp_packet_has_eth_set(pkt, 1);
	odp_packet_has_l2_set(pkt, 1);
	odp_packet_has_ipv6_set(pkt, 1);
	odp_packet_l2_offset_set(pkt, 0);
	odp_packet_l3_offset_set(pkt, OFP_ETHER_HDR_LEN);

	*opkt = pkt;

	odp_packet_copy_to_mem(pkt, 0, plen, orig_pkt_data);

	return 0;
}
Пример #3
0
static int
create_odp_packet_ip4(odp_packet_t *opkt, uint8_t *pkt_data, int plen,
		      uint32_t dst_addr)
{
	odp_pool_t pool;
	uint8_t *buf;
	odp_packet_t pkt = ODP_PACKET_INVALID;
	struct ofp_ether_header *eth;
	struct ofp_ip *iphdr;
	uint32_t eth_len;

	memset(orig_pkt_data, 0x0, sizeof(orig_pkt_data));

	pool = odp_pool_lookup("packet_pool");
	if (pool == ODP_POOL_INVALID) {
		fail_with_odp("ODP packet_pool not found\n");
		return -1;
	}

	pkt = odp_packet_alloc(pool, plen);
	if (pkt == ODP_PACKET_INVALID) {
		fail_with_odp("ODP packet alloc failed");
		return -1;
	}

	buf = odp_packet_data(pkt);

	if (odp_packet_copy_from_mem(pkt, 0, plen, pkt_data) < 0) {
		fail_with_odp("Packet data copy failed\n");
		return -1;
	};

	iphdr = (struct ofp_ip *)&buf[OFP_ETHER_HDR_LEN];

	/* changes to the default packet. Recalculate ip checksum */
	if (dst_addr) {
		iphdr->ip_dst.s_addr = dst_addr;
		iphdr->ip_sum = 0;
		iphdr->ip_sum =
			ofp_cksum_buffer((uint16_t *)iphdr, iphdr->ip_hl<<2);
	}
	/* END OF changes to the default packet */

	eth = (struct ofp_ether_header *)buf;
	if (eth->ether_type == odp_cpu_to_be_16(OFP_ETHERTYPE_VLAN))
		eth_len = OFP_ETHER_HDR_LEN + OFP_ETHER_VLAN_ENCAP_LEN;
	else
		eth_len = OFP_ETHER_HDR_LEN;

	odp_packet_has_eth_set(pkt, 1);
	odp_packet_has_l2_set(pkt, 1);
	odp_packet_has_ipv4_set(pkt, 1);
	odp_packet_l2_offset_set(pkt, 0);
	odp_packet_l3_offset_set(pkt, eth_len);
	odp_packet_l4_offset_set(pkt, eth_len + (iphdr->ip_hl<<2));

	*opkt = pkt;

	odp_packet_copy_to_mem(pkt, 0, plen, orig_pkt_data);

	return 0;
}