summaryrefslogtreecommitdiffstats
path: root/sharpd/sharp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'sharpd/sharp_zebra.c')
-rw-r--r--sharpd/sharp_zebra.c108
1 files changed, 83 insertions, 25 deletions
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);
}