diff options
Diffstat (limited to 'vnet/vnet/lisp-cp')
-rw-r--r-- | vnet/vnet/lisp-cp/control.c | 140 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/control.h | 3 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_cp_dpo.c | 93 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_cp_dpo.h | 38 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.c | 36 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.h | 15 |
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 { |