X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip.c;h=133767bd06c34fa932b5d5c3f13060f9c249a1ff;hb=038e1dfbd;hp=caa553dd6d79197b5de0f75a3517dc0a1c1832aa;hpb=cea194d8f973a2f2b5ef72d212533057174cc70a;p=vpp.git diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c index caa553dd6d7..133767bd06c 100644 --- a/src/vnet/ip/ip.c +++ b/src/vnet/ip/ip.c @@ -31,7 +31,21 @@ ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4) if (is_ip4) return (ip46_address->ip4.as_u8[0] == 127); else - return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1); + return (ip46_address->as_u64[0] == 0 && + clib_net_to_host_u64 (ip46_address->as_u64[1]) == 1); +} + +u8 +ip4_is_local_host (ip4_address_t * ip4_address) +{ + return (ip4_address->as_u8[0] == 127); +} + +u8 +ip6_is_local_host (ip6_address_t * ip6_address) +{ + return (ip6_address->as_u64[0] == 0 && + clib_net_to_host_u64 (ip6_address->as_u64[1]) == 1); } /** @@ -56,13 +70,32 @@ ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4) prefix.fp_proto = FIB_PROTOCOL_IP6; } - clib_memcpy (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t)); - fei = fib_table_lookup (0, &prefix); + clib_memcpy_fast (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t)); + fei = fib_table_lookup (fib_index, &prefix); flags = fib_entry_get_flags (fei); return (flags & FIB_ENTRY_FLAG_LOCAL); } +void +ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4) +{ + if (is_ip4) + dst->ip4.as_u32 = src->ip4.as_u32; + else + clib_memcpy_fast (&dst->ip6, &src->ip6, sizeof (ip6_address_t)); +} + +void +ip_set (ip46_address_t * dst, void *src, u8 is_ip4) +{ + if (is_ip4) + dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32; + else + clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src, + sizeof (ip6_address_t)); +} + u8 ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4) { @@ -97,22 +130,185 @@ ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4) return 0; } -void -ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4) +void * +ip_interface_get_first_ip (u32 sw_if_index, u8 is_ip4) { + ip_lookup_main_t *lm4 = &ip4_main.lookup_main; + ip_lookup_main_t *lm6 = &ip6_main.lookup_main; + ip_interface_address_t *ia = 0; + if (is_ip4) - dst->ip4.as_u32 = src->ip4.as_u32; + { + /* *INDENT-OFF* */ + foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ , + ({ + return ip_interface_address_get_address (lm4, ia); + })); + /* *INDENT-ON* */ + } else - clib_memcpy (&dst->ip6, &src->ip6, sizeof (ip6_address_t)); + { + /* *INDENT-OFF* */ + foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ , + ({ + ip6_address_t *rv; + rv = ip_interface_address_get_address (lm6, ia); + /* Trying to use a link-local ip6 src address is a fool's errand */ + if (!ip6_address_is_link_local_unicast (rv)) + return rv; + })); + /* *INDENT-ON* */ + } + + return 0; } void -ip_set (ip46_address_t * dst, void *src, u8 is_ip4) +ip4_address_normalize (ip4_address_t * ip4, u8 preflen) { - if (is_ip4) - dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32; + ASSERT (preflen <= 32); + if (preflen == 0) + ip4->data_u32 = 0; + else + ip4->data_u32 &= clib_net_to_host_u32 (0xffffffff << (32 - preflen)); +} + +void +ip6_address_normalize (ip6_address_t * ip6, u8 preflen) +{ + ASSERT (preflen <= 128); + if (preflen == 0) + { + ip6->as_u64[0] = 0; + ip6->as_u64[1] = 0; + } + else if (preflen <= 64) + { + ip6->as_u64[0] &= + clib_host_to_net_u64 (0xffffffffffffffffL << (64 - preflen)); + ip6->as_u64[1] = 0; + } + else + ip6->as_u64[1] &= + clib_host_to_net_u64 (0xffffffffffffffffL << (128 - preflen)); +} + +void +ip4_preflen_to_mask (u8 pref_len, ip4_address_t * ip) +{ + if (pref_len == 0) + ip->as_u32 = 0; + else + ip->as_u32 = clib_host_to_net_u32 (~((1 << (32 - pref_len)) - 1)); +} + +u32 +ip4_mask_to_preflen (ip4_address_t * mask) +{ + if (mask->as_u32 == 0) + return 0; + return (32 - log2_first_set (clib_net_to_host_u32 (mask->as_u32))); +} + +void +ip4_prefix_max_address_host_order (ip4_address_t * ip, u8 plen, + ip4_address_t * res) +{ + u32 not_mask; + not_mask = (1 << (32 - plen)) - 1; + res->as_u32 = clib_net_to_host_u32 (ip->as_u32) + not_mask; +} + +void +ip6_preflen_to_mask (u8 pref_len, ip6_address_t * mask) +{ + if (pref_len == 0) + { + mask->as_u64[0] = 0; + mask->as_u64[1] = 0; + } + else if (pref_len <= 64) + { + mask->as_u64[0] = + clib_host_to_net_u64 (0xffffffffffffffffL << (64 - pref_len)); + mask->as_u64[1] = 0; + } else - clib_memcpy (&dst->ip6, (ip6_address_t *) src, sizeof (ip6_address_t)); + { + mask->as_u64[1] = + clib_host_to_net_u64 (0xffffffffffffffffL << (128 - pref_len)); + } +} + +void +ip6_prefix_max_address_host_order (ip6_address_t * ip, u8 plen, + ip6_address_t * res) +{ + u64 not_mask; + if (plen == 0) + { + res->as_u64[0] = 0xffffffffffffffffL; + res->as_u64[1] = 0xffffffffffffffffL; + } + else if (plen <= 64) + { + not_mask = ((u64) 1 << (64 - plen)) - 1; + res->as_u64[0] = clib_net_to_host_u64 (ip->as_u64[0]) + not_mask; + res->as_u64[1] = 0xffffffffffffffffL; + } + else + { + not_mask = ((u64) 1 << (128 - plen)) - 1; + res->as_u64[1] = clib_net_to_host_u64 (ip->as_u64[1]) + not_mask; + } +} + +u32 +ip6_mask_to_preflen (ip6_address_t * mask) +{ + u8 first1, first0; + if (mask->as_u64[0] == 0 && mask->as_u64[1] == 0) + return 0; + first1 = log2_first_set (clib_net_to_host_u64 (mask->as_u64[1])); + first0 = log2_first_set (clib_net_to_host_u64 (mask->as_u64[0])); + + if (first1 != 0) + return 128 - first1; + else + return 64 - first0; +} + +u8 * +format_ip_address_family (u8 * s, va_list * args) +{ + ip_address_family_t af = va_arg (*args, ip_address_family_t); + + switch (af) + { + case AF_IP4: + return (format (s, "ip4")); + case AF_IP6: + return (format (s, "ip6")); + } + + return (format (s, "unknown")); +} + +u8 * +format_ip_dscp (u8 * s, va_list * va) +{ + ip_dscp_t dscp = va_arg (*va, u32); // int promotion of u8 + + switch (dscp) + { +#define _(n,v) \ + case IP_DSCP_##v: \ + return (format (s, "%s", #v)); + foreach_ip_dscp +#undef _ + } + + return (format (s, "unknon")); } /*