mirror_frr/ospfd/ospf_sr.h
Olivier Dugeon cf9b9f77f6 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>
2018-01-18 19:11:11 +01:00

316 lines
9.1 KiB
C

/*
* 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 */