Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ospfd: OSPFv2 support for draft-ietf-lsr-flex-algo #11849

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ ForEachMacros:
- 'FOREACH_CMT_REC'
- 'FOREACH_MGMTD_BE_CLIENT_ID'
- 'FOREACH_MGMTD_DS_ID'
- 'FOREACH_ADMIN_GROUP_BITS'
- 'FOREACH_FLEX_ALGO_DEFN'
- 'FOREACH_SAFI'
- 'FOREACH_SESSION_IN_LIST'
- 'FOREACH_TXN_CFG_BATCH_IN_LIST'
Expand Down
208 changes: 208 additions & 0 deletions doc/user/ospfd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,214 @@ TI-LFA requires a proper Segment Routing configuration.

Note that so far only P2P interfaces are supported.

Flexible Algorithms (Flex-Algo)
===============================

This is a bare-minimum implementation of : :t:`draft-ietf-lsr-flex-algo`. Currently
`Shortest Path First` is the only algorithm supported, with `IGP-Metric` and
`Shortest-Path-First` are the only values supported for `metric-type` and
`calculation-type` respectively. In future support for more algorithms,
metric-types and calculation-types shall be added.

Please note, since Flexible Algorithm Definitions (also referred to as FAD)
are advertised in Opaque LSAs (one ore more), capability to carry Opaque
Linkstate Information (in the form of Opaque LSAs) should be turned on using
``capability opaque`` and ``router-info area`` configration commands under
`router ospf` level.

.. clicmd:: [no] flexible-algorithm (128-255)

Add a new or remove an existing Flexible Algorithm Definition for the
current router to support.

The add will result in the router advertsing the new flexible-algorithm
definition (with the specified algorithm-id) in all relevant types of
self-originated LSAs. By default, `calculation-type` and `metric-type`
for the new flexible-algorithm shall be set to `Shortest-Path-First` and
`IGP-Metric` respectively.

Removing an existing Flexible Algorithm Definition will result in the
router removing all advertisements for the specified algorithm-id from all
the relevant types of self-originated LSAs.

.. clicmd:: [no] flexible-algorithm (128-255) calculation-type (spf)

Set (or reset) the `calculation-type` for the Flexible Algorithm Definition
specified by the algorithm-id. Currently `spf` (i.e. Shortest-Path-First)
only allowed value. Support for more metric-types shall be added in future.

Resetting the `calculation-type` for the Flexible Algorithm Definition will
reset it to the default value of `spf`.

.. clicmd:: [no] flexible-algorithm (128-255) metric-type (igp)

Set the (or reset) `metric-type` for the Flexible Algorithm Definition
specified by the algorithm-id. Currently `igp-metric` is the only allowed
value. Support for more metric-types shall be added in future.

Resetting the `metric-type` for the Flexible Algorithm Definition will
reset it to efault value of `igp-metric`.

.. clicmd:: [no] flexible-algorithm (128-255) priority (0-4294967295)

Set the (or reset) `priority` for the Flexible Algorithm Definition
specified by the algorithm-id. Default value of priority is 0.

Resetting the `priority` for the Flexible Algorithm Definition will reset
it to default value 0.

pushpasis marked this conversation as resolved.
Show resolved Hide resolved
.. clicmd:: [no] flexible-algorithm (128-255) exclude-admin-group (0-4294967295)

Add (or remove) the specified `admin-group` value to (or from) the list of
Exclude-Admin-Groups for the Flexible Algorithm Definition specified by the
algorithm-id.

This will add (or remove) the admin-group to (or from) the list of
admin-groups advertised in the Exclude-Admin-Group Sub-TLV included in the
corresponding Flexible Algorithm Definition TLV (carried inside the
Router-Info external LSA).

.. clicmd:: [no] flexible-algorithm (128-255) include-any-admin-group (0-4294967295)

Add (or remove) the specified `admin-group` value to (or from) the list of
Include-Any-Admin-Groups for the Flexible Algorithm Definition specified by
the algorithm-id.

This will add (or remove) the admin-group to (or from) the list of
admin-groups advertised in the Include-Any-Admin-Group Sub-TLV included in
the corresponding Flexible Algorithm Definition TLV (carried inside the
Router-Info external LSA).

.. clicmd:: [no] flexible-algorithm (128-255) include-all-admin-group (0-4294967295)

Add (or remove) the specified `admin-group` value to (or from) the list of
Include-All-Admin-Groups for the Flexible Algorithm Definition specified by
the algorithm-id.

This will add (or remove) the admin-group to (or from) the list of
admin-groups advertised in the Include-All-Admin-Group Sub-TLV included in
the corresponding Flexible Algorithm Definition TLV (carried inside the
Router-Info external LSA).

.. clicmd:: [no] flexible-algorithm (128-255) exclude-srlg (0-4294967295)

pushpasis marked this conversation as resolved.
Show resolved Hide resolved
Add (or remove) the specified `srlg` value to (or from) the list of
Exclude-SRLGs for the Flexible Algorithm Definition specified by the
algorithm-id.

This will add (or remove) the admin-group to (or from) the list of
SRLGs advertised in the Exclude-SRLG Sub-TLV included in the
corresponding Flexible Algorithm Definition TLV (carried inside the
Router-Info external LSA).

.. clicmd:: [no] flexible-algorithm (128-255) advertise-prefix-metric (0-4294967295)

Set (or reset) the `advertise-prefix-metric` for the Flexible Algorithm
Definition specified by the algorithm-id.

Setting the `advertise-prefix-metric` for the Flexible Algorithm
Definition will results in the router advertising the configured value
inside a Flexible-Algorithm Prefix-Metric(FAPM) Sub-TLV (carried inside
Extended Prefix TLV within a Extended Prefix Opaque LSA), as well as
inside a Flexible-Algorithm ASBR Metric(FAAM) Sub-TLV (to be carried in
the Extended Inter-Area ASBR TLV within a new Extended Inter-Area LSA).
By default no prefix metric is advertised.

Resetting the `advertise-prefix-metric` for the Flexible Algorithm Definition
specified by the algorithm-id will remove advertisement of the previously
configured value from all the relevant Sub-TLVs, TLVs and LSAs.

.. clicmd:: show ip ospf [vrf (vrf-name)] database opaque-area

This existing command's output has been enhanced to display the new
Flexible-Algorithm definition LSAs, TLVs and Sub-TLVs.

Following show command output shows the new Flexible Algoritms Definition
LSAs, TLVs and Sub-TLVs advertised.

.. code-block:: frr

frr# show ip ospf database opaque-area

OSPF Router with ID (1.1.1.1)


Area-Local Opaque-LSA (Area 0.0.0.0)

LS age: 524
Options: 0x42 : *|O|-|-|-|-|E|-
LS Flags: 0x1
LS Type: Area-Local Opaque-LSA
Link State ID: 4.0.0.0 (Area-Local Opaque-Type/ID)
Advertising Router: 1.1.1.1
LS Seq Number: 8000000b
Checksum: 0x9b60
Length: 80

Opaque-Type 4 (Router Information LSA)
Opaque-ID 0x0
Opaque-Info: 60 octets of data
Router Capabilities: 0x10000000
Flexible Algorithm Defintion TLV: Length: 48
Algorithm-Identifier = 128
Priority = 10
Metric-Type = Invalid-Metric-Type
Calculation-Type = spf
FAD Exclude Admin Groups:
[ 30 ]
FAD Include Any Admin Groups:
[ 60, 70 ]
FAD Include All Admin Groups:
[ 20 ]
FAD Flags:
[ 10 ]
FAD Exclude SRLGs:
[ 10 ]

LS age: 771
Options: 0x42 : *|O|-|-|-|-|E|-
LS Flags: 0x6
LS Type: Area-Local Opaque-LSA
Link State ID: 4.0.0.0 (Area-Local Opaque-Type/ID)
Advertising Router: 2.2.2.2
LS Seq Number: 8000000b
Checksum: 0x4d9d
Length: 28

Opaque-Type 7 (Extended Prefix Opaque LSA)
Opaque-ID 0x1
Opaque-Info: 24 octets of data
Extended Prefix TLV: Length 20
Route Type: 1
Address Family: 0x0
Flags: 0x40
Address: 1.1.1.1/32
Prefix FAPM Sub-TLV: Length 8
Algorithm: 128
Flags: 0x0
Metric: 100

LS age: 1383
Options: 0x42 : *|O|-|-|-|-|E|-
LS Flags: 0x1
LS Type: Area-Local Opaque-LSA
Link State ID: 11.0.0.0 (Area-Local Opaque-Type/ID)
Advertising Router: 1.1.1.1
LS Seq Number: 8000000a
Checksum: 0xc826
Length: 40

Opaque-Type 11 (Extended Inter-Area ASBR Opaque LSA)
Opaque-ID 0x0
Opaque-Info: 20 octets of data
Extended Inter-Area ASBR TLV: Length 16
ASBR-Router-Id: 1.1.1.1
Flex-Algo ASBR Metric Sub-TLV: Length 8
Algorithm: 128
Metric:100

frr#

.. _debugging-ospf:

Debugging OSPF
Expand Down
4 changes: 4 additions & 0 deletions lib/admin_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ struct admin_group {
bitfield_t bitmap;
};

#define FOREACH_ADMIN_GROUP_BITS(admngrp, bitpos) \
bf_for_each_set_bit((admngrp)->bitmap, (bitpos), \
EXT_ADMIN_GROUP_MAX_POSITIONS)

char *admin_group_string(char *out, size_t sz, int indent,
const struct admin_group *ag);
char *admin_group_standard_print(char *out, int indent, uint32_t bitmap);
Expand Down
2 changes: 1 addition & 1 deletion lib/affinitymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);

void affinity_map_init(void);

void affinity_map_set_nb_bypass(bool bypass);

#ifdef __cplusplus
}
Expand Down
43 changes: 43 additions & 0 deletions lib/affinitymap_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,37 @@ static struct cmd_node affinitymap_node = {
.config_write = affinity_map_config_write,
};

static bool bypass_nb;

static int affinity_map_update(struct vty *vty, const char *name,
const int position, bool delete)
{
char *old = NULL;
struct affinity_map *map;

if (position >= 0)
old = affinity_map_name_get(position);
map = affinity_map_get(name);
if (!delete) {
if (old && strncmp(old, name, AFFINITY_NAME_SIZE)) {
vty_out(vty, "Bit '%d' already mapped to name '%s'\n",
position, old);
return CMD_WARNING_CONFIG_FAILED;
}

if (!old)
affinity_map_set(name, position);
} else {
if (map)
affinity_map_unset(name);
}

zlog_err("%s: %sd affinity-map '%s', bit %d",
__func__, delete ? "Delete" : "Update", name, position);

return CMD_SUCCESS;
}

/* max value is EXT_ADMIN_GROUP_MAX_POSITIONS - 1 */
DEFPY_YANG_NOSH(affinity_map, affinity_map_cmd,
"affinity-map NAME$name bit-position (0-1023)$position",
Expand All @@ -49,6 +80,9 @@ DEFPY_YANG_NOSH(affinity_map, affinity_map_cmd,
{
char xpathr[XPATH_MAXLEN];

if (bypass_nb)
return affinity_map_update(vty, name, position, false);

snprintf(
xpathr, sizeof(xpathr),
"/frr-affinity-map:lib/affinity-maps/affinity-map[name='%s']/value",
Expand All @@ -68,6 +102,10 @@ DEFPY_YANG_NOSH(no_affinity_map, no_affinity_map_cmd,
{
char xpathr[XPATH_MAXLEN];

if (bypass_nb)
return affinity_map_update(
vty, name, argc > 3 ? (int) position : -1, true);

snprintf(xpathr, sizeof(xpathr),
"/frr-affinity-map:lib/affinity-maps/affinity-map[name='%s']",
name);
Expand Down Expand Up @@ -105,3 +143,8 @@ void affinity_map_init(void)
install_element(CONFIG_NODE, &affinity_map_cmd);
install_element(CONFIG_NODE, &no_affinity_map_cmd);
}

void affinity_map_set_nb_bypass(bool bypass)
{
bypass_nb = bypass;
}
64 changes: 64 additions & 0 deletions lib/bitfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ DECLARE_MTYPE(BITFIELD);
/* compare two bitmaps of the same length */
#define bf_cmp(v1, v2) (memcmp((v1).data, (v2).data, ((v1).m * sizeof(word_t))))

/* return number bits in the allocated bitmap data so far */
#define bf_bit_size(v) ((v).m * WORD_SIZE)

/* return number of bytes in the allocated bitmap data so far */
#define bf_byte_size(v) ((v).m * sizeof(word_t))

/* return number of words in the allocated bitmap data so far */
#define bf_word_size(v) (v).m

/*
* return 0th index back to bitfield
*/
Expand Down Expand Up @@ -268,6 +277,61 @@ static inline bitfield_t bf_copy(bitfield_t src)
return dst;
}

/*
* Encode a bitmap to a word-stream. Returns the number of bytes encoded
* instead of words.
*/
static inline void bf_encode_to_buf(bitfield_t *v, u_int8_t *buf,
u_int16_t *buflen)
{
u_int16_t bm_len, len;
int indx;
word_t *w;

if (!bf_is_inited(*v) || !buflen)
return;

bm_len = (u_int16_t)bf_byte_size(*v);
len = (u_int16_t)bf_word_size(*v);
if (*buflen < bm_len) {
*buflen = 0;
return;
}

w = (word_t *)buf;
*buflen = 0;
for (indx = 0; indx < len; indx++) {
w[indx] = htonl(v->data[indx]);

/* Avoid encoding trailing zeroes */
if (w[indx])
*buflen = indx + 1;
}
(*buflen) *= sizeof(word_t);
}

/*
* Decode a bitmap from a word-stream.
*/
static inline void bf_decode_from_buf(bitfield_t *v, u_int8_t *buf,
u_int16_t buflen)
{
size_t indx;
word_t *w;

assert(buflen);
v->n = 0;
v->m = buflen / sizeof(word_t);
v->data = (word_t *)XCALLOC(MTYPE_BITFIELD, v->m * sizeof(word_t));

w = (word_t *)buf;
for (indx = 0; indx < v->m; indx++) {
v->data[indx] = ntohl(w[indx]);
if (v->data[indx])
v->n = indx + 1;
}
}


#ifdef __cplusplus
}
Expand Down
Loading
Loading