@@ -406,6 +406,29 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id)
406
406
return VRF_DEFAULT ;
407
407
}
408
408
409
+ static struct zebra_vrf * vrf_lookup_by_table_id (uint32_t table_id )
410
+ {
411
+ struct vrf * vrf ;
412
+ struct zebra_vrf * zvrf ;
413
+
414
+ RB_FOREACH (vrf , vrf_id_head , & vrfs_by_id ) {
415
+ zvrf = vrf -> info ;
416
+ if (zvrf == NULL )
417
+ continue ;
418
+ /* case vrf with netns : match the netnsid */
419
+ if (vrf_is_backend_netns ()) {
420
+ return NULL ;
421
+ } else {
422
+ /* VRF is VRF_BACKEND_VRF_LITE */
423
+ if (zvrf -> table_id != table_id )
424
+ continue ;
425
+ return zvrf ;
426
+ }
427
+ }
428
+
429
+ return NULL ;
430
+ }
431
+
409
432
/**
410
433
* @parse_encap_mpls() - Parses encapsulated mpls attributes
411
434
* @tb: Pointer to rtattr to look for nested items in.
@@ -1585,6 +1608,216 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
1585
1608
}
1586
1609
1587
1610
if (fpm && nexthop -> nh_srv6 ) {
1611
+ if (nexthop -> nh_srv6 -> seg6local_action !=
1612
+ ZEBRA_SEG6_LOCAL_ACTION_UNSPEC ) {
1613
+ struct zebra_srv6 * srv6 = zebra_srv6_get_default ();
1614
+ struct zebra_vrf * zvrf ;
1615
+ bool locator_found = false;
1616
+ struct srv6_locator * locator ;
1617
+ struct listnode * node ;
1618
+ struct rtattr * nest , * inner_nest ;
1619
+ const struct seg6local_context * ctx ;
1620
+
1621
+ ctx = & nexthop -> nh_srv6 -> seg6local_ctx ;
1622
+
1623
+ if (!nl_attr_put16 (nlmsg , req_size , RTA_ENCAP_TYPE ,
1624
+ FPM_NH_ENCAP_SRV6_LOCAL_SID ))
1625
+ return false;
1626
+
1627
+ for (ALL_LIST_ELEMENTS_RO (srv6 -> locators , node ,
1628
+ locator )) {
1629
+ if (prefix_match (& locator -> prefix , p )) {
1630
+ locator_found = true;
1631
+ break ;
1632
+ }
1633
+ }
1634
+
1635
+ nest = nl_attr_nest (nlmsg , req_size , RTA_ENCAP );
1636
+
1637
+ /* Process Local SID format */
1638
+ if (locator_found ) {
1639
+ inner_nest =
1640
+ nl_attr_nest (nlmsg , req_size ,
1641
+ FPM_SRV6_LOCALSID_FORMAT );
1642
+
1643
+ if (locator -> block_bits_length )
1644
+ if (!nl_attr_put8 (
1645
+ nlmsg , req_size ,
1646
+ FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN ,
1647
+ locator -> block_bits_length ))
1648
+ return false;
1649
+
1650
+ if (locator -> node_bits_length )
1651
+ if (!nl_attr_put8 (
1652
+ nlmsg , req_size ,
1653
+ FPM_SRV6_LOCALSID_FORMAT_NODE_LEN ,
1654
+ locator -> node_bits_length ))
1655
+ return false;
1656
+
1657
+ if (locator -> function_bits_length )
1658
+ if (!nl_attr_put8 (
1659
+ nlmsg , req_size ,
1660
+ FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN ,
1661
+ locator -> function_bits_length ))
1662
+ return false;
1663
+
1664
+ if (locator -> argument_bits_length )
1665
+ if (!nl_attr_put8 (
1666
+ nlmsg , req_size ,
1667
+ FPM_SRV6_LOCALSID_FORMAT_ARG_LEN ,
1668
+ locator -> argument_bits_length ))
1669
+ return false;
1670
+
1671
+ nl_attr_nest_end (nlmsg , inner_nest );
1672
+ }
1673
+
1674
+ switch (nexthop -> nh_srv6 -> seg6local_action ) {
1675
+ case ZEBRA_SEG6_LOCAL_ACTION_END :
1676
+ if (!nl_attr_put32 (
1677
+ nlmsg , req_size ,
1678
+ FPM_SRV6_LOCALSID_ACTION ,
1679
+ FPM_SRV6_LOCALSID_ACTION_END ))
1680
+ return false;
1681
+
1682
+ break ;
1683
+ case ZEBRA_SEG6_LOCAL_ACTION_END_X :
1684
+ if (!nl_attr_put32 (
1685
+ nlmsg , req_size ,
1686
+ FPM_SRV6_LOCALSID_ACTION ,
1687
+ FPM_SRV6_LOCALSID_ACTION_END_X ))
1688
+ return false;
1689
+
1690
+ if (!nl_attr_put (nlmsg , req_size ,
1691
+ FPM_SRV6_LOCALSID_NH6 ,
1692
+ & ctx -> nh6 ,
1693
+ sizeof (struct in6_addr )))
1694
+ return false;
1695
+ break ;
1696
+ case ZEBRA_SEG6_LOCAL_ACTION_END_T :
1697
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1698
+ if (!zvrf )
1699
+ return false;
1700
+
1701
+ if (!nl_attr_put32 (
1702
+ nlmsg , req_size ,
1703
+ FPM_SRV6_LOCALSID_ACTION ,
1704
+ FPM_SRV6_LOCALSID_ACTION_END_T ))
1705
+ return false;
1706
+
1707
+ if (!nl_attr_put (nlmsg , req_size ,
1708
+ FPM_SRV6_LOCALSID_VRFNAME ,
1709
+ zvrf -> vrf -> name ,
1710
+ strlen (zvrf -> vrf -> name ) + 1 ))
1711
+ return false;
1712
+
1713
+ break ;
1714
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DX4 :
1715
+ if (!nl_attr_put32 (
1716
+ nlmsg , req_size ,
1717
+ FPM_SRV6_LOCALSID_ACTION ,
1718
+ FPM_SRV6_LOCALSID_ACTION_END_DX4 ))
1719
+ return false;
1720
+
1721
+ if (!nl_attr_put (nlmsg , req_size ,
1722
+ FPM_SRV6_LOCALSID_NH4 ,
1723
+ & ctx -> nh4 ,
1724
+ sizeof (struct in_addr )))
1725
+ return false;
1726
+
1727
+ break ;
1728
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT6 :
1729
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1730
+ if (!zvrf )
1731
+ return false;
1732
+
1733
+ if (locator_found &&
1734
+ CHECK_FLAG (locator -> flags ,
1735
+ SRV6_LOCATOR_USID )) {
1736
+ if (!nl_attr_put32 (
1737
+ nlmsg , req_size ,
1738
+ FPM_SRV6_LOCALSID_ACTION ,
1739
+ FPM_SRV6_LOCALSID_ACTION_UDT6 ))
1740
+ return false;
1741
+ } else {
1742
+ if (!nl_attr_put32 (
1743
+ nlmsg , req_size ,
1744
+ FPM_SRV6_LOCALSID_ACTION ,
1745
+ FPM_SRV6_LOCALSID_ACTION_END_DT6 ))
1746
+ return false;
1747
+ }
1748
+
1749
+ if (!nl_attr_put (nlmsg , req_size ,
1750
+ FPM_SRV6_LOCALSID_VRFNAME ,
1751
+ zvrf -> vrf -> name ,
1752
+ strlen (zvrf -> vrf -> name ) + 1 ))
1753
+ return false;
1754
+
1755
+ break ;
1756
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT4 :
1757
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1758
+ if (!zvrf )
1759
+ return false;
1760
+
1761
+ if (locator_found &&
1762
+ CHECK_FLAG (locator -> flags ,
1763
+ SRV6_LOCATOR_USID )) {
1764
+ if (!nl_attr_put32 (
1765
+ nlmsg , req_size ,
1766
+ FPM_SRV6_LOCALSID_ACTION ,
1767
+ FPM_SRV6_LOCALSID_ACTION_UDT4 ))
1768
+ return false;
1769
+ } else {
1770
+ if (!nl_attr_put32 (
1771
+ nlmsg , req_size ,
1772
+ FPM_SRV6_LOCALSID_ACTION ,
1773
+ FPM_SRV6_LOCALSID_ACTION_END_DT4 ))
1774
+ return false;
1775
+ }
1776
+
1777
+ if (!nl_attr_put (nlmsg , req_size ,
1778
+ FPM_SRV6_LOCALSID_VRFNAME ,
1779
+ zvrf -> vrf -> name ,
1780
+ strlen (zvrf -> vrf -> name ) + 1 ))
1781
+ return false;
1782
+
1783
+ break ;
1784
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT46 :
1785
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1786
+ if (!zvrf )
1787
+ return false;
1788
+
1789
+ if (locator_found &&
1790
+ CHECK_FLAG (locator -> flags ,
1791
+ SRV6_LOCATOR_USID )) {
1792
+ if (!nl_attr_put32 (
1793
+ nlmsg , req_size ,
1794
+ FPM_SRV6_LOCALSID_ACTION ,
1795
+ FPM_SRV6_LOCALSID_ACTION_UDT46 ))
1796
+ return false;
1797
+ } else {
1798
+ if (!nl_attr_put32 (
1799
+ nlmsg , req_size ,
1800
+ FPM_SRV6_LOCALSID_ACTION ,
1801
+ FPM_SRV6_LOCALSID_ACTION_END_DT46 ))
1802
+ return false;
1803
+ }
1804
+
1805
+ if (!nl_attr_put (nlmsg , req_size ,
1806
+ FPM_SRV6_LOCALSID_VRFNAME ,
1807
+ zvrf -> vrf -> name ,
1808
+ strlen (zvrf -> vrf -> name ) + 1 ))
1809
+ return false;
1810
+
1811
+ break ;
1812
+ default :
1813
+ zlog_err (
1814
+ "Unsupported seg6local behaviour action=%u" ,
1815
+ nexthop -> nh_srv6 -> seg6local_action );
1816
+ return false;
1817
+ }
1818
+ nl_attr_nest_end (nlmsg , nest );
1819
+ }
1820
+
1588
1821
if (!sid_zero (& nexthop -> nh_srv6 -> seg6_segs )) {
1589
1822
struct zebra_srv6 * srv6 = zebra_srv6_get_default ();
1590
1823
struct rtattr * nest ;
0 commit comments