Skip to content

Commit 84d8e94

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 f5ccb41 commit 84d8e94

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
@@ -59,6 +59,7 @@ enum blackhole_type {
5959
enum nh_encap_type {
6060
NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
6161
FPM_NH_ENCAP_SRV6_ROUTE = 101,
62+
FPM_NH_ENCAP_SRV6_LOCAL_SID = 102,
6263
};
6364

6465
enum {
@@ -67,6 +68,54 @@ enum {
6768
SRV6_ROUTE_ENCAP_SRC_ADDR = 2,
6869
};
6970

71+
enum srv6_localsid_action {
72+
FPM_SRV6_LOCALSID_ACTION_UNSPEC = 0,
73+
FPM_SRV6_LOCALSID_ACTION_END = 1,
74+
FPM_SRV6_LOCALSID_ACTION_END_X = 2,
75+
FPM_SRV6_LOCALSID_ACTION_END_T = 3,
76+
FPM_SRV6_LOCALSID_ACTION_END_DX2 = 4,
77+
FPM_SRV6_LOCALSID_ACTION_END_DX6 = 5,
78+
FPM_SRV6_LOCALSID_ACTION_END_DX4 = 6,
79+
FPM_SRV6_LOCALSID_ACTION_END_DT6 = 7,
80+
FPM_SRV6_LOCALSID_ACTION_END_DT4 = 8,
81+
FPM_SRV6_LOCALSID_ACTION_END_B6 = 9,
82+
FPM_SRV6_LOCALSID_ACTION_END_B6_ENCAP = 10,
83+
FPM_SRV6_LOCALSID_ACTION_END_BM = 11,
84+
FPM_SRV6_LOCALSID_ACTION_END_S = 12,
85+
FPM_SRV6_LOCALSID_ACTION_END_AS = 13,
86+
FPM_SRV6_LOCALSID_ACTION_END_AM = 14,
87+
FPM_SRV6_LOCALSID_ACTION_END_BPF = 15,
88+
FPM_SRV6_LOCALSID_ACTION_END_DT46 = 16,
89+
FPM_SRV6_LOCALSID_ACTION_UDT4 = 100,
90+
FPM_SRV6_LOCALSID_ACTION_UDT6 = 101,
91+
FPM_SRV6_LOCALSID_ACTION_UDT46 = 102,
92+
FPM_SRV6_LOCALSID_ACTION_MAX,
93+
};
94+
95+
enum {
96+
FPM_SRV6_LOCALSID_UNSPEC = 0,
97+
FPM_SRV6_LOCALSID_ACTION = 1,
98+
FPM_SRV6_LOCALSID_SRH = 2,
99+
FPM_SRV6_LOCALSID_TABLE = 3,
100+
FPM_SRV6_LOCALSID_NH4 = 4,
101+
FPM_SRV6_LOCALSID_NH6 = 5,
102+
FPM_SRV6_LOCALSID_IIF = 6,
103+
FPM_SRV6_LOCALSID_OIF = 7,
104+
FPM_SRV6_LOCALSID_BPF = 8,
105+
FPM_SRV6_LOCALSID_VRFTABLE = 9,
106+
FPM_SRV6_LOCALSID_COUNTERS = 10,
107+
FPM_SRV6_LOCALSID_VRFNAME = 100,
108+
FPM_SRV6_LOCALSID_FORMAT = 101,
109+
};
110+
111+
enum {
112+
FPM_SRV6_LOCALSID_FORMAT_UNSPEC = 0,
113+
FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN = 1,
114+
FPM_SRV6_LOCALSID_FORMAT_NODE_LEN = 2,
115+
FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN = 3,
116+
FPM_SRV6_LOCALSID_FORMAT_ARG_LEN = 4,
117+
};
118+
70119
/* Fixed limit on the number of backup nexthops per primary nexthop */
71120
#define NEXTHOP_MAX_BACKUPS 8
72121

zebra/rt_netlink.c

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

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

15871610
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+
15881821
if (!sid_zero(&nexthop->nh_srv6->seg6_segs)) {
15891822
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
15901823
struct rtattr *nest;

0 commit comments

Comments
 (0)