static int start_loop(int verbose) { struct pg_error *error = NULL; struct pg_brick *nic_tmp, *switch_east, *print_tmp; uint16_t port_count = rte_eth_dev_count(); GList *nic_manager = NULL; GList *manager = NULL; g_assert(port_count > 1); /* * Here is an ascii graph of the links: * * [NIC-X] - [PRINT-X] --\ * \ * [NIC-X+1] - [PRINT-X+1] } -- [SWITCH] * / * [NIC-X+2] - [PRINT-X+2] / * .... */ switch_east = pg_switch_new("switch", 20, 20, &error); CHECK_ERROR(error); PG_BM_ADD(manager, switch_east); for (int i = 0; i < port_count; ++i) { nic_tmp = pg_nic_new_by_id("nic", 1, 1, WEST_SIDE, i, &error); CHECK_ERROR(error); print_tmp = pg_print_new("print", 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); CHECK_ERROR(error); if (!verbose) pg_brick_chained_links(&error, nic_tmp, switch_east); else pg_brick_chained_links(&error, nic_tmp, print_tmp, switch_east); CHECK_ERROR(error); PG_BM_ADD(nic_manager, nic_tmp); PG_BM_ADD(manager, print_tmp); } while (1) { uint64_t tot_send_pkts = 0; for (int i = 0; i < 100000; ++i) { uint16_t nb_send_pkts; PG_BM_GET_NEXT(nic_manager, nic_tmp); pg_brick_poll(nic_tmp, &nb_send_pkts, &error); tot_send_pkts += nb_send_pkts; CHECK_ERROR(error); usleep(1); } printf("poll pkts: %lu\n", tot_send_pkts); } nic_manager = g_list_first(nic_manager); PG_BM_DESTROY(manager); PG_BM_DESTROY(nic_manager); return 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; }
static void test_brick_core_verify_re_link(void) { struct pg_error *e = NULL; struct pg_brick *v = pg_nop_new("v", &e); g_assert(!e); struct pg_brick *f = pg_nop_new("f", &e); g_assert(!e); struct pg_brick *a = pg_nop_new("a", &e); g_assert(!e); struct pg_brick *s = pg_nop_new("s", &e); g_assert(!e); /* Initial state: v -- f -- a */ pg_brick_chained_links(&e, v, f, a); g_assert(!e); test_brick_sanity_check_expected(v, 0, 1); test_brick_sanity_check_expected(f, 1, 1); test_brick_sanity_check_expected(a, 1, 0); /* Unlink f */ pg_brick_unlink(f, &e); g_assert(!e); test_brick_sanity_check_expected(v, 0, 0); test_brick_sanity_check_expected(f, 0, 0); test_brick_sanity_check_expected(a, 0, 0); /* Link v and s */ pg_brick_link(v, s, &e); g_assert(!e); test_brick_sanity_check_expected(v, 0, 1); test_brick_sanity_check_expected(s, 1, 0); test_brick_sanity_check_expected(f, 0, 0); test_brick_sanity_check_expected(a, 0, 0); /* link the rest to have v -- s -- f -- a */ pg_brick_link(s, f, &e); g_assert(!e); test_brick_sanity_check_expected(v, 0, 1); test_brick_sanity_check_expected(s, 1, 1); test_brick_sanity_check_expected(f, 1, 0); test_brick_sanity_check_expected(a, 0, 0); pg_brick_link(f, a, &e); g_assert(!e); test_brick_sanity_check_expected(v, 0, 1); test_brick_sanity_check_expected(s, 1, 1); test_brick_sanity_check_expected(f, 1, 1); test_brick_sanity_check_expected(a, 1, 0); pg_brick_destroy(a); pg_brick_destroy(v); pg_brick_destroy(f); pg_brick_destroy(s); }
static void test_icmp_pmtud(void) { struct pg_error *error = NULL; struct pg_brick *pmtud; struct pg_brick *col_east; struct pg_brick *col_west; /* struct pg_brick *print_east; */ /* struct pg_brick *print_west; */ /* FILE *east_file = fopen("east_file.pcap", "w+"); */ /* FILE *west_file = fopen("west_file.pcap", "w+"); */ struct rte_mbuf **pkts; struct rte_mbuf *tmp; uint64_t pkts_mask; struct ether_addr eth_s = {{2}}; struct ether_addr eth_d = {{4}}; pkts = pg_packets_append_ether(pg_packets_create(pg_mask_firsts(64)), pg_mask_firsts(64), ð_s, ð_d, ETHER_TYPE_IPv4); pg_packets_append_ipv4(pkts, pg_mask_firsts(64), 1, 2, 0, 0); /* 10 caracter with the \0*/ pg_packets_append_str(pkts, pg_mask_firsts(64), "siegzeon "); pg_packets_append_blank(pkts, pg_mask_firsts(32), 421 - sizeof(struct ipv4_hdr) - sizeof(struct ether_hdr)); pg_packets_append_blank(pkts, pg_mask_firsts(64) & ~pg_mask_firsts(32), 420 - sizeof(struct ipv4_hdr) - sizeof(struct ether_hdr)); /* * [col_west] -- [print_west] -- [pmtud] -- [print_east] -- [col_east] */ pmtud = pg_pmtud_new("pmtud", PG_WEST_SIDE, 430, &error); g_assert(!error); col_east = pg_collect_new("col_east", &error); g_assert(col_east); g_assert(!error); col_west = pg_collect_new("col_west", &error); g_assert(!error); g_assert(col_west); /* print_east = pg_print_new("print_east", 1, 1, east_file, */ /* PG_PRINT_FLAG_PCAP, NULL, &error); */ /* g_assert(col_east); */ /* g_assert(!error); */ /* print_west = pg_print_new("print_west", 1, 1, west_file, */ /* PG_PRINT_FLAG_PCAP, NULL, &error); */ /* g_assert(!error); */ /* g_assert(col_west); */ /* pg_brick_chained_links(&error, col_west, print_west, pmtud, */ /* print_east, col_east); */ /* g_assert(!error); */ pg_brick_chained_links(&error, col_west, pmtud, col_east); g_assert(!error); pg_brick_burst_to_east(pmtud, 0, pkts, pg_mask_firsts(64), &error); g_assert(!error); pg_brick_west_burst_get(col_east, &pkts_mask, &error); g_assert(!error); g_assert(pg_mask_count(pkts_mask) == 32); g_assert(pg_brick_pkts_count_get(pmtud, PG_EAST_SIDE) == 64); g_assert(pg_brick_pkts_count_get(col_east, PG_EAST_SIDE) == 32); g_assert(pg_brick_pkts_count_get(col_west, PG_WEST_SIDE) == 32); tmp = pg_brick_east_burst_get(col_west, &pkts_mask, &error)[0]; g_assert(pkts_mask == 1); g_assert(tmp); pg_brick_destroy(col_west); pg_brick_destroy(pmtud); pg_brick_destroy(col_east); pg_packets_free(pkts, pg_mask_firsts(64)); /* fclose(east_file); */ /* fclose(west_file); */ g_free(pkts); return; }
static int start_loop(int verbose, int nb_vhost) { struct pg_error *error = NULL; struct pg_brick *nic_tmp, *switch_east, *print_tmp; uint16_t port_count = rte_eth_dev_count(); GList *nic_manager = NULL; GList *manager = NULL; int ret = -1; /* * Here is an ascii graph of the links: * * [NIC-X] - [PRINT-X] --\ * \ * [NIC-X+1] - [PRINT-X+1] } -- [SWITCH] * / * [NIC-X+2] - [PRINT-X+2] / * .... */ switch_east = pg_switch_new("switch", 20, 20, EAST_SIDE, &error); CHECK_ERROR(error); PG_BM_ADD(manager, switch_east); if (nb_vhost) { if (pg_vhost_start("/tmp", &error) < 0) goto free_switch; port_count = nb_vhost; } g_assert(port_count > 1); for (int i = 0; i < port_count; ++i) { char *tmp_name; if (nb_vhost) { tmp_name = g_strdup_printf("vhost-%d", i); nic_tmp = pg_vhost_new(tmp_name, 1, 1, WEST_SIDE, &error); } else { tmp_name = g_strdup_printf("nic-%d", i); nic_tmp = pg_nic_new_by_id(tmp_name, i, &error); } g_free(tmp_name); CHECK_ERROR(error); tmp_name = g_strdup_printf("print-%d", i); print_tmp = pg_print_new(tmp_name, 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); g_free(tmp_name); CHECK_ERROR(error); if (!verbose) pg_brick_chained_links(&error, nic_tmp, switch_east); else pg_brick_chained_links(&error, nic_tmp, print_tmp, switch_east); CHECK_ERROR(error); PG_BM_ADD(nic_manager, nic_tmp); PG_BM_ADD(manager, print_tmp); } while (1) { uint64_t tot_send_pkts = 0; for (int i = 0; i < 100000; ++i) { uint16_t nb_send_pkts; PG_BM_GET_NEXT(nic_manager, nic_tmp); pg_brick_poll(nic_tmp, &nb_send_pkts, &error); tot_send_pkts += nb_send_pkts; CHECK_ERROR(error); usleep(1); } printf("poll pkts: %lu\n", tot_send_pkts); } ret = 0; nic_manager = g_list_first(nic_manager); PG_BM_DESTROY(nic_manager); free_switch: PG_BM_DESTROY(manager); pg_vhost_stop(); return ret; }
static void test_brick_core_multiple_unlink_edge_(struct pg_brick *west[4], struct pg_brick *middle, struct pg_brick *east[4]) { struct pg_error *error = NULL; int ret; int i; for (i = 0; i < 4; i++) { ret = pg_brick_chained_links(&error, west[i], middle, east[i]); g_assert(ret == 0); g_assert(!error); } g_assert(pg_brick_refcount(middle) == 9); for (i = 0; i < 4; i++) { g_assert(pg_brick_refcount(west[i]) == 2); g_assert(pg_brick_refcount(east[i]) == 2); } g_assert(pg_brick_unlink_edge(west[0], east[0], &error) == -1); g_assert(error); pg_error_free(error); error = NULL; g_assert(pg_brick_unlink_edge(east[0], west[0], &error) == -1); g_assert(error); pg_error_free(error); error = NULL; g_assert(!pg_brick_unlink_edge(west[0], middle, &error)); g_assert(!error); g_assert(pg_brick_refcount(west[0]) == 1); for (i = 1; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 2); g_assert(pg_brick_refcount(middle) == 8); for (i = 0; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 2); g_assert(!pg_brick_unlink_edge(west[1], middle, &error)); g_assert(!error); for (i = 0; i < 2; i++) g_assert(pg_brick_refcount(west[i]) == 1); for (i = 2; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 2); g_assert(pg_brick_refcount(middle) == 7); for (i = 0; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 2); g_assert(!pg_brick_unlink_edge(middle, east[0], &error)); g_assert(!error); for (i = 0; i < 2; i++) g_assert(pg_brick_refcount(west[i]) == 1); for (i = 2; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 2); g_assert(pg_brick_refcount(middle) == 6); g_assert(pg_brick_refcount(east[0]) == 1); for (i = 1; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 2); g_assert(!pg_brick_unlink_edge(middle, east[1], &error)); g_assert(!error); for (i = 0; i < 2; i++) g_assert(pg_brick_refcount(west[i]) == 1); for (i = 2; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 2); g_assert(pg_brick_refcount(middle) == 5); for (i = 0; i < 2; i++) g_assert(pg_brick_refcount(east[i]) == 1); for (i = 2; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 2); g_assert(!pg_brick_unlink_edge(west[2], middle, &error)); g_assert(!error); for (i = 0; i < 3; i++) g_assert(pg_brick_refcount(west[i]) == 1); g_assert(pg_brick_refcount(west[3]) == 2); g_assert(pg_brick_refcount(middle) == 4); for (i = 0; i < 2; i++) g_assert(pg_brick_refcount(east[i]) == 1); for (i = 2; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 2); g_assert(!pg_brick_unlink_edge(middle, east[2], &error)); g_assert(!error); for (i = 0; i < 3; i++) g_assert(pg_brick_refcount(west[i]) == 1); g_assert(pg_brick_refcount(west[3]) == 2); g_assert(pg_brick_refcount(middle) == 3); for (i = 0; i < 3; i++) g_assert(pg_brick_refcount(east[i]) == 1); g_assert(pg_brick_refcount(east[3]) == 2); g_assert(!pg_brick_unlink_edge(west[3], middle, &error)); g_assert(!error); for (i = 0; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 1); g_assert(pg_brick_refcount(middle) == 2); for (i = 0; i < 3; i++) g_assert(pg_brick_refcount(east[i]) == 1); g_assert(pg_brick_refcount(east[3]) == 2); g_assert(!pg_brick_unlink_edge(middle, east[3], &error)); g_assert(!error); for (i = 0; i < 4; i++) g_assert(pg_brick_refcount(west[i]) == 1); g_assert(pg_brick_refcount(middle) == 1); for (i = 0; i < 4; i++) g_assert(pg_brick_refcount(east[i]) == 1); }
static int start_loop(uint32_t vtep_ip, struct ether_addr *vtep_mac, struct ether_addr *inner_mac, GList *neighbor_macs) { struct pg_error *error = NULL; struct pg_brick *nic_east, *nic_west, *vtep_east, *vtep_west; struct pg_brick *print_east, *print_west, *print_middle; /* * Here is an ascii graph of the links: * NIC = nic * VT = vtep * * [NIC] - [PRINT] - [VT] -- [PRINT] -- [VT] -- [PRINT] -- [NIC] */ nic_east = pg_nic_new_by_id("nic-e", 1, 1, EAST_SIDE, 0, &error); CHECK_ERROR(error); nic_west = pg_nic_new_by_id("nic-w", 1, 1, WEST_SIDE, 1, &error); CHECK_ERROR(error); vtep_east = pg_vtep_new("vt-e", 1, 1, WEST_SIDE, vtep_ip, *vtep_mac, 1, &error); CHECK_ERROR(error); inverse_mac(vtep_mac); pg_print_mac(vtep_mac); printf("\n"); vtep_west = pg_vtep_new("vt-w", 1, 1, EAST_SIDE, ~vtep_ip, *vtep_mac, 1, &error); CHECK_ERROR(error); print_west = pg_print_new("west", 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); CHECK_ERROR(error); print_east = pg_print_new("east", 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); CHECK_ERROR(error); print_middle = pg_print_new("middle", 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); CHECK_ERROR(error); /* If you want to print transmiting pkts uncomment this and coment * the bellow pg_brick_chained_links * Attention: this may slow down the transmition */ /* pg_brick_chained_links(&error, nic_west, print_west, */ /* vtep_west, print_middle, vtep_east, */ /* print_east, nic_east); */ pg_brick_chained_links(&error, nic_west, vtep_west, vtep_east, nic_east); CHECK_ERROR(error); pg_vtep_add_vni(vtep_west, nic_west, 0, inet_addr("225.0.0.43"), &error); CHECK_ERROR(error); pg_vtep_add_vni(vtep_east, nic_east, 0, inet_addr("225.0.0.43"), &error); CHECK_ERROR(error); while (!quit) { uint16_t nb_send_pkts; g_assert(pg_brick_poll(nic_west, &nb_send_pkts, &error)); usleep(1); g_assert(pg_brick_poll(nic_east, &nb_send_pkts, &error)); usleep(1); } pg_brick_destroy(nic_west); pg_brick_destroy(print_west); pg_brick_destroy(vtep_west); pg_brick_destroy(print_middle); pg_brick_destroy(vtep_east); pg_brick_destroy(print_east); pg_brick_destroy(nic_east); return 0; }