@@ -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+
15381683static 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
15561702void isis_zebra_init (struct event_loop * master , int instance )
0 commit comments