Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isisd: Add Link State Traffic Engineering support #9938

Merged
merged 5 commits into from
Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions doc/user/isisd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ Traffic Engineering

.. note::

IS-IS-TE supports RFC 5305 (base TE), RFC 6119 (IPv6) and RFC 7810 / 8570
(Extended Metric) with or without Multi-Topology. All Traffic Engineering
information are stored in a database formally named TED. However, best
acccuracy is provided without Multi-Topology due to inconsistency of Traffic
Engineering Advertisement of 3rd party commercial routers when MT is enabled.
At this time, FRR offers partial support for some of the routing protocol
extensions that can be used with MPLS-TE. FRR does not currently support a
complete RSVP-TE solution.
Expand All @@ -330,6 +335,15 @@ Traffic Engineering

Configure stable IP address for MPLS-TE.

.. clicmd:: mpls-te router-address ipv6 <X:X::X:X>

Configure stable IPv6 address for MPLS-TE.

.. clicmd:: mpls-te export

Export Traffic Engineering DataBase to other daemons through the ZAPI
Opaque Link State messages.

.. clicmd:: show isis mpls-te interface

.. clicmd:: show isis mpls-te interface INTERFACE
Expand All @@ -340,6 +354,16 @@ Traffic Engineering

Show Traffic Engineering router parameters.

.. clicmd:: show isis [vrf <NAME|all>] mpls-te database [detail|json]

.. clicmd:: show isis [vrf <NAME|all>] mpls-te database vertex [WORD] [detail|json]

.. clicmd:: show isis [vrf <NAME|all>] mpls-te database edge [A.B.C.D|X:X::X:X] [detail|json]

.. clicmd:: show isis [vrf <NAME|all>] mpls-te database subnet [A.B.C.D/M|X:X::X:X/M] [detail|json]

Show Traffic Engineering Database

.. seealso::

:ref:`ospf-traffic-engineering`
Expand Down Expand Up @@ -445,6 +469,10 @@ Debugging ISIS

Update related packets.

.. clicmd:: debug isis te-events

IS-IS Traffic Engineering events

.. clicmd:: debug isis sr-events


Expand Down
23 changes: 16 additions & 7 deletions isisd/isis_adjacency.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void isis_delete_adj(void *arg)

XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ll_ipv6_addrs);

adj_mt_finish(adj);
list_delete(&adj->adj_sids);
Expand Down Expand Up @@ -414,11 +414,11 @@ void isis_adj_print(struct isis_adjacency *adj)
zlog_debug("%pI4", &adj->ipv4_addresses[i]);
}

if (adj->ipv6_address_count) {
if (adj->ll_ipv6_count) {
zlog_debug("IPv6 Address(es):");
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) {
char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &adj->ipv6_addresses[i], buf,
inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i], buf,
sizeof(buf));
zlog_debug("%s", buf);
}
Expand Down Expand Up @@ -577,12 +577,21 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
vty_out(vty, " %pI4\n",
&adj->ipv4_addresses[i]);
}
if (adj->ipv6_address_count) {
if (adj->ll_ipv6_count) {
vty_out(vty, " IPv6 Address(es):\n");
for (unsigned int i = 0; i < adj->ipv6_address_count;
for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) {
char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i],
buf, sizeof(buf));
vty_out(vty, " %s\n", buf);
}
}
if (adj->global_ipv6_count) {
vty_out(vty, " Global IPv6 Address(es):\n");
for (unsigned int i = 0; i < adj->global_ipv6_count;
i++) {
char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &adj->ipv6_addresses[i],
inet_ntop(AF_INET6, &adj->global_ipv6_addrs[i],
buf, sizeof(buf));
vty_out(vty, " %s\n", buf);
}
Expand Down
12 changes: 8 additions & 4 deletions isisd/isis_adjacency.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ struct isis_adjacency {
struct in_addr *ipv4_addresses;
unsigned int ipv4_address_count;
struct in_addr router_address;
struct in6_addr *ipv6_addresses;
unsigned int ipv6_address_count;
struct in6_addr *ll_ipv6_addrs; /* Link local IPv6 neighbor address */
unsigned int ll_ipv6_count;
struct in6_addr *global_ipv6_addrs; /* Global IPv6 neighbor address */
unsigned int global_ipv6_count;
struct in6_addr router_address6;
uint8_t prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
int circuit_t; /* from hello PDU hdr */
Expand Down Expand Up @@ -127,9 +129,11 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
enum isis_adj_usage adj_usage);
DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj));
DECLARE_HOOK(isis_adj_ip_enabled_hook,
(struct isis_adjacency *adj, int family), (adj, family));
(struct isis_adjacency * adj, int family, bool global),
(adj, family, global));
DECLARE_HOOK(isis_adj_ip_disabled_hook,
(struct isis_adjacency *adj, int family), (adj, family));
(struct isis_adjacency * adj, int family, bool global),
(adj, family, global));
void isis_log_adj_change(struct isis_adjacency *adj,
enum isis_adj_state old_state,
enum isis_adj_state new_state, const char *reason);
Expand Down
11 changes: 6 additions & 5 deletions isisd/isis_bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj)
*/
if (circuit->ipv6_router
&& (listcount(circuit->ipv6_link) == 0
|| adj->ipv6_address_count == 0)) {
|| adj->ll_ipv6_count == 0)) {
if (IS_DEBUG_BFD)
zlog_debug(
"ISIS-BFD: skipping BFD initialization on adjacency with %s because IPv6 is enabled but not ready",
Expand All @@ -93,9 +93,9 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj)
* If IS-IS is enabled for both IPv4 and IPv6 on the circuit, prefer
* creating a BFD session over IPv6.
*/
if (circuit->ipv6_router && adj->ipv6_address_count) {
if (circuit->ipv6_router && adj->ll_ipv6_count) {
family = AF_INET6;
dst_ip.ipv6 = adj->ipv6_addresses[0];
dst_ip.ipv6 = adj->ll_ipv6_addrs[0];
local_ips = circuit->ipv6_link;
if (!local_ips || list_isempty(local_ips)) {
if (IS_DEBUG_BFD)
Expand Down Expand Up @@ -181,10 +181,11 @@ void isis_bfd_circuit_cmd(struct isis_circuit *circuit)
}
}

static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family)
static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family,
bool global)
{

if (family != AF_INET6)
if (family != AF_INET6 || global)
return 0;

if (adj->bfd_session)
Expand Down
10 changes: 9 additions & 1 deletion isisd/isis_circuit.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,16 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,

if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix))
listnode_add(circuit->ipv6_link, ipv6);
else
else {
listnode_add(circuit->ipv6_non_link, ipv6);
/* Update Local IPv6 address param. if MPLS TE is on */
if (circuit->ext && circuit->area
&& IS_MPLS_TE(circuit->area->mta)) {
IPV6_ADDR_COPY(&circuit->ext->local_addr6,
&ipv6->prefix);
SET_SUBTLV(circuit->ext, EXT_LOCAL_ADDR6);
}
}
if (circuit->area)
lsp_regenerate_schedule(circuit->area, circuit->is_type,
0);
Expand Down
71 changes: 71 additions & 0 deletions isisd/isis_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,43 @@ void cli_show_isis_mpls_te_router_addr(struct vty *vty,
yang_dnode_get_string(dnode, NULL));
}

/*
* XPath: /frr-isisd:isis/instance/mpls-te/router-address-v6
*/
DEFPY_YANG(isis_mpls_te_router_addr_v6, isis_mpls_te_router_addr_v6_cmd,
"mpls-te router-address ipv6 X:X::X:X",
MPLS_TE_STR
"Stable IP address of the advertising router\n"
"IPv6 address\n"
"MPLS-TE router address in IPv6 address format\n")
{
nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_MODIFY,
ipv6_str);

return nb_cli_apply_changes(vty, NULL);
}

DEFPY_YANG(no_isis_mpls_te_router_addr_v6, no_isis_mpls_te_router_addr_v6_cmd,
"no mpls-te router-address ipv6 [X:X::X:X]",
NO_STR MPLS_TE_STR
"Delete IP address of the advertising router\n"
"IPv6 address\n"
"MPLS-TE router address in IPv6 address format\n")
{
nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_DESTROY,
NULL);

return nb_cli_apply_changes(vty, NULL);
}

void cli_show_isis_mpls_te_router_addr_ipv6(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " mpls-te router-address ipv6 %s\n",
yang_dnode_get_string(dnode, NULL));
}

DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
"[no] mpls-te inter-as [level-1|level-1-2|level-2-only]",
NO_STR MPLS_TE_STR
Expand All @@ -1152,6 +1189,36 @@ DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
return CMD_SUCCESS;
}

/*
* XPath: /frr-isisd:isis/instance/mpls-te/export
*/
DEFPY_YANG(isis_mpls_te_export, isis_mpls_te_export_cmd, "mpls-te export",
MPLS_TE_STR "Enable export of MPLS-TE Link State information\n")
{
nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "true");

return nb_cli_apply_changes(vty, NULL);
}

DEFPY_YANG(no_isis_mpls_te_export, no_isis_mpls_te_export_cmd,
"no mpls-te export",
NO_STR MPLS_TE_STR
"Disable export of MPLS-TE Link State information\n")
{
nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "false");

return nb_cli_apply_changes(vty, NULL);
}

void cli_show_isis_mpls_te_export(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
if (!yang_dnode_get_bool(dnode, NULL))
vty_out(vty, " no");

vty_out(vty, " mpls-te export\n");
}

/*
* XPath: /frr-isisd:isis/instance/default-information-originate
*/
Expand Down Expand Up @@ -3125,7 +3192,11 @@ void isis_cli_init(void)
install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_cmd);
install_element(ISIS_NODE, &isis_mpls_te_router_addr_v6_cmd);
install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_v6_cmd);
install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
install_element(ISIS_NODE, &isis_mpls_te_export_cmd);
install_element(ISIS_NODE, &no_isis_mpls_te_export_cmd);

install_element(ISIS_NODE, &isis_default_originate_cmd);
install_element(ISIS_NODE, &isis_redistribute_cmd);
Expand Down
5 changes: 2 additions & 3 deletions isisd/isis_lfa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,9 +1443,8 @@ static mpls_label_t rlfa_nexthop_label(struct isis_spftree *spftree,
}
break;
case AF_INET6:
for (unsigned int j = 0; j < adj->ipv6_address_count;
j++) {
struct in6_addr addr = adj->ipv6_addresses[j];
for (unsigned int j = 0; j < adj->ll_ipv6_count; j++) {
struct in6_addr addr = adj->ll_ipv6_addrs[j];

if (!IPV6_ADDR_SAME(
&addr,
Expand Down
Loading