]> git.puffer.fish Git - mirror/frr.git/commitdiff
sharpd: Allow sharpd to listen to neighbor events 15179/head
authorDonald Sharp <sharpd@nvidia.com>
Fri, 19 Jan 2024 20:13:49 +0000 (15:13 -0500)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 22 Jan 2024 17:19:20 +0000 (12:19 -0500)
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
doc/user/sharp.rst
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h

index 355b6b4d596bf6d3e108d06db4b1ccdb28fe3272..2be38a31df69d9f774dd2951dce7120eda6d99a9 100644 (file)
@@ -63,6 +63,11 @@ keyword. At present, no sharp commands will be preserved in the config.
    Install a label into the kernel that causes the specified vrf NAME table to
    be used for pop and forward operations when the specified label is seen.
 
+.. clicmd:: sharp watch [vrf VRF_NAME] neighbor
+
+   Instruct zebra to notify sharpd about neighbor events in the specified vrf.
+   If no vrf is specified then assume default.
+
 .. clicmd:: sharp watch <nexthop <A.B.C.D|X:X::X:X>|import <A.B.C.D/M:X:X::X:X/M> [connected]
 
    Instruct zebra to monitor and notify sharp when the specified nexthop is
index cf79bacc6b6e98968f089ba536acf7b620274101..1df765614467c0e3ea34d6f6df879a8ae6507865 100644 (file)
 
 DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator");
 
+DEFPY(watch_neighbor, watch_neighbor_cmd,
+      "sharp watch [vrf NAME$vrf_name] neighbor",
+      "Sharp routing Protocol\n"
+      "Watch for changes\n"
+      "The vrf we would like to watch if non-default\n"
+      "The NAME of the vrf\n"
+      "Neighbor events\n")
+{
+       struct vrf *vrf;
+
+       if (!vrf_name)
+               vrf_name = VRF_DEFAULT_NAME;
+       vrf = vrf_lookup_by_name(vrf_name);
+
+       if (!vrf) {
+               vty_out(vty, "The vrf NAME specified: %s does not exist\n",
+                       vrf_name);
+               return CMD_WARNING;
+       }
+
+       sharp_zebra_register_neigh(vrf->vrf_id, AFI_IP, true);
+
+       return CMD_SUCCESS;
+}
+
+
 DEFPY(watch_redistribute, watch_redistribute_cmd,
       "sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD,
       "Sharp routing Protocol\n"
@@ -1419,6 +1445,7 @@ void sharp_vty_init(void)
        install_element(ENABLE_NODE, &remove_routes_cmd);
        install_element(ENABLE_NODE, &vrf_label_cmd);
        install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
+       install_element(ENABLE_NODE, &watch_neighbor_cmd);
        install_element(ENABLE_NODE, &watch_redistribute_cmd);
        install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
        install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
index cbfa0d1cccece6985ed22c8c3398b815d0812297..6588300daa5f90052ddb8745f57f2198509f2365 100644 (file)
@@ -989,6 +989,41 @@ static int sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
+static int sharp_zebra_process_neigh(ZAPI_CALLBACK_ARGS)
+{
+       union sockunion addr = {}, lladdr = {};
+       struct zapi_neigh_ip api = {};
+       struct interface *ifp;
+
+       zlog_debug("Received a neighbor event");
+       zclient_neigh_ip_decode(zclient->ibuf, &api);
+
+       if (api.ip_in.ipa_type == AF_UNSPEC)
+               return 0;
+
+       sockunion_family(&addr) = api.ip_in.ipa_type;
+       memcpy((uint8_t *)sockunion_get_addr(&addr), &api.ip_in.ip.addr,
+              family2addrsize(api.ip_in.ipa_type));
+
+       sockunion_family(&lladdr) = api.ip_out.ipa_type;
+       if (api.ip_out.ipa_type != AF_UNSPEC)
+               memcpy((uint8_t *)sockunion_get_addr(&lladdr),
+                      &api.ip_out.ip.addr,
+                      family2addrsize(api.ip_out.ipa_type));
+       ifp = if_lookup_by_index(api.index, vrf_id);
+       if (!ifp) {
+               zlog_debug("Failed to lookup interface for neighbor entry: %u for %u",
+                          api.index, vrf_id);
+               return 0;
+       }
+
+       zlog_debug("Received: %s %pSU dev %s lladr %pSU",
+                  (cmd = ZEBRA_NEIGH_ADDED) ? "NEW" : "DEL", &addr, ifp->name,
+                  &lladdr);
+
+       return 0;
+}
+
 int sharp_zebra_send_interface_protodown(struct interface *ifp, bool down)
 {
        zlog_debug("Sending zebra to set %s protodown %s", ifp->name,
@@ -1059,6 +1094,12 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
        return 0;
 }
 
+void sharp_zebra_register_neigh(vrf_id_t vrf_id, afi_t afi, bool reg)
+{
+       zclient_register_neigh(zclient, vrf_id, afi, reg);
+}
+
+
 static zclient_handler *const sharp_handlers[] = {
        [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
        [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
@@ -1070,6 +1111,8 @@ static zclient_handler *const sharp_handlers[] = {
        [ZEBRA_OPAQUE_NOTIFY] = sharp_opq_notify_handler,
        [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
                sharp_zebra_process_srv6_locator_chunk,
+       [ZEBRA_NEIGH_ADDED] = sharp_zebra_process_neigh,
+       [ZEBRA_NEIGH_REMOVED] = sharp_zebra_process_neigh,
 };
 
 void sharp_zebra_init(void)
index 6314f862f57e3dc5a6f26c923013b778a126b4e2..df80ce77a1cf2c066c655f4e0c5453f880fdbedd 100644 (file)
@@ -71,4 +71,6 @@ extern int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
                                           const struct prefix *destination,
                                           uint8_t ip_proto, uint16_t src_port,
                                           uint16_t dst_port, uint64_t rate);
+
+extern void sharp_zebra_register_neigh(vrf_id_t vrf_id, afi_t afi, bool reg);
 #endif