UDP Encapsulation.
[vpp.git] / src / vnet / ip / ip_api.c
index 384ec3e..20e1920 100644 (file)
@@ -70,6 +70,8 @@ _(IP_DUMP, ip_dump)                                                     \
 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del)                             \
 _(IP_ADD_DEL_ROUTE, ip_add_del_route)                                   \
 _(IP_TABLE_ADD_DEL, ip_table_add_del)                                   \
+_(IP_PUNT_POLICE, ip_punt_police)                                       \
+_(IP_PUNT_REDIRECT, ip_punt_redirect)                                   \
 _(SET_IP_FLOW_HASH,set_ip_flow_hash)                                    \
 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config)           \
 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix)           \
@@ -77,7 +79,8 @@ _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del)                             \
 _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump)                                   \
 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable )    \
 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,                             \
-  sw_interface_ip6_set_link_local_address)
+  sw_interface_ip6_set_link_local_address)                             \
+_(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del )
 
 extern void stats_dslock_with_hint (int hint, int tag);
 extern void stats_dsunlock (void);
@@ -180,7 +183,8 @@ copy_fib_next_hop (fib_route_path_encode_t * api_rpath, void *fp_arg)
 static void
 send_ip_fib_details (vpe_api_main_t * am,
                     unix_shared_memory_queue_t * q,
-                    u32 table_id, fib_prefix_t * pfx,
+                    const fib_table_t * table,
+                    const fib_prefix_t * pfx,
                     fib_route_path_encode_t * api_rpaths, u32 context)
 {
   vl_api_ip_fib_details_t *mp;
@@ -196,7 +200,9 @@ send_ip_fib_details (vpe_api_main_t * am,
   mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
   mp->context = context;
 
-  mp->table_id = htonl (table_id);
+  mp->table_id = htonl (table->ft_table_id);
+  memcpy (mp->table_name, table->ft_desc,
+         clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
   mp->address_length = pfx->fp_len;
   memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
 
@@ -295,9 +301,7 @@ vl_api_ip_fib_dump_t_handler (vl_api_ip_fib_dump_t * mp)
     fib_table = fib_table_get (fib_index, pfx.fp_proto);
     api_rpaths = NULL;
     fib_entry_encode (*lfeip, &api_rpaths);
-    send_ip_fib_details (am, q,
-                        fib_table->ft_table_id, &pfx, api_rpaths,
-                        mp->context);
+    send_ip_fib_details (am, q, fib_table, &pfx, api_rpaths, mp->context);
     vec_free (api_rpaths);
   }
 
@@ -361,7 +365,7 @@ send_ip6_fib_details (vpe_api_main_t * am,
       }
     fp->weight = api_rpath->rpath.frp_weight;
     fp->preference = api_rpath->rpath.frp_preference;
-    fp->sw_if_index = api_rpath->rpath.frp_sw_if_index;
+    fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
     copy_fib_next_hop (api_rpath, fp);
     fp++;
   }
@@ -646,6 +650,64 @@ vl_api_ip6_mfib_dump_t_handler (vl_api_ip6_mfib_dump_t * mp)
   vec_free (api_rpaths);
 }
 
+static void
+vl_api_ip_punt_police_t_handler (vl_api_ip_punt_police_t * mp,
+                                vlib_main_t * vm)
+{
+  vl_api_ip_punt_police_reply_t *rmp;
+  int rv = 0;
+
+  if (mp->is_ip6)
+    ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
+  else
+    ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
+
+  REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
+}
+
+static void
+vl_api_ip_punt_redirect_t_handler (vl_api_ip_punt_redirect_t * mp,
+                                  vlib_main_t * vm)
+{
+  vl_api_ip_punt_redirect_reply_t *rmp;
+  int rv = 0;
+
+  if (mp->is_add)
+    {
+      ip46_address_t nh;
+
+      memset (&nh, 0, sizeof (nh));
+
+      if (mp->is_ip6)
+       {
+         memcpy (&nh.ip6, mp->nh, sizeof (nh.ip6));
+
+         ip6_punt_redirect_add (ntohl (mp->rx_sw_if_index),
+                                ntohl (mp->tx_sw_if_index), &nh);
+       }
+      else
+       {
+         memcpy (&nh.ip4, mp->nh, sizeof (nh.ip4));
+
+         ip4_punt_redirect_add (ntohl (mp->rx_sw_if_index),
+                                ntohl (mp->tx_sw_if_index), &nh);
+       }
+    }
+  else
+    {
+      if (mp->is_ip6)
+       {
+         ip6_punt_redirect_del (ntohl (mp->rx_sw_if_index));
+       }
+      else
+       {
+         ip4_punt_redirect_del (ntohl (mp->rx_sw_if_index));
+       }
+    }
+
+  REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
+}
+
 static void
 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                                      vlib_main_t * vm)
@@ -693,9 +755,9 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
          vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
     }
 
-  BAD_SW_IF_INDEX_LABEL;
-
   stats_dsunlock ();
+
+  BAD_SW_IF_INDEX_LABEL;
   REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
 }
 
@@ -744,7 +806,7 @@ vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
 
   if (mp->is_add)
     {
-      ip_table_create (fproto, table_id, 1);
+      ip_table_create (fproto, table_id, 1, mp->name);
     }
   else
     {
@@ -768,10 +830,14 @@ add_del_route_t_handler (u8 is_multipath,
                         u8 is_resolve_attached,
                         u8 is_interface_rx,
                         u8 is_rpf_id,
+                        u8 is_l2_bridged,
+                        u8 is_source_lookup,
+                        u8 is_udp_encap,
                         u32 fib_index,
                         const fib_prefix_t * prefix,
                         dpo_proto_t next_hop_proto,
                         const ip46_address_t * next_hop,
+                        u32 next_hop_id,
                         u32 next_hop_sw_if_index,
                         u8 next_hop_fib_index,
                         u16 next_hop_weight,
@@ -793,12 +859,20 @@ add_del_route_t_handler (u8 is_multipath,
   fib_route_path_t *paths = NULL;
   fib_entry_flag_t entry_flags = FIB_ENTRY_FLAG_NONE;
 
-  if (MPLS_LABEL_INVALID != next_hop_via_label)
+  /*
+   * the special INVALID label meams we are not recursing via a
+   * label. Exp-null value is never a valid via-label so that
+   * also means it's not a via-label and means clients that set
+   * it to 0 by default get the expected behaviour
+   */
+  if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
     {
       path.frp_proto = DPO_PROTO_MPLS;
       path.frp_local_label = next_hop_via_label;
       path.frp_eos = MPLS_NON_EOS;
     }
+  if (is_l2_bridged)
+    path.frp_proto = DPO_PROTO_ETHERNET;
   if (is_resolve_host)
     path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
   if (is_resolve_attached)
@@ -807,8 +881,15 @@ add_del_route_t_handler (u8 is_multipath,
     path_flags |= FIB_ROUTE_PATH_INTF_RX;
   if (is_rpf_id)
     path_flags |= FIB_ROUTE_PATH_RPF_ID;
+  if (is_source_lookup)
+    path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
   if (is_multicast)
     entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
+  if (is_udp_encap)
+    {
+      path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
+      path.frp_udp_encap_id = next_hop_id;
+    }
 
   path.frp_flags = path_flags;
 
@@ -1036,8 +1117,12 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
                                   mp->classify_table_index,
                                   mp->is_resolve_host,
                                   mp->is_resolve_attached, 0, 0,
+                                  mp->is_l2_bridged,
+                                  mp->is_source_lookup,
+                                  mp->is_udp_encap,
                                   fib_index, &pfx, DPO_PROTO_IP4,
                                   &nh,
+                                  ntohl (mp->next_hop_id),
                                   ntohl (mp->next_hop_sw_if_index),
                                   next_hop_fib_index,
                                   mp->next_hop_weight,
@@ -1095,8 +1180,12 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
                                   mp->classify_table_index,
                                   mp->is_resolve_host,
                                   mp->is_resolve_attached, 0, 0,
+                                  mp->is_l2_bridged,
+                                  mp->is_source_lookup,
+                                  mp->is_udp_encap,
                                   fib_index, &pfx, DPO_PROTO_IP6,
-                                  &nh, ntohl (mp->next_hop_sw_if_index),
+                                  &nh, ntohl (mp->next_hop_id),
+                                  ntohl (mp->next_hop_sw_if_index),
                                   next_hop_fib_index,
                                   mp->next_hop_weight,
                                   mp->next_hop_preference,
@@ -1124,7 +1213,8 @@ vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
 }
 
 void
-ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api)
+ip_table_create (fib_protocol_t fproto,
+                u32 table_id, u8 is_api, const u8 * name)
 {
   u32 fib_index, mfib_index;
 
@@ -1147,17 +1237,17 @@ ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api)
 
       if (~0 == fib_index)
        {
-         fib_table_find_or_create_and_lock (fproto, table_id,
-                                            (is_api ?
-                                             FIB_SOURCE_API :
-                                             FIB_SOURCE_CLI));
+         fib_table_find_or_create_and_lock_w_name (fproto, table_id,
+                                                   (is_api ?
+                                                    FIB_SOURCE_API :
+                                                    FIB_SOURCE_CLI), name);
        }
       if (~0 == mfib_index)
        {
-         mfib_table_find_or_create_and_lock (fproto, table_id,
-                                             (is_api ?
-                                              MFIB_SOURCE_API :
-                                              MFIB_SOURCE_CLI));
+         mfib_table_find_or_create_and_lock_w_name (fproto, table_id,
+                                                    (is_api ?
+                                                     MFIB_SOURCE_API :
+                                                     MFIB_SOURCE_CLI), name);
        }
     }
 }
@@ -1771,6 +1861,29 @@ vl_api_mfib_signal_dump_t_handler (vl_api_mfib_signal_dump_t * mp)
     ;
 }
 
+static void
+  vl_api_ip_container_proxy_add_del_t_handler
+  (vl_api_ip_container_proxy_add_del_t * mp)
+{
+  vl_api_ip_container_proxy_add_del_reply_t *rmp;
+  vnet_ip_container_proxy_args_t args;
+  int rv = 0;
+  clib_error_t *error;
+
+  memset (&args, 0, sizeof (args));
+  ip_set (&args.prefix.fp_addr, mp->ip, mp->is_ip4);
+  args.prefix.fp_len = mp->plen ? mp->plen : (mp->is_ip4 ? 32 : 128);
+  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
+  args.is_add = mp->is_add;
+  if ((error = vnet_ip_container_proxy_add_del (&args)))
+    {
+      rv = clib_error_get_code (error);
+      clib_error_report (error);
+    }
+
+  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
+}
+
 #define vl_msg_name_crc_list
 #include <vnet/ip/ip.api.h>
 #undef vl_msg_name_crc_list