FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
lisp_gpe_sub_interface.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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  * @file
17  * @brief LISP sub-interfaces.
18  *
19  */
22 #include <vnet/fib/fib_table.h>
23 #include <vnet/interface.h>
24 
25 /**
26  * @brief Pool of all l3-sub-interfaces
27  */
29 
30 /**
31  * A DB of all LISP L3 sub-interfaces. The key is:{VNI,l-RLOC}
32  */
34 
35 /**
36  * A DB of all VNET L3 sub-interfaces. The key is:{VNI,l-RLOC}
37  * Used in the data-plane for interface lookup on decap.
38  */
40 
41 /**
42  * The next available sub-interface ID. FIXME
43  */
45 
46 
47 static index_t
48 lisp_gpe_sub_interface_db_find (const ip_address_t * lrloc, u32 vni)
49 {
50  uword *p;
51 
53 
54  memset (&key, 0, sizeof (key));
55  ip_address_copy (&key.local_rloc, lrloc);
56  key.vni = clib_host_to_net_u32 (vni);
58 
59  if (NULL == p)
60  return (INDEX_INVALID);
61  else
62  return (p[0]);
63 }
64 
65 static void
67 {
69  l3s->key, l3s - lisp_gpe_sub_interface_pool);
71  l3s->key, l3s->sw_if_index);
72 }
73 
74 static void
76 {
79 }
80 
83 {
84  return (pool_elt_at_index (lisp_gpe_sub_interface_pool, l3si));
85 }
86 
87 static void
88 lisp_gpe_sub_interface_set_table (u32 sw_if_index, u32 table_id)
89 {
90  fib_node_index_t fib_index;
91 
93  ASSERT (FIB_NODE_INDEX_INVALID != fib_index);
94 
96  ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
97 
99  ASSERT (FIB_NODE_INDEX_INVALID != fib_index);
100 
102  ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
103 }
104 
105 static void
107 {
108  ip4_main.fib_index_by_sw_if_index[sw_if_index] = 0;
109  ip4_sw_interface_enable_disable (sw_if_index, 0);
110 
111  ip6_main.fib_index_by_sw_if_index[sw_if_index] = 0;
112  ip6_sw_interface_enable_disable (sw_if_index, 0);
113 }
114 
115 index_t
117  u32 overlay_table_id, u32 vni)
118 {
120  index_t l3si;
121 
122  l3si = lisp_gpe_sub_interface_db_find (lrloc, clib_host_to_net_u32 (vni));
123 
124  if (INDEX_INVALID == l3si)
125  {
126  u32 main_sw_if_index, sub_sw_if_index;
127 
128  /*
129  * find the main interface from the VNI
130  */
131  main_sw_if_index =
132  lisp_gpe_tenant_l3_iface_add_or_lock (vni, overlay_table_id);
133 
134  vnet_sw_interface_t sub_itf_template = {
136  .flood_class = VNET_FLOOD_CLASS_NORMAL,
137  .sup_sw_if_index = main_sw_if_index,
138  .sub.id = lisp_gpe_sub_interface_id++,
139  };
140 
142  &sub_itf_template,
143  &sub_sw_if_index))
144  return (INDEX_INVALID);
145 
146  pool_get (lisp_gpe_sub_interface_pool, l3s);
147  memset (l3s, 0, sizeof (*l3s));
148  l3s->key = clib_mem_alloc (sizeof (*l3s->key));
149  memset (l3s->key, 0, sizeof (*l3s->key));
150 
151  l3s->key->local_rloc = *lrloc;
152  l3s->key->vni = clib_host_to_net_u32 (vni);
153  l3s->main_sw_if_index = main_sw_if_index;
154  l3s->sw_if_index = sub_sw_if_index;
155  l3s->eid_table_id = overlay_table_id;
156 
157  l3si = (l3s - lisp_gpe_sub_interface_pool);
158 
159  // FIXME. enable When we get an adj
162 
164  l3s->sw_if_index,
166 
168  }
169  else
170  {
171  l3s = lisp_gpe_sub_interface_get_i (l3si);
172  l3s->eid_table_id = overlay_table_id;
173  }
174 
176  l3s->locks++;
177 
178  return (l3si);
179 }
180 
181 void
183 {
185 
186  l3s = lisp_gpe_sub_interface_get_i (l3si);
187 
188  l3s->locks--;
189 
190  if (0 == l3s->locks)
191  {
193  l3s->eid_table_id);
194 
195  lisp_gpe_tenant_l3_iface_unlock (clib_net_to_host_u32 (l3s->key->vni));
198 
200 
201  clib_mem_free (l3s->key);
202  pool_put (lisp_gpe_sub_interface_pool, l3s);
203  }
204 }
205 
208 {
209  return (lisp_gpe_sub_interface_get_i (l3si));
210 }
211 
212 u8 *
214 {
216  vnet_main_t *vnm = vnet_get_main ();
217 
218  s = format (s, "%=16U",
220  vnm, vnet_get_sw_interface (vnm, l3s->sw_if_index));
221  s = format (s, "%=10d", clib_net_to_host_u32 (l3s->key->vni));
222  s = format (s, "%=12d", l3s->sw_if_index);
223  s = format (s, "%U", format_ip_address, &l3s->key->local_rloc);
224 
225  return (s);
226 }
227 
228 /** CLI command to show LISP-GPE interfaces. */
229 static clib_error_t *
231  unformat_input_t * input,
232  vlib_cli_command_t * cmd)
233 {
235 
236  vlib_cli_output (vm, "%=16s%=10s%=12s%s", "Name", "VNI", "SW IF Index",
237  "local RLOC");
238 
239  /* *INDENT-OFF* */
240  pool_foreach (l3s, lisp_gpe_sub_interface_pool,
241  ({
243  }));
244  /* *INDENT-ON* */
245 
246  return 0;
247 }
248 
249 /* *INDENT-OFF* */
250 VLIB_CLI_COMMAND (lisp_gpe_sub_interface_command) = {
251  .path = "show gpe sub-interface",
252  .short_help = "show gpe sub-interface",
253  .function = lisp_gpe_sub_interface_show,
254 };
255 /* *INDENT-ON* */
256 
257 static clib_error_t *
259 {
261  hash_create_mem (0,
262  sizeof (lisp_gpe_sub_interface_key_t), sizeof (uword));
264  hash_create_mem (0,
265  sizeof (lisp_gpe_sub_interface_key_t), sizeof (uword));
266 
267  return (NULL);
268 }
269 
271 
272 /*
273  * fd.io coding-style-patch-verification: ON
274  *
275  * Local Variables:
276  * eval: (c-set-style "gnu")
277  * End:
278  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
void lisp_gpe_tenant_l3_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define NULL
Definition: clib.h:55
u32 locks
A reference counting lock on the number of users of this interface.
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
static clib_error_t * lisp_gpe_sub_interface_module_init(vlib_main_t *vm)
#define hash_set_mem(h, key, value)
Definition: hash.h:274
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:120
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
static void lisp_gpe_sub_interface_db_remove(const lisp_gpe_sub_interface_t *l3s)
void ip_address_copy(ip_address_t *dst, const ip_address_t *src)
Definition: lisp_types.c:821
lisp_gpe_sub_interface_t * lisp_gpe_sub_interface_get_i(index_t l3si)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static void lisp_gpe_sub_interface_unset_table(u32 sw_if_index, u32 table_id)
ip_address_t local_rloc
The local-RLOC.
u32 main_sw_if_index
The SW IF index assigned to the main interface of which this is a sub.
static void lisp_gpe_sub_interface_db_insert(const lisp_gpe_sub_interface_t *l3s)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static lisp_gpe_sub_interface_t * lisp_gpe_sub_interface_pool
Pool of all l3-sub-interfaces.
const lisp_gpe_sub_interface_t * lisp_gpe_sub_interface_get(index_t l3si)
u32 sw_if_index
The SW if index assigned to this sub-interface.
LISP sub-interfaces.
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:637
format_function_t format_vnet_sw_interface_name
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
static void lisp_gpe_sub_interface_set_table(u32 sw_if_index, u32 table_id)
#define hash_unset_mem(h, key)
Definition: hash.h:280
void ip4_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip4_forward.c:826
A Key for lookup in the L£ sub-interface DB.
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
lisp_gpe_sub_interface_key_t * key
The interface&#39;s key inthe DB; rloc & vni; The key is allocated from the heap so it can be used in the...
uword * lisp_gpe_sub_interfaces_sw_if_index
A DB of all VNET L3 sub-interfaces.
u32 eid_table_id
The Table-ID in the overlay that this interface is bound to.
vlib_main_t * vm
Definition: buffer.c:276
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:709
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
void lisp_gpe_sub_interface_unlock(index_t l3si)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:536
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_ip_address(u8 *s, va_list *args)
Definition: lisp_types.c:127
ip6_main_t ip6_main
Definition: ip6_forward.c:2846
static uword * lisp_gpe_sub_interfaces
A DB of all LISP L3 sub-interfaces.
static clib_error_t * lisp_gpe_sub_interface_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to show LISP-GPE interfaces.
static void clib_mem_free(void *p)
Definition: mem.h:176
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:954
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
u64 uword
Definition: types.h:112
index_t lisp_gpe_sub_interface_find_or_create_and_lock(const ip_address_t *lrloc, u32 overlay_table_id, u32 vni)
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
unsigned char u8
Definition: types.h:56
A LISP L3 sub-interface.
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u8 * format_lisp_gpe_sub_interface(u8 *s, va_list ap)
#define hash_get_mem(h, key)
Definition: hash.h:268
vnet_sw_interface_type_t type
Definition: interface.h:531
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1117
static index_t lisp_gpe_sub_interface_db_find(const ip_address_t *lrloc, u32 vni)
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:538
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:590
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
u32 * fib_index_by_sw_if_index
Definition: ip6.h:163
u32 lisp_gpe_tenant_l3_iface_add_or_lock(u32 vni, u32 table_id)
Add/create and lock a new or find and lock the existing L3 interface for the tenant.
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip6_forward.c:395
static u32 lisp_gpe_sub_interface_id
The next available sub-interface ID.