Skip to content

Commit 0af0f46

Browse files
committed
isisd: Receive SRv6 SIDs notifications from zebra
Zebra sends a SRV6_SID_NOTIFY notification to inform clients about the result of a SID alloc/release operation. This commit adds a handler to process a SRV6_SID_NOTIFY notification received from zebra. If the notification indicates that a SID allocation operation was successful, then it stores the allocated SID in the SRv6 database, installs the SID into the RIB, and advertises the SID to the other IS-IS routers. If the notification indicates that an operation has failed, it logs the error. Signed-off-by: Carmine Scarpitta <[email protected]>
1 parent 7c203a0 commit 0af0f46

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

isisd/isis_zebra.c

+146
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,151 @@ void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx)
15351535
}
15361536
}
15371537

1538+
static int isis_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
1539+
{
1540+
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
1541+
struct srv6_sid_ctx ctx;
1542+
struct in6_addr sid_addr;
1543+
enum zapi_srv6_sid_notify note;
1544+
uint32_t sid_func;
1545+
struct isis_area *area;
1546+
struct listnode *node, *nnode, *n;
1547+
char buf[256];
1548+
struct srv6_locator *locator;
1549+
struct prefix_ipv6 tmp_prefix;
1550+
struct srv6_adjacency *sra;
1551+
enum srv6_endpoint_behavior_codepoint behavior;
1552+
struct isis_srv6_sid *sid;
1553+
struct isis_adjacency *adj;
1554+
1555+
if (!isis)
1556+
return -1;
1557+
1558+
/* Decode the received notification message */
1559+
if (!zapi_srv6_sid_notify_decode(zclient->ibuf, &ctx, &sid_addr,
1560+
&sid_func, NULL, &note)) {
1561+
zlog_err("%s : error in msg decode", __func__);
1562+
return -1;
1563+
}
1564+
1565+
sr_debug("%s: received SRv6 SID notify: ctx %s sid_value %pI6 sid_func %u note %s",
1566+
__func__, srv6_sid_ctx2str(buf, sizeof(buf), &ctx), &sid_addr,
1567+
sid_func, zapi_srv6_sid_notify2str(note));
1568+
1569+
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1570+
if (!area->srv6db.config.enabled || !area->srv6db.srv6_locator)
1571+
continue;
1572+
1573+
locator = area->srv6db.srv6_locator;
1574+
1575+
/* Verify that the received SID belongs to the configured locator */
1576+
if (note == ZAPI_SRV6_SID_ALLOCATED) {
1577+
tmp_prefix.family = AF_INET6;
1578+
tmp_prefix.prefixlen = IPV6_MAX_BITLEN;
1579+
tmp_prefix.prefix = sid_addr;
1580+
1581+
if (!prefix_match((struct prefix *)&locator->prefix,
1582+
(struct prefix *)&tmp_prefix)) {
1583+
sr_debug("%s : ignoring SRv6 SID notify: locator (area %s) does not match",
1584+
__func__, area->area_tag);
1585+
continue;
1586+
}
1587+
}
1588+
1589+
/* Handle notification */
1590+
switch (note) {
1591+
case ZAPI_SRV6_SID_ALLOCATED:
1592+
sr_debug("SRv6 SID %pI6 %s ALLOCATED", &sid_addr,
1593+
srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
1594+
1595+
if (ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END) {
1596+
/* Remove old End SIDs, if any */
1597+
for (ALL_LIST_ELEMENTS(area->srv6db.srv6_sids,
1598+
node, nnode, sid)) {
1599+
isis_zebra_srv6_sid_uninstall(area, sid);
1600+
listnode_delete(area->srv6db.srv6_sids,
1601+
sid);
1602+
}
1603+
1604+
/* Allocate new SRv6 End SID */
1605+
behavior =
1606+
(CHECK_FLAG(locator->flags,
1607+
SRV6_LOCATOR_USID))
1608+
? SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID
1609+
: SRV6_ENDPOINT_BEHAVIOR_END;
1610+
sid = isis_srv6_sid_alloc(area,
1611+
area->srv6db
1612+
.srv6_locator,
1613+
behavior, &sid_addr);
1614+
if (!sid) {
1615+
zlog_warn("%s: isis_srv6_sid_alloc failed",
1616+
__func__);
1617+
return -1;
1618+
}
1619+
1620+
/*
1621+
* Install the new SRv6 End SID in the forwarding plane through
1622+
* Zebra
1623+
*/
1624+
isis_zebra_srv6_sid_install(area, sid);
1625+
1626+
/* Store the SID */
1627+
listnode_add(area->srv6db.srv6_sids, sid);
1628+
1629+
} else if (ctx.behavior ==
1630+
ZEBRA_SEG6_LOCAL_ACTION_END_X) {
1631+
for (ALL_LIST_ELEMENTS_RO(area->adjacency_list,
1632+
n, adj)) {
1633+
/* Check if the End.X SID is for this adjacecny */
1634+
if (adj->ll_ipv6_count == 0 ||
1635+
memcmp(&adj->ll_ipv6_addrs[0],
1636+
&ctx.nh6,
1637+
sizeof(struct in6_addr)) != 0)
1638+
continue;
1639+
1640+
/* Remove old End.X SIDs, if any */
1641+
for (ALL_LIST_ELEMENTS(adj->srv6_endx_sids,
1642+
node, nnode, sra))
1643+
srv6_endx_sid_del(sra);
1644+
1645+
/* Allocate new End.X SID for the adjacency */
1646+
srv6_endx_sid_add_single(adj, false,
1647+
NULL,
1648+
&sid_addr);
1649+
}
1650+
} else {
1651+
zlog_warn("%s: unsupported behavior %u",
1652+
__func__, ctx.behavior);
1653+
return -1;
1654+
}
1655+
break;
1656+
case ZAPI_SRV6_SID_RELEASED:
1657+
sr_debug("SRv6 SID %pI6 %s: RELEASED", &sid_addr,
1658+
srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
1659+
break;
1660+
case ZAPI_SRV6_SID_FAIL_ALLOC:
1661+
sr_debug("SRv6 SID %pI6 %s: Failed to allocate",
1662+
&sid_addr,
1663+
srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
1664+
1665+
/* Error will be logged by zebra module */
1666+
break;
1667+
case ZAPI_SRV6_SID_FAIL_RELEASE:
1668+
zlog_warn("%s: SRv6 SID %pI6 %s failure to release",
1669+
__func__, &sid_addr,
1670+
srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
1671+
1672+
/* Error will be logged by zebra module */
1673+
break;
1674+
}
1675+
1676+
/* Regenerate LSPs to advertise the new locator and the SID */
1677+
lsp_regenerate_schedule(area, area->is_type, 0);
1678+
}
1679+
1680+
return 0;
1681+
}
1682+
15381683
static zclient_handler *const isis_handlers[] = {
15391684
[ZEBRA_ROUTER_ID_UPDATE] = isis_router_id_update_zebra,
15401685
[ZEBRA_INTERFACE_ADDRESS_ADD] = isis_zebra_if_address_add,
@@ -1551,6 +1696,7 @@ static zclient_handler *const isis_handlers[] = {
15511696
isis_zebra_process_srv6_locator_chunk,
15521697
[ZEBRA_SRV6_LOCATOR_ADD] = isis_zebra_process_srv6_locator_add,
15531698
[ZEBRA_SRV6_LOCATOR_DELETE] = isis_zebra_process_srv6_locator_delete,
1699+
[ZEBRA_SRV6_SID_NOTIFY] = isis_zebra_srv6_sid_notify,
15541700
};
15551701

15561702
void isis_zebra_init(struct event_loop *master, int instance)

0 commit comments

Comments
 (0)