HONEYCOMB-10: jVpp - the new java API. C code and jar file generation
[vpp.git] / vnet / vnet / lisp-cp / control.c
index a1d21be..1822c45 100644 (file)
@@ -122,24 +122,26 @@ vnet_lisp_add_del_local_mapping (vnet_lisp_add_del_mapping_args_t * a,
                                  u32 * map_index_result)
 {
   uword * table_id, * refc;
-  u32 rv;
+  u32 rv, vni;
   vnet_lisp_gpe_add_del_iface_args_t _ai, *ai = &_ai;
   lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
 
+  vni = gid_address_vni(&a->deid);
+
   /* store/remove mapping from map-cache */
   rv = vnet_lisp_add_del_mapping (a, map_index_result);
   if (rv)
     return rv;
 
-  table_id = hash_get(lcm->table_id_by_vni, /* default for now */ 0);
+  table_id = hash_get(lcm->table_id_by_vni, vni);
 
   if (!table_id)
     {
-      clib_warning ("vni %d not associated to a vrf!", 0);
+      clib_warning ("vni %d not associated to a vrf!", vni);
       return VNET_API_ERROR_INVALID_VALUE;
     }
 
-  refc = hash_get(lcm->dp_if_refcount_by_vni, 0);
+  refc = hash_get(lcm->dp_if_refcount_by_vni, vni);
 
   /* enable/disable data-plane interface */
   if (a->is_add)
@@ -148,9 +150,12 @@ vnet_lisp_add_del_local_mapping (vnet_lisp_add_del_mapping_args_t * a,
       if (!refc)
         {
           ai->is_add = 1;
-          ai->vni = 0; /* default for now, pass vni as parameter */
+          ai->vni = vni;
           ai->table_id = table_id[0];
           vnet_lisp_gpe_add_del_iface (ai, 0);
+
+          /* counts the number of eids in a vni that use the interface */
+          hash_set(lcm->dp_if_refcount_by_vni, vni, 1);
         }
       else
         {
@@ -167,7 +172,7 @@ vnet_lisp_add_del_local_mapping (vnet_lisp_add_del_mapping_args_t * a,
       if (refc[0] == 0)
         {
           ai->is_add = 0;
-          ai->vni = 0; /* default for now, pass vni as parameter */
+          ai->vni = vni;
           ai->table_id = table_id[0];
           vnet_lisp_gpe_add_del_iface (ai, 0);
         }
@@ -192,7 +197,7 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
   uword * p;
   vnet_lisp_add_del_mapping_args_t _a, * a = &_a;
 
-  gid_address_type (&eid) = IP_PREFIX;
+  gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
 
   /* Get a line of input. */
   if (! unformat_user (input, unformat_line_input, line_input))
@@ -873,7 +878,7 @@ format_lisp_cp_lookup_trace (u8 * s, va_list * args)
   lisp_cp_lookup_trace_t * t = va_arg (*args, lisp_cp_lookup_trace_t *);
 
   s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
-              format_ip4_address, &t->map_resolver_ip, format_gid_address,
+              format_ip_address, &t->map_resolver_ip, format_gid_address,
               &t->dst_eid);
   return s;
 }
@@ -896,10 +901,13 @@ get_local_iface_ip_for_dst (lisp_cp_main_t *lcm, ip_address_t * dst,
   u32 adj_index;
   ip_adjacency_t * adj;
   ip_interface_address_t * ia = 0;
-  ip_lookup_main_t * lm = &lcm->im4->lookup_main;
+  ip_lookup_main_t * lm;
   ip4_address_t * l4 = 0;
   ip6_address_t * l6 = 0;
 
+  lm = ip_addr_version (dst) == IP4 ?
+      &lcm->im4->lookup_main : &lcm->im6->lookup_main;
+
   adj_index = ip_fib_lookup_with_table (lcm, 0, dst);
   adj = ip_get_adjacency (lm, adj_index);
 
@@ -967,7 +975,7 @@ get_local_iface_ip_for_dst (lisp_cp_main_t *lcm, ip_address_t * dst,
 }
 
 
-static ip_address_t *
+static gid_address_t *
 build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
 {
   ip4_address_t * l4;
@@ -976,9 +984,12 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
   locator_t * loc;
   u32 * loc_indexp;
   ip_interface_address_t * ia = 0;
-  ip_address_t * rlocs = 0;
-  ip_address_t _rloc, * rloc = &_rloc;
+  gid_address_t gid_data, * gid = &gid_data;
+  gid_address_t * rlocs = 0;
+  ip_prefix_t * ippref = &gid_address_ippref (gid);
+  ip_address_t * rloc = &ip_prefix_addr (ippref);
 
+  gid_address_type (gid) = GID_ADDR_IP_PREFIX;
   for (i = 0; i < vec_len(loc_set->locator_indices); i++)
     {
       loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
@@ -990,8 +1001,8 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
                                    loc->sw_if_index, 1 /* unnumbered */,
       ({
        l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
-  ip_addr_v4(rloc) = l4[0];
-  vec_add1(rlocs, rloc[0]);
+        ip_addr_v4 (rloc) = l4[0];
+        vec_add1 (rlocs, gid[0]);
       }));
 
       ip_addr_version(rloc) = IP6;
@@ -999,9 +1010,9 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
       foreach_ip_interface_address (&lcm->im6->lookup_main, ia,
                                    loc->sw_if_index, 1 /* unnumbered */,
       ({
-  l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
-  ip_addr_v6(rloc) = l6[0];
-  vec_add1(rlocs, rloc[0]);
+        l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
+        ip_addr_v6 (rloc) = l6[0];
+        vec_add1 (rlocs, gid[0]);
       }));
     }
   return rlocs;
@@ -1016,7 +1027,7 @@ build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
   vlib_buffer_t * b;
   u32 bi;
   ip_address_t * mr_ip, sloc;
-  ip_address_t * rlocs = 0;
+  gid_address_t * rlocs = 0;
 
   if (vlib_buffer_alloc (vm, &bi, 1) != 1)
     {
@@ -1163,9 +1174,9 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
           gid_address_t src, dst;
           ip_prefix_t * spref, * dpref;
 
-          gid_address_type (&src) = IP_PREFIX;
+          gid_address_type (&src) = GID_ADDR_IP_PREFIX;
           spref = &gid_address_ippref(&src);
-          gid_address_type (&dst) = IP_PREFIX;
+          gid_address_type (&dst) = GID_ADDR_IP_PREFIX;
           dpref = &gid_address_ippref(&dst);
 
           pi0 = from[0];
@@ -1313,7 +1324,7 @@ del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index,
   a->is_add = 0;
   a->dlocator = fe->dst_loc;
   a->slocator = fe->src_loc;
-  a->vni = 0; // XXX should be part of mapping/eid
+  a->vni = gid_address_vni(&a->deid);
   gid_address_copy(&a->deid, &fe->deid);
 
   vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
@@ -1328,9 +1339,10 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
 {
   mapping_t * src_map, * dst_map;
   locator_set_t * dst_ls, * src_ls;
-  u32 i, minp = ~0;
+  u32 i, minp = ~0, sw_if_index;
   locator_t * dl = 0;
   uword * feip = 0, * tidp;
+  fwd_entry_t* fe;
   vnet_lisp_gpe_add_del_fwd_entry_args_t _a, * a = &_a;
 
   memset (a, 0, sizeof(*a));
@@ -1343,6 +1355,17 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
   src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
   dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
 
+  gid_address_copy (&a->deid, &dst_map->eid);
+  a->vni = gid_address_vni(&a->deid);
+
+  tidp = hash_get(lcm->table_id_by_vni, a->vni);
+  if (!tidp)
+    {
+      clib_warning("vni %d not associated to a vrf!", a->vni);
+      return;
+    }
+  a->table_id = tidp[0];
+
   /* XXX simple forwarding policy: first lowest (value) priority locator */
   dst_ls = pool_elt_at_index (lcm->locator_set_pool,
                               dst_map->locator_set_index);
@@ -1350,7 +1373,8 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
     {
       u32 li = vec_elt (dst_ls->locator_indices, i);
       locator_t * l = pool_elt_at_index (lcm->locator_pool, li);
-      if (l->priority < minp && gid_address_type(&l->address) == IP_PREFIX)
+      if (l->priority < minp && gid_address_type(&l->address)
+            == GID_ADDR_IP_PREFIX)
         {
           minp = l->priority;
           dl = l;
@@ -1358,9 +1382,9 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
     }
   if (dl)
     {
-      src_ls = pool_elt_at_index (lcm->locator_set_pool,
-                                  src_map->locator_set_index);
-      for (i = 0; i < vec_len (src_ls->locator_indices); i++)
+      src_ls = pool_elt_at_index(lcm->locator_set_pool,
+                                 src_map->locator_set_index);
+      for (i = 0; i < vec_len(src_ls->locator_indices); i++)
         {
           u32 li = vec_elt (src_ls->locator_indices, i);
           locator_t * sl = pool_elt_at_index (lcm->locator_pool, li);
@@ -1385,8 +1409,8 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
             }
         }
     }
+
   /* insert data plane forwarding entry */
-  u32 sw_if_index;
   a->is_add = 1;
   if (dl)
     a->dlocator = gid_address_ip(&dl->address);
@@ -1396,26 +1420,14 @@ add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
       a->action = dst_map->action;
     }
 
-  gid_address_copy (&a->deid, &dst_map->eid);
-  a->vni = 0; // XXX should be part of mapping/eid
-
-  tidp = hash_get(lcm->table_id_by_vni, a->vni);
-  if (!tidp)
-    {
-      clib_warning("vni %d not associated to a vrf!", a->vni);
-      return;
-    }
-  a->table_id = tidp[0];
-
+  /* TODO remove */
   u8 ipver = ip_prefix_version(&gid_address_ippref(&a->deid));
   a->decap_next_index = (ipver == IP4) ?
           LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
 
-  /* XXX tunnels work only with IP4 now */
   vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
 
   /* add tunnel to fwd entry table XXX check return value from DP insertion */
-  fwd_entry_t* fe;
   pool_get (lcm->fwd_entry_pool, fe);
   fe->dst_loc = a->dlocator;
   fe->src_loc = a->slocator;
@@ -1451,6 +1463,7 @@ compare_locators (lisp_cp_main_t *lcm, u32 * old_ls_indexes,
 void
 process_map_reply (lisp_cp_main_t * lcm, vlib_buffer_t * b)
 {
+  locator_t * loc;
   u32 len = 0, i, ls_index = 0;
   void * h;
   vnet_lisp_add_del_locator_set_args_t _ls_arg, * ls_arg = &_ls_arg;
@@ -1491,6 +1504,10 @@ process_map_reply (lisp_cp_main_t * lcm, vlib_buffer_t * b)
       if (len == ~0)
         {
           clib_warning ("Failed to parse mapping record!");
+          vec_foreach (loc, ls_arg->locators)
+            {
+              locator_free (loc);
+            }
           vec_free(ls_arg->locators);
           return;
         }
@@ -1554,7 +1571,7 @@ process_map_request (vlib_main_t * vm, lisp_cp_main_t * lcm, vlib_buffer_t * b)
   gid_address_t src, dst;
 //  u64 nonce;
   u32 i, len = 0;
-  gid_address_t * itr_rlocs = 0;
+  gid_address_t * itr_rlocs = 0, * rloc;
 
   mreq_hdr = vlib_buffer_get_current (b);
   vlib_buffer_pull (b, sizeof(*mreq_hdr));
@@ -1576,6 +1593,12 @@ process_map_request (vlib_main_t * vm, lisp_cp_main_t * lcm, vlib_buffer_t * b)
   if (len == ~0)
     return;
 
+  /* TODO: RLOCs are currently unused, so free them for now */
+  vec_foreach (rloc, itr_rlocs)
+    {
+      gid_address_free (rloc);
+    }
+
   /* parse eid records and send SMR-invoked map-requests */
   for (i = 0; i < MREQ_REC_COUNT(mreq_hdr); i++)
     {