extern uint32_t installed_routes;
extern uint32_t removed_routes;
+DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
+ "sharp watch nexthop X:X::X:X$nhop",
+ "Sharp routing Protocol\n"
+ "Watch for changes\n"
+ "Watch for nexthop changes\n"
+ "The v6 nexthop to signal for watching\n")
+{
+ struct prefix p;
+
+ memset(&p, 0, sizeof(p));
+
+ p.prefixlen = 128;
+ memcpy(&p.u.prefix6, &nhop, 16);
+ p.family = AF_INET6;
+
+ sharp_zebra_nexthop_watch(&p, true);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
+ "sharp watch nexthop A.B.C.D$nhop",
+ "Sharp routing Protocol\n"
+ "Watch for changes\n"
+ "Watch for nexthop changes\n"
+ "The v4 nexthop to signal for watching\n")
+{
+ struct prefix p;
+
+ memset(&p, 0, sizeof(p));
+
+ p.prefixlen = 32;
+ p.u.prefix4 = nhop;
+ p.family = AF_INET;
+
+ sharp_zebra_nexthop_watch(&p, true);
+
+ return CMD_SUCCESS;
+}
+
DEFPY (install_routes,
install_routes_cmd,
"sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes",
install_element(ENABLE_NODE, &install_routes_cmd);
install_element(ENABLE_NODE, &remove_routes_cmd);
install_element(ENABLE_NODE, &vrf_label_cmd);
+ install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
+ install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
return;
}
return;
}
+void sharp_zebra_nexthop_watch(struct prefix *p, bool watch)
+{
+ int command = ZEBRA_NEXTHOP_REGISTER;
+
+ if (!watch)
+ command = ZEBRA_NEXTHOP_UNREGISTER;
+
+ zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT);
+}
+
+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)
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;
}