IP mcast: allow unicast address as a next-hop
[vpp.git] / src / vnet / ip / ip_api.c
index 0b0a7a9..b4d942b 100644 (file)
@@ -76,6 +76,7 @@ _(IP_ADDRESS_DUMP, ip_address_dump)                                     \
 _(IP_DUMP, ip_dump)                                                     \
 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del)                             \
 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit)                      \
+_(IP_PROBE_NEIGHBOR, ip_probe_neighbor)                                \
 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events)                             \
 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events)                               \
 _(WANT_IP6_RA_EVENTS, want_ip6_ra_events)                               \
@@ -1207,13 +1208,15 @@ mroute_add_del_handler (u8 is_add,
                        dpo_proto_t nh_proto,
                        u32 entry_flags,
                        fib_rpf_id_t rpf_id,
-                       u32 next_hop_sw_if_index, u32 itf_flags, u32 bier_imp)
+                       u32 next_hop_sw_if_index,
+                       ip46_address_t * nh, u32 itf_flags, u32 bier_imp)
 {
   stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
 
   fib_route_path_t path = {
     .frp_sw_if_index = next_hop_sw_if_index,
     .frp_proto = nh_proto,
+    .frp_addr = *nh,
   };
 
   if (is_local)
@@ -1252,6 +1255,7 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
 {
   fib_protocol_t fproto;
   dpo_proto_t nh_proto;
+  ip46_address_t nh;
   u32 fib_index;
   int rv;
 
@@ -1276,6 +1280,8 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
                   sizeof (pfx.fp_grp_addr.ip4));
       clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
                   sizeof (pfx.fp_src_addr.ip4));
+      memset (&nh.ip6, 0, sizeof (nh.ip6));
+      clib_memcpy (&nh.ip4, mp->nh_address, sizeof (nh.ip4));
     }
   else
     {
@@ -1283,6 +1289,7 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
                   sizeof (pfx.fp_grp_addr.ip6));
       clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
                   sizeof (pfx.fp_src_addr.ip6));
+      clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6));
     }
 
   return (mroute_add_del_handler (mp->is_add,
@@ -1292,6 +1299,7 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
                                  ntohl (mp->entry_flags),
                                  ntohl (mp->rpf_id),
                                  ntohl (mp->next_hop_sw_if_index),
+                                 &nh,
                                  ntohl (mp->itf_flags),
                                  ntohl (mp->bier_imp)));
 }
@@ -2684,6 +2692,36 @@ static void
   REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
 }
 
+static void
+vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp)
+{
+  int rv = 0;
+  vlib_main_t *vm = vlib_get_main ();
+  vl_api_ip_probe_neighbor_reply_t *rmp;
+  clib_error_t *error;
+
+  VALIDATE_SW_IF_INDEX (mp);
+
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+
+  if (mp->is_ipv6)
+    error = ip6_probe_neighbor (vm, (ip6_address_t *) mp->dst_address,
+                               sw_if_index);
+  else
+    error = ip4_probe_neighbor (vm, (ip4_address_t *) mp->dst_address,
+                               sw_if_index);
+
+  if (error)
+    {
+      clib_error_report (error);
+      rv = clib_error_get_code (error);
+    }
+
+  BAD_SW_IF_INDEX_LABEL;
+
+  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
+}
+
 static int
 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
 {