diff options
author | AkshayaNadahalli <anadahal@cisco.com> | 2017-02-07 23:59:54 +0530 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2017-02-08 10:21:00 +0000 |
commit | 8ea6d7153b053f1b9bf837ef3a927136f44b41fd (patch) | |
tree | 7622a7dc6266edba33c9d36910114d06e6440cc3 /src/vnet | |
parent | e4ad8cce6cf6e5d50b0ec101a4f5ab5d510ad374 (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>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/fib/ip6_fib.h | 24 | ||||
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 9 |
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); } |