#include "zclient.h"
#include "nexthop.h"
#include "nexthop_group.h"
+#include "link_state.h"
#include "sharp_globals.h"
#include "sharp_nht.h"
vrf_id_t vrf_id;
uint8_t instance;
uint32_t nhgid;
+ uint32_t flags;
const struct nexthop_group *nhg;
const struct nexthop_group *backup_nhg;
enum where_to_restart restart;
*/
static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance,
uint32_t nhgid, const struct nexthop_group *nhg,
- const struct nexthop_group *backup_nhg, char *opaque)
+ const struct nexthop_group *backup_nhg, uint32_t flags,
+ char *opaque)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p));
+ api.flags = flags;
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
uint32_t nhgid,
const struct nexthop_group *nhg,
const struct nexthop_group *backup_nhg,
- uint32_t routes, char *opaque)
+ uint32_t routes, uint32_t flags,
+ char *opaque)
{
uint32_t temp, i;
bool v4 = false;
for (i = count; i < routes; i++) {
bool buffered = route_add(p, vrf_id, (uint8_t)instance, nhgid,
- nhg, backup_nhg, opaque);
+ nhg, backup_nhg, flags, opaque);
if (v4)
p->u.prefix4.s_addr = htonl(++temp);
else
wb.instance = instance;
wb.nhgid = nhgid;
wb.nhg = nhg;
+ wb.flags = flags;
wb.backup_nhg = backup_nhg;
wb.opaque = opaque;
wb.restart = SHARP_INSTALL_ROUTES_RESTART;
uint8_t instance, uint32_t nhgid,
const struct nexthop_group *nhg,
const struct nexthop_group *backup_nhg,
- uint32_t routes, char *opaque)
+ uint32_t routes, uint32_t flags, char *opaque)
{
zlog_debug("Inserting %u routes", routes);
monotime(&sg.r.t_start);
sharp_install_routes_restart(p, 0, vrf_id, instance, nhgid, nhg,
- backup_nhg, routes, opaque);
+ backup_nhg, routes, flags, opaque);
}
static void sharp_remove_routes_restart(struct prefix *p, uint32_t count,
sharp_install_routes_helper(&p, sg.r.vrf_id, sg.r.inst,
sg.r.nhgid, &sg.r.nhop_group,
&sg.r.backup_nhop_group,
- sg.r.total_routes, sg.r.opaque);
+ sg.r.total_routes, sg.r.flags,
+ sg.r.opaque);
}
}
case SHARP_INSTALL_ROUTES_RESTART:
sharp_install_routes_restart(
&wb.p, wb.count, wb.vrf_id, wb.instance, wb.nhgid,
- wb.nhg, wb.backup_nhg, wb.routes, wb.opaque);
+ wb.nhg, wb.backup_nhg, wb.routes, wb.flags,
+ wb.opaque);
return;
case SHARP_DELETE_ROUTES_RESTART:
sharp_remove_routes_restart(&wb.p, wb.count, wb.vrf_id,
static int sharp_debug_nexthops(struct zapi_route *api)
{
int i;
- char buf[PREFIX_STRLEN];
if (api->nexthop_num == 0) {
zlog_debug(
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
zlog_debug(
- " Nexthop %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);
+ " Nexthop %pI4, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ &znh->gate.ipv4.s_addr, znh->type, znh->ifindex,
+ znh->vrf_id, znh->label_num);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6:
zlog_debug(
- " Nexthop %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);
+ " Nexthop %pI6, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ &znh->gate.ipv6, znh->type, znh->ifindex,
+ znh->vrf_id, znh->label_num);
break;
case NEXTHOP_TYPE_IFINDEX:
zlog_debug(" Nexthop IFINDEX: %d, ifindex: %d",
return 0;
}
- zlog_debug("Received update for %pFX", &nhr.prefix);
+ zlog_debug("Received update for %pFX metric: %u", &nhr.prefix,
+ nhr.metric);
nht = sharp_nh_tracker_get(&nhr.prefix);
nht->nhop_num = nhr.nexthop_num;
return 0;
}
+void sharp_redistribute_vrf(struct vrf *vrf, int type)
+{
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
+ 0, vrf->vrf_id);
+}
+
/* Add a zclient with a specified session id, for testing. */
int sharp_zclient_create(uint32_t session_id)
{
return 0;
}
+static const char *const type2txt[] = { "Generic", "Vertex", "Edge", "Subnet" };
+static const char *const status2txt[] = { "Unknown", "New", "Update",
+ "Delete", "Sync", "Orphan"};
/* Handler for opaque messages */
static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS)
{
struct stream *s;
struct zapi_opaque_msg info;
+ struct ls_element *lse;
s = zclient->ibuf;
zlog_debug("%s: [%u] received opaque type %u", __func__,
zclient->session_id, info.type);
+ if (info.type == LINK_STATE_UPDATE) {
+ lse = ls_stream2ted(sg.ted, s, false);
+ if (lse)
+ zlog_debug(" |- Got %s %s from Link State Database",
+ status2txt[lse->status],
+ type2txt[lse->type]);
+ else
+ zlog_debug(
+ "%s: Error to convert Stream into Link State",
+ __func__);
+ }
+
return 0;
}
}
+/* Link State registration */
+void sharp_zebra_register_te(void)
+{
+ /* First register to received Link State Update messages */
+ zclient_register_opaque(zclient, LINK_STATE_UPDATE);
+
+ /* Then, request initial TED with SYNC message */
+ ls_request_sync(zclient);
+}
+
void sharp_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
{
zclient_send_neigh_discovery_req(zclient, ifp, p);
return 0;
}
+int sharp_zebra_srv6_manager_get_locator_chunk(const char *locator_name)
+{
+ return srv6_manager_get_locator_chunk(zclient, locator_name);
+}
+
+int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name)
+{
+ return srv6_manager_release_locator_chunk(zclient, locator_name);
+}
+
+static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
+{
+ struct stream *s = NULL;
+ struct srv6_locator_chunk s6c = {};
+ struct listnode *node, *nnode;
+ struct sharp_srv6_locator *loc;
+
+ s = zclient->ibuf;
+ zapi_srv6_locator_chunk_decode(s, &s6c);
+
+ for (ALL_LIST_ELEMENTS(sg.srv6_locators, node, nnode, loc)) {
+ struct prefix_ipv6 *chunk = NULL;
+ struct listnode *chunk_node;
+ struct prefix_ipv6 *c;
+
+ if (strcmp(loc->name, s6c.locator_name) != 0) {
+ zlog_err("%s: Locator name unmatch %s:%s", __func__,
+ loc->name, s6c.locator_name);
+ continue;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, c))
+ if (!prefix_cmp(c, &s6c.prefix))
+ return;
+
+ chunk = prefix_ipv6_new();
+ *chunk = s6c.prefix;
+ listnode_add(loc->chunks, chunk);
+ return;
+ }
+
+ zlog_err("%s: can't get locator_chunk!!", __func__);
+}
+
void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
zclient->redistribute_route_add = sharp_redistribute_route;
zclient->redistribute_route_del = sharp_redistribute_route;
zclient->opaque_msg_handler = sharp_opaque_handler;
+ zclient->process_srv6_locator_chunk =
+ sharp_zebra_process_srv6_locator_chunk;
}