extern uint32_t total_routes;
extern uint32_t installed_routes;
+extern uint32_t removed_routes;
static int route_notify_owner(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
if (!zapi_route_notify_decode(zclient->ibuf, &p, &table, ¬e))
return -1;
- installed_routes++;
-
- if (total_routes == installed_routes)
- zlog_debug("Installed All Items");
+ switch (note) {
+ case ZAPI_ROUTE_INSTALLED:
+ installed_routes++;
+ if (total_routes == installed_routes)
+ zlog_debug("Installed All Items");
+ break;
+ case ZAPI_ROUTE_FAIL_INSTALL:
+ zlog_debug("Failed install of route");
+ break;
+ case ZAPI_ROUTE_BETTER_ADMIN_WON:
+ zlog_debug("Better Admin Distance won over us");
+ break;
+ case ZAPI_ROUTE_REMOVED:
+ removed_routes++;
+ if (total_routes == removed_routes)
+ zlog_debug("Removed all Items");
+ break;
+ case ZAPI_ROUTE_REMOVE_FAIL:
+ zlog_debug("Route removal Failure");
+ break;
+ }
return 0;
}
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
}
-void route_add(struct prefix *p, struct nexthop *nh)
+void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_SHARP;
+ api.instance = instance;
api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p));
api_nh = &api.nexthops[0];
api_nh->vrf_id = VRF_DEFAULT;
- api_nh->gate.ipv4 = nh->gate.ipv4;
+ api_nh->gate = nh->gate;
api_nh->type = nh->type;
api_nh->ifindex = nh->ifindex;
api.nexthop_num = 1;
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
-void route_delete(struct prefix *p)
+void route_delete(struct prefix *p, uint8_t instance)
{
struct zapi_route api;
api.vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_SHARP;
api.safi = SAFI_UNICAST;
+ api.instance = instance;
memcpy(&api.prefix, p, sizeof(*p));
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
return;
}
+void sharp_zebra_nexthop_watch(struct prefix *p, bool watch)
+{
+ int command = ZEBRA_NEXTHOP_REGISTER;
+
+ if (!watch)
+ command = ZEBRA_NEXTHOP_UNREGISTER;
+
+ if (zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT) < 0)
+ zlog_warn("%s: Failure to send nexthop to zebra",
+ __PRETTY_FUNCTION__);
+}
+
+static int sharp_nexthop_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct zapi_route nhr;
+ char buf[PREFIX_STRLEN];
+ int i;
+
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ zlog_warn("%s: Decode of update failed", __PRETTY_FUNCTION__);
+
+ return 0;
+ }
+
+ zlog_debug("Received update for %s",
+ prefix2str(&nhr.prefix, buf, sizeof(buf)));
+ for (i = 0; i < nhr.nexthop_num; i++) {
+ struct zapi_nexthop *znh = &nhr.nexthops[i];
+
+ switch (znh->type) {
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_IPV4:
+ zlog_debug(
+ "\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ inet_ntop(AF_INET, &znh->gate.ipv4.s_addr, buf,
+ sizeof(buf)),
+ znh->type, znh->ifindex, znh->vrf_id,
+ znh->label_num);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IPV6:
+ zlog_debug(
+ "\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ inet_ntop(AF_INET6, &znh->gate.ipv6, buf,
+ sizeof(buf)),
+ znh->type, znh->ifindex, znh->vrf_id,
+ znh->label_num);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ zlog_debug("\tNexthop IFINDEX: %d, ifindex: %d",
+ znh->type, znh->ifindex);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ zlog_debug("\tNexthop blackhole");
+ break;
+ }
+ }
+ return 0;
+}
+
extern struct zebra_privs_t sharp_privs;
void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
- zclient = zclient_new_notify(master, &opt);
+ zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
zclient->zebra_connected = zebra_connected;
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
+ zclient->nexthop_update = sharp_nexthop_update;
}