2015-12-08 15:45:58 -07:00
|
|
|
/*
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
* Copyright (c) 2016 Cisco and/or its affiliates.
|
2015-12-08 15:45:58 -07:00
|
|
|
* 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.
|
|
|
|
|
*/
|
2016-09-05 19:30:35 +02:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief L2 LISP-GPE decap code.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2015-12-08 15:45:58 -07:00
|
|
|
#include <vlib/vlib.h>
|
2020-09-21 08:17:51 +00:00
|
|
|
#include <lisp/lisp-gpe/lisp_gpe.h>
|
2015-12-08 15:45:58 -07:00
|
|
|
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
typedef struct
|
|
|
|
|
{
|
2015-12-08 15:45:58 -07:00
|
|
|
u32 next_index;
|
|
|
|
|
u32 tunnel_index;
|
|
|
|
|
u32 error;
|
|
|
|
|
lisp_gpe_header_t h;
|
|
|
|
|
} lisp_gpe_rx_trace_t;
|
|
|
|
|
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
static u8 *
|
|
|
|
|
format_lisp_gpe_rx_trace (u8 * s, va_list * args)
|
2015-12-08 15:45:58 -07:00
|
|
|
{
|
|
|
|
|
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
|
|
|
|
|
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
|
2016-08-16 23:04:00 +02:00
|
|
|
lisp_gpe_rx_trace_t *t = va_arg (*args, lisp_gpe_rx_trace_t *);
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
if (t->tunnel_index != ~0)
|
|
|
|
|
{
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
s = format (s, "LISP-GPE: tunnel %d next %d error %d", t->tunnel_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
t->next_index, t->error);
|
2015-12-08 15:45:58 -07:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
s = format (s, "LISP-GPE: no tunnel next %d error %d\n", t->next_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
t->error);
|
2015-12-08 15:45:58 -07:00
|
|
|
}
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
s = format (s, "\n %U", format_lisp_gpe_header_with_length, &t->h,
|
2016-08-16 23:04:00 +02:00
|
|
|
(u32) sizeof (t->h) /* max size */ );
|
2015-12-08 15:45:58 -07:00
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-16 23:04:00 +02:00
|
|
|
static u32 next_proto_to_next_index[LISP_GPE_NEXT_PROTOS] = {
|
|
|
|
|
LISP_GPE_INPUT_NEXT_DROP,
|
|
|
|
|
LISP_GPE_INPUT_NEXT_IP4_INPUT,
|
|
|
|
|
LISP_GPE_INPUT_NEXT_IP6_INPUT,
|
|
|
|
|
LISP_GPE_INPUT_NEXT_L2_INPUT,
|
|
|
|
|
LISP_GPE_INPUT_NEXT_DROP
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
};
|
|
|
|
|
|
2016-07-22 01:45:30 +02:00
|
|
|
always_inline u32
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
next_protocol_to_next_index (lisp_gpe_header_t * lgh, u8 * next_header)
|
|
|
|
|
{
|
2017-02-21 18:28:34 +01:00
|
|
|
lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
|
|
|
|
|
|
2016-05-02 18:26:26 +02:00
|
|
|
/* lisp-gpe router */
|
2016-08-16 23:04:00 +02:00
|
|
|
if (PREDICT_TRUE ((lgh->flags & LISP_GPE_FLAGS_P)
|
2017-02-21 18:28:34 +01:00
|
|
|
|| GPE_ENCAP_VXLAN == lgm->encap_mode))
|
|
|
|
|
{
|
2017-02-28 04:13:21 -08:00
|
|
|
if (PREDICT_FALSE (lgh->next_protocol >= LISP_GPE_NEXT_PROTOS))
|
2017-02-21 18:28:34 +01:00
|
|
|
return LISP_GPE_INPUT_NEXT_DROP;
|
|
|
|
|
|
|
|
|
|
return next_proto_to_next_index[lgh->next_protocol];
|
|
|
|
|
}
|
2016-07-22 01:45:30 +02:00
|
|
|
/* legacy lisp router */
|
2016-05-02 18:26:26 +02:00
|
|
|
else if ((lgh->flags & LISP_GPE_FLAGS_P) == 0)
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
{
|
2016-08-16 23:04:00 +02:00
|
|
|
ip4_header_t *iph = (ip4_header_t *) next_header;
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
if ((iph->ip_version_and_header_length & 0xF0) == 0x40)
|
2016-08-16 23:04:00 +02:00
|
|
|
return LISP_GPE_INPUT_NEXT_IP4_INPUT;
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
else if ((iph->ip_version_and_header_length & 0xF0) == 0x60)
|
2016-08-16 23:04:00 +02:00
|
|
|
return LISP_GPE_INPUT_NEXT_IP6_INPUT;
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
else
|
2016-08-16 23:04:00 +02:00
|
|
|
return LISP_GPE_INPUT_NEXT_DROP;
|
LISP GPE: initial CP commit and DP improvements
Control Plane
-------------
In essence, this introduces basic support for map-request/reply
processing, the logic to generate and consume such messages, including
SMRs, a control-plane backend, consisting of an eid-table, locator and
locator-set tables, and CLI to interact with it. Naturally, we can now
serialize/deserialize LISP specific types: addresses, locators,
mappings, messages. An important caveat is that IPv6 support is not
complete, both for EIDs and RLOCs.
Functionally, the DP forwards all packets it can't handle to the CP
(lisp_cp_lookup node) which takes care of obtaining a mapping for the
packet's destination from a pre-configured map-resolver using the LISP
protocol. The CP then caches this information and programs the DP such
that all new packets with the same destination (or within the covering
prefix) are encapsulated to one of the locators retrieved in the
mapping. Ingress traffic-engineering is not yet supported.
Data Plane
----------
First of all, to enable punting to the CP, when LISP GPE is turned on a
default route that points to lisp_cp_lookup is now inserted. The DP
also exposes an API the CP can use to program forwarding for a given
mapping. This mainly consists in allocating a tunnel and programming the
FIB such that all packets destined to the mapping's prefix are forwarded
to a lisp-gpe encapsulating node.
Another important change done for lisp forwarding is that both source
and destination IP addresses are considered when encapsulating a packet.
To this end, a new FIB/mtrie is introduced as a second stage, src
lookup, post dst lookup. The latter is still done in the IP FIB but for
source-dest entries, in the dest adjacency the lookup_next_index points
to a lisp lookup node and the rewrite_header.sw_if_index points to the
src FIB. This is read by the lisp lookup node which then walks the src
mtrie, finds the associated adjacency, marks the buffer with the index
and forwards the packet to the appropriate next node (typically,
lisp-gpe-encap).
Change-Id: Ibdf52fdc1f89311854621403ccdd66f90e2522fd
Signed-off-by: Florin Coras <fcoras@cisco.com>
2016-02-18 22:20:01 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return LISP_GPE_INPUT_NEXT_DROP;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 01:45:30 +02:00
|
|
|
always_inline tunnel_lookup_t *
|
|
|
|
|
next_index_to_iface (lisp_gpe_main_t * lgm, u32 next_index)
|
|
|
|
|
{
|
|
|
|
|
if (LISP_GPE_INPUT_NEXT_IP4_INPUT == next_index
|
|
|
|
|
|| LISP_GPE_INPUT_NEXT_IP6_INPUT == next_index)
|
|
|
|
|
return &lgm->l3_ifaces;
|
|
|
|
|
else if (LISP_GPE_INPUT_NEXT_L2_INPUT == next_index)
|
|
|
|
|
return &lgm->l2_ifaces;
|
2017-02-22 23:38:08 -08:00
|
|
|
else if (LISP_GPE_INPUT_NEXT_NSH_INPUT == next_index)
|
|
|
|
|
return &lgm->nsh_ifaces;
|
2016-08-16 23:04:00 +02:00
|
|
|
clib_warning ("next_index not associated to an interface!");
|
2016-07-22 01:45:30 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-21 22:32:47 +02:00
|
|
|
static_always_inline void
|
2017-04-05 19:18:20 +02:00
|
|
|
incr_decap_stats (vnet_main_t * vnm, u32 thread_index, u32 length,
|
2016-08-16 23:04:00 +02:00
|
|
|
u32 sw_if_index, u32 * last_sw_if_index, u32 * n_packets,
|
|
|
|
|
u32 * n_bytes)
|
2016-06-21 22:32:47 +02:00
|
|
|
{
|
2016-08-16 23:04:00 +02:00
|
|
|
vnet_interface_main_t *im;
|
2016-06-21 22:32:47 +02:00
|
|
|
|
2016-08-16 23:04:00 +02:00
|
|
|
if (PREDICT_TRUE (sw_if_index == *last_sw_if_index))
|
2016-06-21 22:32:47 +02:00
|
|
|
{
|
|
|
|
|
*n_packets += 1;
|
|
|
|
|
*n_bytes += length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-08-16 23:04:00 +02:00
|
|
|
if (PREDICT_TRUE (*last_sw_if_index != ~0))
|
|
|
|
|
{
|
|
|
|
|
im = &vnm->interface_main;
|
|
|
|
|
|
|
|
|
|
vlib_increment_combined_counter (im->combined_sw_if_counters +
|
|
|
|
|
VNET_INTERFACE_COUNTER_RX,
|
2017-04-05 19:18:20 +02:00
|
|
|
thread_index, *last_sw_if_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
*n_packets, *n_bytes);
|
|
|
|
|
}
|
2016-06-21 22:32:47 +02:00
|
|
|
*last_sw_if_index = sw_if_index;
|
|
|
|
|
*n_packets = 1;
|
|
|
|
|
*n_bytes = length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-05 19:30:35 +02:00
|
|
|
/**
|
|
|
|
|
* @brief LISP-GPE decap dispatcher.
|
|
|
|
|
* @node lisp_gpe_input_inline
|
|
|
|
|
*
|
|
|
|
|
* LISP-GPE decap dispatcher.
|
|
|
|
|
*
|
|
|
|
|
* Decaps IP-UDP-LISP-GPE header and based on the next protocol and in the
|
|
|
|
|
* GPE header and the vni decides the next node to forward the packet to.
|
|
|
|
|
*
|
|
|
|
|
* @param[in] vm vlib_main_t corresponding to current thread.
|
|
|
|
|
* @param[in] node vlib_node_runtime_t data for this node.
|
|
|
|
|
* @param[in] frame vlib_frame_t whose contents should be dispatched.
|
|
|
|
|
*
|
|
|
|
|
* @return number of vectors in frame.
|
|
|
|
|
*/
|
2015-12-08 15:45:58 -07:00
|
|
|
static uword
|
2016-04-26 00:17:24 +02:00
|
|
|
lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_frame_t * from_frame, u8 is_v4)
|
2015-12-08 15:45:58 -07:00
|
|
|
{
|
2017-04-05 19:18:20 +02:00
|
|
|
u32 n_left_from, next_index, *from, *to_next, thread_index;
|
2016-06-21 22:32:47 +02:00
|
|
|
u32 n_bytes = 0, n_packets = 0, last_sw_if_index = ~0, drops = 0;
|
2016-08-16 23:04:00 +02:00
|
|
|
lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
|
2015-12-08 15:45:58 -07:00
|
|
|
|
2018-07-11 12:47:43 +02:00
|
|
|
thread_index = vm->thread_index;
|
2015-12-08 15:45:58 -07:00
|
|
|
from = vlib_frame_vector_args (from_frame);
|
|
|
|
|
n_left_from = from_frame->n_vectors;
|
|
|
|
|
|
|
|
|
|
next_index = node->cached_next_index;
|
|
|
|
|
|
|
|
|
|
while (n_left_from > 0)
|
|
|
|
|
{
|
|
|
|
|
u32 n_left_to_next;
|
|
|
|
|
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
while (n_left_from >= 4 && n_left_to_next >= 2)
|
2016-08-16 23:04:00 +02:00
|
|
|
{
|
|
|
|
|
u32 bi0, bi1;
|
|
|
|
|
vlib_buffer_t *b0, *b1;
|
|
|
|
|
ip4_udp_lisp_gpe_header_t *iul4_0, *iul4_1;
|
|
|
|
|
ip6_udp_lisp_gpe_header_t *iul6_0, *iul6_1;
|
|
|
|
|
lisp_gpe_header_t *lh0, *lh1;
|
|
|
|
|
u32 next0, next1, error0, error1;
|
|
|
|
|
uword *si0, *si1;
|
|
|
|
|
tunnel_lookup_t *tl0, *tl1;
|
|
|
|
|
|
|
|
|
|
/* Prefetch next iteration. */
|
|
|
|
|
{
|
|
|
|
|
vlib_buffer_t *p2, *p3;
|
|
|
|
|
|
|
|
|
|
p2 = vlib_get_buffer (vm, from[2]);
|
|
|
|
|
p3 = vlib_get_buffer (vm, from[3]);
|
|
|
|
|
|
|
|
|
|
vlib_prefetch_buffer_header (p2, LOAD);
|
|
|
|
|
vlib_prefetch_buffer_header (p3, LOAD);
|
|
|
|
|
|
|
|
|
|
CLIB_PREFETCH (p2->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
|
|
|
|
|
CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bi0 = from[0];
|
|
|
|
|
bi1 = from[1];
|
|
|
|
|
to_next[0] = bi0;
|
|
|
|
|
to_next[1] = bi1;
|
|
|
|
|
from += 2;
|
|
|
|
|
to_next += 2;
|
|
|
|
|
n_left_to_next -= 2;
|
|
|
|
|
n_left_from -= 2;
|
|
|
|
|
|
|
|
|
|
b0 = vlib_get_buffer (vm, bi0);
|
|
|
|
|
b1 = vlib_get_buffer (vm, bi1);
|
|
|
|
|
|
|
|
|
|
/* udp leaves current_data pointing at the lisp header */
|
|
|
|
|
if (is_v4)
|
|
|
|
|
{
|
|
|
|
|
vlib_buffer_advance (b0,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip4_header_t)));
|
|
|
|
|
vlib_buffer_advance (b1,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip4_header_t)));
|
|
|
|
|
|
|
|
|
|
iul4_0 = vlib_buffer_get_current (b0);
|
|
|
|
|
iul4_1 = vlib_buffer_get_current (b1);
|
|
|
|
|
|
|
|
|
|
/* pop (ip, udp, lisp-gpe) */
|
|
|
|
|
vlib_buffer_advance (b0, sizeof (*iul4_0));
|
|
|
|
|
vlib_buffer_advance (b1, sizeof (*iul4_1));
|
|
|
|
|
|
|
|
|
|
lh0 = &iul4_0->lisp;
|
|
|
|
|
lh1 = &iul4_1->lisp;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vlib_buffer_advance (b0,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip6_header_t)));
|
|
|
|
|
vlib_buffer_advance (b1,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip6_header_t)));
|
|
|
|
|
|
|
|
|
|
iul6_0 = vlib_buffer_get_current (b0);
|
|
|
|
|
iul6_1 = vlib_buffer_get_current (b1);
|
|
|
|
|
|
|
|
|
|
/* pop (ip, udp, lisp-gpe) */
|
|
|
|
|
vlib_buffer_advance (b0, sizeof (*iul6_0));
|
|
|
|
|
vlib_buffer_advance (b1, sizeof (*iul6_1));
|
|
|
|
|
|
|
|
|
|
lh0 = &iul6_0->lisp;
|
|
|
|
|
lh1 = &iul6_1->lisp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* determine next_index from lisp-gpe header */
|
|
|
|
|
next0 = next_protocol_to_next_index (lh0,
|
|
|
|
|
vlib_buffer_get_current (b0));
|
|
|
|
|
next1 = next_protocol_to_next_index (lh1,
|
|
|
|
|
vlib_buffer_get_current (b1));
|
|
|
|
|
|
|
|
|
|
/* determine if tunnel is l2 or l3 */
|
|
|
|
|
tl0 = next_index_to_iface (lgm, next0);
|
|
|
|
|
tl1 = next_index_to_iface (lgm, next1);
|
|
|
|
|
|
|
|
|
|
/* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
|
|
|
|
|
* decide the rx vrf and the input features to be applied */
|
|
|
|
|
si0 = hash_get (tl0->sw_if_index_by_vni,
|
2017-03-29 09:39:23 +02:00
|
|
|
clib_net_to_host_u32 (lh0->iid << 8));
|
2016-08-16 23:04:00 +02:00
|
|
|
si1 = hash_get (tl1->sw_if_index_by_vni,
|
2017-03-29 09:39:23 +02:00
|
|
|
clib_net_to_host_u32 (lh1->iid << 8));
|
2016-08-16 23:04:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Required to make the l2 tag push / pop code work on l2 subifs */
|
|
|
|
|
vnet_update_l2_len (b0);
|
|
|
|
|
vnet_update_l2_len (b1);
|
|
|
|
|
|
|
|
|
|
if (si0)
|
|
|
|
|
{
|
2017-04-05 19:18:20 +02:00
|
|
|
incr_decap_stats (lgm->vnet_main, thread_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_buffer_length_in_chain (vm, b0), si0[0],
|
|
|
|
|
&last_sw_if_index, &n_packets, &n_bytes);
|
|
|
|
|
vnet_buffer (b0)->sw_if_index[VLIB_RX] = si0[0];
|
|
|
|
|
error0 = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
next0 = LISP_GPE_INPUT_NEXT_DROP;
|
|
|
|
|
error0 = LISP_GPE_ERROR_NO_TUNNEL;
|
|
|
|
|
drops++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (si1)
|
|
|
|
|
{
|
2017-04-05 19:18:20 +02:00
|
|
|
incr_decap_stats (lgm->vnet_main, thread_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_buffer_length_in_chain (vm, b1), si1[0],
|
|
|
|
|
&last_sw_if_index, &n_packets, &n_bytes);
|
|
|
|
|
vnet_buffer (b1)->sw_if_index[VLIB_RX] = si1[0];
|
|
|
|
|
error1 = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
next1 = LISP_GPE_INPUT_NEXT_DROP;
|
|
|
|
|
error1 = LISP_GPE_ERROR_NO_TUNNEL;
|
|
|
|
|
drops++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b0->error = error0 ? node->errors[error0] : 0;
|
|
|
|
|
b1->error = error1 ? node->errors[error1] : 0;
|
|
|
|
|
|
|
|
|
|
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
|
|
|
|
{
|
|
|
|
|
lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b0,
|
|
|
|
|
sizeof (*tr));
|
|
|
|
|
tr->next_index = next0;
|
|
|
|
|
tr->error = error0;
|
|
|
|
|
tr->h = lh0[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
|
|
|
|
|
{
|
|
|
|
|
lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b1,
|
|
|
|
|
sizeof (*tr));
|
|
|
|
|
tr->next_index = next1;
|
|
|
|
|
tr->error = error1;
|
|
|
|
|
tr->h = lh1[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
|
|
|
|
|
n_left_to_next, bi0, bi1, next0,
|
|
|
|
|
next1);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-08 15:45:58 -07:00
|
|
|
while (n_left_from > 0 && n_left_to_next > 0)
|
2016-08-16 23:04:00 +02:00
|
|
|
{
|
|
|
|
|
u32 bi0;
|
|
|
|
|
vlib_buffer_t *b0;
|
|
|
|
|
u32 next0;
|
|
|
|
|
ip4_udp_lisp_gpe_header_t *iul4_0;
|
|
|
|
|
ip6_udp_lisp_gpe_header_t *iul6_0;
|
|
|
|
|
lisp_gpe_header_t *lh0;
|
|
|
|
|
u32 error0;
|
|
|
|
|
uword *si0;
|
|
|
|
|
tunnel_lookup_t *tl0;
|
|
|
|
|
|
|
|
|
|
bi0 = from[0];
|
|
|
|
|
to_next[0] = bi0;
|
|
|
|
|
from += 1;
|
|
|
|
|
to_next += 1;
|
|
|
|
|
n_left_from -= 1;
|
|
|
|
|
n_left_to_next -= 1;
|
|
|
|
|
|
|
|
|
|
b0 = vlib_get_buffer (vm, bi0);
|
|
|
|
|
|
|
|
|
|
/* udp leaves current_data pointing at the lisp header
|
|
|
|
|
* TODO: there's no difference in processing between v4 and v6
|
|
|
|
|
* encapsulated packets so the code should be simplified if ip header
|
|
|
|
|
* info is not going to be used for dp smrs/dpsec */
|
|
|
|
|
if (is_v4)
|
|
|
|
|
{
|
|
|
|
|
vlib_buffer_advance (b0,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip4_header_t)));
|
|
|
|
|
|
|
|
|
|
iul4_0 = vlib_buffer_get_current (b0);
|
|
|
|
|
|
|
|
|
|
/* pop (ip, udp, lisp-gpe) */
|
|
|
|
|
vlib_buffer_advance (b0, sizeof (*iul4_0));
|
|
|
|
|
|
|
|
|
|
lh0 = &iul4_0->lisp;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vlib_buffer_advance (b0,
|
|
|
|
|
-(word) (sizeof (udp_header_t) +
|
|
|
|
|
sizeof (ip6_header_t)));
|
|
|
|
|
|
|
|
|
|
iul6_0 = vlib_buffer_get_current (b0);
|
|
|
|
|
|
|
|
|
|
/* pop (ip, udp, lisp-gpe) */
|
|
|
|
|
vlib_buffer_advance (b0, sizeof (*iul6_0));
|
|
|
|
|
|
|
|
|
|
lh0 = &iul6_0->lisp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO if security is to be implemented, something similar to RPF,
|
|
|
|
|
* probably we'd like to check that the peer is allowed to send us
|
|
|
|
|
* packets. For this, we should use the tunnel table OR check that
|
|
|
|
|
* we have a mapping for the source eid and that the outer source of
|
|
|
|
|
* the packet is one of its locators */
|
|
|
|
|
|
|
|
|
|
/* determine next_index from lisp-gpe header */
|
|
|
|
|
next0 = next_protocol_to_next_index (lh0,
|
|
|
|
|
vlib_buffer_get_current (b0));
|
|
|
|
|
|
|
|
|
|
/* determine if tunnel is l2 or l3 */
|
|
|
|
|
tl0 = next_index_to_iface (lgm, next0);
|
|
|
|
|
|
|
|
|
|
/* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
|
2016-10-25 16:47:52 +02:00
|
|
|
* decide the rx vrf and the input features to be applied.
|
|
|
|
|
* NOTE: vni uses only the first 24 bits */
|
2016-08-16 23:04:00 +02:00
|
|
|
si0 = hash_get (tl0->sw_if_index_by_vni,
|
2016-10-25 16:47:52 +02:00
|
|
|
clib_net_to_host_u32 (lh0->iid << 8));
|
2016-08-16 23:04:00 +02:00
|
|
|
|
|
|
|
|
/* Required to make the l2 tag push / pop code work on l2 subifs */
|
|
|
|
|
vnet_update_l2_len (b0);
|
|
|
|
|
|
|
|
|
|
if (si0)
|
|
|
|
|
{
|
2017-04-05 19:18:20 +02:00
|
|
|
incr_decap_stats (lgm->vnet_main, thread_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_buffer_length_in_chain (vm, b0), si0[0],
|
|
|
|
|
&last_sw_if_index, &n_packets, &n_bytes);
|
|
|
|
|
vnet_buffer (b0)->sw_if_index[VLIB_RX] = si0[0];
|
|
|
|
|
error0 = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
next0 = LISP_GPE_INPUT_NEXT_DROP;
|
|
|
|
|
error0 = LISP_GPE_ERROR_NO_TUNNEL;
|
|
|
|
|
drops++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO error handling if security is implemented */
|
|
|
|
|
b0->error = error0 ? node->errors[error0] : 0;
|
|
|
|
|
|
|
|
|
|
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
|
|
|
|
{
|
|
|
|
|
lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b0,
|
|
|
|
|
sizeof (*tr));
|
|
|
|
|
tr->next_index = next0;
|
|
|
|
|
tr->error = error0;
|
|
|
|
|
tr->h = lh0[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
|
|
|
|
n_left_to_next, bi0, next0);
|
|
|
|
|
}
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
|
|
|
|
|
}
|
2016-06-21 22:32:47 +02:00
|
|
|
|
|
|
|
|
/* flush iface stats */
|
2017-04-05 19:18:20 +02:00
|
|
|
incr_decap_stats (lgm->vnet_main, thread_index, 0, ~0, &last_sw_if_index,
|
2016-08-16 23:04:00 +02:00
|
|
|
&n_packets, &n_bytes);
|
2016-04-26 00:17:24 +02:00
|
|
|
vlib_node_increment_counter (vm, lisp_gpe_ip4_input_node.index,
|
2016-08-16 23:04:00 +02:00
|
|
|
LISP_GPE_ERROR_NO_TUNNEL, drops);
|
2015-12-08 15:45:58 -07:00
|
|
|
return from_frame->n_vectors;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-26 00:17:24 +02:00
|
|
|
static uword
|
|
|
|
|
lisp_gpe_ip4_input (vlib_main_t * vm, vlib_node_runtime_t * node,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_frame_t * from_frame)
|
2016-04-26 00:17:24 +02:00
|
|
|
{
|
2016-08-16 23:04:00 +02:00
|
|
|
return lisp_gpe_input_inline (vm, node, from_frame, 1);
|
2016-04-26 00:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uword
|
|
|
|
|
lisp_gpe_ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node,
|
2016-08-16 23:04:00 +02:00
|
|
|
vlib_frame_t * from_frame)
|
2016-04-26 00:17:24 +02:00
|
|
|
{
|
2016-08-16 23:04:00 +02:00
|
|
|
return lisp_gpe_input_inline (vm, node, from_frame, 0);
|
2016-04-26 00:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 23:04:00 +02:00
|
|
|
static char *lisp_gpe_ip4_input_error_strings[] = {
|
2016-06-23 15:01:58 +02:00
|
|
|
#define lisp_gpe_error(n,s) s,
|
2020-09-21 08:17:51 +00:00
|
|
|
#include <lisp/lisp-gpe/lisp_gpe_error.def>
|
2016-06-23 15:01:58 +02:00
|
|
|
#undef lisp_gpe_error
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-26 00:17:24 +02:00
|
|
|
VLIB_REGISTER_NODE (lisp_gpe_ip4_input_node) = {
|
|
|
|
|
.function = lisp_gpe_ip4_input,
|
|
|
|
|
.name = "lisp-gpe-ip4-input",
|
|
|
|
|
/* Takes a vector of packets. */
|
|
|
|
|
.vector_size = sizeof (u32),
|
|
|
|
|
.n_next_nodes = LISP_GPE_INPUT_N_NEXT,
|
|
|
|
|
.next_nodes = {
|
|
|
|
|
#define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n,
|
|
|
|
|
foreach_lisp_gpe_ip_input_next
|
|
|
|
|
#undef _
|
|
|
|
|
},
|
|
|
|
|
|
2016-06-23 15:01:58 +02:00
|
|
|
.n_errors = ARRAY_LEN (lisp_gpe_ip4_input_error_strings),
|
|
|
|
|
.error_strings = lisp_gpe_ip4_input_error_strings,
|
|
|
|
|
|
2016-04-26 00:17:24 +02:00
|
|
|
.format_buffer = format_lisp_gpe_header_with_length,
|
|
|
|
|
.format_trace = format_lisp_gpe_rx_trace,
|
|
|
|
|
// $$$$ .unformat_buffer = unformat_lisp_gpe_header,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VLIB_REGISTER_NODE (lisp_gpe_ip6_input_node) = {
|
|
|
|
|
.function = lisp_gpe_ip6_input,
|
|
|
|
|
.name = "lisp-gpe-ip6-input",
|
2015-12-08 15:45:58 -07:00
|
|
|
/* Takes a vector of packets. */
|
|
|
|
|
.vector_size = sizeof (u32),
|
|
|
|
|
.n_next_nodes = LISP_GPE_INPUT_N_NEXT,
|
|
|
|
|
.next_nodes = {
|
|
|
|
|
#define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n,
|
2016-04-26 00:17:24 +02:00
|
|
|
foreach_lisp_gpe_ip_input_next
|
2015-12-08 15:45:58 -07:00
|
|
|
#undef _
|
|
|
|
|
},
|
|
|
|
|
|
2016-06-23 15:01:58 +02:00
|
|
|
.n_errors = ARRAY_LEN (lisp_gpe_ip4_input_error_strings),
|
|
|
|
|
.error_strings = lisp_gpe_ip4_input_error_strings,
|
|
|
|
|
|
2015-12-08 15:45:58 -07:00
|
|
|
.format_buffer = format_lisp_gpe_header_with_length,
|
|
|
|
|
.format_trace = format_lisp_gpe_rx_trace,
|
|
|
|
|
// $$$$ .unformat_buffer = unformat_lisp_gpe_header,
|
|
|
|
|
};
|
2016-08-16 23:04:00 +02:00
|
|
|
|
2017-02-22 23:38:08 -08:00
|
|
|
/**
|
|
|
|
|
* Adds arc from lisp-gpe-input to nsh-input if nsh-input is available
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gpe_add_arc_from_input_to_nsh ()
|
|
|
|
|
{
|
|
|
|
|
lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
|
|
|
|
|
vlib_main_t *vm = lgm->vlib_main;
|
|
|
|
|
vlib_node_t *nsh_input;
|
|
|
|
|
|
|
|
|
|
/* Arc already exists */
|
|
|
|
|
if (next_proto_to_next_index[LISP_GPE_NEXT_PROTO_NSH]
|
|
|
|
|
!= LISP_GPE_INPUT_NEXT_DROP)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Check if nsh-input is available */
|
|
|
|
|
if ((nsh_input = vlib_get_node_by_name (vm, (u8 *) "nsh-input")))
|
|
|
|
|
{
|
|
|
|
|
u32 slot4, slot6;
|
|
|
|
|
slot4 = vlib_node_add_next_with_slot (vm, lisp_gpe_ip4_input_node.index,
|
|
|
|
|
nsh_input->index,
|
|
|
|
|
LISP_GPE_NEXT_PROTO_NSH);
|
|
|
|
|
slot6 = vlib_node_add_next_with_slot (vm, lisp_gpe_ip6_input_node.index,
|
|
|
|
|
nsh_input->index,
|
|
|
|
|
LISP_GPE_NEXT_PROTO_NSH);
|
|
|
|
|
ASSERT (slot4 == slot6 && slot4 == LISP_GPE_INPUT_NEXT_NSH_INPUT);
|
|
|
|
|
|
|
|
|
|
next_proto_to_next_index[LISP_GPE_NEXT_PROTO_NSH] = slot4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** GPE decap init function. */
|
|
|
|
|
clib_error_t *
|
|
|
|
|
gpe_decap_init (vlib_main_t * vm)
|
|
|
|
|
{
|
|
|
|
|
clib_error_t *error = 0;
|
|
|
|
|
|
|
|
|
|
if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
gpe_add_arc_from_input_to_nsh ();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-12 13:36:02 +02:00
|
|
|
static uword
|
2020-08-06 12:10:09 -04:00
|
|
|
lisp_gpe_nsh_placeholder_input (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|
|
|
|
vlib_frame_t * from_frame)
|
2017-06-12 13:36:02 +02:00
|
|
|
{
|
|
|
|
|
vlib_node_increment_counter (vm, node->node_index, 0, 1);
|
|
|
|
|
return from_frame->n_vectors;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-06 12:10:09 -04:00
|
|
|
static char *lisp_gpe_nsh_placeholder_error_strings[] = {
|
|
|
|
|
"lisp gpe placeholder nsh decap",
|
2017-06-12 13:36:02 +02:00
|
|
|
};
|
|
|
|
|
|
2020-08-06 12:10:09 -04:00
|
|
|
VLIB_REGISTER_NODE (lisp_gpe_nsh_placeholder_input_node) = {
|
|
|
|
|
.function = lisp_gpe_nsh_placeholder_input,
|
|
|
|
|
.name = "lisp-gpe-nsh-placeholder-input",
|
2017-06-12 13:36:02 +02:00
|
|
|
.vector_size = sizeof (u32),
|
|
|
|
|
.type = VLIB_NODE_TYPE_INTERNAL,
|
|
|
|
|
.n_next_nodes = 1,
|
|
|
|
|
|
|
|
|
|
.n_errors = 1,
|
2020-08-06 12:10:09 -04:00
|
|
|
.error_strings = lisp_gpe_nsh_placeholder_error_strings,
|
2017-06-12 13:36:02 +02:00
|
|
|
|
|
|
|
|
.next_nodes = {
|
|
|
|
|
[0] = "error-drop",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static clib_error_t *
|
2020-08-06 12:10:09 -04:00
|
|
|
lisp_add_placeholder_nsh_node_command_fn (vlib_main_t * vm,
|
|
|
|
|
unformat_input_t * input,
|
|
|
|
|
vlib_cli_command_t * cmd)
|
2017-06-12 13:36:02 +02:00
|
|
|
{
|
|
|
|
|
lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
|
|
|
|
|
vlib_node_add_next (lgm->vlib_main, lisp_gpe_ip4_input_node.index,
|
2020-08-06 12:10:09 -04:00
|
|
|
lisp_gpe_nsh_placeholder_input_node.index);
|
2017-06-12 13:36:02 +02:00
|
|
|
next_proto_to_next_index[LISP_GPE_NEXT_PROTO_NSH] =
|
|
|
|
|
LISP_GPE_INPUT_NEXT_NSH_INPUT;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-06 12:10:09 -04:00
|
|
|
VLIB_CLI_COMMAND (lisp_add_placeholder_nsh_node_command, static) = {
|
|
|
|
|
.path = "test one nsh add-placeholder-decap-node",
|
|
|
|
|
.function = lisp_add_placeholder_nsh_node_command_fn,
|
2017-06-12 13:36:02 +02:00
|
|
|
};
|
|
|
|
|
|
2017-02-22 23:38:08 -08:00
|
|
|
VLIB_INIT_FUNCTION (gpe_decap_init);
|
|
|
|
|
|
2016-08-16 23:04:00 +02:00
|
|
|
/*
|
|
|
|
|
* fd.io coding-style-patch-verification: ON
|
|
|
|
|
*
|
|
|
|
|
* Local Variables:
|
|
|
|
|
* eval: (c-set-style "gnu")
|
|
|
|
|
* End:
|
|
|
|
|
*/
|