From 99d9484027721d0b4bde80467aa425cba37c5853 Mon Sep 17 00:00:00 2001 From: Matthias Gatto Date: Mon, 23 Mar 2020 13:35:26 +0100 Subject: [PATCH] vtep: add an option to have no multicast Signed-off-by: Matthias Gatto --- include/packetgraph/vtep.h | 5 ++++- src/vtep-impl.h | 38 +++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/include/packetgraph/vtep.h b/include/packetgraph/vtep.h index 1a796bfa1..b4e3bde8a 100644 --- a/include/packetgraph/vtep.h +++ b/include/packetgraph/vtep.h @@ -34,7 +34,10 @@ enum pg_vtep_flags { * when incoming packets, just forward it */ PG_VTEP_NO_INNERMAC_CHECK = 2, PG_VTEP_FORCE_UPD_IPV6_CHECKSUM = 4, - PG_VTEP_ALL_OPTI = PG_VTEP_NO_COPY | PG_VTEP_NO_INNERMAC_CHECK + PG_VTEP_ALL_OPTI = PG_VTEP_NO_COPY | PG_VTEP_NO_INNERMAC_CHECK, + /* in this mode we don't do multicast, + dst mac must be add manually */ + PG_VTEP_NO_MULTICAST = 8 }; struct ether_addr; diff --git a/src/vtep-impl.h b/src/vtep-impl.h index dec384078..800a3ba5e 100644 --- a/src/vtep-impl.h +++ b/src/vtep-impl.h @@ -355,10 +355,12 @@ static inline int vtep_header_prepend(struct vtep_state *state, static inline int vtep_encapsulate(struct vtep_state *state, struct vtep_port *port, - struct rte_mbuf **pkts, uint64_t pkts_mask, + struct rte_mbuf **pkts, + uint64_t *maskp, struct pg_error **errp) { struct rte_mempool *mp = pg_get_mempool(); + uint64_t pkts_mask = *maskp; /* do the encapsulation */ for (; pkts_mask;) { @@ -388,6 +390,12 @@ static inline int vtep_encapsulate(struct vtep_state *state, unicast = 0; } + if (state->flags & PG_VTEP_NO_MULTICAST && !unicast) { + /* in this case all we can do is to skip the packet */ + *maskp &= ~i; + continue; + } + if (unlikely(!(state->flags & PG_VTEP_NO_COPY))) { tmp = rte_pktmbuf_clone(pkt, mp); if (unlikely(!tmp)) @@ -459,11 +467,15 @@ static inline int to_vtep(struct pg_brick *brick, enum pg_side from, if (unlikely(are_mac_tables_dead(port) && try_fix_tables(state, port, errp) < 0)) return -1; - /* if the port VNI is not set up ignore the packets */ - if (unlikely(!pg_is_multicast_ip(port->multicast_ip))) - return 0; - if (unlikely(vtep_encapsulate(state, port, pkts, pkts_mask, errp) < 0)) + if (state->flags & PG_VTEP_NO_MULTICAST) { + /* if the port VNI is not set up ignore the packets */ + if (unlikely(!pg_is_multicast_ip(port->multicast_ip))) + return 0; + } + + if (unlikely(vtep_encapsulate(state, port, pkts, + &pkts_mask, errp) < 0)) return -1; ret = pg_brick_side_forward(s, from, state->pkts, pkts_mask, errp); @@ -795,7 +807,8 @@ static int do_add_vni(struct vtep_state *state, uint16_t edge_index, *errp = pg_error_new("port already attached to a vni"); return -1; } - if (unlikely(pg_is_multicast_ip(port->multicast_ip))) { + if (!(state->flags & PG_VTEP_NO_MULTICAST) && + unlikely(pg_is_multicast_ip(port->multicast_ip))) { *errp = pg_error_new("port alread have a mutlicast IP"); return -1; } @@ -806,7 +819,8 @@ static int do_add_vni(struct vtep_state *state, uint16_t edge_index, g_assert(!pg_mac_table_init(&port->mac_to_dst, &state->exeption_env)); g_assert(!pg_mac_table_init(&port->known_mac, &state->exeption_env)); - multicast_subscribe(state, port, multicast_ip, errp); + if (!(state->flags & PG_VTEP_NO_MULTICAST)) + multicast_subscribe(state, port, multicast_ip, errp); return 0; } @@ -827,8 +841,8 @@ static void do_remove_vni(struct vtep_state *state, if (!pg_is_multicast_ip(port->multicast_ip)) return; - multicast_unsubscribe(state, port, port->multicast_ip, - errp); + if (!(state->flags & PG_VTEP_NO_MULTICAST)) + multicast_unsubscribe(state, port, port->multicast_ip, errp); if (pg_error_is_set(errp)) return; @@ -1053,12 +1067,6 @@ int pg_vtep_add_vni_(struct pg_brick *brick, pg_ip_copy(multicast_ip, &tmp_ip); - if (!pg_is_multicast_ip(tmp_ip)) { - *errp = pg_error_new( - "Provided IP is not in the multicast range"); - return -1; - } - /* lookup for the vtep brick index */ found = 0; for (i = 0; i < brick->sides[side].max; i++)