mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 00:18:53 +00:00
Merge pull request #6342 from Orange-OpenSource/dev_isis_sr
isisd: Preparation to merge Segment-Routing into master
This commit is contained in:
commit
82624cef0c
@ -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
|
||||
!
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
1327
isisd/isis_sr.c
1327
isisd/isis_sr.c
File diff suppressed because it is too large
Load Diff
105
isisd/isis_sr.h
105
isisd/isis_sr.h
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user