sharpd: Allow sharpd to listen to neighbor events

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
Donald Sharp 2024-01-19 15:13:49 -05:00
parent a0d38a7ac6
commit 01cb1fb82c
4 changed files with 77 additions and 0 deletions

View 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 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. 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] .. 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 Instruct zebra to monitor and notify sharp when the specified nexthop is

View file

@ -27,6 +27,32 @@
DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator"); 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, DEFPY(watch_redistribute, watch_redistribute_cmd,
"sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD, "sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD,
"Sharp routing Protocol\n" "Sharp routing Protocol\n"
@ -1419,6 +1445,7 @@ void sharp_vty_init(void)
install_element(ENABLE_NODE, &remove_routes_cmd); install_element(ENABLE_NODE, &remove_routes_cmd);
install_element(ENABLE_NODE, &vrf_label_cmd); install_element(ENABLE_NODE, &vrf_label_cmd);
install_element(ENABLE_NODE, &sharp_nht_data_dump_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_redistribute_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v6_cmd); install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v4_cmd); install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);

View file

@ -989,6 +989,41 @@ static int sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
return 0; 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) int sharp_zebra_send_interface_protodown(struct interface *ifp, bool down)
{ {
zlog_debug("Sending zebra to set %s protodown %s", ifp->name, 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; 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[] = { static zclient_handler *const sharp_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add, [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
[ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete, [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_OPAQUE_NOTIFY] = sharp_opq_notify_handler,
[ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
sharp_zebra_process_srv6_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) void sharp_zebra_init(void)

View file

@ -71,4 +71,6 @@ extern int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
const struct prefix *destination, const struct prefix *destination,
uint8_t ip_proto, uint16_t src_port, uint8_t ip_proto, uint16_t src_port,
uint16_t dst_port, uint64_t rate); uint16_t dst_port, uint64_t rate);
extern void sharp_zebra_register_neigh(vrf_id_t vrf_id, afi_t afi, bool reg);
#endif #endif