Change-Id: I50ff0cacf88182f8e0be19840c50f4954de586e2
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
{
vnet_sw_interface_t *si = vnet_get_hw_sw_interface (vnm, hw_if_index);
*sw_if_indexp = si->sw_if_index;
{
vnet_sw_interface_t *si = vnet_get_hw_sw_interface (vnm, hw_if_index);
*sw_if_indexp = si->sw_if_index;
+
+ /* By default don't flood to loopbacks, as packets just keep
+ * coming back ... If this loopback becomes a BVI, we'll change it */
+ si->flood_class = VNET_FLOOD_CLASS_NO_FLOOD;
+ /* THe BVI interface */
+ VNET_FLOOD_CLASS_BVI,
/* Always flood */
VNET_FLOOD_CLASS_NORMAL,
VNET_FLOOD_CLASS_TUNNEL_MASTER,
/* Does not flood when tunnel master is in the same L2 BD */
/* Always flood */
VNET_FLOOD_CLASS_NORMAL,
VNET_FLOOD_CLASS_TUNNEL_MASTER,
/* Does not flood when tunnel master is in the same L2 BD */
- VNET_FLOOD_CLASS_TUNNEL_NORMAL
+ VNET_FLOOD_CLASS_TUNNEL_NORMAL,
+ /* Never flood to this type */
+ VNET_FLOOD_CLASS_NO_FLOOD,
} vnet_flood_class_t;
/* Software-interface. This corresponds to a Ethernet VLAN, ATM vc, a
} vnet_flood_class_t;
/* Software-interface. This corresponds to a Ethernet VLAN, ATM vc, a
static void
update_flood_count (l2_bridge_domain_t * bd_config)
{
static void
update_flood_count (l2_bridge_domain_t * bd_config)
{
- bd_config->flood_count = vec_len (bd_config->members) -
- (bd_config->tun_master_count ? bd_config->tun_normal_count : 0);
+ bd_config->flood_count = (vec_len (bd_config->members) -
+ (bd_config->tun_master_count ?
+ bd_config->tun_normal_count : 0));
+ bd_config->flood_count -= bd_config->no_flood_count;
}
void
bd_add_member (l2_bridge_domain_t * bd_config, l2_flood_member_t * member)
{
}
void
bd_add_member (l2_bridge_domain_t * bd_config, l2_flood_member_t * member)
{
vnet_sw_interface_t *sw_if = vnet_get_sw_interface
(vnet_get_main (), member->sw_if_index);
/*
* Add one element to the vector
vnet_sw_interface_t *sw_if = vnet_get_sw_interface
(vnet_get_main (), member->sw_if_index);
/*
* Add one element to the vector
- * vector is ordered [ bvi, normal/tun_masters..., tun_normals... ]
+ * vector is ordered [ bvi, normal/tun_masters..., tun_normals... no_flood]
* When flooding, the bvi interface (if present) must be the last member
* processed due to how BVI processing can change the packet. To enable
* this order, we make the bvi interface the first in the vector and
* When flooding, the bvi interface (if present) must be the last member
* processed due to how BVI processing can change the packet. To enable
* this order, we make the bvi interface the first in the vector and
- * flooding walks the vector in reverse.
+ * flooding walks the vector in reverse. The flood-count determines where
+ * in the member list to start the walk from.
*/
switch (sw_if->flood_class)
{
*/
switch (sw_if->flood_class)
{
+ case VNET_FLOOD_CLASS_NO_FLOOD:
+ bd_config->no_flood_count++;
+ ix = vec_len (bd_config->members);
+ break;
+ case VNET_FLOOD_CLASS_BVI:
+ ix = 0;
+ break;
case VNET_FLOOD_CLASS_TUNNEL_MASTER:
bd_config->tun_master_count++;
/* Fall through */
case VNET_FLOOD_CLASS_TUNNEL_MASTER:
bd_config->tun_master_count++;
/* Fall through */
- default:
- /* Fall through */
case VNET_FLOOD_CLASS_NORMAL:
case VNET_FLOOD_CLASS_NORMAL:
- ix = (member->flags & L2_FLOOD_MEMBER_BVI) ? 0 :
- vec_len (bd_config->members) - bd_config->tun_normal_count;
+ ix = (vec_len (bd_config->members) -
+ bd_config->tun_normal_count - bd_config->no_flood_count);
break;
case VNET_FLOOD_CLASS_TUNNEL_NORMAL:
break;
case VNET_FLOOD_CLASS_TUNNEL_NORMAL:
- ix = vec_len (bd_config->members);
+ ix = (vec_len (bd_config->members) - bd_config->no_flood_count);
bd_config->tun_normal_count++;
break;
}
bd_config->tun_normal_count++;
break;
}
/* Tunnels (Unicast vxlan) are flooded if there are no masters */
u32 tun_normal_count;
/* Tunnels (Unicast vxlan) are flooded if there are no masters */
u32 tun_normal_count;
+ /* Interface on which packets are not flooded */
+ u32 no_flood_count;
+
/* hash ip4/ip6 -> mac for arp/nd termination */
uword *mac_by_ip4;
uword *mac_by_ip6;
/* hash ip4/ip6 -> mac for arp/nd termination */
uword *mac_by_ip4;
uword *mac_by_ip6;
/* undo any BVI-related config */
if (bd_config->bvi_sw_if_index == sw_if_index)
{
/* undo any BVI-related config */
if (bd_config->bvi_sw_if_index == sw_if_index)
{
+ vnet_sw_interface_t *si;
+
bd_config->bvi_sw_if_index = ~0;
config->bvi = 0;
bd_config->bvi_sw_if_index = ~0;
config->bvi = 0;
"ethernet-input",
VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
ASSERT (slot == VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
"ethernet-input",
VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
ASSERT (slot == VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
+
+ /* since this is a no longer BVI interface do not to flood to it */
+ si = vnet_get_sw_interface (vnm, sw_if_index);
+ si->flood_class = VNET_FLOOD_CLASS_NO_FLOOD;
}
/* Clear MACs learned on the interface */
}
/* Clear MACs learned on the interface */
/* Do BVI interface initializations */
if (bvi)
{
/* Do BVI interface initializations */
if (bvi)
{
+ vnet_sw_interface_t *si;
+
/* ensure BD has no bvi interface (or replace that one with this??) */
if (bd_config->bvi_sw_if_index != ~0)
{
/* ensure BD has no bvi interface (or replace that one with this??) */
if (bd_config->bvi_sw_if_index != ~0)
{
"l2-input",
VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
ASSERT (slot == VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
"l2-input",
VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
ASSERT (slot == VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT);
+
+ /* since this is a BVI interface we want to flood to it */
+ si = vnet_get_sw_interface (vnm, sw_if_index);
+ si->flood_class = VNET_FLOOD_CLASS_BVI;
}
/* Add interface to bridge-domain flood vector */
}
/* Add interface to bridge-domain flood vector */