Merge pull request #6342 from Orange-OpenSource/dev_isis_sr

isisd: Preparation to merge Segment-Routing into master
This commit is contained in:
Renato Westphal 2020-05-14 14:23:03 -03:00 committed by GitHub
commit 82624cef0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1107 additions and 528 deletions

View File

@ -473,15 +473,16 @@ Traffic Engineering
Segment Routing
===============
This is an EXPERIMENTAL support of Segment Routing as per draft
`draft-ietf-isis-segment-routing-extensions-25.txt` for MPLS dataplane.
It supports IPv4, IPv6 and ECMP and has been tested against Cisco & Juniper
routers.
This is an EXPERIMENTAL support of Segment Routing as per RFC8667
for MPLS dataplane. It supports IPv4, IPv6 and ECMP and has been
tested against Cisco & Juniper routers.
Known limitations:
- No support for level redistribution (L1 to L2 or L2 to L1)
- No support for binding SID
- No support for SRMS
- No support for SRLB
- Only one SRGB and default SPF Algorithm is supported
.. index:: [no] segment-routing on
.. clicmd:: [no] segment-routing on
@ -491,14 +492,15 @@ Known limitations:
.. index:: [no] segment-routing global-block (0-1048575) (0-1048575)
.. clicmd:: [no] segment-routing global-block (0-1048575) (0-1048575)
Seet the Segment Routing Global Block i.e. the label range used by MPLS
Set the Segment Routing Global Block i.e. the label range used by MPLS
to store label in the MPLS FIB.
.. index:: [no] segment-routing node-msd (1-16)
.. clicmd:: [no] segment-routing node-msd (1-16)
Set the Maximum Stack Depth supported by the router. The value depend of the
MPLS dataplane. E.g. for Linux kernel, since version 4.13 it is 32.
MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value
is 32.
.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null]
.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null]
@ -514,6 +516,11 @@ Known limitations:
Show detailed information about all learned Segment Routing Prefix-SIDs.
.. index:: show isis segment-routing nodes
.. clicmd:: show isis segment-routing nodes
Show detailed information about all learned Segment Routing Nodes.
Debugging ISIS
==============
@ -707,3 +714,32 @@ Then the :file:`isisd.conf` itself:
mpls-te router-address 10.1.1.1
!
line vty
A Segment Routing configuration, with IPv4, IPv6, SRGB and MSD configuration.
.. code-block:: frr
hostname HOSTNAME
password PASSWORD
log file /var/log/isisd.log
!
!
interface eth0
ip router isis SR
isis network point-to-point
!
interface eth1
ip router isis SR
!
!
router isis SR
net 49.0000.0000.0000.0001.00
is-type level-1
topology ipv6-unicast
lsp-gen-interval 2
segment-routing on
segment-routing node-msd 8
segment-routing prefix 10.1.1.1/32 index 100 explicit-null
segment-routing prefix 2001:db8:1000::1/128 index 101 explicit-null
!

View File

@ -1521,7 +1521,9 @@ int isis_instance_segment_routing_msd_node_msd_modify(
area = nb_running_get_entry(args->dnode, NULL, true);
area->srdb.config.msd = yang_dnode_get_uint8(args->dnode, NULL);
isis_sr_cfg_msd_update(area);
/* Update and regenerate LSP */
lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@ -1536,7 +1538,9 @@ int isis_instance_segment_routing_msd_node_msd_destroy(
area = nb_running_get_entry(args->dnode, NULL, true);
area->srdb.config.msd = 0;
isis_sr_cfg_msd_update(area);
/* Update and regenerate LSP */
lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,7 @@
/*
* This is an implementation of Segment Routing for IS-IS
* as per draft draft-ietf-isis-segment-routing-extensions-25
* This is an implementation of Segment Routing for IS-IS as per RFC 8667
*
* Copyright (C) 2019 Orange Labs http://www.orange.com
* Copyright (C) 2019 Orange http://www.orange.com
*
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
* Contributor: Renato Westphal <renato@opensourcerouting.org> for NetDEF
@ -55,30 +54,31 @@
#define SRGB_LOWER_BOUND 16000
#define SRGB_UPPER_BOUND 23999
PREDECL_RBTREE_UNIQ(tree_sr_node)
PREDECL_RBTREE_UNIQ(tree_sr_node_prefix)
PREDECL_RBTREE_UNIQ(tree_sr_area_prefix)
PREDECL_RBTREE_UNIQ(tree_sr_prefix_cfg)
/* Segment Routing Data Base (SRDB) RB-Tree structure */
PREDECL_RBTREE_UNIQ(srdb_node)
PREDECL_RBTREE_UNIQ(srdb_node_prefix)
PREDECL_RBTREE_UNIQ(srdb_area_prefix)
PREDECL_RBTREE_UNIQ(srdb_prefix_cfg)
/* SR Adj-SID type. */
/* Segment Routing Adjacency-SID type. */
enum sr_adj_type {
ISIS_SR_ADJ_NORMAL = 0,
ISIS_SR_LAN_BACKUP,
};
/* SR Adjacency. */
/* Segment Routing Adjacency. */
struct sr_adjacency {
/* Adjacency type. */
enum sr_adj_type type;
/* Adj-SID nexthop information. */
/* Adjacency-SID nexthop information. */
struct {
int family;
union g_addr address;
mpls_label_t label;
} nexthop;
/* (LAN-)Adj-SID Sub-TLV. */
/* (LAN-)Adjacency-SID Sub-TLV. */
union {
struct isis_adj_sid *adj_sid;
struct isis_lan_adj_sid *ladj_sid;
@ -88,32 +88,40 @@ struct sr_adjacency {
struct isis_adjacency *adj;
};
/* SR Prefix-SID type. */
/* Segment Routing Prefix-SID type. */
enum sr_prefix_type {
ISIS_SR_PREFIX_LOCAL = 0,
ISIS_SR_PREFIX_REMOTE,
};
/* SR Nexthop Information. */
/* Segment Routing Nexthop Information. */
struct sr_nexthop_info {
mpls_label_t label;
time_t uptime;
};
/* SR Prefix-SID. */
/* State of Object (SR-Node and SR-Prefix) stored in SRDB */
enum srdb_state {
SRDB_STATE_VALIDATED = 0,
SRDB_STATE_NEW,
SRDB_STATE_MODIFIED,
SRDB_STATE_UNCHANGED
};
/* Segment Routing Prefix-SID. */
struct sr_prefix {
/* RB-tree entries. */
struct tree_sr_node_prefix_item node_entry;
struct tree_sr_area_prefix_item area_entry;
/* SRDB RB-tree entries. */
struct srdb_node_prefix_item node_entry;
struct srdb_area_prefix_item area_entry;
/* IP prefix. */
struct prefix prefix;
/* SID value, algorithm and flags. */
/* SID value, algorithm and flags subTLVs. */
struct isis_prefix_sid sid;
/* Local label value. */
mpls_label_t local_label;
/* Input label value. */
mpls_label_t input_label;
/* Prefix-SID type. */
enum sr_prefix_type type;
@ -128,20 +136,17 @@ struct sr_prefix {
} remote;
} u;
/* Backpointer to SR node. */
/* Backpointer to Segment Routing node. */
struct sr_node *srn;
/* Flags used while the LSPDB is being parsed. */
uint8_t parse_flags;
#define F_ISIS_SR_PREFIX_SID_NEW 0x01
#define F_ISIS_SR_PREFIX_SID_MODIFIED 0x02
#define F_ISIS_SR_PREFIX_SID_UNCHANGED 0x04
/* SR-Prefix State used while the LSPDB is being parsed. */
enum srdb_state state;
};
/* SR node. */
/* Segment Routing node. */
struct sr_node {
/* RB-tree entry. */
struct tree_sr_node_item entry;
/* SRDB RB-tree entry. */
struct srdb_node_item entry;
/* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */
int level;
@ -149,39 +154,38 @@ struct sr_node {
/* IS-IS node identifier. */
uint8_t sysid[ISIS_SYS_ID_LEN];
/* IS-IS node capabilities (SRGB, SR Algorithms, etc). */
/* Segment Routing node capabilities (SRGB, SR Algorithms) subTLVs. */
struct isis_router_cap cap;
/* List of Prefix-SIDs advertised by this node. */
struct tree_sr_node_prefix_head prefix_sids;
struct srdb_node_prefix_head prefix_sids;
/* Backpointer to IS-IS area. */
struct isis_area *area;
/* Flags used while the LSPDB is being parsed. */
uint8_t parse_flags;
#define F_ISIS_SR_NODE_NEW 0x01
#define F_ISIS_SR_NODE_MODIFIED 0x02
#define F_ISIS_SR_NODE_UNCHANGED 0x04
/* SR-Node State used while the LSPDB is being parsed. */
enum srdb_state state;
};
/* NOTE: these values must be in sync with the YANG module. */
/* SID type. NOTE: these values must be in sync with the YANG module. */
enum sr_sid_value_type {
SR_SID_VALUE_TYPE_INDEX = 0,
SR_SID_VALUE_TYPE_ABSOLUTE = 1,
};
/* NOTE: these values must be in sync with the YANG module. */
#define IS_SID_VALUE(flag) CHECK_FLAG(flag, ISIS_PREFIX_SID_VALUE)
/* Last Hop Behavior. NOTE: these values must be in sync with the YANG module */
enum sr_last_hop_behavior {
SR_LAST_HOP_BEHAVIOR_EXP_NULL = 0,
SR_LAST_HOP_BEHAVIOR_NO_PHP = 1,
SR_LAST_HOP_BEHAVIOR_PHP = 2,
};
/* SR Prefix-SID configuration. */
/* Segment Routing Prefix-SID configuration. */
struct sr_prefix_cfg {
/* RB-tree entry. */
struct tree_sr_prefix_cfg_item entry;
/* SRDB RB-tree entry. */
struct srdb_prefix_cfg_item entry;
/* IP prefix. */
struct prefix prefix;
@ -202,21 +206,21 @@ struct sr_prefix_cfg {
struct isis_area *area;
};
/* Per-area IS-IS Segment Routing information. */
/* Per-area IS-IS Segment Routing Data Base (SRDB). */
struct isis_sr_db {
/* Operational status of Segment Routing. */
/* Global Operational status of Segment Routing. */
bool enabled;
/* Adj-SIDs. */
/* List of local Adjacency-SIDs. */
struct list *adj_sids;
/* SR information from all nodes. */
struct tree_sr_node_head sr_nodes[ISIS_LEVELS];
/* Segment Routing Node information per IS-IS level. */
struct srdb_node_head sr_nodes[ISIS_LEVELS];
/* Prefix-SIDs. */
struct tree_sr_area_prefix_head prefix_sids[ISIS_LEVELS];
/* Segment Routing Prefix-SIDs per IS-IS level. */
struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS];
/* Area SR configuration. */
/* Area Segment Routing configuration. */
struct {
/* Administrative status of Segment Routing. */
bool enabled;
@ -229,14 +233,13 @@ struct isis_sr_db {
uint8_t msd;
/* Prefix-SID mappings. */
struct tree_sr_prefix_cfg_head prefix_sids;
struct srdb_prefix_cfg_head prefix_sids;
} config;
};
/* Prototypes. */
extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
uint32_t upper_bound);
extern void isis_sr_cfg_msd_update(struct isis_area *area);
extern struct sr_prefix_cfg *
isis_sr_cfg_prefix_add(struct isis_area *area, const struct prefix *prefix);
extern void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg);

View File

@ -284,7 +284,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
sbuf_push(buf, indent,
"Unidir. Utilized Bandwidth: %g (Bytes/sec)\n",
exts->use_bw);
/* Segment Routing Adjacency */
/* Segment Routing Adjacency as per RFC8667 section #2.2.1 */
if (IS_SUBTLV(exts, EXT_ADJ_SID)) {
struct isis_adj_sid *adj;
@ -315,6 +315,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
: '0');
}
}
/* Segment Routing LAN-Adjacency as per RFC8667 section #2.2.2 */
if (IS_SUBTLV(exts, EXT_LAN_ADJ_SID)) {
struct isis_lan_adj_sid *lan;
@ -476,6 +477,7 @@ static int pack_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
stream_putc(s, ISIS_SUBTLV_DEF_SIZE);
stream_putf(s, exts->use_bw);
}
/* Segment Routing Adjacency as per RFC8667 section #2.2.1 */
if (IS_SUBTLV(exts, EXT_ADJ_SID)) {
struct isis_adj_sid *adj;
@ -495,6 +497,7 @@ static int pack_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
}
}
/* Segment Routing LAN-Adjacency as per RFC8667 section #2.2.2 */
if (IS_SUBTLV(exts, EXT_LAN_ADJ_SID)) {
struct isis_lan_adj_sid *lan;
@ -721,7 +724,7 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
SET_SUBTLV(exts, EXT_USE_BW);
}
break;
/* Segment Routing Adjacency */
/* Segment Routing Adjacency as per RFC8667 section #2.2.1 */
case ISIS_SUBTLV_ADJ_SID:
if (subtlv_len != ISIS_SUBTLV_ADJ_SID_SIZE
&& subtlv_len != ISIS_SUBTLV_ADJ_SID_SIZE + 1) {
@ -749,6 +752,7 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
SET_SUBTLV(exts, EXT_ADJ_SID);
}
break;
/* Segment Routing LAN-Adjacency as per RFC8667 section 2.2.2 */
case ISIS_SUBTLV_LAN_ADJ_SID:
if (subtlv_len != ISIS_SUBTLV_LAN_ADJ_SID_SIZE
&& subtlv_len != ISIS_SUBTLV_LAN_ADJ_SID_SIZE + 1) {
@ -789,7 +793,7 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
return 0;
}
/* Functions for Sub-TLV 3 SR Prefix-SID */
/* Functions for Sub-TLV 3 SR Prefix-SID as per RFC8667 section 2.1 */
static struct isis_item *copy_item_prefix_sid(struct isis_item *i)
{
struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i;
@ -2585,7 +2589,7 @@ out:
return 1;
}
/* Functions related to TLV 242 Router Capability */
/* Functions related to TLV 242 Router Capability as per RFC7981 */
static struct isis_router_cap *copy_tlv_router_cap(
const struct isis_router_cap *router_cap)
{
@ -2614,7 +2618,7 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
router_cap->flags & ISIS_ROUTER_CAP_FLAG_D ? '1' : '0',
router_cap->flags & ISIS_ROUTER_CAP_FLAG_S ? '1' : '0');
/* SR Global Block */
/* Segment Routing Global Block as per RFC8667 section #3.1 */
if (router_cap->srgb.range_size != 0)
sbuf_push(buf, indent,
" Segment Routing: I:%s V:%s, SRGB Base: %d Range: %d\n",
@ -2623,7 +2627,7 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
router_cap->srgb.lower_bound,
router_cap->srgb.range_size);
/* SR Algorithms */
/* Segment Routing Algorithms as per RFC8667 section #3.2 */
if (router_cap->algo[0] != SR_ALGORITHM_UNSET) {
sbuf_push(buf, indent, " Algorithm: %s",
router_cap->algo[0] == 0 ? "0: SPF"
@ -2637,7 +2641,7 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
sbuf_push(buf, indent, "\n");
}
/* SR Node MSSD */
/* Segment Routing Node MSD as per RFC8491 section #2 */
if (router_cap->msd != 0)
sbuf_push(buf, indent, " Node MSD: %d\n", router_cap->msd);
}
@ -2674,7 +2678,7 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
stream_put_ipv4(s, router_cap->router_id.s_addr);
stream_putc(s, router_cap->flags);
/* Add SRGB if set */
/* Add SRGB if set as per RFC8667 section #3.1 */
if ((router_cap->srgb.range_size != 0)
&& (router_cap->srgb.lower_bound != 0)) {
stream_putc(s, ISIS_SUBTLV_SID_LABEL_RANGE);
@ -2685,7 +2689,7 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
stream_putc(s, ISIS_SUBTLV_SID_LABEL_SIZE);
stream_put3(s, router_cap->srgb.lower_bound);
/* Then SR Algorithm if set */
/* Then SR Algorithm if set as per RFC8667 section #3.2 */
for (nb_algo = 0; nb_algo < SR_ALGORITHM_COUNT; nb_algo++)
if (router_cap->algo[nb_algo] == SR_ALGORITHM_UNSET)
break;
@ -2695,7 +2699,7 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
for (int i = 0; i < nb_algo; i++)
stream_putc(s, router_cap->algo[i]);
}
/* And finish with MSD if set */
/* And finish with MSD if set as per RFC8491 section #2 */
if (router_cap->msd != 0) {
stream_putc(s, ISIS_SUBTLV_NODE_MSD);
stream_putc(s, ISIS_SUBTLV_NODE_MSD_SIZE);
@ -4602,6 +4606,7 @@ void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs,
append_item(&tlvs->oldstyle_ip_reach, (struct isis_item *)r);
}
/* Add IS-IS SR Adjacency-SID subTLVs */
void isis_tlvs_add_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_adj_sid *adj)
{
@ -4609,6 +4614,7 @@ void isis_tlvs_add_adj_sid(struct isis_ext_subtlvs *exts,
SET_SUBTLV(exts, EXT_ADJ_SID);
}
/* Delete IS-IS SR Adjacency-SID subTLVs */
void isis_tlvs_del_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_adj_sid *adj)
{
@ -4618,6 +4624,7 @@ void isis_tlvs_del_adj_sid(struct isis_ext_subtlvs *exts,
UNSET_SUBTLV(exts, EXT_ADJ_SID);
}
/* Add IS-IS SR LAN-Adjacency-SID subTLVs */
void isis_tlvs_add_lan_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_lan_adj_sid *lan)
{
@ -4625,6 +4632,7 @@ void isis_tlvs_add_lan_adj_sid(struct isis_ext_subtlvs *exts,
SET_SUBTLV(exts, EXT_LAN_ADJ_SID);
}
/* Delete IS-IS SR LAN-Adjacency-SID subTLVs */
void isis_tlvs_del_lan_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_lan_adj_sid *lan)
{

View File

@ -135,10 +135,7 @@ struct isis_threeway_adj {
uint32_t neighbor_circuit_id;
};
/*
* Segment Routing subTLV's as per
* draft-ietf-isis-segment-routing-extension-25
*/
/* Segment Routing subTLV's as per RFC8667 */
#define ISIS_SUBTLV_SRGB_FLAG_I 0x80
#define ISIS_SUBTLV_SRGB_FLAG_V 0x40
#define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
@ -216,7 +213,7 @@ struct isis_router_cap {
struct in_addr router_id;
uint8_t flags;
/* draft-ietf-segment-routing-extensions-25 */
/* RFC 8667 section #3 */
struct isis_srgb srgb;
uint8_t algo[SR_ALGORITHM_COUNT];
/* RFC 8491 */
@ -344,7 +341,7 @@ struct isis_subtlvs {
/* draft-baker-ipv6-isis-dst-src-routing-06 */
struct prefix_ipv6 *source_prefix;
/* draft-ietf-isis-segment-routing-extensions-25 */
/* RFC 8667 section #2.4 */
struct isis_item_list prefix_sids;
};
@ -394,15 +391,17 @@ enum isis_tlv_type {
/* RFC 5307 */
ISIS_SUBTLV_LLRI = 4,
/* RFC 8491 */
ISIS_SUBTLV_NODE_MSD = 23,
/* RFC 5316 */
ISIS_SUBTLV_RAS = 24,
ISIS_SUBTLV_RIP = 25,
/* draft-isis-segment-routing-extension-25 */
/* RFC 8667 section #2 */
ISIS_SUBTLV_SID_LABEL = 1,
ISIS_SUBTLV_SID_LABEL_RANGE = 2,
ISIS_SUBTLV_ALGORITHM = 19,
ISIS_SUBTLV_NODE_MSD = 23,
ISIS_SUBTLV_PREFIX_SID = 3,
ISIS_SUBTLV_ADJ_SID = 31,
ISIS_SUBTLV_LAN_ADJ_SID = 32,
@ -421,21 +420,26 @@ enum isis_tlv_type {
/* subTLVs size for TE and SR */
enum ext_subtlv_size {
/* RFC 5307 */
ISIS_SUBTLV_LLRI_SIZE = 8,
/* RFC 5305 & RFC 6119 */
ISIS_SUBTLV_UNRSV_BW_SIZE = 32,
ISIS_SUBTLV_TE_METRIC_SIZE = 3,
ISIS_SUBTLV_IPV6_ADDR_SIZE = 16,
/* draft-isis-segment-routing-extension-25 */
/* RFC 8491 */
ISIS_SUBTLV_NODE_MSD_SIZE = 2,
/* RFC 8667 section #2 */
ISIS_SUBTLV_SID_LABEL_SIZE = 3,
ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
ISIS_SUBTLV_ALGORITHM_SIZE = 4,
ISIS_SUBTLV_NODE_MSD_SIZE = 2,
ISIS_SUBTLV_ADJ_SID_SIZE = 5,
ISIS_SUBTLV_LAN_ADJ_SID_SIZE = 11,
ISIS_SUBTLV_PREFIX_SID_SIZE = 5,
/* RFC 7810 */
ISIS_SUBTLV_MM_DELAY_SIZE = 8,
ISIS_SUBTLV_HDR_SIZE = 2,

View File

@ -49,6 +49,7 @@
#include "isisd/isis_lsp.h"
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_te.h"
#include "isisd/isis_sr.h"
@ -253,8 +254,12 @@ void isis_zebra_route_del_route(struct prefix *prefix,
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
}
/* Install Prefix-SID in the forwarding plane. */
void isis_zebra_install_prefix_sid(const struct sr_prefix *srp)
/**
* Install Prefix-SID in the forwarding plane through Zebra.
*
* @param srp Segment Routing Prefix-SID
*/
static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
{
struct zapi_labels zl;
struct zapi_nexthop *znh;
@ -265,7 +270,7 @@ void isis_zebra_install_prefix_sid(const struct sr_prefix *srp)
/* Prepare message. */
memset(&zl, 0, sizeof(zl));
zl.type = ZEBRA_LSP_ISIS_SR;
zl.local_label = srp->local_label;
zl.local_label = srp->input_label;
switch (srp->type) {
case ISIS_SR_PREFIX_LOCAL:
@ -314,15 +319,19 @@ void isis_zebra_install_prefix_sid(const struct sr_prefix *srp)
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
}
/* Uninstall Prefix-SID from the forwarding plane. */
void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
/**
* Uninstall Prefix-SID from the forwarding plane through Zebra.
*
* @param srp Segment Routing Prefix-SID
*/
static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
{
struct zapi_labels zl;
/* Prepare message. */
memset(&zl, 0, sizeof(zl));
zl.type = ZEBRA_LSP_ISIS_SR;
zl.local_label = srp->local_label;
zl.local_label = srp->input_label;
if (srp->type == ISIS_SR_PREFIX_REMOTE) {
/* Update route in the RIB too. */
@ -336,6 +345,69 @@ void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
}
/**
* Send Prefix-SID to ZEBRA for installation or deletion.
*
* @param cmd ZEBRA_MPLS_LABELS_REPLACE or ZEBRA_ROUTE_DELETE
* @param srp Segment Routing Prefix-SID
*/
void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp)
{
if (cmd != ZEBRA_MPLS_LABELS_REPLACE
&& cmd != ZEBRA_MPLS_LABELS_DELETE) {
flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
__func__);
return;
}
sr_debug(" |- %s label %u for prefix %pFX",
cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete",
srp->input_label, &srp->prefix);
if (cmd == ZEBRA_MPLS_LABELS_REPLACE)
isis_zebra_prefix_install_prefix_sid(srp);
else
isis_zebra_uninstall_prefix_sid(srp);
}
/**
* Send (LAN)-Adjacency-SID to ZEBRA for installation or deletion.
*
* @param cmd ZEBRA_MPLS_LABELS_ADD or ZEBRA_ROUTE_DELETE
* @param sra Segment Routing Adjacency-SID
*/
void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
{
struct zapi_labels zl;
struct zapi_nexthop *znh;
if (cmd != ZEBRA_MPLS_LABELS_ADD && cmd != ZEBRA_MPLS_LABELS_DELETE) {
flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
__func__);
return;
}
sr_debug(" |- %s label %u for interface %s",
cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete",
sra->nexthop.label, sra->adj->circuit->interface->name);
memset(&zl, 0, sizeof(zl));
zl.type = ZEBRA_LSP_ISIS_SR;
zl.local_label = sra->nexthop.label;
zl.nexthop_num = 1;
znh = &zl.nexthops[0];
znh->gate = sra->nexthop.address;
znh->type = (sra->nexthop.family == AF_INET)
? NEXTHOP_TYPE_IPV4_IFINDEX
: NEXTHOP_TYPE_IPV6_IFINDEX;
znh->ifindex = sra->adj->circuit->interface->ifindex;
znh->label_num = 1;
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
(void)zebra_send_mpls_labels(zclient, cmd, &zl);
}
static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
{
struct zapi_route api;

View File

@ -36,6 +36,7 @@ void isis_zebra_stop(void);
struct isis_route_info;
struct sr_prefix;
struct sr_adjacency;
void isis_zebra_route_add_route(struct prefix *prefix,
struct prefix_ipv6 *src_p,
@ -43,8 +44,8 @@ void isis_zebra_route_add_route(struct prefix *prefix,
void isis_zebra_route_del_route(struct prefix *prefix,
struct prefix_ipv6 *src_p,
struct isis_route_info *route_info);
void isis_zebra_install_prefix_sid(const struct sr_prefix *srp);
void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp);
void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp);
void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra);
int isis_distribute_list_update(int routetype);
void isis_zebra_redistribute_set(afi_t afi, int type);
void isis_zebra_redistribute_unset(afi_t afi, int type);

View File

@ -254,6 +254,12 @@ extern struct thread_master *master;
zlog_debug(__VA_ARGS__); \
} while (0)
#define sr_debug(...) \
do { \
if (IS_DEBUG_ISIS(DEBUG_SR)) \
zlog_debug(__VA_ARGS__); \
} while (0)
#define DEBUG_TE DEBUG_LSP_GEN
#define IS_DEBUG_ISIS(x) (isis->debugs & x)