@@ -407,6 +407,29 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id)
407
407
return VRF_DEFAULT ;
408
408
}
409
409
410
+ static struct zebra_vrf * vrf_lookup_by_table_id (uint32_t table_id )
411
+ {
412
+ struct vrf * vrf ;
413
+ struct zebra_vrf * zvrf ;
414
+
415
+ RB_FOREACH (vrf , vrf_id_head , & vrfs_by_id ) {
416
+ zvrf = vrf -> info ;
417
+ if (zvrf == NULL )
418
+ continue ;
419
+ /* case vrf with netns : match the netnsid */
420
+ if (vrf_is_backend_netns ()) {
421
+ return NULL ;
422
+ } else {
423
+ /* VRF is VRF_BACKEND_VRF_LITE */
424
+ if (zvrf -> table_id != table_id )
425
+ continue ;
426
+ return zvrf ;
427
+ }
428
+ }
429
+
430
+ return NULL ;
431
+ }
432
+
410
433
/**
411
434
* @parse_encap_mpls() - Parses encapsulated mpls attributes
412
435
* @tb: Pointer to rtattr to look for nested items in.
@@ -1675,6 +1698,216 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
1675
1698
}
1676
1699
1677
1700
if (fpm && nexthop -> nh_srv6 ) {
1701
+ if (nexthop -> nh_srv6 -> seg6local_action !=
1702
+ ZEBRA_SEG6_LOCAL_ACTION_UNSPEC ) {
1703
+ struct zebra_srv6 * srv6 = zebra_srv6_get_default ();
1704
+ struct zebra_vrf * zvrf ;
1705
+ bool locator_found = false;
1706
+ struct srv6_locator * locator ;
1707
+ struct listnode * node ;
1708
+ struct rtattr * nest , * inner_nest ;
1709
+ const struct seg6local_context * ctx ;
1710
+
1711
+ ctx = & nexthop -> nh_srv6 -> seg6local_ctx ;
1712
+
1713
+ if (!nl_attr_put16 (nlmsg , req_size , RTA_ENCAP_TYPE ,
1714
+ FPM_NH_ENCAP_SRV6_LOCAL_SID ))
1715
+ return false;
1716
+
1717
+ for (ALL_LIST_ELEMENTS_RO (srv6 -> locators , node ,
1718
+ locator )) {
1719
+ if (prefix_match (& locator -> prefix , p )) {
1720
+ locator_found = true;
1721
+ break ;
1722
+ }
1723
+ }
1724
+
1725
+ nest = nl_attr_nest (nlmsg , req_size , RTA_ENCAP );
1726
+
1727
+ /* Process Local SID format */
1728
+ if (locator_found ) {
1729
+ inner_nest =
1730
+ nl_attr_nest (nlmsg , req_size ,
1731
+ FPM_SRV6_LOCALSID_FORMAT );
1732
+
1733
+ if (locator -> block_bits_length )
1734
+ if (!nl_attr_put8 (
1735
+ nlmsg , req_size ,
1736
+ FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN ,
1737
+ locator -> block_bits_length ))
1738
+ return false;
1739
+
1740
+ if (locator -> node_bits_length )
1741
+ if (!nl_attr_put8 (
1742
+ nlmsg , req_size ,
1743
+ FPM_SRV6_LOCALSID_FORMAT_NODE_LEN ,
1744
+ locator -> node_bits_length ))
1745
+ return false;
1746
+
1747
+ if (locator -> function_bits_length )
1748
+ if (!nl_attr_put8 (
1749
+ nlmsg , req_size ,
1750
+ FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN ,
1751
+ locator -> function_bits_length ))
1752
+ return false;
1753
+
1754
+ if (locator -> argument_bits_length )
1755
+ if (!nl_attr_put8 (
1756
+ nlmsg , req_size ,
1757
+ FPM_SRV6_LOCALSID_FORMAT_ARG_LEN ,
1758
+ locator -> argument_bits_length ))
1759
+ return false;
1760
+
1761
+ nl_attr_nest_end (nlmsg , inner_nest );
1762
+ }
1763
+
1764
+ switch (nexthop -> nh_srv6 -> seg6local_action ) {
1765
+ case ZEBRA_SEG6_LOCAL_ACTION_END :
1766
+ if (!nl_attr_put32 (
1767
+ nlmsg , req_size ,
1768
+ FPM_SRV6_LOCALSID_ACTION ,
1769
+ FPM_SRV6_LOCALSID_ACTION_END ))
1770
+ return false;
1771
+
1772
+ break ;
1773
+ case ZEBRA_SEG6_LOCAL_ACTION_END_X :
1774
+ if (!nl_attr_put32 (
1775
+ nlmsg , req_size ,
1776
+ FPM_SRV6_LOCALSID_ACTION ,
1777
+ FPM_SRV6_LOCALSID_ACTION_END_X ))
1778
+ return false;
1779
+
1780
+ if (!nl_attr_put (nlmsg , req_size ,
1781
+ FPM_SRV6_LOCALSID_NH6 ,
1782
+ & ctx -> nh6 ,
1783
+ sizeof (struct in6_addr )))
1784
+ return false;
1785
+ break ;
1786
+ case ZEBRA_SEG6_LOCAL_ACTION_END_T :
1787
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1788
+ if (!zvrf )
1789
+ return false;
1790
+
1791
+ if (!nl_attr_put32 (
1792
+ nlmsg , req_size ,
1793
+ FPM_SRV6_LOCALSID_ACTION ,
1794
+ FPM_SRV6_LOCALSID_ACTION_END_T ))
1795
+ return false;
1796
+
1797
+ if (!nl_attr_put (nlmsg , req_size ,
1798
+ FPM_SRV6_LOCALSID_VRFNAME ,
1799
+ zvrf -> vrf -> name ,
1800
+ strlen (zvrf -> vrf -> name ) + 1 ))
1801
+ return false;
1802
+
1803
+ break ;
1804
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DX4 :
1805
+ if (!nl_attr_put32 (
1806
+ nlmsg , req_size ,
1807
+ FPM_SRV6_LOCALSID_ACTION ,
1808
+ FPM_SRV6_LOCALSID_ACTION_END_DX4 ))
1809
+ return false;
1810
+
1811
+ if (!nl_attr_put (nlmsg , req_size ,
1812
+ FPM_SRV6_LOCALSID_NH4 ,
1813
+ & ctx -> nh4 ,
1814
+ sizeof (struct in_addr )))
1815
+ return false;
1816
+
1817
+ break ;
1818
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT6 :
1819
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1820
+ if (!zvrf )
1821
+ return false;
1822
+
1823
+ if (locator_found &&
1824
+ CHECK_FLAG (locator -> flags ,
1825
+ SRV6_LOCATOR_USID )) {
1826
+ if (!nl_attr_put32 (
1827
+ nlmsg , req_size ,
1828
+ FPM_SRV6_LOCALSID_ACTION ,
1829
+ FPM_SRV6_LOCALSID_ACTION_UDT6 ))
1830
+ return false;
1831
+ } else {
1832
+ if (!nl_attr_put32 (
1833
+ nlmsg , req_size ,
1834
+ FPM_SRV6_LOCALSID_ACTION ,
1835
+ FPM_SRV6_LOCALSID_ACTION_END_DT6 ))
1836
+ return false;
1837
+ }
1838
+
1839
+ if (!nl_attr_put (nlmsg , req_size ,
1840
+ FPM_SRV6_LOCALSID_VRFNAME ,
1841
+ zvrf -> vrf -> name ,
1842
+ strlen (zvrf -> vrf -> name ) + 1 ))
1843
+ return false;
1844
+
1845
+ break ;
1846
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT4 :
1847
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1848
+ if (!zvrf )
1849
+ return false;
1850
+
1851
+ if (locator_found &&
1852
+ CHECK_FLAG (locator -> flags ,
1853
+ SRV6_LOCATOR_USID )) {
1854
+ if (!nl_attr_put32 (
1855
+ nlmsg , req_size ,
1856
+ FPM_SRV6_LOCALSID_ACTION ,
1857
+ FPM_SRV6_LOCALSID_ACTION_UDT4 ))
1858
+ return false;
1859
+ } else {
1860
+ if (!nl_attr_put32 (
1861
+ nlmsg , req_size ,
1862
+ FPM_SRV6_LOCALSID_ACTION ,
1863
+ FPM_SRV6_LOCALSID_ACTION_END_DT4 ))
1864
+ return false;
1865
+ }
1866
+
1867
+ if (!nl_attr_put (nlmsg , req_size ,
1868
+ FPM_SRV6_LOCALSID_VRFNAME ,
1869
+ zvrf -> vrf -> name ,
1870
+ strlen (zvrf -> vrf -> name ) + 1 ))
1871
+ return false;
1872
+
1873
+ break ;
1874
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DT46 :
1875
+ zvrf = vrf_lookup_by_table_id (ctx -> table );
1876
+ if (!zvrf )
1877
+ return false;
1878
+
1879
+ if (locator_found &&
1880
+ CHECK_FLAG (locator -> flags ,
1881
+ SRV6_LOCATOR_USID )) {
1882
+ if (!nl_attr_put32 (
1883
+ nlmsg , req_size ,
1884
+ FPM_SRV6_LOCALSID_ACTION ,
1885
+ FPM_SRV6_LOCALSID_ACTION_UDT46 ))
1886
+ return false;
1887
+ } else {
1888
+ if (!nl_attr_put32 (
1889
+ nlmsg , req_size ,
1890
+ FPM_SRV6_LOCALSID_ACTION ,
1891
+ FPM_SRV6_LOCALSID_ACTION_END_DT46 ))
1892
+ return false;
1893
+ }
1894
+
1895
+ if (!nl_attr_put (nlmsg , req_size ,
1896
+ FPM_SRV6_LOCALSID_VRFNAME ,
1897
+ zvrf -> vrf -> name ,
1898
+ strlen (zvrf -> vrf -> name ) + 1 ))
1899
+ return false;
1900
+
1901
+ break ;
1902
+ default :
1903
+ zlog_err (
1904
+ "Unsupported seg6local behaviour action=%u" ,
1905
+ nexthop -> nh_srv6 -> seg6local_action );
1906
+ return false;
1907
+ }
1908
+ nl_attr_nest_end (nlmsg , nest );
1909
+ }
1910
+
1678
1911
if (!sid_zero (& nexthop -> nh_srv6 -> seg6_segs )) {
1679
1912
struct zebra_srv6 * srv6 = zebra_srv6_get_default ();
1680
1913
struct rtattr * nest ;
0 commit comments