aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-03-04 14:08:11 -0800
committerNeale Ranns <nranns@cisco.com>2019-03-06 10:31:38 +0000
commit8da9fc659badc016e409f772673002f021c0cc4a (patch)
tree0223180b7344b652ab8c45bb38f47f335bbed7c5 /src/plugins/gbp
parentdc8d93b02949f508d5eed312a51aa91102224b39 (diff)
GBP: learn from ARP and L2 packets
Change-Id: I8af7bca566ec7c9bd2b72529d49e04c6e649b44a Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/plugins/gbp')
-rw-r--r--src/plugins/gbp/gbp.api1
-rw-r--r--src/plugins/gbp/gbp_api.c4
-rw-r--r--src/plugins/gbp/gbp_bridge_domain.c5
-rw-r--r--src/plugins/gbp/gbp_bridge_domain.h6
-rw-r--r--src/plugins/gbp/gbp_endpoint.c23
-rw-r--r--src/plugins/gbp/gbp_learn_node.c29
-rw-r--r--src/plugins/gbp/gbp_vxlan.c9
-rw-r--r--src/plugins/gbp/gbp_vxlan.h9
8 files changed, 69 insertions, 17 deletions
diff --git a/src/plugins/gbp/gbp.api b/src/plugins/gbp/gbp.api
index 347855197d7..8343e228f19 100644
--- a/src/plugins/gbp/gbp.api
+++ b/src/plugins/gbp/gbp.api
@@ -344,6 +344,7 @@ typedef gbp_vxlan_tunnel
u32 vni;
vl_api_gbp_vxlan_tunnel_mode_t mode;
u32 bd_rd_id;
+ vl_api_ip4_address_t src;
};
define gbp_vxlan_tunnel_add
diff --git a/src/plugins/gbp/gbp_api.c b/src/plugins/gbp/gbp_api.c
index 7c36da6829a..ffdae2869bf 100644
--- a/src/plugins/gbp/gbp_api.c
+++ b/src/plugins/gbp/gbp_api.c
@@ -1036,9 +1036,11 @@ vl_api_gbp_vxlan_tunnel_add_t_handler (vl_api_gbp_vxlan_tunnel_add_t * mp)
{
vl_api_gbp_vxlan_tunnel_add_reply_t *rmp;
gbp_vxlan_tunnel_layer_t layer;
+ ip4_address_t src;
u32 sw_if_index;
int rv = 0;
+ ip4_address_decode (mp->tunnel.src, &src);
rv = gbp_vxlan_tunnel_mode_2_layer (mp->tunnel.mode, &layer);
if (0 != rv)
@@ -1046,7 +1048,7 @@ vl_api_gbp_vxlan_tunnel_add_t_handler (vl_api_gbp_vxlan_tunnel_add_t * mp)
rv = gbp_vxlan_tunnel_add (ntohl (mp->tunnel.vni),
layer,
- ntohl (mp->tunnel.bd_rd_id), &sw_if_index);
+ ntohl (mp->tunnel.bd_rd_id), &src, &sw_if_index);
out:
/* *INDENT-OFF* */
diff --git a/src/plugins/gbp/gbp_bridge_domain.c b/src/plugins/gbp/gbp_bridge_domain.c
index 261b5683903..24bfb254ad4 100644
--- a/src/plugins/gbp/gbp_bridge_domain.c
+++ b/src/plugins/gbp/gbp_bridge_domain.c
@@ -16,6 +16,7 @@
#include <plugins/gbp/gbp_bridge_domain.h>
#include <plugins/gbp/gbp_endpoint.h>
#include <plugins/gbp/gbp_sclass.h>
+#include <plugins/gbp/gbp_learn.h>
#include <vnet/dpo/dvr_dpo.h>
#include <vnet/fib/fib_table.h>
@@ -125,7 +126,7 @@ format_gbp_bridge_domain_flags (u8 * s, va_list * args)
}
else
{
- s = format (s, "noe");
+ s = format (s, "none");
}
return (s);
}
@@ -218,6 +219,7 @@ gbp_bridge_domain_add_and_lock (u32 bd_id,
MODE_L2_BRIDGE, gb->gb_bm_flood_sw_if_index,
bd_index, L2_BD_PORT_TYPE_NORMAL, 0, 0);
gbp_sclass_enable_l2 (gb->gb_bm_flood_sw_if_index);
+ gbp_learn_enable (gb->gb_bm_flood_sw_if_index, GBP_LEARN_MODE_L2);
}
/*
@@ -275,6 +277,7 @@ gbp_bridge_domain_unlock (index_t index)
MODE_L3, gb->gb_bm_flood_sw_if_index,
gb->gb_bd_index, L2_BD_PORT_TYPE_NORMAL, 0, 0);
gbp_sclass_disable_l2 (gb->gb_bm_flood_sw_if_index);
+ gbp_learn_enable (gb->gb_bm_flood_sw_if_index, GBP_LEARN_MODE_L2);
}
gbp_bridge_domain_db_remove (gb);
diff --git a/src/plugins/gbp/gbp_bridge_domain.h b/src/plugins/gbp/gbp_bridge_domain.h
index 25498eee5fe..8e6146c7955 100644
--- a/src/plugins/gbp/gbp_bridge_domain.h
+++ b/src/plugins/gbp/gbp_bridge_domain.h
@@ -63,10 +63,10 @@ typedef struct gbp_bridge_domain_t_
u32 gb_bm_flood_sw_if_index;
/**
- * The BD's VNI interface on which packets from unkown endpoints
- * arrive
+ * The index of the BD's VNI interface on which packets from
+ * unkown endpoints arrive
*/
- u32 gb_vni_sw_if_index;
+ u32 gb_vni;
/**
* locks/references to the BD so it does not get deleted (from the API)
diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c
index 9cae2ab9421..4bd726fec31 100644
--- a/src/plugins/gbp/gbp_endpoint.c
+++ b/src/plugins/gbp/gbp_endpoint.c
@@ -32,6 +32,7 @@
#include <vnet/fib/fib_table.h>
#include <vnet/ip/ip_neighbor.h>
#include <vnet/fib/fib_walk.h>
+#include <vnet/vxlan-gbp/vxlan_gbp.h>
static const char *gbp_endpoint_attr_names[] = GBP_ENDPOINT_ATTR_NAMES;
@@ -473,6 +474,7 @@ gbp_endpoint_n_learned (int n)
static void
gbp_endpoint_loc_update (gbp_endpoint_loc_t * gel,
+ const gbp_bridge_domain_t * gb,
u32 sw_if_index,
index_t ggi,
gbp_endpoint_flags_t flags,
@@ -508,6 +510,24 @@ gbp_endpoint_loc_update (gbp_endpoint_loc_t * gel,
if (NULL != tun_dst)
ip46_address_copy (&gel->tun.gel_dst, tun_dst);
+ if (ip46_address_is_multicast (&gel->tun.gel_src))
+ {
+ /*
+ * we learnt the EP from the multicast tunnel.
+ * Create a unicast TEP from the packet's source
+ * and the fixed address of the BD's parent tunnel
+ */
+ const gbp_vxlan_tunnel_t *gt;
+
+ gt = gbp_vxlan_tunnel_get (gb->gb_vni);
+
+ if (NULL != gt)
+ {
+ ip46_address_copy (&gel->tun.gel_src, &gt->gt_src);
+ sw_if_index = gt->gt_sw_if_index;
+ }
+ }
+
/*
* the input interface may be the parent GBP-vxlan interface,
* create a child vlxan-gbp tunnel and use that as the endpoint's
@@ -862,7 +882,8 @@ gbp_endpoint_update_and_lock (gbp_endpoint_src_t src,
gei = gbp_endpoint_index (ge);
gel = gbp_endpoint_loc_find_or_add (ge, src);
- gbp_endpoint_loc_update (gel, sw_if_index, ggi, flags, tun_src, tun_dst);
+ gbp_endpoint_loc_update (gel, gbd, sw_if_index, ggi, flags, tun_src,
+ tun_dst);
if (src <= best)
{
diff --git a/src/plugins/gbp/gbp_learn_node.c b/src/plugins/gbp/gbp_learn_node.c
index ebb121716b2..461d209e0a6 100644
--- a/src/plugins/gbp/gbp_learn_node.c
+++ b/src/plugins/gbp/gbp_learn_node.c
@@ -22,6 +22,7 @@
#include <vnet/l2/l2_input.h>
#include <vnet/fib/fib_table.h>
#include <vnet/vxlan-gbp/vxlan_gbp_packet.h>
+#include <vnet/ethernet/arp_packet.h>
#define GBP_LEARN_DBG(...) \
vlib_log_debug (gbp_learn_main.gl_logger, __VA_ARGS__);
@@ -72,10 +73,8 @@ gbp_learn_l2_cp (const gbp_learn_l2_t * gl2)
format_mac_address_t, &gl2->mac,
format_ip46_address, &gl2->ip, IP46_TYPE_ANY, gl2->epg);
- vec_add1 (ips, gl2->ip);
-
- ASSERT (!ip46_address_is_zero (&gl2->outer_src));
- ASSERT (!ip46_address_is_zero (&gl2->outer_dst));
+ if (!ip46_address_is_zero (&gl2->ip))
+ vec_add1 (ips, gl2->ip);
/*
* flip the source and dst, since that's how it was received, this API
@@ -107,9 +106,6 @@ gbp_learn_l2_ip4_dp (const u8 * mac, const ip4_address_t * ip,
};
mac_address_from_bytes (&gl2.mac, mac);
- ASSERT (!ip46_address_is_zero (&gl2.outer_src));
- ASSERT (!ip46_address_is_zero (&gl2.outer_dst));
-
vl_api_rpc_call_main_thread (gbp_learn_l2_cp, (u8 *) & gl2, sizeof (gl2));
}
@@ -260,6 +256,12 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
{
gbp_learn_get_outer (eh0, &outer_src, &outer_dst);
+ if (outer_src.as_u32 == 0 || outer_dst.as_u32 == 0)
+ {
+ t0 = 2;
+ goto trace;
+ }
+
switch (clib_net_to_host_u16 (eh0->type))
{
case ETHERNET_TYPE_IP4:
@@ -290,6 +292,19 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
break;
}
+ case ETHERNET_TYPE_ARP:
+ {
+ const ethernet_arp_header_t *arp0;
+
+ arp0 = (ethernet_arp_header_t *) (eh0 + 1);
+
+ gbp_learn_l2_ip4_dp (eh0->src_address,
+ &arp0->ip4_over_ethernet[0].ip4,
+ vnet_buffer (b0)->l2.bd_index,
+ sw_if_index0, epg0,
+ &outer_src, &outer_dst);
+ break;
+ }
default:
gbp_learn_l2_dp (eh0->src_address,
vnet_buffer (b0)->l2.bd_index,
diff --git a/src/plugins/gbp/gbp_vxlan.c b/src/plugins/gbp/gbp_vxlan.c
index 846ea0fa6ff..c0e88fdda8e 100644
--- a/src/plugins/gbp/gbp_vxlan.c
+++ b/src/plugins/gbp/gbp_vxlan.c
@@ -465,7 +465,8 @@ VNET_HW_INTERFACE_CLASS (gbp_vxlan_hw_interface_class) = {
int
gbp_vxlan_tunnel_add (u32 vni, gbp_vxlan_tunnel_layer_t layer,
- u32 bd_rd_id, u32 * sw_if_indexp)
+ u32 bd_rd_id,
+ const ip4_address_t * src, u32 * sw_if_indexp)
{
gbp_vxlan_tunnel_t *gt;
index_t gti;
@@ -512,6 +513,7 @@ gbp_vxlan_tunnel_add (u32 vni, gbp_vxlan_tunnel_layer_t layer,
gt->gt_vni = vni;
gt->gt_layer = layer;
gt->gt_bd_rd_id = bd_rd_id;
+ gt->gt_src.ip4.as_u32 = src->as_u32;
gt->gt_hw_if_index = vnet_register_interface (vnm,
gbp_vxlan_device_class.index,
gti,
@@ -534,7 +536,7 @@ gbp_vxlan_tunnel_add (u32 vni, gbp_vxlan_tunnel_layer_t layer,
gt->gt_gbd = gbi;
gt->gt_bd_index = gb->gb_bd_index;
- gb->gb_vni_sw_if_index = gt->gt_sw_if_index;
+ gb->gb_vni = gti;
/* set it up as a GBP interface */
gt->gt_itf = gbp_itf_add_and_lock (gt->gt_sw_if_index,
gt->gt_bd_index);
@@ -571,7 +573,8 @@ gbp_vxlan_tunnel_add (u32 vni, gbp_vxlan_tunnel_layer_t layer,
*/
hash_set (gv_db, vni, gti);
- vec_validate (gbp_vxlan_tunnel_db, gt->gt_sw_if_index);
+ vec_validate_init_empty (gbp_vxlan_tunnel_db,
+ gt->gt_sw_if_index, INDEX_INVALID);
gbp_vxlan_tunnel_db[gt->gt_sw_if_index] = gti;
if (sw_if_indexp)
diff --git a/src/plugins/gbp/gbp_vxlan.h b/src/plugins/gbp/gbp_vxlan.h
index acf5f4b1c7c..908abc2990e 100644
--- a/src/plugins/gbp/gbp_vxlan.h
+++ b/src/plugins/gbp/gbp_vxlan.h
@@ -82,6 +82,11 @@ typedef struct gbp_vxlan_tunnel_t_
* list of child vxlan-gbp tunnels built from this template
*/
index_t *gt_tuns;
+
+ /**
+ * The source address to use for child tunnels
+ */
+ ip46_address_t gt_src;
} gbp_vxlan_tunnel_t;
/**
@@ -103,7 +108,9 @@ typedef enum gbp_vxlan_tunnel_type_t_
} gbp_vxlan_tunnel_type_t;
extern int gbp_vxlan_tunnel_add (u32 vni, gbp_vxlan_tunnel_layer_t layer,
- u32 bd_rd_id, u32 * sw_if_indexp);
+ u32 bd_rd_id,
+ const ip4_address_t * src,
+ u32 * sw_if_indexp);
extern int gbp_vxlan_tunnel_del (u32 vni);
extern gbp_vxlan_tunnel_type_t gbp_vxlan_tunnel_get_type (u32 sw_if_index);