diff options
Diffstat (limited to 'sharpd')
-rw-r--r-- | sharpd/sharp_logpump.c | 1 | ||||
-rw-r--r-- | sharpd/sharp_main.c | 50 | ||||
-rw-r--r-- | sharpd/sharp_nht.c | 8 | ||||
-rw-r--r-- | sharpd/sharp_nht.h | 1 | ||||
-rw-r--r-- | sharpd/sharp_vty.c | 32 | ||||
-rw-r--r-- | sharpd/sharp_zebra.c | 108 | ||||
-rw-r--r-- | sharpd/sharp_zebra.h | 5 |
7 files changed, 158 insertions, 47 deletions
diff --git a/sharpd/sharp_logpump.c b/sharpd/sharp_logpump.c index 5474e80..d02921f 100644 --- a/sharpd/sharp_logpump.c +++ b/sharpd/sharp_logpump.c @@ -5,6 +5,7 @@ */ #include <zebra.h> +#include <sys/resource.h> #include "vty.h" #include "command.h" diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index fa85c2b..f4ce147 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -54,6 +54,23 @@ struct zebra_privs_t sharp_privs = { struct option longopts[] = {{0}}; +struct sharp_global sg; + +static void sharp_global_init(void) +{ + memset(&sg, 0, sizeof(sg)); + sg.nhs = list_new(); + sg.nhs->del = (void (*)(void *))sharp_nh_tracker_free; + sg.ted = NULL; + sg.srv6_locators = list_new(); +} + +static void sharp_global_destroy(void) +{ + list_delete(&sg.nhs); + list_delete(&sg.srv6_locators); +} + /* Master of threads. */ struct event_loop *master; @@ -68,6 +85,11 @@ static void sigint(void) { zlog_notice("Terminating on signal"); + vrf_terminate(); + sharp_zebra_terminate(); + + sharp_global_destroy(); + frr_fini(); exit(0); @@ -98,8 +120,6 @@ struct frr_signal_t sharp_signals[] = { }, }; -#define SHARP_VTY_PORT 2614 - static const struct frr_yang_module_info *const sharpd_yang_modules[] = { &frr_filter_info, &frr_interface_info, @@ -107,26 +127,20 @@ static const struct frr_yang_module_info *const sharpd_yang_modules[] = { &frr_vrf_info, }; -FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT, +/* clang-format off */ +FRR_DAEMON_INFO(sharpd, SHARP, + .vty_port = SHARP_VTY_PORT, + .proghelp = "Implementation of a Sharp of routes daemon.", - .proghelp = "Implementation of a Sharp of routes daemon.", + .signals = sharp_signals, + .n_signals = array_size(sharp_signals), - .signals = sharp_signals, - .n_signals = array_size(sharp_signals), + .privs = &sharp_privs, - .privs = &sharp_privs, .yang_modules = sharpd_yang_modules, - .n_yang_modules = array_size(sharpd_yang_modules), + .yang_modules = sharpd_yang_modules, + .n_yang_modules = array_size(sharpd_yang_modules), ); - -struct sharp_global sg; - -static void sharp_global_init(void) -{ - memset(&sg, 0, sizeof(sg)); - sg.nhs = list_new(); - sg.ted = NULL; - sg.srv6_locators = list_new(); -} +/* clang-format on */ static void sharp_start_configuration(void) { diff --git a/sharpd/sharp_nht.c b/sharpd/sharp_nht.c index fa78805..6d64fcf 100644 --- a/sharpd/sharp_nht.c +++ b/sharpd/sharp_nht.c @@ -40,6 +40,11 @@ struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p) return nht; } +void sharp_nh_tracker_free(struct sharp_nh_tracker *nht) +{ + XFREE(MTYPE_NH_TRACKER, nht); +} + void sharp_nh_tracker_dump(struct vty *vty) { struct listnode *node; @@ -169,7 +174,8 @@ static void sharp_nhgroup_delete_cb(const char *name) if (!snhg) return; - nhg_del(snhg->id); + if (sharp_nhgroup_id_is_installed(snhg->id)) + nhg_del(snhg->id); sharp_nhg_rb_del(&nhg_head, snhg); XFREE(MTYPE_NHG, snhg); } diff --git a/sharpd/sharp_nht.h b/sharpd/sharp_nht.h index 5523f28..b27952a 100644 --- a/sharpd/sharp_nht.h +++ b/sharpd/sharp_nht.h @@ -18,6 +18,7 @@ struct sharp_nh_tracker { }; extern struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p); +extern void sharp_nh_tracker_free(struct sharp_nh_tracker *nht); extern void sharp_nh_tracker_dump(struct vty *vty); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index cf79bac..07050ab 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -27,8 +27,35 @@ 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, + "[no] sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD, + NO_STR "Sharp routing Protocol\n" "Watch for changes\n" "The vrf we would like to watch if non-default\n" @@ -49,7 +76,7 @@ DEFPY(watch_redistribute, watch_redistribute_cmd, } source = proto_redistnum(AFI_IP, argv[argc-1]->text); - sharp_redistribute_vrf(vrf, source); + sharp_redistribute_vrf(vrf, source, !no); return CMD_SUCCESS; } @@ -1419,6 +1446,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); diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index c095fec..133da91 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -251,8 +251,7 @@ static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance, /* Only send via ID if nhgroup has been successfully installed */ if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) { - SET_FLAG(api.message, ZAPI_MESSAGE_NHG); - api.nhgid = nhgid; + zapi_route_set_nhg_id(&api, &nhgid); } else { for (ALL_NEXTHOPS_PTR(nhg, nh)) { /* Check if we set a VNI label */ @@ -512,6 +511,7 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) static void zebra_connected(struct zclient *zclient) { + zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, true); zclient_send_reg_requests(zclient, VRF_DEFAULT); /* @@ -562,6 +562,12 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg, } if (api_nhg.nexthop_num == 0) { + if (sharp_nhgroup_id_is_installed(id)) { + zlog_debug("%s: nhg %u: no nexthops, deleting nexthop group", __func__, + id); + zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg); + return; + } zlog_debug("%s: nhg %u not sent: no valid nexthops", __func__, id); is_valid = false; @@ -666,27 +672,20 @@ static int sharp_debug_nexthops(struct zapi_route *api) return i; } -static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS) + +static void sharp_nexthop_update(struct vrf *vrf, struct prefix *matched, + struct zapi_route *nhr) { struct sharp_nh_tracker *nht; - struct zapi_route nhr; - struct prefix matched; - - if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) { - zlog_err("%s: Decode of update failed", __func__); - return 0; - } zlog_debug("Received update for %pFX actual match: %pFX metric: %u", - &matched, &nhr.prefix, nhr.metric); + matched, &nhr->prefix, nhr->metric); - nht = sharp_nh_tracker_get(&matched); - nht->nhop_num = nhr.nexthop_num; + nht = sharp_nh_tracker_get(matched); + nht->nhop_num = nhr->nexthop_num; nht->updates++; - sharp_debug_nexthops(&nhr); - - return 0; + sharp_debug_nexthops(nhr); } static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS) @@ -705,10 +704,11 @@ static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS) return 0; } -void sharp_redistribute_vrf(struct vrf *vrf, int type) +void sharp_redistribute_vrf(struct vrf *vrf, int type, bool turn_on) { - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, - 0, vrf->vrf_id); + zebra_redistribute_send(turn_on ? ZEBRA_REDISTRIBUTE_ADD + : ZEBRA_REDISTRIBUTE_DELETE, + zclient, AFI_IP, type, 0, vrf->vrf_id); } static zclient_handler *const sharp_opaque_handlers[] = { @@ -934,6 +934,7 @@ static int nhg_notify_owner(ZAPI_CALLBACK_ARGS) zlog_debug("Failed install of nhg %u", id); break; case ZAPI_NHG_REMOVED: + sharp_nhgroup_id_set_installed(id, false); zlog_debug("Removed nhg %u", id); break; case ZAPI_NHG_REMOVE_FAIL: @@ -989,6 +990,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,11 +1095,16 @@ 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, [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner, - [ZEBRA_NEXTHOP_UPDATE] = sharp_nexthop_update, [ZEBRA_NHG_NOTIFY_OWNER] = nhg_notify_owner, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = sharp_redistribute_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = sharp_redistribute_route, @@ -1071,19 +1112,36 @@ 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) { - struct zclient_options opt = {.receive_notify = true}; + hook_register_prio(if_real, 0, sharp_ifp_create); + hook_register_prio(if_up, 0, sharp_ifp_up); + hook_register_prio(if_down, 0, sharp_ifp_down); + hook_register_prio(if_unreal, 0, sharp_ifp_destroy); - if_zapi_callbacks(sharp_ifp_create, sharp_ifp_up, sharp_ifp_down, - sharp_ifp_destroy); - - zclient = zclient_new(master, &opt, sharp_handlers, + zclient = zclient_new(master, &zclient_options_default, sharp_handlers, array_size(sharp_handlers)); zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); zclient->zebra_connected = zebra_connected; zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready; + zclient->nexthop_update = sharp_nexthop_update; +} + +void sharp_zebra_terminate(void) +{ + struct sharp_zclient *node = sharp_clients_head; + + while (node) { + sharp_zclient_delete(node->client->session_id); + + node = sharp_clients_head; + } + + zclient_stop(zclient); + zclient_free(zclient); } diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 025b4d8..5cbcc14 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -8,6 +8,7 @@ #define __SHARP_ZEBRA_H__ extern void sharp_zebra_init(void); +extern void sharp_zebra_terminate(void); /* Add and delete extra zapi client sessions, for testing */ int sharp_zclient_create(uint32_t session_id); @@ -54,7 +55,7 @@ extern void sharp_zebra_send_arp(const struct interface *ifp, /* Register Link State Opaque messages */ extern void sharp_zebra_register_te(void); -extern void sharp_redistribute_vrf(struct vrf *vrf, int source); +extern void sharp_redistribute_vrf(struct vrf *vrf, int source, bool turn_on); extern int sharp_zebra_srv6_manager_get_locator_chunk(const char *lname); extern int sharp_zebra_srv6_manager_release_locator_chunk(const char *lname); @@ -70,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 |