FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
ip.c
Go to the documentation of this file.
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 
20 
21 u8
22 ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
23 {
24  if (is_ip4)
25  return (ip46_address->ip4.as_u32 == 0);
26  else
27  return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
28 }
29 
30 u8
31 ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
32 {
33  if (is_ip4)
34  return (ip46_address->ip4.as_u8[0] == 127);
35  else
36  return (ip46_address->as_u64[0] == 0 &&
37  clib_net_to_host_u64 (ip46_address->as_u64[1]) == 1);
38 }
39 
40 u8
42 {
43  return (ip4_address->as_u8[0] == 127);
44 }
45 
46 u8
47 ip6_is_local_host (ip6_address_t * ip6_address)
48 {
49  return (ip6_address->as_u64[0] == 0 &&
50  clib_net_to_host_u64 (ip6_address->as_u64[1]) == 1);
51 }
52 
53 /**
54  * Checks that an ip is local to the requested fib
55  */
56 u8
57 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
58 {
59  fib_node_index_t fei;
62 
63  /* Check if requester is local */
64  if (is_ip4)
65  {
66  prefix.fp_len = 32;
67  prefix.fp_proto = FIB_PROTOCOL_IP4;
68  }
69  else
70  {
71  prefix.fp_len = 128;
72  prefix.fp_proto = FIB_PROTOCOL_IP6;
73  }
74 
75  clib_memcpy_fast (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
76  fei = fib_table_lookup (fib_index, &prefix);
77  flags = fib_entry_get_flags (fei);
78 
79  return (flags & FIB_ENTRY_FLAG_LOCAL);
80 }
81 
82 void
83 ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
84 {
85  if (is_ip4)
86  {
88  dst->ip4.as_u32 = src->ip4.as_u32;
89  }
90  else
91  clib_memcpy_fast (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
92 }
93 
94 void
95 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
96 {
97  if (is_ip4)
98  {
100  dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
101  }
102  else
103  clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
104  sizeof (ip6_address_t));
105 }
106 
107 /* *INDENT-OFF* */
109  [IP_FEATURE_INPUT] = {
110  [AF_IP4] = {
111  [SAFI_UNICAST] = "ip4-unicast",
112  [SAFI_MULTICAST] = "ip4-multicast",
113  },
114  [AF_IP6] = {
115  [SAFI_UNICAST] = "ip6-unicast",
116  [SAFI_MULTICAST] = "ip6-multicast",
117  },
118  },
119  [IP_FEATURE_OUTPUT] = {
120  [AF_IP4] = {
121  [SAFI_UNICAST] = "ip4-output",
122  [SAFI_MULTICAST] = "ip4-output",
123  },
124  [AF_IP6] = {
125  [SAFI_UNICAST] = "ip6-output",
126  [SAFI_MULTICAST] = "ip6-output",
127  },
128  },
129  [IP_FEATURE_LOCAL] = {
130  [AF_IP4] = {
131  [SAFI_UNICAST] = "ip4-local",
132  [SAFI_MULTICAST] = "ip4-local",
133  },
134  [AF_IP6] = {
135  [SAFI_UNICAST] = "ip6-local",
136  [SAFI_MULTICAST] = "ip6-local",
137  },
138  },
139  [IP_FEATURE_PUNT] = {
140  [AF_IP4] = {
141  [SAFI_UNICAST] = "ip4-punt",
142  [SAFI_MULTICAST] = "ip4-punt",
143  },
144  [AF_IP6] = {
145  [SAFI_UNICAST] = "ip6-punt",
146  [SAFI_MULTICAST] = "ip6-punt",
147  },
148  },
149  [IP_FEATURE_DROP] = {
150  [AF_IP4] = {
151  [SAFI_UNICAST] = "ip4-drop",
152  [SAFI_MULTICAST] = "ip4-drop",
153  },
154  [AF_IP6] = {
155  [SAFI_UNICAST] = "ip6-drop",
156  [SAFI_MULTICAST] = "ip6-drop",
157  },
158  },
159 };
160 /* *INDENT-ON* */
161 
162 void
166  const char *feature_name,
167  u32 sw_if_index, int enable,
168  void *feature_config, u32 n_feature_config_bytes)
169 {
170  if (IP_FEATURE_INPUT == loc)
171  {
172  if (N_SAFI == safi)
175  feature_name, sw_if_index,
176  enable, feature_config,
177  n_feature_config_bytes);
178  else
180  feature_name, sw_if_index,
181  enable, feature_config,
182  n_feature_config_bytes);
183  }
184  else
186  feature_name, sw_if_index,
187  enable, feature_config,
188  n_feature_config_bytes);
189 }
190 
191 int
193 {
194  fib_protocol_t fproto;
195  u32 fib_index;
196 
197  fproto = ip_address_family_to_fib_proto (af);
198  fib_index = fib_table_find (fproto, table_id);
199 
200  if (~0 == fib_index)
201  return VNET_API_ERROR_NO_SUCH_FIB;
202 
203  fib_table_set_flow_hash_config (fib_index, fproto, flow_hash_config);
204 
205  return 0;
206 }
207 
208 void
210 {
211  ip_flow_hash_router_id = router_id;
212 }
213 
214 u8 *
215 format_ip_address_family (u8 * s, va_list * args)
216 {
217  ip_address_family_t af = va_arg (*args, int); // int promo ip_address_family_t);
218 
219  switch (af)
220  {
221  case AF_IP4:
222  return (format (s, "ip4"));
223  case AF_IP6:
224  return (format (s, "ip6"));
225  }
226 
227  return (format (s, "unknown"));
228 }
229 
230 uword
232 {
233  ip_address_family_t *af = va_arg (*args, ip_address_family_t *);
234 
235  if (unformat (input, "ip4") || unformat (input, "ipv4") ||
236  unformat (input, "IP4") || unformat (input, "IPv4"))
237  {
238  *af = AF_IP4;
239  return (1);
240  }
241  else if (unformat (input, "ip6") || unformat (input, "ipv6") ||
242  unformat (input, "IP6") || unformat (input, "IPv6"))
243  {
244  *af = AF_IP6;
245  return (1);
246  }
247  return (0);
248 }
249 
250 u8 *
251 format_ip_sub_address_family (u8 * s, va_list * args)
252 {
253  ip_sub_address_family_t safi = va_arg (*args, int); // int promo ip_sub_address_family_t);
254 
255  switch (safi)
256  {
257  case SAFI_UNICAST:
258  return (format (s, "unicast"));
259  case SAFI_MULTICAST:
260  return (format (s, "multicast"));
261  }
262 
263  return (format (s, "unknown"));
264 }
265 
266 uword
268 {
269  ip_sub_address_family_t *safi = va_arg (*args, ip_sub_address_family_t *);
270 
271  if (unformat (input, "unicast") || unformat (input, "uni"))
272  {
273  *safi = SAFI_UNICAST;
274  return (1);
275  }
276  else if (unformat (input, "multicast") || unformat (input, "multi"))
277  {
278  *safi = SAFI_MULTICAST;
279  return (1);
280  }
281  return (0);
282 }
283 
284 u8 *
285 format_ip_dscp (u8 * s, va_list * va)
286 {
287  ip_dscp_t dscp = va_arg (*va, u32); // int promotion of u8
288 
289  switch (dscp)
290  {
291 #define _(n,v) \
292  case IP_DSCP_##v: \
293  return (format (s, "%s", #v));
295 #undef _
296  }
297 
298  return (format (s, "unknown"));
299 }
300 
301 uword
302 unformat_ip_dscp (unformat_input_t * input, va_list * args)
303 {
304  ip_dscp_t *dscp = va_arg (*args, ip_dscp_t *);
305 
306  if (0)
307  ;
308 #define _(n,v) \
309  else if (unformat (input, #v)) \
310  *dscp = IP_DSCP_##v;
312 #undef _
313  else
314  return 0;
315 
316  return 1;
317 }
318 
319 u8 *
320 format_ip_ecn (u8 * s, va_list * va)
321 {
322  ip_ecn_t ecn = va_arg (*va, u32); // int promotion of u8
323 
324  switch (ecn)
325  {
326 #define _(n,v) \
327  case IP_ECN_##v: \
328  return (format (s, "%s", #v));
330 #undef _
331  }
332 
333  return (format (s, "unknown"));
334 }
335 
336 /*
337  * fd.io coding-style-patch-verification: ON
338  *
339  * Local Variables:
340  * eval: (c-set-style "gnu")
341  * End:
342  */
ip_ecn_t
enum ip_ecn_t_ ip_ecn_t
ip_feature_enable_disable
void ip_feature_enable_disable(ip_address_family_t af, ip_sub_address_family_t safi, ip_feature_location_t loc, const char *feature_name, u32 sw_if_index, int enable, void *feature_config, u32 n_feature_config_bytes)
Definition: ip.c:163
ip46_address_mask_ip4
static void ip46_address_mask_ip4(ip46_address_t *ip46)
Definition: ip46_address.h:61
ip_set
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:95
ip_dscp_t
enum ip_dscp_t_ ip_dscp_t
unformat_ip_sub_address_family
uword unformat_ip_sub_address_family(unformat_input_t *input, va_list *args)
Definition: ip.c:267
fib_table_set_flow_hash_config
void fib_table_set_flow_hash_config(u32 fib_index, fib_protocol_t proto, flow_hash_config_t hash_config)
Set the flow hash configured used by the table.
Definition: fib_table.c:1064
fib_table.h
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
SAFI_UNICAST
@ SAFI_UNICAST
Definition: ip_types.h:43
unformat_ip_dscp
uword unformat_ip_dscp(unformat_input_t *input, va_list *args)
Definition: ip.c:302
unformat_ip_address_family
uword unformat_ip_address_family(unformat_input_t *input, va_list *args)
Definition: ip.c:231
fib_table_lookup
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
Definition: fib_table.c:68
ip_flow_hash_router_id
u32 ip_flow_hash_router_id
Definition: ip.c:19
unformat_input_t
struct _unformat_input_t unformat_input_t
format_ip_ecn
u8 * format_ip_ecn(u8 *s, va_list *va)
Definition: ip.c:320
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
N_IP_FEATURE_LOCATIONS
#define N_IP_FEATURE_LOCATIONS
Definition: ip_types.h:76
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
fib_entry_flag_t
enum fib_entry_flag_t_ fib_entry_flag_t
format_ip_address_family
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:215
foreach_ip_ecn
@ foreach_ip_ecn
Definition: ip_packet.h:144
ip_flow_hash_set
int ip_flow_hash_set(ip_address_family_t af, u32 table_id, u32 flow_hash_config)
Definition: ip.c:192
fib_node_index_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
ip_is_local_host
u8 ip_is_local_host(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:31
uword
u64 uword
Definition: types.h:112
foreach_ip_dscp
@ foreach_ip_dscp
Definition: ip_packet.h:118
src
vl_api_address_t src
Definition: gre.api:54
fib_protocol_t
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
ip4_address_t
Definition: ip4_packet.h:50
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
FIB_ENTRY_FLAG_LOCAL
@ FIB_ENTRY_FLAG_LOCAL
Definition: fib_entry.h:117
N_AF
#define N_AF
Definition: ip_types.h:27
ip_address_family_to_fib_proto
fib_protocol_t ip_address_family_to_fib_proto(ip_address_family_t af)
Definition: ip_types.c:223
format
description fragment has unexpected format
Definition: map.api:433
ip.h
u32
unsigned int u32
Definition: types.h:88
ip_is_local
u8 ip_is_local(u32 fib_index, ip46_address_t *ip46_address, u8 is_ip4)
Checks that an ip is local to the requested fib.
Definition: ip.c:57
ip_copy
void ip_copy(ip46_address_t *dst, ip46_address_t *src, u8 is_ip4)
Definition: ip.c:83
table_id
u32 table_id
Definition: wireguard.api:102
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
ip4_address
manual_print typedef u8 ip4_address[4]
Definition: ip_types.api:18
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
ip6_is_local_host
u8 ip6_is_local_host(ip6_address_t *ip6_address)
Definition: ip.c:47
ip6_address
manual_print typedef u8 ip6_address[16]
Definition: ip_types.api:19
fib_entry_get_flags
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:291
AF_IP6
@ AF_IP6
Definition: ip_types.h:24
ip_flow_hash_router_id_set
void ip_flow_hash_router_id_set(u32 router_id)
Definition: ip.c:209
vnet_feature_enable_disable
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: pnat_test_stubs.h:50
FOR_EACH_IP_ADDRESS_SUB_FAMILY
#define FOR_EACH_IP_ADDRESS_SUB_FAMILY(_safi)
Definition: ip_types.h:53
u8
unsigned char u8
Definition: types.h:56
N_SAFI
#define N_SAFI
Definition: ip_types.h:47
ip_sub_address_family_t
enum ip_sub_address_family_t_ ip_sub_address_family_t
ip4_is_local_host
u8 ip4_is_local_host(ip4_address_t *ip4_address)
Definition: ip.c:41
ip_feature_location_t
enum ip_feature_location_t_ ip_feature_location_t
SAFI_MULTICAST
@ SAFI_MULTICAST
Definition: ip_types.h:44
format_ip_sub_address_family
u8 * format_ip_sub_address_family(u8 *s, va_list *args)
Definition: ip.c:251
fib_table_find
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1106
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
format_ip_dscp
u8 * format_ip_dscp(u8 *s, va_list *va)
Definition: ip.c:285
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
dscp
vl_api_ip_dscp_t dscp
Definition: dhcp.api:163
ip_arc_names
static const char * ip_arc_names[N_IP_FEATURE_LOCATIONS][N_AF][N_SAFI]
Definition: ip.c:108
prefix
vl_api_prefix_t prefix
Definition: ip.api:146
ip_address_family_t
enum ip_address_family_t_ ip_address_family_t
ip_is_zero
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:22
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105