Skip to content

Commit b1dea24

Browse files
committed
zebra: Extend FPM to send missing seg6local info
Zebra’s `dplane_fpm_nl` module allows an external component to learn the forwarding information computed by the FRR routing suite. Currently, the SRv6 Local SIDs exported by the `dplane_fpm_nl` module do not include some information such the SID format (i.e., locator block length, locator node length, function length, and argument length). This commit adds the missing information to the SRv6 Local SIDs exported by the `dplane_fpm_nl`. Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
1 parent 2fbdf88 commit b1dea24

File tree

2 files changed

+282
-0
lines changed

2 files changed

+282
-0
lines changed

lib/nexthop.h

+49
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum blackhole_type {
4444
enum nh_encap_type {
4545
NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
4646
FPM_NH_ENCAP_SRV6_ROUTE = 101,
47+
FPM_NH_ENCAP_SRV6_LOCAL_SID = 102,
4748
};
4849

4950
enum {
@@ -52,6 +53,54 @@ enum {
5253
SRV6_ROUTE_ENCAP_SRC_ADDR = 2,
5354
};
5455

56+
enum srv6_localsid_action {
57+
FPM_SRV6_LOCALSID_ACTION_UNSPEC = 0,
58+
FPM_SRV6_LOCALSID_ACTION_END = 1,
59+
FPM_SRV6_LOCALSID_ACTION_END_X = 2,
60+
FPM_SRV6_LOCALSID_ACTION_END_T = 3,
61+
FPM_SRV6_LOCALSID_ACTION_END_DX2 = 4,
62+
FPM_SRV6_LOCALSID_ACTION_END_DX6 = 5,
63+
FPM_SRV6_LOCALSID_ACTION_END_DX4 = 6,
64+
FPM_SRV6_LOCALSID_ACTION_END_DT6 = 7,
65+
FPM_SRV6_LOCALSID_ACTION_END_DT4 = 8,
66+
FPM_SRV6_LOCALSID_ACTION_END_B6 = 9,
67+
FPM_SRV6_LOCALSID_ACTION_END_B6_ENCAP = 10,
68+
FPM_SRV6_LOCALSID_ACTION_END_BM = 11,
69+
FPM_SRV6_LOCALSID_ACTION_END_S = 12,
70+
FPM_SRV6_LOCALSID_ACTION_END_AS = 13,
71+
FPM_SRV6_LOCALSID_ACTION_END_AM = 14,
72+
FPM_SRV6_LOCALSID_ACTION_END_BPF = 15,
73+
FPM_SRV6_LOCALSID_ACTION_END_DT46 = 16,
74+
FPM_SRV6_LOCALSID_ACTION_UDT4 = 100,
75+
FPM_SRV6_LOCALSID_ACTION_UDT6 = 101,
76+
FPM_SRV6_LOCALSID_ACTION_UDT46 = 102,
77+
FPM_SRV6_LOCALSID_ACTION_MAX,
78+
};
79+
80+
enum {
81+
FPM_SRV6_LOCALSID_UNSPEC = 0,
82+
FPM_SRV6_LOCALSID_ACTION = 1,
83+
FPM_SRV6_LOCALSID_SRH = 2,
84+
FPM_SRV6_LOCALSID_TABLE = 3,
85+
FPM_SRV6_LOCALSID_NH4 = 4,
86+
FPM_SRV6_LOCALSID_NH6 = 5,
87+
FPM_SRV6_LOCALSID_IIF = 6,
88+
FPM_SRV6_LOCALSID_OIF = 7,
89+
FPM_SRV6_LOCALSID_BPF = 8,
90+
FPM_SRV6_LOCALSID_VRFTABLE = 9,
91+
FPM_SRV6_LOCALSID_COUNTERS = 10,
92+
FPM_SRV6_LOCALSID_VRFNAME = 100,
93+
FPM_SRV6_LOCALSID_FORMAT = 101,
94+
};
95+
96+
enum {
97+
FPM_SRV6_LOCALSID_FORMAT_UNSPEC = 0,
98+
FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN = 1,
99+
FPM_SRV6_LOCALSID_FORMAT_NODE_LEN = 2,
100+
FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN = 3,
101+
FPM_SRV6_LOCALSID_FORMAT_ARG_LEN = 4,
102+
};
103+
55104
/* Fixed limit on the number of backup nexthops per primary nexthop */
56105
#define NEXTHOP_MAX_BACKUPS 8
57106

zebra/rt_netlink.c

+233
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,29 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id)
407407
return VRF_DEFAULT;
408408
}
409409

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+
410433
/**
411434
* @parse_encap_mpls() - Parses encapsulated mpls attributes
412435
* @tb: Pointer to rtattr to look for nested items in.
@@ -1675,6 +1698,216 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
16751698
}
16761699

16771700
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+
16781911
if (!sid_zero(&nexthop->nh_srv6->seg6_segs)) {
16791912
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
16801913
struct rtattr *nest;

0 commit comments

Comments
 (0)