From e6475153fadee7177aa84be4d5a66e8b9bc3ebe2 Mon Sep 17 00:00:00 2001 From: Matthias Gatto Date: Tue, 24 Mar 2020 13:46:13 +0100 Subject: [PATCH] vtep: pg_vtep_add_vni_dst Signed-off-by: Matthias Gatto --- include/packetgraph/vtep.h | 10 +++++++ src/vtep-impl.h | 55 ++++++++++++++++++++++++++++++++++++++ tests/vtep/tests.c | 44 ++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/include/packetgraph/vtep.h b/include/packetgraph/vtep.h index b4e3bde8a..cb20c679e 100644 --- a/include/packetgraph/vtep.h +++ b/include/packetgraph/vtep.h @@ -96,6 +96,16 @@ int pg_vtep6_add_vni(struct pg_brick *brick, struct pg_brick *neighbor, uint32_t vni, uint8_t *multicast_ip, struct pg_error **errp); +int pg_vtep4_add_vni_dst(struct pg_brick *brick, uint32_t vni, + struct ether_addr *mac_vm, + struct ether_addr *dmac, uint32_t dip, + struct pg_error **errp); + +int pg_vtep6_add_vni_dst(struct pg_brick *brick, uint32_t vni, + struct ether_addr *mac_vm, + struct ether_addr *dmac, uint8_t *dip, + struct pg_error **errp); + #ifndef __cplusplus /** diff --git a/src/vtep-impl.h b/src/vtep-impl.h index 44baa1a0f..b00af25a4 100644 --- a/src/vtep-impl.h +++ b/src/vtep-impl.h @@ -1086,6 +1086,61 @@ int pg_vtep_add_vni_(struct pg_brick *brick, return 0; } +#define pg_vtep_add_vni_dst__(version) CATCAT(pg_vtep, version, _add_vni_dst) +#define pg_vtep_add_vni_dst_ pg_vtep_add_vni_dst__(IP_VERSION) + +int pg_vtep_add_vni_dst_(struct pg_brick *brick, uint32_t vni, + struct ether_addr *mac_vm, + struct ether_addr *dmac, IP_IN_TYPE dip, + struct pg_error **errp) +{ + struct vtep_state *state = pg_brick_get_state(brick, + struct vtep_state); + struct dest_addresses dst = {*dmac, +#if IP_VERSION == 4 + dip, +#else + {.word8 = {0}}, +#endif + state->vtep_tick}; + union pg_mac tmp = {.rte_addr = *mac_vm}; + struct vtep_port *ports = state->ports; + struct vtep_port *good_port = NULL; + struct pg_brick_side *s = &brick->sides[pg_flip_side(state->output)]; + + if (!brick) { + *errp = pg_error_new("brick is NULL"); + return -1; + } + + if (!is_vni_valid(vni)) { + *errp = pg_error_new("Invalid VNI"); + return -1; + } + +#if IP_VERSION != 4 + pg_ip_copy(dip, &dst.ip); +#endif + + for (int i = 0; i < s->nb; ++i) { + if (ports[i].vni == vni) { + good_port = &ports[i]; + break; + } + } + + if (!good_port) { + *errp = pg_error_new("can't find good VNI"); + return -1; + } + + pg_mac_table_elem_set(&good_port->mac_to_dst, tmp, &dst, + sizeof(struct dest_addresses)); + + return 0; +} + + #define pg_vtep_clean_all_mac__(version) \ CATCAT(pg_vtep, version, _clean_all_mac) #define pg_vtep_clean_all_mac_ pg_vtep_clean_all_mac__(IP_VERSION) diff --git a/tests/vtep/tests.c b/tests/vtep/tests.c index 8ab9a7387..4b9719ae6 100644 --- a/tests/vtep/tests.c +++ b/tests/vtep/tests.c @@ -1233,6 +1233,49 @@ static void test_vtep_lifetime(void) g_free(pkts); } +static void test_vtep_add_vni_dst(void) +{ + struct pg_error *error = NULL; + struct ether_addr multicast_mac1 = {{0,0,0,0,0,1}}; + struct ether_addr multicast_mac2 = {{0,0,0,0,0,2}}; + struct ether_addr mac_dst = {{0xaa}}; + struct rte_mbuf **pkts; + + pg_autobrick struct pg_brick *col = pg_collect_new("collect", &error); + pg_autobrick struct pg_brick *nop = pg_nop_new("n", &error); + pg_autobrick struct pg_brick *vtep = pg_vtep_new( + "vt", 1, PG_EAST_SIDE, 15, multicast_mac1, + PG_VTEP_DST_PORT, PG_VTEP_ALL_OPTI | PG_VTEP_NO_MULTICAST, + &error); + CHECK_ERROR(error); + + pg_brick_chained_links(&error, nop, vtep, col); + CHECK_ERROR(error); + + pg_vtep_add_vni(vtep, nop, 0, inet_addr("225.0.0.43"), &error); + CHECK_ERROR(error); + + pkts = pg_packets_create(-1LL); + pg_packets_append_ether(pkts, -1LL, + &(struct ether_addr){{0, 1}}, + &mac_dst, ETHER_TYPE_IPv4); + pg_packets_append_ipv4(pkts, -1LL, 0, -1, 10, 17); + + /* we test "no multicast", we didn't add any VNI DST + * so packets should be blocked */ + pg_brick_burst_to_east(vtep, 0, pkts, 1, &error); + g_assert(pg_brick_pkts_count_get(col, PG_EAST_SIDE) == 0); + + /* manually add vni DST */ + pg_vtep4_add_vni_dst(vtep, 0, &mac_dst, &multicast_mac2, + 1337, &error); + + pg_brick_burst_to_east(vtep, 0, pkts, -1LLU, &error); + g_assert(pg_brick_pkts_count_get(col, PG_EAST_SIDE) == 64); + pg_packets_free(pkts, pg_mask_firsts(NB_PKTS)); + +} + int main(int argc, char **argv) { int r; @@ -1248,6 +1291,7 @@ int main(int argc, char **argv) pg_test_add_func("/vtep/simple/no-copy", test_vtep_simple_no_copy); pg_test_add_func("/vtep/simple/all-opti", test_vtep_simple_all_opti); pg_test_add_func("/vtep/simple/lifetime", test_vtep_lifetime); + pg_test_add_func("/vtep/simple/add-vni-dst", test_vtep_add_vni_dst); pg_test_add_func("/vtep/vnis/all-opti", test_vtep_vnis_all_opti); pg_test_add_func("/vtep/vnis/no-copy", test_vtep_vnis_no_copy);