summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/lisp-cp
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/lisp-cp')
-rw-r--r--vnet/vnet/lisp-cp/control.c140
-rw-r--r--vnet/vnet/lisp-cp/control.h3
-rw-r--r--vnet/vnet/lisp-cp/lisp_cp_dpo.c93
-rw-r--r--vnet/vnet/lisp-cp/lisp_cp_dpo.h38
-rw-r--r--vnet/vnet/lisp-cp/lisp_types.c36
-rw-r--r--vnet/vnet/lisp-cp/lisp_types.h15
6 files changed, 258 insertions, 67 deletions
diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c
index 16d7bfa0e1f..5de30d5bb64 100644
--- a/vnet/vnet/lisp-cp/control.c
+++ b/vnet/vnet/lisp-cp/control.c
@@ -18,6 +18,8 @@
#include <vnet/lisp-cp/packets.h>
#include <vnet/lisp-cp/lisp_msg_serdes.h>
#include <vnet/lisp-gpe/lisp_gpe.h>
+#include <vnet/fib/fib_entry.h>
+#include <vnet/fib/fib_table.h>
typedef struct
{
@@ -74,37 +76,36 @@ ip_interface_get_first_ip_address (lisp_cp_main_t * lcm, u32 sw_if_index,
return 1;
}
-static u32
-ip_fib_lookup_with_table (lisp_cp_main_t * lcm, u32 fib_index,
- ip_address_t * dst)
+/**
+ * convert from a LISP address to a FIB prefix
+ */
+void
+ip_address_to_fib_prefix (const ip_address_t * addr, fib_prefix_t * prefix)
{
- if (ip_addr_version (dst) == IP4)
- return ip4_fib_lookup_with_table (lcm->im4, fib_index, &ip_addr_v4 (dst),
- 0);
+ if (addr->version == IP4)
+ {
+ prefix->fp_len = 32;
+ prefix->fp_proto = FIB_PROTOCOL_IP4;
+ memset (&prefix->fp_addr.pad, 0, sizeof (prefix->fp_addr.pad));
+ memcpy (&prefix->fp_addr.ip4, &addr->ip, sizeof (prefix->fp_addr.ip4));
+ }
else
- return ip6_fib_lookup_with_table (lcm->im6, fib_index, &ip_addr_v6 (dst));
+ {
+ prefix->fp_len = 128;
+ prefix->fp_proto = FIB_PROTOCOL_IP6;
+ memcpy (&prefix->fp_addr.ip6, &addr->ip, sizeof (prefix->fp_addr.ip6));
+ }
}
-u32
-ip_fib_get_egress_iface_for_dst_with_lm (lisp_cp_main_t * lcm,
- ip_address_t * dst,
- ip_lookup_main_t * lm)
+/**
+ * convert from a LISP to a FIB prefix
+ */
+void
+ip_prefix_to_fib_prefix (const ip_prefix_t * ip_prefix,
+ fib_prefix_t * fib_prefix)
{
- u32 adj_index;
- ip_adjacency_t *adj;
-
- adj_index = ip_fib_lookup_with_table (lcm, 0, dst);
- adj = ip_get_adjacency (lm, adj_index);
-
- if (adj == 0)
- return ~0;
-
- /* we only want outgoing routes */
- if (adj->lookup_next_index != IP_LOOKUP_NEXT_ARP
- && adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
- return ~0;
-
- return adj->rewrite_header.sw_if_index;
+ ip_address_to_fib_prefix (&ip_prefix->addr, fib_prefix);
+ fib_prefix->fp_len = ip_prefix->len;
}
/**
@@ -114,12 +115,14 @@ ip_fib_get_egress_iface_for_dst_with_lm (lisp_cp_main_t * lcm,
u32
ip_fib_get_egress_iface_for_dst (lisp_cp_main_t * lcm, ip_address_t * dst)
{
- ip_lookup_main_t *lm;
+ fib_node_index_t fei;
+ fib_prefix_t prefix;
+
+ ip_address_to_fib_prefix (dst, &prefix);
- lm = ip_addr_version (dst) == IP4 ?
- &lcm->im4->lookup_main : &lcm->im6->lookup_main;
+ fei = fib_table_lookup (0, &prefix);
- return ip_fib_get_egress_iface_for_dst_with_lm (lcm, dst, lm);
+ return (fib_entry_get_resolving_interface (fei));
}
/**
@@ -140,7 +143,7 @@ ip_fib_get_first_egress_ip_for_dst (lisp_cp_main_t * lcm, ip_address_t * dst,
ipver = ip_addr_version (dst);
lm = (ipver == IP4) ? &lcm->im4->lookup_main : &lcm->im6->lookup_main;
- si = ip_fib_get_egress_iface_for_dst_with_lm (lcm, dst, lm);
+ si = ip_fib_get_egress_iface_for_dst (lcm, dst);
if ((u32) ~ 0 == si)
return 0;
@@ -2871,28 +2874,14 @@ lisp_get_vni_from_buffer_ip (lisp_cp_main_t * lcm, vlib_buffer_t * b,
u8 version)
{
uword *vnip;
- u32 vni = ~0, table_id = ~0, fib_index;
+ u32 vni = ~0, table_id = ~0;
- if (version == IP4)
- {
- ip4_fib_t *fib;
- ip4_main_t *im4 = &ip4_main;
- fib_index = vec_elt (im4->fib_index_by_sw_if_index,
- vnet_buffer (b)->sw_if_index[VLIB_RX]);
- fib = find_ip4_fib_by_table_index_or_id (im4, fib_index,
- IP4_ROUTE_FLAG_FIB_INDEX);
- table_id = fib->table_id;
- }
- else
- {
- ip6_fib_t *fib;
- ip6_main_t *im6 = &ip6_main;
- fib_index = vec_elt (im6->fib_index_by_sw_if_index,
- vnet_buffer (b)->sw_if_index[VLIB_RX]);
- fib = find_ip6_fib_by_table_index_or_id (im6, fib_index,
- IP6_ROUTE_FLAG_FIB_INDEX);
- table_id = fib->table_id;
- }
+ table_id =
+ fib_table_get_table_id_for_sw_if_index (vnet_buffer (b)->sw_if_index
+ [VLIB_RX],
+ (version ==
+ IP4 ? FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6));
vnip = hash_get (lcm->vni_by_table_id, table_id);
if (vnip)
@@ -2979,8 +2968,9 @@ get_src_and_dst_eids_from_buffer (lisp_cp_main_t * lcm, vlib_buffer_t * b,
}
static uword
-lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
+lisp_cp_lookup_inline (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * from_frame, int overlay)
{
u32 *from, *to_next_drop, di, si;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
@@ -3010,6 +3000,7 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
b0 = vlib_get_buffer (vm, pi0);
b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
+ vnet_buffer (b0)->lisp.overlay_afi = overlay;
/* src/dst eid pair */
get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst);
@@ -3070,10 +3061,45 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
return from_frame->n_vectors;
}
+static uword
+lisp_cp_lookup_ip4 (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * from_frame)
+{
+ return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP));
+}
+
+static uword
+lisp_cp_lookup_ip6 (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * from_frame)
+{
+ return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP6));
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (lisp_cp_lookup_ip4_node) = {
+ .function = lisp_cp_lookup_ip4,
+ .name = "lisp-cp-lookup-ip4",
+ .vector_size = sizeof (u32),
+ .format_trace = format_lisp_cp_lookup_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+
+ .n_errors = LISP_CP_LOOKUP_N_ERROR,
+ .error_strings = lisp_cp_lookup_error_strings,
+
+ .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
+
+ .next_nodes = {
+ [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
+ [LISP_CP_LOOKUP_NEXT_IP4_LOOKUP] = "ip4-lookup",
+ [LISP_CP_LOOKUP_NEXT_IP6_LOOKUP] = "ip6-lookup",
+ },
+};
+/* *INDENT-ON* */
+
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (lisp_cp_lookup_node) = {
- .function = lisp_cp_lookup,
- .name = "lisp-cp-lookup",
+VLIB_REGISTER_NODE (lisp_cp_lookup_ip6_node) = {
+ .function = lisp_cp_lookup_ip6,
+ .name = "lisp-cp-lookup-ip6",
.vector_size = sizeof (u32),
.format_trace = format_lisp_cp_lookup_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
diff --git a/vnet/vnet/lisp-cp/control.h b/vnet/vnet/lisp-cp/control.h
index 76590b2c36b..02efd046170 100644
--- a/vnet/vnet/lisp-cp/control.h
+++ b/vnet/vnet/lisp-cp/control.h
@@ -149,7 +149,8 @@ typedef struct
lisp_cp_main_t lisp_control_main;
extern vlib_node_registration_t lisp_cp_input_node;
-extern vlib_node_registration_t lisp_cp_lookup_node;
+extern vlib_node_registration_t lisp_cp_lookup_ip4_node;
+extern vlib_node_registration_t lisp_cp_lookup_ip6_node;
clib_error_t *lisp_cp_init ();
diff --git a/vnet/vnet/lisp-cp/lisp_cp_dpo.c b/vnet/vnet/lisp-cp/lisp_cp_dpo.c
new file mode 100644
index 00000000000..0bb8098d6fc
--- /dev/null
+++ b/vnet/vnet/lisp-cp/lisp_cp_dpo.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/dpo/dpo.h>
+#include <vnet/lisp-gpe/lisp_gpe.h>
+#include <vnet/lisp-cp/control.h>
+
+index_t
+lisp_cp_dpo_get (fib_protocol_t proto)
+{
+ /*
+ * there are only two instances of this DPO type.
+ * we can use the protocol as the index
+ */
+ return (proto);
+}
+
+static u8*
+format_lisp_cp_dpo (u8 *s, va_list *args)
+{
+ index_t index = va_arg (*args, index_t);
+ CLIB_UNUSED(u32 indent) = va_arg (*args, u32);
+
+ return (format(s, "lisp-cp-punt-%U",
+ format_fib_protocol, index));
+}
+
+static void
+lisp_cp_dpo_lock (dpo_id_t *dpo)
+{
+}
+
+static void
+lisp_cp_dpo_unlock (dpo_id_t *dpo)
+{
+}
+
+const static dpo_vft_t lisp_cp_vft = {
+ .dv_lock = lisp_cp_dpo_lock,
+ .dv_unlock = lisp_cp_dpo_unlock,
+ .dv_format = format_lisp_cp_dpo,
+};
+
+/**
+ * @brief The per-protocol VLIB graph nodes that are assigned to a LISP-CP
+ * object.
+ *
+ * this means that these graph nodes are ones from which a LISP-CP is the
+ * parent object in the DPO-graph.
+ */
+const static char* const lisp_cp_ip4_nodes[] =
+{
+ "lisp-cp-lookup-ip4",
+ NULL,
+};
+const static char* const lisp_cp_ip6_nodes[] =
+{
+ "lisp-cp-lookup-ip6",
+ NULL,
+};
+
+const static char* const * const lisp_cp_nodes[DPO_PROTO_NUM] =
+{
+ [DPO_PROTO_IP4] = lisp_cp_ip4_nodes,
+ [DPO_PROTO_IP6] = lisp_cp_ip6_nodes,
+ [DPO_PROTO_MPLS] = NULL,
+};
+
+clib_error_t *
+lisp_cp_dpo_module_init (vlib_main_t * vm)
+{
+ /*
+ * there are no exit arcs from the LIS-CP VLIB node, so we
+ * pass NULL as said node array.
+ */
+ dpo_register(DPO_LISP_CP, &lisp_cp_vft, lisp_cp_nodes);
+
+ return (NULL);
+}
+
+VLIB_INIT_FUNCTION(lisp_cp_dpo_module_init);
diff --git a/vnet/vnet/lisp-cp/lisp_cp_dpo.h b/vnet/vnet/lisp-cp/lisp_cp_dpo.h
new file mode 100644
index 00000000000..ea97711a8de
--- /dev/null
+++ b/vnet/vnet/lisp-cp/lisp_cp_dpo.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LISP_CP_DPO_H__
+#define __LISP_CP_DPO_H__
+
+#include <vnet/vnet.h>
+#include <vnet/fib/fib_types.h>
+#include <vnet/dpo/dpo.h>
+
+/**
+ * A representation of punt to the LISP control plane.
+ */
+typedef struct lisp_cp_dpo_t
+{
+ /**
+ * The transport payload type.
+ */
+ fib_protocol_t lcd_proto;
+} lisp_cp_dpo_t;
+
+extern index_t lisp_cp_dpo_get(fib_protocol_t proto);
+
+extern void lisp_cp_dpo_module_init(void);
+
+#endif
diff --git a/vnet/vnet/lisp-cp/lisp_types.c b/vnet/vnet/lisp-cp/lisp_types.c
index b4fb1d91bfc..a2edb487cca 100644
--- a/vnet/vnet/lisp-cp/lisp_types.c
+++ b/vnet/vnet/lisp-cp/lisp_types.c
@@ -147,6 +147,8 @@ uword
unformat_ip_address (unformat_input_t * input, va_list * args)
{
ip_address_t *a = va_arg (*args, ip_address_t *);
+
+ memset (a, 0, sizeof (*a));
if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
ip_addr_version (a) = IP4;
else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
@@ -331,8 +333,32 @@ unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
return 1;
}
+u8 *
+format_negative_mapping_action (u8 * s, va_list * args)
+{
+ lisp_action_e action = va_arg (*args, lisp_action_e);
+
+ switch (action)
+ {
+ case LISP_NO_ACTION:
+ s = format (s, "no-action");
+ break;
+ case LISP_FORWARD_NATIVE:
+ s = format (s, "natively-forward");
+ break;
+ case LISP_SEND_MAP_REQUEST:
+ s = format (s, "send-map-request");
+ break;
+ case LISP_DROP:
+ default:
+ s = format (s, "drop");
+ break;
+ }
+ return (s);
+}
+
u16
-ip_address_size (ip_address_t * a)
+ip_address_size (const ip_address_t * a)
{
switch (ip_addr_version (a))
{
@@ -653,7 +679,7 @@ gid_address_free (gid_address_t * a)
}
int
-ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
+ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
{
int res = 0;
if (ip_addr_version (ip1) != ip_addr_version (ip2))
@@ -670,19 +696,19 @@ ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
}
void
-ip_address_copy (ip_address_t * dst, ip_address_t * src)
+ip_address_copy (ip_address_t * dst, const ip_address_t * src)
{
clib_memcpy (dst, src, sizeof (ip_address_t));
}
void
-ip_address_copy_addr (void *dst, ip_address_t * src)
+ip_address_copy_addr (void *dst, const ip_address_t * src)
{
clib_memcpy (dst, src, ip_address_size (src));
}
void
-ip_address_set (ip_address_t * dst, void *src, u8 version)
+ip_address_set (ip_address_t * dst, const void *src, u8 version)
{
clib_memcpy (dst, src, ip_version_to_size (version));
ip_addr_version (dst) = version;
diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h
index cb1b277b530..cd1d1b9a642 100644
--- a/vnet/vnet/lisp-cp/lisp_types.h
+++ b/vnet/vnet/lisp-cp/lisp_types.h
@@ -42,10 +42,10 @@ typedef CLIB_PACKED(struct ip_address
#define ip_addr_v6(_a) (_a)->ip.v6
#define ip_addr_version(_a) (_a)->version
-int ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2);
-void ip_address_copy (ip_address_t * dst, ip_address_t * src);
-void ip_address_copy_addr (void *dst, ip_address_t * src);
-void ip_address_set (ip_address_t * dst, void *src, u8 version);
+int ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2);
+void ip_address_copy (ip_address_t * dst, const ip_address_t * src);
+void ip_address_copy_addr (void *dst, const ip_address_t * src);
+void ip_address_set (ip_address_t * dst, const void *src, u8 version);
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct ip_prefix
@@ -63,6 +63,11 @@ typedef CLIB_PACKED(struct ip_prefix
void ip_prefix_normalize (ip_prefix_t * a);
+extern void ip_address_to_fib_prefix (const ip_address_t * addr,
+ fib_prefix_t * prefix);
+extern void ip_prefix_to_fib_prefix (const ip_prefix_t * ipp,
+ fib_prefix_t * fibp);
+
typedef enum
{
/* NOTE: ip addresses are left out on purpose. Use max masked ip-prefixes
@@ -107,6 +112,7 @@ typedef fid_address_t dp_address_t;
#define fid_addr_ippref(_a) (_a)->ippref
#define fid_addr_mac(_a) (_a)->mac
#define fid_addr_type(_a) (_a)->type
+u8 *format_fid_address (u8 * s, va_list * args);
typedef struct
{
@@ -293,6 +299,7 @@ typedef struct
uword
unformat_negative_mapping_action (unformat_input_t * input, va_list * args);
+u8 *format_negative_mapping_action (u8 *, va_list * args);
typedef struct locator_pair
{