예제 #1
0
int main(int argc, char **argv)
{
	/**
	 * Simple example of firewall between two NICs.
	 * Print brick simply show packets.
	 *
	 * [nic-west]--[print-west]--[firewall]--[print-east]--[nic_east]
	 */

	struct pg_error *error = NULL;
	struct pg_brick *nic_west, *nic_east;
	struct pg_brick *print_west, *print_east;
	struct pg_brick *fw;
	struct pg_graph *graph;

	/* init packetgraph and nics */
	pg_start(argc, argv, &error);
	if (pg_nic_port_count() < 2) {
		printf("You need two DPDK ports to run this example\n");
		return 1;
	}

	/* create bricks */
	nic_west = pg_nic_new_by_id("nic-west", 0, &error);
	fw = pg_firewall_new("fw", PG_NO_CONN_WORKER, &error);
	print_west = pg_print_new("print-west", 0,
				  PG_PRINT_FLAG_MAX, 0, &error);
	print_east = pg_print_new("print-east", 0,
				  PG_PRINT_FLAG_MAX, 0, &error);
	nic_east = pg_nic_new_by_id("nic_east", 1, &error);

	/* link bricks */
	pg_brick_chained_links(&error, nic_west, print_west,
			       fw, print_east, nic_east);

	/* add some rules to firewall */
	pg_firewall_rule_add(fw, "tcp portrange 1-1024", PG_MAX_SIDE, 1, &error);
	pg_firewall_rule_add(fw, "icmp", PG_MAX_SIDE, 1, &error);
	pg_firewall_reload(fw, &error);

	/* create a graph with all bricks inside */
	graph = pg_graph_new("graph", fw, &error);

	printf("let's pool 1000*1000 times ...\n");
	for (int i = 0; i < 1000000; i++) {
		if (pg_graph_poll(graph, &error) < 0) {
			pg_error_print(error);
			pg_error_free(error);
		}
	}

	pg_graph_destroy(graph);
	pg_stop();
	return 0;
}
예제 #2
0
int main(int argc, char **argv)
{
	struct pg_error *error = NULL;
	struct pg_brick *fw;
	struct pg_brick *nic_west, *nic_east;
	uint16_t nb_send_pkts;
	uint64_t total;
	struct timeval start, end;
	int i;

	pg_start(argc, argv, &error);
	CHECK_ERROR(error);
	g_assert(rte_eth_dev_count() >= 2);

	nic_west = pg_nic_new_by_id("port 0", 1, 1, WEST_SIDE, 0, &error);
	CHECK_ERROR(error);
	fw = pg_firewall_new("fw", 1, 1, PG_NO_CONN_WORKER, &error);
	pg_firewall_thread_register(fw);
	CHECK_ERROR(error);
	nic_east = pg_nic_new_by_id("port 1", 1, 1, EAST_SIDE, 1, &error);
	CHECK_ERROR(error);

	pg_brick_link(nic_west, fw, &error);
	CHECK_ERROR(error);
	pg_brick_link(fw, nic_east, &error);
	CHECK_ERROR(error);

	g_assert(!pg_firewall_rule_add(fw, "tcp portrange 50-60", MAX_SIDE, 1,
				       &error));
	CHECK_ERROR(error);
	g_assert(!pg_firewall_rule_add(fw, "icmp", MAX_SIDE, 1, &error));
	CHECK_ERROR(error);
	g_assert(!pg_firewall_reload(fw, &error));
	CHECK_ERROR(error);

	for (;;) {
		gettimeofday(&start, 0);
		total = 0;
		for (i = 0; i < LOOPS; i++) {
			g_assert(pg_brick_poll(nic_west,
					       &nb_send_pkts,
					       &error));
			usleep(1);
			total += nb_send_pkts;
			g_assert(pg_brick_poll(nic_east,
					       &nb_send_pkts,
					       &error));
			total += nb_send_pkts;
			usleep(1);
		}
		gettimeofday(&end, 0);
		usleep(100);
		printf("time in us: for %i loops: %lu\ntotal %"PRIu64"\n",
		       LOOPS,
		       (end.tv_sec * 1000000 + end.tv_usec) -
		       (start.tv_sec * 1000000 + start.tv_usec), total);
		pg_firewall_gc(fw);
	}

	pg_stop();
	return 0;
}
예제 #3
0
static void firewall_replay(const unsigned char *pkts[],
			    int pkts_nb, int *pkts_size)
{
	struct pg_brick *gen_west, *gen_east;
	struct pg_brick *fw;
	struct pg_brick *col_west, *col_east;
	struct pg_error *error = NULL;
	uint16_t i, packet_count;
	struct rte_mbuf *packet;
	struct ether_hdr *eth;
	uint64_t filtered_pkts_mask;
	struct rte_mbuf **filtered_pkts;
	struct ether_addr tmp_addr;
	int ret;

	/* have some collectors and generators on each sides
	 * [collector]--[generator>]--[firewall]--[<generator]--[collector]
	 * 10.0.2.15                                         173.194.40.111
	 * 8:0:27:b6:5:16                                   52:54:0:12:35:2
	 */
	gen_west = pg_packetsgen_new("gen_west", 1, 1, EAST_SIDE, &packet, 1,
				  &error);
	g_assert(!error);
	gen_east = pg_packetsgen_new("gen_east", 1, 1, WEST_SIDE, &packet, 1,
				  &error);
	g_assert(!error);
	fw = pg_firewall_new("fw", 1, 1, PG_NONE, &error);
	g_assert(!error);
	col_west = pg_collect_new("col_west", 1, 1, &error);
	g_assert(!error);
	col_east = pg_collect_new("col_east", 1, 1, &error);
	g_assert(!error);
	pg_brick_link(col_west, gen_west, &error);
	g_assert(!error);
	pg_brick_link(gen_west, fw, &error);
	g_assert(!error);
	pg_brick_link(fw, gen_east, &error);
	g_assert(!error);
	pg_brick_link(gen_east, col_east, &error);
	g_assert(!error);

	/* open all traffic of 10.0.2.15 from the west side of the firewall
	 * returning traffic should be allowed due to STATEFUL option
	 */
	ret = pg_firewall_rule_add(fw, "src host 10.0.2.15", WEST_SIDE, 1, &error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(!error);
	g_assert(ret < 0);

	/* replay traffic */
	for (i = 0; i < pkts_nb; i++) {
		struct ip *ip;

		packet = build_packet(pkts[i], pkts_size[i]);
		eth = rte_pktmbuf_mtod(packet, struct ether_hdr*);
		ip = (struct ip *)(eth + 1);

		if (ip->ip_src.s_addr == inet_addr("10.0.2.15")) {
			pg_brick_poll(gen_west, &packet_count, &error);
			g_assert(!error);
			g_assert(packet_count == 1);
			filtered_pkts = pg_brick_west_burst_get(col_east,
				&filtered_pkts_mask, &error);
			g_assert(!error);
			g_assert(pg_mask_count(filtered_pkts_mask) == 1);
			/* check eth source address */
			eth = rte_pktmbuf_mtod(filtered_pkts[0],
					       struct ether_hdr*);
			pg_scan_ether_addr(&tmp_addr, "08:00:27:b6:05:16");
			g_assert(is_same_ether_addr(&eth->s_addr, &tmp_addr));
			/* check ip source address */
			ip = (struct ip *)(eth + 1);
			g_assert(ip->ip_src.s_addr == inet_addr("10.0.2.15"));
		} else if (ip->ip_src.s_addr == inet_addr("173.194.40.111")) {
예제 #4
0
static void firewall_filter_rules(enum pg_side dir)
{
	struct pg_brick *gen;
	struct pg_brick *fw;
	struct pg_brick *col;
	struct pg_error *error = NULL;
	uint16_t i;
	int ret;
	static uint16_t nb = 30;
	struct rte_mbuf *packets[nb];
	uint64_t filtered_pkts_mask;
	struct rte_mbuf **filtered_pkts;
	uint64_t bit;
	uint16_t packet_count;
	struct ip *ip;
	struct ether_hdr *eth;

	/* create and connect 3 bricks: generator -> firewall -> collector */
	gen = pg_packetsgen_new("gen", 2, 2, pg_flip_side(dir), packets, nb, &error);
	g_assert(!error);
	fw = pg_firewall_new("fw", 2, 2, PG_NONE, &error);
	g_assert(!error);
	col = pg_collect_new("col", 2, 2, &error);
	g_assert(!error);
	/* revert link if needed */
	if (dir == WEST_SIDE) {
		pg_brick_link(gen, fw, &error);
		g_assert(!error);
		pg_brick_link(fw, col, &error);
		g_assert(!error);
	} else {
		pg_brick_link(col, fw, &error);
		g_assert(!error);
		pg_brick_link(fw, gen, &error);
		g_assert(!error);
	}

	/* build some UDP packets mixed sources */
	for (i = 0; i < nb; i++)
		switch (i % 3) {
		case 0:
			packets[i] = build_ip_packet("10.0.0.1",
						     "10.0.0.255", i);
			break;
		case 1:
			packets[i] = build_ip_packet("10.0.0.2",
						     "10.0.0.255", i);
			break;
		case 2:
			packets[i] = build_ip_packet("10.0.0.3",
						     "10.0.0.255", i);
			break;
		}

	/* configure firewall to allow traffic from 10.0.0.1 */
	ret = pg_firewall_rule_add(fw, "src host 10.0.0.1", dir, 0, &error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let's burst ! */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 0);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.1"));
	}

	/* now allow packets from 10.0.0.2 */
	ret = pg_firewall_rule_add(fw, "src host 10.0.0.2", dir, 0, &error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb * 2 / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 0 || i % 3 == 1);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.1") ||
			 ip->ip_src.s_addr == inet_addr("10.0.0.2"));
	}

	/* test that flush really blocks */
	pg_firewall_rule_flush(fw);
	ret = pg_firewall_reload(fw, &error);
	g_assert(!error);
	g_assert(ret < 0);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == 0);

	/* flush and only allow packets from 10.0.0.2 */
	pg_firewall_rule_flush(fw);
	ret = pg_firewall_rule_add(fw, "src host 10.0.0.2", dir, 0, &error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 1);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.2"));
	}

	/* flush and make two rules in one */
	pg_firewall_rule_flush(fw);
	ret = pg_firewall_rule_add(fw, "src host (10.0.0.1 or 10.0.0.2)", dir, 0,
				&error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb * 2 / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 0 || i % 3 == 1);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.1") ||
			 ip->ip_src.s_addr == inet_addr("10.0.0.2"));
	}

	/* flush and revert rules, packets should not pass */
	pg_firewall_rule_flush(fw);
	ret = pg_firewall_rule_add(fw, "src host (10.0.0.1)", pg_flip_side(dir), 0,
				&error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	/* check collect brick */
	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == 0);

	/* flush and allow packets from both sides */
	pg_firewall_rule_flush(fw);
	ret = pg_firewall_rule_add(fw, "src host (10.0.0.1)", MAX_SIDE, 0, &error);
	g_assert(!error);
	g_assert(ret == 0);
	ret = pg_firewall_reload(fw, &error);
	g_assert(ret < 0);
	g_assert(!error);

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 0);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.1"));
	}

	/* inverse generator and collector to test both sides */
	pg_brick_unlink(fw, &error);
	g_assert(!error);
	if (dir == WEST_SIDE) {
		pg_brick_link(col, fw, &error);
		g_assert(!error);
		pg_brick_link(fw, gen, &error);
		g_assert(!error);
	} else {
		pg_brick_link(gen, fw, &error);
		g_assert(!error);
		pg_brick_link(fw, col, &error);
		g_assert(!error);
	}

	/* let it goooo */
	pg_brick_poll(gen, &packet_count, &error);
	g_assert(!error);
	g_assert(packet_count == nb);

	if (dir == WEST_SIDE)
		filtered_pkts = pg_brick_west_burst_get(col, &filtered_pkts_mask,
						     &error);
	else
		filtered_pkts = pg_brick_east_burst_get(col, &filtered_pkts_mask,
						     &error);
	g_assert(!error);
	g_assert(pg_mask_count(filtered_pkts_mask) == nb / 3);
	for (; filtered_pkts_mask;) {
		pg_low_bit_iterate_full(filtered_pkts_mask, bit, i);
		g_assert(i % 3 == 0);
		eth = rte_pktmbuf_mtod(filtered_pkts[i], struct ether_hdr*);
		ip = (struct ip *)(eth + 1);
		g_assert(ip->ip_src.s_addr == inet_addr("10.0.0.1"));
	}

	/* clean */
	for (i = 0; i < nb; i++)
		rte_pktmbuf_free(packets[i]);
	pg_brick_destroy(gen);
	pg_brick_destroy(fw);
	pg_brick_destroy(col);
}