mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-03 23:47:16 +00:00 
			
		
		
		
	OSPFD: Add Experimental Segment Routing support
This is an implementation of draft-ietf-ospf-segment-routing-extensions-24 and RFC7684 for Extended Link & Prefix Opaque LSA. Look to doc/OSPF_SR.rst for implementation details & known limitations. New files: - ospfd/ospf_sr.h: Segment Routing structure definition (SubTLVs + SRDB) - ospfd/ospf_sr.c: Main functions for Segment Routing support - ospfd/ospf_ext.h: TLVs and SubTLVs definition for RFC7684 - ospfd/ospf_ext.c: RFC7684 Extended Link / Prefix implementation - doc/OSPF-SRr.rst: Documentation Modified Files: - doc/ospfd.texi: Add new Segment Routing CLI command definition - lib/command.h: Add new string command for Segment Routing CLI - lib/mpls.h: Add default value for SRGB - lib/route_types.txt: Add new OSPF Segment Routing route type - ospfd/ospf_dump.[c,h]: Add OSPF SR debug - ospfd/ospf_memory.[c,h]: Add new Segment Routing memory type - ospfd/ospf_opaque.[c,h]: Add ospf_sr_init() starting function - ospfd/ospf_ri.c: Add new functions to Set/Get Segment Routing TLVs Add new ospf_router_info_lsa_upadte() to send Opaque LSA to ospf_sr.c() - ospfd/ospf_ri.h: Add new Router Information SR SubTLVs - ospfd/ospf_spf.c: Add new scheduler when running SPF to trigger update of NHLFE - ospfd/ospfd.h: Add new thread for Segment Routing scheduler - ospfd/subdir.am: Add new files - vtysh/Makefile.am: Add new ospf_sr.c file for vtysh - zebra/kernel_netlink.c: Add new OSPF_SR route type - zebra/rt_netlink.[c,h]: Add new OSPF_SR route type - zebra/zebra_mpls.h: Add new OSPF_SR route type Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
		
							parent
							
								
									b782607f7f
								
							
						
					
					
						commit
						cf9b9f77f6
					
				
							
								
								
									
										82
									
								
								doc/OSPF-SR.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								doc/OSPF-SR.rst
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
OSPF Segment Routing
 | 
			
		||||
====================
 | 
			
		||||
 | 
			
		||||
This is an EXPERIMENTAL support of draft draft-ietf-ospf-segment-routing-extensions-24.
 | 
			
		||||
DON'T use it for production network.
 | 
			
		||||
 | 
			
		||||
Implementation details
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Segment Routing used 3 differents OPAQUE LSA in OSPF to carry the various information:
 | 
			
		||||
 - Router Information: flood the Segment Routing capabilities of the node. This include
 | 
			
		||||
 the supported algorithms, the Segment Routing Global Block (SRGB) and the Maximum Stack
 | 
			
		||||
 Depth.
 | 
			
		||||
 - Extended Link: flood the Adjaceny and Lan Adjacency Segment Identifier
 | 
			
		||||
 - Extended Prefix: flood the Prefix Segment Identifier
 | 
			
		||||
 | 
			
		||||
The implementation follow previous TE and Router Information code. It used the OPAQUE LSA
 | 
			
		||||
functions define in ospf_opaque.[c,h] as well as the OSPF API. This latter is mandatory
 | 
			
		||||
for the implementation as it provides the Callback to Segment Routing functions (see below)
 | 
			
		||||
when an Extended Link / Prefix or Router Information is received.
 | 
			
		||||
 | 
			
		||||
Following files where modified or added:
 | 
			
		||||
 - ospd_ri.[c,h] have been modified to add the new TLVs for Segment Routing.
 | 
			
		||||
 - ospf_ext.[c,h] implement RFC7684 as base support of Extended Link and Prefix Opaque LSA.
 | 
			
		||||
 - ospf_sr.[c,h] implement the earth of Segment Routing. It adds a new Segment Routing database
 | 
			
		||||
 to manage Segment Identifiers per Link and Prefix and Segment Routing enable node, Callback
 | 
			
		||||
 functions to process incoming LSA and install MPLS FIB entry through Zebra.
 | 
			
		||||
 | 
			
		||||
the figure below shows the relation between the various files:
 | 
			
		||||
 | 
			
		||||
 - ospf_sr.c centralized all the Segment Routing processing. It receives Opaque LSA
 | 
			
		||||
 Router Information (4.0.0.0) from ospf_ri.c and Extended Prefix (7.0.0.X) Link (8.0.0.X)
 | 
			
		||||
 from ospf_ext.c. Once received, it parse TLVs and SubTLVs and store information in SRDB
 | 
			
		||||
 (which is defined in ospf_sr.h). For each received LSA, NHLFE is computed and send to
 | 
			
		||||
 Zebra to add/remove new MPLS labels entries and FEC. New CLI configurations are also
 | 
			
		||||
 centralized in ospf_sr.c. This CLI will trigger the flooding os new LSA Router Information
 | 
			
		||||
 (4.0.0.0), Extended Prefix (7.0.0.X) and Link (8.0.0.X) by ospf_ri.c, respectively ospf_ext.c.
 | 
			
		||||
 - ospf_ri.c send back to ospf_sr.c received Router Information LSA and update self Router
 | 
			
		||||
 Information LSA with paramters provided by ospf_sr.c i.e. SRGB and MSD. It use ospf_opaque.c
 | 
			
		||||
 functions to send / received these Opaque LSAs.
 | 
			
		||||
 - ospf_ext.c send bacl to ospf_sr.c received Extended Prefix and Link Opaque LSA and send
 | 
			
		||||
 self Extended Prefix and Link Opaque LSA through ospf_opaque.c functions.
 | 
			
		||||
 | 
			
		||||
                    +-----------+     +-------+
 | 
			
		||||
                    |           |     |       |
 | 
			
		||||
                    | ospf_sr.c +-----+  SRDB |
 | 
			
		||||
        +-----------+           +--+  |       |
 | 
			
		||||
        |           +-^-------^-+  |  +-------+
 | 
			
		||||
        |             |   |   |    |
 | 
			
		||||
        |             |   |   |    |
 | 
			
		||||
        |             |   |   |    +--------+
 | 
			
		||||
        |             |   |   |             |
 | 
			
		||||
    +---v----------+  |   |   |       +-----v-------+
 | 
			
		||||
    |              |  |   |   |       |             |
 | 
			
		||||
    | ospf_ri.c    +--+   |   +-------+ ospf_ext.c  |
 | 
			
		||||
    | LSA 4.0.0.0  |      |           | LSA 7.0.0.X |
 | 
			
		||||
    |              |      |           | LSA 8.0.0.X |
 | 
			
		||||
    +---^----------+      |           |             |
 | 
			
		||||
        |                 |           +-----^-------+
 | 
			
		||||
        |                 |                 |
 | 
			
		||||
        |                 |                 |
 | 
			
		||||
        |        +--------v------------+    |
 | 
			
		||||
        |        |                     |    |
 | 
			
		||||
        |        | ZEBRA: Labels + FEC |    |
 | 
			
		||||
        |        |                     |    |
 | 
			
		||||
        |        +---------------------+    |
 | 
			
		||||
        |                                   |
 | 
			
		||||
        |                                   |
 | 
			
		||||
        |         +---------------+         |
 | 
			
		||||
        |         |               |         |
 | 
			
		||||
        +---------> ospf_opaque.c <---------+
 | 
			
		||||
                  |               |
 | 
			
		||||
                  +---------------+
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Known limitations
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
 - Only single Area is supported. ABR is not yet supported
 | 
			
		||||
 - Only SPF algorithm is supported
 | 
			
		||||
 - Extended Prefix Range is not supported
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ networks.
 | 
			
		||||
* Opaque LSA::
 | 
			
		||||
* OSPF Traffic Engineering::
 | 
			
		||||
* Router Information::
 | 
			
		||||
* Segment Routing::
 | 
			
		||||
* Debugging OSPF::              
 | 
			
		||||
* OSPF Configuration Examples::
 | 
			
		||||
@end menu
 | 
			
		||||
@ -724,6 +725,44 @@ Show Router Capabilities flag.
 | 
			
		||||
Show Router Capabilities PCE parameters.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@node Segment Routing
 | 
			
		||||
@section Segment Routing
 | 
			
		||||
 | 
			
		||||
This is an EXPERIMENTAL support of Segment Routing as per draft
 | 
			
		||||
 draft-ietf-ospf-segment-routing-extensions-24i for MPLS dataplane.
 | 
			
		||||
 | 
			
		||||
@deffn {OSPF Command} {segment-routing on} {}
 | 
			
		||||
@deffnx {OSPF Command} {no segment-routing} {}
 | 
			
		||||
Enable Segment Routing. Even if this also activate routing information support,
 | 
			
		||||
it is preferable to also activate routing information, and set accordingly the
 | 
			
		||||
Area or AS flooding.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@deffn {OSPF Command} {segment-routing global-block (0-1048575) (0-1048575)} {}
 | 
			
		||||
@deffnx {OSPF Command} {no segment-routing global-block} {}
 | 
			
		||||
Fix the Segment Routing Global Block i.e. the label range used by MPLS to store
 | 
			
		||||
label in the MPLS FIB.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@deffn {OSPF Command} {segment-routing node-msd (1-16)} {}
 | 
			
		||||
@deffnx {OSPF Command} {no segment-routing node-msd} {}
 | 
			
		||||
Fix 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.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@deffn {OSPF Command} {segment-routing prefix A.B.C.D/M index (0-65535)} {}
 | 
			
		||||
@deffnx {OSPF Command} {no segment-routing prefix A.B.C.D/M} {}
 | 
			
		||||
Set the Segment Rounting index for the specifyed prefix. Note
 | 
			
		||||
that, only prefix with /32 corresponding to a loopback interface are  
 | 
			
		||||
currently supported.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@deffn {Command} {show ip ospf database segment-routing} {}
 | 
			
		||||
@deffnx {Command} {show ip ospf database segment-routing adv-router @var{adv-router}} {}
 | 
			
		||||
@deffnx {Command} {show ip ospf database segment-routing self-originate} {}
 | 
			
		||||
Show Segment Routing Data Base, all SR nodes, specific advertized router or self router.
 | 
			
		||||
@end deffn
 | 
			
		||||
 | 
			
		||||
@node Debugging OSPF
 | 
			
		||||
@section Debugging OSPF
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -358,6 +358,7 @@ struct cmd_node {
 | 
			
		||||
#define OSPF_RI_STR "OSPF Router Information specific commands\n"
 | 
			
		||||
#define PCE_STR "PCE Router Information specific commands\n"
 | 
			
		||||
#define MPLS_STR "MPLS information\n"
 | 
			
		||||
#define SR_STR "Segment-Routing specific commands\n"
 | 
			
		||||
#define WATCHFRR_STR "watchfrr information\n"
 | 
			
		||||
#define ZEBRA_STR "Zebra information\n"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,8 +41,10 @@
 | 
			
		||||
#define MPLS_MAX_UNRESERVED_LABEL          1048575
 | 
			
		||||
 | 
			
		||||
/* Default min and max SRGB label range */
 | 
			
		||||
#define MPLS_DEFAULT_MIN_SRGB_LABEL        16000
 | 
			
		||||
#define MPLS_DEFAULT_MAX_SRGB_LABEL        23999
 | 
			
		||||
#define MPLS_DEFAULT_MIN_SRGB_LABEL        10000
 | 
			
		||||
#define MPLS_DEFAULT_MAX_SRGB_LABEL        50000
 | 
			
		||||
#define MPLS_DEFAULT_MIN_SRGB_SIZE         5000
 | 
			
		||||
#define MPLS_DEFAULT_MAX_SRGB_SIZE         20000
 | 
			
		||||
 | 
			
		||||
/* Maximum # labels that can be pushed. */
 | 
			
		||||
#define MPLS_MAX_LABELS                    16
 | 
			
		||||
@ -94,7 +96,8 @@ enum lsp_types_t {
 | 
			
		||||
	ZEBRA_LSP_NONE = 0,   /* No LSP. */
 | 
			
		||||
	ZEBRA_LSP_STATIC = 1, /* Static LSP. */
 | 
			
		||||
	ZEBRA_LSP_LDP = 2,    /* LDP LSP. */
 | 
			
		||||
	ZEBRA_LSP_BGP = 3     /* BGP LSP. */
 | 
			
		||||
	ZEBRA_LSP_BGP = 3,    /* BGP LSP. */
 | 
			
		||||
	ZEBRA_LSP_SR = 4      /* Segment Routing LSP. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Functions for basic label operations. */
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,7 @@ ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL,  'b', 0, 0, "BGP-Direct"
 | 
			
		||||
ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
 | 
			
		||||
ZEBRA_ROUTE_BABEL,      babel,     babeld, 'A', 1, 1, "Babel"
 | 
			
		||||
ZEBRA_ROUTE_SHARP,    sharp,     sharpd, 'D', 1, 1, "SHARP"
 | 
			
		||||
ZEBRA_ROUTE_OSPF_SR,    ospf-sr,   ospfd,  's', 1, 0, "OSPF-SR" 
 | 
			
		||||
ZEBRA_ROUTE_ALL,        wildcard,  none,   '-', 0, 0, "-"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -103,3 +104,4 @@ ZEBRA_ROUTE_LDP,    "Label Distribution Protocol (LDP)"
 | 
			
		||||
ZEBRA_ROUTE_VNC_DIRECT,    "VNC direct (not via zebra) routes"
 | 
			
		||||
ZEBRA_ROUTE_BABEL,  "Babel routing protocol (Babel)"
 | 
			
		||||
ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
 | 
			
		||||
ZEBRA_ROUTE_OSPF_SR, "OSPF Segment Routing (OSPF-SR)"
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,8 @@ unsigned long conf_debug_ospf_lsa = 0;
 | 
			
		||||
unsigned long conf_debug_ospf_zebra = 0;
 | 
			
		||||
unsigned long conf_debug_ospf_nssa = 0;
 | 
			
		||||
unsigned long conf_debug_ospf_te = 0;
 | 
			
		||||
unsigned long conf_debug_ospf_ext = 0;
 | 
			
		||||
unsigned long conf_debug_ospf_sr = 0;
 | 
			
		||||
 | 
			
		||||
/* Enable debug option variables -- valid only session. */
 | 
			
		||||
unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
 | 
			
		||||
@ -61,7 +63,8 @@ unsigned long term_debug_ospf_lsa = 0;
 | 
			
		||||
unsigned long term_debug_ospf_zebra = 0;
 | 
			
		||||
unsigned long term_debug_ospf_nssa = 0;
 | 
			
		||||
unsigned long term_debug_ospf_te = 0;
 | 
			
		||||
 | 
			
		||||
unsigned long term_debug_ospf_ext = 0;
 | 
			
		||||
unsigned long term_debug_ospf_sr = 0;
 | 
			
		||||
 | 
			
		||||
const char *ospf_redist_string(u_int route_type)
 | 
			
		||||
{
 | 
			
		||||
@ -1441,6 +1444,33 @@ DEFUN (no_debug_ospf_te,
 | 
			
		||||
	return CMD_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFUN (debug_ospf_sr,
 | 
			
		||||
       debug_ospf_sr_cmd,
 | 
			
		||||
       "debug ospf sr",
 | 
			
		||||
       DEBUG_STR
 | 
			
		||||
       OSPF_STR
 | 
			
		||||
       "OSPF-SR information\n")
 | 
			
		||||
{
 | 
			
		||||
	if (vty->node == CONFIG_NODE)
 | 
			
		||||
		CONF_DEBUG_ON(sr, SR);
 | 
			
		||||
	TERM_DEBUG_ON(sr, SR);
 | 
			
		||||
	return CMD_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFUN (no_debug_ospf_sr,
 | 
			
		||||
       no_debug_ospf_sr_cmd,
 | 
			
		||||
       "no debug ospf sr",
 | 
			
		||||
       NO_STR
 | 
			
		||||
       DEBUG_STR
 | 
			
		||||
       OSPF_STR
 | 
			
		||||
       "OSPF-SR information\n")
 | 
			
		||||
{
 | 
			
		||||
	if (vty->node == CONFIG_NODE)
 | 
			
		||||
		CONF_DEBUG_OFF(sr, SR);
 | 
			
		||||
	TERM_DEBUG_OFF(sr, SR);
 | 
			
		||||
	return CMD_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFUN (no_debug_ospf,
 | 
			
		||||
       no_debug_ospf_cmd,
 | 
			
		||||
       "no debug ospf",
 | 
			
		||||
@ -1774,6 +1804,7 @@ void debug_init()
 | 
			
		||||
	install_element(ENABLE_NODE, &debug_ospf_event_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &debug_ospf_nssa_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &debug_ospf_te_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &debug_ospf_sr_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_ism_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_nsm_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_lsa_cmd);
 | 
			
		||||
@ -1781,6 +1812,7 @@ void debug_init()
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_event_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_nssa_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_te_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &no_debug_ospf_sr_cmd);
 | 
			
		||||
 | 
			
		||||
	install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd);
 | 
			
		||||
	install_element(ENABLE_NODE, &debug_ospf_packet_cmd);
 | 
			
		||||
@ -1809,12 +1841,14 @@ void debug_init()
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_event_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_nssa_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_te_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_sr_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_nsm_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_lsa_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_zebra_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_event_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_nssa_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_te_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &no_debug_ospf_sr_cmd);
 | 
			
		||||
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd);
 | 
			
		||||
	install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd);
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,8 @@
 | 
			
		||||
#define OSPF_DEBUG_EVENT        0x01
 | 
			
		||||
#define OSPF_DEBUG_NSSA		0x02
 | 
			
		||||
#define OSPF_DEBUG_TE          0x04
 | 
			
		||||
#define OSPF_DEBUG_EXT         0x08
 | 
			
		||||
#define OSPF_DEBUG_SR          0x10
 | 
			
		||||
 | 
			
		||||
/* Macro for setting debug option. */
 | 
			
		||||
#define CONF_DEBUG_PACKET_ON(a, b)	    conf_debug_ospf_packet[a] |= (b)
 | 
			
		||||
@ -98,6 +100,10 @@
 | 
			
		||||
 | 
			
		||||
#define IS_DEBUG_OSPF_TE  IS_DEBUG_OSPF(te,TE)
 | 
			
		||||
 | 
			
		||||
#define IS_DEBUG_OSPF_EXT  IS_DEBUG_OSPF(ext,EXT)
 | 
			
		||||
 | 
			
		||||
#define IS_DEBUG_OSPF_SR  IS_DEBUG_OSPF(sr,SR)
 | 
			
		||||
 | 
			
		||||
#define IS_CONF_DEBUG_OSPF_PACKET(a, b)                                        \
 | 
			
		||||
	(conf_debug_ospf_packet[a] & OSPF_DEBUG_##b)
 | 
			
		||||
#define IS_CONF_DEBUG_OSPF(a, b) (conf_debug_ospf_##a & OSPF_DEBUG_##b)
 | 
			
		||||
@ -119,6 +125,8 @@ extern unsigned long term_debug_ospf_lsa;
 | 
			
		||||
extern unsigned long term_debug_ospf_zebra;
 | 
			
		||||
extern unsigned long term_debug_ospf_nssa;
 | 
			
		||||
extern unsigned long term_debug_ospf_te;
 | 
			
		||||
extern unsigned long term_debug_ospf_ext;
 | 
			
		||||
extern unsigned long term_debug_ospf_sr;
 | 
			
		||||
 | 
			
		||||
/* Message Strings. */
 | 
			
		||||
extern char *ospf_lsa_type_str[];
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1769
									
								
								ospfd/ospf_ext.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1769
									
								
								ospfd/ospf_ext.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										196
									
								
								ospfd/ospf_ext.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								ospfd/ospf_ext.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,196 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This is an implementation of RFC7684 OSPFv2 Prefix/Link Attribute
 | 
			
		||||
 * Advertisement
 | 
			
		||||
 *
 | 
			
		||||
 * Module name: Extended Prefix/Link Opaque LSA header definition
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Anselme Sawadogo <anselmesawadogo@gmail.com>
 | 
			
		||||
 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016 - 2017 Orange Labs http://www.orange.com
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FRR.
 | 
			
		||||
 *
 | 
			
		||||
 * FRR is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any
 | 
			
		||||
 * later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FRR is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with FRR; see the file COPYING.  If not, write to the Free
 | 
			
		||||
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _FRR_OSPF_EXT_PREF_H_
 | 
			
		||||
#define _FRR_OSPF_EXT_PREF_H_
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Opaque LSA's link state ID for Extended Prefix/Link is
 | 
			
		||||
 * structured as follows.
 | 
			
		||||
 *
 | 
			
		||||
 *        24       16        8        0
 | 
			
		||||
 * +--------+--------+--------+--------+
 | 
			
		||||
 * |  7/8   |........|........|........|
 | 
			
		||||
 * +--------+--------+--------+--------+
 | 
			
		||||
 * |<-Type->|<------- Instance ------->|
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * Type:      IANA has assigned '7' for Extended Prefix Opaque LSA
 | 
			
		||||
 * 			    and '8' for Extended Link Opaque LSA
 | 
			
		||||
 * Instance:  User may select arbitrary 24-bit values to identify
 | 
			
		||||
 *            different instances of Extended Prefix/Link Opaque LSA
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *        24       16        8        0
 | 
			
		||||
 * +--------+--------+--------+--------+ ---
 | 
			
		||||
 * |   LS age        |Options |  10,11 |  A
 | 
			
		||||
 * +--------+--------+--------+--------+  |  Standard (Opaque) LSA header;
 | 
			
		||||
 * |   7/8  |        Instance          |  |
 | 
			
		||||
 * +--------+--------+--------+--------+  |  Type 10 or 11 are used for Extended
 | 
			
		||||
 * |        Advertising router         |  |  Prefix Opaque LSA
 | 
			
		||||
 * +--------+--------+--------+--------+  |
 | 
			
		||||
 * |        LS sequence number         |  |  Type 10 only is used for Extended
 | 
			
		||||
 * +--------+--------+--------+--------+  |  Link Opaque LSA
 | 
			
		||||
 * |   LS checksum   |     Length      |  V
 | 
			
		||||
 * +--------+--------+--------+--------+ ---
 | 
			
		||||
 * |      Type       |     Length      |  A
 | 
			
		||||
 * +--------+--------+--------+--------+  |  TLV part for Extended Prefix/Link
 | 
			
		||||
 * |                                   |  |  Opaque LSA;
 | 
			
		||||
 * ~              Values ...           ~  |  Values might be structured as a set
 | 
			
		||||
 * |                                   |  V  of sub-TLVs.
 | 
			
		||||
 * +--------+--------+--------+--------+ ---
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Global use constant numbers */
 | 
			
		||||
 | 
			
		||||
#define	MAX_LEGAL_EXT_INSTANCE_NUM	(0xffff)
 | 
			
		||||
#define LEGAL_EXT_INSTANCE_RANGE(i)	(0 <= (i) && (i) <= 0xffff)
 | 
			
		||||
 | 
			
		||||
/* Flags to manage Extended Link/Prefix Opaque LSA */
 | 
			
		||||
#define EXT_LPFLG_LSA_INACTIVE          0x00
 | 
			
		||||
#define EXT_LPFLG_LSA_ACTIVE            0x01
 | 
			
		||||
#define EXT_LPFLG_LSA_ENGAGED           0x02
 | 
			
		||||
#define EXT_LPFLG_LSA_LOOKUP_DONE       0x04
 | 
			
		||||
#define EXT_LPFLG_LSA_FORCED_REFRESH    0x08
 | 
			
		||||
#define EXT_LPFLG_FIB_ENTRY_SET         0x10
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Following section defines TLV (tag, length, value) structures,
 | 
			
		||||
 * used in Extended Prefix/Link Opaque LSA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix TLV Route Types */
 | 
			
		||||
#define EXT_TLV_PREF_ROUTE_UNSPEC	0
 | 
			
		||||
#define EXT_TLV_PREF_ROUTE_INTRA_AREA	1
 | 
			
		||||
#define EXT_TLV_PREF_ROUTE_INTER_AREA	3
 | 
			
		||||
#define EXT_TLV_PREF_ROUTE_AS_EXT	5
 | 
			
		||||
#define EXT_TLV_PREF_ROUTE_NSSA_EXT	7
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix and Extended Prefix Range TLVs'
 | 
			
		||||
 * Address family flag for IPv4 */
 | 
			
		||||
#define EXT_TLV_PREF_AF_IPV4		0
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix TLV Flags */
 | 
			
		||||
#define EXT_TLV_PREF_AFLG		0x80
 | 
			
		||||
#define EXT_TLV_PREF_NFLG		0x40
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix Range TLV Flags */
 | 
			
		||||
#define EXT_TLV_PREF_RANGE_IAFLG	0x80
 | 
			
		||||
 | 
			
		||||
/* ERO subtlvs Flags */
 | 
			
		||||
#define EXT_SUBTLV_ERO_LFLG		0x80
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix TLV see RFC 7684 section 2.1 */
 | 
			
		||||
#define EXT_TLV_PREFIX			1
 | 
			
		||||
#define EXT_TLV_PREFIX_SIZE		8
 | 
			
		||||
struct ext_tlv_prefix {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t route_type;
 | 
			
		||||
	u_int8_t pref_length;
 | 
			
		||||
	u_int8_t af;
 | 
			
		||||
	u_int8_t flags;
 | 
			
		||||
	struct in_addr address;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Extended Link TLV see RFC 7684 section 3.1 */
 | 
			
		||||
#define EXT_TLV_LINK			1
 | 
			
		||||
#define EXT_TLV_LINK_SIZE		12
 | 
			
		||||
struct ext_tlv_link {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t link_type;
 | 
			
		||||
	u_int8_t reserved[3];
 | 
			
		||||
	struct in_addr link_id;
 | 
			
		||||
	struct in_addr link_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Remote Interface Address Sub-TLV, Cisco experimental use Sub-TLV */
 | 
			
		||||
#define EXT_SUBTLV_RMT_ITF_ADDR         32768
 | 
			
		||||
#define EXT_SUBTLV_RMT_ITF_ADDR_SIZE	4
 | 
			
		||||
struct ext_subtlv_rmt_itf_addr {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	struct in_addr value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Internal structure to manage Extended Link/Prefix Opaque LSA */
 | 
			
		||||
struct ospf_ext_lp {
 | 
			
		||||
	bool enabled;
 | 
			
		||||
 | 
			
		||||
	/* Flags to manage this Extended Prefix/Link Opaque LSA */
 | 
			
		||||
	u_int32_t flags;
 | 
			
		||||
 | 
			
		||||
	/* Scope is area Opaque Type 10 or AS Opaque LSA Type 11 for
 | 
			
		||||
	 * Extended Prefix and area Opaque Type 10 for Extended Link */
 | 
			
		||||
	u_int8_t scope;
 | 
			
		||||
 | 
			
		||||
	/* area pointer if flooding is Type 10 Null if flooding is AS scope */
 | 
			
		||||
	struct ospf_area *area;
 | 
			
		||||
	struct in_addr area_id;
 | 
			
		||||
 | 
			
		||||
	/* List of interface with Segment Routing enable */
 | 
			
		||||
	struct list *iflist;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure to aggregate interfaces information for Extended Prefix/Link */
 | 
			
		||||
struct ext_itf {
 | 
			
		||||
	/* 24-bit Opaque-ID field value according to RFC 7684 specification */
 | 
			
		||||
	u_int32_t instance;
 | 
			
		||||
	u_int8_t type; /* Extended Prefix (7) or Link (8) */
 | 
			
		||||
 | 
			
		||||
	/* Reference pointer to a Zebra-interface. */
 | 
			
		||||
	struct interface *ifp;
 | 
			
		||||
 | 
			
		||||
	/* Area info in which this SR link belongs to. */
 | 
			
		||||
	struct ospf_area *area;
 | 
			
		||||
 | 
			
		||||
	/* Flags to manage this link parameters. */
 | 
			
		||||
	u_int32_t flags;
 | 
			
		||||
 | 
			
		||||
	/* SID type: Node, Adjacency or LAN Adjacency */
 | 
			
		||||
	enum sid_type stype;
 | 
			
		||||
 | 
			
		||||
	/* extended link/prefix TLV information */
 | 
			
		||||
	struct ext_tlv_prefix prefix;
 | 
			
		||||
	struct ext_subtlv_prefix_sid node_sid;
 | 
			
		||||
	struct ext_tlv_link link;
 | 
			
		||||
	struct ext_subtlv_adj_sid adj_sid[2];
 | 
			
		||||
	struct ext_subtlv_lan_adj_sid lan_sid[2];
 | 
			
		||||
 | 
			
		||||
	/* cisco experimental subtlv */
 | 
			
		||||
	struct ext_subtlv_rmt_itf_addr rmt_itf_addr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Prototypes. */
 | 
			
		||||
extern int ospf_ext_init(void);
 | 
			
		||||
extern void ospf_ext_term(void);
 | 
			
		||||
extern void ospf_ext_update_sr(bool);
 | 
			
		||||
extern int ospf_ext_schedule_prefix_index(struct interface *, u_int32_t,
 | 
			
		||||
					  struct prefix_ipv4 *);
 | 
			
		||||
#endif /* _FRR_OSPF_EXT_PREF_H_ */
 | 
			
		||||
@ -53,3 +53,5 @@ DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params")
 | 
			
		||||
DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message")
 | 
			
		||||
DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters")
 | 
			
		||||
DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters")
 | 
			
		||||
DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters")
 | 
			
		||||
DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters")
 | 
			
		||||
 | 
			
		||||
@ -52,5 +52,7 @@ DECLARE_MTYPE(OSPF_IF_PARAMS)
 | 
			
		||||
DECLARE_MTYPE(OSPF_MESSAGE)
 | 
			
		||||
DECLARE_MTYPE(OSPF_MPLS_TE)
 | 
			
		||||
DECLARE_MTYPE(OSPF_PCE_PARAMS)
 | 
			
		||||
DECLARE_MTYPE(OSPF_SR_PARAMS)
 | 
			
		||||
DECLARE_MTYPE(OSPF_EXT_PARAMS)
 | 
			
		||||
 | 
			
		||||
#endif /* _QUAGGA_OSPF_MEMORY_H */
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,10 @@
 | 
			
		||||
#include "ospfd/ospf_route.h"
 | 
			
		||||
#include "ospfd/ospf_ase.h"
 | 
			
		||||
#include "ospfd/ospf_zebra.h"
 | 
			
		||||
#include "ospfd/ospf_te.h"
 | 
			
		||||
#include "ospfd/ospf_sr.h"
 | 
			
		||||
#include "ospfd/ospf_ri.h"
 | 
			
		||||
#include "ospfd/ospf_ext.h"
 | 
			
		||||
 | 
			
		||||
DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table")
 | 
			
		||||
DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info")
 | 
			
		||||
@ -59,9 +63,6 @@ DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info")
 | 
			
		||||
 * Followings are initialize/terminate functions for Opaque-LSAs handling.
 | 
			
		||||
 *------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#include "ospfd/ospf_te.h"
 | 
			
		||||
#include "ospfd/ospf_ri.h"
 | 
			
		||||
 | 
			
		||||
#ifdef SUPPORT_OSPF_API
 | 
			
		||||
int ospf_apiserver_init(void);
 | 
			
		||||
void ospf_apiserver_term(void);
 | 
			
		||||
@ -85,9 +86,17 @@ void ospf_opaque_init(void)
 | 
			
		||||
	if (ospf_mpls_te_init() != 0)
 | 
			
		||||
		exit(1);
 | 
			
		||||
 | 
			
		||||
	/* Segment Routing init */
 | 
			
		||||
	if (ospf_sr_init() != 0)
 | 
			
		||||
		exit(1);
 | 
			
		||||
 | 
			
		||||
	if (ospf_router_info_init() != 0)
 | 
			
		||||
		exit(1);
 | 
			
		||||
 | 
			
		||||
	/* Force Extended Prefix/Link to Type 10 */
 | 
			
		||||
	if (ospf_ext_init() != 0)
 | 
			
		||||
		exit(1);
 | 
			
		||||
 | 
			
		||||
#ifdef SUPPORT_OSPF_API
 | 
			
		||||
	if ((ospf_apiserver_enable) && (ospf_apiserver_init() != 0))
 | 
			
		||||
		exit(1);
 | 
			
		||||
@ -102,6 +111,10 @@ void ospf_opaque_term(void)
 | 
			
		||||
 | 
			
		||||
	ospf_router_info_term();
 | 
			
		||||
 | 
			
		||||
	ospf_ext_term();
 | 
			
		||||
 | 
			
		||||
	ospf_sr_term();
 | 
			
		||||
 | 
			
		||||
#ifdef SUPPORT_OSPF_API
 | 
			
		||||
	ospf_apiserver_term();
 | 
			
		||||
#endif /* SUPPORT_OSPF_API */
 | 
			
		||||
@ -209,6 +222,12 @@ static const char *ospf_opaque_type_name(u_char opaque_type)
 | 
			
		||||
	case OPAQUE_TYPE_ROUTER_INFORMATION_LSA:
 | 
			
		||||
		name = "Router Information LSA";
 | 
			
		||||
		break;
 | 
			
		||||
	case OPAQUE_TYPE_EXTENDED_PREFIX_LSA:
 | 
			
		||||
		name = "Extended Prefix Opaque LSA";
 | 
			
		||||
		break;
 | 
			
		||||
	case OPAQUE_TYPE_EXTENDED_LINK_LSA:
 | 
			
		||||
		name = "Extended Link Opaque LSA";
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		if (OPAQUE_TYPE_RANGE_UNASSIGNED(opaque_type))
 | 
			
		||||
			name = "Unassigned";
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,9 @@
 | 
			
		||||
#define OPAQUE_TYPE_L1VPN_LSA                          5
 | 
			
		||||
#define OPAQUE_TYPE_ROUTER_INFORMATION_LSA             4
 | 
			
		||||
#define OPAQUE_TYPE_INTER_AS_LSA                       6
 | 
			
		||||
#define OPAQUE_TYPE_MAX                                6
 | 
			
		||||
#define OPAQUE_TYPE_EXTENDED_PREFIX_LSA                7
 | 
			
		||||
#define OPAQUE_TYPE_EXTENDED_LINK_LSA                  8
 | 
			
		||||
#define OPAQUE_TYPE_MAX                                8
 | 
			
		||||
 | 
			
		||||
/* Followings types are proposed in internet-draft documents. */
 | 
			
		||||
#define OPAQUE_TYPE_8021_QOSPF				129
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										423
									
								
								ospfd/ospf_ri.c
									
									
									
									
									
								
							
							
						
						
									
										423
									
								
								ospfd/ospf_ri.c
									
									
									
									
									
								
							@ -3,9 +3,8 @@
 | 
			
		||||
 * with support of RFC5088 PCE Capabilites announcement
 | 
			
		||||
 *
 | 
			
		||||
 * Module name: Router Information
 | 
			
		||||
 * Version:     0.99.22
 | 
			
		||||
 * Created:     2012-02-01 by Olivier Dugeon
 | 
			
		||||
 * Copyright (C) 2012 Orange Labs http://www.orange.com/
 | 
			
		||||
 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
 | 
			
		||||
 * Copyright (C) 2012 - 2017 Orange Labs http://www.orange.com/
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of GNU Quagga.
 | 
			
		||||
 *
 | 
			
		||||
@ -39,6 +38,7 @@
 | 
			
		||||
#include "thread.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "sockunion.h" /* for inet_aton() */
 | 
			
		||||
#include "mpls.h"
 | 
			
		||||
 | 
			
		||||
#include "ospfd/ospfd.h"
 | 
			
		||||
#include "ospfd/ospf_interface.h"
 | 
			
		||||
@ -55,8 +55,8 @@
 | 
			
		||||
#include "ospfd/ospf_route.h"
 | 
			
		||||
#include "ospfd/ospf_ase.h"
 | 
			
		||||
#include "ospfd/ospf_zebra.h"
 | 
			
		||||
#include "ospfd/ospf_sr.h"
 | 
			
		||||
#include "ospfd/ospf_ri.h"
 | 
			
		||||
#include "ospfd/ospf_te.h"
 | 
			
		||||
 | 
			
		||||
/* Store Router Information PCE TLV and SubTLV in network byte order. */
 | 
			
		||||
struct ospf_pce_info {
 | 
			
		||||
@ -69,6 +69,20 @@ struct ospf_pce_info {
 | 
			
		||||
	struct ri_pce_subtlv_cap_flag pce_cap_flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Store Router Information Segment Routing TLV and SubTLV in network byte order. */
 | 
			
		||||
struct ospf_ri_sr_info {
 | 
			
		||||
	bool enabled;
 | 
			
		||||
	/* Algorithms supported by the node */
 | 
			
		||||
	struct ri_sr_tlv_sr_algorithm algo;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Segment Routing Global Block i.e. label range
 | 
			
		||||
	 * Only one range supported in this code
 | 
			
		||||
	 */
 | 
			
		||||
	struct ri_sr_tlv_sid_label_range range;
 | 
			
		||||
	/* Maximum SID Depth supported by the node */
 | 
			
		||||
	struct ri_sr_tlv_node_msd msd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Following structure are internal use only. */
 | 
			
		||||
struct ospf_router_info {
 | 
			
		||||
	bool enabled;
 | 
			
		||||
@ -77,7 +91,7 @@ struct ospf_router_info {
 | 
			
		||||
	u_int8_t scope;
 | 
			
		||||
 | 
			
		||||
/* Flags to manage this router information. */
 | 
			
		||||
#define RIFLG_LSA_ENGAGED			0x1
 | 
			
		||||
#define RIFLG_LSA_ENGAGED		0x1
 | 
			
		||||
#define RIFLG_LSA_FORCED_REFRESH	0x2
 | 
			
		||||
	u_int32_t flags;
 | 
			
		||||
 | 
			
		||||
@ -90,6 +104,9 @@ struct ospf_router_info {
 | 
			
		||||
 | 
			
		||||
	/* Store PCE capability LSA */
 | 
			
		||||
	struct ospf_pce_info pce_info;
 | 
			
		||||
 | 
			
		||||
	/* Store SR capability LSA */
 | 
			
		||||
	struct ospf_ri_sr_info sr_info;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -113,15 +130,19 @@ static int ospf_router_info_lsa_originate(void *arg);
 | 
			
		||||
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
 | 
			
		||||
static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode);
 | 
			
		||||
static void ospf_router_info_register_vty(void);
 | 
			
		||||
static int ospf_router_info_lsa_update(struct ospf_lsa *lsa);
 | 
			
		||||
static void del_pce_info(void *val);
 | 
			
		||||
 | 
			
		||||
int ospf_router_info_init(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	zlog_info("RI -> Initialize Router Information");
 | 
			
		||||
 | 
			
		||||
	memset(&OspfRI, 0, sizeof(struct ospf_router_info));
 | 
			
		||||
	OspfRI.enabled = false;
 | 
			
		||||
	OspfRI.registered = 0;
 | 
			
		||||
	OspfRI.scope = OSPF_OPAQUE_AS_LSA;
 | 
			
		||||
	OspfRI.area_id.s_addr = 0;
 | 
			
		||||
	OspfRI.flags = 0;
 | 
			
		||||
 | 
			
		||||
	/* Initialize pce domain and neighbor list */
 | 
			
		||||
@ -131,6 +152,9 @@ int ospf_router_info_init(void)
 | 
			
		||||
	OspfRI.pce_info.pce_neighbor = list_new();
 | 
			
		||||
	OspfRI.pce_info.pce_neighbor->del = del_pce_info;
 | 
			
		||||
 | 
			
		||||
	/* Initialize Segment Routing information structure */
 | 
			
		||||
	OspfRI.sr_info.enabled = false;
 | 
			
		||||
 | 
			
		||||
	ospf_router_info_register_vty();
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
@ -143,19 +167,22 @@ static int ospf_router_info_register(u_int8_t scope)
 | 
			
		||||
	if (OspfRI.registered)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	zlog_info("Register Router Information with scope %s(%d)",
 | 
			
		||||
	zlog_info("RI -> Register Router Information with scope %s(%d)",
 | 
			
		||||
		  scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
 | 
			
		||||
	rc = ospf_register_opaque_functab(
 | 
			
		||||
		scope, OPAQUE_TYPE_ROUTER_INFORMATION_LSA,
 | 
			
		||||
		NULL, /* new interface */
 | 
			
		||||
		NULL, /* del interface */
 | 
			
		||||
		ospf_router_info_ism_change, ospf_router_info_nsm_change,
 | 
			
		||||
		ospf_router_info_ism_change,
 | 
			
		||||
		ospf_router_info_nsm_change,
 | 
			
		||||
		ospf_router_info_config_write_router,
 | 
			
		||||
		NULL, /* Config. write interface */
 | 
			
		||||
		NULL, /* Config. write debug */
 | 
			
		||||
		ospf_router_info_show_info, ospf_router_info_lsa_originate,
 | 
			
		||||
		ospf_router_info_lsa_refresh, NULL, /* new_lsa_hook */
 | 
			
		||||
		NULL);				    /* del_lsa_hook */
 | 
			
		||||
		ospf_router_info_show_info,
 | 
			
		||||
		ospf_router_info_lsa_originate,
 | 
			
		||||
		ospf_router_info_lsa_refresh,
 | 
			
		||||
		ospf_router_info_lsa_update,
 | 
			
		||||
		NULL); /* del_lsa_hook */
 | 
			
		||||
 | 
			
		||||
	if (rc != 0) {
 | 
			
		||||
		zlog_warn(
 | 
			
		||||
@ -204,6 +231,20 @@ static void del_pce_info(void *val)
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Catch RI LSA flooding Scope for ospf_ext.[h,c] code */
 | 
			
		||||
struct scope_info ospf_router_info_get_flooding_scope(void)
 | 
			
		||||
{
 | 
			
		||||
	struct scope_info flooding_scope;
 | 
			
		||||
	if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
 | 
			
		||||
		flooding_scope.scope = OSPF_OPAQUE_AS_LSA;
 | 
			
		||||
		flooding_scope.area_id.s_addr = 0;
 | 
			
		||||
		return flooding_scope;
 | 
			
		||||
	}
 | 
			
		||||
	flooding_scope.scope = OSPF_OPAQUE_AREA_LSA;
 | 
			
		||||
	flooding_scope.area_id.s_addr = OspfRI.area_id.s_addr;
 | 
			
		||||
	return flooding_scope;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*
 | 
			
		||||
 * Followings are control functions for ROUTER INFORMATION parameters
 | 
			
		||||
 *management.
 | 
			
		||||
@ -399,6 +440,84 @@ static void set_pce_cap_flag(u_int32_t cap, struct ospf_pce_info *pce)
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Segment Routing TLV setter */
 | 
			
		||||
 | 
			
		||||
/* Algorithm SubTLV - section 3.1 */
 | 
			
		||||
static void set_sr_algorithm(u_int8_t algo)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	OspfRI.sr_info.algo.value[0] = algo;
 | 
			
		||||
	for (int i = 1; i < ALGORITHM_COUNT; i++)
 | 
			
		||||
		OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
 | 
			
		||||
 | 
			
		||||
	/* Set TLV type and length == only 1 Algorithm */
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.algo) = htons(RI_SR_TLV_SR_ALGORITHM);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.algo) = htons(sizeof(u_int8_t));
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* unset Aglogithm SubTLV */
 | 
			
		||||
static void unset_sr_algorithm(u_int8_t algo)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < ALGORITHM_COUNT; i++)
 | 
			
		||||
		OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
 | 
			
		||||
 | 
			
		||||
	/* Unset TLV type and length */
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.algo) = htons(0);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.algo) = htons(0);
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Segment Routing Global Block SubTLV - section 3.2 */
 | 
			
		||||
static void set_sr_sid_label_range(struct sr_srgb srgb)
 | 
			
		||||
{
 | 
			
		||||
	/* Set Header */
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.range) = htons(RI_SR_TLV_SID_LABEL_RANGE);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.range) =
 | 
			
		||||
		htons(SUBTLV_SID_LABEL_SIZE + sizeof(u_int32_t));
 | 
			
		||||
	/* Set Range Size */
 | 
			
		||||
	OspfRI.sr_info.range.size = htonl(SET_RANGE_SIZE(srgb.range_size));
 | 
			
		||||
	/* Set Lower bound label SubTLV */
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.range.lower) = htons(SUBTLV_SID_LABEL);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.range.lower) = htons(SID_RANGE_LABEL_LENGTH);
 | 
			
		||||
	OspfRI.sr_info.range.lower.value = htonl(SET_LABEL(srgb.lower_bound));
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unset this SRGB SubTLV */
 | 
			
		||||
static void unset_sr_sid_label_range()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.range) = htons(0);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.range) = htons(0);
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.range.lower) = htons(0);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.range.lower) = htons(0);
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set Maximum Stack Depth for this router */
 | 
			
		||||
static void set_sr_node_msd(u_int8_t msd)
 | 
			
		||||
{
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.msd) = htons(RI_SR_TLV_NODE_MSD);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.msd) = htons(sizeof(u_int32_t));
 | 
			
		||||
	OspfRI.sr_info.msd.value = msd;
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unset this router MSD */
 | 
			
		||||
static void unset_sr_node_msd()
 | 
			
		||||
{
 | 
			
		||||
	TLV_TYPE(OspfRI.sr_info.msd) = htons(0);
 | 
			
		||||
	TLV_LEN(OspfRI.sr_info.msd) = htons(0);
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void unset_param(struct tlv_header *tlv)
 | 
			
		||||
{
 | 
			
		||||
@ -466,11 +585,62 @@ static int is_mandated_params_set(struct ospf_router_info ori)
 | 
			
		||||
	    && (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0))
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	if ((ori.sr_info.enabled) && (ntohs(TLV_TYPE(ori.sr_info.algo)) == 0)
 | 
			
		||||
	    && (ntohs(TLV_TYPE(ori.sr_info.range)) == 0))
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	rc = 1;
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used by Segment Routing to set new TLVs and Sub-TLVs values
 | 
			
		||||
 *
 | 
			
		||||
 * @param enable To activate or not Segment Routing router Information flooding
 | 
			
		||||
 * @param size   Size of Label Range i.e. SRGB size
 | 
			
		||||
 * @param lower  Lower bound of the Label Range i.e. SRGB first label
 | 
			
		||||
 * @param msd    Maximum label Stack Depth suported by the router
 | 
			
		||||
 *
 | 
			
		||||
 * @return none
 | 
			
		||||
 */
 | 
			
		||||
void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, u_int8_t msd)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	/* First activate and initialize Router Information is necessary */
 | 
			
		||||
	if (!OspfRI.enabled) {
 | 
			
		||||
		OspfRI.enabled = true;
 | 
			
		||||
		initialize_params(&OspfRI);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (IS_DEBUG_OSPF_SR)
 | 
			
		||||
		zlog_debug("RI-> %s Routing Information for Segment Routing",
 | 
			
		||||
			enable ? "Enable" : "Disable");
 | 
			
		||||
 | 
			
		||||
	/* Unset or Set SR parameters */
 | 
			
		||||
	if (!enable) {
 | 
			
		||||
		unset_sr_algorithm(SR_ALGORITHM_SPF);
 | 
			
		||||
		unset_sr_sid_label_range();
 | 
			
		||||
		unset_sr_node_msd();
 | 
			
		||||
		OspfRI.sr_info.enabled = false;
 | 
			
		||||
	} else {
 | 
			
		||||
		// Only SR_ALGORITHM_SPF is supported
 | 
			
		||||
		set_sr_algorithm(SR_ALGORITHM_SPF);
 | 
			
		||||
		set_sr_sid_label_range(srgb);
 | 
			
		||||
		if (msd != 0)
 | 
			
		||||
			set_sr_node_msd(msd);
 | 
			
		||||
		else
 | 
			
		||||
			unset_sr_node_msd();
 | 
			
		||||
		OspfRI.sr_info.enabled = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Refresh if already engaged or originate RI LSA */
 | 
			
		||||
	if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
 | 
			
		||||
		ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
 | 
			
		||||
	else
 | 
			
		||||
		ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*
 | 
			
		||||
 * Followings are callback functions against generic Opaque-LSAs handling.
 | 
			
		||||
 *------------------------------------------------------------------------*/
 | 
			
		||||
@ -519,12 +689,22 @@ static void ospf_router_info_lsa_body_set(struct stream *s)
 | 
			
		||||
	/* Build Router Information TLV */
 | 
			
		||||
	build_tlv(s, &OspfRI.router_cap.header);
 | 
			
		||||
 | 
			
		||||
	/* Compute PCE Info header first */
 | 
			
		||||
	set_pce_header (&OspfRI.pce_info);
 | 
			
		||||
	/* Build Segment Routing TLVs if enabled */
 | 
			
		||||
	if (OspfRI.sr_info.enabled) {
 | 
			
		||||
		/* Build Algorithm TLV */
 | 
			
		||||
		build_tlv(s, &TLV_HDR(OspfRI.sr_info.algo));
 | 
			
		||||
		/* Build SRGB TLV */
 | 
			
		||||
		build_tlv(s, &TLV_HDR(OspfRI.sr_info.range));
 | 
			
		||||
		/* Build MSD TLV */
 | 
			
		||||
		build_tlv(s, &TLV_HDR(OspfRI.sr_info.msd));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Add RI PCE TLV if it is set */
 | 
			
		||||
	if (OspfRI.pce_info.enabled) {
 | 
			
		||||
 | 
			
		||||
		/* Compute PCE Info header first */
 | 
			
		||||
		set_pce_header (&OspfRI.pce_info);
 | 
			
		||||
 | 
			
		||||
		/* Build PCE TLV */
 | 
			
		||||
		build_tlv_header(s, &OspfRI.pce_info.pce_header.header);
 | 
			
		||||
 | 
			
		||||
@ -855,6 +1035,38 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback to handle Segment Routing information */
 | 
			
		||||
static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	/* Sanity Check */
 | 
			
		||||
	if (lsa == NULL) {
 | 
			
		||||
		zlog_warn("OSPF-RI (ospf_router_info_lsa_update): Abort! LSA is NULL");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if it is not my LSA */
 | 
			
		||||
	if (IS_LSA_SELF(lsa))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Process only Router Information LSA */
 | 
			
		||||
	if (GET_OPAQUE_TYPE(
 | 
			
		||||
			ntohl(lsa->data->id.s_addr)) != OPAQUE_TYPE_ROUTER_INFORMATION_LSA)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Check if Router Info & Segment Routing are enable */
 | 
			
		||||
	if (!OspfRI.enabled || !OspfRI.sr_info.enabled)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Call Segment Routing LSA update or deletion */
 | 
			
		||||
	if (!IS_LSA_MAXAGE(lsa))
 | 
			
		||||
		ospf_sr_ri_lsa_update(lsa);
 | 
			
		||||
	else
 | 
			
		||||
		ospf_sr_ri_lsa_delete(lsa);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*
 | 
			
		||||
 * Followings are vty session control functions.
 | 
			
		||||
 *------------------------------------------------------------------------*/
 | 
			
		||||
@ -1021,6 +1233,98 @@ static u_int16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
 | 
			
		||||
	return sum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Display Segment Routing Algorithm TLV information */
 | 
			
		||||
static u_int16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
 | 
			
		||||
{
 | 
			
		||||
	struct ri_sr_tlv_sr_algorithm *algo =
 | 
			
		||||
		(struct ri_sr_tlv_sr_algorithm *)tlvh;
 | 
			
		||||
	int i;
 | 
			
		||||
	if (vty != NULL) {
 | 
			
		||||
		vty_out(vty, "  Segment Routing Algorithm TLV:\n");
 | 
			
		||||
		for (i = 0; i < ntohs(algo->header.length); i++) {
 | 
			
		||||
			switch (algo->value[i]) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				vty_out(vty, "    Algorithm %d: SPF\n", i);
 | 
			
		||||
				break;
 | 
			
		||||
			case 1:
 | 
			
		||||
				vty_out(vty, "    Algorithm %d: Strict SPF\n",
 | 
			
		||||
					i);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				vty_out(vty,
 | 
			
		||||
					"  Algorithm %d: Unknown value %d\n", i,
 | 
			
		||||
					algo->value[i]);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	else {
 | 
			
		||||
		zlog_debug("  Segment Routing Algorithm TLV:\n");
 | 
			
		||||
		for (i = 0; i < ntohs(algo->header.length); i++)
 | 
			
		||||
			switch (algo->value[i]) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				zlog_debug("    Algorithm %d: SPF\n", i);
 | 
			
		||||
				break;
 | 
			
		||||
			case 1:
 | 
			
		||||
				zlog_debug("    Algorithm %d: Strict SPF\n", i);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				zlog_debug(
 | 
			
		||||
					"    Algorithm %d: Unknown value %d\n",
 | 
			
		||||
					i, algo->value[i]);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TLV_SIZE(tlvh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Display Segment Routing SID/Label Range TLV information */
 | 
			
		||||
static u_int16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
 | 
			
		||||
{
 | 
			
		||||
	struct ri_sr_tlv_sid_label_range *range =
 | 
			
		||||
		(struct ri_sr_tlv_sid_label_range *)tlvh;
 | 
			
		||||
 | 
			
		||||
	if (vty != NULL) {
 | 
			
		||||
		vty_out(vty,
 | 
			
		||||
			"  Segment Routing Range TLV:\n"
 | 
			
		||||
			"    Range Size = %d\n"
 | 
			
		||||
			"    SID Label = %d\n\n",
 | 
			
		||||
			GET_RANGE_SIZE(ntohl(range->size)),
 | 
			
		||||
			GET_LABEL(ntohl(range->lower.value)));
 | 
			
		||||
	} else {
 | 
			
		||||
		zlog_debug(
 | 
			
		||||
			"  Segment Routing Range TLV:\n"
 | 
			
		||||
			"    Range Size = %d\n"
 | 
			
		||||
			"    SID Label = %d\n\n",
 | 
			
		||||
			GET_RANGE_SIZE(ntohl(range->size)),
 | 
			
		||||
			GET_LABEL(ntohl(range->lower.value)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TLV_SIZE(tlvh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Display Segment Routing Maximum Stack Depth TLV information */
 | 
			
		||||
static u_int16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
 | 
			
		||||
{
 | 
			
		||||
	struct ri_sr_tlv_node_msd *msd = (struct ri_sr_tlv_node_msd *)tlvh;
 | 
			
		||||
 | 
			
		||||
	if (vty != NULL) {
 | 
			
		||||
		vty_out(vty,
 | 
			
		||||
			"  Segment Routing MSD TLV:\n"
 | 
			
		||||
			"    Node Maximum Stack Depth = %d\n",
 | 
			
		||||
			msd->value);
 | 
			
		||||
	} else {
 | 
			
		||||
		zlog_debug(
 | 
			
		||||
			"  Segment Routing MSD TLV:\n"
 | 
			
		||||
			"    Node Maximum Stack Depth = %d\n",
 | 
			
		||||
			msd->value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TLV_SIZE(tlvh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
 | 
			
		||||
{
 | 
			
		||||
	struct lsa_header *lsah = (struct lsa_header *)lsa->data;
 | 
			
		||||
@ -1041,6 +1345,16 @@ static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
 | 
			
		||||
			sum += TLV_HDR_SIZE;
 | 
			
		||||
			sum += show_vty_pce_info(vty, tlvh, length - sum);
 | 
			
		||||
			break;
 | 
			
		||||
		case RI_SR_TLV_SR_ALGORITHM:
 | 
			
		||||
			sum += show_vty_sr_algorithm(vty, tlvh);
 | 
			
		||||
			break;
 | 
			
		||||
		case RI_SR_TLV_SID_LABEL_RANGE:
 | 
			
		||||
			sum += show_vty_sr_range(vty, tlvh);
 | 
			
		||||
			break;
 | 
			
		||||
		case RI_SR_TLV_NODE_MSD:
 | 
			
		||||
			sum += show_vty_sr_msd(vty, tlvh);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			sum += show_vty_unknown_tlv(vty, tlvh);
 | 
			
		||||
			break;
 | 
			
		||||
@ -1058,53 +1372,54 @@ static void ospf_router_info_config_write_router(struct vty *vty)
 | 
			
		||||
	struct ri_pce_subtlv_neighbor *neighbor;
 | 
			
		||||
	struct in_addr tmp;
 | 
			
		||||
 | 
			
		||||
	if (OspfRI.enabled) {
 | 
			
		||||
		if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
 | 
			
		||||
			vty_out(vty, " router-info as\n");
 | 
			
		||||
		else
 | 
			
		||||
			vty_out(vty, " router-info area %s\n",
 | 
			
		||||
				inet_ntoa(OspfRI.area_id));
 | 
			
		||||
	if (!OspfRI.enabled)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
		if (OspfRI.pce_info.enabled) {
 | 
			
		||||
	if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
 | 
			
		||||
		vty_out(vty, " router-info as\n");
 | 
			
		||||
	else
 | 
			
		||||
		vty_out(vty, " router-info area %s\n",
 | 
			
		||||
			inet_ntoa(OspfRI.area_id));
 | 
			
		||||
 | 
			
		||||
			if (pce->pce_address.header.type != 0)
 | 
			
		||||
				vty_out(vty, "  pce address %s\n",
 | 
			
		||||
					inet_ntoa(pce->pce_address.address.value));
 | 
			
		||||
	if (OspfRI.pce_info.enabled) {
 | 
			
		||||
 | 
			
		||||
			if (pce->pce_cap_flag.header.type != 0)
 | 
			
		||||
				vty_out(vty, "  pce flag 0x%x\n",
 | 
			
		||||
					ntohl(pce->pce_cap_flag.value));
 | 
			
		||||
		if (pce->pce_address.header.type != 0)
 | 
			
		||||
			vty_out(vty, "  pce address %s\n",
 | 
			
		||||
				inet_ntoa(pce->pce_address.address.value));
 | 
			
		||||
 | 
			
		||||
			for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
 | 
			
		||||
				if (domain->header.type != 0) {
 | 
			
		||||
					if (domain->type == PCE_DOMAIN_TYPE_AREA) {
 | 
			
		||||
						tmp.s_addr = domain->value;
 | 
			
		||||
						vty_out(vty, "  pce domain area %s\n",
 | 
			
		||||
							inet_ntoa(tmp));
 | 
			
		||||
					} else {
 | 
			
		||||
						vty_out(vty, "  pce domain as %d\n",
 | 
			
		||||
							ntohl(domain->value));
 | 
			
		||||
					}
 | 
			
		||||
		if (pce->pce_cap_flag.header.type != 0)
 | 
			
		||||
			vty_out(vty, "  pce flag 0x%x\n",
 | 
			
		||||
				ntohl(pce->pce_cap_flag.value));
 | 
			
		||||
 | 
			
		||||
		for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
 | 
			
		||||
			if (domain->header.type != 0) {
 | 
			
		||||
				if (domain->type == PCE_DOMAIN_TYPE_AREA) {
 | 
			
		||||
					tmp.s_addr = domain->value;
 | 
			
		||||
					vty_out(vty, "  pce domain area %s\n",
 | 
			
		||||
						inet_ntoa(tmp));
 | 
			
		||||
				} else {
 | 
			
		||||
					vty_out(vty, "  pce domain as %d\n",
 | 
			
		||||
						ntohl(domain->value));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
 | 
			
		||||
				if (neighbor->header.type != 0) {
 | 
			
		||||
					if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
 | 
			
		||||
						tmp.s_addr = neighbor->value;
 | 
			
		||||
						vty_out(vty, "  pce neighbor area %s\n",
 | 
			
		||||
							inet_ntoa(tmp));
 | 
			
		||||
					} else {
 | 
			
		||||
						vty_out(vty, "  pce neighbor as %d\n",
 | 
			
		||||
							ntohl(neighbor->value));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (pce->pce_scope.header.type != 0)
 | 
			
		||||
				vty_out(vty, "  pce scope 0x%x\n",
 | 
			
		||||
					ntohl(OspfRI.pce_info.pce_scope.value));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
 | 
			
		||||
			if (neighbor->header.type != 0) {
 | 
			
		||||
				if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
 | 
			
		||||
					tmp.s_addr = neighbor->value;
 | 
			
		||||
					vty_out(vty, "  pce neighbor area %s\n",
 | 
			
		||||
						inet_ntoa(tmp));
 | 
			
		||||
				} else {
 | 
			
		||||
					vty_out(vty, "  pce neighbor as %d\n",
 | 
			
		||||
						ntohl(neighbor->value));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (pce->pce_scope.header.type != 0)
 | 
			
		||||
			vty_out(vty, "  pce scope 0x%x\n",
 | 
			
		||||
				ntohl(OspfRI.pce_info.pce_scope.value));
 | 
			
		||||
	}
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
@ -1539,7 +1854,7 @@ DEFUN (show_ip_opsf_router_info_pce,
 | 
			
		||||
	struct ri_pce_subtlv_domain *domain;
 | 
			
		||||
	struct ri_pce_subtlv_neighbor *neighbor;
 | 
			
		||||
 | 
			
		||||
	if (OspfRI.enabled) {
 | 
			
		||||
	if ((OspfRI.enabled) && (OspfRI.pce_info.enabled)) {
 | 
			
		||||
		vty_out(vty, "--- PCE parameters ---\n");
 | 
			
		||||
 | 
			
		||||
		if (pce->pce_address.header.type != 0)
 | 
			
		||||
@ -1568,7 +1883,7 @@ DEFUN (show_ip_opsf_router_info_pce,
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
		vty_out(vty,
 | 
			
		||||
			"  Router Information is disabled on this router\n");
 | 
			
		||||
			"  PCE info is disabled on this router\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CMD_SUCCESS;
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This is an implementation of RFC4970 Router Information
 | 
			
		||||
 * with support of RFC5088 PCE Capabilites announcement
 | 
			
		||||
 * and support of draft-ietf-ospf-segment-routing-extensions-18
 | 
			
		||||
 * for Segment Routing Capabilities announcement
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * Module name: Router Information
 | 
			
		||||
 * Version:     0.99.22
 | 
			
		||||
 * Created:     2012-02-01 by Olivier Dugeon
 | 
			
		||||
 * Copyright (C) 2012 Orange Labs http://www.orange.com/
 | 
			
		||||
 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
 | 
			
		||||
 * Copyright (C) 2012 - 2017 Orange Labs http://www.orange.com/
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of GNU Zebra.
 | 
			
		||||
 *
 | 
			
		||||
@ -33,7 +35,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *        24       16        8        0
 | 
			
		||||
 * +--------+--------+--------+--------+
 | 
			
		||||
 * |    1   |  MBZ   |........|........|
 | 
			
		||||
 * |    4   |  MBZ   |........|........|
 | 
			
		||||
 * +--------+--------+--------+--------+
 | 
			
		||||
 * |<-Type->|<Resv'd>|<-- Instance --->|
 | 
			
		||||
 *
 | 
			
		||||
@ -57,9 +59,8 @@
 | 
			
		||||
 * +--------+--------+--------+--------+  |
 | 
			
		||||
 * |   LS checksum   |     Length      |  V
 | 
			
		||||
 * +--------+--------+--------+--------+ ---
 | 
			
		||||
 * |      Type       |     Length      |  A
 | 
			
		||||
 * +--------+--------+--------+--------+  |  TLV part for Router Information;
 | 
			
		||||
 * Values might be
 | 
			
		||||
 * |      Type       |     Length      |  A  TLV part for Router Information;
 | 
			
		||||
 * +--------+--------+--------+--------+  |  Values might be
 | 
			
		||||
 * |              Values ...           |  V  structured as a set of sub-TLVs.
 | 
			
		||||
 * +--------+--------+--------+--------+ ---
 | 
			
		||||
 */
 | 
			
		||||
@ -68,9 +69,9 @@
 | 
			
		||||
 * Following section defines TLV body parts.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Up to now, 8 code point have been assigned to Router Information */
 | 
			
		||||
/* Up to now, 11 code points have been assigned to Router Information */
 | 
			
		||||
/* Only type 1 Router Capabilities and 6 PCE are supported with this code */
 | 
			
		||||
#define RI_IANA_MAX_TYPE		8
 | 
			
		||||
#define RI_IANA_MAX_TYPE		11
 | 
			
		||||
 | 
			
		||||
/* RFC4970: Router Information Capabilities TLV */ /* Mandatory */
 | 
			
		||||
#define RI_TLV_CAPABILITIES		1
 | 
			
		||||
@ -80,12 +81,13 @@ struct ri_tlv_router_cap {
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define RI_GRACE_RESTART	0x01
 | 
			
		||||
#define RI_GRACE_HELPER		0x02
 | 
			
		||||
#define RI_STUB_SUPPORT		0x04
 | 
			
		||||
#define RI_TE_SUPPORT		0x08
 | 
			
		||||
#define RI_P2P_OVER_LAN		0x10
 | 
			
		||||
#define RI_TE_EXPERIMENTAL	0x20
 | 
			
		||||
/* Capabilities bits are left align */
 | 
			
		||||
#define RI_GRACE_RESTART	0x80000000
 | 
			
		||||
#define RI_GRACE_HELPER		0x40000000
 | 
			
		||||
#define RI_STUB_SUPPORT		0x20000000
 | 
			
		||||
#define RI_TE_SUPPORT		0x10000000
 | 
			
		||||
#define RI_P2P_OVER_LAN		0x08000000
 | 
			
		||||
#define RI_TE_EXPERIMENTAL	0x04000000
 | 
			
		||||
 | 
			
		||||
#define RI_TLV_LENGTH		4
 | 
			
		||||
 | 
			
		||||
@ -151,22 +153,30 @@ struct ri_pce_subtlv_neighbor {
 | 
			
		||||
#define RI_PCE_SUBTLV_CAP_FLAG		5
 | 
			
		||||
 | 
			
		||||
#define PCE_CAP_GMPLS_LINK		0x0001
 | 
			
		||||
#define PCE_CAP_BIDIRECTIONAL	0x0002
 | 
			
		||||
#define PCE_CAP_DIVERSE_PATH	0x0004
 | 
			
		||||
#define PCE_CAP_LOAD_BALANCE	0x0008
 | 
			
		||||
#define PCE_CAP_SYNCHRONIZED	0x0010
 | 
			
		||||
#define PCE_CAP_BIDIRECTIONAL		0x0002
 | 
			
		||||
#define PCE_CAP_DIVERSE_PATH		0x0004
 | 
			
		||||
#define PCE_CAP_LOAD_BALANCE		0x0008
 | 
			
		||||
#define PCE_CAP_SYNCHRONIZED		0x0010
 | 
			
		||||
#define PCE_CAP_OBJECTIVES		0x0020
 | 
			
		||||
#define PCE_CAP_ADDITIVE		0x0040
 | 
			
		||||
#define PCE_CAP_PRIORIZATION	0x0080
 | 
			
		||||
#define PCE_CAP_MULTIPLE_REQ	0x0100
 | 
			
		||||
#define PCE_CAP_PRIORIZATION		0x0080
 | 
			
		||||
#define PCE_CAP_MULTIPLE_REQ		0x0100
 | 
			
		||||
 | 
			
		||||
struct ri_pce_subtlv_cap_flag {
 | 
			
		||||
	struct tlv_header header; /* Type = 5; Length = n x 4 bytes. */
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure to share flooding scope info for Segment Routing */
 | 
			
		||||
struct scope_info {
 | 
			
		||||
	u_int8_t scope;
 | 
			
		||||
	struct in_addr area_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Prototypes. */
 | 
			
		||||
extern int ospf_router_info_init(void);
 | 
			
		||||
extern void ospf_router_info_term(void);
 | 
			
		||||
 | 
			
		||||
extern int ospf_router_info_enable(void);
 | 
			
		||||
extern void ospf_router_info_update_sr(bool, struct sr_srgb, u_int8_t);
 | 
			
		||||
extern struct scope_info ospf_router_info_get_flooding_scope(void);
 | 
			
		||||
#endif /* _ZEBRA_OSPF_ROUTER_INFO_H */
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,7 @@
 | 
			
		||||
#include "ospfd/ospf_ase.h"
 | 
			
		||||
#include "ospfd/ospf_abr.h"
 | 
			
		||||
#include "ospfd/ospf_dump.h"
 | 
			
		||||
#include "ospfd/ospf_sr.h"
 | 
			
		||||
 | 
			
		||||
/* Variables to ensure a SPF scheduled log message is printed only once */
 | 
			
		||||
 | 
			
		||||
@ -1339,7 +1340,6 @@ static int ospf_spf_calculate_timer(struct thread *thread)
 | 
			
		||||
 | 
			
		||||
	ospf_ase_calculate_timer_add(ospf);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (IS_DEBUG_OSPF_EVENT)
 | 
			
		||||
		zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu",
 | 
			
		||||
			   __PRETTY_FUNCTION__,
 | 
			
		||||
@ -1366,6 +1366,9 @@ static int ospf_spf_calculate_timer(struct thread *thread)
 | 
			
		||||
		ospf_abr_task(ospf);
 | 
			
		||||
	abr_time = monotime_since(&start_time, NULL);
 | 
			
		||||
 | 
			
		||||
	/* Schedule Segment Routing update */
 | 
			
		||||
	ospf_sr_update_timer_add(ospf);
 | 
			
		||||
 | 
			
		||||
	total_spf_time =
 | 
			
		||||
		monotime_since(&spf_start_time, &ospf->ts_spf_duration);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2186
									
								
								ospfd/ospf_sr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2186
									
								
								ospfd/ospf_sr.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										315
									
								
								ospfd/ospf_sr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								ospfd/ospf_sr.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,315 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This is an implementation of Segment Routing
 | 
			
		||||
 * as per draft draft-ietf-ospf-segment-routing-extensions-24
 | 
			
		||||
 *
 | 
			
		||||
 * Module name: Segment Routing header definitions
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
 | 
			
		||||
 * Author: Anselme Sawadogo <anselmesawadogo@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016 - 2017 Orange Labs http://www.orange.com
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FRR.
 | 
			
		||||
 *
 | 
			
		||||
 * FRR is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any
 | 
			
		||||
 * later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FRR is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with FRR; see the file COPYING.  If not, write to the Free
 | 
			
		||||
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _FRR_OSPF_SR_H
 | 
			
		||||
#define _FRR_OSPF_SR_H
 | 
			
		||||
 | 
			
		||||
/* Default Route priority for OSPF Segment Routing */
 | 
			
		||||
#define OSPF_SR_PRIORITY_DEFAULT	10
 | 
			
		||||
 | 
			
		||||
/* macros and constants for segment routing */
 | 
			
		||||
#define SET_RANGE_SIZE_MASK             0xffffff00
 | 
			
		||||
#define GET_RANGE_SIZE_MASK             0x00ffffff
 | 
			
		||||
#define SET_LABEL_MASK                  0xffffff00
 | 
			
		||||
#define GET_LABEL_MASK                  0x00ffffff
 | 
			
		||||
#define SET_RANGE_SIZE(range_size) ((range_size << 8) & SET_RANGE_SIZE_MASK)
 | 
			
		||||
#define GET_RANGE_SIZE(range_size) ((range_size >> 8) & GET_RANGE_SIZE_MASK)
 | 
			
		||||
#define SET_LABEL(label) ((label << 8) & SET_LABEL_MASK)
 | 
			
		||||
#define GET_LABEL(label) ((label >> 8) & GET_LABEL_MASK)
 | 
			
		||||
 | 
			
		||||
/* Label range for Adj-SID attribution purpose. See ospf_ext.c */
 | 
			
		||||
#define ADJ_SID_MIN                     50000
 | 
			
		||||
#define ADJ_SID_MAX                     51000
 | 
			
		||||
 | 
			
		||||
#define OSPF_SR_DEFAULT_METRIC		1
 | 
			
		||||
 | 
			
		||||
/* Segment Routing TLVs as per draft-ietf-ospf-segment-routing-extensions-19 */
 | 
			
		||||
 | 
			
		||||
/* Segment ID could be a Label (3 bytes) or an Index (4 bytes) */
 | 
			
		||||
#define SID_BASE_SIZE	4
 | 
			
		||||
#define SID_LABEL	3
 | 
			
		||||
#define SID_LABEL_SIZE	(SID_BASE_SIZE + SID_LABEL)
 | 
			
		||||
#define SID_INDEX	4
 | 
			
		||||
#define SID_INDEX_SIZE	(SID_BASE_SIZE + SID_INDEX)
 | 
			
		||||
 | 
			
		||||
/* SID/Label Sub TLV - section 2.1 */
 | 
			
		||||
#define SUBTLV_SID_LABEL		1
 | 
			
		||||
#define SUBTLV_SID_LABEL_SIZE		8
 | 
			
		||||
struct subtlv_sid_label {
 | 
			
		||||
	/* Length is 3 (20 rightmost bits MPLS label) or 4 (32 bits SID) */
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Following section defines Segment Routing TLV (tag, length, value)
 | 
			
		||||
 * structures, used in Router Information Opaque LSA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* RI SR-Algorithm TLV - section 3.1 */
 | 
			
		||||
#define RI_SR_TLV_SR_ALGORITHM          8
 | 
			
		||||
struct ri_sr_tlv_sr_algorithm {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
#define SR_ALGORITHM_SPF         0
 | 
			
		||||
#define SR_ALGORITHM_STRICT_SPF  1
 | 
			
		||||
#define SR_ALGORITHM_UNSET       255
 | 
			
		||||
#define ALGORITHM_COUNT          4
 | 
			
		||||
	/* Only 4 algorithms supported in this code */
 | 
			
		||||
	u_int8_t value[ALGORITHM_COUNT];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* RI SID/Label Range TLV - section 3.2 */
 | 
			
		||||
#define RI_SR_TLV_SID_LABEL_RANGE	9
 | 
			
		||||
struct ri_sr_tlv_sid_label_range {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
/* Only 24 upper most bits are significant */
 | 
			
		||||
#define SID_RANGE_LABEL_LENGTH	3
 | 
			
		||||
	u_int32_t size;
 | 
			
		||||
	/* A SID/Label sub-TLV will follow. */
 | 
			
		||||
	struct subtlv_sid_label lower;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* RI Node/MSD TLV as per draft-ietf-ospf-segment-routing-msd-05 */
 | 
			
		||||
#define RI_SR_TLV_NODE_MSD		12
 | 
			
		||||
struct ri_sr_tlv_node_msd {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t subtype; /* always = 1 */
 | 
			
		||||
	u_int8_t value;
 | 
			
		||||
	u_int16_t padding;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Following section defines Segment Routing TLV (tag, length, value)
 | 
			
		||||
 * structures, used in Extended Prefix/Link Opaque LSA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Adj-SID and LAN-Ajd-SID subtlvs' flags */
 | 
			
		||||
#define EXT_SUBTLV_LINK_ADJ_SID_BFLG	0x80
 | 
			
		||||
#define EXT_SUBTLV_LINK_ADJ_SID_VFLG	0x40
 | 
			
		||||
#define EXT_SUBTLV_LINK_ADJ_SID_LFLG	0x20
 | 
			
		||||
#define EXT_SUBTLV_LINK_ADJ_SID_SFLG	0x10
 | 
			
		||||
 | 
			
		||||
/* Prefix SID subtlv Flags */
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_NPFLG	0x40
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_MFLG	0x20
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_EFLG	0x10
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_VFLG	0x08
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_LFLG	0x04
 | 
			
		||||
 | 
			
		||||
/* SID/Label Binding subtlv Flags */
 | 
			
		||||
#define EXT_SUBTLV_SID_BINDING_MFLG	0x80
 | 
			
		||||
 | 
			
		||||
/* Extended Prefix Range TLV - section 4 */
 | 
			
		||||
#define EXT_TLV_PREF_RANGE		2
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_RANGE_SIZE	12
 | 
			
		||||
struct ext_tlv_prefix_range {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t pref_length;
 | 
			
		||||
	u_int8_t af;
 | 
			
		||||
	u_int16_t range_size;
 | 
			
		||||
	u_int8_t flags;
 | 
			
		||||
	u_int8_t reserved[3];
 | 
			
		||||
	struct in_addr address;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Prefix SID Sub-TLV - section 5 */
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID		2
 | 
			
		||||
#define EXT_SUBTLV_PREFIX_SID_SIZE	8
 | 
			
		||||
struct ext_subtlv_prefix_sid {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t flags;
 | 
			
		||||
	u_int8_t reserved;
 | 
			
		||||
	u_int8_t mtid;
 | 
			
		||||
	u_int8_t algorithm;
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Adj-SID Sub-TLV - section 6.1 */
 | 
			
		||||
#define EXT_SUBTLV_ADJ_SID		2
 | 
			
		||||
#define EXT_SUBTLV_ADJ_SID_SIZE		8
 | 
			
		||||
struct ext_subtlv_adj_sid {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t flags;
 | 
			
		||||
	u_int8_t reserved;
 | 
			
		||||
	u_int8_t mtid;
 | 
			
		||||
	u_int8_t weight;
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* LAN Adj-SID Sub-TLV - section 6.2 */
 | 
			
		||||
#define EXT_SUBTLV_LAN_ADJ_SID		3
 | 
			
		||||
#define EXT_SUBTLV_LAN_ADJ_SID_SIZE	12
 | 
			
		||||
struct ext_subtlv_lan_adj_sid {
 | 
			
		||||
	struct tlv_header header;
 | 
			
		||||
	u_int8_t flags;
 | 
			
		||||
	u_int8_t reserved;
 | 
			
		||||
	u_int8_t mtid;
 | 
			
		||||
	u_int8_t weight;
 | 
			
		||||
	struct in_addr neighbor_id;
 | 
			
		||||
	u_int32_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Following section define structure used to manage Segment Routing
 | 
			
		||||
 * information and TLVs / SubTLVs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Structure aggregating SRGB info retrieved from an lsa */
 | 
			
		||||
struct sr_srgb {
 | 
			
		||||
	u_int32_t range_size;
 | 
			
		||||
	u_int32_t lower_bound;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* SID type to make difference between loopback interfaces and others */
 | 
			
		||||
enum sid_type { PREF_SID, ADJ_SID, LAN_ADJ_SID };
 | 
			
		||||
 | 
			
		||||
/* Structure aggregating all OSPF Segment Routing information for the node */
 | 
			
		||||
struct ospf_sr_db {
 | 
			
		||||
	/* Status of Segment Routing: enable or disable */
 | 
			
		||||
	bool enabled;
 | 
			
		||||
 | 
			
		||||
	/* Ongoing Update following an OSPF SPF */
 | 
			
		||||
	bool update;
 | 
			
		||||
 | 
			
		||||
	/* Flooding Scope: Area = 10 or AS = 11 */
 | 
			
		||||
	u_int8_t scope;
 | 
			
		||||
 | 
			
		||||
	/* FRR SR node */
 | 
			
		||||
	struct sr_node *self;
 | 
			
		||||
 | 
			
		||||
	/* List of neighbour SR nodes */
 | 
			
		||||
	struct hash *neighbors;
 | 
			
		||||
 | 
			
		||||
	/* List of SR prefix */
 | 
			
		||||
	struct route_table *prefix;
 | 
			
		||||
 | 
			
		||||
	/* Local SR info announced in Router Info LSA */
 | 
			
		||||
 | 
			
		||||
	/* Algorithms supported by the node */
 | 
			
		||||
	u_int8_t algo[ALGORITHM_COUNT];
 | 
			
		||||
	/*
 | 
			
		||||
	 * Segment Routing Global Block i.e. label range
 | 
			
		||||
	 * Only one range supported in this code
 | 
			
		||||
	 */
 | 
			
		||||
	struct sr_srgb srgb;
 | 
			
		||||
	/* Maximum SID Depth supported by the node */
 | 
			
		||||
	u_int8_t msd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure aggregating all received SR info from LSAs by node */
 | 
			
		||||
struct sr_node {
 | 
			
		||||
	struct in_addr adv_router; /* used to identify sender of LSA */
 | 
			
		||||
	/* 24-bit Opaque-ID field value according to RFC 7684 specification */
 | 
			
		||||
	u_int32_t instance;
 | 
			
		||||
 | 
			
		||||
	u_int8_t algo[ALGORITHM_COUNT]; /* Algorithms supported by the node */
 | 
			
		||||
	/* Segment Routing Global Block i.e. label range */
 | 
			
		||||
	struct sr_srgb srgb;
 | 
			
		||||
	u_int8_t msd; /* Maximum SID Depth */
 | 
			
		||||
 | 
			
		||||
	/* List of Prefix & Link advertise by this node */
 | 
			
		||||
	struct list *ext_prefix; /* For Node SID */
 | 
			
		||||
	struct list *ext_link;   /* For Adj and LAN SID */
 | 
			
		||||
 | 
			
		||||
	/* Pointer to FRR SR-Node or NULL if it is not a neighbor */
 | 
			
		||||
	struct sr_node *neighbor;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Segment Routing - NHLFE info: support IPv4 Only */
 | 
			
		||||
struct sr_nhlfe {
 | 
			
		||||
	struct prefix_ipv4 prefv4;
 | 
			
		||||
	struct in_addr nexthop;
 | 
			
		||||
	ifindex_t ifindex;
 | 
			
		||||
	mpls_label_t label_in;
 | 
			
		||||
	mpls_label_t label_out;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure aggregating all Segment Routing Link information */
 | 
			
		||||
/* Link are generally advertised by pair: primary + backup */
 | 
			
		||||
struct sr_link {
 | 
			
		||||
	struct in_addr adv_router; /* used to identify sender of LSA */
 | 
			
		||||
	/* 24-bit Opaque-ID field value according to RFC 7684 specification */
 | 
			
		||||
	u_int32_t instance;
 | 
			
		||||
 | 
			
		||||
	/* Flags to manage this link parameters. */
 | 
			
		||||
	u_int32_t flags[2];
 | 
			
		||||
 | 
			
		||||
	/* Segment Routing ID */
 | 
			
		||||
	u_int32_t sid[2];
 | 
			
		||||
	enum sid_type type;
 | 
			
		||||
 | 
			
		||||
	/* SR NHLFE for this link */
 | 
			
		||||
	struct sr_nhlfe nhlfe[2];
 | 
			
		||||
 | 
			
		||||
	/* Back pointer to SR Node which advertise this Link */
 | 
			
		||||
	struct sr_node *srn;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure aggregating all Segment Routing Prefix information */
 | 
			
		||||
struct sr_prefix {
 | 
			
		||||
	struct in_addr adv_router; /* used to identify sender of LSA */
 | 
			
		||||
	/* 24-bit Opaque-ID field value according to RFC 7684 specification */
 | 
			
		||||
	u_int32_t instance;
 | 
			
		||||
 | 
			
		||||
	/* Flags to manage this prefix parameters. */
 | 
			
		||||
	u_int32_t flags;
 | 
			
		||||
 | 
			
		||||
	/* Segment Routing ID */
 | 
			
		||||
	u_int32_t sid;
 | 
			
		||||
	enum sid_type type;
 | 
			
		||||
 | 
			
		||||
	/* SR NHLFE for this prefix */
 | 
			
		||||
	struct sr_nhlfe nhlfe;
 | 
			
		||||
 | 
			
		||||
	/* Back pointer to SR Node which advertise this Prefix */
 | 
			
		||||
	struct sr_node *srn;
 | 
			
		||||
 | 
			
		||||
	/* Pointer to SR Node which is the next hop for this Prefix
 | 
			
		||||
	 * or NULL if next hop is the destination of the prefix */
 | 
			
		||||
	struct sr_node *nexthop;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Prototypes definition */
 | 
			
		||||
/* Segment Routing initialisation functions */
 | 
			
		||||
extern int ospf_sr_init(void);
 | 
			
		||||
extern void ospf_sr_term(void);
 | 
			
		||||
/* Segment Routing LSA update & delete functions */
 | 
			
		||||
extern void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa);
 | 
			
		||||
extern void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa);
 | 
			
		||||
extern void ospf_sr_ext_link_lsa_update(struct ospf_lsa *);
 | 
			
		||||
extern void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *);
 | 
			
		||||
extern void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *);
 | 
			
		||||
extern void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *);
 | 
			
		||||
/* Segment Routing configuration functions */
 | 
			
		||||
extern u_int32_t get_ext_link_label_value(void);
 | 
			
		||||
extern void ospf_sr_config_write_router(struct vty *);
 | 
			
		||||
/* Segment Routing re-routing function */
 | 
			
		||||
extern void ospf_sr_update_timer_add(struct ospf *);
 | 
			
		||||
#endif /* _FRR_OSPF_SR_H */
 | 
			
		||||
@ -240,6 +240,7 @@ struct ospf {
 | 
			
		||||
	struct thread *t_external_lsa;      /* AS-external-LSA origin timer. */
 | 
			
		||||
	struct thread
 | 
			
		||||
		*t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
 | 
			
		||||
	struct thread *t_sr_update; /* Segment Routing update timer */
 | 
			
		||||
 | 
			
		||||
	unsigned int maxage_delay;      /* Delay on Maxage remover timer, sec */
 | 
			
		||||
	struct thread *t_maxage;	/* MaxAge LSA remover timer. */
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ ospfd_libfrrospf_a_SOURCES = \
 | 
			
		||||
	ospfd/ospf_bfd.c \
 | 
			
		||||
	ospfd/ospf_dump.c \
 | 
			
		||||
	ospfd/ospf_dump_api.c \
 | 
			
		||||
	ospfd/ospf_ext.c \
 | 
			
		||||
	ospfd/ospf_flood.c \
 | 
			
		||||
	ospfd/ospf_ia.c \
 | 
			
		||||
	ospfd/ospf_interface.c \
 | 
			
		||||
@ -36,6 +37,7 @@ ospfd_libfrrospf_a_SOURCES = \
 | 
			
		||||
	ospfd/ospf_route.c \
 | 
			
		||||
	ospfd/ospf_routemap.c \
 | 
			
		||||
	ospfd/ospf_spf.c \
 | 
			
		||||
	ospfd/ospf_sr.c \
 | 
			
		||||
	ospfd/ospf_te.c \
 | 
			
		||||
	ospfd/ospf_vty.c \
 | 
			
		||||
	ospfd/ospf_zebra.c \
 | 
			
		||||
@ -66,6 +68,7 @@ noinst_HEADERS += \
 | 
			
		||||
	ospfd/ospf_apiserver.h \
 | 
			
		||||
	ospfd/ospf_ase.h \
 | 
			
		||||
	ospfd/ospf_bfd.h \
 | 
			
		||||
	ospfd/ospf_ext.h \
 | 
			
		||||
	ospfd/ospf_flood.h \
 | 
			
		||||
	ospfd/ospf_ia.h \
 | 
			
		||||
	ospfd/ospf_interface.h \
 | 
			
		||||
@ -76,6 +79,7 @@ noinst_HEADERS += \
 | 
			
		||||
	ospfd/ospf_ri.h \
 | 
			
		||||
	ospfd/ospf_route.h \
 | 
			
		||||
	ospfd/ospf_spf.h \
 | 
			
		||||
	ospfd/ospf_sr.h \
 | 
			
		||||
	ospfd/ospf_te.h \
 | 
			
		||||
	ospfd/ospf_vty.h \
 | 
			
		||||
	ospfd/ospf_zebra.h \
 | 
			
		||||
 | 
			
		||||
@ -75,6 +75,7 @@ vtysh_scan += $(top_srcdir)/ospfd/ospf_opaque.c
 | 
			
		||||
vtysh_scan += $(top_srcdir)/ospfd/ospf_ri.c
 | 
			
		||||
vtysh_scan += $(top_srcdir)/ospfd/ospf_routemap.c
 | 
			
		||||
vtysh_scan += $(top_srcdir)/ospfd/ospf_te.c
 | 
			
		||||
vtysh_scan += $(top_srcdir)/ospfd/ospf_sr.c
 | 
			
		||||
vtysh_scan += $(top_srcdir)/ospfd/ospf_vty.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,7 @@ static const struct message rtproto_str[] = {
 | 
			
		||||
	{RTPROT_MROUTED, "mroute"},
 | 
			
		||||
	{RTPROT_BGP, "BGP"},
 | 
			
		||||
	{RTPROT_OSPF, "OSPF"},
 | 
			
		||||
	{RTPROT_OSPF_SR, "OSPF-SR"},
 | 
			
		||||
	{RTPROT_ISIS, "IS-IS"},
 | 
			
		||||
	{RTPROT_RIP, "RIP"},
 | 
			
		||||
	{RTPROT_RIPNG, "RIPNG"},
 | 
			
		||||
 | 
			
		||||
@ -98,7 +98,8 @@ static inline int is_selfroute(int proto)
 | 
			
		||||
	    || (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)
 | 
			
		||||
	    || (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
 | 
			
		||||
	    || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
 | 
			
		||||
	    || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)) {
 | 
			
		||||
	    || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)
 | 
			
		||||
	    || (proto == RTPROT_OSPF_SR)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -118,6 +119,9 @@ static inline int zebra2proto(int proto)
 | 
			
		||||
	case ZEBRA_ROUTE_OSPF6:
 | 
			
		||||
		proto = RTPROT_OSPF;
 | 
			
		||||
		break;
 | 
			
		||||
	case ZEBRA_ROUTE_OSPF_SR:
 | 
			
		||||
		proto = RTPROT_OSPF_SR;
 | 
			
		||||
		break;
 | 
			
		||||
	case ZEBRA_ROUTE_STATIC:
 | 
			
		||||
		proto = RTPROT_STATIC;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
@ -52,6 +52,7 @@
 | 
			
		||||
#define RTPROT_EIGRP       192
 | 
			
		||||
#define RTPROT_LDP         193
 | 
			
		||||
#define RTPROT_SHARP       194
 | 
			
		||||
#define RTPROT_OSPF_SR     195
 | 
			
		||||
 | 
			
		||||
void rt_netlink_init(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -316,6 +316,12 @@ void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt);
 | 
			
		||||
 */
 | 
			
		||||
void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Uninstall all Segment Routing NHLFEs for a particular LSP forwarding entry.
 | 
			
		||||
 * If no other NHLFEs exist, the entry would be deleted.
 | 
			
		||||
 */
 | 
			
		||||
void mpls_sr_lsp_uninstall_all(struct hash_backet *backet, void *ctxt);
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_CUMULUS)
 | 
			
		||||
/*
 | 
			
		||||
 * Check that the label values used in LSP creation are consistent. The
 | 
			
		||||
@ -448,6 +454,8 @@ static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type)
 | 
			
		||||
		return ZEBRA_ROUTE_LDP;
 | 
			
		||||
	case ZEBRA_LSP_BGP:
 | 
			
		||||
		return ZEBRA_ROUTE_BGP;
 | 
			
		||||
	case ZEBRA_LSP_SR:
 | 
			
		||||
		return ZEBRA_ROUTE_OSPF_SR;
 | 
			
		||||
	case ZEBRA_LSP_NONE:
 | 
			
		||||
	default:
 | 
			
		||||
		return ZEBRA_ROUTE_KERNEL;
 | 
			
		||||
@ -464,6 +472,8 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
 | 
			
		||||
		return "LDP";
 | 
			
		||||
	case ZEBRA_LSP_BGP:
 | 
			
		||||
		return "BGP";
 | 
			
		||||
	case ZEBRA_LSP_SR:
 | 
			
		||||
		return "SR";
 | 
			
		||||
	default:
 | 
			
		||||
		return "Unknown";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user