Remove duplicate ip6 get interface address code
[vpp.git] / src / vnet / ip / ip6_forward.c
index 50951c2..5dd22b9 100644 (file)
@@ -42,6 +42,7 @@
 #include <vnet/ethernet/ethernet.h>    /* for ethernet_header_t */
 #include <vnet/srp/srp.h>      /* for srp_hw_interface_class */
 #include <vppinfra/cache.h>
+#include <vnet/fib/fib_urpf_list.h>    /* for FIB uRPF check */
 #include <vnet/fib/ip6_fib.h>
 #include <vnet/mfib/ip6_mfib.h>
 #include <vnet/dpo/load_balance.h>
@@ -49,6 +50,9 @@
 
 #include <vppinfra/bihash_template.c>
 
+/* Flag used by IOAM code. Classifier sets it pop-hop-by-hop checks it */
+#define OI_DECAP   0x80000000
+
 /**
  * @file
  * @brief IPv6 Forwarding.
@@ -424,9 +428,7 @@ ip6_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
 
 /* get first interface address */
 ip6_address_t *
-ip6_interface_first_address (ip6_main_t * im,
-                            u32 sw_if_index,
-                            ip_interface_address_t ** result_ia)
+ip6_interface_first_address (ip6_main_t * im, u32 sw_if_index)
 {
   ip_lookup_main_t *lm = &im->lookup_main;
   ip_interface_address_t *ia = 0;
@@ -441,8 +443,6 @@ ip6_interface_first_address (ip6_main_t * im,
     break;
   }));
   /* *INDENT-ON* */
-  if (result_ia)
-    *result_ia = result ? ia : 0;
   return result;
 }
 
@@ -1313,6 +1313,25 @@ ip6_locate_header (vlib_buffer_t * p0,
   return (next_proto);
 }
 
+/**
+ * @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));
+}
+
 static uword
 ip6_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
@@ -1463,16 +1482,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 +1587,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);
            }
 
@@ -3298,7 +3314,7 @@ vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
   vec_validate (lm->classify_table_index_by_sw_if_index, sw_if_index);
   lm->classify_table_index_by_sw_if_index[sw_if_index] = table_index;
 
-  if_addr = ip6_interface_first_address (ipm, sw_if_index, NULL);
+  if_addr = ip6_interface_first_address (ipm, sw_if_index);
 
   if (NULL != if_addr)
     {