@@ -1535,6 +1535,151 @@ void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx)
1535
1535
}
1536
1536
}
1537
1537
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
+
1538
1683
static zclient_handler * const isis_handlers [] = {
1539
1684
[ZEBRA_ROUTER_ID_UPDATE ] = isis_router_id_update_zebra ,
1540
1685
[ZEBRA_INTERFACE_ADDRESS_ADD ] = isis_zebra_if_address_add ,
@@ -1551,6 +1696,7 @@ static zclient_handler *const isis_handlers[] = {
1551
1696
isis_zebra_process_srv6_locator_chunk ,
1552
1697
[ZEBRA_SRV6_LOCATOR_ADD ] = isis_zebra_process_srv6_locator_add ,
1553
1698
[ZEBRA_SRV6_LOCATOR_DELETE ] = isis_zebra_process_srv6_locator_delete ,
1699
+ [ZEBRA_SRV6_SID_NOTIFY ] = isis_zebra_srv6_sid_notify ,
1554
1700
};
1555
1701
1556
1702
void isis_zebra_init (struct event_loop * master , int instance )
0 commit comments