aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkshayaNadahalli <anadahal@cisco.com>2017-02-07 23:59:54 +0530
committerNeale Ranns <nranns@cisco.com>2017-02-08 10:21:00 +0000
commit8ea6d7153b053f1b9bf837ef3a927136f44b41fd (patch)
tree7622a7dc6266edba33c9d36910114d06e6440cc3
parente4ad8cce6cf6e5d50b0ec101a4f5ab5d510ad374 (diff)
Fix source address reachability check for ip6 local packets
Currently ip6 local check fails with error - source lookup miss if route to source of packet is over a dpo object such as load balance - recurssive route, tunnel adj - GRE, SR etc. So unless packet source is of a directly connected neibhor or has route with both interface and nexthop specified, it will be dropped. Fix is to check urpf list and if at least one link exists in the list, then allow packets to be processed, else drop. Change-Id: Id426311bb63bab506754a79409c602fdb6d0f190 Signed-off-by: AkshayaNadahalli <anadahal@cisco.com>
-rw-r--r--src/vnet/fib/ip6_fib.h24
-rw-r--r--src/vnet/ip/ip6_forward.c9
2 files changed, 26 insertions, 7 deletions
diff --git a/src/vnet/fib/ip6_fib.h b/src/vnet/fib/ip6_fib.h
index 78da3746f17..e460e2ffd09 100644
--- a/src/vnet/fib/ip6_fib.h
+++ b/src/vnet/fib/ip6_fib.h
@@ -20,6 +20,7 @@
#include <vnet/ip/format.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_urpf_list.h>
#include <vnet/ip/lookup.h>
#include <vnet/dpo/load_balance.h>
@@ -67,7 +68,28 @@ extern void ip6_fib_table_walk(u32 fib_index,
void *ctx);
/**
- * @biref return the DPO that the LB stacks on.
+ * @brief returns number of links on which src is reachable.
+ */
+always_inline int
+ip6_urpf_loose_check (ip6_main_t * im,
+ vlib_buffer_t * b,
+ ip6_header_t * i)
+{
+ const load_balance_t *lb0;
+ index_t lbi;
+
+ lbi = ip6_fib_table_fwding_lookup_with_if_index(
+ im,
+ vnet_buffer (b)->sw_if_index[VLIB_RX],
+ &i->src_address);
+
+ lb0 = load_balance_get(lbi);
+
+ return (fib_urpf_check_size (lb0->lb_urpf));
+}
+
+/**
+ * @brief return the DPO that the LB stacks on.
*/
always_inline u32
ip6_src_lookup_for_packet (ip6_main_t * im,
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index 50951c27495..06c20bbaa12 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -1463,16 +1463,14 @@ ip6_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
type0 != IP_BUILTIN_PROTOCOL_ICMP &&
!ip6_address_is_link_local_unicast (&ip0->src_address))
{
- u32 src_adj_index0 = ip6_src_lookup_for_packet (im, p0, ip0);
- error0 = (ADJ_INDEX_INVALID == src_adj_index0
+ error0 = (!ip6_urpf_loose_check (im, p0, ip0)
? IP6_ERROR_SRC_LOOKUP_MISS : error0);
}
if (error1 == IP6_ERROR_UNKNOWN_PROTOCOL &&
type1 != IP_BUILTIN_PROTOCOL_ICMP &&
!ip6_address_is_link_local_unicast (&ip1->src_address))
{
- u32 src_adj_index1 = ip6_src_lookup_for_packet (im, p1, ip1);
- error1 = (ADJ_INDEX_INVALID == src_adj_index1
+ error1 = (!ip6_urpf_loose_check (im, p1, ip1)
? IP6_ERROR_SRC_LOOKUP_MISS : error1);
}
@@ -1570,8 +1568,7 @@ ip6_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
type0 != IP_BUILTIN_PROTOCOL_ICMP &&
!ip6_address_is_link_local_unicast (&ip0->src_address))
{
- u32 src_adj_index0 = ip6_src_lookup_for_packet (im, p0, ip0);
- error0 = (ADJ_INDEX_INVALID == src_adj_index0
+ error0 = (!ip6_urpf_loose_check (im, p0, ip0)
? IP6_ERROR_SRC_LOOKUP_MISS : error0);
}