Fix source address reachability check for ip6 local packets 66/5066/6
authorAkshayaNadahalli <anadahal@cisco.com>
Tue, 7 Feb 2017 18:29:54 +0000 (23:59 +0530)
committerNeale Ranns <nranns@cisco.com>
Wed, 8 Feb 2017 10:21:00 +0000 (10:21 +0000)
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>
src/vnet/fib/ip6_fib.h
src/vnet/ip/ip6_forward.c

index 78da374..e460e2f 100644 (file)
@@ -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,
index 50951c2..06c20bb 100644 (file)
@@ -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);
            }