session: add support for application namespacing
[vpp.git] / src / vnet / ip / ip.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/ip/ip.h>
17 #include <vnet/fib/fib_table.h>
18
19 u8
20 ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
21 {
22   if (is_ip4)
23     return (ip46_address->ip4.as_u32 == 0);
24   else
25     return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
26 }
27
28 u8
29 ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
30 {
31   if (is_ip4)
32     return (ip46_address->ip4.as_u8[0] == 127);
33   else
34     return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1);
35 }
36
37 /**
38  * Checks that an ip is local to the requested fib
39  */
40 u8
41 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
42 {
43   fib_node_index_t fei;
44   fib_entry_flag_t flags;
45   fib_prefix_t prefix;
46
47   /* Check if requester is local */
48   if (is_ip4)
49     {
50       prefix.fp_len = 32;
51       prefix.fp_proto = FIB_PROTOCOL_IP4;
52     }
53   else
54     {
55       prefix.fp_len = 128;
56       prefix.fp_proto = FIB_PROTOCOL_IP6;
57     }
58
59   clib_memcpy (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
60   fei = fib_table_lookup (0, &prefix);
61   flags = fib_entry_get_flags (fei);
62
63   return (flags & FIB_ENTRY_FLAG_LOCAL);
64 }
65
66 u8
67 ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4)
68 {
69   ip_interface_address_t *ia = 0;
70
71   if (is_ip4)
72     {
73       ip_lookup_main_t *lm4 = &ip4_main.lookup_main;
74       ip4_address_t *ip4;
75       /* *INDENT-OFF* */
76       foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ ,
77       ({
78         ip4 = ip_interface_address_get_address (lm4, ia);
79         if (ip4_address_compare (ip4, &ip->ip4) == 0)
80           return 1;
81       }));
82       /* *INDENT-ON* */
83     }
84   else
85     {
86       ip_lookup_main_t *lm6 = &ip6_main.lookup_main;
87       ip6_address_t *ip6;
88       /* *INDENT-OFF* */
89       foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ ,
90       ({
91         ip6 = ip_interface_address_get_address (lm6, ia);
92         if (ip6_address_compare (ip6, &ip->ip6) == 0)
93           return 1;
94       }));
95       /* *INDENT-ON* */
96     }
97   return 0;
98 }
99
100 void
101 ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
102 {
103   if (is_ip4)
104     dst->ip4.as_u32 = src->ip4.as_u32;
105   else
106     clib_memcpy (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
107 }
108
109 void
110 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
111 {
112   if (is_ip4)
113     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
114   else
115     clib_memcpy (&dst->ip6, (ip6_address_t *) src, sizeof (ip6_address_t));
116 }
117
118 /*
119  * fd.io coding-style-patch-verification: ON
120  *
121  * Local Variables:
122  * eval: (c-set-style "gnu")
123  * End:
124  */