summaryrefslogtreecommitdiffstats
path: root/sharpd
diff options
context:
space:
mode:
Diffstat (limited to 'sharpd')
-rw-r--r--sharpd/sharp_logpump.c1
-rw-r--r--sharpd/sharp_main.c50
-rw-r--r--sharpd/sharp_nht.c8
-rw-r--r--sharpd/sharp_nht.h1
-rw-r--r--sharpd/sharp_vty.c32
-rw-r--r--sharpd/sharp_zebra.c108
-rw-r--r--sharpd/sharp_zebra.h5
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