diff options
author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
---|---|---|
committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /isisd | |
parent | *: add indent control files (diff) | |
download | frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'isisd')
51 files changed, 19543 insertions, 20184 deletions
diff --git a/isisd/dict.c b/isisd/dict.c index 56676edaf..f09a8152a 100644 --- a/isisd/dict.c +++ b/isisd/dict.c @@ -24,7 +24,7 @@ /* * These macros provide short convenient names for structure members, * which are embellished with dict_ prefixes so that they are - * properly confined to the documented namespace. It's legal for a + * properly confined to the documented namespace. It's legal for a * program which uses dict to define, for instance, a macro called ``parent''. * Such a macro would interfere with the dnode_t struct definition. * In general, highly portable and reusable C modules which expose their @@ -67,26 +67,26 @@ static void dnode_free(dnode_t *node, void *context); static void rotate_left(dnode_t *upper) { - dnode_t *lower, *lowleft, *upparent; + dnode_t *lower, *lowleft, *upparent; - lower = upper->right; - upper->right = lowleft = lower->left; - lowleft->parent = upper; + lower = upper->right; + upper->right = lowleft = lower->left; + lowleft->parent = upper; - lower->parent = upparent = upper->parent; + lower->parent = upparent = upper->parent; - /* don't need to check for root node here because root->parent is - the sentinel nil node, and root->parent->left points back to root */ + /* don't need to check for root node here because root->parent is + the sentinel nil node, and root->parent->left points back to root */ - if (upper == upparent->left) { - upparent->left = lower; - } else { - assert (upper == upparent->right); - upparent->right = lower; - } + if (upper == upparent->left) { + upparent->left = lower; + } else { + assert(upper == upparent->right); + upparent->right = lower; + } - lower->left = upper; - upper->parent = lower; + lower->left = upper; + upper->parent = lower; } /* @@ -96,23 +96,23 @@ static void rotate_left(dnode_t *upper) static void rotate_right(dnode_t *upper) { - dnode_t *lower, *lowright, *upparent; + dnode_t *lower, *lowright, *upparent; - lower = upper->left; - upper->left = lowright = lower->right; - lowright->parent = upper; + lower = upper->left; + upper->left = lowright = lower->right; + lowright->parent = upper; - lower->parent = upparent = upper->parent; + lower->parent = upparent = upper->parent; - if (upper == upparent->right) { - upparent->right = lower; - } else { - assert (upper == upparent->left); - upparent->left = lower; - } + if (upper == upparent->right) { + upparent->right = lower; + } else { + assert(upper == upparent->left); + upparent->left = lower; + } - lower->right = upper; - upper->parent = lower; + lower->right = upper; + upper->parent = lower; } /* @@ -122,11 +122,11 @@ static void rotate_right(dnode_t *upper) static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) { - if (node == nil) - return; - free_nodes(dict, node->left, nil); - free_nodes(dict, node->right, nil); - dict->freenode(node, dict->context); + if (node == nil) + return; + free_nodes(dict, node->left, nil); + free_nodes(dict, node->right, nil); + dict->freenode(node, dict->context); } /* @@ -135,29 +135,29 @@ static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) * dict_next() successor function, verifying that the key of each node is * strictly lower than that of its successor, if duplicates are not allowed, * or lower or equal if duplicates are allowed. This function is used for - * debugging purposes. + * debugging purposes. */ static int verify_bintree(dict_t *dict) { - dnode_t *first, *next; + dnode_t *first, *next; - first = dict_first(dict); + first = dict_first(dict); - if (dict->dupes) { - while (first && (next = dict_next(dict, first))) { - if (dict->compare(first->key, next->key) > 0) - return 0; - first = next; - } - } else { - while (first && (next = dict_next(dict, first))) { - if (dict->compare(first->key, next->key) >= 0) - return 0; - first = next; + if (dict->dupes) { + while (first && (next = dict_next(dict, first))) { + if (dict->compare(first->key, next->key) > 0) + return 0; + first = next; + } + } else { + while (first && (next = dict_next(dict, first))) { + if (dict->compare(first->key, next->key) >= 0) + return 0; + first = next; + } } - } - return 1; + return 1; } @@ -176,27 +176,27 @@ static int verify_bintree(dict_t *dict) static unsigned int verify_redblack(dnode_t *nil, dnode_t *root) { - unsigned height_left, height_right; - - if (root != nil) { - height_left = verify_redblack(nil, root->left); - height_right = verify_redblack(nil, root->right); - if (height_left == 0 || height_right == 0) - return 0; - if (height_left != height_right) - return 0; - if (root->color == dnode_red) { - if (root->left->color != dnode_black) - return 0; - if (root->right->color != dnode_black) - return 0; - return height_left; + unsigned height_left, height_right; + + if (root != nil) { + height_left = verify_redblack(nil, root->left); + height_right = verify_redblack(nil, root->right); + if (height_left == 0 || height_right == 0) + return 0; + if (height_left != height_right) + return 0; + if (root->color == dnode_red) { + if (root->left->color != dnode_black) + return 0; + if (root->right->color != dnode_black) + return 0; + return height_left; + } + if (root->color != dnode_black) + return 0; + return height_left + 1; } - if (root->color != dnode_black) - return 0; - return height_left + 1; - } - return 1; + return 1; } /* @@ -207,11 +207,11 @@ static unsigned int verify_redblack(dnode_t *nil, dnode_t *root) static dictcount_t verify_node_count(dnode_t *nil, dnode_t *root) { - if (root == nil) - return 0; - else - return 1 + verify_node_count(nil, root->left) - + verify_node_count(nil, root->right); + if (root == nil) + return 0; + else + return 1 + verify_node_count(nil, root->left) + + verify_node_count(nil, root->right); } /* @@ -223,12 +223,12 @@ static dictcount_t verify_node_count(dnode_t *nil, dnode_t *root) static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) { - if (root != nil) { - return root == node - || verify_dict_has_node(nil, root->left, node) - || verify_dict_has_node(nil, root->right, node); - } - return 0; + if (root != nil) { + return root == node + || verify_dict_has_node(nil, root->left, node) + || verify_dict_has_node(nil, root->right, node); + } + return 0; } @@ -238,37 +238,37 @@ static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) dict_t *dict_create(dictcount_t maxcount, dict_comp_t comp) { - dict_t *new = XCALLOC(MTYPE_ISIS_DICT, sizeof(dict_t)); - - if (new) { - new->compare = comp; - new->allocnode = dnode_alloc; - new->freenode = dnode_free; - new->context = NULL; - new->nodecount = 0; - new->maxcount = maxcount; - new->nilnode.left = &new->nilnode; - new->nilnode.right = &new->nilnode; - new->nilnode.parent = &new->nilnode; - new->nilnode.color = dnode_black; - new->dupes = 0; - } - return new; + dict_t *new = XCALLOC(MTYPE_ISIS_DICT, sizeof(dict_t)); + + if (new) { + new->compare = comp; + new->allocnode = dnode_alloc; + new->freenode = dnode_free; + new->context = NULL; + new->nodecount = 0; + new->maxcount = maxcount; + new->nilnode.left = &new->nilnode; + new->nilnode.right = &new->nilnode; + new->nilnode.parent = &new->nilnode; + new->nilnode.color = dnode_black; + new->dupes = 0; + } + return new; } /* * Select a different set of node allocator routines. */ -void dict_set_allocator(dict_t *dict, dnode_alloc_t al, - dnode_free_t fr, void *context) +void dict_set_allocator(dict_t *dict, dnode_alloc_t al, dnode_free_t fr, + void *context) { - assert (dict_count(dict) == 0); - assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL)); + assert(dict_count(dict) == 0); + assert((al == NULL && fr == NULL) || (al != NULL && fr != NULL)); - dict->allocnode = al ? al : dnode_alloc; - dict->freenode = fr ? fr : dnode_free; - dict->context = context; + dict->allocnode = al ? al : dnode_alloc; + dict->freenode = fr ? fr : dnode_free; + dict->context = context; } /* @@ -278,8 +278,8 @@ void dict_set_allocator(dict_t *dict, dnode_alloc_t al, void dict_destroy(dict_t *dict) { - assert (dict_isempty(dict)); - XFREE(MTYPE_ISIS_DICT, dict); + assert(dict_isempty(dict)); + XFREE(MTYPE_ISIS_DICT, dict); } /* @@ -289,11 +289,11 @@ void dict_destroy(dict_t *dict) void dict_free_nodes(dict_t *dict) { - dnode_t *nil = dict_nil(dict), *root = dict_root(dict); - free_nodes(dict, root, nil); - dict->nodecount = 0; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; + dnode_t *nil = dict_nil(dict), *root = dict_root(dict); + free_nodes(dict, root, nil); + dict->nodecount = 0; + dict->nilnode.left = &dict->nilnode; + dict->nilnode.right = &dict->nilnode; } /* @@ -302,7 +302,7 @@ void dict_free_nodes(dict_t *dict) void dict_free(dict_t *dict) { - dict_free_nodes(dict); + dict_free_nodes(dict); } /* @@ -311,39 +311,39 @@ void dict_free(dict_t *dict) dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) { - dict->compare = comp; - dict->allocnode = dnode_alloc; - dict->freenode = dnode_free; - dict->context = NULL; - dict->nodecount = 0; - dict->maxcount = maxcount; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; - dict->nilnode.parent = &dict->nilnode; - dict->nilnode.color = dnode_black; - dict->dupes = 0; - return dict; + dict->compare = comp; + dict->allocnode = dnode_alloc; + dict->freenode = dnode_free; + dict->context = NULL; + dict->nodecount = 0; + dict->maxcount = maxcount; + dict->nilnode.left = &dict->nilnode; + dict->nilnode.right = &dict->nilnode; + dict->nilnode.parent = &dict->nilnode; + dict->nilnode.color = dnode_black; + dict->dupes = 0; + return dict; } -/* +/* * Initialize a dictionary in the likeness of another dictionary */ void dict_init_like(dict_t *dict, const dict_t *template) { - dict->compare = template->compare; - dict->allocnode = template->allocnode; - dict->freenode = template->freenode; - dict->context = template->context; - dict->nodecount = 0; - dict->maxcount = template->maxcount; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; - dict->nilnode.parent = &dict->nilnode; - dict->nilnode.color = dnode_black; - dict->dupes = template->dupes; - - assert (dict_similar(dict, template)); + dict->compare = template->compare; + dict->allocnode = template->allocnode; + dict->freenode = template->freenode; + dict->context = template->context; + dict->nodecount = 0; + dict->maxcount = template->maxcount; + dict->nilnode.left = &dict->nilnode; + dict->nilnode.right = &dict->nilnode; + dict->nilnode.parent = &dict->nilnode; + dict->nilnode.color = dnode_black; + dict->dupes = template->dupes; + + assert(dict_similar(dict, template)); } /* @@ -352,11 +352,11 @@ void dict_init_like(dict_t *dict, const dict_t *template) static void dict_clear(dict_t *dict) { - dict->nodecount = 0; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; - dict->nilnode.parent = &dict->nilnode; - assert (dict->nilnode.color == dnode_black); + dict->nodecount = 0; + dict->nilnode.left = &dict->nilnode; + dict->nilnode.right = &dict->nilnode; + dict->nilnode.parent = &dict->nilnode; + assert(dict->nilnode.color == dnode_black); } @@ -365,31 +365,31 @@ static void dict_clear(dict_t *dict) * debugging purposes, and should be placed in assert statements. Just because * this function succeeds doesn't mean that the tree is not corrupt. Certain * corruptions in the tree may simply cause undefined behavior. - */ + */ int dict_verify(dict_t *dict) { - dnode_t *nil = dict_nil(dict), *root = dict_root(dict); + dnode_t *nil = dict_nil(dict), *root = dict_root(dict); - /* check that the sentinel node and root node are black */ - if (root->color != dnode_black) - return 0; - if (nil->color != dnode_black) - return 0; - if (nil->right != nil) - return 0; - /* nil->left is the root node; check that its parent pointer is nil */ - if (nil->left->parent != nil) - return 0; - /* perform a weak test that the tree is a binary search tree */ - if (!verify_bintree(dict)) - return 0; - /* verify that the tree is a red-black tree */ - if (!verify_redblack(nil, root)) - return 0; - if (verify_node_count(nil, root) != dict_count(dict)) - return 0; - return 1; + /* check that the sentinel node and root node are black */ + if (root->color != dnode_black) + return 0; + if (nil->color != dnode_black) + return 0; + if (nil->right != nil) + return 0; + /* nil->left is the root node; check that its parent pointer is nil */ + if (nil->left->parent != nil) + return 0; + /* perform a weak test that the tree is a binary search tree */ + if (!verify_bintree(dict)) + return 0; + /* verify that the tree is a red-black tree */ + if (!verify_redblack(nil, root)) + return 0; + if (verify_node_count(nil, root) != dict_count(dict)) + return 0; + return 1; } /* @@ -399,62 +399,64 @@ int dict_verify(dict_t *dict) int dict_similar(const dict_t *left, const dict_t *right) { - if (left->compare != right->compare) - return 0; + if (left->compare != right->compare) + return 0; - if (left->allocnode != right->allocnode) - return 0; + if (left->allocnode != right->allocnode) + return 0; - if (left->freenode != right->freenode) - return 0; + if (left->freenode != right->freenode) + return 0; - if (left->context != right->context) - return 0; + if (left->context != right->context) + return 0; - if (left->dupes != right->dupes) - return 0; + if (left->dupes != right->dupes) + return 0; - return 1; + return 1; } /* * Locate a node in the dictionary having the given key. - * If the node is not found, a null a pointer is returned (rather than + * If the node is not found, a null a pointer is returned (rather than * a pointer that dictionary's nil sentinel node), otherwise a pointer to the * located node is returned. */ dnode_t *dict_lookup(dict_t *dict, const void *key) { - dnode_t *root = dict_root(dict); - dnode_t *nil = dict_nil(dict); - dnode_t *saved; - int result; - - /* simple binary search adapted for trees that contain duplicate keys */ - - while (root != nil) { - result = dict->compare(key, root->key); - if (result < 0) - root = root->left; - else if (result > 0) - root = root->right; - else { - if (!dict->dupes) { /* no duplicates, return match */ - return root; - } else { /* could be dupes, find leftmost one */ - do { - saved = root; - root = root->left; - while (root != nil && dict->compare(key, root->key)) + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *saved; + int result; + + /* simple binary search adapted for trees that contain duplicate keys */ + + while (root != nil) { + result = dict->compare(key, root->key); + if (result < 0) + root = root->left; + else if (result > 0) root = root->right; - } while (root != nil); - return saved; - } + else { + if (!dict->dupes) { /* no duplicates, return match + */ + return root; + } else { /* could be dupes, find leftmost one */ + do { + saved = root; + root = root->left; + while (root != nil + && dict->compare(key, root->key)) + root = root->right; + } while (root != nil); + return saved; + } + } } - } - return NULL; + return NULL; } /* @@ -464,29 +466,29 @@ dnode_t *dict_lookup(dict_t *dict, const void *key) dnode_t *dict_lower_bound(dict_t *dict, const void *key) { - dnode_t *root = dict_root(dict); - dnode_t *nil = dict_nil(dict); - dnode_t *tentative = 0; - - while (root != nil) { - int result = dict->compare(key, root->key); - - if (result > 0) { - root = root->right; - } else if (result < 0) { - tentative = root; - root = root->left; - } else { - if (!dict->dupes) { - return root; - } else { - tentative = root; - root = root->left; - } - } - } - - return tentative; + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *tentative = 0; + + while (root != nil) { + int result = dict->compare(key, root->key); + + if (result > 0) { + root = root->right; + } else if (result < 0) { + tentative = root; + root = root->left; + } else { + if (!dict->dupes) { + return root; + } else { + tentative = root; + root = root->left; + } + } + } + + return tentative; } /* @@ -496,29 +498,29 @@ dnode_t *dict_lower_bound(dict_t *dict, const void *key) dnode_t *dict_upper_bound(dict_t *dict, const void *key) { - dnode_t *root = dict_root(dict); - dnode_t *nil = dict_nil(dict); - dnode_t *tentative = 0; - - while (root != nil) { - int result = dict->compare(key, root->key); - - if (result < 0) { - root = root->left; - } else if (result > 0) { - tentative = root; - root = root->right; - } else { - if (!dict->dupes) { - return root; - } else { - tentative = root; - root = root->right; - } - } - } - - return tentative; + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *tentative = 0; + + while (root != nil) { + int result = dict->compare(key, root->key); + + if (result < 0) { + root = root->left; + } else if (result > 0) { + tentative = root; + root = root->right; + } else { + if (!dict->dupes) { + return root; + } else { + tentative = root; + root = root->right; + } + } + } + + return tentative; } /* @@ -531,93 +533,96 @@ dnode_t *dict_upper_bound(dict_t *dict, const void *key) void dict_insert(dict_t *dict, dnode_t *node, const void *key) { - dnode_t *where = dict_root(dict), *nil = dict_nil(dict); - dnode_t *parent = nil, *uncle, *grandpa; - int result = -1; - - node->key = key; - - assert (!dict_isfull(dict)); - assert (!dict_contains(dict, node)); - assert (!dnode_is_in_a_dict(node)); + dnode_t *where = dict_root(dict), *nil = dict_nil(dict); + dnode_t *parent = nil, *uncle, *grandpa; + int result = -1; + + node->key = key; + + assert(!dict_isfull(dict)); + assert(!dict_contains(dict, node)); + assert(!dnode_is_in_a_dict(node)); + + /* basic binary tree insert */ + + while (where != nil) { + parent = where; + result = dict->compare(key, where->key); + /* trap attempts at duplicate key insertion unless it's + * explicitly allowed */ + assert(dict->dupes || result != 0); + if (result < 0) + where = where->left; + else + where = where->right; + } - /* basic binary tree insert */ + assert(where == nil); - while (where != nil) { - parent = where; - result = dict->compare(key, where->key); - /* trap attempts at duplicate key insertion unless it's explicitly allowed */ - assert (dict->dupes || result != 0); if (result < 0) - where = where->left; + parent->left = node; else - where = where->right; - } - - assert (where == nil); - - if (result < 0) - parent->left = node; - else - parent->right = node; - - node->parent = parent; - node->left = nil; - node->right = nil; - - dict->nodecount++; - - /* red black adjustments */ - - node->color = dnode_red; - - while (parent->color == dnode_red) { - grandpa = parent->parent; - if (parent == grandpa->left) { - uncle = grandpa->right; - if (uncle->color == dnode_red) { /* red parent, red uncle */ - parent->color = dnode_black; - uncle->color = dnode_black; - grandpa->color = dnode_red; - node = grandpa; - parent = grandpa->parent; - } else { /* red parent, black uncle */ - if (node == parent->right) { - rotate_left(parent); - parent = node; - assert (grandpa == parent->parent); - /* rotation between parent and child preserves grandpa */ - } - parent->color = dnode_black; - grandpa->color = dnode_red; - rotate_right(grandpa); - break; - } - } else { /* symmetric cases: parent == parent->parent->right */ - uncle = grandpa->left; - if (uncle->color == dnode_red) { - parent->color = dnode_black; - uncle->color = dnode_black; - grandpa->color = dnode_red; - node = grandpa; - parent = grandpa->parent; - } else { - if (node == parent->left) { - rotate_right(parent); - parent = node; - assert (grandpa == parent->parent); + parent->right = node; + + node->parent = parent; + node->left = nil; + node->right = nil; + + dict->nodecount++; + + /* red black adjustments */ + + node->color = dnode_red; + + while (parent->color == dnode_red) { + grandpa = parent->parent; + if (parent == grandpa->left) { + uncle = grandpa->right; + if (uncle->color + == dnode_red) { /* red parent, red uncle */ + parent->color = dnode_black; + uncle->color = dnode_black; + grandpa->color = dnode_red; + node = grandpa; + parent = grandpa->parent; + } else { /* red parent, black uncle */ + if (node == parent->right) { + rotate_left(parent); + parent = node; + assert(grandpa == parent->parent); + /* rotation between parent and child + * preserves grandpa */ + } + parent->color = dnode_black; + grandpa->color = dnode_red; + rotate_right(grandpa); + break; + } + } else { /* symmetric cases: parent == parent->parent->right */ + uncle = grandpa->left; + if (uncle->color == dnode_red) { + parent->color = dnode_black; + uncle->color = dnode_black; + grandpa->color = dnode_red; + node = grandpa; + parent = grandpa->parent; + } else { + if (node == parent->left) { + rotate_right(parent); + parent = node; + assert(grandpa == parent->parent); + } + parent->color = dnode_black; + grandpa->color = dnode_red; + rotate_left(grandpa); + break; + } } - parent->color = dnode_black; - grandpa->color = dnode_red; - rotate_left(grandpa); - break; - } } - } - dict_root(dict)->color = dnode_black; + dict_root(dict)->color = dnode_black; - assert (dict_verify(dict)); + assert(dict_verify(dict)); } /* @@ -628,172 +633,185 @@ void dict_insert(dict_t *dict, dnode_t *node, const void *key) dnode_t *dict_delete(dict_t *dict, dnode_t *delete) { - dnode_t *nil = dict_nil(dict), *child, *delparent = delete->parent; - - /* basic deletion */ - - assert (!dict_isempty(dict)); - assert (dict_contains(dict, delete)); - - /* - * If the node being deleted has two children, then we replace it with its - * successor (i.e. the leftmost node in the right subtree.) By doing this, - * we avoid the traditional algorithm under which the successor's key and - * value *only* move to the deleted node and the successor is spliced out - * from the tree. We cannot use this approach because the user may hold - * pointers to the successor, or nodes may be inextricably tied to some - * other structures by way of embedding, etc. So we must splice out the - * node we are given, not some other node, and must not move contents from - * one node to another behind the user's back. - */ - - if (delete->left != nil && delete->right != nil) { - dnode_t *next = dict_next(dict, delete); - assert (next); - dnode_t *nextparent = next->parent; - dnode_color_t nextcolor = next->color; - - assert (next != nil); - assert (next->parent != nil); - assert (next->left == nil); + dnode_t *nil = dict_nil(dict), *child, *delparent = delete->parent; - /* - * First, splice out the successor from the tree completely, by - * moving up its right child into its place. - */ + /* basic deletion */ - child = next->right; - child->parent = nextparent; - - if (nextparent->left == next) { - nextparent->left = child; - } else { - assert (nextparent->right == next); - nextparent->right = child; - } + assert(!dict_isempty(dict)); + assert(dict_contains(dict, delete)); /* - * Now that the successor has been extricated from the tree, install it - * in place of the node that we want deleted. + * If the node being deleted has two children, then we replace it with + * its + * successor (i.e. the leftmost node in the right subtree.) By doing + * this, + * we avoid the traditional algorithm under which the successor's key + * and + * value *only* move to the deleted node and the successor is spliced + * out + * from the tree. We cannot use this approach because the user may hold + * pointers to the successor, or nodes may be inextricably tied to some + * other structures by way of embedding, etc. So we must splice out the + * node we are given, not some other node, and must not move contents + * from + * one node to another behind the user's back. */ - next->parent = delparent; - next->left = delete->left; - next->right = delete->right; - next->left->parent = next; - next->right->parent = next; - next->color = delete->color; - delete->color = nextcolor; - - if (delparent->left == delete) { - delparent->left = next; - } else { - assert (delparent->right == delete); - delparent->right = next; - } - - } else { - assert (delete != nil); - assert (delete->left == nil || delete->right == nil); + if (delete->left != nil && delete->right != nil) { + dnode_t *next = dict_next(dict, delete); + assert(next); + dnode_t *nextparent = next->parent; + dnode_color_t nextcolor = next->color; - child = (delete->left != nil) ? delete->left : delete->right; + assert(next != nil); + assert(next->parent != nil); + assert(next->left == nil); - child->parent = delparent = delete->parent; - - if (delete == delparent->left) { - delparent->left = child; - } else { - assert (delete == delparent->right); - delparent->right = child; - } - } + /* + * First, splice out the successor from the tree completely, by + * moving up its right child into its place. + */ - delete->parent = NULL; - delete->right = NULL; - delete->left = NULL; + child = next->right; + child->parent = nextparent; - dict->nodecount--; + if (nextparent->left == next) { + nextparent->left = child; + } else { + assert(nextparent->right == next); + nextparent->right = child; + } - assert (verify_bintree(dict)); + /* + * Now that the successor has been extricated from the tree, + * install it + * in place of the node that we want deleted. + */ + + next->parent = delparent; + next->left = delete->left; + next->right = delete->right; + next->left->parent = next; + next->right->parent = next; + next->color = delete->color; + delete->color = nextcolor; + + if (delparent->left == delete) { + delparent->left = next; + } else { + assert(delparent->right == delete); + delparent->right = next; + } - /* red-black adjustments */ + } else { + assert(delete != nil); + assert(delete->left == nil || delete->right == nil); - if (delete->color == dnode_black) { - dnode_t *parent, *sister; + child = (delete->left != nil) ? delete->left : delete->right; - dict_root(dict)->color = dnode_red; + child->parent = delparent = delete->parent; - while (child->color == dnode_black) { - parent = child->parent; - if (child == parent->left) { - sister = parent->right; - assert (sister != nil); - if (sister->color == dnode_red) { - sister->color = dnode_black; - parent->color = dnode_red; - rotate_left(parent); - sister = parent->right; - assert (sister != nil); - } - if (sister->left->color == dnode_black - && sister->right->color == dnode_black) { - sister->color = dnode_red; - child = parent; + if (delete == delparent->left) { + delparent->left = child; } else { - if (sister->right->color == dnode_black) { - assert (sister->left->color == dnode_red); - sister->left->color = dnode_black; - sister->color = dnode_red; - rotate_right(sister); - sister = parent->right; - assert (sister != nil); - } - sister->color = parent->color; - sister->right->color = dnode_black; - parent->color = dnode_black; - rotate_left(parent); - break; - } - } else { /* symmetric case: child == child->parent->right */ - assert (child == parent->right); - sister = parent->left; - assert (sister != nil); - if (sister->color == dnode_red) { - sister->color = dnode_black; - parent->color = dnode_red; - rotate_right(parent); - sister = parent->left; - assert (sister != nil); + assert(delete == delparent->right); + delparent->right = child; } - if (sister->right->color == dnode_black - && sister->left->color == dnode_black) { - sister->color = dnode_red; - child = parent; - } else { - if (sister->left->color == dnode_black) { - assert (sister->right->color == dnode_red); - sister->right->color = dnode_black; - sister->color = dnode_red; - rotate_left(sister); - sister = parent->left; - assert (sister != nil); - } - sister->color = parent->color; - sister->left->color = dnode_black; - parent->color = dnode_black; - rotate_right(parent); - break; - } - } } - child->color = dnode_black; - dict_root(dict)->color = dnode_black; - } + delete->parent = NULL; + delete->right = NULL; + delete->left = NULL; + + dict->nodecount--; + + assert(verify_bintree(dict)); + + /* red-black adjustments */ + + if (delete->color == dnode_black) { + dnode_t *parent, *sister; + + dict_root(dict)->color = dnode_red; + + while (child->color == dnode_black) { + parent = child->parent; + if (child == parent->left) { + sister = parent->right; + assert(sister != nil); + if (sister->color == dnode_red) { + sister->color = dnode_black; + parent->color = dnode_red; + rotate_left(parent); + sister = parent->right; + assert(sister != nil); + } + if (sister->left->color == dnode_black + && sister->right->color == dnode_black) { + sister->color = dnode_red; + child = parent; + } else { + if (sister->right->color + == dnode_black) { + assert(sister->left->color + == dnode_red); + sister->left->color = + dnode_black; + sister->color = dnode_red; + rotate_right(sister); + sister = parent->right; + assert(sister != nil); + } + sister->color = parent->color; + sister->right->color = dnode_black; + parent->color = dnode_black; + rotate_left(parent); + break; + } + } else { /* symmetric case: child == + child->parent->right */ + assert(child == parent->right); + sister = parent->left; + assert(sister != nil); + if (sister->color == dnode_red) { + sister->color = dnode_black; + parent->color = dnode_red; + rotate_right(parent); + sister = parent->left; + assert(sister != nil); + } + if (sister->right->color == dnode_black + && sister->left->color == dnode_black) { + sister->color = dnode_red; + child = parent; + } else { + if (sister->left->color + == dnode_black) { + assert(sister->right->color + == dnode_red); + sister->right->color = + dnode_black; + sister->color = dnode_red; + rotate_left(sister); + sister = parent->left; + assert(sister != nil); + } + sister->color = parent->color; + sister->left->color = dnode_black; + parent->color = dnode_black; + rotate_right(parent); + break; + } + } + } + + child->color = dnode_black; + dict_root(dict)->color = dnode_black; + } - assert (dict_verify(dict)); + assert(dict_verify(dict)); - return delete; + return delete; } /* @@ -803,20 +821,20 @@ dnode_t *dict_delete(dict_t *dict, dnode_t *delete) int dict_alloc_insert(dict_t *dict, const void *key, void *data) { - dnode_t *node = dict->allocnode (dict->context); + dnode_t *node = dict->allocnode(dict->context); - if (node) { - dnode_init(node, data); - dict_insert(dict, node, key); - return 1; - } - return 0; + if (node) { + dnode_init(node, data); + dict_insert(dict, node, key); + return 1; + } + return 0; } void dict_delete_free(dict_t *dict, dnode_t *node) { - dict_delete(dict, node); - dict->freenode(node, dict->context); + dict_delete(dict, node); + dict->freenode(node, dict->context); } /* @@ -826,13 +844,13 @@ void dict_delete_free(dict_t *dict, dnode_t *node) dnode_t *dict_first(dict_t *dict) { - dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; + dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; - if (root != nil) - while ((left = root->left) != nil) - root = left; + if (root != nil) + while ((left = root->left) != nil) + root = left; - return (root == nil) ? NULL : root; + return (root == nil) ? NULL : root; } /* @@ -842,13 +860,13 @@ dnode_t *dict_first(dict_t *dict) dnode_t *dict_last(dict_t *dict) { - dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *right; + dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *right; - if (root != nil) - while ((right = root->right) != nil) - root = right; + if (root != nil) + while ((right = root->right) != nil) + root = right; - return (root == nil) ? NULL : root; + return (root == nil) ? NULL : root; } /* @@ -860,23 +878,23 @@ dnode_t *dict_last(dict_t *dict) dnode_t *dict_next(dict_t *dict, dnode_t *curr) { - dnode_t *nil = dict_nil(dict), *parent, *left; + dnode_t *nil = dict_nil(dict), *parent, *left; - if (curr->right != nil) { - curr = curr->right; - while ((left = curr->left) != nil) - curr = left; - return curr; - } - - parent = curr->parent; + if (curr->right != nil) { + curr = curr->right; + while ((left = curr->left) != nil) + curr = left; + return curr; + } - while (parent != nil && curr == parent->right) { - curr = parent; parent = curr->parent; - } - return (parent == nil) ? NULL : parent; + while (parent != nil && curr == parent->right) { + curr = parent; + parent = curr->parent; + } + + return (parent == nil) ? NULL : parent; } /* @@ -886,28 +904,28 @@ dnode_t *dict_next(dict_t *dict, dnode_t *curr) dnode_t *dict_prev(dict_t *dict, dnode_t *curr) { - dnode_t *nil = dict_nil(dict), *parent, *right; - - if (curr->left != nil) { - curr = curr->left; - while ((right = curr->right) != nil) - curr = right; - return curr; - } + dnode_t *nil = dict_nil(dict), *parent, *right; - parent = curr->parent; + if (curr->left != nil) { + curr = curr->left; + while ((right = curr->right) != nil) + curr = right; + return curr; + } - while (parent != nil && curr == parent->left) { - curr = parent; parent = curr->parent; - } - return (parent == nil) ? NULL : parent; + while (parent != nil && curr == parent->left) { + curr = parent; + parent = curr->parent; + } + + return (parent == nil) ? NULL : parent; } void dict_allow_dupes(dict_t *dict) { - dict->dupes = 1; + dict->dupes = 1; } #undef dict_count @@ -919,266 +937,266 @@ void dict_allow_dupes(dict_t *dict) dictcount_t dict_count(dict_t *dict) { - return dict->nodecount; + return dict->nodecount; } int dict_isempty(dict_t *dict) { - return dict->nodecount == 0; + return dict->nodecount == 0; } int dict_isfull(dict_t *dict) { - return dict->nodecount == dict->maxcount; + return dict->nodecount == dict->maxcount; } int dict_contains(dict_t *dict, dnode_t *node) { - return verify_dict_has_node(dict_nil(dict), dict_root(dict), node); + return verify_dict_has_node(dict_nil(dict), dict_root(dict), node); } static dnode_t *dnode_alloc(void *context) { - return XCALLOC(MTYPE_ISIS_DICT_NODE, sizeof(dnode_t)); + return XCALLOC(MTYPE_ISIS_DICT_NODE, sizeof(dnode_t)); } static void dnode_free(dnode_t *node, void *context) { - XFREE(MTYPE_ISIS_DICT_NODE, node); + XFREE(MTYPE_ISIS_DICT_NODE, node); } dnode_t *dnode_create(void *data) { - dnode_t *new = XCALLOC(MTYPE_ISIS_DICT_NODE, sizeof(dnode_t)); - if (new) { - new->data = data; - new->parent = NULL; - new->left = NULL; - new->right = NULL; - } - return new; + dnode_t *new = XCALLOC(MTYPE_ISIS_DICT_NODE, sizeof(dnode_t)); + if (new) { + new->data = data; + new->parent = NULL; + new->left = NULL; + new->right = NULL; + } + return new; } dnode_t *dnode_init(dnode_t *dnode, void *data) { - dnode->data = data; - dnode->parent = NULL; - dnode->left = NULL; - dnode->right = NULL; - return dnode; + dnode->data = data; + dnode->parent = NULL; + dnode->left = NULL; + dnode->right = NULL; + return dnode; } void dnode_destroy(dnode_t *dnode) { - assert (!dnode_is_in_a_dict(dnode)); - XFREE(MTYPE_ISIS_DICT_NODE, dnode); + assert(!dnode_is_in_a_dict(dnode)); + XFREE(MTYPE_ISIS_DICT_NODE, dnode); } void *dnode_get(dnode_t *dnode) { - return dnode->data; + return dnode->data; } const void *dnode_getkey(dnode_t *dnode) { - return dnode->key; + return dnode->key; } void dnode_put(dnode_t *dnode, void *data) { - dnode->data = data; + dnode->data = data; } int dnode_is_in_a_dict(dnode_t *dnode) { - return (dnode->parent && dnode->left && dnode->right); + return (dnode->parent && dnode->left && dnode->right); } void dict_process(dict_t *dict, void *context, dnode_process_t function) { - dnode_t *node = dict_first(dict), *next; - - while (node != NULL) { - /* check for callback function deleting */ - /* the next node from under us */ - assert (dict_contains(dict, node)); - next = dict_next(dict, node); - function(dict, node, context); - node = next; - } + dnode_t *node = dict_first(dict), *next; + + while (node != NULL) { + /* check for callback function deleting */ + /* the next node from under us */ + assert(dict_contains(dict, node)); + next = dict_next(dict, node); + function(dict, node, context); + node = next; + } } static void load_begin_internal(dict_load_t *load, dict_t *dict) { - load->dictptr = dict; - load->nilnode.left = &load->nilnode; - load->nilnode.right = &load->nilnode; + load->dictptr = dict; + load->nilnode.left = &load->nilnode; + load->nilnode.right = &load->nilnode; } void dict_load_begin(dict_load_t *load, dict_t *dict) { - assert (dict_isempty(dict)); - load_begin_internal(load, dict); + assert(dict_isempty(dict)); + load_begin_internal(load, dict); } void dict_load_next(dict_load_t *load, dnode_t *newnode, const void *key) { - dict_t *dict = load->dictptr; - dnode_t *nil = &load->nilnode; - - assert (!dnode_is_in_a_dict(newnode)); - assert (dict->nodecount < dict->maxcount); - - #ifndef NDEBUG - if (dict->nodecount > 0) { - if (dict->dupes) - assert (dict->compare(nil->left->key, key) <= 0); - else - assert (dict->compare(nil->left->key, key) < 0); - } - #endif - - newnode->key = key; - nil->right->left = newnode; - nil->right = newnode; - newnode->left = nil; - dict->nodecount++; + dict_t *dict = load->dictptr; + dnode_t *nil = &load->nilnode; + + assert(!dnode_is_in_a_dict(newnode)); + assert(dict->nodecount < dict->maxcount); + +#ifndef NDEBUG + if (dict->nodecount > 0) { + if (dict->dupes) + assert(dict->compare(nil->left->key, key) <= 0); + else + assert(dict->compare(nil->left->key, key) < 0); + } +#endif + + newnode->key = key; + nil->right->left = newnode; + nil->right = newnode; + newnode->left = nil; + dict->nodecount++; } void dict_load_end(dict_load_t *load) { - dict_t *dict = load->dictptr; - dnode_t *tree[DICT_DEPTH_MAX] = { 0 }; - dnode_t *curr, *dictnil = dict_nil(dict), *loadnil = &load->nilnode, *next; - dnode_t *complete = 0; - dictcount_t fullcount = DICTCOUNT_T_MAX, nodecount = dict->nodecount; - dictcount_t botrowcount; - unsigned baselevel = 0, level = 0, i; - - assert (dnode_red == 0 && dnode_black == 1); - - while (fullcount >= nodecount && fullcount) - fullcount >>= 1; - - botrowcount = nodecount - fullcount; - - for (curr = loadnil->left; curr != loadnil; curr = next) { - next = curr->left; - - if (complete == NULL && botrowcount-- == 0) { - assert (baselevel == 0); - assert (level == 0); - baselevel = level = 1; - complete = tree[0]; - - if (complete != 0) { - tree[0] = 0; - complete->right = dictnil; - while (tree[level] != 0) { - tree[level]->right = complete; - complete->parent = tree[level]; - complete = tree[level]; - tree[level++] = 0; + dict_t *dict = load->dictptr; + dnode_t *tree[DICT_DEPTH_MAX] = {0}; + dnode_t *curr, *dictnil = dict_nil(dict), *loadnil = &load->nilnode, + *next; + dnode_t *complete = 0; + dictcount_t fullcount = DICTCOUNT_T_MAX, nodecount = dict->nodecount; + dictcount_t botrowcount; + unsigned baselevel = 0, level = 0, i; + + assert(dnode_red == 0 && dnode_black == 1); + + while (fullcount >= nodecount && fullcount) + fullcount >>= 1; + + botrowcount = nodecount - fullcount; + + for (curr = loadnil->left; curr != loadnil; curr = next) { + next = curr->left; + + if (complete == NULL && botrowcount-- == 0) { + assert(baselevel == 0); + assert(level == 0); + baselevel = level = 1; + complete = tree[0]; + + if (complete != 0) { + tree[0] = 0; + complete->right = dictnil; + while (tree[level] != 0) { + tree[level]->right = complete; + complete->parent = tree[level]; + complete = tree[level]; + tree[level++] = 0; + } + } } - } - } - if (complete == NULL) { - curr->left = dictnil; - curr->right = dictnil; - curr->color = level % 2; - complete = curr; - - assert (level == baselevel); - while (tree[level] != 0) { - tree[level]->right = complete; - complete->parent = tree[level]; - complete = tree[level]; - tree[level++] = 0; - } - } else { - curr->left = complete; - curr->color = (level + 1) % 2; - complete->parent = curr; - tree[level] = curr; - complete = 0; - level = baselevel; + if (complete == NULL) { + curr->left = dictnil; + curr->right = dictnil; + curr->color = level % 2; + complete = curr; + + assert(level == baselevel); + while (tree[level] != 0) { + tree[level]->right = complete; + complete->parent = tree[level]; + complete = tree[level]; + tree[level++] = 0; + } + } else { + curr->left = complete; + curr->color = (level + 1) % 2; + complete->parent = curr; + tree[level] = curr; + complete = 0; + level = baselevel; + } } - } - if (complete == NULL) - complete = dictnil; + if (complete == NULL) + complete = dictnil; - for (i = 0; i < DICT_DEPTH_MAX; i++) { - if (tree[i] != 0) { - tree[i]->right = complete; - complete->parent = tree[i]; - complete = tree[i]; + for (i = 0; i < DICT_DEPTH_MAX; i++) { + if (tree[i] != 0) { + tree[i]->right = complete; + complete->parent = tree[i]; + complete = tree[i]; + } } - } - dictnil->color = dnode_black; - dictnil->right = dictnil; - complete->parent = dictnil; - complete->color = dnode_black; - dict_root(dict) = complete; + dictnil->color = dnode_black; + dictnil->right = dictnil; + complete->parent = dictnil; + complete->color = dnode_black; + dict_root(dict) = complete; - assert (dict_verify(dict)); + assert(dict_verify(dict)); } void dict_merge(dict_t *dest, dict_t *source) { - dict_load_t load; - dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source); - - assert (dict_similar(dest, source)); - - if (source == dest) - return; - - dest->nodecount = 0; - load_begin_internal(&load, dest); - - for (;;) { - if (leftnode != NULL && rightnode != NULL) { - if (dest->compare(leftnode->key, rightnode->key) < 0) - goto copyleft; - else - goto copyright; - } else if (leftnode != NULL) { - goto copyleft; - } else if (rightnode != NULL) { - goto copyright; - } else { - assert (leftnode == NULL && rightnode == NULL); - break; + dict_load_t load; + dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source); + + assert(dict_similar(dest, source)); + + if (source == dest) + return; + + dest->nodecount = 0; + load_begin_internal(&load, dest); + + for (;;) { + if (leftnode != NULL && rightnode != NULL) { + if (dest->compare(leftnode->key, rightnode->key) < 0) + goto copyleft; + else + goto copyright; + } else if (leftnode != NULL) { + goto copyleft; + } else if (rightnode != NULL) { + goto copyright; + } else { + assert(leftnode == NULL && rightnode == NULL); + break; + } + + copyleft : { + dnode_t *next = dict_next(dest, leftnode); +#ifndef NDEBUG + leftnode->left = + NULL; /* suppress assertion in dict_load_next */ +#endif + dict_load_next(&load, leftnode, leftnode->key); + leftnode = next; + continue; } - copyleft: - { - dnode_t *next = dict_next(dest, leftnode); - #ifndef NDEBUG - leftnode->left = NULL; /* suppress assertion in dict_load_next */ - #endif - dict_load_next(&load, leftnode, leftnode->key); - leftnode = next; - continue; + copyright : { + dnode_t *next = dict_next(source, rightnode); +#ifndef NDEBUG + rightnode->left = NULL; +#endif + dict_load_next(&load, rightnode, rightnode->key); + rightnode = next; + continue; } - - copyright: - { - dnode_t *next = dict_next(source, rightnode); - #ifndef NDEBUG - rightnode->left = NULL; - #endif - dict_load_next(&load, rightnode, rightnode->key); - rightnode = next; - continue; } - } - dict_clear(source); - dict_load_end(&load); + dict_clear(source); + dict_load_end(&load); } #ifdef KAZLIB_TEST_MAIN @@ -1192,54 +1210,54 @@ typedef char input_t[256]; static int tokenize(char *string, ...) { - char **tokptr; - va_list arglist; - int tokcount = 0; - - va_start(arglist, string); - tokptr = va_arg(arglist, char **); - while (tokptr) { - while (*string && isspace((unsigned char) *string)) - string++; - if (!*string) - break; - *tokptr = string; - while (*string && !isspace((unsigned char) *string)) - string++; + char **tokptr; + va_list arglist; + int tokcount = 0; + + va_start(arglist, string); tokptr = va_arg(arglist, char **); - tokcount++; - if (!*string) - break; - *string++ = 0; - } - va_end(arglist); - - return tokcount; + while (tokptr) { + while (*string && isspace((unsigned char)*string)) + string++; + if (!*string) + break; + *tokptr = string; + while (*string && !isspace((unsigned char)*string)) + string++; + tokptr = va_arg(arglist, char **); + tokcount++; + if (!*string) + break; + *string++ = 0; + } + va_end(arglist); + + return tokcount; } static int comparef(const void *key1, const void *key2) { - return strcmp(key1, key2); + return strcmp(key1, key2); } static char *dupstring(char *str) { - int sz = strlen(str) + 1; - char *new = XCALLOC(MTYPE_ISIS_TMP, sz); - if (new) - memcpy(new, str, sz); - return new; + int sz = strlen(str) + 1; + char *new = XCALLOC(MTYPE_ISIS_TMP, sz); + if (new) + memcpy(new, str, sz); + return new; } static dnode_t *new_node(void *c) { - static dnode_t few[5]; - static int count; + static dnode_t few[5]; + static int count; - if (count < 5) - return few + count++; + if (count < 5) + return few + count++; - return NULL; + return NULL; } static void del_node(dnode_t *n, void *c) @@ -1250,238 +1268,239 @@ static int prompt = 0; static void construct(dict_t *d) { - input_t in; - int done = 0; - dict_load_t dl; - dnode_t *dn; - char *tok1, *tok2, *val; - const char *key; - char *help = - "p turn prompt on\n" - "q finish construction\n" - "a <key> <val> add new entry\n"; - - if (!dict_isempty(d)) - puts("warning: dictionary not empty!"); - - dict_load_begin(&dl, d); - - while (!done) { - if (prompt) - putchar('>'); - fflush(stdout); - - if (!fgets(in, sizeof(input_t), stdin)) - break; - - switch (in[0]) { - case '?': - puts(help); - break; - case 'p': - prompt = 1; - break; - case 'q': - done = 1; - break; - case 'a': - if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { - puts("what?"); - break; - } - key = dupstring(tok1); - val = dupstring(tok2); - dn = dnode_create(val); - - if (!key || !val || !dn) { - puts("out of memory"); - free((void *) key); - free(val); - if (dn) - dnode_destroy(dn); - } + input_t in; + int done = 0; + dict_load_t dl; + dnode_t *dn; + char *tok1, *tok2, *val; + const char *key; + char *help = + "p turn prompt on\n" + "q finish construction\n" + "a <key> <val> add new entry\n"; + + if (!dict_isempty(d)) + puts("warning: dictionary not empty!"); + + dict_load_begin(&dl, d); + + while (!done) { + if (prompt) + putchar('>'); + fflush(stdout); + + if (!fgets(in, sizeof(input_t), stdin)) + break; - dict_load_next(&dl, dn, key); - break; - default: - putchar('?'); - putchar('\n'); - break; + switch (in[0]) { + case '?': + puts(help); + break; + case 'p': + prompt = 1; + break; + case 'q': + done = 1; + break; + case 'a': + if (tokenize(in + 1, &tok1, &tok2, (char **)0) != 2) { + puts("what?"); + break; + } + key = dupstring(tok1); + val = dupstring(tok2); + dn = dnode_create(val); + + if (!key || !val || !dn) { + puts("out of memory"); + free((void *)key); + free(val); + if (dn) + dnode_destroy(dn); + } + + dict_load_next(&dl, dn, key); + break; + default: + putchar('?'); + putchar('\n'); + break; + } } - } - dict_load_end(&dl); + dict_load_end(&dl); } int main(void) { - input_t in; - dict_t darray[10]; - dict_t *d = &darray[0]; - dnode_t *dn; - int i; - char *tok1, *tok2, *val; - const char *key; - - char *help = - "a <key> <val> add value to dictionary\n" - "d <key> delete value from dictionary\n" - "l <key> lookup value in dictionary\n" - "( <key> lookup lower bound\n" - ") <key> lookup upper bound\n" - "# <num> switch to alternate dictionary (0-9)\n" - "j <num> <num> merge two dictionaries\n" - "f free the whole dictionary\n" - "k allow duplicate keys\n" - "c show number of entries\n" - "t dump whole dictionary in sort order\n" - "m make dictionary out of sorted items\n" - "p turn prompt on\n" - "s switch to non-functioning allocator\n" - "q quit"; - - for (i = 0; i < 10; i++) - dict_init(&darray[i], DICTCOUNT_T_MAX, comparef); - - for (;;) { - if (prompt) - putchar('>'); - fflush(stdout); - - if (!fgets(in, sizeof(input_t), stdin)) - break; - - switch(in[0]) { - case '?': - puts(help); - break; - case 'a': - if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { - puts("what?"); - break; - } - key = dupstring(tok1); - val = dupstring(tok2); - - if (!key || !val) { - puts("out of memory"); - free((void *) key); - free(val); - } + input_t in; + dict_t darray[10]; + dict_t *d = &darray[0]; + dnode_t *dn; + int i; + char *tok1, *tok2, *val; + const char *key; + + char *help = + "a <key> <val> add value to dictionary\n" + "d <key> delete value from dictionary\n" + "l <key> lookup value in dictionary\n" + "( <key> lookup lower bound\n" + ") <key> lookup upper bound\n" + "# <num> switch to alternate dictionary (0-9)\n" + "j <num> <num> merge two dictionaries\n" + "f free the whole dictionary\n" + "k allow duplicate keys\n" + "c show number of entries\n" + "t dump whole dictionary in sort order\n" + "m make dictionary out of sorted items\n" + "p turn prompt on\n" + "s switch to non-functioning allocator\n" + "q quit"; + + for (i = 0; i < 10; i++) + dict_init(&darray[i], DICTCOUNT_T_MAX, comparef); + + for (;;) { + if (prompt) + putchar('>'); + fflush(stdout); + + if (!fgets(in, sizeof(input_t), stdin)) + break; - if (!dict_alloc_insert(d, key, val)) { - puts("dict_alloc_insert failed"); - free((void *) key); - free(val); - break; - } - break; - case 'd': - if (tokenize(in+1, &tok1, (char **) 0) != 1) { - puts("what?"); - break; - } - dn = dict_lookup(d, tok1); - if (!dn) { - puts("dict_lookup failed"); - break; - } - val = dnode_get(dn); - key = dnode_getkey(dn); - dict_delete_free(d, dn); - - free(val); - free((void *) key); - break; - case 'f': - dict_free(d); - break; - case 'l': - case '(': - case ')': - if (tokenize(in+1, &tok1, (char **) 0) != 1) { - puts("what?"); - break; - } - dn = 0; switch (in[0]) { + case '?': + puts(help); + break; + case 'a': + if (tokenize(in + 1, &tok1, &tok2, (char **)0) != 2) { + puts("what?"); + break; + } + key = dupstring(tok1); + val = dupstring(tok2); + + if (!key || !val) { + puts("out of memory"); + free((void *)key); + free(val); + } + + if (!dict_alloc_insert(d, key, val)) { + puts("dict_alloc_insert failed"); + free((void *)key); + free(val); + break; + } + break; + case 'd': + if (tokenize(in + 1, &tok1, (char **)0) != 1) { + puts("what?"); + break; + } + dn = dict_lookup(d, tok1); + if (!dn) { + puts("dict_lookup failed"); + break; + } + val = dnode_get(dn); + key = dnode_getkey(dn); + dict_delete_free(d, dn); + + free(val); + free((void *)key); + break; + case 'f': + dict_free(d); + break; case 'l': - dn = dict_lookup(d, tok1); - break; case '(': - dn = dict_lower_bound(d, tok1); - break; case ')': - dn = dict_upper_bound(d, tok1); - break; - } - if (!dn) { - puts("lookup failed"); - break; - } - val = dnode_get(dn); - puts(val); - break; - case 'm': - construct(d); - break; - case 'k': - dict_allow_dupes(d); - break; - case 'c': - printf("%lu\n", (unsigned long) dict_count(d)); - break; - case 't': - for (dn = dict_first(d); dn; dn = dict_next(d, dn)) { - printf("%s\t%s\n", (char *) dnode_getkey(dn), - (char *) dnode_get(dn)); - } - break; - case 'q': - exit(0); - break; - case '\0': - break; - case 'p': - prompt = 1; - break; - case 's': - dict_set_allocator(d, new_node, del_node, NULL); - break; - case '#': - if (tokenize(in+1, &tok1, (char **) 0) != 1) { - puts("what?"); - break; - } else { - int dictnum = atoi(tok1); - if (dictnum < 0 || dictnum > 9) { - puts("invalid number"); + if (tokenize(in + 1, &tok1, (char **)0) != 1) { + puts("what?"); + break; + } + dn = 0; + switch (in[0]) { + case 'l': + dn = dict_lookup(d, tok1); + break; + case '(': + dn = dict_lower_bound(d, tok1); + break; + case ')': + dn = dict_upper_bound(d, tok1); + break; + } + if (!dn) { + puts("lookup failed"); + break; + } + val = dnode_get(dn); + puts(val); break; - } - d = &darray[dictnum]; - } - break; - case 'j': - if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { - puts("what?"); - break; - } else { - int dict1 = atoi(tok1), dict2 = atoi(tok2); - if (dict1 < 0 || dict1 > 9 || dict2 < 0 || dict2 > 9) { - puts("invalid number"); + case 'm': + construct(d); + break; + case 'k': + dict_allow_dupes(d); + break; + case 'c': + printf("%lu\n", (unsigned long)dict_count(d)); + break; + case 't': + for (dn = dict_first(d); dn; dn = dict_next(d, dn)) { + printf("%s\t%s\n", (char *)dnode_getkey(dn), + (char *)dnode_get(dn)); + } + break; + case 'q': + exit(0); + break; + case '\0': + break; + case 'p': + prompt = 1; + break; + case 's': + dict_set_allocator(d, new_node, del_node, NULL); + break; + case '#': + if (tokenize(in + 1, &tok1, (char **)0) != 1) { + puts("what?"); + break; + } else { + int dictnum = atoi(tok1); + if (dictnum < 0 || dictnum > 9) { + puts("invalid number"); + break; + } + d = &darray[dictnum]; + } + break; + case 'j': + if (tokenize(in + 1, &tok1, &tok2, (char **)0) != 2) { + puts("what?"); + break; + } else { + int dict1 = atoi(tok1), dict2 = atoi(tok2); + if (dict1 < 0 || dict1 > 9 || dict2 < 0 + || dict2 > 9) { + puts("invalid number"); + break; + } + dict_merge(&darray[dict1], &darray[dict2]); + } + break; + default: + putchar('?'); + putchar('\n'); break; - } - dict_merge(&darray[dict1], &darray[dict2]); } - break; - default: - putchar('?'); - putchar('\n'); - break; } - } - return 0; + return 0; } #endif diff --git a/isisd/dict.h b/isisd/dict.h index 93edb7d60..a5ee92231 100644 --- a/isisd/dict.h +++ b/isisd/dict.h @@ -41,12 +41,12 @@ typedef unsigned long dictcount_t; typedef enum { dnode_red, dnode_black } dnode_color_t; typedef struct dnode_t { - struct dnode_t *dict_left; - struct dnode_t *dict_right; - struct dnode_t *dict_parent; - dnode_color_t dict_color; - const void *dict_key; - void *dict_data; + struct dnode_t *dict_left; + struct dnode_t *dict_right; + struct dnode_t *dict_parent; + dnode_color_t dict_color; + const void *dict_key; + void *dict_data; } dnode_t; typedef int (*dict_comp_t)(const void *, const void *); @@ -54,21 +54,21 @@ typedef dnode_t *(*dnode_alloc_t)(void *); typedef void (*dnode_free_t)(dnode_t *, void *); typedef struct dict_t { - dnode_t dict_nilnode; - dictcount_t dict_nodecount; - dictcount_t dict_maxcount; - dict_comp_t dict_compare; - dnode_alloc_t dict_allocnode; - dnode_free_t dict_freenode; - void *dict_context; - int dict_dupes; + dnode_t dict_nilnode; + dictcount_t dict_nodecount; + dictcount_t dict_maxcount; + dict_comp_t dict_compare; + dnode_alloc_t dict_allocnode; + dnode_free_t dict_freenode; + void *dict_context; + int dict_dupes; } dict_t; typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *); typedef struct dict_load_t { - dict_t *dict_dictptr; - dnode_t dict_nilnode; + dict_t *dict_dictptr; + dnode_t dict_nilnode; } dict_load_t; extern dict_t *dict_create(dictcount_t, dict_comp_t); diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index e4a4e0c42..d8cb32375 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -1,19 +1,19 @@ /* - * IS-IS Rout(e)ing protocol - isis_adjacency.c + * IS-IS Rout(e)ing protocol - isis_adjacency.c * handling of IS-IS adjacencies * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -51,512 +51,498 @@ extern struct isis *isis; -static struct isis_adjacency * -adj_alloc (const u_char *id) +static struct isis_adjacency *adj_alloc(const u_char *id) { - struct isis_adjacency *adj; + struct isis_adjacency *adj; - adj = XCALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency)); - memcpy (adj->sysid, id, ISIS_SYS_ID_LEN); + adj = XCALLOC(MTYPE_ISIS_ADJACENCY, sizeof(struct isis_adjacency)); + memcpy(adj->sysid, id, ISIS_SYS_ID_LEN); - return adj; + return adj; } -struct isis_adjacency * -isis_new_adj (const u_char * id, const u_char * snpa, int level, - struct isis_circuit *circuit) +struct isis_adjacency *isis_new_adj(const u_char *id, const u_char *snpa, + int level, struct isis_circuit *circuit) { - struct isis_adjacency *adj; - int i; - - adj = adj_alloc (id); /* P2P kludge */ - - if (adj == NULL) - { - zlog_err ("Out of memory!"); - return NULL; - } - - if (snpa) { - memcpy (adj->snpa, snpa, ETH_ALEN); - } else { - memset (adj->snpa, ' ', ETH_ALEN); - } - - adj->circuit = circuit; - adj->level = level; - adj->flaps = 0; - adj->last_flap = time (NULL); - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - listnode_add (circuit->u.bc.adjdb[level - 1], adj); - adj->dischanges[level - 1] = 0; - for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */ - { - adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis - = ISIS_UNKNOWN_DIS; - adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change - = time (NULL); + struct isis_adjacency *adj; + int i; + + adj = adj_alloc(id); /* P2P kludge */ + + if (adj == NULL) { + zlog_err("Out of memory!"); + return NULL; + } + + if (snpa) { + memcpy(adj->snpa, snpa, ETH_ALEN); + } else { + memset(adj->snpa, ' ', ETH_ALEN); } - } - return adj; + adj->circuit = circuit; + adj->level = level; + adj->flaps = 0; + adj->last_flap = time(NULL); + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + listnode_add(circuit->u.bc.adjdb[level - 1], adj); + adj->dischanges[level - 1] = 0; + for (i = 0; i < DIS_RECORDS; + i++) /* clear N DIS state change records */ + { + adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis = + ISIS_UNKNOWN_DIS; + adj->dis_record[(i * ISIS_LEVELS) + level - 1] + .last_dis_change = time(NULL); + } + } + + return adj; } -struct isis_adjacency * -isis_adj_lookup (const u_char * sysid, struct list *adjdb) +struct isis_adjacency *isis_adj_lookup(const u_char *sysid, struct list *adjdb) { - struct isis_adjacency *adj; - struct listnode *node; + struct isis_adjacency *adj; + struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) - if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0) - return adj; + for (ALL_LIST_ELEMENTS_RO(adjdb, node, adj)) + if (memcmp(adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0) + return adj; - return NULL; + return NULL; } -struct isis_adjacency * -isis_adj_lookup_snpa (const u_char * ssnpa, struct list *adjdb) +struct isis_adjacency *isis_adj_lookup_snpa(const u_char *ssnpa, + struct list *adjdb) { - struct listnode *node; - struct isis_adjacency *adj; + struct listnode *node; + struct isis_adjacency *adj; - for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) - if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0) - return adj; + for (ALL_LIST_ELEMENTS_RO(adjdb, node, adj)) + if (memcmp(adj->snpa, ssnpa, ETH_ALEN) == 0) + return adj; - return NULL; + return NULL; } -void -isis_delete_adj (void *arg) +void isis_delete_adj(void *arg) { - struct isis_adjacency *adj = arg; + struct isis_adjacency *adj = arg; - if (!adj) - return; + if (!adj) + return; - THREAD_TIMER_OFF (adj->t_expire); + THREAD_TIMER_OFF(adj->t_expire); - /* remove from SPF trees */ - spftree_area_adj_del (adj->circuit->area, adj); + /* remove from SPF trees */ + spftree_area_adj_del(adj->circuit->area, adj); - if (adj->area_addrs) - list_delete (adj->area_addrs); - if (adj->ipv4_addrs) - list_delete (adj->ipv4_addrs); - if (adj->ipv6_addrs) - list_delete (adj->ipv6_addrs); + if (adj->area_addrs) + list_delete(adj->area_addrs); + if (adj->ipv4_addrs) + list_delete(adj->ipv4_addrs); + if (adj->ipv6_addrs) + list_delete(adj->ipv6_addrs); - adj_mt_finish(adj); + adj_mt_finish(adj); - XFREE (MTYPE_ISIS_ADJACENCY, adj); - return; + XFREE(MTYPE_ISIS_ADJACENCY, adj); + return; } -static const char * -adj_state2string (int state) +static const char *adj_state2string(int state) { - switch (state) - { - case ISIS_ADJ_INITIALIZING: - return "Initializing"; - case ISIS_ADJ_UP: - return "Up"; - case ISIS_ADJ_DOWN: - return "Down"; - default: - return "Unknown"; - } - - return NULL; /* not reached */ + switch (state) { + case ISIS_ADJ_INITIALIZING: + return "Initializing"; + case ISIS_ADJ_UP: + return "Up"; + case ISIS_ADJ_DOWN: + return "Down"; + default: + return "Unknown"; + } + + return NULL; /* not reached */ } -void -isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state, - const char *reason) +void isis_adj_state_change(struct isis_adjacency *adj, + enum isis_adj_state new_state, const char *reason) { - int old_state; - int level; - struct isis_circuit *circuit; - bool del; - - old_state = adj->adj_state; - adj->adj_state = new_state; - - circuit = adj->circuit; - - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s", - circuit->area->area_tag, - old_state, new_state, reason ? reason : "unspecified"); - } - - if (circuit->area->log_adj_changes) - { - const char *adj_name; - struct isis_dynhn *dyn; - - dyn = dynhn_find_by_id (adj->sysid); - if (dyn) - adj_name = (const char *)dyn->name.name; - else - adj_name = sysid_print (adj->sysid); - - zlog_info ("%%ADJCHANGE: Adjacency to %s (%s) changed from %s to %s, %s", - adj_name, - adj->circuit->interface->name, - adj_state2string (old_state), - adj_state2string (new_state), - reason ? reason : "unspecified"); - } - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - del = false; - for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) - { - if ((adj->level & level) == 0) - continue; - if (new_state == ISIS_ADJ_UP) - { - circuit->upadjcount[level - 1]++; - isis_event_adjacency_state_change (adj, new_state); - /* update counter & timers for debugging purposes */ - adj->last_flap = time (NULL); - adj->flaps++; - } - else if (new_state == ISIS_ADJ_DOWN) - { - listnode_delete (circuit->u.bc.adjdb[level - 1], adj); - circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) - { - /* Clean lsp_queue when no adj is up. */ - if (circuit->lsp_queue) - list_delete_all_node (circuit->lsp_queue); - } - isis_event_adjacency_state_change (adj, new_state); - del = true; - } - - if (circuit->u.bc.lan_neighs[level - 1]) - { - list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]); - isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1], - circuit->u.bc.lan_neighs[level - 1]); - } - - /* On adjacency state change send new pseudo LSP if we are the DR */ - if (circuit->u.bc.is_dr[level - 1]) - lsp_regenerate_schedule_pseudo (circuit, level); - } - - if (del) - isis_delete_adj (adj); - - adj = NULL; - } - else if (circuit->circ_type == CIRCUIT_T_P2P) - { - del = false; - for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) - { - if ((adj->level & level) == 0) - continue; - if (new_state == ISIS_ADJ_UP) - { - circuit->upadjcount[level - 1]++; - isis_event_adjacency_state_change (adj, new_state); - - if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN) - send_hello (circuit, level); - - /* update counter & timers for debugging purposes */ - adj->last_flap = time (NULL); - adj->flaps++; - - /* 7.3.17 - going up on P2P -> send CSNP */ - /* FIXME: yup, I know its wrong... but i will do it! (for now) */ - send_csnp (circuit, level); - } - else if (new_state == ISIS_ADJ_DOWN) - { - if (adj->circuit->u.p2p.neighbor == adj) - adj->circuit->u.p2p.neighbor = NULL; - circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) - { - /* Clean lsp_queue when no adj is up. */ - if (circuit->lsp_queue) - list_delete_all_node (circuit->lsp_queue); - } - isis_event_adjacency_state_change (adj, new_state); - del = true; - } - } - - if (del) - isis_delete_adj (adj); - - adj = NULL; - } - - return; + int old_state; + int level; + struct isis_circuit *circuit; + bool del; + + old_state = adj->adj_state; + adj->adj_state = new_state; + + circuit = adj->circuit; + + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug("ISIS-Adj (%s): Adjacency state change %d->%d: %s", + circuit->area->area_tag, old_state, new_state, + reason ? reason : "unspecified"); + } + + if (circuit->area->log_adj_changes) { + const char *adj_name; + struct isis_dynhn *dyn; + + dyn = dynhn_find_by_id(adj->sysid); + if (dyn) + adj_name = (const char *)dyn->name.name; + else + adj_name = sysid_print(adj->sysid); + + zlog_info( + "%%ADJCHANGE: Adjacency to %s (%s) changed from %s to %s, %s", + adj_name, adj->circuit->interface->name, + adj_state2string(old_state), + adj_state2string(new_state), + reason ? reason : "unspecified"); + } + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + del = false; + for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { + if ((adj->level & level) == 0) + continue; + if (new_state == ISIS_ADJ_UP) { + circuit->upadjcount[level - 1]++; + isis_event_adjacency_state_change(adj, + new_state); + /* update counter & timers for debugging + * purposes */ + adj->last_flap = time(NULL); + adj->flaps++; + } else if (new_state == ISIS_ADJ_DOWN) { + listnode_delete(circuit->u.bc.adjdb[level - 1], + adj); + circuit->upadjcount[level - 1]--; + if (circuit->upadjcount[level - 1] == 0) { + /* Clean lsp_queue when no adj is up. */ + if (circuit->lsp_queue) + list_delete_all_node( + circuit->lsp_queue); + } + isis_event_adjacency_state_change(adj, + new_state); + del = true; + } + + if (circuit->u.bc.lan_neighs[level - 1]) { + list_delete_all_node( + circuit->u.bc.lan_neighs[level - 1]); + isis_adj_build_neigh_list( + circuit->u.bc.adjdb[level - 1], + circuit->u.bc.lan_neighs[level - 1]); + } + + /* On adjacency state change send new pseudo LSP if we + * are the DR */ + if (circuit->u.bc.is_dr[level - 1]) + lsp_regenerate_schedule_pseudo(circuit, level); + } + + if (del) + isis_delete_adj(adj); + + adj = NULL; + } else if (circuit->circ_type == CIRCUIT_T_P2P) { + del = false; + for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { + if ((adj->level & level) == 0) + continue; + if (new_state == ISIS_ADJ_UP) { + circuit->upadjcount[level - 1]++; + isis_event_adjacency_state_change(adj, + new_state); + + if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN) + send_hello(circuit, level); + + /* update counter & timers for debugging + * purposes */ + adj->last_flap = time(NULL); + adj->flaps++; + + /* 7.3.17 - going up on P2P -> send CSNP */ + /* FIXME: yup, I know its wrong... but i will do + * it! (for now) */ + send_csnp(circuit, level); + } else if (new_state == ISIS_ADJ_DOWN) { + if (adj->circuit->u.p2p.neighbor == adj) + adj->circuit->u.p2p.neighbor = NULL; + circuit->upadjcount[level - 1]--; + if (circuit->upadjcount[level - 1] == 0) { + /* Clean lsp_queue when no adj is up. */ + if (circuit->lsp_queue) + list_delete_all_node( + circuit->lsp_queue); + } + isis_event_adjacency_state_change(adj, + new_state); + del = true; + } + } + + if (del) + isis_delete_adj(adj); + + adj = NULL; + } + + return; } -void -isis_adj_print (struct isis_adjacency *adj) +void isis_adj_print(struct isis_adjacency *adj) { - struct isis_dynhn *dyn; - struct listnode *node; - struct in_addr *ipv4_addr; - struct in6_addr *ipv6_addr; - u_char ip6[INET6_ADDRSTRLEN]; - - if (!adj) - return; - dyn = dynhn_find_by_id (adj->sysid); - if (dyn) - zlog_debug ("%s", dyn->name.name); - - zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d", - sysid_print (adj->sysid), snpa_print (adj->snpa), - adj->level, adj->hold_time); - if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) - { - zlog_debug ("IPv4 Address(es):"); - - for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr)) - zlog_debug ("%s", inet_ntoa (*ipv4_addr)); - } - - if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) - { - zlog_debug ("IPv6 Address(es):"); - for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr)) - { - inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN); - zlog_debug ("%s", ip6); + struct isis_dynhn *dyn; + struct listnode *node; + struct in_addr *ipv4_addr; + struct in6_addr *ipv6_addr; + u_char ip6[INET6_ADDRSTRLEN]; + + if (!adj) + return; + dyn = dynhn_find_by_id(adj->sysid); + if (dyn) + zlog_debug("%s", dyn->name.name); + + zlog_debug("SystemId %20s SNPA %s, level %d\nHolding Time %d", + sysid_print(adj->sysid), snpa_print(adj->snpa), adj->level, + adj->hold_time); + if (adj->ipv4_addrs && listcount(adj->ipv4_addrs) > 0) { + zlog_debug("IPv4 Address(es):"); + + for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, ipv4_addr)) + zlog_debug("%s", inet_ntoa(*ipv4_addr)); + } + + if (adj->ipv6_addrs && listcount(adj->ipv6_addrs) > 0) { + zlog_debug("IPv6 Address(es):"); + for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, ipv6_addr)) { + inet_ntop(AF_INET6, ipv6_addr, (char *)ip6, + INET6_ADDRSTRLEN); + zlog_debug("%s", ip6); + } } - } - zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids)); + zlog_debug("Speaks: %s", nlpid2string(&adj->nlpids)); - return; + return; } -int -isis_adj_expire (struct thread *thread) +int isis_adj_expire(struct thread *thread) { - struct isis_adjacency *adj; + struct isis_adjacency *adj; - /* - * Get the adjacency - */ - adj = THREAD_ARG (thread); - assert (adj); - adj->t_expire = NULL; + /* + * Get the adjacency + */ + adj = THREAD_ARG(thread); + assert(adj); + adj->t_expire = NULL; - /* trigger the adj expire event */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired"); + /* trigger the adj expire event */ + isis_adj_state_change(adj, ISIS_ADJ_DOWN, "holding time expired"); - return 0; + return 0; } /* * show isis neighbor [detail] */ -void -isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail) +void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, + char detail) { - struct in6_addr *ipv6_addr; - u_char ip6[INET6_ADDRSTRLEN]; - struct in_addr *ip_addr; - time_t now; - struct isis_dynhn *dyn; - int level; - struct listnode *node; - - dyn = dynhn_find_by_id (adj->sysid); - if (dyn) - vty_out (vty, " %-20s", dyn->name.name); - else - vty_out (vty, " %-20s", sysid_print (adj->sysid)); - - if (detail == ISIS_UI_LEVEL_BRIEF) - { - if (adj->circuit) - vty_out (vty, "%-12s", adj->circuit->interface->name); - else - vty_out (vty, "NULL circuit!"); - vty_out (vty, "%-3u", adj->level); /* level */ - vty_out (vty, "%-13s", adj_state2string (adj->adj_state)); - now = time (NULL); - if (adj->last_upd) - vty_out (vty, "%-9llu", - (unsigned long long)adj->last_upd + adj->hold_time - now); - else - vty_out (vty, "- "); - vty_out (vty, "%-10s", snpa_print (adj->snpa)); - vty_out (vty, "\n"); - } - - if (detail == ISIS_UI_LEVEL_DETAIL) - { - level = adj->level; - vty_out (vty, "\n"); - if (adj->circuit) - vty_out (vty, " Interface: %s", adj->circuit->interface->name); - else - vty_out (vty, " Interface: NULL circuit"); - vty_out (vty, ", Level: %u", adj->level); /* level */ - vty_out (vty, ", State: %s", adj_state2string (adj->adj_state)); - now = time (NULL); - if (adj->last_upd) - vty_out (vty, ", Expires in %s", - time2string (adj->last_upd + adj->hold_time - now)); - else - vty_out (vty, ", Expires in %s", time2string (adj->hold_time)); - vty_out (vty, "\n"); - vty_out (vty, " Adjacency flaps: %u", adj->flaps); - vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap)); - vty_out (vty, "\n"); - vty_out (vty, " Circuit type: %s", circuit_t2string (adj->circuit_t)); - vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids)); - vty_out (vty, "\n"); - if (adj->mt_count != 1 || adj->mt_set[0] != ISIS_MT_IPV4_UNICAST) - { - vty_out (vty, " Topologies:\n"); - for (unsigned int i = 0; i < adj->mt_count; i++) - vty_out (vty, " %s\n", isis_mtid2str(adj->mt_set[i])); - } - vty_out (vty, " SNPA: %s", snpa_print (adj->snpa)); - if (adj->circuit && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) - { - dyn = dynhn_find_by_id (adj->lanid); - if (dyn) - vty_out (vty, ", LAN id: %s.%02x", - dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]); - else - vty_out (vty, ", LAN id: %s.%02x", - sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]); - - vty_out (vty, "\n"); - vty_out (vty, " LAN Priority: %u", adj->prio[adj->level - 1]); - - vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago", - isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1]. - dis), adj->dischanges[level - 1], - time2string (now - - (adj->dis_record[ISIS_LEVELS + level - 1]. - last_dis_change))); - } - vty_out (vty, "\n"); - - if (adj->area_addrs && listcount (adj->area_addrs) > 0) - { - struct area_addr *area_addr; - vty_out (vty, " Area Address(es):\n"); - for (ALL_LIST_ELEMENTS_RO (adj->area_addrs, node, area_addr)) - vty_out (vty, " %s\n", - isonet_print(area_addr->area_addr, area_addr->addr_len)); - } - if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) - { - vty_out (vty, " IPv4 Address(es):\n"); - for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr)) - vty_out (vty, " %s\n", inet_ntoa(*ip_addr)); + struct in6_addr *ipv6_addr; + u_char ip6[INET6_ADDRSTRLEN]; + struct in_addr *ip_addr; + time_t now; + struct isis_dynhn *dyn; + int level; + struct listnode *node; + + dyn = dynhn_find_by_id(adj->sysid); + if (dyn) + vty_out(vty, " %-20s", dyn->name.name); + else + vty_out(vty, " %-20s", sysid_print(adj->sysid)); + + if (detail == ISIS_UI_LEVEL_BRIEF) { + if (adj->circuit) + vty_out(vty, "%-12s", adj->circuit->interface->name); + else + vty_out(vty, "NULL circuit!"); + vty_out(vty, "%-3u", adj->level); /* level */ + vty_out(vty, "%-13s", adj_state2string(adj->adj_state)); + now = time(NULL); + if (adj->last_upd) + vty_out(vty, "%-9llu", + (unsigned long long)adj->last_upd + + adj->hold_time - now); + else + vty_out(vty, "- "); + vty_out(vty, "%-10s", snpa_print(adj->snpa)); + vty_out(vty, "\n"); } - if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) - { - vty_out (vty, " IPv6 Address(es):\n"); - for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr)) - { - inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN); - vty_out (vty, " %s\n", ip6); - } + + if (detail == ISIS_UI_LEVEL_DETAIL) { + level = adj->level; + vty_out(vty, "\n"); + if (adj->circuit) + vty_out(vty, " Interface: %s", + adj->circuit->interface->name); + else + vty_out(vty, " Interface: NULL circuit"); + vty_out(vty, ", Level: %u", adj->level); /* level */ + vty_out(vty, ", State: %s", adj_state2string(adj->adj_state)); + now = time(NULL); + if (adj->last_upd) + vty_out(vty, ", Expires in %s", + time2string(adj->last_upd + adj->hold_time + - now)); + else + vty_out(vty, ", Expires in %s", + time2string(adj->hold_time)); + vty_out(vty, "\n"); + vty_out(vty, " Adjacency flaps: %u", adj->flaps); + vty_out(vty, ", Last: %s ago", + time2string(now - adj->last_flap)); + vty_out(vty, "\n"); + vty_out(vty, " Circuit type: %s", + circuit_t2string(adj->circuit_t)); + vty_out(vty, ", Speaks: %s", nlpid2string(&adj->nlpids)); + vty_out(vty, "\n"); + if (adj->mt_count != 1 + || adj->mt_set[0] != ISIS_MT_IPV4_UNICAST) { + vty_out(vty, " Topologies:\n"); + for (unsigned int i = 0; i < adj->mt_count; i++) + vty_out(vty, " %s\n", + isis_mtid2str(adj->mt_set[i])); + } + vty_out(vty, " SNPA: %s", snpa_print(adj->snpa)); + if (adj->circuit + && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) { + dyn = dynhn_find_by_id(adj->lanid); + if (dyn) + vty_out(vty, ", LAN id: %s.%02x", + dyn->name.name, + adj->lanid[ISIS_SYS_ID_LEN]); + else + vty_out(vty, ", LAN id: %s.%02x", + sysid_print(adj->lanid), + adj->lanid[ISIS_SYS_ID_LEN]); + + vty_out(vty, "\n"); + vty_out(vty, " LAN Priority: %u", + adj->prio[adj->level - 1]); + + vty_out(vty, ", %s, DIS flaps: %u, Last: %s ago", + isis_disflag2string( + adj->dis_record[ISIS_LEVELS + level - 1] + .dis), + adj->dischanges[level - 1], + time2string(now - (adj->dis_record[ISIS_LEVELS + + level - 1] + .last_dis_change))); + } + vty_out(vty, "\n"); + + if (adj->area_addrs && listcount(adj->area_addrs) > 0) { + struct area_addr *area_addr; + vty_out(vty, " Area Address(es):\n"); + for (ALL_LIST_ELEMENTS_RO(adj->area_addrs, node, + area_addr)) + vty_out(vty, " %s\n", + isonet_print(area_addr->area_addr, + area_addr->addr_len)); + } + if (adj->ipv4_addrs && listcount(adj->ipv4_addrs) > 0) { + vty_out(vty, " IPv4 Address(es):\n"); + for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, + ip_addr)) + vty_out(vty, " %s\n", inet_ntoa(*ip_addr)); + } + if (adj->ipv6_addrs && listcount(adj->ipv6_addrs) > 0) { + vty_out(vty, " IPv6 Address(es):\n"); + for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, + ipv6_addr)) { + inet_ntop(AF_INET6, ipv6_addr, (char *)ip6, + INET6_ADDRSTRLEN); + vty_out(vty, " %s\n", ip6); + } + } + vty_out(vty, "\n"); } - vty_out (vty, "\n"); - } - return; + return; } -void -isis_adj_build_neigh_list (struct list *adjdb, struct list *list) +void isis_adj_build_neigh_list(struct list *adjdb, struct list *list) { - struct isis_adjacency *adj; - struct listnode *node; - - if (!list) - { - zlog_warn ("isis_adj_build_neigh_list(): NULL list"); - return; - } - - for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) - { - if (!adj) - { - zlog_warn ("isis_adj_build_neigh_list(): NULL adj"); - return; + struct isis_adjacency *adj; + struct listnode *node; + + if (!list) { + zlog_warn("isis_adj_build_neigh_list(): NULL list"); + return; } - if ((adj->adj_state == ISIS_ADJ_UP || - adj->adj_state == ISIS_ADJ_INITIALIZING)) - listnode_add (list, adj->snpa); - } - return; + for (ALL_LIST_ELEMENTS_RO(adjdb, node, adj)) { + if (!adj) { + zlog_warn("isis_adj_build_neigh_list(): NULL adj"); + return; + } + + if ((adj->adj_state == ISIS_ADJ_UP + || adj->adj_state == ISIS_ADJ_INITIALIZING)) + listnode_add(list, adj->snpa); + } + return; } -void -isis_adj_build_up_list (struct list *adjdb, struct list *list) +void isis_adj_build_up_list(struct list *adjdb, struct list *list) { - struct isis_adjacency *adj; - struct listnode *node; - - if (adjdb == NULL) { - zlog_warn ("isis_adj_build_up_list(): adjacency DB is empty"); - return; - } - - if (!list) - { - zlog_warn ("isis_adj_build_up_list(): NULL list"); - return; - } - - for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) - { - if (!adj) - { - zlog_warn ("isis_adj_build_up_list(): NULL adj"); - return; + struct isis_adjacency *adj; + struct listnode *node; + + if (adjdb == NULL) { + zlog_warn("isis_adj_build_up_list(): adjacency DB is empty"); + return; + } + + if (!list) { + zlog_warn("isis_adj_build_up_list(): NULL list"); + return; } - if (adj->adj_state == ISIS_ADJ_UP) - listnode_add (list, adj); - } + for (ALL_LIST_ELEMENTS_RO(adjdb, node, adj)) { + if (!adj) { + zlog_warn("isis_adj_build_up_list(): NULL adj"); + return; + } - return; + if (adj->adj_state == ISIS_ADJ_UP) + listnode_add(list, adj); + } + + return; } -int -isis_adj_usage2levels(enum isis_adj_usage usage) +int isis_adj_usage2levels(enum isis_adj_usage usage) { - switch (usage) - { - case ISIS_ADJ_LEVEL1: - return IS_LEVEL_1; - case ISIS_ADJ_LEVEL2: - return IS_LEVEL_2; - case ISIS_ADJ_LEVEL1AND2: - return IS_LEVEL_1 | IS_LEVEL_2; - default: - break; - } - return 0; + switch (usage) { + case ISIS_ADJ_LEVEL1: + return IS_LEVEL_1; + case ISIS_ADJ_LEVEL2: + return IS_LEVEL_2; + case ISIS_ADJ_LEVEL1AND2: + return IS_LEVEL_1 | IS_LEVEL_2; + default: + break; + } + return 0; } diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h index a81797bb1..9f4af1b45 100644 --- a/isisd/isis_adjacency.h +++ b/isisd/isis_adjacency.h @@ -1,20 +1,20 @@ /* - * IS-IS Rout(e)ing protocol - isis_adjacency.h + * IS-IS Rout(e)ing protocol - isis_adjacency.h * IS-IS adjacency handling * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -25,95 +25,90 @@ #ifndef _ZEBRA_ISIS_ADJACENCY_H #define _ZEBRA_ISIS_ADJACENCY_H -enum isis_adj_usage -{ - ISIS_ADJ_NONE, - ISIS_ADJ_LEVEL1, - ISIS_ADJ_LEVEL2, - ISIS_ADJ_LEVEL1AND2 +enum isis_adj_usage { + ISIS_ADJ_NONE, + ISIS_ADJ_LEVEL1, + ISIS_ADJ_LEVEL2, + ISIS_ADJ_LEVEL1AND2 }; -enum isis_system_type -{ - ISIS_SYSTYPE_UNKNOWN, - ISIS_SYSTYPE_ES, - ISIS_SYSTYPE_IS, - ISIS_SYSTYPE_L1_IS, - ISIS_SYSTYPE_L2_IS +enum isis_system_type { + ISIS_SYSTYPE_UNKNOWN, + ISIS_SYSTYPE_ES, + ISIS_SYSTYPE_IS, + ISIS_SYSTYPE_L1_IS, + ISIS_SYSTYPE_L2_IS }; -enum isis_adj_state -{ - ISIS_ADJ_UNKNOWN, - ISIS_ADJ_INITIALIZING, - ISIS_ADJ_UP, - ISIS_ADJ_DOWN +enum isis_adj_state { + ISIS_ADJ_UNKNOWN, + ISIS_ADJ_INITIALIZING, + ISIS_ADJ_UP, + ISIS_ADJ_DOWN }; /* * we use the following codes to give an indication _why_ * a specific adjacency is up or down */ -enum isis_adj_updown_reason -{ - ISIS_ADJ_REASON_SEENSELF, - ISIS_ADJ_REASON_AREA_MISMATCH, - ISIS_ADJ_REASON_HOLDTIMER_EXPIRED, - ISIS_ADJ_REASON_AUTH_FAILED, - ISIS_ADJ_REASON_CHECKSUM_FAILED +enum isis_adj_updown_reason { + ISIS_ADJ_REASON_SEENSELF, + ISIS_ADJ_REASON_AREA_MISMATCH, + ISIS_ADJ_REASON_HOLDTIMER_EXPIRED, + ISIS_ADJ_REASON_AUTH_FAILED, + ISIS_ADJ_REASON_CHECKSUM_FAILED }; #define DIS_RECORDS 8 /* keep the last 8 DIS state changes on record */ -struct isis_dis_record -{ - int dis; /* is our neighbor the DIS ? */ - time_t last_dis_change; /* timestamp for last dis change */ +struct isis_dis_record { + int dis; /* is our neighbor the DIS ? */ + time_t last_dis_change; /* timestamp for last dis change */ }; -struct isis_adjacency -{ - u_char snpa[ETH_ALEN]; /* NeighbourSNPAAddress */ - u_char sysid[ISIS_SYS_ID_LEN]; /* neighbourSystemIdentifier */ - u_char lanid[ISIS_SYS_ID_LEN + 1]; /* LAN id on bcast circuits */ - int dischanges[ISIS_LEVELS]; /* how many DIS changes ? */ - /* an array of N levels for M records */ - struct isis_dis_record dis_record[DIS_RECORDS * ISIS_LEVELS]; - enum isis_adj_state adj_state; /* adjacencyState */ - enum isis_adj_usage adj_usage; /* adjacencyUsage */ - struct list *area_addrs; /* areaAdressesOfNeighbour */ - struct nlpids nlpids; /* protocols spoken ... */ - struct list *ipv4_addrs; - struct in_addr router_address; - struct list *ipv6_addrs; - struct in6_addr router_address6; - u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */ - int circuit_t; /* from hello PDU hdr */ - int level; /* level (1 or 2) */ - enum isis_system_type sys_type; /* neighbourSystemType */ - u_int16_t hold_time; /* entryRemainingTime */ - u_int32_t last_upd; - u_int32_t last_flap; /* last time the adj flapped */ - int flaps; /* number of adjacency flaps */ - struct thread *t_expire; /* expire after hold_time */ - struct isis_circuit *circuit; /* back pointer */ - uint16_t *mt_set; /* Topologies this adjacency is valid for */ - unsigned int mt_count; /* Number of entries in mt_set */ +struct isis_adjacency { + u_char snpa[ETH_ALEN]; /* NeighbourSNPAAddress */ + u_char sysid[ISIS_SYS_ID_LEN]; /* neighbourSystemIdentifier */ + u_char lanid[ISIS_SYS_ID_LEN + 1]; /* LAN id on bcast circuits */ + int dischanges[ISIS_LEVELS]; /* how many DIS changes ? */ + /* an array of N levels for M records */ + struct isis_dis_record dis_record[DIS_RECORDS * ISIS_LEVELS]; + enum isis_adj_state adj_state; /* adjacencyState */ + enum isis_adj_usage adj_usage; /* adjacencyUsage */ + struct list *area_addrs; /* areaAdressesOfNeighbour */ + struct nlpids nlpids; /* protocols spoken ... */ + struct list *ipv4_addrs; + struct in_addr router_address; + struct list *ipv6_addrs; + struct in6_addr router_address6; + u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */ + int circuit_t; /* from hello PDU hdr */ + int level; /* level (1 or 2) */ + enum isis_system_type sys_type; /* neighbourSystemType */ + u_int16_t hold_time; /* entryRemainingTime */ + u_int32_t last_upd; + u_int32_t last_flap; /* last time the adj flapped */ + int flaps; /* number of adjacency flaps */ + struct thread *t_expire; /* expire after hold_time */ + struct isis_circuit *circuit; /* back pointer */ + uint16_t *mt_set; /* Topologies this adjacency is valid for */ + unsigned int mt_count; /* Number of entries in mt_set */ }; -struct isis_adjacency *isis_adj_lookup (const u_char * sysid, struct list *adjdb); -struct isis_adjacency *isis_adj_lookup_snpa (const u_char * ssnpa, - struct list *adjdb); -struct isis_adjacency *isis_new_adj (const u_char * id, const u_char * snpa, int level, - struct isis_circuit *circuit); -void isis_delete_adj (void *adj); -void isis_adj_state_change (struct isis_adjacency *adj, - enum isis_adj_state state, const char *reason); -void isis_adj_print (struct isis_adjacency *adj); -int isis_adj_expire (struct thread *thread); -void isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail); -void isis_adj_build_neigh_list (struct list *adjdb, struct list *list); -void isis_adj_build_up_list (struct list *adjdb, struct list *list); +struct isis_adjacency *isis_adj_lookup(const u_char *sysid, struct list *adjdb); +struct isis_adjacency *isis_adj_lookup_snpa(const u_char *ssnpa, + struct list *adjdb); +struct isis_adjacency *isis_new_adj(const u_char *id, const u_char *snpa, + int level, struct isis_circuit *circuit); +void isis_delete_adj(void *adj); +void isis_adj_state_change(struct isis_adjacency *adj, + enum isis_adj_state state, const char *reason); +void isis_adj_print(struct isis_adjacency *adj); +int isis_adj_expire(struct thread *thread); +void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, + char detail); +void isis_adj_build_neigh_list(struct list *adjdb, struct list *list); +void isis_adj_build_up_list(struct list *adjdb, struct list *list); int isis_adj_usage2levels(enum isis_adj_usage usage); #endif /* ISIS_ADJACENCY_H */ diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 4ebaa4a1e..69c2f941f 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_bpf.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -48,15 +48,16 @@ extern struct zebra_privs_t isisd_privs; struct bpf_insn llcfilter[] = { - BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN), /* check first byte */ - BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5), - BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1), - BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3), /* check second byte */ - BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2), - BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1), /* check third byte */ - BPF_STMT (BPF_RET + BPF_K, (u_int) - 1), - BPF_STMT (BPF_RET + BPF_K, 0) -}; + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, + ETHER_HDR_LEN), /* check first byte */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5), + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, + 3), /* check second byte */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1), /* check third byte */ + BPF_STMT(BPF_RET + BPF_K, (u_int)-1), + BPF_STMT(BPF_RET + BPF_K, 0)}; u_int readblen = 0; u_char *readbuff = NULL; @@ -65,272 +66,250 @@ u_char *readbuff = NULL; * ISO 10589 - 8.4.8 */ -u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 }; -u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 }; -u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 }; -u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 }; +u_char ALL_L1_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x14}; +u_char ALL_L2_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x15}; +u_char ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05}; +u_char ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04}; static char sock_buff[8192]; -static int -open_bpf_dev (struct isis_circuit *circuit) +static int open_bpf_dev(struct isis_circuit *circuit) { - int i = 0, fd; - char bpfdev[128]; - struct ifreq ifr; - u_int blen, immediate; + int i = 0, fd; + char bpfdev[128]; + struct ifreq ifr; + u_int blen, immediate; #ifdef BIOCSSEESENT - u_int seesent; + u_int seesent; #endif - struct timeval timeout; - struct bpf_program bpf_prog; - - do - { - (void) snprintf (bpfdev, sizeof (bpfdev), "/dev/bpf%d", i++); - fd = open (bpfdev, O_RDWR); - } - while (fd < 0 && errno == EBUSY); - - if (fd < 0) - { - zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s", - safe_strerror (errno)); - return ISIS_WARNING; - } - - zlog_debug ("Opened BPF device %s", bpfdev); - - memcpy (ifr.ifr_name, circuit->interface->name, sizeof (ifr.ifr_name)); - if (ioctl (fd, BIOCSETIF, (caddr_t) & ifr) < 0) - { - zlog_warn ("open_bpf_dev(): failed to bind to interface: %s", - safe_strerror (errno)); - return ISIS_WARNING; - } - - if (ioctl (fd, BIOCGBLEN, (caddr_t) & blen) < 0) - { - zlog_warn ("failed to get BPF buffer len"); - blen = circuit->interface->mtu; - } - - readblen = blen; - - if (readbuff == NULL) - readbuff = malloc (blen); - - zlog_debug ("BPF buffer len = %u", blen); - - /* BPF(4): reads return immediately upon packet reception. - * Otherwise, a read will block until either the kernel - * buffer becomes full or a timeout occurs. - */ - immediate = 1; - if (ioctl (fd, BIOCIMMEDIATE, (caddr_t) & immediate) < 0) - { - zlog_warn ("failed to set BPF dev to immediate mode"); - } + struct timeval timeout; + struct bpf_program bpf_prog; + + do { + (void)snprintf(bpfdev, sizeof(bpfdev), "/dev/bpf%d", i++); + fd = open(bpfdev, O_RDWR); + } while (fd < 0 && errno == EBUSY); + + if (fd < 0) { + zlog_warn("open_bpf_dev(): failed to create bpf socket: %s", + safe_strerror(errno)); + return ISIS_WARNING; + } + + zlog_debug("Opened BPF device %s", bpfdev); + + memcpy(ifr.ifr_name, circuit->interface->name, sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { + zlog_warn("open_bpf_dev(): failed to bind to interface: %s", + safe_strerror(errno)); + return ISIS_WARNING; + } + + if (ioctl(fd, BIOCGBLEN, (caddr_t)&blen) < 0) { + zlog_warn("failed to get BPF buffer len"); + blen = circuit->interface->mtu; + } + + readblen = blen; + + if (readbuff == NULL) + readbuff = malloc(blen); + + zlog_debug("BPF buffer len = %u", blen); + + /* BPF(4): reads return immediately upon packet reception. + * Otherwise, a read will block until either the kernel + * buffer becomes full or a timeout occurs. + */ + immediate = 1; + if (ioctl(fd, BIOCIMMEDIATE, (caddr_t)&immediate) < 0) { + zlog_warn("failed to set BPF dev to immediate mode"); + } #ifdef BIOCSSEESENT - /* - * We want to see only incoming packets - */ - seesent = 0; - if (ioctl (fd, BIOCSSEESENT, (caddr_t) & seesent) < 0) - { - zlog_warn ("failed to set BPF dev to incoming only mode"); - } + /* + * We want to see only incoming packets + */ + seesent = 0; + if (ioctl(fd, BIOCSSEESENT, (caddr_t)&seesent) < 0) { + zlog_warn("failed to set BPF dev to incoming only mode"); + } #endif - /* - * ...but all of them - */ - if (ioctl (fd, BIOCPROMISC) < 0) - { - zlog_warn ("failed to set BPF dev to promiscuous mode"); - } - - /* - * If the buffer length is smaller than our mtu, lets try to increase it - */ - if (blen < circuit->interface->mtu) - { - if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0) - { - zlog_warn ("failed to set BPF buffer len (%u to %u)", blen, - circuit->interface->mtu); + /* + * ...but all of them + */ + if (ioctl(fd, BIOCPROMISC) < 0) { + zlog_warn("failed to set BPF dev to promiscuous mode"); + } + + /* + * If the buffer length is smaller than our mtu, lets try to increase it + */ + if (blen < circuit->interface->mtu) { + if (ioctl(fd, BIOCSBLEN, &circuit->interface->mtu) < 0) { + zlog_warn("failed to set BPF buffer len (%u to %u)", + blen, circuit->interface->mtu); + } + } + + /* + * Set a timeout parameter - hope this helps select() + */ + timeout.tv_sec = 600; + timeout.tv_usec = 0; + if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { + zlog_warn("failed to set BPF device timeout"); + } + + /* + * And set the filter + */ + memset(&bpf_prog, 0, sizeof(struct bpf_program)); + bpf_prog.bf_len = 8; + bpf_prog.bf_insns = &(llcfilter[0]); + if (ioctl(fd, BIOCSETF, (caddr_t)&bpf_prog) < 0) { + zlog_warn("open_bpf_dev(): failed to install filter: %s", + safe_strerror(errno)); + return ISIS_WARNING; } - } - - /* - * Set a timeout parameter - hope this helps select() - */ - timeout.tv_sec = 600; - timeout.tv_usec = 0; - if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t) & timeout) < 0) - { - zlog_warn ("failed to set BPF device timeout"); - } - - /* - * And set the filter - */ - memset (&bpf_prog, 0, sizeof (struct bpf_program)); - bpf_prog.bf_len = 8; - bpf_prog.bf_insns = &(llcfilter[0]); - if (ioctl (fd, BIOCSETF, (caddr_t) & bpf_prog) < 0) - { - zlog_warn ("open_bpf_dev(): failed to install filter: %s", - safe_strerror (errno)); - return ISIS_WARNING; - } - - assert (fd > 0); - - circuit->fd = fd; - - return ISIS_OK; + + assert(fd > 0); + + circuit->fd = fd; + + return ISIS_OK; } /* * Create the socket and set the tx/rx funcs */ -int -isis_sock_init (struct isis_circuit *circuit) +int isis_sock_init(struct isis_circuit *circuit) { - int retval = ISIS_OK; - - if (isisd_privs.change (ZPRIVS_RAISE)) - zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno)); - - retval = open_bpf_dev (circuit); - - if (retval != ISIS_OK) - { - zlog_warn ("%s: could not initialize the socket", __func__); - goto end; - } - - if (if_is_broadcast(circuit->interface)) - { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } - else - { - zlog_warn ("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; - } + int retval = ISIS_OK; + + if (isisd_privs.change(ZPRIVS_RAISE)) + zlog_err("%s: could not raise privs, %s", __func__, + safe_strerror(errno)); + + retval = open_bpf_dev(circuit); + + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", __func__); + goto end; + } + + if (if_is_broadcast(circuit->interface)) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + goto end; + } end: - if (isisd_privs.change (ZPRIVS_LOWER)) - zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno)); + if (isisd_privs.change(ZPRIVS_LOWER)) + zlog_err("%s: could not lower privs, %s", __func__, + safe_strerror(errno)); - return retval; + return retval; } -int -isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa) +int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) { - int bytesread = 0, bytestoread, offset, one = 1; - struct bpf_hdr *bpf_hdr; + int bytesread = 0, bytestoread, offset, one = 1; + struct bpf_hdr *bpf_hdr; - assert (circuit->fd > 0); + assert(circuit->fd > 0); - if (ioctl (circuit->fd, FIONREAD, (caddr_t) & bytestoread) < 0) - { - zlog_warn ("ioctl() FIONREAD failed: %s", safe_strerror (errno)); - } + if (ioctl(circuit->fd, FIONREAD, (caddr_t)&bytestoread) < 0) { + zlog_warn("ioctl() FIONREAD failed: %s", safe_strerror(errno)); + } - if (bytestoread) - { - bytesread = read (circuit->fd, readbuff, readblen); - } - if (bytesread < 0) - { - zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s", - safe_strerror (errno)); - return ISIS_WARNING; - } + if (bytestoread) { + bytesread = read(circuit->fd, readbuff, readblen); + } + if (bytesread < 0) { + zlog_warn("isis_recv_pdu_bcast(): read() failed: %s", + safe_strerror(errno)); + return ISIS_WARNING; + } - if (bytesread == 0) - return ISIS_WARNING; + if (bytesread == 0) + return ISIS_WARNING; - bpf_hdr = (struct bpf_hdr *) readbuff; + bpf_hdr = (struct bpf_hdr *)readbuff; - assert (bpf_hdr->bh_caplen == bpf_hdr->bh_datalen); + assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen); - offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN; + offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN; - /* then we lose the BPF, LLC and ethernet headers */ - stream_write (circuit->rcv_stream, readbuff + offset, - bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); - stream_set_getp (circuit->rcv_stream, 0); + /* then we lose the BPF, LLC and ethernet headers */ + stream_write(circuit->rcv_stream, readbuff + offset, + bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); + stream_set_getp(circuit->rcv_stream, 0); - memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN, - ETHER_ADDR_LEN); + memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN, + ETHER_ADDR_LEN); - if (ioctl (circuit->fd, BIOCFLUSH, &one) < 0) - zlog_warn ("Flushing failed: %s", safe_strerror (errno)); + if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0) + zlog_warn("Flushing failed: %s", safe_strerror(errno)); - return ISIS_OK; + return ISIS_OK; } -int -isis_send_pdu_bcast (struct isis_circuit *circuit, int level) +int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) { - struct ether_header *eth; - ssize_t written; - size_t buflen; - - buflen = stream_get_endp (circuit->snd_stream) + LLC_LEN + ETHER_HDR_LEN; - if (buflen > sizeof (sock_buff)) - { - zlog_warn ("isis_send_pdu_bcast: sock_buff size %zu is less than " - "output pdu size %zu on circuit %s", - sizeof (sock_buff), buflen, circuit->interface->name); - return ISIS_WARNING; - } - - stream_set_getp (circuit->snd_stream, 0); - - /* - * First the eth header - */ - eth = (struct ether_header *) sock_buff; - if (level == 1) - memcpy (eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN); - else - memcpy (eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN); - memcpy (eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN); - size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN; - eth->ether_type = htons(isis_ethertype(frame_size)); - - /* - * Then the LLC - */ - sock_buff[ETHER_HDR_LEN] = ISO_SAP; - sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP; - sock_buff[ETHER_HDR_LEN + 2] = 0x03; - - /* then we copy the data */ - memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data, - stream_get_endp (circuit->snd_stream)); - - /* now we can send this */ - written = write (circuit->fd, sock_buff, buflen); - if (written < 0) - { - zlog_warn("IS-IS bpf: could not transmit packet on %s: %s", - circuit->interface->name, safe_strerror(errno)); - if (ERRNO_IO_RETRY(errno)) - return ISIS_WARNING; - return ISIS_ERROR; - } - - return ISIS_OK; + struct ether_header *eth; + ssize_t written; + size_t buflen; + + buflen = stream_get_endp(circuit->snd_stream) + LLC_LEN + ETHER_HDR_LEN; + if (buflen > sizeof(sock_buff)) { + zlog_warn( + "isis_send_pdu_bcast: sock_buff size %zu is less than " + "output pdu size %zu on circuit %s", + sizeof(sock_buff), buflen, circuit->interface->name); + return ISIS_WARNING; + } + + stream_set_getp(circuit->snd_stream, 0); + + /* + * First the eth header + */ + eth = (struct ether_header *)sock_buff; + if (level == 1) + memcpy(eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN); + else + memcpy(eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN); + memcpy(eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN); + size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN; + eth->ether_type = htons(isis_ethertype(frame_size)); + + /* + * Then the LLC + */ + sock_buff[ETHER_HDR_LEN] = ISO_SAP; + sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP; + sock_buff[ETHER_HDR_LEN + 2] = 0x03; + + /* then we copy the data */ + memcpy(sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data, + stream_get_endp(circuit->snd_stream)); + + /* now we can send this */ + written = write(circuit->fd, sock_buff, buflen); + if (written < 0) { + zlog_warn("IS-IS bpf: could not transmit packet on %s: %s", + circuit->interface->name, safe_strerror(errno)); + if (ERRNO_IO_RETRY(errno)) + return ISIS_WARNING; + return ISIS_ERROR; + } + + return ISIS_OK; } #endif /* ISIS_METHOD == ISIS_METHOD_BPF */ diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index d07ea27c4..72810532b 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_circuit.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -71,1366 +71,1282 @@ int isis_interface_config_write(struct vty *); int isis_if_new_hook(struct interface *); int isis_if_delete_hook(struct interface *); -struct isis_circuit * -isis_circuit_new () +struct isis_circuit *isis_circuit_new() { - struct isis_circuit *circuit; - int i; - - circuit = XCALLOC (MTYPE_ISIS_CIRCUIT, sizeof (struct isis_circuit)); - if (circuit == NULL) - { - zlog_err ("Can't malloc isis circuit"); - return NULL; - } - - /* - * Default values - */ - circuit->is_type = IS_LEVEL_1_AND_2; - circuit->flags = 0; - circuit->pad_hellos = 1; - for (i = 0; i < 2; i++) - { - circuit->hello_interval[i] = DEFAULT_HELLO_INTERVAL; - circuit->hello_multiplier[i] = DEFAULT_HELLO_MULTIPLIER; - circuit->csnp_interval[i] = DEFAULT_CSNP_INTERVAL; - circuit->psnp_interval[i] = DEFAULT_PSNP_INTERVAL; - circuit->priority[i] = DEFAULT_PRIORITY; - circuit->metric[i] = DEFAULT_CIRCUIT_METRIC; - circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC; - } - - circuit->mtc = mpls_te_circuit_new(); - - circuit_mt_init(circuit); - - QOBJ_REG (circuit, isis_circuit); - - return circuit; + struct isis_circuit *circuit; + int i; + + circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit)); + if (circuit == NULL) { + zlog_err("Can't malloc isis circuit"); + return NULL; + } + + /* + * Default values + */ + circuit->is_type = IS_LEVEL_1_AND_2; + circuit->flags = 0; + circuit->pad_hellos = 1; + for (i = 0; i < 2; i++) { + circuit->hello_interval[i] = DEFAULT_HELLO_INTERVAL; + circuit->hello_multiplier[i] = DEFAULT_HELLO_MULTIPLIER; + circuit->csnp_interval[i] = DEFAULT_CSNP_INTERVAL; + circuit->psnp_interval[i] = DEFAULT_PSNP_INTERVAL; + circuit->priority[i] = DEFAULT_PRIORITY; + circuit->metric[i] = DEFAULT_CIRCUIT_METRIC; + circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC; + } + + circuit->mtc = mpls_te_circuit_new(); + + circuit_mt_init(circuit); + + QOBJ_REG(circuit, isis_circuit); + + return circuit; } -void -isis_circuit_del (struct isis_circuit *circuit) +void isis_circuit_del(struct isis_circuit *circuit) { - if (!circuit) - return; + if (!circuit) + return; - QOBJ_UNREG (circuit); + QOBJ_UNREG(circuit); - isis_circuit_if_unbind (circuit, circuit->interface); + isis_circuit_if_unbind(circuit, circuit->interface); - circuit_mt_finish(circuit); + circuit_mt_finish(circuit); - /* and lastly the circuit itself */ - XFREE (MTYPE_ISIS_CIRCUIT, circuit); + /* and lastly the circuit itself */ + XFREE(MTYPE_ISIS_CIRCUIT, circuit); - return; + return; } -void -isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area) +void isis_circuit_configure(struct isis_circuit *circuit, + struct isis_area *area) { - assert (area); - circuit->area = area; - - /* - * Whenever the is-type of an area is changed, the is-type of each circuit - * in that area is updated to a non-empty subset of the area is-type. - * Inversely, when configuring a new circuit, this property should be - * ensured as well. - */ - if (area->is_type != IS_LEVEL_1_AND_2) - circuit->is_type = area->is_type; - - /* - * Add the circuit into area - */ - listnode_add (area->circuit_list, circuit); - - circuit->idx = flags_get_index (&area->flags); - - return; + assert(area); + circuit->area = area; + + /* + * Whenever the is-type of an area is changed, the is-type of each + * circuit + * in that area is updated to a non-empty subset of the area is-type. + * Inversely, when configuring a new circuit, this property should be + * ensured as well. + */ + if (area->is_type != IS_LEVEL_1_AND_2) + circuit->is_type = area->is_type; + + /* + * Add the circuit into area + */ + listnode_add(area->circuit_list, circuit); + + circuit->idx = flags_get_index(&area->flags); + + return; } -void -isis_circuit_deconfigure (struct isis_circuit *circuit, struct isis_area *area) +void isis_circuit_deconfigure(struct isis_circuit *circuit, + struct isis_area *area) { - /* Free the index of SRM and SSN flags */ - flags_free_index (&area->flags, circuit->idx); - circuit->idx = 0; - /* Remove circuit from area */ - assert (circuit->area == area); - listnode_delete (area->circuit_list, circuit); - circuit->area = NULL; - - return; + /* Free the index of SRM and SSN flags */ + flags_free_index(&area->flags, circuit->idx); + circuit->idx = 0; + /* Remove circuit from area */ + assert(circuit->area == area); + listnode_delete(area->circuit_list, circuit); + circuit->area = NULL; + + return; } -struct isis_circuit * -circuit_lookup_by_ifp (struct interface *ifp, struct list *list) +struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp, + struct list *list) { - struct isis_circuit *circuit = NULL; - struct listnode *node; + struct isis_circuit *circuit = NULL; + struct listnode *node; - if (!list) - return NULL; + if (!list) + return NULL; - for (ALL_LIST_ELEMENTS_RO (list, node, circuit)) - if (circuit->interface == ifp) - { - assert (ifp->info == circuit); - return circuit; - } + for (ALL_LIST_ELEMENTS_RO(list, node, circuit)) + if (circuit->interface == ifp) { + assert(ifp->info == circuit); + return circuit; + } - return NULL; + return NULL; } -struct isis_circuit * -circuit_scan_by_ifp (struct interface *ifp) +struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp) { - struct isis_area *area; - struct listnode *node; - struct isis_circuit *circuit; - - if (ifp->info) - return (struct isis_circuit *)ifp->info; - - if (isis->area_list) - { - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - circuit = circuit_lookup_by_ifp (ifp, area->circuit_list); - if (circuit) - return circuit; - } - } - return circuit_lookup_by_ifp (ifp, isis->init_circ_list); + struct isis_area *area; + struct listnode *node; + struct isis_circuit *circuit; + + if (ifp->info) + return (struct isis_circuit *)ifp->info; + + if (isis->area_list) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + circuit = + circuit_lookup_by_ifp(ifp, area->circuit_list); + if (circuit) + return circuit; + } + } + return circuit_lookup_by_ifp(ifp, isis->init_circ_list); } -void -isis_circuit_add_addr (struct isis_circuit *circuit, - struct connected *connected) +void isis_circuit_add_addr(struct isis_circuit *circuit, + struct connected *connected) { - struct listnode *node; - struct prefix_ipv4 *ipv4; + struct listnode *node; + struct prefix_ipv4 *ipv4; #if defined(EXTREME_DEBUG) - char buf[PREFIX2STR_BUFFER]; + char buf[PREFIX2STR_BUFFER]; #endif - struct prefix_ipv6 *ipv6; + struct prefix_ipv6 *ipv6; - if (connected->address->family == AF_INET) - { - u_int32_t addr = connected->address->u.prefix4.s_addr; - addr = ntohl (addr); - if (IPV4_NET0(addr) || - IPV4_NET127(addr) || - IN_CLASSD(addr) || - IPV4_LINKLOCAL(addr)) - return; + if (connected->address->family == AF_INET) { + u_int32_t addr = connected->address->u.prefix4.s_addr; + addr = ntohl(addr); + if (IPV4_NET0(addr) || IPV4_NET127(addr) || IN_CLASSD(addr) + || IPV4_LINKLOCAL(addr)) + return; - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4)) - if (prefix_same ((struct prefix *) ipv4, connected->address)) - return; + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ipv4)) + if (prefix_same((struct prefix *)ipv4, + connected->address)) + return; - ipv4 = prefix_ipv4_new (); - ipv4->prefixlen = connected->address->prefixlen; - ipv4->prefix = connected->address->u.prefix4; - listnode_add (circuit->ip_addrs, ipv4); + ipv4 = prefix_ipv4_new(); + ipv4->prefixlen = connected->address->prefixlen; + ipv4->prefix = connected->address->u.prefix4; + listnode_add(circuit->ip_addrs, ipv4); - /* Update MPLS TE Local IP address parameter */ - set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix); + /* Update MPLS TE Local IP address parameter */ + set_circuitparams_local_ipaddr(circuit->mtc, ipv4->prefix); - if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); + if (circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, + 0); #ifdef EXTREME_DEBUG - prefix2str (connected->address, buf, sizeof (buf)); - zlog_debug ("Added IP address %s to circuit %d", buf, - circuit->circuit_id); + prefix2str(connected->address, buf, sizeof(buf)); + zlog_debug("Added IP address %s to circuit %d", buf, + circuit->circuit_id); #endif /* EXTREME_DEBUG */ - } - if (connected->address->family == AF_INET6) - { - if (IN6_IS_ADDR_LOOPBACK(&connected->address->u.prefix6)) - return; - - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ipv6)) - if (prefix_same ((struct prefix *) ipv6, connected->address)) - return; - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ipv6)) - if (prefix_same ((struct prefix *) ipv6, connected->address)) - return; - - ipv6 = prefix_ipv6_new (); - ipv6->prefixlen = connected->address->prefixlen; - ipv6->prefix = connected->address->u.prefix6; - - if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix)) - listnode_add (circuit->ipv6_link, ipv6); - else - listnode_add (circuit->ipv6_non_link, ipv6); - if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); + } + if (connected->address->family == AF_INET6) { + if (IN6_IS_ADDR_LOOPBACK(&connected->address->u.prefix6)) + return; + + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ipv6)) + if (prefix_same((struct prefix *)ipv6, + connected->address)) + return; + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ipv6)) + if (prefix_same((struct prefix *)ipv6, + connected->address)) + return; + + ipv6 = prefix_ipv6_new(); + ipv6->prefixlen = connected->address->prefixlen; + ipv6->prefix = connected->address->u.prefix6; + + if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix)) + listnode_add(circuit->ipv6_link, ipv6); + else + listnode_add(circuit->ipv6_non_link, ipv6); + if (circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, + 0); #ifdef EXTREME_DEBUG - prefix2str (connected->address, buf, sizeof (buf)); - zlog_debug ("Added IPv6 address %s to circuit %d", buf, - circuit->circuit_id); + prefix2str(connected->address, buf, sizeof(buf)); + zlog_debug("Added IPv6 address %s to circuit %d", buf, + circuit->circuit_id); #endif /* EXTREME_DEBUG */ - } - return; + } + return; } -void -isis_circuit_del_addr (struct isis_circuit *circuit, - struct connected *connected) +void isis_circuit_del_addr(struct isis_circuit *circuit, + struct connected *connected) { - struct prefix_ipv4 *ipv4, *ip = NULL; - struct listnode *node; - char buf[PREFIX2STR_BUFFER]; - struct prefix_ipv6 *ipv6, *ip6 = NULL; - int found = 0; - - if (connected->address->family == AF_INET) - { - ipv4 = prefix_ipv4_new (); - ipv4->prefixlen = connected->address->prefixlen; - ipv4->prefix = connected->address->u.prefix4; - - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip)) - if (prefix_same ((struct prefix *) ip, (struct prefix *) ipv4)) - break; - - if (ip) - { - listnode_delete (circuit->ip_addrs, ip); - if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); + struct prefix_ipv4 *ipv4, *ip = NULL; + struct listnode *node; + char buf[PREFIX2STR_BUFFER]; + struct prefix_ipv6 *ipv6, *ip6 = NULL; + int found = 0; + + if (connected->address->family == AF_INET) { + ipv4 = prefix_ipv4_new(); + ipv4->prefixlen = connected->address->prefixlen; + ipv4->prefix = connected->address->u.prefix4; + + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ip)) + if (prefix_same((struct prefix *)ip, + (struct prefix *)ipv4)) + break; + + if (ip) { + listnode_delete(circuit->ip_addrs, ip); + if (circuit->area) + lsp_regenerate_schedule(circuit->area, + circuit->is_type, 0); + } else { + prefix2str(connected->address, buf, sizeof(buf)); + zlog_warn( + "Nonexistant ip address %s removal attempt from \ + circuit %d", + buf, circuit->circuit_id); + zlog_warn("Current ip addresses on %s:", + circuit->interface->name); + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, + ip)) { + prefix2str(ip, buf, sizeof(buf)); + zlog_warn(" %s", buf); + } + zlog_warn("End of addresses"); + } + + prefix_ipv4_free(ipv4); } - else - { - prefix2str (connected->address, buf, sizeof (buf)); - zlog_warn ("Nonexistant ip address %s removal attempt from \ - circuit %d", buf, circuit->circuit_id); - zlog_warn ("Current ip addresses on %s:", circuit->interface->name); - for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ip)) - { - prefix2str(ip, buf, sizeof(buf)); - zlog_warn(" %s", buf); - } - zlog_warn("End of addresses"); + if (connected->address->family == AF_INET6) { + ipv6 = prefix_ipv6_new(); + ipv6->prefixlen = connected->address->prefixlen; + ipv6->prefix = connected->address->u.prefix6; + + if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix)) { + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, + ip6)) { + if (prefix_same((struct prefix *)ip6, + (struct prefix *)ipv6)) + break; + } + if (ip6) { + listnode_delete(circuit->ipv6_link, ip6); + found = 1; + } + } else { + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, + ip6)) { + if (prefix_same((struct prefix *)ip6, + (struct prefix *)ipv6)) + break; + } + if (ip6) { + listnode_delete(circuit->ipv6_non_link, ip6); + found = 1; + } + } + + if (!found) { + prefix2str(connected->address, buf, sizeof(buf)); + zlog_warn( + "Nonexitant ip address %s removal attempt from \ + circuit %d", + buf, circuit->circuit_id); + zlog_warn("Current ip addresses on %s:", + circuit->interface->name); + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, + ip6)) { + prefix2str((struct prefix *)ip6, (char *)buf, + BUFSIZ); + zlog_warn(" %s", buf); + } + zlog_warn(" -----"); + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, + ip6)) { + prefix2str((struct prefix *)ip6, (char *)buf, + BUFSIZ); + zlog_warn(" %s", buf); + } + zlog_warn("End of addresses"); + } else if (circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, + 0); + + prefix_ipv6_free(ipv6); } + return; +} - prefix_ipv4_free (ipv4); - } - if (connected->address->family == AF_INET6) - { - ipv6 = prefix_ipv6_new (); - ipv6->prefixlen = connected->address->prefixlen; - ipv6->prefix = connected->address->u.prefix6; - - if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix)) - { - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ip6)) - { - if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6)) - break; - } - if (ip6) - { - listnode_delete (circuit->ipv6_link, ip6); - found = 1; - } - } - else - { - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ip6)) - { - if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6)) - break; - } - if (ip6) - { - listnode_delete (circuit->ipv6_non_link, ip6); - found = 1; - } +static u_char isis_circuit_id_gen(struct interface *ifp) +{ + u_char id = 0; + char ifname[16]; + unsigned int i; + int start = -1, end = -1; + + /* + * Get a stable circuit id from ifname. This makes + * the ifindex from flapping when netdevs are created + * and deleted on the fly. Note that this circuit id + * is used in pseudo lsps so it is better to be stable. + * The following code works on any reasonanle ifname + * like: eth1 or trk-1.1 etc. + */ + for (i = 0; i < strlen(ifp->name); i++) { + if (isdigit((unsigned char)ifp->name[i])) { + if (start < 0) { + start = i; + end = i + 1; + } else { + end = i + 1; + } + } else if (start >= 0) + break; } - if (!found) - { - prefix2str (connected->address, buf, sizeof (buf)); - zlog_warn ("Nonexitant ip address %s removal attempt from \ - circuit %d", buf, circuit->circuit_id); - zlog_warn ("Current ip addresses on %s:", circuit->interface->name); - for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ip6)) - { - prefix2str((struct prefix*)ip6, (char *)buf, BUFSIZ); - zlog_warn(" %s", buf); - } - zlog_warn(" -----"); - for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip6)) - { - prefix2str((struct prefix*)ip6, (char *)buf, BUFSIZ); - zlog_warn(" %s", buf); - } - zlog_warn("End of addresses"); + if ((start >= 0) && (end >= start) && (end - start) < 16) { + memset(ifname, 0, 16); + strncpy(ifname, &ifp->name[start], end - start); + id = (u_char)atoi(ifname); } - else if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); - prefix_ipv6_free (ipv6); - } - return; -} + /* Try to be unique. */ + if (!id) + id = (u_char)((ifp->ifindex & 0xff) | 0x80); -static u_char -isis_circuit_id_gen (struct interface *ifp) -{ - u_char id = 0; - char ifname[16]; - unsigned int i; - int start = -1, end = -1; - - /* - * Get a stable circuit id from ifname. This makes - * the ifindex from flapping when netdevs are created - * and deleted on the fly. Note that this circuit id - * is used in pseudo lsps so it is better to be stable. - * The following code works on any reasonanle ifname - * like: eth1 or trk-1.1 etc. - */ - for (i = 0; i < strlen (ifp->name); i++) - { - if (isdigit((unsigned char)ifp->name[i])) - { - if (start < 0) - { - start = i; - end = i + 1; - } - else - { - end = i + 1; - } - } - else if (start >= 0) - break; - } - - if ((start >= 0) && (end >= start) && (end - start) < 16) - { - memset (ifname, 0, 16); - strncpy (ifname, &ifp->name[start], end - start); - id = (u_char)atoi(ifname); - } - - /* Try to be unique. */ - if (!id) - id = (u_char)((ifp->ifindex & 0xff) | 0x80); - - return id; + return id; } -void -isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp) +void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp) { - struct listnode *node, *nnode; - struct connected *conn; - - circuit->circuit_id = isis_circuit_id_gen (ifp); - - isis_circuit_if_bind (circuit, ifp); - /* isis_circuit_update_addrs (circuit, ifp); */ - - if (if_is_broadcast (ifp)) - { - if (circuit->circ_type_config == CIRCUIT_T_P2P) - circuit->circ_type = CIRCUIT_T_P2P; - else - circuit->circ_type = CIRCUIT_T_BROADCAST; - } - else if (if_is_pointopoint (ifp)) - { - circuit->circ_type = CIRCUIT_T_P2P; - } - else if (if_is_loopback (ifp)) - { - circuit->circ_type = CIRCUIT_T_LOOPBACK; - circuit->is_passive = 1; - } - else - { - /* It's normal in case of loopback etc. */ - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("isis_circuit_if_add: unsupported media"); - circuit->circ_type = CIRCUIT_T_UNKNOWN; - } - - circuit->ip_addrs = list_new (); - circuit->ipv6_link = list_new (); - circuit->ipv6_non_link = list_new (); - - for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn)) - isis_circuit_add_addr (circuit, conn); - - return; + struct listnode *node, *nnode; + struct connected *conn; + + circuit->circuit_id = isis_circuit_id_gen(ifp); + + isis_circuit_if_bind(circuit, ifp); + /* isis_circuit_update_addrs (circuit, ifp); */ + + if (if_is_broadcast(ifp)) { + if (circuit->circ_type_config == CIRCUIT_T_P2P) + circuit->circ_type = CIRCUIT_T_P2P; + else + circuit->circ_type = CIRCUIT_T_BROADCAST; + } else if (if_is_pointopoint(ifp)) { + circuit->circ_type = CIRCUIT_T_P2P; + } else if (if_is_loopback(ifp)) { + circuit->circ_type = CIRCUIT_T_LOOPBACK; + circuit->is_passive = 1; + } else { + /* It's normal in case of loopback etc. */ + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("isis_circuit_if_add: unsupported media"); + circuit->circ_type = CIRCUIT_T_UNKNOWN; + } + + circuit->ip_addrs = list_new(); + circuit->ipv6_link = list_new(); + circuit->ipv6_non_link = list_new(); + + for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, conn)) + isis_circuit_add_addr(circuit, conn); + + return; } -void -isis_circuit_if_del (struct isis_circuit *circuit, struct interface *ifp) +void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp) { - struct listnode *node, *nnode; - struct connected *conn; - - assert (circuit->interface == ifp); - - /* destroy addresses */ - for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn)) - isis_circuit_del_addr (circuit, conn); - - if (circuit->ip_addrs) - { - assert (listcount(circuit->ip_addrs) == 0); - list_delete (circuit->ip_addrs); - circuit->ip_addrs = NULL; - } - - if (circuit->ipv6_link) - { - assert (listcount(circuit->ipv6_link) == 0); - list_delete (circuit->ipv6_link); - circuit->ipv6_link = NULL; - } - - if (circuit->ipv6_non_link) - { - assert (listcount(circuit->ipv6_non_link) == 0); - list_delete (circuit->ipv6_non_link); - circuit->ipv6_non_link = NULL; - } - - circuit->circ_type = CIRCUIT_T_UNKNOWN; - circuit->circuit_id = 0; - - return; + struct listnode *node, *nnode; + struct connected *conn; + + assert(circuit->interface == ifp); + + /* destroy addresses */ + for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, conn)) + isis_circuit_del_addr(circuit, conn); + + if (circuit->ip_addrs) { + assert(listcount(circuit->ip_addrs) == 0); + list_delete(circuit->ip_addrs); + circuit->ip_addrs = NULL; + } + + if (circuit->ipv6_link) { + assert(listcount(circuit->ipv6_link) == 0); + list_delete(circuit->ipv6_link); + circuit->ipv6_link = NULL; + } + + if (circuit->ipv6_non_link) { + assert(listcount(circuit->ipv6_non_link) == 0); + list_delete(circuit->ipv6_non_link); + circuit->ipv6_non_link = NULL; + } + + circuit->circ_type = CIRCUIT_T_UNKNOWN; + circuit->circuit_id = 0; + + return; } -void -isis_circuit_if_bind (struct isis_circuit *circuit, struct interface *ifp) +void isis_circuit_if_bind(struct isis_circuit *circuit, struct interface *ifp) { - assert (circuit != NULL); - assert (ifp != NULL); - if (circuit->interface) - assert (circuit->interface == ifp); - else - circuit->interface = ifp; - if (ifp->info) - assert (ifp->info == circuit); - else - ifp->info = circuit; - isis_link_params_update (circuit, ifp); + assert(circuit != NULL); + assert(ifp != NULL); + if (circuit->interface) + assert(circuit->interface == ifp); + else + circuit->interface = ifp; + if (ifp->info) + assert(ifp->info == circuit); + else + ifp->info = circuit; + isis_link_params_update(circuit, ifp); } -void -isis_circuit_if_unbind (struct isis_circuit *circuit, struct interface *ifp) +void isis_circuit_if_unbind(struct isis_circuit *circuit, struct interface *ifp) { - assert (circuit != NULL); - assert (ifp != NULL); - assert (circuit->interface == ifp); - assert (ifp->info == circuit); - circuit->interface = NULL; - ifp->info = NULL; + assert(circuit != NULL); + assert(ifp != NULL); + assert(circuit->interface == ifp); + assert(ifp->info == circuit); + circuit->interface = NULL; + ifp->info = NULL; } -static void -isis_circuit_update_all_srmflags (struct isis_circuit *circuit, int is_set) +static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit, + int is_set) { - struct isis_area *area; - struct isis_lsp *lsp; - dnode_t *dnode, *dnode_next; - int level; - - assert (circuit); - area = circuit->area; - assert (area); - for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) - { - if (level & circuit->is_type) - { - if (area->lspdb[level - 1] && - dict_count (area->lspdb[level - 1]) > 0) - { - for (dnode = dict_first (area->lspdb[level - 1]); - dnode != NULL; dnode = dnode_next) - { - dnode_next = dict_next (area->lspdb[level - 1], dnode); - lsp = dnode_get (dnode); - if (is_set) - { - ISIS_SET_FLAG (lsp->SRMflags, circuit); - } - else - { - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - } - } - } - } - } + struct isis_area *area; + struct isis_lsp *lsp; + dnode_t *dnode, *dnode_next; + int level; + + assert(circuit); + area = circuit->area; + assert(area); + for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) { + if (level & circuit->is_type) { + if (area->lspdb[level - 1] + && dict_count(area->lspdb[level - 1]) > 0) { + for (dnode = dict_first(area->lspdb[level - 1]); + dnode != NULL; dnode = dnode_next) { + dnode_next = dict_next( + area->lspdb[level - 1], dnode); + lsp = dnode_get(dnode); + if (is_set) { + ISIS_SET_FLAG(lsp->SRMflags, + circuit); + } else { + ISIS_CLEAR_FLAG(lsp->SRMflags, + circuit); + } + } + } + } + } } -size_t -isis_circuit_pdu_size(struct isis_circuit *circuit) +size_t isis_circuit_pdu_size(struct isis_circuit *circuit) { - return ISO_MTU(circuit); + return ISO_MTU(circuit); } -void -isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream) +void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream) { - size_t stream_size = isis_circuit_pdu_size(circuit); - - if (!*stream) - { - *stream = stream_new(stream_size); - } - else - { - if (STREAM_SIZE(*stream) != stream_size) - stream_resize(*stream, stream_size); - stream_reset(*stream); - } + size_t stream_size = isis_circuit_pdu_size(circuit); + + if (!*stream) { + *stream = stream_new(stream_size); + } else { + if (STREAM_SIZE(*stream) != stream_size) + stream_resize(*stream, stream_size); + stream_reset(*stream); + } } -void -isis_circuit_prepare (struct isis_circuit *circuit) +void isis_circuit_prepare(struct isis_circuit *circuit) { #ifdef GNU_LINUX - thread_add_read(master, isis_receive, circuit, circuit->fd, - &circuit->t_read); + thread_add_read(master, isis_receive, circuit, circuit->fd, + &circuit->t_read); #else - thread_add_timer_msec(master, isis_receive, circuit, - listcount(circuit->area->circuit_list) * 100, - &circuit->t_read); + thread_add_timer_msec(master, isis_receive, circuit, + listcount(circuit->area->circuit_list) * 100, + &circuit->t_read); #endif } -int -isis_circuit_up (struct isis_circuit *circuit) +int isis_circuit_up(struct isis_circuit *circuit) { - int retv; - - /* Set the flags for all the lsps of the circuit. */ - isis_circuit_update_all_srmflags (circuit, 1); - - if (circuit->state == C_STATE_UP) - return ISIS_OK; - - if (circuit->is_passive) - return ISIS_OK; - - if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) - { - zlog_err("Interface MTU %zu on %s is too low to support area lsp mtu %u!", - isis_circuit_pdu_size(circuit), circuit->interface->name, - circuit->area->lsp_mtu); - isis_circuit_update_all_srmflags(circuit, 0); - return ISIS_ERROR; - } - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - /* - * Get the Hardware Address - */ - if (circuit->interface->hw_addr_len != ETH_ALEN) - { - zlog_warn ("unsupported link layer"); - } - else - { - memcpy (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN); - } + int retv; + + /* Set the flags for all the lsps of the circuit. */ + isis_circuit_update_all_srmflags(circuit, 1); + + if (circuit->state == C_STATE_UP) + return ISIS_OK; + + if (circuit->is_passive) + return ISIS_OK; + + if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) { + zlog_err( + "Interface MTU %zu on %s is too low to support area lsp mtu %u!", + isis_circuit_pdu_size(circuit), + circuit->interface->name, circuit->area->lsp_mtu); + isis_circuit_update_all_srmflags(circuit, 0); + return ISIS_ERROR; + } + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + /* + * Get the Hardware Address + */ + if (circuit->interface->hw_addr_len != ETH_ALEN) { + zlog_warn("unsupported link layer"); + } else { + memcpy(circuit->u.bc.snpa, circuit->interface->hw_addr, + ETH_ALEN); + } #ifdef EXTREME_DEGUG - zlog_debug ("isis_circuit_if_add: if_id %d, isomtu %d snpa %s", - circuit->interface->ifindex, ISO_MTU (circuit), - snpa_print (circuit->u.bc.snpa)); + zlog_debug("isis_circuit_if_add: if_id %d, isomtu %d snpa %s", + circuit->interface->ifindex, ISO_MTU(circuit), + snpa_print(circuit->u.bc.snpa)); #endif /* EXTREME_DEBUG */ - circuit->u.bc.adjdb[0] = list_new (); - circuit->u.bc.adjdb[1] = list_new (); - - /* - * ISO 10589 - 8.4.1 Enabling of broadcast circuits - */ - - /* initilizing the hello sending threads - * for a broadcast IF - */ - - /* 8.4.1 a) commence sending of IIH PDUs */ - - if (circuit->is_type & IS_LEVEL_1) - { - thread_add_event(master, send_lan_l1_hello, circuit, 0, NULL); - circuit->u.bc.lan_neighs[0] = list_new (); - } - - if (circuit->is_type & IS_LEVEL_2) - { - thread_add_event(master, send_lan_l2_hello, circuit, 0, NULL); - circuit->u.bc.lan_neighs[1] = list_new (); - } - - /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */ - /* 8.4.1 c) FIXME: listen for ESH PDUs */ - - /* 8.4.1 d) */ - /* dr election will commence in... */ - if (circuit->is_type & IS_LEVEL_1) - thread_add_timer(master, isis_run_dr_l1, circuit, - 2 * circuit->hello_interval[0], - &circuit->u.bc.t_run_dr[0]); - if (circuit->is_type & IS_LEVEL_2) - thread_add_timer(master, isis_run_dr_l2, circuit, - 2 * circuit->hello_interval[1], - &circuit->u.bc.t_run_dr[1]); - } - else - { - /* initializing the hello send threads - * for a ptp IF - */ - circuit->u.p2p.neighbor = NULL; - thread_add_event(master, send_p2p_hello, circuit, 0, NULL); - } - - /* initializing PSNP timers */ - if (circuit->is_type & IS_LEVEL_1) - thread_add_timer(master, send_l1_psnp, circuit, - isis_jitter(circuit->psnp_interval[0], PSNP_JITTER), - &circuit->t_send_psnp[0]); - - if (circuit->is_type & IS_LEVEL_2) - thread_add_timer(master, send_l2_psnp, circuit, - isis_jitter(circuit->psnp_interval[1], PSNP_JITTER), - &circuit->t_send_psnp[1]); - - /* unified init for circuits; ignore warnings below this level */ - retv = isis_sock_init (circuit); - if (retv != ISIS_OK) - { - isis_circuit_down (circuit); - return retv; - } - - /* initialize the circuit streams after opening connection */ - isis_circuit_stream(circuit, &circuit->rcv_stream); - isis_circuit_stream(circuit, &circuit->snd_stream); - - isis_circuit_prepare (circuit); - - circuit->lsp_queue = list_new (); - circuit->lsp_queue_last_cleared = time (NULL); - - return ISIS_OK; + circuit->u.bc.adjdb[0] = list_new(); + circuit->u.bc.adjdb[1] = list_new(); + + /* + * ISO 10589 - 8.4.1 Enabling of broadcast circuits + */ + + /* initilizing the hello sending threads + * for a broadcast IF + */ + + /* 8.4.1 a) commence sending of IIH PDUs */ + + if (circuit->is_type & IS_LEVEL_1) { + thread_add_event(master, send_lan_l1_hello, circuit, 0, + NULL); + circuit->u.bc.lan_neighs[0] = list_new(); + } + + if (circuit->is_type & IS_LEVEL_2) { + thread_add_event(master, send_lan_l2_hello, circuit, 0, + NULL); + circuit->u.bc.lan_neighs[1] = list_new(); + } + + /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */ + /* 8.4.1 c) FIXME: listen for ESH PDUs */ + + /* 8.4.1 d) */ + /* dr election will commence in... */ + if (circuit->is_type & IS_LEVEL_1) + thread_add_timer(master, isis_run_dr_l1, circuit, + 2 * circuit->hello_interval[0], + &circuit->u.bc.t_run_dr[0]); + if (circuit->is_type & IS_LEVEL_2) + thread_add_timer(master, isis_run_dr_l2, circuit, + 2 * circuit->hello_interval[1], + &circuit->u.bc.t_run_dr[1]); + } else { + /* initializing the hello send threads + * for a ptp IF + */ + circuit->u.p2p.neighbor = NULL; + thread_add_event(master, send_p2p_hello, circuit, 0, NULL); + } + + /* initializing PSNP timers */ + if (circuit->is_type & IS_LEVEL_1) + thread_add_timer( + master, send_l1_psnp, circuit, + isis_jitter(circuit->psnp_interval[0], PSNP_JITTER), + &circuit->t_send_psnp[0]); + + if (circuit->is_type & IS_LEVEL_2) + thread_add_timer( + master, send_l2_psnp, circuit, + isis_jitter(circuit->psnp_interval[1], PSNP_JITTER), + &circuit->t_send_psnp[1]); + + /* unified init for circuits; ignore warnings below this level */ + retv = isis_sock_init(circuit); + if (retv != ISIS_OK) { + isis_circuit_down(circuit); + return retv; + } + + /* initialize the circuit streams after opening connection */ + isis_circuit_stream(circuit, &circuit->rcv_stream); + isis_circuit_stream(circuit, &circuit->snd_stream); + + isis_circuit_prepare(circuit); + + circuit->lsp_queue = list_new(); + circuit->lsp_queue_last_cleared = time(NULL); + + return ISIS_OK; } -void -isis_circuit_down (struct isis_circuit *circuit) +void isis_circuit_down(struct isis_circuit *circuit) { - if (circuit->state != C_STATE_UP) - return; - - /* Clear the flags for all the lsps of the circuit. */ - isis_circuit_update_all_srmflags (circuit, 0); - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - /* destroy neighbour lists */ - if (circuit->u.bc.lan_neighs[0]) - { - list_delete (circuit->u.bc.lan_neighs[0]); - circuit->u.bc.lan_neighs[0] = NULL; - } - if (circuit->u.bc.lan_neighs[1]) - { - list_delete (circuit->u.bc.lan_neighs[1]); - circuit->u.bc.lan_neighs[1] = NULL; - } - /* destroy adjacency databases */ - if (circuit->u.bc.adjdb[0]) - { - circuit->u.bc.adjdb[0]->del = isis_delete_adj; - list_delete (circuit->u.bc.adjdb[0]); - circuit->u.bc.adjdb[0] = NULL; - } - if (circuit->u.bc.adjdb[1]) - { - circuit->u.bc.adjdb[1]->del = isis_delete_adj; - list_delete (circuit->u.bc.adjdb[1]); - circuit->u.bc.adjdb[1] = NULL; - } - if (circuit->u.bc.is_dr[0]) - { - isis_dr_resign (circuit, 1); - circuit->u.bc.is_dr[0] = 0; - } - memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1); - if (circuit->u.bc.is_dr[1]) - { - isis_dr_resign (circuit, 2); - circuit->u.bc.is_dr[1] = 0; - } - memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); - memset (circuit->u.bc.snpa, 0, ETH_ALEN); - - THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]); - THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]); - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]); - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[0]); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[1]); - circuit->lsp_regenerate_pending[0] = 0; - circuit->lsp_regenerate_pending[1] = 0; - } - else if (circuit->circ_type == CIRCUIT_T_P2P) - { - isis_delete_adj (circuit->u.p2p.neighbor); - circuit->u.p2p.neighbor = NULL; - THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello); - } - - /* Cancel all active threads */ - THREAD_TIMER_OFF (circuit->t_send_csnp[0]); - THREAD_TIMER_OFF (circuit->t_send_csnp[1]); - THREAD_TIMER_OFF (circuit->t_send_psnp[0]); - THREAD_TIMER_OFF (circuit->t_send_psnp[1]); - THREAD_OFF (circuit->t_read); - - if (circuit->lsp_queue) - { - circuit->lsp_queue->del = NULL; - list_delete (circuit->lsp_queue); - circuit->lsp_queue = NULL; - } - - /* send one gratuitous hello to spead up convergence */ - if (circuit->is_type & IS_LEVEL_1) - send_hello (circuit, IS_LEVEL_1); - if (circuit->is_type & IS_LEVEL_2) - send_hello (circuit, IS_LEVEL_2); - - circuit->upadjcount[0] = 0; - circuit->upadjcount[1] = 0; - - /* close the socket */ - if (circuit->fd) - { - close (circuit->fd); - circuit->fd = 0; - } - - if (circuit->rcv_stream != NULL) - { - stream_free (circuit->rcv_stream); - circuit->rcv_stream = NULL; - } - - if (circuit->snd_stream != NULL) - { - stream_free (circuit->snd_stream); - circuit->snd_stream = NULL; - } - - thread_cancel_event (master, circuit); - - return; + if (circuit->state != C_STATE_UP) + return; + + /* Clear the flags for all the lsps of the circuit. */ + isis_circuit_update_all_srmflags(circuit, 0); + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + /* destroy neighbour lists */ + if (circuit->u.bc.lan_neighs[0]) { + list_delete(circuit->u.bc.lan_neighs[0]); + circuit->u.bc.lan_neighs[0] = NULL; + } + if (circuit->u.bc.lan_neighs[1]) { + list_delete(circuit->u.bc.lan_neighs[1]); + circuit->u.bc.lan_neighs[1] = NULL; + } + /* destroy adjacency databases */ + if (circuit->u.bc.adjdb[0]) { + circuit->u.bc.adjdb[0]->del = isis_delete_adj; + list_delete(circuit->u.bc.adjdb[0]); + circuit->u.bc.adjdb[0] = NULL; + } + if (circuit->u.bc.adjdb[1]) { + circuit->u.bc.adjdb[1]->del = isis_delete_adj; + list_delete(circuit->u.bc.adjdb[1]); + circuit->u.bc.adjdb[1] = NULL; + } + if (circuit->u.bc.is_dr[0]) { + isis_dr_resign(circuit, 1); + circuit->u.bc.is_dr[0] = 0; + } + memset(circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1); + if (circuit->u.bc.is_dr[1]) { + isis_dr_resign(circuit, 2); + circuit->u.bc.is_dr[1] = 0; + } + memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); + memset(circuit->u.bc.snpa, 0, ETH_ALEN); + + THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[0]); + THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[1]); + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[0]); + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[1]); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]); + circuit->lsp_regenerate_pending[0] = 0; + circuit->lsp_regenerate_pending[1] = 0; + } else if (circuit->circ_type == CIRCUIT_T_P2P) { + isis_delete_adj(circuit->u.p2p.neighbor); + circuit->u.p2p.neighbor = NULL; + THREAD_TIMER_OFF(circuit->u.p2p.t_send_p2p_hello); + } + + /* Cancel all active threads */ + THREAD_TIMER_OFF(circuit->t_send_csnp[0]); + THREAD_TIMER_OFF(circuit->t_send_csnp[1]); + THREAD_TIMER_OFF(circuit->t_send_psnp[0]); + THREAD_TIMER_OFF(circuit->t_send_psnp[1]); + THREAD_OFF(circuit->t_read); + + if (circuit->lsp_queue) { + circuit->lsp_queue->del = NULL; + list_delete(circuit->lsp_queue); + circuit->lsp_queue = NULL; + } + + /* send one gratuitous hello to spead up convergence */ + if (circuit->is_type & IS_LEVEL_1) + send_hello(circuit, IS_LEVEL_1); + if (circuit->is_type & IS_LEVEL_2) + send_hello(circuit, IS_LEVEL_2); + + circuit->upadjcount[0] = 0; + circuit->upadjcount[1] = 0; + + /* close the socket */ + if (circuit->fd) { + close(circuit->fd); + circuit->fd = 0; + } + + if (circuit->rcv_stream != NULL) { + stream_free(circuit->rcv_stream); + circuit->rcv_stream = NULL; + } + + if (circuit->snd_stream != NULL) { + stream_free(circuit->snd_stream); + circuit->snd_stream = NULL; + } + + thread_cancel_event(master, circuit); + + return; } -void -circuit_update_nlpids (struct isis_circuit *circuit) +void circuit_update_nlpids(struct isis_circuit *circuit) { - circuit->nlpids.count = 0; - - if (circuit->ip_router) - { - circuit->nlpids.nlpids[0] = NLPID_IP; - circuit->nlpids.count++; - } - if (circuit->ipv6_router) - { - circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6; - circuit->nlpids.count++; - } - return; + circuit->nlpids.count = 0; + + if (circuit->ip_router) { + circuit->nlpids.nlpids[0] = NLPID_IP; + circuit->nlpids.count++; + } + if (circuit->ipv6_router) { + circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6; + circuit->nlpids.count++; + } + return; } -void -isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty, - char detail) +void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, + char detail) { - if (detail == ISIS_UI_LEVEL_BRIEF) - { - vty_out (vty, " %-12s", circuit->interface->name); - vty_out (vty, "0x%-7x", circuit->circuit_id); - vty_out (vty, "%-9s", circuit_state2string (circuit->state)); - vty_out (vty, "%-9s", circuit_type2string (circuit->circ_type)); - vty_out (vty, "%-9s", circuit_t2string (circuit->is_type)); - vty_out (vty, "\n"); - } - - if (detail == ISIS_UI_LEVEL_DETAIL) - { - struct listnode *node; - struct prefix *ip_addr; - char buf[BUFSIZ]; - - vty_out (vty, " Interface: %s", circuit->interface->name); - vty_out (vty, ", State: %s", circuit_state2string (circuit->state)); - if (circuit->is_passive) - vty_out (vty, ", Passive"); - else - vty_out (vty, ", Active"); - vty_out (vty, ", Circuit Id: 0x%x", circuit->circuit_id); - vty_out (vty, "\n"); - vty_out (vty, " Type: %s", circuit_type2string (circuit->circ_type)); - vty_out (vty, ", Level: %s", circuit_t2string (circuit->is_type)); - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - vty_out (vty, ", SNPA: %-10s", snpa_print (circuit->u.bc.snpa)); - vty_out (vty, "\n"); - if (circuit->is_type & IS_LEVEL_1) - { - vty_out (vty, " Level-1 Information:\n"); - if (circuit->area->newmetric) - vty_out (vty, " Metric: %d", circuit->te_metric[0]); - else - vty_out (vty, " Metric: %d", - circuit->metric[0]); - if (!circuit->is_passive) - { - vty_out (vty, ", Active neighbors: %u\n", - circuit->upadjcount[0]); - vty_out (vty, " Hello interval: %u, " - "Holddown count: %u %s\n", - circuit->hello_interval[0], - circuit->hello_multiplier[0], - (circuit->pad_hellos ? "(pad)" : "(no-pad)")); - vty_out (vty, " CNSP interval: %u, " - "PSNP interval: %u\n", - circuit->csnp_interval[0], - circuit->psnp_interval[0]); - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - vty_out (vty, " LAN Priority: %u, %s\n", - circuit->priority[0], - (circuit->u.bc.is_dr[0] ? "is DIS" : "is not DIS")); - } - else - { - vty_out (vty, "\n"); - } - } - if (circuit->is_type & IS_LEVEL_2) - { - vty_out (vty, " Level-2 Information:\n"); - if (circuit->area->newmetric) - vty_out (vty, " Metric: %d", circuit->te_metric[1]); - else - vty_out (vty, " Metric: %d", - circuit->metric[1]); - if (!circuit->is_passive) - { - vty_out (vty, ", Active neighbors: %u\n", - circuit->upadjcount[1]); - vty_out (vty, " Hello interval: %u, " - "Holddown count: %u %s\n", - circuit->hello_interval[1], - circuit->hello_multiplier[1], - (circuit->pad_hellos ? "(pad)" : "(no-pad)")); - vty_out (vty, " CNSP interval: %u, " - "PSNP interval: %u\n", - circuit->csnp_interval[1], - circuit->psnp_interval[1]); - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - vty_out (vty, " LAN Priority: %u, %s\n", - circuit->priority[1], - (circuit->u.bc.is_dr[1] ? "is DIS" : "is not DIS")); - } - else - { - vty_out (vty, "\n"); - } - } - if (circuit->ip_addrs && listcount (circuit->ip_addrs) > 0) - { - vty_out (vty, " IP Prefix(es):\n"); - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip_addr)) - { - prefix2str (ip_addr, buf, sizeof (buf)), - vty_out (vty, " %s\n", buf); - } - } - if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) - { - vty_out (vty, " IPv6 Link-Locals:\n"); - for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ip_addr)) - { - prefix2str(ip_addr, (char*)buf, BUFSIZ), - vty_out (vty, " %s\n", buf); - } - } - if (circuit->ipv6_non_link && listcount(circuit->ipv6_non_link) > 0) - { - vty_out (vty, " IPv6 Prefixes:\n"); - for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip_addr)) - { - prefix2str(ip_addr, (char*)buf, BUFSIZ), - vty_out (vty, " %s\n", buf); - } - } - - vty_out (vty, "\n"); - } - return; + if (detail == ISIS_UI_LEVEL_BRIEF) { + vty_out(vty, " %-12s", circuit->interface->name); + vty_out(vty, "0x%-7x", circuit->circuit_id); + vty_out(vty, "%-9s", circuit_state2string(circuit->state)); + vty_out(vty, "%-9s", circuit_type2string(circuit->circ_type)); + vty_out(vty, "%-9s", circuit_t2string(circuit->is_type)); + vty_out(vty, "\n"); + } + + if (detail == ISIS_UI_LEVEL_DETAIL) { + struct listnode *node; + struct prefix *ip_addr; + char buf[BUFSIZ]; + + vty_out(vty, " Interface: %s", circuit->interface->name); + vty_out(vty, ", State: %s", + circuit_state2string(circuit->state)); + if (circuit->is_passive) + vty_out(vty, ", Passive"); + else + vty_out(vty, ", Active"); + vty_out(vty, ", Circuit Id: 0x%x", circuit->circuit_id); + vty_out(vty, "\n"); + vty_out(vty, " Type: %s", + circuit_type2string(circuit->circ_type)); + vty_out(vty, ", Level: %s", circuit_t2string(circuit->is_type)); + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + vty_out(vty, ", SNPA: %-10s", + snpa_print(circuit->u.bc.snpa)); + vty_out(vty, "\n"); + if (circuit->is_type & IS_LEVEL_1) { + vty_out(vty, " Level-1 Information:\n"); + if (circuit->area->newmetric) + vty_out(vty, " Metric: %d", + circuit->te_metric[0]); + else + vty_out(vty, " Metric: %d", + circuit->metric[0]); + if (!circuit->is_passive) { + vty_out(vty, ", Active neighbors: %u\n", + circuit->upadjcount[0]); + vty_out(vty, + " Hello interval: %u, " + "Holddown count: %u %s\n", + circuit->hello_interval[0], + circuit->hello_multiplier[0], + (circuit->pad_hellos ? "(pad)" + : "(no-pad)")); + vty_out(vty, + " CNSP interval: %u, " + "PSNP interval: %u\n", + circuit->csnp_interval[0], + circuit->psnp_interval[0]); + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + vty_out(vty, + " LAN Priority: %u, %s\n", + circuit->priority[0], + (circuit->u.bc.is_dr[0] + ? "is DIS" + : "is not DIS")); + } else { + vty_out(vty, "\n"); + } + } + if (circuit->is_type & IS_LEVEL_2) { + vty_out(vty, " Level-2 Information:\n"); + if (circuit->area->newmetric) + vty_out(vty, " Metric: %d", + circuit->te_metric[1]); + else + vty_out(vty, " Metric: %d", + circuit->metric[1]); + if (!circuit->is_passive) { + vty_out(vty, ", Active neighbors: %u\n", + circuit->upadjcount[1]); + vty_out(vty, + " Hello interval: %u, " + "Holddown count: %u %s\n", + circuit->hello_interval[1], + circuit->hello_multiplier[1], + (circuit->pad_hellos ? "(pad)" + : "(no-pad)")); + vty_out(vty, + " CNSP interval: %u, " + "PSNP interval: %u\n", + circuit->csnp_interval[1], + circuit->psnp_interval[1]); + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + vty_out(vty, + " LAN Priority: %u, %s\n", + circuit->priority[1], + (circuit->u.bc.is_dr[1] + ? "is DIS" + : "is not DIS")); + } else { + vty_out(vty, "\n"); + } + } + if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) { + vty_out(vty, " IP Prefix(es):\n"); + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, + ip_addr)) { + prefix2str(ip_addr, buf, sizeof(buf)), + vty_out(vty, " %s\n", buf); + } + } + if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) { + vty_out(vty, " IPv6 Link-Locals:\n"); + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, + ip_addr)) { + prefix2str(ip_addr, (char *)buf, BUFSIZ), + vty_out(vty, " %s\n", buf); + } + } + if (circuit->ipv6_non_link + && listcount(circuit->ipv6_non_link) > 0) { + vty_out(vty, " IPv6 Prefixes:\n"); + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, + ip_addr)) { + prefix2str(ip_addr, (char *)buf, BUFSIZ), + vty_out(vty, " %s\n", buf); + } + } + + vty_out(vty, "\n"); + } + return; } -int -isis_interface_config_write (struct vty *vty) +int isis_interface_config_write(struct vty *vty) { - int write = 0; - struct listnode *node, *node2; - struct interface *ifp; - struct isis_area *area; - struct isis_circuit *circuit; - int i; - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - { - if (ifp->ifindex == IFINDEX_DELETED) - continue; - - /* IF name */ - vty_out (vty, "interface %s\n", ifp->name); - write++; - /* IF desc */ - if (ifp->desc) - { - vty_out (vty, " description %s\n", ifp->desc); - write++; - } - /* ISIS Circuit */ - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node2, area)) - { - circuit = circuit_lookup_by_ifp (ifp, area->circuit_list); - if (circuit == NULL) - continue; - if (circuit->ip_router) - { - vty_out (vty, " ip router isis %s\n",area->area_tag); - write++; - } - if (circuit->is_passive) - { - vty_out (vty, " isis passive\n"); - write++; - } - if (circuit->circ_type_config == CIRCUIT_T_P2P) - { - vty_out (vty, " isis network point-to-point\n"); - write++; - } - if (circuit->ipv6_router) - { - vty_out (vty, " ipv6 router isis %s\n",area->area_tag); - write++; - } - - /* ISIS - circuit type */ - if (circuit->is_type == IS_LEVEL_1) - { - vty_out (vty, " isis circuit-type level-1\n"); - write++; - } - else - { - if (circuit->is_type == IS_LEVEL_2) - { - vty_out (vty," isis circuit-type level-2-only\n"); - write++; - } - } - - /* ISIS - CSNP interval */ - if (circuit->csnp_interval[0] == circuit->csnp_interval[1]) - { - if (circuit->csnp_interval[0] != DEFAULT_CSNP_INTERVAL) - { - vty_out (vty, " isis csnp-interval %d\n", - circuit->csnp_interval[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->csnp_interval[i] != DEFAULT_CSNP_INTERVAL) - { - vty_out (vty, " isis csnp-interval %d level-%d\n", - circuit->csnp_interval[i], i + 1); - write++; - } - } - } - - /* ISIS - PSNP interval */ - if (circuit->psnp_interval[0] == circuit->psnp_interval[1]) - { - if (circuit->psnp_interval[0] != DEFAULT_PSNP_INTERVAL) - { - vty_out (vty, " isis psnp-interval %d\n", - circuit->psnp_interval[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->psnp_interval[i] != DEFAULT_PSNP_INTERVAL) - { - vty_out (vty, " isis psnp-interval %d level-%d\n", - circuit->psnp_interval[i], i + 1); - write++; - } - } - } - - /* ISIS - Hello padding - Defaults to true so only display if false */ - if (circuit->pad_hellos == 0) - { - vty_out (vty, " no isis hello padding\n"); - write++; - } - - /* ISIS - Hello interval */ - if (circuit->hello_interval[0] == circuit->hello_interval[1]) - { - if (circuit->hello_interval[0] != DEFAULT_HELLO_INTERVAL) - { - vty_out (vty, " isis hello-interval %d\n", - circuit->hello_interval[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->hello_interval[i] != DEFAULT_HELLO_INTERVAL) - { - vty_out (vty, " isis hello-interval %d level-%d\n", - circuit->hello_interval[i], i + 1); - write++; - } - } - } - - /* ISIS - Hello Multiplier */ - if (circuit->hello_multiplier[0] == circuit->hello_multiplier[1]) - { - if (circuit->hello_multiplier[0] != DEFAULT_HELLO_MULTIPLIER) - { - vty_out (vty, " isis hello-multiplier %d\n", - circuit->hello_multiplier[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->hello_multiplier[i] != DEFAULT_HELLO_MULTIPLIER) - { - vty_out (vty, " isis hello-multiplier %d level-%d\n", - circuit->hello_multiplier[i],i + 1); - write++; - } - } - } - - /* ISIS - Priority */ - if (circuit->priority[0] == circuit->priority[1]) - { - if (circuit->priority[0] != DEFAULT_PRIORITY) - { - vty_out (vty, " isis priority %d\n", - circuit->priority[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->priority[i] != DEFAULT_PRIORITY) - { - vty_out (vty, " isis priority %d level-%d\n", - circuit->priority[i], i + 1); - write++; - } - } - } - - /* ISIS - Metric */ - if (circuit->te_metric[0] == circuit->te_metric[1]) - { - if (circuit->te_metric[0] != DEFAULT_CIRCUIT_METRIC) - { - vty_out (vty, " isis metric %d\n",circuit->te_metric[0]); - write++; - } - } - else - { - for (i = 0; i < 2; i++) - { - if (circuit->te_metric[i] != DEFAULT_CIRCUIT_METRIC) - { - vty_out (vty, " isis metric %d level-%d\n", - circuit->te_metric[i], i + 1); - write++; - } - } - } - if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - vty_out (vty, " isis password md5 %s\n", - circuit->passwd.passwd); - write++; - } - else if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) - { - vty_out (vty, " isis password clear %s\n", - circuit->passwd.passwd); - write++; - } - write += circuit_write_mt_settings(circuit, vty); - } - vty_out (vty, "!\n"); - } - - return write; + int write = 0; + struct listnode *node, *node2; + struct interface *ifp; + struct isis_area *area; + struct isis_circuit *circuit; + int i; + + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + if (ifp->ifindex == IFINDEX_DELETED) + continue; + + /* IF name */ + vty_out(vty, "interface %s\n", ifp->name); + write++; + /* IF desc */ + if (ifp->desc) { + vty_out(vty, " description %s\n", ifp->desc); + write++; + } + /* ISIS Circuit */ + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node2, area)) { + circuit = + circuit_lookup_by_ifp(ifp, area->circuit_list); + if (circuit == NULL) + continue; + if (circuit->ip_router) { + vty_out(vty, " ip router isis %s\n", + area->area_tag); + write++; + } + if (circuit->is_passive) { + vty_out(vty, " isis passive\n"); + write++; + } + if (circuit->circ_type_config == CIRCUIT_T_P2P) { + vty_out(vty, " isis network point-to-point\n"); + write++; + } + if (circuit->ipv6_router) { + vty_out(vty, " ipv6 router isis %s\n", + area->area_tag); + write++; + } + + /* ISIS - circuit type */ + if (circuit->is_type == IS_LEVEL_1) { + vty_out(vty, " isis circuit-type level-1\n"); + write++; + } else { + if (circuit->is_type == IS_LEVEL_2) { + vty_out(vty, + " isis circuit-type level-2-only\n"); + write++; + } + } + + /* ISIS - CSNP interval */ + if (circuit->csnp_interval[0] + == circuit->csnp_interval[1]) { + if (circuit->csnp_interval[0] + != DEFAULT_CSNP_INTERVAL) { + vty_out(vty, " isis csnp-interval %d\n", + circuit->csnp_interval[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->csnp_interval[i] + != DEFAULT_CSNP_INTERVAL) { + vty_out(vty, + " isis csnp-interval %d level-%d\n", + circuit->csnp_interval + [i], + i + 1); + write++; + } + } + } + + /* ISIS - PSNP interval */ + if (circuit->psnp_interval[0] + == circuit->psnp_interval[1]) { + if (circuit->psnp_interval[0] + != DEFAULT_PSNP_INTERVAL) { + vty_out(vty, " isis psnp-interval %d\n", + circuit->psnp_interval[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->psnp_interval[i] + != DEFAULT_PSNP_INTERVAL) { + vty_out(vty, + " isis psnp-interval %d level-%d\n", + circuit->psnp_interval + [i], + i + 1); + write++; + } + } + } + + /* ISIS - Hello padding - Defaults to true so only + * display if false */ + if (circuit->pad_hellos == 0) { + vty_out(vty, " no isis hello padding\n"); + write++; + } + + /* ISIS - Hello interval */ + if (circuit->hello_interval[0] + == circuit->hello_interval[1]) { + if (circuit->hello_interval[0] + != DEFAULT_HELLO_INTERVAL) { + vty_out(vty, + " isis hello-interval %d\n", + circuit->hello_interval[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->hello_interval[i] + != DEFAULT_HELLO_INTERVAL) { + vty_out(vty, + " isis hello-interval %d level-%d\n", + circuit->hello_interval + [i], + i + 1); + write++; + } + } + } + + /* ISIS - Hello Multiplier */ + if (circuit->hello_multiplier[0] + == circuit->hello_multiplier[1]) { + if (circuit->hello_multiplier[0] + != DEFAULT_HELLO_MULTIPLIER) { + vty_out(vty, + " isis hello-multiplier %d\n", + circuit->hello_multiplier[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->hello_multiplier[i] + != DEFAULT_HELLO_MULTIPLIER) { + vty_out(vty, + " isis hello-multiplier %d level-%d\n", + circuit->hello_multiplier + [i], + i + 1); + write++; + } + } + } + + /* ISIS - Priority */ + if (circuit->priority[0] == circuit->priority[1]) { + if (circuit->priority[0] != DEFAULT_PRIORITY) { + vty_out(vty, " isis priority %d\n", + circuit->priority[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->priority[i] + != DEFAULT_PRIORITY) { + vty_out(vty, + " isis priority %d level-%d\n", + circuit->priority[i], + i + 1); + write++; + } + } + } + + /* ISIS - Metric */ + if (circuit->te_metric[0] == circuit->te_metric[1]) { + if (circuit->te_metric[0] + != DEFAULT_CIRCUIT_METRIC) { + vty_out(vty, " isis metric %d\n", + circuit->te_metric[0]); + write++; + } + } else { + for (i = 0; i < 2; i++) { + if (circuit->te_metric[i] + != DEFAULT_CIRCUIT_METRIC) { + vty_out(vty, + " isis metric %d level-%d\n", + circuit->te_metric[i], + i + 1); + write++; + } + } + } + if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) { + vty_out(vty, " isis password md5 %s\n", + circuit->passwd.passwd); + write++; + } else if (circuit->passwd.type + == ISIS_PASSWD_TYPE_CLEARTXT) { + vty_out(vty, " isis password clear %s\n", + circuit->passwd.passwd); + write++; + } + write += circuit_write_mt_settings(circuit, vty); + } + vty_out(vty, "!\n"); + } + + return write; } -struct isis_circuit * -isis_circuit_create (struct isis_area *area, struct interface *ifp) +struct isis_circuit *isis_circuit_create(struct isis_area *area, + struct interface *ifp) { - struct isis_circuit *circuit = circuit_scan_by_ifp (ifp); - if (circuit && circuit->area) - return NULL; - circuit = isis_csm_state_change (ISIS_ENABLE, circuit, area); - if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP) - return circuit; - isis_circuit_if_bind (circuit, ifp); - return circuit; + struct isis_circuit *circuit = circuit_scan_by_ifp(ifp); + if (circuit && circuit->area) + return NULL; + circuit = isis_csm_state_change(ISIS_ENABLE, circuit, area); + if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP) + return circuit; + isis_circuit_if_bind(circuit, ifp); + return circuit; } -void -isis_circuit_af_set (struct isis_circuit *circuit, bool ip_router, bool ipv6_router) +void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, + bool ipv6_router) { - struct isis_area *area = circuit->area; - bool change = circuit->ip_router != ip_router || circuit->ipv6_router != ipv6_router; - bool was_enabled = !!circuit->area; - - area->ip_circuits += ip_router - circuit->ip_router; - area->ipv6_circuits += ipv6_router - circuit->ipv6_router; - circuit->ip_router = ip_router; - circuit->ipv6_router = ipv6_router; - - if (!change) - return; - - circuit_update_nlpids (circuit); - - if (!ip_router && !ipv6_router) - isis_csm_state_change (ISIS_DISABLE, circuit, area); - else if (!was_enabled) - isis_csm_state_change (ISIS_ENABLE, circuit, area); - else - lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); + struct isis_area *area = circuit->area; + bool change = circuit->ip_router != ip_router + || circuit->ipv6_router != ipv6_router; + bool was_enabled = !!circuit->area; + + area->ip_circuits += ip_router - circuit->ip_router; + area->ipv6_circuits += ipv6_router - circuit->ipv6_router; + circuit->ip_router = ip_router; + circuit->ipv6_router = ipv6_router; + + if (!change) + return; + + circuit_update_nlpids(circuit); + + if (!ip_router && !ipv6_router) + isis_csm_state_change(ISIS_DISABLE, circuit, area); + else if (!was_enabled) + isis_csm_state_change(ISIS_ENABLE, circuit, area); + else + lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); } -int -isis_circuit_passive_set (struct isis_circuit *circuit, bool passive) +int isis_circuit_passive_set(struct isis_circuit *circuit, bool passive) { - if (circuit->is_passive == passive) - return 0; - - if (if_is_loopback (circuit->interface) && !passive) - return -1; - - if (circuit->state != C_STATE_UP) - { - circuit->is_passive = passive; - } - else - { - struct isis_area *area = circuit->area; - isis_csm_state_change (ISIS_DISABLE, circuit, area); - circuit->is_passive = passive; - isis_csm_state_change (ISIS_ENABLE, circuit, area); - } - - return 0; + if (circuit->is_passive == passive) + return 0; + + if (if_is_loopback(circuit->interface) && !passive) + return -1; + + if (circuit->state != C_STATE_UP) { + circuit->is_passive = passive; + } else { + struct isis_area *area = circuit->area; + isis_csm_state_change(ISIS_DISABLE, circuit, area); + circuit->is_passive = passive; + isis_csm_state_change(ISIS_ENABLE, circuit, area); + } + + return 0; } -int -isis_circuit_metric_set (struct isis_circuit *circuit, int level, int metric) +int isis_circuit_metric_set(struct isis_circuit *circuit, int level, int metric) { - assert (level == IS_LEVEL_1 || level == IS_LEVEL_2); - if (metric > MAX_WIDE_LINK_METRIC) - return -1; - if (circuit->area && circuit->area->oldmetric - && metric > MAX_NARROW_LINK_METRIC) - return -1; - - circuit->te_metric[level - 1] = metric; - circuit->metric[level - 1] = metric; - - if (circuit->area) - lsp_regenerate_schedule (circuit->area, level, 0); - return 0; + assert(level == IS_LEVEL_1 || level == IS_LEVEL_2); + if (metric > MAX_WIDE_LINK_METRIC) + return -1; + if (circuit->area && circuit->area->oldmetric + && metric > MAX_NARROW_LINK_METRIC) + return -1; + + circuit->te_metric[level - 1] = metric; + circuit->metric[level - 1] = metric; + + if (circuit->area) + lsp_regenerate_schedule(circuit->area, level, 0); + return 0; } -int -isis_circuit_passwd_unset (struct isis_circuit *circuit) +int isis_circuit_passwd_unset(struct isis_circuit *circuit) { - memset(&circuit->passwd, 0, sizeof(circuit->passwd)); - return 0; + memset(&circuit->passwd, 0, sizeof(circuit->passwd)); + return 0; } -static int -isis_circuit_passwd_set (struct isis_circuit *circuit, u_char passwd_type, const char *passwd) +static int isis_circuit_passwd_set(struct isis_circuit *circuit, + u_char passwd_type, const char *passwd) { - int len; + int len; - if (!passwd) - return -1; + if (!passwd) + return -1; - len = strlen(passwd); - if (len > 254) - return -1; + len = strlen(passwd); + if (len > 254) + return -1; - circuit->passwd.len = len; - strncpy((char *)circuit->passwd.passwd, passwd, 255); - circuit->passwd.type = passwd_type; - return 0; + circuit->passwd.len = len; + strncpy((char *)circuit->passwd.passwd, passwd, 255); + circuit->passwd.type = passwd_type; + return 0; } -int -isis_circuit_passwd_cleartext_set (struct isis_circuit *circuit, const char *passwd) +int isis_circuit_passwd_cleartext_set(struct isis_circuit *circuit, + const char *passwd) { - return isis_circuit_passwd_set (circuit, ISIS_PASSWD_TYPE_CLEARTXT, passwd); + return isis_circuit_passwd_set(circuit, ISIS_PASSWD_TYPE_CLEARTXT, + passwd); } -int -isis_circuit_passwd_hmac_md5_set (struct isis_circuit *circuit, const char *passwd) +int isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, + const char *passwd) { - return isis_circuit_passwd_set (circuit, ISIS_PASSWD_TYPE_HMAC_MD5, passwd); + return isis_circuit_passwd_set(circuit, ISIS_PASSWD_TYPE_HMAC_MD5, + passwd); } struct cmd_node interface_node = { - INTERFACE_NODE, - "%s(config-if)# ", - 1, + INTERFACE_NODE, "%s(config-if)# ", 1, }; -int -isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type) +int isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type) { - /* Changing the network type to/of loopback or unknown interfaces - * is not supported. */ - if (circ_type == CIRCUIT_T_UNKNOWN - || circ_type == CIRCUIT_T_LOOPBACK - || circuit->circ_type == CIRCUIT_T_LOOPBACK) - { - if (circuit->circ_type != circ_type) - return -1; - else - return 0; - } - - if (circuit->circ_type == circ_type) - return 0; - - if (circuit->state != C_STATE_UP) - { - circuit->circ_type = circ_type; - circuit->circ_type_config = circ_type; - } - else - { - struct isis_area *area = circuit->area; - if (circ_type == CIRCUIT_T_BROADCAST - && !if_is_broadcast(circuit->interface)) - return -1; - - isis_csm_state_change(ISIS_DISABLE, circuit, area); - circuit->circ_type = circ_type; - circuit->circ_type_config = circ_type; - isis_csm_state_change(ISIS_ENABLE, circuit, area); - } - return 0; + /* Changing the network type to/of loopback or unknown interfaces + * is not supported. */ + if (circ_type == CIRCUIT_T_UNKNOWN || circ_type == CIRCUIT_T_LOOPBACK + || circuit->circ_type == CIRCUIT_T_LOOPBACK) { + if (circuit->circ_type != circ_type) + return -1; + else + return 0; + } + + if (circuit->circ_type == circ_type) + return 0; + + if (circuit->state != C_STATE_UP) { + circuit->circ_type = circ_type; + circuit->circ_type_config = circ_type; + } else { + struct isis_area *area = circuit->area; + if (circ_type == CIRCUIT_T_BROADCAST + && !if_is_broadcast(circuit->interface)) + return -1; + + isis_csm_state_change(ISIS_DISABLE, circuit, area); + circuit->circ_type = circ_type; + circuit->circ_type_config = circ_type; + isis_csm_state_change(ISIS_ENABLE, circuit, area); + } + return 0; } -int -isis_circuit_mt_enabled_set (struct isis_circuit *circuit, uint16_t mtid, - bool enabled) +int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, + bool enabled) { - struct isis_circuit_mt_setting *setting; + struct isis_circuit_mt_setting *setting; - setting = circuit_get_mt_setting(circuit, mtid); - if (setting->enabled != enabled) - { - setting->enabled = enabled; - lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); - } + setting = circuit_get_mt_setting(circuit, mtid); + if (setting->enabled != enabled) { + setting->enabled = enabled; + lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2, + 0); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } -int -isis_if_new_hook (struct interface *ifp) +int isis_if_new_hook(struct interface *ifp) { - return 0; + return 0; } -int -isis_if_delete_hook (struct interface *ifp) +int isis_if_delete_hook(struct interface *ifp) { - struct isis_circuit *circuit; - /* Clean up the circuit data */ - if (ifp && ifp->info) - { - circuit = ifp->info; - isis_csm_state_change (IF_DOWN_FROM_Z, circuit, circuit->area); - isis_csm_state_change (ISIS_DISABLE, circuit, circuit->area); - } - - return 0; + struct isis_circuit *circuit; + /* Clean up the circuit data */ + if (ifp && ifp->info) { + circuit = ifp->info; + isis_csm_state_change(IF_DOWN_FROM_Z, circuit, circuit->area); + isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area); + } + + return 0; } -void -isis_circuit_init () +void isis_circuit_init() { - /* Initialize Zebra interface data structure */ - if_add_hook (IF_NEW_HOOK, isis_if_new_hook); - if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook); + /* Initialize Zebra interface data structure */ + if_add_hook(IF_NEW_HOOK, isis_if_new_hook); + if_add_hook(IF_DELETE_HOOK, isis_if_delete_hook); - /* Install interface node */ - install_node (&interface_node, isis_interface_config_write); - if_cmd_init (); + /* Install interface node */ + install_node(&interface_node, isis_interface_config_write); + if_cmd_init(); - isis_vty_init (); + isis_vty_init(); } diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 82ca7ca0d..5e523cd68 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_circuit.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -32,162 +32,165 @@ #define CIRCUIT_MAX 255 -struct password -{ - struct password *next; - int len; - u_char *pass; +struct password { + struct password *next; + int len; + u_char *pass; }; -struct metric -{ - u_char metric_default; - u_char metric_error; - u_char metric_expense; - u_char metric_delay; +struct metric { + u_char metric_default; + u_char metric_error; + u_char metric_expense; + u_char metric_delay; }; -struct isis_bcast_info -{ - u_char snpa[ETH_ALEN]; /* SNPA of this circuit */ - char run_dr_elect[2]; /* Should we run dr election ? */ - struct thread *t_run_dr[2]; /* DR election thread */ - struct thread *t_send_lan_hello[2]; /* send LAN IIHs in this thread */ - struct list *adjdb[2]; /* adjacency dbs */ - struct list *lan_neighs[2]; /* list of lx neigh snpa */ - char is_dr[2]; /* Are we level x DR ? */ - u_char l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */ - u_char l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */ - struct thread *t_refresh_pseudo_lsp[2]; /* refresh pseudo-node LSPs */ +struct isis_bcast_info { + u_char snpa[ETH_ALEN]; /* SNPA of this circuit */ + char run_dr_elect[2]; /* Should we run dr election ? */ + struct thread *t_run_dr[2]; /* DR election thread */ + struct thread *t_send_lan_hello[2]; /* send LAN IIHs in this thread */ + struct list *adjdb[2]; /* adjacency dbs */ + struct list *lan_neighs[2]; /* list of lx neigh snpa */ + char is_dr[2]; /* Are we level x DR ? */ + u_char l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */ + u_char l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */ + struct thread *t_refresh_pseudo_lsp[2]; /* refresh pseudo-node LSPs */ }; -struct isis_p2p_info -{ - struct isis_adjacency *neighbor; - struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */ +struct isis_p2p_info { + struct isis_adjacency *neighbor; + struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */ }; -struct isis_circuit -{ - int state; - u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */ - struct isis_area *area; /* back pointer to the area */ - struct interface *interface; /* interface info from z */ - int fd; /* IS-IS l1/2 socket */ - int sap_length; /* SAP length for DLPI */ - struct nlpids nlpids; - /* - * Threads - */ - struct thread *t_read; - struct thread *t_send_csnp[2]; - struct thread *t_send_psnp[2]; - struct list *lsp_queue; /* LSPs to be txed (both levels) */ - time_t lsp_queue_last_cleared;/* timestamp used to enforce transmit interval; - * for scalability, use one timestamp per - * circuit, instead of one per lsp per circuit - */ - /* there is no real point in two streams, just for programming kicker */ - int (*rx) (struct isis_circuit * circuit, u_char * ssnpa); - struct stream *rcv_stream; /* Stream for receiving */ - int (*tx) (struct isis_circuit * circuit, int level); - struct stream *snd_stream; /* Stream for sending */ - int idx; /* idx in S[RM|SN] flags */ +struct isis_circuit { + int state; + u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */ + struct isis_area *area; /* back pointer to the area */ + struct interface *interface; /* interface info from z */ + int fd; /* IS-IS l1/2 socket */ + int sap_length; /* SAP length for DLPI */ + struct nlpids nlpids; + /* + * Threads + */ + struct thread *t_read; + struct thread *t_send_csnp[2]; + struct thread *t_send_psnp[2]; + struct list *lsp_queue; /* LSPs to be txed (both levels) */ + time_t lsp_queue_last_cleared; /* timestamp used to enforce transmit + * interval; + * for scalability, use one timestamp per + * circuit, instead of one per lsp per + * circuit + */ + /* there is no real point in two streams, just for programming kicker */ + int (*rx)(struct isis_circuit *circuit, u_char *ssnpa); + struct stream *rcv_stream; /* Stream for receiving */ + int (*tx)(struct isis_circuit *circuit, int level); + struct stream *snd_stream; /* Stream for sending */ + int idx; /* idx in S[RM|SN] flags */ + /* $FRR indent$ */ + /* clang-format off */ #define CIRCUIT_T_UNKNOWN 0 #define CIRCUIT_T_BROADCAST 1 #define CIRCUIT_T_P2P 2 #define CIRCUIT_T_LOOPBACK 3 - int circ_type; /* type of the physical interface */ - int circ_type_config; /* config type of the physical interface */ - union - { - struct isis_bcast_info bc; - struct isis_p2p_info p2p; - } u; - u_char priority[2]; /* l1/2 IS configured priority */ - int pad_hellos; /* add padding to Hello PDUs ? */ - char ext_domain; /* externalDomain (boolean) */ - int lsp_regenerate_pending[ISIS_LEVELS]; - /* - * Configurables - */ - struct isis_passwd passwd; /* Circuit rx/tx password */ - int is_type; /* circuit is type == level of circuit - * differentiated from circuit type (media) */ - u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */ - u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */ - u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */ - u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */ - u_int8_t metric[2]; - u_int32_t te_metric[2]; - struct mpls_te_circuit *mtc; /* Support for MPLS-TE parameters - see isis_te.[c,h] */ - int ip_router; /* Route IP ? */ - int is_passive; /* Is Passive ? */ - struct list *mt_settings; /* IS-IS MT Settings */ - struct list *ip_addrs; /* our IP addresses */ - int ipv6_router; /* Route IPv6 ? */ - struct list *ipv6_link; /* our link local IPv6 addresses */ - struct list *ipv6_non_link; /* our non-link local IPv6 addresses */ - u_int16_t upadjcount[2]; + int circ_type; /* type of the physical interface */ + int circ_type_config; /* config type of the physical interface */ + union { + struct isis_bcast_info bc; + struct isis_p2p_info p2p; + } u; + u_char priority[2]; /* l1/2 IS configured priority */ + int pad_hellos; /* add padding to Hello PDUs ? */ + char ext_domain; /* externalDomain (boolean) */ + int lsp_regenerate_pending[ISIS_LEVELS]; + /* + * Configurables + */ + struct isis_passwd passwd; /* Circuit rx/tx password */ + int is_type; /* circuit is type == level of circuit + * differentiated from circuit type (media) */ + u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */ + u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */ + u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */ + u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */ + u_int8_t metric[2]; + u_int32_t te_metric[2]; + struct mpls_te_circuit + *mtc; /* Support for MPLS-TE parameters - see isis_te.[c,h] */ + int ip_router; /* Route IP ? */ + int is_passive; /* Is Passive ? */ + struct list *mt_settings; /* IS-IS MT Settings */ + struct list *ip_addrs; /* our IP addresses */ + int ipv6_router; /* Route IPv6 ? */ + struct list *ipv6_link; /* our link local IPv6 addresses */ + struct list *ipv6_non_link; /* our non-link local IPv6 addresses */ + u_int16_t upadjcount[2]; #define ISIS_CIRCUIT_FLAPPED_AFTER_SPF 0x01 - u_char flags; - /* - * Counters as in 10589--11.2.5.9 - */ - u_int32_t adj_state_changes; /* changesInAdjacencyState */ - u_int32_t init_failures; /* intialisationFailures */ - u_int32_t ctrl_pdus_rxed; /* controlPDUsReceived */ - u_int32_t ctrl_pdus_txed; /* controlPDUsSent */ - u_int32_t desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges */ - u_int32_t rej_adjacencies; /* rejectedAdjacencies */ - - QOBJ_FIELDS + u_char flags; + /* + * Counters as in 10589--11.2.5.9 + */ + u_int32_t adj_state_changes; /* changesInAdjacencyState */ + u_int32_t init_failures; /* intialisationFailures */ + u_int32_t ctrl_pdus_rxed; /* controlPDUsReceived */ + u_int32_t ctrl_pdus_txed; /* controlPDUsSent */ + u_int32_t + desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges */ + u_int32_t rej_adjacencies; /* rejectedAdjacencies */ + + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(isis_circuit) -void isis_circuit_init (void); -struct isis_circuit *isis_circuit_new (void); -void isis_circuit_del (struct isis_circuit *circuit); -struct isis_circuit *circuit_lookup_by_ifp (struct interface *ifp, - struct list *list); -struct isis_circuit *circuit_scan_by_ifp (struct interface *ifp); -void isis_circuit_configure (struct isis_circuit *circuit, - struct isis_area *area); -void isis_circuit_deconfigure (struct isis_circuit *circuit, - struct isis_area *area); -void isis_circuit_if_add (struct isis_circuit *circuit, - struct interface *ifp); -void isis_circuit_if_del (struct isis_circuit *circuit, - struct interface *ifp); -void isis_circuit_if_bind (struct isis_circuit *circuit, - struct interface *ifp); -void isis_circuit_if_unbind (struct isis_circuit *circuit, - struct interface *ifp); -void isis_circuit_add_addr (struct isis_circuit *circuit, - struct connected *conn); -void isis_circuit_del_addr (struct isis_circuit *circuit, - struct connected *conn); -void isis_circuit_prepare (struct isis_circuit *circuit); -int isis_circuit_up (struct isis_circuit *circuit); -void isis_circuit_down (struct isis_circuit *); -void circuit_update_nlpids (struct isis_circuit *circuit); -void isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty, - char detail); +void isis_circuit_init(void); +struct isis_circuit *isis_circuit_new(void); +void isis_circuit_del(struct isis_circuit *circuit); +struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp, + struct list *list); +struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp); +void isis_circuit_configure(struct isis_circuit *circuit, + struct isis_area *area); +void isis_circuit_deconfigure(struct isis_circuit *circuit, + struct isis_area *area); +void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp); +void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp); +void isis_circuit_if_bind(struct isis_circuit *circuit, struct interface *ifp); +void isis_circuit_if_unbind(struct isis_circuit *circuit, + struct interface *ifp); +void isis_circuit_add_addr(struct isis_circuit *circuit, + struct connected *conn); +void isis_circuit_del_addr(struct isis_circuit *circuit, + struct connected *conn); +void isis_circuit_prepare(struct isis_circuit *circuit); +int isis_circuit_up(struct isis_circuit *circuit); +void isis_circuit_down(struct isis_circuit *); +void circuit_update_nlpids(struct isis_circuit *circuit); +void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, + char detail); size_t isis_circuit_pdu_size(struct isis_circuit *circuit); void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream); -struct isis_circuit *isis_circuit_create (struct isis_area *area, struct interface *ifp); -void isis_circuit_af_set (struct isis_circuit *circuit, bool ip_router, bool ipv6_router); -int isis_circuit_passive_set (struct isis_circuit *circuit, bool passive); -void isis_circuit_is_type_set (struct isis_circuit *circuit, int is_type); -int isis_circuit_circ_type_set (struct isis_circuit *circuit, int circ_type); - -int isis_circuit_metric_set (struct isis_circuit *circuit, int level, int metric); - -int isis_circuit_passwd_unset (struct isis_circuit *circuit); -int isis_circuit_passwd_cleartext_set (struct isis_circuit *circuit, const char *passwd); -int isis_circuit_passwd_hmac_md5_set (struct isis_circuit *circuit, const char *passwd); - -int isis_circuit_mt_enabled_set (struct isis_circuit *circuit, uint16_t mtid, bool enabled); +struct isis_circuit *isis_circuit_create(struct isis_area *area, + struct interface *ifp); +void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, + bool ipv6_router); +int isis_circuit_passive_set(struct isis_circuit *circuit, bool passive); +void isis_circuit_is_type_set(struct isis_circuit *circuit, int is_type); +int isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type); + +int isis_circuit_metric_set(struct isis_circuit *circuit, int level, + int metric); + +int isis_circuit_passwd_unset(struct isis_circuit *circuit); +int isis_circuit_passwd_cleartext_set(struct isis_circuit *circuit, + const char *passwd); +int isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, + const char *passwd); + +int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, + bool enabled); #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_common.h b/isisd/isis_common.h index 6c827115b..ba6c5f876 100644 --- a/isisd/isis_common.h +++ b/isisd/isis_common.h @@ -1,19 +1,19 @@ /* - * IS-IS Rout(e)ing protocol - isis_common.h + * IS-IS Rout(e)ing protocol - isis_common.h * some common data structures * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -27,25 +27,23 @@ /* * Area Address */ -struct area_addr -{ - u_char addr_len; - u_char area_addr[20]; +struct area_addr { + u_char addr_len; + u_char area_addr[20]; }; -struct isis_passwd -{ - u_char len; +struct isis_passwd { + u_char len; #define ISIS_PASSWD_TYPE_UNUSED 0 #define ISIS_PASSWD_TYPE_CLEARTXT 1 #define ISIS_PASSWD_TYPE_HMAC_MD5 54 #define ISIS_PASSWD_TYPE_PRIVATE 255 - u_char type; - /* Authenticate SNPs? */ + u_char type; +/* Authenticate SNPs? */ #define SNP_AUTH_SEND 0x01 #define SNP_AUTH_RECV 0x02 - u_char snp_auth; - u_char passwd[255]; + u_char snp_auth; + u_char passwd[255]; }; /* @@ -53,19 +51,17 @@ struct isis_passwd * one struct for cache list * one struct for LSP TLV */ -struct hostname -{ - u_char namelen; - u_char name[255]; +struct hostname { + u_char namelen; + u_char name[255]; }; /* * Supported Protocol IDs */ -struct nlpids -{ - u_char count; - u_char nlpids[4]; /* FIXME: enough ? */ +struct nlpids { + u_char count; + u_char nlpids[4]; /* FIXME: enough ? */ }; #endif diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h index b59d77bf3..4b5ff888b 100644 --- a/isisd/isis_constants.h +++ b/isisd/isis_constants.h @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isis_constants.h + * IS-IS Rout(e)ing protocol - isis_constants.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -163,9 +163,9 @@ /* we need to be aware of the fact we are using ISO sized * packets, using isomtu = mtu - LLC_LEN */ -#define ISO_MTU(C) \ - ((if_is_broadcast ((C)->interface)) ? \ - (C->interface->mtu - LLC_LEN) : (C->interface->mtu)) +#define ISO_MTU(C) \ + ((if_is_broadcast((C)->interface)) ? (C->interface->mtu - LLC_LEN) \ + : (C->interface->mtu)) #ifndef ETH_ALEN #define ETH_ALEN 6 @@ -176,9 +176,9 @@ static inline uint16_t isis_ethertype(size_t len) { - if (len > MAX_LLC_LEN) - return ETHERTYPE_EXT_LLC; - return len; + if (len > MAX_LLC_LEN) + return ETHERTYPE_EXT_LLC; + return len; } #endif /* ISIS_CONSTANTS_H */ diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c index 90272d68b..b0ccdee76 100644 --- a/isisd/isis_csm.c +++ b/isisd/isis_csm.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_csm.c * IS-IS circuit state machine * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -51,169 +51,165 @@ extern struct isis *isis; -static const char *csm_statestr[] = { - "C_STATE_NA", - "C_STATE_INIT", - "C_STATE_CONF", - "C_STATE_UP" -}; +static const char *csm_statestr[] = {"C_STATE_NA", "C_STATE_INIT", + "C_STATE_CONF", "C_STATE_UP"}; #define STATE2STR(S) csm_statestr[S] static const char *csm_eventstr[] = { - "NO_STATE", - "ISIS_ENABLE", - "IF_UP_FROM_Z", - "ISIS_DISABLE", - "IF_DOWN_FROM_Z", + "NO_STATE", "ISIS_ENABLE", "IF_UP_FROM_Z", + "ISIS_DISABLE", "IF_DOWN_FROM_Z", }; #define EVENT2STR(E) csm_eventstr[E] struct isis_circuit * -isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg) +isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) { - int old_state; + int old_state; - old_state = circuit ? circuit->state : C_STATE_NA; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("CSM_EVENT: %s", EVENT2STR (event)); + old_state = circuit ? circuit->state : C_STATE_NA; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("CSM_EVENT: %s", EVENT2STR(event)); - switch (old_state) - { - case C_STATE_NA: - if (circuit) - zlog_warn ("Non-null circuit while state C_STATE_NA"); - assert (circuit == NULL); - switch (event) - { - case ISIS_ENABLE: - circuit = isis_circuit_new (); - isis_circuit_configure (circuit, (struct isis_area *) arg); - circuit->state = C_STATE_CONF; - break; - case IF_UP_FROM_Z: - circuit = isis_circuit_new (); - isis_circuit_if_add (circuit, (struct interface *) arg); - listnode_add (isis->init_circ_list, circuit); - circuit->state = C_STATE_INIT; - break; - case ISIS_DISABLE: - zlog_warn ("circuit already disabled"); - break; - case IF_DOWN_FROM_Z: - zlog_warn ("circuit already disconnected"); - break; - } - break; - case C_STATE_INIT: - assert (circuit); - switch (event) - { - case ISIS_ENABLE: - isis_circuit_configure (circuit, (struct isis_area *) arg); - if (isis_circuit_up (circuit) != ISIS_OK) - { - isis_circuit_deconfigure (circuit, (struct isis_area *) arg); - break; - } - circuit->state = C_STATE_UP; - isis_event_circuit_state_change (circuit, circuit->area, 1); - listnode_delete (isis->init_circ_list, circuit); - break; - case IF_UP_FROM_Z: - assert (circuit); - zlog_warn ("circuit already connected"); - break; - case ISIS_DISABLE: - zlog_warn ("circuit already disabled"); - break; - case IF_DOWN_FROM_Z: - isis_circuit_if_del (circuit, (struct interface *) arg); - listnode_delete (isis->init_circ_list, circuit); - isis_circuit_del (circuit); - circuit = NULL; - break; - } - break; - case C_STATE_CONF: - assert (circuit); - switch (event) - { - case ISIS_ENABLE: - zlog_warn ("circuit already enabled"); - break; - case IF_UP_FROM_Z: - isis_circuit_if_add (circuit, (struct interface *) arg); - if (isis_circuit_up (circuit) != ISIS_OK) - { - zlog_err("Could not bring up %s because of invalid config.", - circuit->interface->name); - zlog_err("Clearing config for %s. Please re-examine it.", - circuit->interface->name); - if (circuit->ip_router) - { - circuit->ip_router = 0; - circuit->area->ip_circuits--; - } - if (circuit->ipv6_router) - { - circuit->ipv6_router = 0; - circuit->area->ipv6_circuits--; - } - circuit_update_nlpids(circuit); - isis_circuit_deconfigure(circuit, circuit->area); - listnode_add (isis->init_circ_list, circuit); - circuit->state = C_STATE_INIT; - break; - } - circuit->state = C_STATE_UP; - isis_event_circuit_state_change (circuit, circuit->area, 1); - break; - case ISIS_DISABLE: - isis_circuit_deconfigure (circuit, (struct isis_area *) arg); - isis_circuit_del (circuit); - circuit = NULL; - break; - case IF_DOWN_FROM_Z: - zlog_warn ("circuit already disconnected"); - break; - } - break; - case C_STATE_UP: - assert (circuit); - switch (event) - { - case ISIS_ENABLE: - zlog_warn ("circuit already configured"); - break; - case IF_UP_FROM_Z: - zlog_warn ("circuit already connected"); - break; - case ISIS_DISABLE: - isis_circuit_down (circuit); - isis_circuit_deconfigure (circuit, (struct isis_area *) arg); - circuit->state = C_STATE_INIT; - isis_event_circuit_state_change (circuit, - (struct isis_area *)arg, 0); - listnode_add (isis->init_circ_list, circuit); - break; - case IF_DOWN_FROM_Z: - isis_circuit_down (circuit); - isis_circuit_if_del (circuit, (struct interface *) arg); - circuit->state = C_STATE_CONF; - isis_event_circuit_state_change (circuit, circuit->area, 0); - break; - } - break; + switch (old_state) { + case C_STATE_NA: + if (circuit) + zlog_warn("Non-null circuit while state C_STATE_NA"); + assert(circuit == NULL); + switch (event) { + case ISIS_ENABLE: + circuit = isis_circuit_new(); + isis_circuit_configure(circuit, + (struct isis_area *)arg); + circuit->state = C_STATE_CONF; + break; + case IF_UP_FROM_Z: + circuit = isis_circuit_new(); + isis_circuit_if_add(circuit, (struct interface *)arg); + listnode_add(isis->init_circ_list, circuit); + circuit->state = C_STATE_INIT; + break; + case ISIS_DISABLE: + zlog_warn("circuit already disabled"); + break; + case IF_DOWN_FROM_Z: + zlog_warn("circuit already disconnected"); + break; + } + break; + case C_STATE_INIT: + assert(circuit); + switch (event) { + case ISIS_ENABLE: + isis_circuit_configure(circuit, + (struct isis_area *)arg); + if (isis_circuit_up(circuit) != ISIS_OK) { + isis_circuit_deconfigure( + circuit, (struct isis_area *)arg); + break; + } + circuit->state = C_STATE_UP; + isis_event_circuit_state_change(circuit, circuit->area, + 1); + listnode_delete(isis->init_circ_list, circuit); + break; + case IF_UP_FROM_Z: + assert(circuit); + zlog_warn("circuit already connected"); + break; + case ISIS_DISABLE: + zlog_warn("circuit already disabled"); + break; + case IF_DOWN_FROM_Z: + isis_circuit_if_del(circuit, (struct interface *)arg); + listnode_delete(isis->init_circ_list, circuit); + isis_circuit_del(circuit); + circuit = NULL; + break; + } + break; + case C_STATE_CONF: + assert(circuit); + switch (event) { + case ISIS_ENABLE: + zlog_warn("circuit already enabled"); + break; + case IF_UP_FROM_Z: + isis_circuit_if_add(circuit, (struct interface *)arg); + if (isis_circuit_up(circuit) != ISIS_OK) { + zlog_err( + "Could not bring up %s because of invalid config.", + circuit->interface->name); + zlog_err( + "Clearing config for %s. Please re-examine it.", + circuit->interface->name); + if (circuit->ip_router) { + circuit->ip_router = 0; + circuit->area->ip_circuits--; + } + if (circuit->ipv6_router) { + circuit->ipv6_router = 0; + circuit->area->ipv6_circuits--; + } + circuit_update_nlpids(circuit); + isis_circuit_deconfigure(circuit, + circuit->area); + listnode_add(isis->init_circ_list, circuit); + circuit->state = C_STATE_INIT; + break; + } + circuit->state = C_STATE_UP; + isis_event_circuit_state_change(circuit, circuit->area, + 1); + break; + case ISIS_DISABLE: + isis_circuit_deconfigure(circuit, + (struct isis_area *)arg); + isis_circuit_del(circuit); + circuit = NULL; + break; + case IF_DOWN_FROM_Z: + zlog_warn("circuit already disconnected"); + break; + } + break; + case C_STATE_UP: + assert(circuit); + switch (event) { + case ISIS_ENABLE: + zlog_warn("circuit already configured"); + break; + case IF_UP_FROM_Z: + zlog_warn("circuit already connected"); + break; + case ISIS_DISABLE: + isis_circuit_down(circuit); + isis_circuit_deconfigure(circuit, + (struct isis_area *)arg); + circuit->state = C_STATE_INIT; + isis_event_circuit_state_change( + circuit, (struct isis_area *)arg, 0); + listnode_add(isis->init_circ_list, circuit); + break; + case IF_DOWN_FROM_Z: + isis_circuit_down(circuit); + isis_circuit_if_del(circuit, (struct interface *)arg); + circuit->state = C_STATE_CONF; + isis_event_circuit_state_change(circuit, circuit->area, + 0); + break; + } + break; - default: - zlog_warn ("Invalid circuit state %d", old_state); - } + default: + zlog_warn("Invalid circuit state %d", old_state); + } - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state), - circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA)); + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("CSM_STATE_CHANGE: %s -> %s ", STATE2STR(old_state), + circuit ? STATE2STR(circuit->state) + : STATE2STR(C_STATE_NA)); - return circuit; + return circuit; } diff --git a/isisd/isis_csm.h b/isisd/isis_csm.h index a1e0f234f..53a5f9d5d 100644 --- a/isisd/isis_csm.h +++ b/isisd/isis_csm.h @@ -3,18 +3,18 @@ * IS-IS circuit state machine * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -40,8 +40,7 @@ #define ISIS_DISABLE 3 #define IF_DOWN_FROM_Z 4 -struct isis_circuit *isis_csm_state_change (int event, - struct isis_circuit *circuit, - void *arg); +struct isis_circuit * +isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg); #endif /* _ZEBRA_ISIS_CSM_H */ diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c index afd8a14f9..7ac8b54fa 100644 --- a/isisd/isis_dlpi.c +++ b/isisd/isis_dlpi.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_dlpi.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -49,37 +49,36 @@ extern struct zebra_privs_t isisd_privs; -static t_uscalar_t dlpi_ctl[1024]; /* DLPI control messages */ +static t_uscalar_t dlpi_ctl[1024]; /* DLPI control messages */ /* * Table 9 - Architectural constants for use with ISO 8802 subnetworks * ISO 10589 - 8.4.8 */ -u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 }; -u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 }; -u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 }; -u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 }; +u_char ALL_L1_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x14}; +u_char ALL_L2_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x15}; +u_char ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05}; +u_char ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04}; static u_char sock_buff[8192]; -static u_short pf_filter[] = -{ - ENF_PUSHWORD + 0, /* Get the SSAP/DSAP values */ - ENF_PUSHLIT | ENF_CAND, /* Check them */ - ISO_SAP | (ISO_SAP << 8), - ENF_PUSHWORD + 1, /* Get the control value */ - ENF_PUSHLIT | ENF_AND, /* Isolate it */ +static u_short pf_filter[] = { + ENF_PUSHWORD + 0, /* Get the SSAP/DSAP values */ + ENF_PUSHLIT | ENF_CAND, /* Check them */ + ISO_SAP | (ISO_SAP << 8), + ENF_PUSHWORD + 1, /* Get the control value */ + ENF_PUSHLIT | ENF_AND, /* Isolate it */ #ifdef _BIG_ENDIAN - 0xFF00, + 0xFF00, #else - 0x00FF, + 0x00FF, #endif - ENF_PUSHLIT | ENF_CAND, /* Test for expected value */ + ENF_PUSHLIT | ENF_CAND, /* Test for expected value */ #ifdef _BIG_ENDIAN - 0x0300 + 0x0300 #else - 0x0003 + 0x0003 #endif }; @@ -90,564 +89,530 @@ static u_short pf_filter[] = * interfaces plus the (optional; not needed) Solaris packet filter module. */ -static int -dlpisend (int fd, const void *cbuf, size_t cbuflen, - const void *dbuf, size_t dbuflen, int flags) +static int dlpisend(int fd, const void *cbuf, size_t cbuflen, const void *dbuf, + size_t dbuflen, int flags) { - const struct strbuf *ctlptr = NULL; - const struct strbuf *dataptr = NULL; - struct strbuf ctlbuf, databuf; - int rv; - - if (cbuf != NULL) - { - memset (&ctlbuf, 0, sizeof (ctlbuf)); - ctlbuf.len = cbuflen; - ctlbuf.buf = (void *)cbuf; - ctlptr = &ctlbuf; - } - - if (dbuf != NULL) - { - memset (&databuf, 0, sizeof (databuf)); - databuf.len = dbuflen; - databuf.buf = (void *)dbuf; - dataptr = &databuf; - } - - /* We assume this doesn't happen often and isn't operationally significant */ - rv = putmsg(fd, ctlptr, dataptr, flags); - if (rv == -1 && dbuf == NULL) - { - /* - * For actual PDU transmission - recognizable buf dbuf != NULL, - * the error is passed upwards and should not be printed here. - */ - zlog_debug ("%s: putmsg: %s", __func__, safe_strerror (errno)); - } - return rv; + const struct strbuf *ctlptr = NULL; + const struct strbuf *dataptr = NULL; + struct strbuf ctlbuf, databuf; + int rv; + + if (cbuf != NULL) { + memset(&ctlbuf, 0, sizeof(ctlbuf)); + ctlbuf.len = cbuflen; + ctlbuf.buf = (void *)cbuf; + ctlptr = &ctlbuf; + } + + if (dbuf != NULL) { + memset(&databuf, 0, sizeof(databuf)); + databuf.len = dbuflen; + databuf.buf = (void *)dbuf; + dataptr = &databuf; + } + + /* We assume this doesn't happen often and isn't operationally + * significant */ + rv = putmsg(fd, ctlptr, dataptr, flags); + if (rv == -1 && dbuf == NULL) { + /* + * For actual PDU transmission - recognizable buf dbuf != NULL, + * the error is passed upwards and should not be printed here. + */ + zlog_debug("%s: putmsg: %s", __func__, safe_strerror(errno)); + } + return rv; } -static ssize_t -dlpirctl (int fd) +static ssize_t dlpirctl(int fd) { - struct pollfd fds[1]; - struct strbuf ctlbuf, databuf; - int flags, retv; - - do - { - /* Poll is used here in case the device doesn't speak DLPI correctly */ - memset (fds, 0, sizeof (fds)); - fds[0].fd = fd; - fds[0].events = POLLIN | POLLPRI; - if (poll (fds, 1, 1000) <= 0) - return -1; - - memset (&ctlbuf, 0, sizeof (ctlbuf)); - memset (&databuf, 0, sizeof (databuf)); - ctlbuf.maxlen = sizeof (dlpi_ctl); - ctlbuf.buf = (void *)dlpi_ctl; - databuf.maxlen = sizeof (sock_buff); - databuf.buf = (void *)sock_buff; - flags = 0; - retv = getmsg (fd, &ctlbuf, &databuf, &flags); + struct pollfd fds[1]; + struct strbuf ctlbuf, databuf; + int flags, retv; + + do { + /* Poll is used here in case the device doesn't speak DLPI + * correctly */ + memset(fds, 0, sizeof(fds)); + fds[0].fd = fd; + fds[0].events = POLLIN | POLLPRI; + if (poll(fds, 1, 1000) <= 0) + return -1; + + memset(&ctlbuf, 0, sizeof(ctlbuf)); + memset(&databuf, 0, sizeof(databuf)); + ctlbuf.maxlen = sizeof(dlpi_ctl); + ctlbuf.buf = (void *)dlpi_ctl; + databuf.maxlen = sizeof(sock_buff); + databuf.buf = (void *)sock_buff; + flags = 0; + retv = getmsg(fd, &ctlbuf, &databuf, &flags); + + if (retv < 0) + return -1; + } while (ctlbuf.len == 0); + + if (!(retv & MORECTL)) { + while (retv & MOREDATA) { + flags = 0; + retv = getmsg(fd, NULL, &databuf, &flags); + } + return ctlbuf.len; + } - if (retv < 0) - return -1; - } - while (ctlbuf.len == 0); - - if (!(retv & MORECTL)) - { - while (retv & MOREDATA) - { - flags = 0; - retv = getmsg (fd, NULL, &databuf, &flags); + while (retv & MORECTL) { + flags = 0; + retv = getmsg(fd, &ctlbuf, &databuf, &flags); } - return ctlbuf.len; - } - - while (retv & MORECTL) - { - flags = 0; - retv = getmsg (fd, &ctlbuf, &databuf, &flags); - } - return -1; + return -1; } -static int -dlpiok (int fd, t_uscalar_t oprim) +static int dlpiok(int fd, t_uscalar_t oprim) { - int retv; - dl_ok_ack_t *doa = (dl_ok_ack_t *)dlpi_ctl; - - retv = dlpirctl (fd); - if (retv < (ssize_t)DL_OK_ACK_SIZE || doa->dl_primitive != DL_OK_ACK || - doa->dl_correct_primitive != oprim) - { - return -1; - } - else - { - return 0; - } + int retv; + dl_ok_ack_t *doa = (dl_ok_ack_t *)dlpi_ctl; + + retv = dlpirctl(fd); + if (retv < (ssize_t)DL_OK_ACK_SIZE || doa->dl_primitive != DL_OK_ACK + || doa->dl_correct_primitive != oprim) { + return -1; + } else { + return 0; + } } -static int -dlpiinfo (int fd) +static int dlpiinfo(int fd) { - dl_info_req_t dir; - ssize_t retv; - - memset (&dir, 0, sizeof (dir)); - dir.dl_primitive = DL_INFO_REQ; - /* Info_req uses M_PCPROTO. */ - dlpisend (fd, &dir, sizeof (dir), NULL, 0, RS_HIPRI); - retv = dlpirctl (fd); - if (retv < (ssize_t)DL_INFO_ACK_SIZE || dlpi_ctl[0] != DL_INFO_ACK) - return -1; - else - return retv; + dl_info_req_t dir; + ssize_t retv; + + memset(&dir, 0, sizeof(dir)); + dir.dl_primitive = DL_INFO_REQ; + /* Info_req uses M_PCPROTO. */ + dlpisend(fd, &dir, sizeof(dir), NULL, 0, RS_HIPRI); + retv = dlpirctl(fd); + if (retv < (ssize_t)DL_INFO_ACK_SIZE || dlpi_ctl[0] != DL_INFO_ACK) + return -1; + else + return retv; } -static int -dlpiopen (const char *devpath, ssize_t *acklen) +static int dlpiopen(const char *devpath, ssize_t *acklen) { - int fd, flags; - - fd = open (devpath, O_RDWR | O_NONBLOCK | O_NOCTTY); - if (fd == -1) - return -1; - - /* All that we want is for the open itself to be non-blocking, not I/O. */ - flags = fcntl (fd, F_GETFL, 0); - if (flags != -1) - fcntl (fd, F_SETFL, flags & ~O_NONBLOCK); - - /* After opening, ask for information */ - if ((*acklen = dlpiinfo (fd)) == -1) - { - close (fd); - return -1; - } + int fd, flags; + + fd = open(devpath, O_RDWR | O_NONBLOCK | O_NOCTTY); + if (fd == -1) + return -1; + + /* All that we want is for the open itself to be non-blocking, not I/O. + */ + flags = fcntl(fd, F_GETFL, 0); + if (flags != -1) + fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + + /* After opening, ask for information */ + if ((*acklen = dlpiinfo(fd)) == -1) { + close(fd); + return -1; + } - return fd; + return fd; } -static int -dlpiattach (int fd, int unit) +static int dlpiattach(int fd, int unit) { - dl_attach_req_t dar; + dl_attach_req_t dar; - memset (&dar, 0, sizeof (dar)); - dar.dl_primitive = DL_ATTACH_REQ; - dar.dl_ppa = unit; - dlpisend (fd, &dar, sizeof (dar), NULL, 0, 0); - return dlpiok (fd, dar.dl_primitive); + memset(&dar, 0, sizeof(dar)); + dar.dl_primitive = DL_ATTACH_REQ; + dar.dl_ppa = unit; + dlpisend(fd, &dar, sizeof(dar), NULL, 0, 0); + return dlpiok(fd, dar.dl_primitive); } -static int -dlpibind (int fd) +static int dlpibind(int fd) { - dl_bind_req_t dbr; - int retv; - dl_bind_ack_t *dba = (dl_bind_ack_t *)dlpi_ctl; - - memset (&dbr, 0, sizeof (dbr)); - dbr.dl_primitive = DL_BIND_REQ; - dbr.dl_service_mode = DL_CLDLS; - dlpisend (fd, &dbr, sizeof (dbr), NULL, 0, 0); - - retv = dlpirctl (fd); - if (retv < (ssize_t)DL_BIND_ACK_SIZE || dba->dl_primitive != DL_BIND_ACK) - return -1; - else - return 0; + dl_bind_req_t dbr; + int retv; + dl_bind_ack_t *dba = (dl_bind_ack_t *)dlpi_ctl; + + memset(&dbr, 0, sizeof(dbr)); + dbr.dl_primitive = DL_BIND_REQ; + dbr.dl_service_mode = DL_CLDLS; + dlpisend(fd, &dbr, sizeof(dbr), NULL, 0, 0); + + retv = dlpirctl(fd); + if (retv < (ssize_t)DL_BIND_ACK_SIZE + || dba->dl_primitive != DL_BIND_ACK) + return -1; + else + return 0; } -static int -dlpimcast (int fd, const u_char *mcaddr) +static int dlpimcast(int fd, const u_char *mcaddr) { - struct { - dl_enabmulti_req_t der; - u_char addr[ETHERADDRL]; - } dler; - - memset (&dler, 0, sizeof (dler)); - dler.der.dl_primitive = DL_ENABMULTI_REQ; - dler.der.dl_addr_length = sizeof (dler.addr); - dler.der.dl_addr_offset = dler.addr - (u_char *)&dler; - memcpy (dler.addr, mcaddr, sizeof (dler.addr)); - dlpisend (fd, &dler, sizeof (dler), NULL, 0, 0); - return dlpiok (fd, dler.der.dl_primitive); + struct { + dl_enabmulti_req_t der; + u_char addr[ETHERADDRL]; + } dler; + + memset(&dler, 0, sizeof(dler)); + dler.der.dl_primitive = DL_ENABMULTI_REQ; + dler.der.dl_addr_length = sizeof(dler.addr); + dler.der.dl_addr_offset = dler.addr - (u_char *)&dler; + memcpy(dler.addr, mcaddr, sizeof(dler.addr)); + dlpisend(fd, &dler, sizeof(dler), NULL, 0, 0); + return dlpiok(fd, dler.der.dl_primitive); } -static int -dlpiaddr (int fd, u_char *addr) +static int dlpiaddr(int fd, u_char *addr) { - dl_phys_addr_req_t dpar; - dl_phys_addr_ack_t *dpaa = (dl_phys_addr_ack_t *)dlpi_ctl; - int retv; - - memset (&dpar, 0, sizeof (dpar)); - dpar.dl_primitive = DL_PHYS_ADDR_REQ; - dpar.dl_addr_type = DL_CURR_PHYS_ADDR; - dlpisend (fd, &dpar, sizeof (dpar), NULL, 0, 0); - - retv = dlpirctl (fd); - if (retv < (ssize_t)DL_PHYS_ADDR_ACK_SIZE - || dpaa->dl_primitive != DL_PHYS_ADDR_ACK) - return -1; - - if (dpaa->dl_addr_offset < DL_PHYS_ADDR_ACK_SIZE || - dpaa->dl_addr_length != ETHERADDRL || - dpaa->dl_addr_offset + dpaa->dl_addr_length > (size_t)retv) - return -1; - - bcopy((char *)dpaa + dpaa->dl_addr_offset, addr, ETHERADDRL); - return 0; + dl_phys_addr_req_t dpar; + dl_phys_addr_ack_t *dpaa = (dl_phys_addr_ack_t *)dlpi_ctl; + int retv; + + memset(&dpar, 0, sizeof(dpar)); + dpar.dl_primitive = DL_PHYS_ADDR_REQ; + dpar.dl_addr_type = DL_CURR_PHYS_ADDR; + dlpisend(fd, &dpar, sizeof(dpar), NULL, 0, 0); + + retv = dlpirctl(fd); + if (retv < (ssize_t)DL_PHYS_ADDR_ACK_SIZE + || dpaa->dl_primitive != DL_PHYS_ADDR_ACK) + return -1; + + if (dpaa->dl_addr_offset < DL_PHYS_ADDR_ACK_SIZE + || dpaa->dl_addr_length != ETHERADDRL + || dpaa->dl_addr_offset + dpaa->dl_addr_length > (size_t)retv) + return -1; + + bcopy((char *)dpaa + dpaa->dl_addr_offset, addr, ETHERADDRL); + return 0; } -static int -open_dlpi_dev (struct isis_circuit *circuit) +static int open_dlpi_dev(struct isis_circuit *circuit) { - int fd = -1, unit, retval; - char devpath[MAXPATHLEN]; - dl_info_ack_t *dia = (dl_info_ack_t *)dlpi_ctl; - ssize_t acklen; - - /* Only broadcast-type are supported at the moment */ - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - { - zlog_warn ("%s: non-broadcast interface %s", __func__, - circuit->interface->name); - return ISIS_WARNING; - } - - /* Try the vanity node first, if permitted */ - if (getenv("DLPI_DEVONLY") == NULL) - { - (void) snprintf (devpath, sizeof(devpath), "/dev/net/%s", - circuit->interface->name); - fd = dlpiopen (devpath, &acklen); - } - - /* Now try as an ordinary Style 1 node */ - if (fd == -1) - { - (void) snprintf (devpath, sizeof (devpath), "/dev/%s", - circuit->interface->name); - unit = -1; - fd = dlpiopen (devpath, &acklen); - } - - /* If that fails, try again as Style 2 */ - if (fd == -1) - { - char *cp; - - cp = devpath + strlen (devpath); - while (--cp >= devpath && isdigit(*cp)) - ; - unit = strtol(cp, NULL, 0); - *cp = '\0'; - fd = dlpiopen (devpath, &acklen); - - /* If that too fails, then the device really doesn't exist */ - if (fd == -1) - { - zlog_warn ("%s: unknown interface %s", __func__, - circuit->interface->name); - return ISIS_WARNING; + int fd = -1, unit, retval; + char devpath[MAXPATHLEN]; + dl_info_ack_t *dia = (dl_info_ack_t *)dlpi_ctl; + ssize_t acklen; + + /* Only broadcast-type are supported at the moment */ + if (circuit->circ_type != CIRCUIT_T_BROADCAST) { + zlog_warn("%s: non-broadcast interface %s", __func__, + circuit->interface->name); + return ISIS_WARNING; + } + + /* Try the vanity node first, if permitted */ + if (getenv("DLPI_DEVONLY") == NULL) { + (void)snprintf(devpath, sizeof(devpath), "/dev/net/%s", + circuit->interface->name); + fd = dlpiopen(devpath, &acklen); + } + + /* Now try as an ordinary Style 1 node */ + if (fd == -1) { + (void)snprintf(devpath, sizeof(devpath), "/dev/%s", + circuit->interface->name); + unit = -1; + fd = dlpiopen(devpath, &acklen); + } + + /* If that fails, try again as Style 2 */ + if (fd == -1) { + char *cp; + + cp = devpath + strlen(devpath); + while (--cp >= devpath && isdigit(*cp)) + ; + unit = strtol(cp, NULL, 0); + *cp = '\0'; + fd = dlpiopen(devpath, &acklen); + + /* If that too fails, then the device really doesn't exist */ + if (fd == -1) { + zlog_warn("%s: unknown interface %s", __func__, + circuit->interface->name); + return ISIS_WARNING; + } + + /* Double check the DLPI style */ + if (dia->dl_provider_style != DL_STYLE2) { + zlog_warn( + "open_dlpi_dev(): interface %s: %s is not style 2", + circuit->interface->name, devpath); + close(fd); + return ISIS_WARNING; + } + + /* If it succeeds, then we need to attach to the unit specified + */ + dlpiattach(fd, unit); + + /* Reget the information, as it may be different per node */ + if ((acklen = dlpiinfo(fd)) == -1) { + close(fd); + return ISIS_WARNING; + } + } else { + /* Double check the DLPI style */ + if (dia->dl_provider_style != DL_STYLE1) { + zlog_warn( + "open_dlpi_dev(): interface %s: %s is not style 1", + circuit->interface->name, devpath); + close(fd); + return ISIS_WARNING; + } } - /* Double check the DLPI style */ - if (dia->dl_provider_style != DL_STYLE2) - { - zlog_warn ("open_dlpi_dev(): interface %s: %s is not style 2", - circuit->interface->name, devpath); - close (fd); - return ISIS_WARNING; + /* Check that the interface we've got is the kind we expect */ + if ((dia->dl_sap_length != 2 && dia->dl_sap_length != -2) + || dia->dl_service_mode != DL_CLDLS + || dia->dl_addr_length != ETHERADDRL + 2 + || dia->dl_brdcst_addr_length != ETHERADDRL) { + zlog_warn("%s: unsupported interface type for %s", __func__, + circuit->interface->name); + close(fd); + return ISIS_WARNING; + } + switch (dia->dl_mac_type) { + case DL_CSMACD: + case DL_ETHER: + case DL_100VG: + case DL_100VGTPR: + case DL_ETH_CSMA: + case DL_100BT: + break; + default: + zlog_warn("%s: unexpected mac type on %s: %lld", __func__, + circuit->interface->name, + (long long)dia->dl_mac_type); + close(fd); + return ISIS_WARNING; + } + + circuit->sap_length = dia->dl_sap_length; + + /* + * The local hardware address is something that should be provided by + * way of + * sockaddr_dl for the interface, but isn't on Solaris. We set it here + * based + * on DLPI's reported address to avoid roto-tilling the world. + * (Note that isis_circuit_if_add on Solaris doesn't set the snpa.) + * + * Unfortunately, GLD is broken and doesn't provide the address after + * attach, + * so we need to be careful and use DL_PHYS_ADDR_REQ instead. + */ + if (dlpiaddr(fd, circuit->u.bc.snpa) == -1) { + zlog_warn( + "open_dlpi_dev(): interface %s: unable to get MAC address", + circuit->interface->name); + close(fd); + return ISIS_WARNING; } - /* If it succeeds, then we need to attach to the unit specified */ - dlpiattach (fd, unit); + /* Now bind to SAP 0. This gives us 802-type traffic. */ + if (dlpibind(fd) == -1) { + zlog_warn("%s: cannot bind SAP 0 on %s", __func__, + circuit->interface->name); + close(fd); + return ISIS_WARNING; + } - /* Reget the information, as it may be different per node */ - if ((acklen = dlpiinfo (fd)) == -1) - { - close (fd); - return ISIS_WARNING; + /* + * Join to multicast groups according to + * 8.4.2 - Broadcast subnetwork IIH PDUs + */ + retval = 0; + retval |= dlpimcast(fd, ALL_L1_ISS); + retval |= dlpimcast(fd, ALL_ISS); + retval |= dlpimcast(fd, ALL_L2_ISS); + + if (retval != 0) { + zlog_warn("%s: unable to join multicast on %s", __func__, + circuit->interface->name); + close(fd); + return ISIS_WARNING; } - } - else - { - /* Double check the DLPI style */ - if (dia->dl_provider_style != DL_STYLE1) - { - zlog_warn ("open_dlpi_dev(): interface %s: %s is not style 1", - circuit->interface->name, devpath); - close (fd); - return ISIS_WARNING; + + /* Push on the packet filter to avoid stray 802 packets */ + if (ioctl(fd, I_PUSH, "pfmod") == 0) { + struct packetfilt pfil; + struct strioctl sioc; + + pfil.Pf_Priority = 0; + pfil.Pf_FilterLen = sizeof(pf_filter) / sizeof(u_short); + memcpy(pfil.Pf_Filter, pf_filter, sizeof(pf_filter)); + /* pfmod does not support transparent ioctls */ + sioc.ic_cmd = PFIOCSETF; + sioc.ic_timout = 5; + sioc.ic_len = sizeof(struct packetfilt); + sioc.ic_dp = (char *)&pfil; + if (ioctl(fd, I_STR, &sioc) == -1) + zlog_warn("%s: could not perform PF_IOCSETF on %s", + __func__, circuit->interface->name); } - } - - /* Check that the interface we've got is the kind we expect */ - if ((dia->dl_sap_length != 2 && dia->dl_sap_length != -2) || - dia->dl_service_mode != DL_CLDLS || dia->dl_addr_length != ETHERADDRL + 2 || - dia->dl_brdcst_addr_length != ETHERADDRL) - { - zlog_warn ("%s: unsupported interface type for %s", __func__, - circuit->interface->name); - close (fd); - return ISIS_WARNING; - } - switch (dia->dl_mac_type) - { - case DL_CSMACD: - case DL_ETHER: - case DL_100VG: - case DL_100VGTPR: - case DL_ETH_CSMA: - case DL_100BT: - break; - default: - zlog_warn ("%s: unexpected mac type on %s: %lld", __func__, - circuit->interface->name, (long long)dia->dl_mac_type); - close (fd); - return ISIS_WARNING; - } - - circuit->sap_length = dia->dl_sap_length; - - /* - * The local hardware address is something that should be provided by way of - * sockaddr_dl for the interface, but isn't on Solaris. We set it here based - * on DLPI's reported address to avoid roto-tilling the world. - * (Note that isis_circuit_if_add on Solaris doesn't set the snpa.) - * - * Unfortunately, GLD is broken and doesn't provide the address after attach, - * so we need to be careful and use DL_PHYS_ADDR_REQ instead. - */ - if (dlpiaddr (fd, circuit->u.bc.snpa) == -1) - { - zlog_warn ("open_dlpi_dev(): interface %s: unable to get MAC address", - circuit->interface->name); - close (fd); - return ISIS_WARNING; - } - - /* Now bind to SAP 0. This gives us 802-type traffic. */ - if (dlpibind (fd) == -1) - { - zlog_warn ("%s: cannot bind SAP 0 on %s", __func__, - circuit->interface->name); - close (fd); - return ISIS_WARNING; - } - - /* - * Join to multicast groups according to - * 8.4.2 - Broadcast subnetwork IIH PDUs - */ - retval = 0; - retval |= dlpimcast (fd, ALL_L1_ISS); - retval |= dlpimcast (fd, ALL_ISS); - retval |= dlpimcast (fd, ALL_L2_ISS); - - if (retval != 0) - { - zlog_warn ("%s: unable to join multicast on %s", __func__, - circuit->interface->name); - close (fd); - return ISIS_WARNING; - } - - /* Push on the packet filter to avoid stray 802 packets */ - if (ioctl (fd, I_PUSH, "pfmod") == 0) - { - struct packetfilt pfil; - struct strioctl sioc; - - pfil.Pf_Priority = 0; - pfil.Pf_FilterLen = sizeof (pf_filter) / sizeof (u_short); - memcpy (pfil.Pf_Filter, pf_filter, sizeof (pf_filter)); - /* pfmod does not support transparent ioctls */ - sioc.ic_cmd = PFIOCSETF; - sioc.ic_timout = 5; - sioc.ic_len = sizeof (struct packetfilt); - sioc.ic_dp = (char *)&pfil; - if (ioctl (fd, I_STR, &sioc) == -1) - zlog_warn("%s: could not perform PF_IOCSETF on %s", - __func__, circuit->interface->name); - } - - circuit->fd = fd; - - return ISIS_OK; + + circuit->fd = fd; + + return ISIS_OK; } /* * Create the socket and set the tx/rx funcs */ -int -isis_sock_init (struct isis_circuit *circuit) +int isis_sock_init(struct isis_circuit *circuit) { - int retval = ISIS_OK; - - if (isisd_privs.change (ZPRIVS_RAISE)) - zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno)); - - retval = open_dlpi_dev (circuit); - - if (retval != ISIS_OK) - { - zlog_warn ("%s: could not initialize the socket", __func__); - goto end; - } - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } - else - { - zlog_warn ("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; - } + int retval = ISIS_OK; + + if (isisd_privs.change(ZPRIVS_RAISE)) + zlog_err("%s: could not raise privs, %s", __func__, + safe_strerror(errno)); + + retval = open_dlpi_dev(circuit); + + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", __func__); + goto end; + } + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + goto end; + } end: - if (isisd_privs.change (ZPRIVS_LOWER)) - zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno)); + if (isisd_privs.change(ZPRIVS_LOWER)) + zlog_err("%s: could not lower privs, %s", __func__, + safe_strerror(errno)); - return retval; + return retval; } -int -isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa) +int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) { - struct pollfd fds[1]; - struct strbuf ctlbuf, databuf; - int flags, retv; - dl_unitdata_ind_t *dui = (dl_unitdata_ind_t *)dlpi_ctl; - - memset (fds, 0, sizeof (fds)); - fds[0].fd = circuit->fd; - fds[0].events = POLLIN | POLLPRI; - if (poll (fds, 1, 0) <= 0) - return ISIS_WARNING; - - memset (&ctlbuf, 0, sizeof (ctlbuf)); - memset (&databuf, 0, sizeof (databuf)); - ctlbuf.maxlen = sizeof (dlpi_ctl); - ctlbuf.buf = (void *)dlpi_ctl; - databuf.maxlen = sizeof (sock_buff); - databuf.buf = (void *)sock_buff; - flags = 0; - retv = getmsg (circuit->fd, &ctlbuf, &databuf, &flags); - - if (retv < 0) - { - zlog_warn ("isis_recv_pdu_bcast: getmsg failed: %s", - safe_strerror (errno)); - return ISIS_WARNING; - } - - if (retv & (MORECTL | MOREDATA)) - { - while (retv & (MORECTL | MOREDATA)) - { - flags = 0; - retv = getmsg (circuit->fd, &ctlbuf, &databuf, &flags); + struct pollfd fds[1]; + struct strbuf ctlbuf, databuf; + int flags, retv; + dl_unitdata_ind_t *dui = (dl_unitdata_ind_t *)dlpi_ctl; + + memset(fds, 0, sizeof(fds)); + fds[0].fd = circuit->fd; + fds[0].events = POLLIN | POLLPRI; + if (poll(fds, 1, 0) <= 0) + return ISIS_WARNING; + + memset(&ctlbuf, 0, sizeof(ctlbuf)); + memset(&databuf, 0, sizeof(databuf)); + ctlbuf.maxlen = sizeof(dlpi_ctl); + ctlbuf.buf = (void *)dlpi_ctl; + databuf.maxlen = sizeof(sock_buff); + databuf.buf = (void *)sock_buff; + flags = 0; + retv = getmsg(circuit->fd, &ctlbuf, &databuf, &flags); + + if (retv < 0) { + zlog_warn("isis_recv_pdu_bcast: getmsg failed: %s", + safe_strerror(errno)); + return ISIS_WARNING; + } + + if (retv & (MORECTL | MOREDATA)) { + while (retv & (MORECTL | MOREDATA)) { + flags = 0; + retv = getmsg(circuit->fd, &ctlbuf, &databuf, &flags); + } + return ISIS_WARNING; } - return ISIS_WARNING; - } - if (ctlbuf.len < (ssize_t)DL_UNITDATA_IND_SIZE || - dui->dl_primitive != DL_UNITDATA_IND) - return ISIS_WARNING; + if (ctlbuf.len < (ssize_t)DL_UNITDATA_IND_SIZE + || dui->dl_primitive != DL_UNITDATA_IND) + return ISIS_WARNING; - if (dui->dl_src_addr_length != ETHERADDRL + 2 || - dui->dl_src_addr_offset < DL_UNITDATA_IND_SIZE || - dui->dl_src_addr_offset + dui->dl_src_addr_length > (size_t)ctlbuf.len) - return ISIS_WARNING; + if (dui->dl_src_addr_length != ETHERADDRL + 2 + || dui->dl_src_addr_offset < DL_UNITDATA_IND_SIZE + || dui->dl_src_addr_offset + dui->dl_src_addr_length + > (size_t)ctlbuf.len) + return ISIS_WARNING; - memcpy (ssnpa, (char *)dui + dui->dl_src_addr_offset + - (circuit->sap_length > 0 ? circuit->sap_length : 0), ETHERADDRL); + memcpy(ssnpa, + (char *)dui + dui->dl_src_addr_offset + + (circuit->sap_length > 0 ? circuit->sap_length : 0), + ETHERADDRL); - if (databuf.len < LLC_LEN || sock_buff[0] != ISO_SAP || - sock_buff[1] != ISO_SAP || sock_buff[2] != 3) - return ISIS_WARNING; + if (databuf.len < LLC_LEN || sock_buff[0] != ISO_SAP + || sock_buff[1] != ISO_SAP || sock_buff[2] != 3) + return ISIS_WARNING; - stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, - databuf.len - LLC_LEN); - stream_set_getp (circuit->rcv_stream, 0); + stream_write(circuit->rcv_stream, sock_buff + LLC_LEN, + databuf.len - LLC_LEN); + stream_set_getp(circuit->rcv_stream, 0); - return ISIS_OK; + return ISIS_OK; } -int -isis_send_pdu_bcast (struct isis_circuit *circuit, int level) +int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) { - dl_unitdata_req_t *dur = (dl_unitdata_req_t *)dlpi_ctl; - char *dstaddr; - u_short *dstsap; - int buflen; - int rv; - - buflen = stream_get_endp (circuit->snd_stream) + LLC_LEN; - if ((size_t)buflen > sizeof (sock_buff)) - { - zlog_warn ("isis_send_pdu_bcast: sock_buff size %zu is less than " - "output pdu size %d on circuit %s", - sizeof (sock_buff), buflen, circuit->interface->name); - return ISIS_WARNING; - } - - stream_set_getp (circuit->snd_stream, 0); - - memset (dur, 0, sizeof (*dur)); - dur->dl_primitive = DL_UNITDATA_REQ; - dur->dl_dest_addr_length = ETHERADDRL + 2; - dur->dl_dest_addr_offset = sizeof (*dur); - - dstaddr = (char *)(dur + 1); - if (circuit->sap_length < 0) - { - dstsap = (u_short *)(dstaddr + ETHERADDRL); - } - else - { - dstsap = (u_short *)dstaddr; - dstaddr += circuit->sap_length; - } - if (level == 1) - memcpy (dstaddr, ALL_L1_ISS, ETHERADDRL); - else - memcpy (dstaddr, ALL_L2_ISS, ETHERADDRL); - /* Note: DLPI SAP values are in host byte order */ - *dstsap = buflen; - - sock_buff[0] = ISO_SAP; - sock_buff[1] = ISO_SAP; - sock_buff[2] = 0x03; - memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data, - stream_get_endp (circuit->snd_stream)); - rv = dlpisend(circuit->fd, dur, sizeof (*dur) + dur->dl_dest_addr_length, - sock_buff, buflen, 0); - if (rv < 0) - { - zlog_warn("IS-IS dlpi: could not transmit packet on %s: %s", - circuit->interface->name, safe_strerror(errno)); - if (ERRNO_IO_RETRY(errno)) - return ISIS_WARNING; - return ISIS_ERROR; - } - - return ISIS_OK; + dl_unitdata_req_t *dur = (dl_unitdata_req_t *)dlpi_ctl; + char *dstaddr; + u_short *dstsap; + int buflen; + int rv; + + buflen = stream_get_endp(circuit->snd_stream) + LLC_LEN; + if ((size_t)buflen > sizeof(sock_buff)) { + zlog_warn( + "isis_send_pdu_bcast: sock_buff size %zu is less than " + "output pdu size %d on circuit %s", + sizeof(sock_buff), buflen, circuit->interface->name); + return ISIS_WARNING; + } + + stream_set_getp(circuit->snd_stream, 0); + + memset(dur, 0, sizeof(*dur)); + dur->dl_primitive = DL_UNITDATA_REQ; + dur->dl_dest_addr_length = ETHERADDRL + 2; + dur->dl_dest_addr_offset = sizeof(*dur); + + dstaddr = (char *)(dur + 1); + if (circuit->sap_length < 0) { + dstsap = (u_short *)(dstaddr + ETHERADDRL); + } else { + dstsap = (u_short *)dstaddr; + dstaddr += circuit->sap_length; + } + if (level == 1) + memcpy(dstaddr, ALL_L1_ISS, ETHERADDRL); + else + memcpy(dstaddr, ALL_L2_ISS, ETHERADDRL); + /* Note: DLPI SAP values are in host byte order */ + *dstsap = buflen; + + sock_buff[0] = ISO_SAP; + sock_buff[1] = ISO_SAP; + sock_buff[2] = 0x03; + memcpy(sock_buff + LLC_LEN, circuit->snd_stream->data, + stream_get_endp(circuit->snd_stream)); + rv = dlpisend(circuit->fd, dur, sizeof(*dur) + dur->dl_dest_addr_length, + sock_buff, buflen, 0); + if (rv < 0) { + zlog_warn("IS-IS dlpi: could not transmit packet on %s: %s", + circuit->interface->name, safe_strerror(errno)); + if (ERRNO_IO_RETRY(errno)) + return ISIS_WARNING; + return ISIS_ERROR; + } + + return ISIS_OK; } #endif /* ISIS_METHOD == ISIS_METHOD_DLPI */ diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c index 96cf8488d..3f532ecf8 100644 --- a/isisd/isis_dr.c +++ b/isisd/isis_dr.c @@ -1,19 +1,19 @@ /* * IS-IS Rout(e)ing protocol - isis_dr.c - * IS-IS designated router related routines + * IS-IS designated router related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -47,321 +47,306 @@ #include "isisd/isis_dr.h" #include "isisd/isis_events.h" -const char * -isis_disflag2string (int disflag) +const char *isis_disflag2string(int disflag) { - switch (disflag) - { - case ISIS_IS_NOT_DIS: - return "is not DIS"; - case ISIS_IS_DIS: - return "is DIS"; - case ISIS_WAS_DIS: - return "was DIS"; - default: - return "unknown DIS state"; - } - return NULL; /* not reached */ + switch (disflag) { + case ISIS_IS_NOT_DIS: + return "is not DIS"; + case ISIS_IS_DIS: + return "is DIS"; + case ISIS_WAS_DIS: + return "was DIS"; + default: + return "unknown DIS state"; + } + return NULL; /* not reached */ } -int -isis_run_dr_l1 (struct thread *thread) +int isis_run_dr_l1(struct thread *thread) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - if (circuit->u.bc.run_dr_elect[0]) - zlog_warn ("isis_run_dr(): run_dr_elect already set for l1"); + if (circuit->u.bc.run_dr_elect[0]) + zlog_warn("isis_run_dr(): run_dr_elect already set for l1"); - circuit->u.bc.t_run_dr[0] = NULL; - circuit->u.bc.run_dr_elect[0] = 1; + circuit->u.bc.t_run_dr[0] = NULL; + circuit->u.bc.run_dr_elect[0] = 1; - return ISIS_OK; + return ISIS_OK; } -int -isis_run_dr_l2 (struct thread *thread) +int isis_run_dr_l2(struct thread *thread) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - if (circuit->u.bc.run_dr_elect[1]) - zlog_warn ("isis_run_dr(): run_dr_elect already set for l2"); + if (circuit->u.bc.run_dr_elect[1]) + zlog_warn("isis_run_dr(): run_dr_elect already set for l2"); - circuit->u.bc.t_run_dr[1] = NULL; - circuit->u.bc.run_dr_elect[1] = 1; + circuit->u.bc.t_run_dr[1] = NULL; + circuit->u.bc.run_dr_elect[1] = 1; - return ISIS_OK; + return ISIS_OK; } -static int -isis_check_dr_change (struct isis_adjacency *adj, int level) +static int isis_check_dr_change(struct isis_adjacency *adj, int level) { - int i; - - if (adj->dis_record[level - 1].dis != - adj->dis_record[(1 * ISIS_LEVELS) + level - 1].dis) - /* was there a DIS state transition ? */ - { - adj->dischanges[level - 1]++; - /* ok rotate the history list through */ - for (i = DIS_RECORDS - 1; i > 0; i--) + int i; + + if (adj->dis_record[level - 1].dis + != adj->dis_record[(1 * ISIS_LEVELS) + level - 1].dis) + /* was there a DIS state transition ? */ { - adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis = - adj->dis_record[((i - 1) * ISIS_LEVELS) + level - 1].dis; - adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change = - adj->dis_record[((i - 1) * ISIS_LEVELS) + level - - 1].last_dis_change; + adj->dischanges[level - 1]++; + /* ok rotate the history list through */ + for (i = DIS_RECORDS - 1; i > 0; i--) { + adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis = + adj->dis_record[((i - 1) * ISIS_LEVELS) + level + - 1] + .dis; + adj->dis_record[(i * ISIS_LEVELS) + level - 1] + .last_dis_change = + adj->dis_record[((i - 1) * ISIS_LEVELS) + level + - 1] + .last_dis_change; + } } - } - return ISIS_OK; + return ISIS_OK; } -int -isis_dr_elect (struct isis_circuit *circuit, int level) +int isis_dr_elect(struct isis_circuit *circuit, int level) { - struct list *adjdb; - struct listnode *node; - struct isis_adjacency *adj, *adj_dr = NULL; - struct list *list = list_new (); - u_char own_prio; - int biggest_prio = -1; - int cmp_res, retval = ISIS_OK; - - own_prio = circuit->priority[level - 1]; - adjdb = circuit->u.bc.adjdb[level - 1]; - - if (!adjdb) - { - zlog_warn ("isis_dr_elect() adjdb == NULL"); - list_delete (list); - return ISIS_WARNING; - } - isis_adj_build_up_list (adjdb, list); - - /* - * Loop the adjacencies and find the one with the biggest priority - */ - for (ALL_LIST_ELEMENTS_RO (list, node, adj)) - { - /* clear flag for show output */ - adj->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; - adj->dis_record[level - 1].last_dis_change = time (NULL); - - if (adj->prio[level - 1] > biggest_prio) - { - biggest_prio = adj->prio[level - 1]; - adj_dr = adj; + struct list *adjdb; + struct listnode *node; + struct isis_adjacency *adj, *adj_dr = NULL; + struct list *list = list_new(); + u_char own_prio; + int biggest_prio = -1; + int cmp_res, retval = ISIS_OK; + + own_prio = circuit->priority[level - 1]; + adjdb = circuit->u.bc.adjdb[level - 1]; + + if (!adjdb) { + zlog_warn("isis_dr_elect() adjdb == NULL"); + list_delete(list); + return ISIS_WARNING; } - else if (adj->prio[level - 1] == biggest_prio) - { - /* - * Comparison of MACs breaks a tie - */ - if (adj_dr) - { - cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN); - if (cmp_res < 0) - { - adj_dr = adj; + isis_adj_build_up_list(adjdb, list); + + /* + * Loop the adjacencies and find the one with the biggest priority + */ + for (ALL_LIST_ELEMENTS_RO(list, node, adj)) { + /* clear flag for show output */ + adj->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; + adj->dis_record[level - 1].last_dis_change = time(NULL); + + if (adj->prio[level - 1] > biggest_prio) { + biggest_prio = adj->prio[level - 1]; + adj_dr = adj; + } else if (adj->prio[level - 1] == biggest_prio) { + /* + * Comparison of MACs breaks a tie + */ + if (adj_dr) { + cmp_res = memcmp(adj_dr->snpa, adj->snpa, + ETH_ALEN); + if (cmp_res < 0) { + adj_dr = adj; + } + if (cmp_res == 0) + zlog_warn( + "isis_dr_elect(): multiple adjacencies with same SNPA"); + } else { + adj_dr = adj; + } } - if (cmp_res == 0) - zlog_warn - ("isis_dr_elect(): multiple adjacencies with same SNPA"); - } - else - { - adj_dr = adj; - } } - } - - if (!adj_dr) - { - /* - * Could not find the DR - means we are alone. Resign if we were DR. - */ - if (circuit->u.bc.is_dr[level - 1]) - retval = isis_dr_resign (circuit, level); - list_delete (list); - return retval; - } - - /* - * Now we have the DR adjacency, compare it to self - */ - if (adj_dr->prio[level - 1] < own_prio || - (adj_dr->prio[level - 1] == own_prio && - memcmp (adj_dr->snpa, circuit->u.bc.snpa, ETH_ALEN) < 0)) - { - adj_dr->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; - adj_dr->dis_record[level - 1].last_dis_change = time (NULL); - - /* rotate the history log */ - for (ALL_LIST_ELEMENTS_RO (list, node, adj)) - isis_check_dr_change (adj, level); - - /* We are the DR, commence DR */ - if (circuit->u.bc.is_dr[level - 1] == 0 && listcount (list) > 0) - retval = isis_dr_commence (circuit, level); - } - else - { - /* ok we have found the DIS - lets mark the adjacency */ - /* set flag for show output */ - adj_dr->dis_record[level - 1].dis = ISIS_IS_DIS; - adj_dr->dis_record[level - 1].last_dis_change = time (NULL); - - /* now loop through a second time to check if there has been a DIS change - * if yes rotate the history log - */ - - for (ALL_LIST_ELEMENTS_RO (list, node, adj)) - isis_check_dr_change (adj, level); - - /* - * We are not DR - if we were -> resign - */ - if (circuit->u.bc.is_dr[level - 1]) - retval = isis_dr_resign (circuit, level); - } - list_delete (list); - return retval; + + if (!adj_dr) { + /* + * Could not find the DR - means we are alone. Resign if we were + * DR. + */ + if (circuit->u.bc.is_dr[level - 1]) + retval = isis_dr_resign(circuit, level); + list_delete(list); + return retval; + } + + /* + * Now we have the DR adjacency, compare it to self + */ + if (adj_dr->prio[level - 1] < own_prio + || (adj_dr->prio[level - 1] == own_prio + && memcmp(adj_dr->snpa, circuit->u.bc.snpa, ETH_ALEN) < 0)) { + adj_dr->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; + adj_dr->dis_record[level - 1].last_dis_change = time(NULL); + + /* rotate the history log */ + for (ALL_LIST_ELEMENTS_RO(list, node, adj)) + isis_check_dr_change(adj, level); + + /* We are the DR, commence DR */ + if (circuit->u.bc.is_dr[level - 1] == 0 && listcount(list) > 0) + retval = isis_dr_commence(circuit, level); + } else { + /* ok we have found the DIS - lets mark the adjacency */ + /* set flag for show output */ + adj_dr->dis_record[level - 1].dis = ISIS_IS_DIS; + adj_dr->dis_record[level - 1].last_dis_change = time(NULL); + + /* now loop through a second time to check if there has been a + * DIS change + * if yes rotate the history log + */ + + for (ALL_LIST_ELEMENTS_RO(list, node, adj)) + isis_check_dr_change(adj, level); + + /* + * We are not DR - if we were -> resign + */ + if (circuit->u.bc.is_dr[level - 1]) + retval = isis_dr_resign(circuit, level); + } + list_delete(list); + return retval; } -int -isis_dr_resign (struct isis_circuit *circuit, int level) +int isis_dr_resign(struct isis_circuit *circuit, int level) { - u_char id[ISIS_SYS_ID_LEN + 2]; + u_char id[ISIS_SYS_ID_LEN + 2]; - zlog_debug ("isis_dr_resign l%d", level); + zlog_debug("isis_dr_resign l%d", level); - circuit->u.bc.is_dr[level - 1] = 0; - circuit->u.bc.run_dr_elect[level - 1] = 0; - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[level - 1]); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - circuit->lsp_regenerate_pending[level - 1] = 0; + circuit->u.bc.is_dr[level - 1] = 0; + circuit->u.bc.run_dr_elect[level - 1] = 0; + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[level - 1]); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + circuit->lsp_regenerate_pending[level - 1] = 0; - memcpy (id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (id) = circuit->circuit_id; - LSP_FRAGMENT (id) = 0; - lsp_purge_pseudo (id, circuit, level); + memcpy(id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(id) = circuit->circuit_id; + LSP_FRAGMENT(id) = 0; + lsp_purge_pseudo(id, circuit, level); - if (level == 1) - { - memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1); + if (level == 1) { + memset(circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1); - THREAD_TIMER_OFF (circuit->t_send_csnp[0]); + THREAD_TIMER_OFF(circuit->t_send_csnp[0]); - thread_add_timer(master, isis_run_dr_l1, circuit, - 2 * circuit->hello_interval[0], - &circuit->u.bc.t_run_dr[0]); + thread_add_timer(master, isis_run_dr_l1, circuit, + 2 * circuit->hello_interval[0], + &circuit->u.bc.t_run_dr[0]); - thread_add_timer(master, send_l1_psnp, circuit, - isis_jitter(circuit->psnp_interval[level - 1], PSNP_JITTER), - &circuit->t_send_psnp[0]); - } - else - { - memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); + thread_add_timer(master, send_l1_psnp, circuit, + isis_jitter(circuit->psnp_interval[level - 1], + PSNP_JITTER), + &circuit->t_send_psnp[0]); + } else { + memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); - THREAD_TIMER_OFF (circuit->t_send_csnp[1]); + THREAD_TIMER_OFF(circuit->t_send_csnp[1]); - thread_add_timer(master, isis_run_dr_l2, circuit, - 2 * circuit->hello_interval[1], - &circuit->u.bc.t_run_dr[1]); + thread_add_timer(master, isis_run_dr_l2, circuit, + 2 * circuit->hello_interval[1], + &circuit->u.bc.t_run_dr[1]); - thread_add_timer(master, send_l2_psnp, circuit, - isis_jitter(circuit->psnp_interval[level - 1], PSNP_JITTER), - &circuit->t_send_psnp[1]); - } + thread_add_timer(master, send_l2_psnp, circuit, + isis_jitter(circuit->psnp_interval[level - 1], + PSNP_JITTER), + &circuit->t_send_psnp[1]); + } - thread_add_event(master, isis_event_dis_status_change, circuit, 0, NULL); + thread_add_event(master, isis_event_dis_status_change, circuit, 0, + NULL); - return ISIS_OK; + return ISIS_OK; } -int -isis_dr_commence (struct isis_circuit *circuit, int level) +int isis_dr_commence(struct isis_circuit *circuit, int level) { - u_char old_dr[ISIS_SYS_ID_LEN + 2]; - - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("isis_dr_commence l%d", level); - - /* Lets keep a pause in DR election */ - circuit->u.bc.run_dr_elect[level - 1] = 0; - if (level == 1) - thread_add_timer(master, isis_run_dr_l1, circuit, - 2 * circuit->hello_interval[0], - &circuit->u.bc.t_run_dr[0]); - else - thread_add_timer(master, isis_run_dr_l2, circuit, - 2 * circuit->hello_interval[1], - &circuit->u.bc.t_run_dr[1]); - circuit->u.bc.is_dr[level - 1] = 1; - - if (level == 1) - { - memcpy (old_dr, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT (old_dr) = 0; - if (LSP_PSEUDO_ID (old_dr)) - { - /* there was a dr elected, purge its LSPs from the db */ - lsp_purge_pseudo (old_dr, circuit, level); - } - memcpy (circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN); - *(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id; - - assert (circuit->circuit_id); /* must be non-zero */ - /* if (circuit->t_send_l1_psnp) - thread_cancel (circuit->t_send_l1_psnp); */ - lsp_generate_pseudo (circuit, 1); - - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]); - thread_add_timer(master, isis_run_dr_l1, circuit, - 2 * circuit->hello_interval[0], - &circuit->u.bc.t_run_dr[0]); - - thread_add_timer(master, send_l1_csnp, circuit, - isis_jitter(circuit->csnp_interval[level - 1], CSNP_JITTER), - &circuit->t_send_csnp[0]); - - } - else - { - memcpy (old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT (old_dr) = 0; - if (LSP_PSEUDO_ID (old_dr)) - { - /* there was a dr elected, purge its LSPs from the db */ - lsp_purge_pseudo (old_dr, circuit, level); + u_char old_dr[ISIS_SYS_ID_LEN + 2]; + + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("isis_dr_commence l%d", level); + + /* Lets keep a pause in DR election */ + circuit->u.bc.run_dr_elect[level - 1] = 0; + if (level == 1) + thread_add_timer(master, isis_run_dr_l1, circuit, + 2 * circuit->hello_interval[0], + &circuit->u.bc.t_run_dr[0]); + else + thread_add_timer(master, isis_run_dr_l2, circuit, + 2 * circuit->hello_interval[1], + &circuit->u.bc.t_run_dr[1]); + circuit->u.bc.is_dr[level - 1] = 1; + + if (level == 1) { + memcpy(old_dr, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(old_dr) = 0; + if (LSP_PSEUDO_ID(old_dr)) { + /* there was a dr elected, purge its LSPs from the db */ + lsp_purge_pseudo(old_dr, circuit, level); + } + memcpy(circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN); + *(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = + circuit->circuit_id; + + assert(circuit->circuit_id); /* must be non-zero */ + /* if (circuit->t_send_l1_psnp) + thread_cancel (circuit->t_send_l1_psnp); */ + lsp_generate_pseudo(circuit, 1); + + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[0]); + thread_add_timer(master, isis_run_dr_l1, circuit, + 2 * circuit->hello_interval[0], + &circuit->u.bc.t_run_dr[0]); + + thread_add_timer(master, send_l1_csnp, circuit, + isis_jitter(circuit->csnp_interval[level - 1], + CSNP_JITTER), + &circuit->t_send_csnp[0]); + + } else { + memcpy(old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(old_dr) = 0; + if (LSP_PSEUDO_ID(old_dr)) { + /* there was a dr elected, purge its LSPs from the db */ + lsp_purge_pseudo(old_dr, circuit, level); + } + memcpy(circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN); + *(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = + circuit->circuit_id; + + assert(circuit->circuit_id); /* must be non-zero */ + /* if (circuit->t_send_l1_psnp) + thread_cancel (circuit->t_send_l1_psnp); */ + lsp_generate_pseudo(circuit, 2); + + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[1]); + thread_add_timer(master, isis_run_dr_l2, circuit, + 2 * circuit->hello_interval[1], + &circuit->u.bc.t_run_dr[1]); + + thread_add_timer(master, send_l2_csnp, circuit, + isis_jitter(circuit->csnp_interval[level - 1], + CSNP_JITTER), + &circuit->t_send_csnp[1]); } - memcpy (circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN); - *(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id; - - assert (circuit->circuit_id); /* must be non-zero */ - /* if (circuit->t_send_l1_psnp) - thread_cancel (circuit->t_send_l1_psnp); */ - lsp_generate_pseudo (circuit, 2); - - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]); - thread_add_timer(master, isis_run_dr_l2, circuit, - 2 * circuit->hello_interval[1], - &circuit->u.bc.t_run_dr[1]); - - thread_add_timer(master, send_l2_csnp, circuit, - isis_jitter(circuit->csnp_interval[level - 1], CSNP_JITTER), - &circuit->t_send_csnp[1]); - } - thread_add_event(master, isis_event_dis_status_change, circuit, 0, NULL); + thread_add_event(master, isis_event_dis_status_change, circuit, 0, + NULL); - return ISIS_OK; + return ISIS_OK; } diff --git a/isisd/isis_dr.h b/isisd/isis_dr.h index 801cd0e47..ed26558b0 100644 --- a/isisd/isis_dr.h +++ b/isisd/isis_dr.h @@ -1,19 +1,19 @@ /* * IS-IS Rout(e)ing protocol - isis_dr.h - * IS-IS designated router related routines + * IS-IS designated router related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -24,19 +24,18 @@ #ifndef _ZEBRA_ISIS_DR_H #define _ZEBRA_ISIS_DR_H -int isis_run_dr_l1 (struct thread *thread); -int isis_run_dr_l2 (struct thread *thread); -int isis_dr_elect (struct isis_circuit *circuit, int level); -int isis_dr_resign (struct isis_circuit *circuit, int level); -int isis_dr_commence (struct isis_circuit *circuit, int level); -const char *isis_disflag2string (int disflag); +int isis_run_dr_l1(struct thread *thread); +int isis_run_dr_l2(struct thread *thread); +int isis_dr_elect(struct isis_circuit *circuit, int level); +int isis_dr_resign(struct isis_circuit *circuit, int level); +int isis_dr_commence(struct isis_circuit *circuit, int level); +const char *isis_disflag2string(int disflag); -enum isis_dis_state -{ - ISIS_IS_NOT_DIS, - ISIS_IS_DIS, - ISIS_WAS_DIS, - ISIS_UNKNOWN_DIS +enum isis_dis_state { + ISIS_IS_NOT_DIS, + ISIS_IS_DIS, + ISIS_WAS_DIS, + ISIS_UNKNOWN_DIS }; #endif /* _ZEBRA_ISIS_DR_H */ diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c index 35d573d30..9249ad629 100644 --- a/isisd/isis_dynhn.c +++ b/isisd/isis_dynhn.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_dynhn.c * Dynamic hostname cache * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -44,107 +44,100 @@ extern struct host host; struct list *dyn_cache = NULL; -static int dyn_cache_cleanup (struct thread *); +static int dyn_cache_cleanup(struct thread *); -void -dyn_cache_init (void) +void dyn_cache_init(void) { - if (dyn_cache == NULL) - dyn_cache = list_new (); - thread_add_timer(master, dyn_cache_cleanup, NULL, 120, &isis->t_dync_clean); - return; + if (dyn_cache == NULL) + dyn_cache = list_new(); + thread_add_timer(master, dyn_cache_cleanup, NULL, 120, + &isis->t_dync_clean); + return; } -static int -dyn_cache_cleanup (struct thread *thread) +static int dyn_cache_cleanup(struct thread *thread) { - struct listnode *node, *nnode; - struct isis_dynhn *dyn; - time_t now = time (NULL); + struct listnode *node, *nnode; + struct isis_dynhn *dyn; + time_t now = time(NULL); - isis->t_dync_clean = NULL; + isis->t_dync_clean = NULL; - for (ALL_LIST_ELEMENTS (dyn_cache, node, nnode, dyn)) - { - if ((now - dyn->refresh) < MAX_LSP_LIFETIME) - continue; + for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) { + if ((now - dyn->refresh) < MAX_LSP_LIFETIME) + continue; - list_delete_node (dyn_cache, node); - XFREE (MTYPE_ISIS_DYNHN, dyn); - } + list_delete_node(dyn_cache, node); + XFREE(MTYPE_ISIS_DYNHN, dyn); + } - thread_add_timer(master, dyn_cache_cleanup, NULL, 120, &isis->t_dync_clean); - return ISIS_OK; + thread_add_timer(master, dyn_cache_cleanup, NULL, 120, + &isis->t_dync_clean); + return ISIS_OK; } -struct isis_dynhn * -dynhn_find_by_id (const u_char * id) +struct isis_dynhn *dynhn_find_by_id(const u_char *id) { - struct listnode *node = NULL; - struct isis_dynhn *dyn = NULL; + struct listnode *node = NULL; + struct isis_dynhn *dyn = NULL; - for (ALL_LIST_ELEMENTS_RO (dyn_cache, node, dyn)) - if (memcmp (dyn->id, id, ISIS_SYS_ID_LEN) == 0) - return dyn; + for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) + if (memcmp(dyn->id, id, ISIS_SYS_ID_LEN) == 0) + return dyn; - return NULL; + return NULL; } -struct isis_dynhn * -dynhn_find_by_name (const char *hostname) +struct isis_dynhn *dynhn_find_by_name(const char *hostname) { - struct listnode *node = NULL; - struct isis_dynhn *dyn = NULL; + struct listnode *node = NULL; + struct isis_dynhn *dyn = NULL; - for (ALL_LIST_ELEMENTS_RO (dyn_cache, node, dyn)) - if (strncmp ((char *)dyn->name.name, hostname, 255) == 0) - return dyn; + for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) + if (strncmp((char *)dyn->name.name, hostname, 255) == 0) + return dyn; - return NULL; + return NULL; } -void -isis_dynhn_insert (const u_char * id, struct hostname *hostname, int level) +void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level) { - struct isis_dynhn *dyn; - - dyn = dynhn_find_by_id (id); - if (dyn) - { - memcpy (&dyn->name, hostname, hostname->namelen + 1); - memcpy (dyn->id, id, ISIS_SYS_ID_LEN); - dyn->refresh = time (NULL); - return; - } - dyn = XCALLOC (MTYPE_ISIS_DYNHN, sizeof (struct isis_dynhn)); - if (!dyn) - { - zlog_warn ("isis_dynhn_insert(): out of memory!"); - return; - } - - /* we also copy the length */ - memcpy (&dyn->name, hostname, hostname->namelen + 1); - memcpy (dyn->id, id, ISIS_SYS_ID_LEN); - dyn->refresh = time (NULL); - dyn->level = level; - - listnode_add (dyn_cache, dyn); - - return; + struct isis_dynhn *dyn; + + dyn = dynhn_find_by_id(id); + if (dyn) { + memcpy(&dyn->name, hostname, hostname->namelen + 1); + memcpy(dyn->id, id, ISIS_SYS_ID_LEN); + dyn->refresh = time(NULL); + return; + } + dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn)); + if (!dyn) { + zlog_warn("isis_dynhn_insert(): out of memory!"); + return; + } + + /* we also copy the length */ + memcpy(&dyn->name, hostname, hostname->namelen + 1); + memcpy(dyn->id, id, ISIS_SYS_ID_LEN); + dyn->refresh = time(NULL); + dyn->level = level; + + listnode_add(dyn_cache, dyn); + + return; } -void -isis_dynhn_remove (const u_char * id) +void isis_dynhn_remove(const u_char *id) { - struct isis_dynhn *dyn; - - dyn = dynhn_find_by_id (id); - if (!dyn) - return; - listnode_delete (dyn_cache, dyn); - XFREE (MTYPE_ISIS_DYNHN, dyn); - return; + struct isis_dynhn *dyn; + + dyn = dynhn_find_by_id(id); + if (!dyn) + return; + listnode_delete(dyn_cache, dyn); + XFREE(MTYPE_ISIS_DYNHN, dyn); + return; } /* @@ -153,19 +146,19 @@ isis_dynhn_remove (const u_char * id) * 2 0000.0000.0002 bar-gw * * 0000.0000.0004 this-gw */ -void -dynhn_print_all (struct vty *vty) +void dynhn_print_all(struct vty *vty) { - struct listnode *node; - struct isis_dynhn *dyn; - - vty_out (vty, "Level System ID Dynamic Hostname\n"); - for (ALL_LIST_ELEMENTS_RO (dyn_cache, node, dyn)) - { - vty_out (vty, "%-7d", dyn->level); - vty_out (vty, "%-15s%-15s\n", sysid_print (dyn->id),dyn->name.name); - } - - vty_out (vty, " * %s %s\n", sysid_print (isis->sysid),unix_hostname()); - return; + struct listnode *node; + struct isis_dynhn *dyn; + + vty_out(vty, "Level System ID Dynamic Hostname\n"); + for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) { + vty_out(vty, "%-7d", dyn->level); + vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id), + dyn->name.name); + } + + vty_out(vty, " * %s %s\n", sysid_print(isis->sysid), + unix_hostname()); + return; } diff --git a/isisd/isis_dynhn.h b/isisd/isis_dynhn.h index c36d9a009..f3ca94d40 100644 --- a/isisd/isis_dynhn.h +++ b/isisd/isis_dynhn.h @@ -3,17 +3,17 @@ * Dynamic hostname cache * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -23,19 +23,18 @@ #ifndef _ZEBRA_ISIS_DYNHN_H #define _ZEBRA_ISIS_DYNHN_H -struct isis_dynhn -{ - u_char id[ISIS_SYS_ID_LEN]; - struct hostname name; - time_t refresh; - int level; +struct isis_dynhn { + u_char id[ISIS_SYS_ID_LEN]; + struct hostname name; + time_t refresh; + int level; }; -void dyn_cache_init (void); -void isis_dynhn_insert (const u_char * id, struct hostname *hostname, int level); -void isis_dynhn_remove (const u_char * id); -struct isis_dynhn *dynhn_find_by_id (const u_char * id); -struct isis_dynhn *dynhn_find_by_name (const char *hostname); -void dynhn_print_all (struct vty *vty); +void dyn_cache_init(void); +void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level); +void isis_dynhn_remove(const u_char *id); +struct isis_dynhn *dynhn_find_by_id(const u_char *id); +struct isis_dynhn *dynhn_find_by_name(const char *hostname); +void dynhn_print_all(struct vty *vty); #endif /* _ZEBRA_ISIS_DYNHN_H */ diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 8011d2db9..9af256ba3 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isis_events.h + * IS-IS Rout(e)ing protocol - isis_events.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -50,7 +50,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_spf.h" -/* debug isis-spf spf-events +/* debug isis-spf spf-events 4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4 4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2 4w4d: ISIS-Spf (tlt): L2, new LSP 0 DEAD.BEEF.0043.00-00 @@ -58,222 +58,212 @@ 4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844 */ -void -isis_event_circuit_state_change (struct isis_circuit *circuit, - struct isis_area *area, int up) +void isis_event_circuit_state_change(struct isis_circuit *circuit, + struct isis_area *area, int up) { - area->circuit_state_changes++; + area->circuit_state_changes++; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) circuit %s", area->area_tag, - up ? "up" : "down"); + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) circuit %s", area->area_tag, + up ? "up" : "down"); - /* - * Regenerate LSPs this affects - */ - lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); + /* + * Regenerate LSPs this affects + */ + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0); - return; + return; } -static void -circuit_commence_level (struct isis_circuit *circuit, int level) +static void circuit_commence_level(struct isis_circuit *circuit, int level) { - if (level == 1) - { - if (! circuit->is_passive) - thread_add_timer(master, send_l1_psnp, circuit, - isis_jitter(circuit->psnp_interval[0], PSNP_JITTER), - &circuit->t_send_psnp[0]); - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - thread_add_timer(master, isis_run_dr_l1, circuit, - 2 * circuit->hello_interval[0], - &circuit->u.bc.t_run_dr[0]); - - thread_add_timer(master, send_lan_l1_hello, circuit, - isis_jitter(circuit->hello_interval[0], IIH_JITTER), - &circuit->u.bc.t_send_lan_hello[0]); - - circuit->u.bc.lan_neighs[0] = list_new (); + if (level == 1) { + if (!circuit->is_passive) + thread_add_timer(master, send_l1_psnp, circuit, + isis_jitter(circuit->psnp_interval[0], + PSNP_JITTER), + &circuit->t_send_psnp[0]); + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + thread_add_timer(master, isis_run_dr_l1, circuit, + 2 * circuit->hello_interval[0], + &circuit->u.bc.t_run_dr[0]); + + thread_add_timer(master, send_lan_l1_hello, circuit, + isis_jitter(circuit->hello_interval[0], + IIH_JITTER), + &circuit->u.bc.t_send_lan_hello[0]); + + circuit->u.bc.lan_neighs[0] = list_new(); + } + } else { + if (!circuit->is_passive) + thread_add_timer(master, send_l2_psnp, circuit, + isis_jitter(circuit->psnp_interval[1], + PSNP_JITTER), + &circuit->t_send_psnp[1]); + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + thread_add_timer(master, isis_run_dr_l2, circuit, + 2 * circuit->hello_interval[1], + &circuit->u.bc.t_run_dr[1]); + + thread_add_timer(master, send_lan_l2_hello, circuit, + isis_jitter(circuit->hello_interval[1], + IIH_JITTER), + &circuit->u.bc.t_send_lan_hello[1]); + + circuit->u.bc.lan_neighs[1] = list_new(); + } } - } - else - { - if (! circuit->is_passive) - thread_add_timer(master, send_l2_psnp, circuit, - isis_jitter(circuit->psnp_interval[1], PSNP_JITTER), - &circuit->t_send_psnp[1]); - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - thread_add_timer(master, isis_run_dr_l2, circuit, - 2 * circuit->hello_interval[1], - &circuit->u.bc.t_run_dr[1]); - - thread_add_timer(master, send_lan_l2_hello, circuit, - isis_jitter(circuit->hello_interval[1], IIH_JITTER), - &circuit->u.bc.t_send_lan_hello[1]); - - circuit->u.bc.lan_neighs[1] = list_new (); - } - } - return; + return; } -static void -circuit_resign_level (struct isis_circuit *circuit, int level) +static void circuit_resign_level(struct isis_circuit *circuit, int level) { - int idx = level - 1; - - THREAD_TIMER_OFF (circuit->t_send_csnp[idx]); - THREAD_TIMER_OFF (circuit->t_send_psnp[idx]); - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[idx]); - THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[idx]); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[idx]); - circuit->lsp_regenerate_pending[idx] = 0; - circuit->u.bc.run_dr_elect[idx] = 0; - if (circuit->u.bc.lan_neighs[idx] != NULL) { - list_delete (circuit->u.bc.lan_neighs[idx]); - circuit->u.bc.lan_neighs[idx] = NULL; - } - } - - return; + int idx = level - 1; + + THREAD_TIMER_OFF(circuit->t_send_csnp[idx]); + THREAD_TIMER_OFF(circuit->t_send_psnp[idx]); + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[idx]); + THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[idx]); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]); + circuit->lsp_regenerate_pending[idx] = 0; + circuit->u.bc.run_dr_elect[idx] = 0; + if (circuit->u.bc.lan_neighs[idx] != NULL) { + list_delete(circuit->u.bc.lan_neighs[idx]); + circuit->u.bc.lan_neighs[idx] = NULL; + } + } + + return; } -void -isis_circuit_is_type_set (struct isis_circuit *circuit, int newtype) +void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype) { - if (circuit->state != C_STATE_UP) - { - circuit->is_type = newtype; - return; - } - - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) circuit type change %s -> %s", - circuit->area->area_tag, - circuit_t2string (circuit->is_type), - circuit_t2string (newtype)); - - if (circuit->is_type == newtype) - return; /* No change */ - - if (!(newtype & circuit->area->is_type)) - { - zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because" - " area is %s", circuit->area->area_tag, - circuit_t2string (newtype), - circuit_t2string (circuit->area->is_type)); - return; - } - - if (! circuit->is_passive) - { - switch (circuit->is_type) - { - case IS_LEVEL_1: - if (newtype == IS_LEVEL_2) - circuit_resign_level (circuit, 1); - circuit_commence_level (circuit, 2); - break; - case IS_LEVEL_1_AND_2: - if (newtype == IS_LEVEL_1) - circuit_resign_level (circuit, 2); - else - circuit_resign_level (circuit, 1); - break; - case IS_LEVEL_2: - if (newtype == IS_LEVEL_1) - circuit_resign_level (circuit, 2); - circuit_commence_level (circuit, 1); - break; - default: - break; - } - } - - circuit->is_type = newtype; - lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); - - return; + if (circuit->state != C_STATE_UP) { + circuit->is_type = newtype; + return; + } + + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) circuit type change %s -> %s", + circuit->area->area_tag, + circuit_t2string(circuit->is_type), + circuit_t2string(newtype)); + + if (circuit->is_type == newtype) + return; /* No change */ + + if (!(newtype & circuit->area->is_type)) { + zlog_err( + "ISIS-Evt (%s) circuit type change - invalid level %s because" + " area is %s", + circuit->area->area_tag, circuit_t2string(newtype), + circuit_t2string(circuit->area->is_type)); + return; + } + + if (!circuit->is_passive) { + switch (circuit->is_type) { + case IS_LEVEL_1: + if (newtype == IS_LEVEL_2) + circuit_resign_level(circuit, 1); + circuit_commence_level(circuit, 2); + break; + case IS_LEVEL_1_AND_2: + if (newtype == IS_LEVEL_1) + circuit_resign_level(circuit, 2); + else + circuit_resign_level(circuit, 1); + break; + case IS_LEVEL_2: + if (newtype == IS_LEVEL_1) + circuit_resign_level(circuit, 2); + circuit_commence_level(circuit, 1); + break; + default: + break; + } + } + + circuit->is_type = newtype; + lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); + + return; } - /* 04/18/2002 by Gwak. */ - /************************************************************************** - * - * EVENTS for LSP generation - * - * 1) an Adajacency or Circuit Up/Down event - * 2) a chnage in Circuit metric - * 3) a change in Reachable Address metric - * 4) a change in manualAreaAddresses - * 5) a change in systemID - * 6) a change in DIS status - * 7) a chnage in the waiting status - * - * *********************************************************************** - * - * current support event - * - * 1) Adjacency Up/Down event - * 6) a change in DIS status - * - * ***********************************************************************/ - -void -isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate) +/* 04/18/2002 by Gwak. */ +/************************************************************************** + * + * EVENTS for LSP generation + * + * 1) an Adajacency or Circuit Up/Down event + * 2) a chnage in Circuit metric + * 3) a change in Reachable Address metric + * 4) a change in manualAreaAddresses + * 5) a change in systemID + * 6) a change in DIS status + * 7) a chnage in the waiting status + * + * *********************************************************************** + * + * current support event + * + * 1) Adjacency Up/Down event + * 6) a change in DIS status + * + * ***********************************************************************/ + +void isis_event_adjacency_state_change(struct isis_adjacency *adj, int newstate) { - /* adjacency state change event. - * - the only proto-type was supported */ + /* adjacency state change event. + * - the only proto-type was supported */ - /* invalid arguments */ - if (!adj || !adj->circuit || !adj->circuit->area) - return; + /* invalid arguments */ + if (!adj || !adj->circuit || !adj->circuit->area) + return; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) Adjacency State change", - adj->circuit->area->area_tag); + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) Adjacency State change", + adj->circuit->area->area_tag); - /* LSP generation again */ - lsp_regenerate_schedule (adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); + /* LSP generation again */ + lsp_regenerate_schedule(adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); - return; + return; } /* events supporting code */ -int -isis_event_dis_status_change (struct thread *thread) +int isis_event_dis_status_change(struct thread *thread) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - circuit = THREAD_ARG (thread); + circuit = THREAD_ARG(thread); - /* invalid arguments */ - if (!circuit || !circuit->area) - return 0; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag); + /* invalid arguments */ + if (!circuit || !circuit->area) + return 0; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) DIS status change", + circuit->area->area_tag); - /* LSP generation again */ - lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); + /* LSP generation again */ + lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); - return 0; + return 0; } -void -isis_event_auth_failure (char *area_tag, const char *error_string, u_char *sysid) +void isis_event_auth_failure(char *area_tag, const char *error_string, + u_char *sysid) { - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) Authentication failure %s from %s", - area_tag, error_string, sysid_print (sysid)); + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) Authentication failure %s from %s", + area_tag, error_string, sysid_print(sysid)); - return; + return; } diff --git a/isisd/isis_events.h b/isisd/isis_events.h index e9aa05db7..0ed2059c6 100644 --- a/isisd/isis_events.h +++ b/isisd/isis_events.h @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isis_events.h + * IS-IS Rout(e)ing protocol - isis_events.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -25,17 +25,16 @@ /* * Events related to circuit */ -void isis_event_circuit_state_change (struct isis_circuit *circuit, - struct isis_area *area, int state); -void isis_event_circuit_type_change (struct isis_circuit *circuit, - int newtype); +void isis_event_circuit_state_change(struct isis_circuit *circuit, + struct isis_area *area, int state); +void isis_event_circuit_type_change(struct isis_circuit *circuit, int newtype); /* * Events related to adjacencies */ -void isis_event_adjacency_state_change (struct isis_adjacency *adj, - int newstate); +void isis_event_adjacency_state_change(struct isis_adjacency *adj, + int newstate); -int isis_event_dis_status_change (struct thread *thread); +int isis_event_dis_status_change(struct thread *thread); /* * Error events @@ -43,7 +42,7 @@ int isis_event_dis_status_change (struct thread *thread); #define AUTH_ERROR_TYPE_LSP 3 #define AUTH_ERROR_TYPE_SNP 2 #define AUTH_ERROR_TYPE_HELLO 1 -void isis_event_auth_failure (char *area_tag, const char *error_string, - u_char *sysid); +void isis_event_auth_failure(char *area_tag, const char *error_string, + u_char *sysid); #endif /* _ZEBRA_ISIS_EVENTS_H */ diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c index 6c88cfeda..e28d90d3d 100644 --- a/isisd/isis_flags.c +++ b/isisd/isis_flags.c @@ -3,17 +3,17 @@ * Routines for manipulation of SSN and SRM flags * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -29,58 +29,49 @@ #include "isisd/isis_common.h" #include "isisd/isis_flags.h" -void -flags_initialize (struct flags *flags) +void flags_initialize(struct flags *flags) { - flags->maxindex = 0; - flags->free_idcs = NULL; + flags->maxindex = 0; + flags->free_idcs = NULL; } -long int -flags_get_index (struct flags *flags) +long int flags_get_index(struct flags *flags) { - struct listnode *node; - long int index; + struct listnode *node; + long int index; - if (flags->free_idcs == NULL || flags->free_idcs->count == 0) - { - index = flags->maxindex++; - } - else - { - node = listhead (flags->free_idcs); - index = (long int) listgetdata (node); - listnode_delete (flags->free_idcs, (void *) index); - index--; - } + if (flags->free_idcs == NULL || flags->free_idcs->count == 0) { + index = flags->maxindex++; + } else { + node = listhead(flags->free_idcs); + index = (long int)listgetdata(node); + listnode_delete(flags->free_idcs, (void *)index); + index--; + } - return index; + return index; } -void -flags_free_index (struct flags *flags, long int index) +void flags_free_index(struct flags *flags, long int index) { - if (index + 1 == flags->maxindex) - { - flags->maxindex--; - return; - } + if (index + 1 == flags->maxindex) { + flags->maxindex--; + return; + } - if (flags->free_idcs == NULL) - { - flags->free_idcs = list_new (); - } + if (flags->free_idcs == NULL) { + flags->free_idcs = list_new(); + } - listnode_add (flags->free_idcs, (void *) (index + 1)); + listnode_add(flags->free_idcs, (void *)(index + 1)); - return; + return; } -int -flags_any_set (u_int32_t * flags) +int flags_any_set(u_int32_t *flags) { - u_int32_t zero[ISIS_MAX_CIRCUITS]; - memset (zero, 0x00, ISIS_MAX_CIRCUITS * 4); + u_int32_t zero[ISIS_MAX_CIRCUITS]; + memset(zero, 0x00, ISIS_MAX_CIRCUITS * 4); - return bcmp (flags, zero, ISIS_MAX_CIRCUITS * 4); + return bcmp(flags, zero, ISIS_MAX_CIRCUITS * 4); } diff --git a/isisd/isis_flags.h b/isisd/isis_flags.h index ba11cf42b..c57f77880 100644 --- a/isisd/isis_flags.h +++ b/isisd/isis_flags.h @@ -3,17 +3,17 @@ * Routines for manipulation of SSN and SRM flags * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -31,38 +31,37 @@ /* * Flags structure for SSN and SRM flags */ -struct flags -{ - int maxindex; - struct list *free_idcs; +struct flags { + int maxindex; + struct list *free_idcs; }; -void flags_initialize (struct flags *flags); -long int flags_get_index (struct flags *flags); -void flags_free_index (struct flags *flags, long int index); -int flags_any_set (u_int32_t * flags); +void flags_initialize(struct flags *flags); +long int flags_get_index(struct flags *flags); +void flags_free_index(struct flags *flags, long int index); +int flags_any_set(u_int32_t *flags); -#define ISIS_SET_FLAG(F,C) \ - { \ - F[C->idx>>5] |= (1<<(C->idx & 0x1F)); \ - } +#define ISIS_SET_FLAG(F, C) \ + { \ + F[C->idx >> 5] |= (1 << (C->idx & 0x1F)); \ + } -#define ISIS_CLEAR_FLAG(F,C) \ - { \ - F[C->idx>>5] &= ~(1<<(C->idx & 0x1F)); \ - } +#define ISIS_CLEAR_FLAG(F, C) \ + { \ + F[C->idx >> 5] &= ~(1 << (C->idx & 0x1F)); \ + } #define ISIS_CHECK_FLAG(F, C) (F[(C)->idx>>5] & (1<<(C->idx & 0x1F))) /* sets all u_32int_t flags to 1 */ -#define ISIS_FLAGS_SET_ALL(FLAGS) \ - { \ - memset(FLAGS,0xFF,ISIS_MAX_CIRCUITS*4); \ - } +#define ISIS_FLAGS_SET_ALL(FLAGS) \ + { \ + memset(FLAGS, 0xFF, ISIS_MAX_CIRCUITS * 4); \ + } -#define ISIS_FLAGS_CLEAR_ALL(FLAGS) \ - { \ - memset(FLAGS,0x00,ISIS_MAX_CIRCUITS*4); \ - } +#define ISIS_FLAGS_CLEAR_ALL(FLAGS) \ + { \ + memset(FLAGS, 0x00, ISIS_MAX_CIRCUITS * 4); \ + } #endif /* _ZEBRA_ISIS_FLAGS_H */ diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index ed376058b..40c6141ab 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -3,18 +3,18 @@ * LSP processing * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program 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 of the License, or (at your option) + * This program 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 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -56,2214 +56,2288 @@ #include "isisd/isis_mt.h" /* staticly assigned vars for printing purposes */ -char lsp_bits_string[200]; /* FIXME: enough ? */ +char lsp_bits_string[200]; /* FIXME: enough ? */ -static int lsp_l1_refresh (struct thread *thread); -static int lsp_l2_refresh (struct thread *thread); -static int lsp_l1_refresh_pseudo (struct thread *thread); -static int lsp_l2_refresh_pseudo (struct thread *thread); +static int lsp_l1_refresh(struct thread *thread); +static int lsp_l2_refresh(struct thread *thread); +static int lsp_l1_refresh_pseudo(struct thread *thread); +static int lsp_l2_refresh_pseudo(struct thread *thread); -int -lsp_id_cmp (u_char * id1, u_char * id2) +int lsp_id_cmp(u_char *id1, u_char *id2) { - return memcmp (id1, id2, ISIS_SYS_ID_LEN + 2); + return memcmp(id1, id2, ISIS_SYS_ID_LEN + 2); } -dict_t * -lsp_db_init (void) +dict_t *lsp_db_init(void) { - dict_t *dict; + dict_t *dict; - dict = dict_create (DICTCOUNT_T_MAX, (dict_comp_t) lsp_id_cmp); + dict = dict_create(DICTCOUNT_T_MAX, (dict_comp_t)lsp_id_cmp); - return dict; + return dict; } -struct isis_lsp * -lsp_search (u_char * id, dict_t * lspdb) +struct isis_lsp *lsp_search(u_char *id, dict_t *lspdb) { - dnode_t *node; + dnode_t *node; #ifdef EXTREME_DEBUG - dnode_t *dn; - - zlog_debug ("searching db"); - for (dn = dict_first (lspdb); dn; dn = dict_next (lspdb, dn)) - { - zlog_debug ("%s\t%pX", rawlspid_print ((u_char *) dnode_getkey (dn)), - dnode_get (dn)); - } + dnode_t *dn; + + zlog_debug("searching db"); + for (dn = dict_first(lspdb); dn; dn = dict_next(lspdb, dn)) { + zlog_debug("%s\t%pX", + rawlspid_print((u_char *)dnode_getkey(dn)), + dnode_get(dn)); + } #endif /* EXTREME DEBUG */ - node = dict_lookup (lspdb, id); + node = dict_lookup(lspdb, id); - if (node) - return (struct isis_lsp *) dnode_get (node); + if (node) + return (struct isis_lsp *)dnode_get(node); - return NULL; + return NULL; } -static void -lsp_clear_data (struct isis_lsp *lsp) +static void lsp_clear_data(struct isis_lsp *lsp) { - if (!lsp) - return; - - if (lsp->tlv_data.hostname) - isis_dynhn_remove (lsp->lsp_header->lsp_id); - - if (lsp->own_lsp) - { - if (lsp->tlv_data.nlpids) - XFREE (MTYPE_ISIS_TLV, lsp->tlv_data.nlpids); - if (lsp->tlv_data.hostname) - XFREE (MTYPE_ISIS_TLV, lsp->tlv_data.hostname); - if (lsp->tlv_data.router_id) - XFREE (MTYPE_ISIS_TLV, lsp->tlv_data.router_id); - } - - free_tlvs (&lsp->tlv_data); + if (!lsp) + return; + + if (lsp->tlv_data.hostname) + isis_dynhn_remove(lsp->lsp_header->lsp_id); + + if (lsp->own_lsp) { + if (lsp->tlv_data.nlpids) + XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.nlpids); + if (lsp->tlv_data.hostname) + XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.hostname); + if (lsp->tlv_data.router_id) + XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.router_id); + } + + free_tlvs(&lsp->tlv_data); } -static void -lsp_destroy (struct isis_lsp *lsp) +static void lsp_destroy(struct isis_lsp *lsp) { - struct listnode *cnode, *lnode, *lnnode; - struct isis_lsp *lsp_in_list; - struct isis_circuit *circuit; - - if (!lsp) - return; - - if (lsp->area->circuit_list) { - for (ALL_LIST_ELEMENTS_RO (lsp->area->circuit_list, cnode, circuit)) - { - if (circuit->lsp_queue == NULL) - continue; - for (ALL_LIST_ELEMENTS (circuit->lsp_queue, lnode, lnnode, lsp_in_list)) - if (lsp_in_list == lsp) - list_delete_node(circuit->lsp_queue, lnode); - } - } - ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); - ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags); - - lsp_clear_data (lsp); - - if (LSP_FRAGMENT (lsp->lsp_header->lsp_id) == 0 && lsp->lspu.frags) - { - list_delete (lsp->lspu.frags); - lsp->lspu.frags = NULL; - } - - isis_spf_schedule (lsp->area, lsp->level); - - if (lsp->pdu) - stream_free (lsp->pdu); - XFREE (MTYPE_ISIS_LSP, lsp); + struct listnode *cnode, *lnode, *lnnode; + struct isis_lsp *lsp_in_list; + struct isis_circuit *circuit; + + if (!lsp) + return; + + if (lsp->area->circuit_list) { + for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, + circuit)) { + if (circuit->lsp_queue == NULL) + continue; + for (ALL_LIST_ELEMENTS(circuit->lsp_queue, lnode, + lnnode, lsp_in_list)) + if (lsp_in_list == lsp) + list_delete_node(circuit->lsp_queue, + lnode); + } + } + ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); + ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + + lsp_clear_data(lsp); + + if (LSP_FRAGMENT(lsp->lsp_header->lsp_id) == 0 && lsp->lspu.frags) { + list_delete(lsp->lspu.frags); + lsp->lspu.frags = NULL; + } + + isis_spf_schedule(lsp->area, lsp->level); + + if (lsp->pdu) + stream_free(lsp->pdu); + XFREE(MTYPE_ISIS_LSP, lsp); } -void -lsp_db_destroy (dict_t * lspdb) +void lsp_db_destroy(dict_t *lspdb) { - dnode_t *dnode, *next; - struct isis_lsp *lsp; - - dnode = dict_first (lspdb); - while (dnode) - { - next = dict_next (lspdb, dnode); - lsp = dnode_get (dnode); - lsp_destroy (lsp); - dict_delete_free (lspdb, dnode); - dnode = next; - } - - dict_free (lspdb); - - return; + dnode_t *dnode, *next; + struct isis_lsp *lsp; + + dnode = dict_first(lspdb); + while (dnode) { + next = dict_next(lspdb, dnode); + lsp = dnode_get(dnode); + lsp_destroy(lsp); + dict_delete_free(lspdb, dnode); + dnode = next; + } + + dict_free(lspdb); + + return; } /* * Remove all the frags belonging to the given lsp */ -static void -lsp_remove_frags (struct list *frags, dict_t * lspdb) +static void lsp_remove_frags(struct list *frags, dict_t *lspdb) { - dnode_t *dnode; - struct listnode *lnode, *lnnode; - struct isis_lsp *lsp; - - for (ALL_LIST_ELEMENTS (frags, lnode, lnnode, lsp)) - { - dnode = dict_lookup (lspdb, lsp->lsp_header->lsp_id); - lsp_destroy (lsp); - dnode_destroy (dict_delete (lspdb, dnode)); - } + dnode_t *dnode; + struct listnode *lnode, *lnnode; + struct isis_lsp *lsp; + + for (ALL_LIST_ELEMENTS(frags, lnode, lnnode, lsp)) { + dnode = dict_lookup(lspdb, lsp->lsp_header->lsp_id); + lsp_destroy(lsp); + dnode_destroy(dict_delete(lspdb, dnode)); + } - list_delete_all_node (frags); + list_delete_all_node(frags); - return; + return; } -void -lsp_search_and_destroy (u_char * id, dict_t * lspdb) +void lsp_search_and_destroy(u_char *id, dict_t *lspdb) { - dnode_t *node; - struct isis_lsp *lsp; - - node = dict_lookup (lspdb, id); - if (node) - { - node = dict_delete (lspdb, node); - lsp = dnode_get (node); - /* - * If this is a zero lsp, remove all the frags now - */ - if (LSP_FRAGMENT (lsp->lsp_header->lsp_id) == 0) - { - if (lsp->lspu.frags) - lsp_remove_frags (lsp->lspu.frags, lspdb); - } - else - { - /* - * else just remove this frag, from the zero lsps' frag list - */ - if (lsp->lspu.zero_lsp && lsp->lspu.zero_lsp->lspu.frags) - listnode_delete (lsp->lspu.zero_lsp->lspu.frags, lsp); - } - lsp_destroy (lsp); - dnode_destroy (node); - } + dnode_t *node; + struct isis_lsp *lsp; + + node = dict_lookup(lspdb, id); + if (node) { + node = dict_delete(lspdb, node); + lsp = dnode_get(node); + /* + * If this is a zero lsp, remove all the frags now + */ + if (LSP_FRAGMENT(lsp->lsp_header->lsp_id) == 0) { + if (lsp->lspu.frags) + lsp_remove_frags(lsp->lspu.frags, lspdb); + } else { + /* + * else just remove this frag, from the zero lsps' frag + * list + */ + if (lsp->lspu.zero_lsp + && lsp->lspu.zero_lsp->lspu.frags) + listnode_delete(lsp->lspu.zero_lsp->lspu.frags, + lsp); + } + lsp_destroy(lsp); + dnode_destroy(node); + } } /* * Compares a LSP to given values * Params are given in net order */ -int -lsp_compare (char *areatag, struct isis_lsp *lsp, u_int32_t seq_num, - u_int16_t checksum, u_int16_t rem_lifetime) +int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num, + u_int16_t checksum, u_int16_t rem_lifetime) { - /* no point in double ntohl on seqnum */ - if (lsp->lsp_header->seq_num == seq_num && - lsp->lsp_header->checksum == checksum && - /*comparing with 0, no need to do ntohl */ - ((lsp->lsp_header->rem_lifetime == 0 && rem_lifetime == 0) || - (lsp->lsp_header->rem_lifetime != 0 && rem_lifetime != 0))) - { - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x," - " lifetime %us", - areatag, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime)); - zlog_debug ("ISIS-Snp (%s): is equal to ours seq 0x%08x," - " cksum 0x%04x, lifetime %us", - areatag, - ntohl (seq_num), ntohs (checksum), ntohs (rem_lifetime)); - } - return LSP_EQUAL; - } - - /* - * LSPs with identical checksums should only be treated as newer if: - * a) The current LSP has a remaining lifetime != 0 and the other LSP has a - * remaining lifetime == 0. In this case, we should participate in the purge - * and should not treat the current LSP with remaining lifetime == 0 as older. - * b) The LSP has an incorrect checksum. In this case, we need to react as given - * in 7.3.16.2. - */ - if (ntohl (seq_num) > ntohl (lsp->lsp_header->seq_num) - || (ntohl(seq_num) == ntohl(lsp->lsp_header->seq_num) - && ( (lsp->lsp_header->rem_lifetime != 0 - && rem_lifetime == 0) - || lsp->lsp_header->checksum != checksum))) - { - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x," - " lifetime %us", - areatag, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (seq_num), ntohs (checksum), ntohs (rem_lifetime)); - zlog_debug ("ISIS-Snp (%s): is newer than ours seq 0x%08x, " - "cksum 0x%04x, lifetime %us", - areatag, - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime)); - } - return LSP_NEWER; - } - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug - ("ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x, lifetime %us", - areatag, rawlspid_print (lsp->lsp_header->lsp_id), ntohl (seq_num), - ntohs (checksum), ntohs (rem_lifetime)); - zlog_debug ("ISIS-Snp (%s): is older than ours seq 0x%08x," - " cksum 0x%04x, lifetime %us", areatag, - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime)); - } - - return LSP_OLDER; + /* no point in double ntohl on seqnum */ + if (lsp->lsp_header->seq_num == seq_num + && lsp->lsp_header->checksum == checksum && + /*comparing with 0, no need to do ntohl */ + ((lsp->lsp_header->rem_lifetime == 0 && rem_lifetime == 0) + || (lsp->lsp_header->rem_lifetime != 0 && rem_lifetime != 0))) { + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x," + " lifetime %us", + areatag, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime)); + zlog_debug( + "ISIS-Snp (%s): is equal to ours seq 0x%08x," + " cksum 0x%04x, lifetime %us", + areatag, ntohl(seq_num), ntohs(checksum), + ntohs(rem_lifetime)); + } + return LSP_EQUAL; + } + + /* + * LSPs with identical checksums should only be treated as newer if: + * a) The current LSP has a remaining lifetime != 0 and the other LSP + * has a + * remaining lifetime == 0. In this case, we should participate in + * the purge + * and should not treat the current LSP with remaining lifetime == 0 + * as older. + * b) The LSP has an incorrect checksum. In this case, we need to react + * as given + * in 7.3.16.2. + */ + if (ntohl(seq_num) > ntohl(lsp->lsp_header->seq_num) + || (ntohl(seq_num) == ntohl(lsp->lsp_header->seq_num) + && ((lsp->lsp_header->rem_lifetime != 0 && rem_lifetime == 0) + || lsp->lsp_header->checksum != checksum))) { + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x," + " lifetime %us", + areatag, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(seq_num), ntohs(checksum), + ntohs(rem_lifetime)); + zlog_debug( + "ISIS-Snp (%s): is newer than ours seq 0x%08x, " + "cksum 0x%04x, lifetime %us", + areatag, ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime)); + } + return LSP_NEWER; + } + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x, lifetime %us", + areatag, rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(seq_num), ntohs(checksum), ntohs(rem_lifetime)); + zlog_debug( + "ISIS-Snp (%s): is older than ours seq 0x%08x," + " cksum 0x%04x, lifetime %us", + areatag, ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime)); + } + + return LSP_OLDER; } -static void -lsp_auth_add (struct isis_lsp *lsp) +static void lsp_auth_add(struct isis_lsp *lsp) { - struct isis_passwd *passwd; - unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; - - /* - * Add the authentication info if its present - */ - (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd) : - (passwd = &lsp->area->domain_passwd); - switch (passwd->type) - { - /* Cleartext */ - case ISIS_PASSWD_TYPE_CLEARTXT: - memcpy (&lsp->tlv_data.auth_info, passwd, sizeof (struct isis_passwd)); - tlv_add_authinfo (passwd->type, passwd->len, passwd->passwd, lsp->pdu); - break; - - /* HMAC MD5 */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - /* Remember where TLV is written so we can later - * overwrite the MD5 hash */ - lsp->auth_tlv_offset = stream_get_endp (lsp->pdu); - memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); - lsp->tlv_data.auth_info.type = ISIS_PASSWD_TYPE_HMAC_MD5; - lsp->tlv_data.auth_info.len = ISIS_AUTH_MD5_SIZE; - memcpy (&lsp->tlv_data.auth_info.passwd, hmac_md5_hash, - ISIS_AUTH_MD5_SIZE); - tlv_add_authinfo (passwd->type, ISIS_AUTH_MD5_SIZE, hmac_md5_hash, - lsp->pdu); - break; - - default: - break; - } + struct isis_passwd *passwd; + unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; + + /* + * Add the authentication info if its present + */ + (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd) + : (passwd = &lsp->area->domain_passwd); + switch (passwd->type) { + /* Cleartext */ + case ISIS_PASSWD_TYPE_CLEARTXT: + memcpy(&lsp->tlv_data.auth_info, passwd, + sizeof(struct isis_passwd)); + tlv_add_authinfo(passwd->type, passwd->len, passwd->passwd, + lsp->pdu); + break; + + /* HMAC MD5 */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + /* Remember where TLV is written so we can later + * overwrite the MD5 hash */ + lsp->auth_tlv_offset = stream_get_endp(lsp->pdu); + memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); + lsp->tlv_data.auth_info.type = ISIS_PASSWD_TYPE_HMAC_MD5; + lsp->tlv_data.auth_info.len = ISIS_AUTH_MD5_SIZE; + memcpy(&lsp->tlv_data.auth_info.passwd, hmac_md5_hash, + ISIS_AUTH_MD5_SIZE); + tlv_add_authinfo(passwd->type, ISIS_AUTH_MD5_SIZE, + hmac_md5_hash, lsp->pdu); + break; + + default: + break; + } } -static void -lsp_auth_update (struct isis_lsp *lsp) +static void lsp_auth_update(struct isis_lsp *lsp) { - struct isis_passwd *passwd; - unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; - uint16_t checksum, rem_lifetime; - - /* For HMAC MD5 we need to recompute the md5 hash and store it */ - (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd) : - (passwd = &lsp->area->domain_passwd); - if (passwd->type != ISIS_PASSWD_TYPE_HMAC_MD5) - return; - - /* - * In transient conditions (when net is configured where authentication - * config and lsp regenerate schedule is not yet run), there could be - * an own_lsp with auth_tlv_offset set to 0. In such a case, simply - * return, when lsp_regenerate is run, lsp will have auth tlv. - */ - if (lsp->auth_tlv_offset == 0) - return; - - /* - * RFC 5304 set auth value, checksum and remaining lifetime to zero - * before computation and reset to old values after computation. - */ - checksum = lsp->lsp_header->checksum; - rem_lifetime = lsp->lsp_header->rem_lifetime; - lsp->lsp_header->checksum = 0; - lsp->lsp_header->rem_lifetime = 0; - /* Set the authentication value as well to zero */ - memset (STREAM_DATA (lsp->pdu) + lsp->auth_tlv_offset + 3, - 0, ISIS_AUTH_MD5_SIZE); - /* Compute autentication value */ - hmac_md5 (STREAM_DATA (lsp->pdu), stream_get_endp(lsp->pdu), - (unsigned char *) &passwd->passwd, passwd->len, - (unsigned char *) &hmac_md5_hash); - /* Copy the hash into the stream */ - memcpy (STREAM_DATA (lsp->pdu) + lsp->auth_tlv_offset + 3, - hmac_md5_hash, ISIS_AUTH_MD5_SIZE); - memcpy (&lsp->tlv_data.auth_info.passwd, hmac_md5_hash, - ISIS_AUTH_MD5_SIZE); - /* Copy back the checksum and remaining lifetime */ - lsp->lsp_header->checksum = checksum; - lsp->lsp_header->rem_lifetime = rem_lifetime; + struct isis_passwd *passwd; + unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; + uint16_t checksum, rem_lifetime; + + /* For HMAC MD5 we need to recompute the md5 hash and store it */ + (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd) + : (passwd = &lsp->area->domain_passwd); + if (passwd->type != ISIS_PASSWD_TYPE_HMAC_MD5) + return; + + /* + * In transient conditions (when net is configured where authentication + * config and lsp regenerate schedule is not yet run), there could be + * an own_lsp with auth_tlv_offset set to 0. In such a case, simply + * return, when lsp_regenerate is run, lsp will have auth tlv. + */ + if (lsp->auth_tlv_offset == 0) + return; + + /* + * RFC 5304 set auth value, checksum and remaining lifetime to zero + * before computation and reset to old values after computation. + */ + checksum = lsp->lsp_header->checksum; + rem_lifetime = lsp->lsp_header->rem_lifetime; + lsp->lsp_header->checksum = 0; + lsp->lsp_header->rem_lifetime = 0; + /* Set the authentication value as well to zero */ + memset(STREAM_DATA(lsp->pdu) + lsp->auth_tlv_offset + 3, 0, + ISIS_AUTH_MD5_SIZE); + /* Compute autentication value */ + hmac_md5(STREAM_DATA(lsp->pdu), stream_get_endp(lsp->pdu), + (unsigned char *)&passwd->passwd, passwd->len, + (unsigned char *)&hmac_md5_hash); + /* Copy the hash into the stream */ + memcpy(STREAM_DATA(lsp->pdu) + lsp->auth_tlv_offset + 3, hmac_md5_hash, + ISIS_AUTH_MD5_SIZE); + memcpy(&lsp->tlv_data.auth_info.passwd, hmac_md5_hash, + ISIS_AUTH_MD5_SIZE); + /* Copy back the checksum and remaining lifetime */ + lsp->lsp_header->checksum = checksum; + lsp->lsp_header->rem_lifetime = rem_lifetime; } -void -lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num) +void lsp_inc_seqnum(struct isis_lsp *lsp, u_int32_t seq_num) { - u_int32_t newseq; - - if (seq_num == 0 || ntohl (lsp->lsp_header->seq_num) > seq_num) - newseq = ntohl (lsp->lsp_header->seq_num) + 1; - else - newseq = seq_num + 1; - - lsp->lsp_header->seq_num = htonl (newseq); - - /* Recompute authentication and checksum information */ - lsp_auth_update (lsp); - /* ISO 10589 - 7.3.11 Generation of the checksum - * The checksum shall be computed over all fields in the LSP which appear - * after the Remaining Lifetime field. This field (and those appearing - * before it) are excluded so that the LSP may be aged by systems without - * requiring recomputation. - */ - fletcher_checksum(STREAM_DATA (lsp->pdu) + 12, - ntohs (lsp->lsp_header->pdu_len) - 12, 12); - - isis_spf_schedule (lsp->area, lsp->level); - - return; + u_int32_t newseq; + + if (seq_num == 0 || ntohl(lsp->lsp_header->seq_num) > seq_num) + newseq = ntohl(lsp->lsp_header->seq_num) + 1; + else + newseq = seq_num + 1; + + lsp->lsp_header->seq_num = htonl(newseq); + + /* Recompute authentication and checksum information */ + lsp_auth_update(lsp); + /* ISO 10589 - 7.3.11 Generation of the checksum + * The checksum shall be computed over all fields in the LSP which + * appear + * after the Remaining Lifetime field. This field (and those appearing + * before it) are excluded so that the LSP may be aged by systems + * without + * requiring recomputation. + */ + fletcher_checksum(STREAM_DATA(lsp->pdu) + 12, + ntohs(lsp->lsp_header->pdu_len) - 12, 12); + + isis_spf_schedule(lsp->area, lsp->level); + + return; } /* * Genetates checksum for LSP and its frags */ -static void -lsp_seqnum_update (struct isis_lsp *lsp0) +static void lsp_seqnum_update(struct isis_lsp *lsp0) { - struct isis_lsp *lsp; - struct listnode *node; + struct isis_lsp *lsp; + struct listnode *node; - lsp_inc_seqnum (lsp0, 0); + lsp_inc_seqnum(lsp0, 0); - if (!lsp0->lspu.frags) - return; + if (!lsp0->lspu.frags) + return; - for (ALL_LIST_ELEMENTS_RO (lsp0->lspu.frags, node, lsp)) - lsp_inc_seqnum (lsp, 0); + for (ALL_LIST_ELEMENTS_RO(lsp0->lspu.frags, node, lsp)) + lsp_inc_seqnum(lsp, 0); - return; + return; } -static u_int8_t -lsp_bits_generate (int level, int overload_bit, int attached_bit) +static u_int8_t lsp_bits_generate(int level, int overload_bit, int attached_bit) { - u_int8_t lsp_bits = 0; - if (level == IS_LEVEL_1) - lsp_bits = IS_LEVEL_1; - else - lsp_bits = IS_LEVEL_1_AND_2; - if (overload_bit) - lsp_bits |= overload_bit; - if (attached_bit) - lsp_bits |= attached_bit; - return lsp_bits; + u_int8_t lsp_bits = 0; + if (level == IS_LEVEL_1) + lsp_bits = IS_LEVEL_1; + else + lsp_bits = IS_LEVEL_1_AND_2; + if (overload_bit) + lsp_bits |= overload_bit; + if (attached_bit) + lsp_bits |= attached_bit; + return lsp_bits; } -static void -lsp_update_data (struct isis_lsp *lsp, struct stream *stream, - struct isis_area *area, int level) +static void lsp_update_data(struct isis_lsp *lsp, struct stream *stream, + struct isis_area *area, int level) { - uint32_t expected = 0, found; - int retval; - - /* free the old lsp data */ - lsp_clear_data (lsp); - - /* copying only the relevant part of our stream */ - if (lsp->pdu != NULL) - stream_free (lsp->pdu); - lsp->pdu = stream_dup (stream); - - /* setting pointers to the correct place */ - lsp->isis_header = (struct isis_fixed_hdr *) (STREAM_DATA (lsp->pdu)); - lsp->lsp_header = (struct isis_link_state_hdr *) (STREAM_DATA (lsp->pdu) + - ISIS_FIXED_HDR_LEN); - lsp->area = area; - lsp->level = level; - lsp->age_out = ZERO_AGE_LIFETIME; - lsp->installed = time (NULL); - /* - * Get LSP data i.e. TLVs - */ - expected |= TLVFLAG_AUTH_INFO; - expected |= TLVFLAG_AREA_ADDRS; - expected |= TLVFLAG_IS_NEIGHS; - expected |= TLVFLAG_NLPID; - if (area->dynhostname) - expected |= TLVFLAG_DYN_HOSTNAME; - if (area->newmetric) - { - expected |= TLVFLAG_TE_IS_NEIGHS; - expected |= TLVFLAG_TE_IPV4_REACHABILITY; - expected |= TLVFLAG_TE_ROUTER_ID; - } - expected |= TLVFLAG_MT_ROUTER_INFORMATION; - expected |= TLVFLAG_IPV4_ADDR; - expected |= TLVFLAG_IPV4_INT_REACHABILITY; - expected |= TLVFLAG_IPV4_EXT_REACHABILITY; - expected |= TLVFLAG_IPV6_ADDR; - expected |= TLVFLAG_IPV6_REACHABILITY; - - retval = parse_tlvs (area->area_tag, STREAM_DATA (lsp->pdu) + - ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN, - ntohs (lsp->lsp_header->pdu_len) - - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN, - &expected, &found, &lsp->tlv_data, - NULL); - if (retval != ISIS_OK) - { - zlog_warn ("Could not parse LSP"); - return; - } - - if ((found & TLVFLAG_DYN_HOSTNAME) && (area->dynhostname)) - { - isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname, - (lsp->lsp_header->lsp_bits & LSPBIT_IST) == - IS_LEVEL_1_AND_2 ? IS_LEVEL_2 : IS_LEVEL_1); - } - - return; + uint32_t expected = 0, found; + int retval; + + /* free the old lsp data */ + lsp_clear_data(lsp); + + /* copying only the relevant part of our stream */ + if (lsp->pdu != NULL) + stream_free(lsp->pdu); + lsp->pdu = stream_dup(stream); + + /* setting pointers to the correct place */ + lsp->isis_header = (struct isis_fixed_hdr *)(STREAM_DATA(lsp->pdu)); + lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu) + + ISIS_FIXED_HDR_LEN); + lsp->area = area; + lsp->level = level; + lsp->age_out = ZERO_AGE_LIFETIME; + lsp->installed = time(NULL); + /* + * Get LSP data i.e. TLVs + */ + expected |= TLVFLAG_AUTH_INFO; + expected |= TLVFLAG_AREA_ADDRS; + expected |= TLVFLAG_IS_NEIGHS; + expected |= TLVFLAG_NLPID; + if (area->dynhostname) + expected |= TLVFLAG_DYN_HOSTNAME; + if (area->newmetric) { + expected |= TLVFLAG_TE_IS_NEIGHS; + expected |= TLVFLAG_TE_IPV4_REACHABILITY; + expected |= TLVFLAG_TE_ROUTER_ID; + } + expected |= TLVFLAG_MT_ROUTER_INFORMATION; + expected |= TLVFLAG_IPV4_ADDR; + expected |= TLVFLAG_IPV4_INT_REACHABILITY; + expected |= TLVFLAG_IPV4_EXT_REACHABILITY; + expected |= TLVFLAG_IPV6_ADDR; + expected |= TLVFLAG_IPV6_REACHABILITY; + + retval = parse_tlvs(area->area_tag, + STREAM_DATA(lsp->pdu) + ISIS_FIXED_HDR_LEN + + ISIS_LSP_HDR_LEN, + ntohs(lsp->lsp_header->pdu_len) - ISIS_FIXED_HDR_LEN + - ISIS_LSP_HDR_LEN, + &expected, &found, &lsp->tlv_data, NULL); + if (retval != ISIS_OK) { + zlog_warn("Could not parse LSP"); + return; + } + + if ((found & TLVFLAG_DYN_HOSTNAME) && (area->dynhostname)) { + isis_dynhn_insert(lsp->lsp_header->lsp_id, + lsp->tlv_data.hostname, + (lsp->lsp_header->lsp_bits & LSPBIT_IST) + == IS_LEVEL_1_AND_2 + ? IS_LEVEL_2 + : IS_LEVEL_1); + } + + return; } -void -lsp_update (struct isis_lsp *lsp, struct stream *stream, - struct isis_area *area, int level) +void lsp_update(struct isis_lsp *lsp, struct stream *stream, + struct isis_area *area, int level) { - dnode_t *dnode = NULL; - - /* Remove old LSP from database. This is required since the - * lsp_update_data will free the lsp->pdu (which has the key, lsp_id) - * and will update it with the new data in the stream. */ - dnode = dict_lookup (area->lspdb[level - 1], lsp->lsp_header->lsp_id); - if (dnode) - dnode_destroy (dict_delete (area->lspdb[level - 1], dnode)); - - if (lsp->own_lsp) - { - zlog_err("ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP", - area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id)); - lsp_clear_data(lsp); - lsp->own_lsp = 0; - } - - /* rebuild the lsp data */ - lsp_update_data (lsp, stream, area, level); - - /* insert the lsp back into the database */ - lsp_insert (lsp, area->lspdb[level - 1]); + dnode_t *dnode = NULL; + + /* Remove old LSP from database. This is required since the + * lsp_update_data will free the lsp->pdu (which has the key, lsp_id) + * and will update it with the new data in the stream. */ + dnode = dict_lookup(area->lspdb[level - 1], lsp->lsp_header->lsp_id); + if (dnode) + dnode_destroy(dict_delete(area->lspdb[level - 1], dnode)); + + if (lsp->own_lsp) { + zlog_err( + "ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP", + area->area_tag, + rawlspid_print(lsp->lsp_header->lsp_id)); + lsp_clear_data(lsp); + lsp->own_lsp = 0; + } + + /* rebuild the lsp data */ + lsp_update_data(lsp, stream, area, level); + + /* insert the lsp back into the database */ + lsp_insert(lsp, area->lspdb[level - 1]); } /* creation of LSP directly from what we received */ -struct isis_lsp * -lsp_new_from_stream_ptr (struct stream *stream, - u_int16_t pdu_len, struct isis_lsp *lsp0, - struct isis_area *area, int level) +struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream, + u_int16_t pdu_len, + struct isis_lsp *lsp0, + struct isis_area *area, int level) { - struct isis_lsp *lsp; - - lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp)); - lsp_update_data (lsp, stream, area, level); - - if (lsp0 == NULL) - { - /* - * zero lsp -> create the list for fragments - */ - lsp->lspu.frags = list_new (); - } - else - { - /* - * a fragment -> set the backpointer and add this to zero lsps frag list - */ - lsp->lspu.zero_lsp = lsp0; - listnode_add (lsp0->lspu.frags, lsp); - } - - return lsp; + struct isis_lsp *lsp; + + lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp)); + lsp_update_data(lsp, stream, area, level); + + if (lsp0 == NULL) { + /* + * zero lsp -> create the list for fragments + */ + lsp->lspu.frags = list_new(); + } else { + /* + * a fragment -> set the backpointer and add this to zero lsps + * frag list + */ + lsp->lspu.zero_lsp = lsp0; + listnode_add(lsp0->lspu.frags, lsp); + } + + return lsp; } -struct isis_lsp * -lsp_new(struct isis_area *area, u_char * lsp_id, - u_int16_t rem_lifetime, u_int32_t seq_num, - u_int8_t lsp_bits, u_int16_t checksum, int level) +struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id, + u_int16_t rem_lifetime, u_int32_t seq_num, + u_int8_t lsp_bits, u_int16_t checksum, int level) { - struct isis_lsp *lsp; - - lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp)); - lsp->area = area; - - lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu); - if (LSP_FRAGMENT (lsp_id) == 0) - lsp->lspu.frags = list_new (); - lsp->isis_header = (struct isis_fixed_hdr *) (STREAM_DATA (lsp->pdu)); - lsp->lsp_header = (struct isis_link_state_hdr *) - (STREAM_DATA (lsp->pdu) + ISIS_FIXED_HDR_LEN); - - /* at first we fill the FIXED HEADER */ - (level == IS_LEVEL_1) ? fill_fixed_hdr (lsp->isis_header, L1_LINK_STATE) : - fill_fixed_hdr (lsp->isis_header, L2_LINK_STATE); - - /* now for the LSP HEADER */ - /* Minimal LSP PDU size */ - lsp->lsp_header->pdu_len = htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - memcpy (lsp->lsp_header->lsp_id, lsp_id, ISIS_SYS_ID_LEN + 2); - lsp->lsp_header->checksum = checksum; /* Provided in network order */ - lsp->lsp_header->seq_num = htonl (seq_num); - lsp->lsp_header->rem_lifetime = htons (rem_lifetime); - lsp->lsp_header->lsp_bits = lsp_bits; - lsp->level = level; - lsp->age_out = ZERO_AGE_LIFETIME; - - stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("New LSP with ID %s-%02x-%02x len %d seqnum %08x", - sysid_print (lsp_id), LSP_PSEUDO_ID (lsp->lsp_header->lsp_id), - LSP_FRAGMENT (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->pdu_len), - ntohl (lsp->lsp_header->seq_num)); - - return lsp; + struct isis_lsp *lsp; + + lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp)); + lsp->area = area; + + lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu); + if (LSP_FRAGMENT(lsp_id) == 0) + lsp->lspu.frags = list_new(); + lsp->isis_header = (struct isis_fixed_hdr *)(STREAM_DATA(lsp->pdu)); + lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu) + + ISIS_FIXED_HDR_LEN); + + /* at first we fill the FIXED HEADER */ + (level == IS_LEVEL_1) ? fill_fixed_hdr(lsp->isis_header, L1_LINK_STATE) + : fill_fixed_hdr(lsp->isis_header, L2_LINK_STATE); + + /* now for the LSP HEADER */ + /* Minimal LSP PDU size */ + lsp->lsp_header->pdu_len = htons(ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + memcpy(lsp->lsp_header->lsp_id, lsp_id, ISIS_SYS_ID_LEN + 2); + lsp->lsp_header->checksum = checksum; /* Provided in network order */ + lsp->lsp_header->seq_num = htonl(seq_num); + lsp->lsp_header->rem_lifetime = htons(rem_lifetime); + lsp->lsp_header->lsp_bits = lsp_bits; + lsp->level = level; + lsp->age_out = ZERO_AGE_LIFETIME; + + stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("New LSP with ID %s-%02x-%02x len %d seqnum %08x", + sysid_print(lsp_id), + LSP_PSEUDO_ID(lsp->lsp_header->lsp_id), + LSP_FRAGMENT(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->pdu_len), + ntohl(lsp->lsp_header->seq_num)); + + return lsp; } -void -lsp_insert (struct isis_lsp *lsp, dict_t * lspdb) +void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb) { - dict_alloc_insert (lspdb, lsp->lsp_header->lsp_id, lsp); - if (lsp->lsp_header->seq_num != 0) - { - isis_spf_schedule (lsp->area, lsp->level); - } + dict_alloc_insert(lspdb, lsp->lsp_header->lsp_id, lsp); + if (lsp->lsp_header->seq_num != 0) { + isis_spf_schedule(lsp->area, lsp->level); + } } /* * Build a list of LSPs with non-zero ht bounded by start and stop ids */ -void -lsp_build_list_nonzero_ht (u_char * start_id, u_char * stop_id, - struct list *list, dict_t * lspdb) +void lsp_build_list_nonzero_ht(u_char *start_id, u_char *stop_id, + struct list *list, dict_t *lspdb) { - dnode_t *first, *last, *curr; + dnode_t *first, *last, *curr; - first = dict_lower_bound (lspdb, start_id); - if (!first) - return; + first = dict_lower_bound(lspdb, start_id); + if (!first) + return; - last = dict_upper_bound (lspdb, stop_id); + last = dict_upper_bound(lspdb, stop_id); - curr = first; + curr = first; - if (((struct isis_lsp *) (curr->dict_data))->lsp_header->rem_lifetime) - listnode_add (list, first->dict_data); + if (((struct isis_lsp *)(curr->dict_data))->lsp_header->rem_lifetime) + listnode_add(list, first->dict_data); - while (curr) - { - curr = dict_next (lspdb, curr); - if (curr && - ((struct isis_lsp *) (curr->dict_data))->lsp_header->rem_lifetime) - listnode_add (list, curr->dict_data); - if (curr == last) - break; - } + while (curr) { + curr = dict_next(lspdb, curr); + if (curr + && ((struct isis_lsp *)(curr->dict_data)) + ->lsp_header->rem_lifetime) + listnode_add(list, curr->dict_data); + if (curr == last) + break; + } - return; + return; } /* * Build a list of num_lsps LSPs bounded by start_id and stop_id. */ -void -lsp_build_list (u_char * start_id, u_char * stop_id, u_char num_lsps, - struct list *list, dict_t * lspdb) +void lsp_build_list(u_char *start_id, u_char *stop_id, u_char num_lsps, + struct list *list, dict_t *lspdb) { - u_char count; - dnode_t *first, *last, *curr; + u_char count; + dnode_t *first, *last, *curr; - first = dict_lower_bound (lspdb, start_id); - if (!first) - return; + first = dict_lower_bound(lspdb, start_id); + if (!first) + return; - last = dict_upper_bound (lspdb, stop_id); + last = dict_upper_bound(lspdb, stop_id); - curr = first; + curr = first; - listnode_add (list, first->dict_data); - count = 1; + listnode_add(list, first->dict_data); + count = 1; - while (curr) - { - curr = dict_next (lspdb, curr); - if (curr) - { - listnode_add (list, curr->dict_data); - count++; - } - if (count == num_lsps || curr == last) - break; - } + while (curr) { + curr = dict_next(lspdb, curr); + if (curr) { + listnode_add(list, curr->dict_data); + count++; + } + if (count == num_lsps || curr == last) + break; + } - return; + return; } /* * Build a list of LSPs with SSN flag set for the given circuit */ -void -lsp_build_list_ssn (struct isis_circuit *circuit, u_char num_lsps, - struct list *list, dict_t * lspdb) +void lsp_build_list_ssn(struct isis_circuit *circuit, u_char num_lsps, + struct list *list, dict_t *lspdb) { - dnode_t *dnode, *next; - struct isis_lsp *lsp; - u_char count = 0; - - dnode = dict_first (lspdb); - while (dnode != NULL) - { - next = dict_next (lspdb, dnode); - lsp = dnode_get (dnode); - if (ISIS_CHECK_FLAG (lsp->SSNflags, circuit)) - { - listnode_add (list, lsp); - ++count; - } - if (count == num_lsps) - break; - dnode = next; - } - - return; + dnode_t *dnode, *next; + struct isis_lsp *lsp; + u_char count = 0; + + dnode = dict_first(lspdb); + while (dnode != NULL) { + next = dict_next(lspdb, dnode); + lsp = dnode_get(dnode); + if (ISIS_CHECK_FLAG(lsp->SSNflags, circuit)) { + listnode_add(list, lsp); + ++count; + } + if (count == num_lsps) + break; + dnode = next; + } + + return; } -static void -lsp_set_time (struct isis_lsp *lsp) +static void lsp_set_time(struct isis_lsp *lsp) { - assert (lsp); + assert(lsp); - if (lsp->lsp_header->rem_lifetime == 0) - { - if (lsp->age_out > 0) - lsp->age_out--; - return; - } + if (lsp->lsp_header->rem_lifetime == 0) { + if (lsp->age_out > 0) + lsp->age_out--; + return; + } - lsp->lsp_header->rem_lifetime = - htons (ntohs (lsp->lsp_header->rem_lifetime) - 1); + lsp->lsp_header->rem_lifetime = + htons(ntohs(lsp->lsp_header->rem_lifetime) - 1); } -static void -lspid_print (u_char * lsp_id, u_char * trg, char dynhost, char frag) +static void lspid_print(u_char *lsp_id, u_char *trg, char dynhost, char frag) { - struct isis_dynhn *dyn = NULL; - u_char id[SYSID_STRLEN]; - - if (dynhost) - dyn = dynhn_find_by_id (lsp_id); - else - dyn = NULL; - - if (dyn) - sprintf ((char *)id, "%.14s", dyn->name.name); - else if (!memcmp (isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost) - sprintf ((char *)id, "%.14s", unix_hostname ()); - else - memcpy (id, sysid_print (lsp_id), 15); - if (frag) - sprintf ((char *)trg, "%s.%02x-%02x", id, LSP_PSEUDO_ID (lsp_id), - LSP_FRAGMENT (lsp_id)); - else - sprintf ((char *)trg, "%s.%02x", id, LSP_PSEUDO_ID (lsp_id)); + struct isis_dynhn *dyn = NULL; + u_char id[SYSID_STRLEN]; + + if (dynhost) + dyn = dynhn_find_by_id(lsp_id); + else + dyn = NULL; + + if (dyn) + sprintf((char *)id, "%.14s", dyn->name.name); + else if (!memcmp(isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost) + sprintf((char *)id, "%.14s", unix_hostname()); + else + memcpy(id, sysid_print(lsp_id), 15); + if (frag) + sprintf((char *)trg, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id), + LSP_FRAGMENT(lsp_id)); + else + sprintf((char *)trg, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id)); } /* Convert the lsp attribute bits to attribute string */ -const char * -lsp_bits2string (u_char * lsp_bits) +const char *lsp_bits2string(u_char *lsp_bits) { - char *pos = lsp_bits_string; + char *pos = lsp_bits_string; - if (!*lsp_bits) - return " none"; + if (!*lsp_bits) + return " none"; - /* we only focus on the default metric */ - pos += sprintf (pos, "%d/", - ISIS_MASK_LSP_ATT_DEFAULT_BIT (*lsp_bits) ? 1 : 0); + /* we only focus on the default metric */ + pos += sprintf(pos, "%d/", + ISIS_MASK_LSP_ATT_DEFAULT_BIT(*lsp_bits) ? 1 : 0); - pos += sprintf (pos, "%d/", - ISIS_MASK_LSP_PARTITION_BIT (*lsp_bits) ? 1 : 0); + pos += sprintf(pos, "%d/", + ISIS_MASK_LSP_PARTITION_BIT(*lsp_bits) ? 1 : 0); - pos += sprintf (pos, "%d", ISIS_MASK_LSP_OL_BIT (*lsp_bits) ? 1 : 0); + pos += sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(*lsp_bits) ? 1 : 0); - *(pos) = '\0'; + *(pos) = '\0'; - return lsp_bits_string; + return lsp_bits_string; } /* this function prints the lsp on show isis database */ -void -lsp_print (struct isis_lsp *lsp, struct vty *vty, char dynhost) +void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost) { - u_char LSPid[255]; - char age_out[8]; - - lspid_print (lsp->lsp_header->lsp_id, LSPid, dynhost, 1); - vty_out (vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' '); - vty_out (vty, "%5u ", ntohs (lsp->lsp_header->pdu_len)); - vty_out (vty, "0x%08x ", ntohl (lsp->lsp_header->seq_num)); - vty_out (vty, "0x%04x ", ntohs (lsp->lsp_header->checksum)); - if (ntohs (lsp->lsp_header->rem_lifetime) == 0) - { - snprintf (age_out, 8, "(%u)", lsp->age_out); - age_out[7] = '\0'; - vty_out (vty, "%7s ", age_out); - } - else - vty_out (vty, " %5u ", ntohs (lsp->lsp_header->rem_lifetime)); - vty_out (vty, "%s\n", - lsp_bits2string(&lsp->lsp_header->lsp_bits)); + u_char LSPid[255]; + char age_out[8]; + + lspid_print(lsp->lsp_header->lsp_id, LSPid, dynhost, 1); + vty_out(vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' '); + vty_out(vty, "%5u ", ntohs(lsp->lsp_header->pdu_len)); + vty_out(vty, "0x%08x ", ntohl(lsp->lsp_header->seq_num)); + vty_out(vty, "0x%04x ", ntohs(lsp->lsp_header->checksum)); + if (ntohs(lsp->lsp_header->rem_lifetime) == 0) { + snprintf(age_out, 8, "(%u)", lsp->age_out); + age_out[7] = '\0'; + vty_out(vty, "%7s ", age_out); + } else + vty_out(vty, " %5u ", ntohs(lsp->lsp_header->rem_lifetime)); + vty_out(vty, "%s\n", lsp_bits2string(&lsp->lsp_header->lsp_bits)); } -static void -lsp_print_mt_reach(struct list *list, struct vty *vty, - char dynhost, uint16_t mtid) +static void lsp_print_mt_reach(struct list *list, struct vty *vty, char dynhost, + uint16_t mtid) { - struct listnode *node; - struct te_is_neigh *neigh; - - for (ALL_LIST_ELEMENTS_RO (list, node, neigh)) - { - u_char lspid[255]; - - lspid_print(neigh->neigh_id, lspid, dynhost, 0); - if (mtid == ISIS_MT_IPV4_UNICAST) - { - vty_out(vty, " Metric : %-8u IS-Extended : %s\n", - GET_TE_METRIC(neigh), lspid); - } - else - { - vty_out(vty, " Metric : %-8u MT-Reach : %s %s\n", - GET_TE_METRIC(neigh), lspid, - isis_mtid2str(mtid)); - } - if (IS_MPLS_TE(isisMplsTE)) - mpls_te_print_detail(vty, neigh); - } + struct listnode *node; + struct te_is_neigh *neigh; + + for (ALL_LIST_ELEMENTS_RO(list, node, neigh)) { + u_char lspid[255]; + + lspid_print(neigh->neigh_id, lspid, dynhost, 0); + if (mtid == ISIS_MT_IPV4_UNICAST) { + vty_out(vty, + " Metric : %-8u IS-Extended : %s\n", + GET_TE_METRIC(neigh), lspid); + } else { + vty_out(vty, + " Metric : %-8u MT-Reach : %s %s\n", + GET_TE_METRIC(neigh), lspid, + isis_mtid2str(mtid)); + } + if (IS_MPLS_TE(isisMplsTE)) + mpls_te_print_detail(vty, neigh); + } } -static void -lsp_print_mt_ipv6_reach(struct list *list, struct vty *vty, uint16_t mtid) +static void lsp_print_mt_ipv6_reach(struct list *list, struct vty *vty, + uint16_t mtid) { - struct listnode *node; - struct ipv6_reachability *ipv6_reach; - struct in6_addr in6; - u_char buff[BUFSIZ]; - - for (ALL_LIST_ELEMENTS_RO (list, node, ipv6_reach)) - { - memset (&in6, 0, sizeof (in6)); - memcpy (in6.s6_addr, ipv6_reach->prefix, - PSIZE (ipv6_reach->prefix_len)); - inet_ntop (AF_INET6, &in6, (char *)buff, BUFSIZ); - if (mtid == ISIS_MT_IPV4_UNICAST) - { - if ((ipv6_reach->control_info & - CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL) - vty_out (vty, " Metric : %-8" PRIu32 " IPv6-Internal : %s/%d\n", - ntohl (ipv6_reach->metric), - buff, ipv6_reach->prefix_len); - else - vty_out (vty, " Metric : %-8" PRIu32 " IPv6-External : %s/%d\n", - ntohl (ipv6_reach->metric), - buff, ipv6_reach->prefix_len); - } - else - { - if ((ipv6_reach->control_info & - CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL) - vty_out (vty, " Metric : %-8" PRIu32 " IPv6-MT-Int : %s/%d %s\n", - ntohl (ipv6_reach->metric), - buff, ipv6_reach->prefix_len, - isis_mtid2str(mtid)); - else - vty_out (vty, " Metric : %-8" PRIu32 " IPv6-MT-Ext : %s/%d %s\n", - ntohl (ipv6_reach->metric), - buff, ipv6_reach->prefix_len, - isis_mtid2str(mtid)); - } - } + struct listnode *node; + struct ipv6_reachability *ipv6_reach; + struct in6_addr in6; + u_char buff[BUFSIZ]; + + for (ALL_LIST_ELEMENTS_RO(list, node, ipv6_reach)) { + memset(&in6, 0, sizeof(in6)); + memcpy(in6.s6_addr, ipv6_reach->prefix, + PSIZE(ipv6_reach->prefix_len)); + inet_ntop(AF_INET6, &in6, (char *)buff, BUFSIZ); + if (mtid == ISIS_MT_IPV4_UNICAST) { + if ((ipv6_reach->control_info & CTRL_INFO_DISTRIBUTION) + == DISTRIBUTION_INTERNAL) + vty_out(vty, " Metric : %-8" PRIu32 + " IPv6-Internal : %s/%d\n", + ntohl(ipv6_reach->metric), buff, + ipv6_reach->prefix_len); + else + vty_out(vty, " Metric : %-8" PRIu32 + " IPv6-External : %s/%d\n", + ntohl(ipv6_reach->metric), buff, + ipv6_reach->prefix_len); + } else { + if ((ipv6_reach->control_info & CTRL_INFO_DISTRIBUTION) + == DISTRIBUTION_INTERNAL) + vty_out(vty, " Metric : %-8" PRIu32 + " IPv6-MT-Int : %s/%d %s\n", + ntohl(ipv6_reach->metric), buff, + ipv6_reach->prefix_len, + isis_mtid2str(mtid)); + else + vty_out(vty, " Metric : %-8" PRIu32 + " IPv6-MT-Ext : %s/%d %s\n", + ntohl(ipv6_reach->metric), buff, + ipv6_reach->prefix_len, + isis_mtid2str(mtid)); + } + } } -static void -lsp_print_mt_ipv4_reach(struct list *list, struct vty *vty, uint16_t mtid) +static void lsp_print_mt_ipv4_reach(struct list *list, struct vty *vty, + uint16_t mtid) { - struct listnode *node; - struct te_ipv4_reachability *te_ipv4_reach; - - for (ALL_LIST_ELEMENTS_RO (list, node, te_ipv4_reach)) - { - if (mtid == ISIS_MT_IPV4_UNICAST) - { - /* FIXME: There should be better way to output this stuff. */ - vty_out (vty, " Metric : %-8" PRIu32 " IPv4-Extended : %s/%d\n", - ntohl (te_ipv4_reach->te_metric), - inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start, - te_ipv4_reach->control)), - te_ipv4_reach->control & 0x3F); - } - else - { - /* FIXME: There should be better way to output this stuff. */ - vty_out (vty, " Metric : %-8" PRIu32 " IPv4-MT : %s/%d %s\n", - ntohl (te_ipv4_reach->te_metric), - inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start, - te_ipv4_reach->control)), - te_ipv4_reach->control & 0x3F, - isis_mtid2str(mtid)); - } - } + struct listnode *node; + struct te_ipv4_reachability *te_ipv4_reach; + + for (ALL_LIST_ELEMENTS_RO(list, node, te_ipv4_reach)) { + if (mtid == ISIS_MT_IPV4_UNICAST) { + /* FIXME: There should be better way to output this + * stuff. */ + vty_out(vty, " Metric : %-8" PRIu32 + " IPv4-Extended : %s/%d\n", + ntohl(te_ipv4_reach->te_metric), + inet_ntoa(newprefix2inaddr( + &te_ipv4_reach->prefix_start, + te_ipv4_reach->control)), + te_ipv4_reach->control & 0x3F); + } else { + /* FIXME: There should be better way to output this + * stuff. */ + vty_out(vty, " Metric : %-8" PRIu32 + " IPv4-MT : %s/%d %s\n", + ntohl(te_ipv4_reach->te_metric), + inet_ntoa(newprefix2inaddr( + &te_ipv4_reach->prefix_start, + te_ipv4_reach->control)), + te_ipv4_reach->control & 0x3F, + isis_mtid2str(mtid)); + } + } } -void -lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost) +void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost) { - struct area_addr *area_addr; - int i; - struct listnode *lnode; - struct is_neigh *is_neigh; - struct ipv4_reachability *ipv4_reach; - struct in_addr *ipv4_addr; - struct mt_router_info *mt_router_info; - struct tlv_mt_ipv6_reachs *mt_ipv6_reachs; - struct tlv_mt_neighbors *mt_is_neigh; - struct tlv_mt_ipv4_reachs *mt_ipv4_reachs; - u_char LSPid[255]; - u_char hostname[255]; - u_char ipv4_reach_prefix[20]; - u_char ipv4_reach_mask[20]; - u_char ipv4_address[20]; - - lspid_print (lsp->lsp_header->lsp_id, LSPid, dynhost, 1); - lsp_print (lsp, vty, dynhost); - - /* for all area address */ - if (lsp->tlv_data.area_addrs) - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.area_addrs, lnode, area_addr)) - { - vty_out (vty, " Area Address: %s\n", - isonet_print(area_addr->area_addr, area_addr->addr_len)); - } - - /* for the nlpid tlv */ - if (lsp->tlv_data.nlpids) - { - for (i = 0; i < lsp->tlv_data.nlpids->count; i++) - { - switch (lsp->tlv_data.nlpids->nlpids[i]) - { - case NLPID_IP: - case NLPID_IPV6: - vty_out (vty, " NLPID : 0x%X\n", - lsp->tlv_data.nlpids->nlpids[i]); - break; - default: - vty_out (vty, " NLPID : %s\n", "unknown"); - break; - } - } - } - - for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_router_info, lnode, mt_router_info)) - { - vty_out (vty, " MT : %s%s\n", - isis_mtid2str(mt_router_info->mtid), - mt_router_info->overload ? " (overload)" : ""); - } - - /* for the hostname tlv */ - if (lsp->tlv_data.hostname) - { - bzero (hostname, sizeof (hostname)); - memcpy (hostname, lsp->tlv_data.hostname->name, - lsp->tlv_data.hostname->namelen); - vty_out (vty, " Hostname : %s\n", hostname); - } - - /* authentication tlv */ - if (lsp->tlv_data.auth_info.type != ISIS_PASSWD_TYPE_UNUSED) - { - if (lsp->tlv_data.auth_info.type == ISIS_PASSWD_TYPE_HMAC_MD5) - vty_out (vty, " Auth type : md5\n"); - else if (lsp->tlv_data.auth_info.type == ISIS_PASSWD_TYPE_CLEARTXT) - vty_out (vty, " Auth type : clear text\n"); - } - - /* TE router id */ - if (lsp->tlv_data.router_id) - { - memcpy (ipv4_address, inet_ntoa (lsp->tlv_data.router_id->id), - sizeof (ipv4_address)); - vty_out (vty, " Router ID : %s\n", ipv4_address); - } - - if (lsp->tlv_data.ipv4_addrs) - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_addrs, lnode, ipv4_addr)) - { - memcpy (ipv4_address, inet_ntoa (*ipv4_addr), sizeof (ipv4_address)); - vty_out (vty, " IPv4 Address: %s\n", ipv4_address); - } - - /* for the IS neighbor tlv */ - if (lsp->tlv_data.is_neighs) - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.is_neighs, lnode, is_neigh)) - { - lspid_print (is_neigh->neigh_id, LSPid, dynhost, 0); - vty_out (vty, " Metric : %-8" PRIu8 " IS : %s\n", - is_neigh->metrics.metric_default, LSPid); - } - - /* for the internal reachable tlv */ - if (lsp->tlv_data.ipv4_int_reachs) - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_int_reachs, lnode, - ipv4_reach)) - { - memcpy (ipv4_reach_prefix, inet_ntoa (ipv4_reach->prefix), - sizeof (ipv4_reach_prefix)); - memcpy (ipv4_reach_mask, inet_ntoa (ipv4_reach->mask), - sizeof (ipv4_reach_mask)); - vty_out (vty, " Metric : %-8" PRIu8 " IPv4-Internal : %s %s\n", - ipv4_reach->metrics.metric_default, ipv4_reach_prefix, - ipv4_reach_mask); - } - - /* for the external reachable tlv */ - if (lsp->tlv_data.ipv4_ext_reachs) - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_ext_reachs, lnode, - ipv4_reach)) - { - memcpy (ipv4_reach_prefix, inet_ntoa (ipv4_reach->prefix), - sizeof (ipv4_reach_prefix)); - memcpy (ipv4_reach_mask, inet_ntoa (ipv4_reach->mask), - sizeof (ipv4_reach_mask)); - vty_out (vty, " Metric : %-8" PRIu8 " IPv4-External : %s %s\n", - ipv4_reach->metrics.metric_default, ipv4_reach_prefix, - ipv4_reach_mask); - } - - /* IPv6 tlv */ - lsp_print_mt_ipv6_reach(lsp->tlv_data.ipv6_reachs, vty, - ISIS_MT_IPV4_UNICAST); - - /* MT IPv6 reachability tlv */ - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_ipv6_reachs, lnode, mt_ipv6_reachs)) - lsp_print_mt_ipv6_reach(mt_ipv6_reachs->list, vty, mt_ipv6_reachs->mtid); - - /* TE IS neighbor tlv */ - lsp_print_mt_reach(lsp->tlv_data.te_is_neighs, vty, - dynhost, ISIS_MT_IPV4_UNICAST); - - /* MT IS neighbor tlv */ - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_is_neighs, lnode, mt_is_neigh)) - lsp_print_mt_reach(mt_is_neigh->list, vty, dynhost, mt_is_neigh->mtid); - - /* TE IPv4 tlv */ - lsp_print_mt_ipv4_reach(lsp->tlv_data.te_ipv4_reachs, vty, - ISIS_MT_IPV4_UNICAST); - - /* MT IPv4 reachability tlv */ - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_ipv4_reachs, lnode, mt_ipv4_reachs)) - lsp_print_mt_ipv4_reach(mt_ipv4_reachs->list, vty, mt_ipv4_reachs->mtid); - - vty_out (vty, "\n"); - - return; + struct area_addr *area_addr; + int i; + struct listnode *lnode; + struct is_neigh *is_neigh; + struct ipv4_reachability *ipv4_reach; + struct in_addr *ipv4_addr; + struct mt_router_info *mt_router_info; + struct tlv_mt_ipv6_reachs *mt_ipv6_reachs; + struct tlv_mt_neighbors *mt_is_neigh; + struct tlv_mt_ipv4_reachs *mt_ipv4_reachs; + u_char LSPid[255]; + u_char hostname[255]; + u_char ipv4_reach_prefix[20]; + u_char ipv4_reach_mask[20]; + u_char ipv4_address[20]; + + lspid_print(lsp->lsp_header->lsp_id, LSPid, dynhost, 1); + lsp_print(lsp, vty, dynhost); + + /* for all area address */ + if (lsp->tlv_data.area_addrs) + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.area_addrs, lnode, + area_addr)) { + vty_out(vty, " Area Address: %s\n", + isonet_print(area_addr->area_addr, + area_addr->addr_len)); + } + + /* for the nlpid tlv */ + if (lsp->tlv_data.nlpids) { + for (i = 0; i < lsp->tlv_data.nlpids->count; i++) { + switch (lsp->tlv_data.nlpids->nlpids[i]) { + case NLPID_IP: + case NLPID_IPV6: + vty_out(vty, " NLPID : 0x%X\n", + lsp->tlv_data.nlpids->nlpids[i]); + break; + default: + vty_out(vty, " NLPID : %s\n", "unknown"); + break; + } + } + } + + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_router_info, lnode, + mt_router_info)) { + vty_out(vty, " MT : %s%s\n", + isis_mtid2str(mt_router_info->mtid), + mt_router_info->overload ? " (overload)" : ""); + } + + /* for the hostname tlv */ + if (lsp->tlv_data.hostname) { + bzero(hostname, sizeof(hostname)); + memcpy(hostname, lsp->tlv_data.hostname->name, + lsp->tlv_data.hostname->namelen); + vty_out(vty, " Hostname : %s\n", hostname); + } + + /* authentication tlv */ + if (lsp->tlv_data.auth_info.type != ISIS_PASSWD_TYPE_UNUSED) { + if (lsp->tlv_data.auth_info.type == ISIS_PASSWD_TYPE_HMAC_MD5) + vty_out(vty, " Auth type : md5\n"); + else if (lsp->tlv_data.auth_info.type + == ISIS_PASSWD_TYPE_CLEARTXT) + vty_out(vty, " Auth type : clear text\n"); + } + + /* TE router id */ + if (lsp->tlv_data.router_id) { + memcpy(ipv4_address, inet_ntoa(lsp->tlv_data.router_id->id), + sizeof(ipv4_address)); + vty_out(vty, " Router ID : %s\n", ipv4_address); + } + + if (lsp->tlv_data.ipv4_addrs) + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_addrs, lnode, + ipv4_addr)) { + memcpy(ipv4_address, inet_ntoa(*ipv4_addr), + sizeof(ipv4_address)); + vty_out(vty, " IPv4 Address: %s\n", ipv4_address); + } + + /* for the IS neighbor tlv */ + if (lsp->tlv_data.is_neighs) + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, lnode, + is_neigh)) { + lspid_print(is_neigh->neigh_id, LSPid, dynhost, 0); + vty_out(vty, " Metric : %-8" PRIu8 + " IS : %s\n", + is_neigh->metrics.metric_default, LSPid); + } + + /* for the internal reachable tlv */ + if (lsp->tlv_data.ipv4_int_reachs) + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_int_reachs, lnode, + ipv4_reach)) { + memcpy(ipv4_reach_prefix, inet_ntoa(ipv4_reach->prefix), + sizeof(ipv4_reach_prefix)); + memcpy(ipv4_reach_mask, inet_ntoa(ipv4_reach->mask), + sizeof(ipv4_reach_mask)); + vty_out(vty, " Metric : %-8" PRIu8 + " IPv4-Internal : %s %s\n", + ipv4_reach->metrics.metric_default, + ipv4_reach_prefix, ipv4_reach_mask); + } + + /* for the external reachable tlv */ + if (lsp->tlv_data.ipv4_ext_reachs) + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_ext_reachs, lnode, + ipv4_reach)) { + memcpy(ipv4_reach_prefix, inet_ntoa(ipv4_reach->prefix), + sizeof(ipv4_reach_prefix)); + memcpy(ipv4_reach_mask, inet_ntoa(ipv4_reach->mask), + sizeof(ipv4_reach_mask)); + vty_out(vty, " Metric : %-8" PRIu8 + " IPv4-External : %s %s\n", + ipv4_reach->metrics.metric_default, + ipv4_reach_prefix, ipv4_reach_mask); + } + + /* IPv6 tlv */ + lsp_print_mt_ipv6_reach(lsp->tlv_data.ipv6_reachs, vty, + ISIS_MT_IPV4_UNICAST); + + /* MT IPv6 reachability tlv */ + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_ipv6_reachs, lnode, + mt_ipv6_reachs)) + lsp_print_mt_ipv6_reach(mt_ipv6_reachs->list, vty, + mt_ipv6_reachs->mtid); + + /* TE IS neighbor tlv */ + lsp_print_mt_reach(lsp->tlv_data.te_is_neighs, vty, dynhost, + ISIS_MT_IPV4_UNICAST); + + /* MT IS neighbor tlv */ + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_is_neighs, lnode, + mt_is_neigh)) + lsp_print_mt_reach(mt_is_neigh->list, vty, dynhost, + mt_is_neigh->mtid); + + /* TE IPv4 tlv */ + lsp_print_mt_ipv4_reach(lsp->tlv_data.te_ipv4_reachs, vty, + ISIS_MT_IPV4_UNICAST); + + /* MT IPv4 reachability tlv */ + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_ipv4_reachs, lnode, + mt_ipv4_reachs)) + lsp_print_mt_ipv4_reach(mt_ipv4_reachs->list, vty, + mt_ipv4_reachs->mtid); + + vty_out(vty, "\n"); + + return; } /* print all the lsps info in the local lspdb */ -int -lsp_print_all (struct vty *vty, dict_t * lspdb, char detail, char dynhost) +int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost) { - dnode_t *node = dict_first (lspdb), *next; - int lsp_count = 0; - - if (detail == ISIS_UI_LEVEL_BRIEF) - { - while (node != NULL) - { - /* I think it is unnecessary, so I comment it out */ - /* dict_contains (lspdb, node); */ - next = dict_next (lspdb, node); - lsp_print (dnode_get (node), vty, dynhost); - node = next; - lsp_count++; - } - } - else if (detail == ISIS_UI_LEVEL_DETAIL) - { - while (node != NULL) - { - next = dict_next (lspdb, node); - lsp_print_detail (dnode_get (node), vty, dynhost); - node = next; - lsp_count++; - } - } - - return lsp_count; + dnode_t *node = dict_first(lspdb), *next; + int lsp_count = 0; + + if (detail == ISIS_UI_LEVEL_BRIEF) { + while (node != NULL) { + /* I think it is unnecessary, so I comment it out */ + /* dict_contains (lspdb, node); */ + next = dict_next(lspdb, node); + lsp_print(dnode_get(node), vty, dynhost); + node = next; + lsp_count++; + } + } else if (detail == ISIS_UI_LEVEL_DETAIL) { + while (node != NULL) { + next = dict_next(lspdb, node); + lsp_print_detail(dnode_get(node), vty, dynhost); + node = next; + lsp_count++; + } + } + + return lsp_count; } -static void -_lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to, - int frag_thold, - unsigned int tlv_build_func (struct list *, struct stream *, - void *arg), - void *arg) +static void _lsp_tlv_fit(struct isis_lsp *lsp, struct list **from, + struct list **to, int frag_thold, + unsigned int tlv_build_func(struct list *, + struct stream *, + void *arg), + void *arg) { - while (*from && listcount(*from)) - { - unsigned int count; - - count = tlv_build_func(*from, lsp->pdu, arg); - - if (listcount(*to) != 0 || count != listcount(*from)) - { - struct listnode *node, *nnode; - void *elem; - - for (ALL_LIST_ELEMENTS(*from, node, nnode, elem)) - { - if (!count) - break; - listnode_add (*to, elem); - list_delete_node (*from, node); - --count; - } - } - else - { - list_free (*to); - *to = *from; - *from = NULL; - } - } + while (*from && listcount(*from)) { + unsigned int count; + + count = tlv_build_func(*from, lsp->pdu, arg); + + if (listcount(*to) != 0 || count != listcount(*from)) { + struct listnode *node, *nnode; + void *elem; + + for (ALL_LIST_ELEMENTS(*from, node, nnode, elem)) { + if (!count) + break; + listnode_add(*to, elem); + list_delete_node(*from, node); + --count; + } + } else { + list_free(*to); + *to = *from; + *from = NULL; + } + } } -#define FRAG_THOLD(S,T) \ - ((STREAM_SIZE(S)*T)/100) +#define FRAG_THOLD(S, T) ((STREAM_SIZE(S) * T) / 100) /* stream*, area->lsp_frag_threshold, increment */ -#define FRAG_NEEDED(S,T,I) \ - (STREAM_SIZE(S)-STREAM_REMAIN(S)+(I) > FRAG_THOLD(S,T)) +#define FRAG_NEEDED(S, T, I) \ + (STREAM_SIZE(S) - STREAM_REMAIN(S) + (I) > FRAG_THOLD(S, T)) /* FIXME: It shouldn't be necessary to pass tlvsize here, TLVs can have * variable length (TE TLVs, sub TLVs). */ -static void -lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to, - int tlvsize, int frag_thold, - int tlv_build_func (struct list *, struct stream *)) +static void lsp_tlv_fit(struct isis_lsp *lsp, struct list **from, + struct list **to, int tlvsize, int frag_thold, + int tlv_build_func(struct list *, struct stream *)) { - int count, i; - - /* can we fit all ? */ - if (!FRAG_NEEDED (lsp->pdu, frag_thold, listcount (*from) * tlvsize + 2)) - { - tlv_build_func (*from, lsp->pdu); - if (listcount (*to) != 0) - { - struct listnode *node, *nextnode; - void *elem; - - for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem)) - { - listnode_add (*to, elem); - list_delete_node (*from, node); - } - } - else - { - list_free (*to); - *to = *from; - *from = NULL; - } - } - else if (!FRAG_NEEDED (lsp->pdu, frag_thold, tlvsize + 2)) - { - /* fit all we can */ - count = FRAG_THOLD (lsp->pdu, frag_thold) - 2 - - (STREAM_SIZE (lsp->pdu) - STREAM_REMAIN (lsp->pdu)); - count = count / tlvsize; - if (count > (int)listcount (*from)) - count = listcount (*from); - for (i = 0; i < count; i++) - { - listnode_add (*to, listgetdata (listhead (*from))); - listnode_delete (*from, listgetdata (listhead (*from))); - } - tlv_build_func (*to, lsp->pdu); - } - lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); - return; + int count, i; + + /* can we fit all ? */ + if (!FRAG_NEEDED(lsp->pdu, frag_thold, + listcount(*from) * tlvsize + 2)) { + tlv_build_func(*from, lsp->pdu); + if (listcount(*to) != 0) { + struct listnode *node, *nextnode; + void *elem; + + for (ALL_LIST_ELEMENTS(*from, node, nextnode, elem)) { + listnode_add(*to, elem); + list_delete_node(*from, node); + } + } else { + list_free(*to); + *to = *from; + *from = NULL; + } + } else if (!FRAG_NEEDED(lsp->pdu, frag_thold, tlvsize + 2)) { + /* fit all we can */ + count = FRAG_THOLD(lsp->pdu, frag_thold) - 2 + - (STREAM_SIZE(lsp->pdu) - STREAM_REMAIN(lsp->pdu)); + count = count / tlvsize; + if (count > (int)listcount(*from)) + count = listcount(*from); + for (i = 0; i < count; i++) { + listnode_add(*to, listgetdata(listhead(*from))); + listnode_delete(*from, listgetdata(listhead(*from))); + } + tlv_build_func(*to, lsp->pdu); + } + lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu)); + return; } -static u_int16_t -lsp_rem_lifetime (struct isis_area *area, int level) +static u_int16_t lsp_rem_lifetime(struct isis_area *area, int level) { - u_int16_t rem_lifetime; + u_int16_t rem_lifetime; - /* Add jitter to configured LSP lifetime */ - rem_lifetime = isis_jitter (area->max_lsp_lifetime[level - 1], - MAX_AGE_JITTER); + /* Add jitter to configured LSP lifetime */ + rem_lifetime = + isis_jitter(area->max_lsp_lifetime[level - 1], MAX_AGE_JITTER); - /* No jitter if the max refresh will be less than configure gen interval */ - /* N.B. this calucation is acceptable since rem_lifetime is in [332,65535] at - * this point */ - if (area->lsp_gen_interval[level - 1] > (rem_lifetime - 300)) - rem_lifetime = area->max_lsp_lifetime[level - 1]; + /* No jitter if the max refresh will be less than configure gen interval + */ + /* N.B. this calucation is acceptable since rem_lifetime is in + * [332,65535] at + * this point */ + if (area->lsp_gen_interval[level - 1] > (rem_lifetime - 300)) + rem_lifetime = area->max_lsp_lifetime[level - 1]; - return rem_lifetime; + return rem_lifetime; } -static u_int16_t -lsp_refresh_time (struct isis_lsp *lsp, u_int16_t rem_lifetime) +static u_int16_t lsp_refresh_time(struct isis_lsp *lsp, u_int16_t rem_lifetime) { - struct isis_area *area = lsp->area; - int level = lsp->level; - u_int16_t refresh_time; + struct isis_area *area = lsp->area; + int level = lsp->level; + u_int16_t refresh_time; - /* Add jitter to LSP refresh time */ - refresh_time = isis_jitter (area->lsp_refresh[level - 1], - MAX_LSP_GEN_JITTER); + /* Add jitter to LSP refresh time */ + refresh_time = + isis_jitter(area->lsp_refresh[level - 1], MAX_LSP_GEN_JITTER); - /* RFC 4444 : make sure the refresh time is at least less than 300 - * of the remaining lifetime and more than gen interval */ - if (refresh_time <= area->lsp_gen_interval[level - 1] || - refresh_time > (rem_lifetime - 300)) - refresh_time = rem_lifetime - 300; + /* RFC 4444 : make sure the refresh time is at least less than 300 + * of the remaining lifetime and more than gen interval */ + if (refresh_time <= area->lsp_gen_interval[level - 1] + || refresh_time > (rem_lifetime - 300)) + refresh_time = rem_lifetime - 300; - /* In cornercases, refresh_time might be <= lsp_gen_interval, however - * we accept this violation to satisfy refresh_time <= rem_lifetime - 300 */ + /* In cornercases, refresh_time might be <= lsp_gen_interval, however + * we accept this violation to satisfy refresh_time <= rem_lifetime - + * 300 */ - return refresh_time; + return refresh_time; } -static struct isis_lsp * -lsp_next_frag (u_char frag_num, struct isis_lsp *lsp0, struct isis_area *area, - int level) +static struct isis_lsp *lsp_next_frag(u_char frag_num, struct isis_lsp *lsp0, + struct isis_area *area, int level) { - struct isis_lsp *lsp; - u_char frag_id[ISIS_SYS_ID_LEN + 2]; - - memcpy (frag_id, lsp0->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT (frag_id) = frag_num; - /* FIXME add authentication TLV for fragment LSPs */ - lsp = lsp_search (frag_id, area->lspdb[level - 1]); - if (lsp) - { - /* Clear the TLVs */ - lsp_clear_data (lsp); - return lsp; - } - lsp = lsp_new (area, frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0, - lsp_bits_generate (level, area->overload_bit, - area->attached_bit), 0, level); - lsp->area = area; - lsp->own_lsp = 1; - lsp_insert (lsp, area->lspdb[level - 1]); - listnode_add (lsp0->lspu.frags, lsp); - lsp->lspu.zero_lsp = lsp0; - return lsp; + struct isis_lsp *lsp; + u_char frag_id[ISIS_SYS_ID_LEN + 2]; + + memcpy(frag_id, lsp0->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(frag_id) = frag_num; + /* FIXME add authentication TLV for fragment LSPs */ + lsp = lsp_search(frag_id, area->lspdb[level - 1]); + if (lsp) { + /* Clear the TLVs */ + lsp_clear_data(lsp); + return lsp; + } + lsp = lsp_new(area, frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0, + lsp_bits_generate(level, area->overload_bit, + area->attached_bit), + 0, level); + lsp->area = area; + lsp->own_lsp = 1; + lsp_insert(lsp, area->lspdb[level - 1]); + listnode_add(lsp0->lspu.frags, lsp); + lsp->lspu.zero_lsp = lsp0; + return lsp; } -static void -lsp_build_ext_reach_ipv4(struct isis_lsp *lsp, struct isis_area *area, - struct tlvs *tlv_data) +static void lsp_build_ext_reach_ipv4(struct isis_lsp *lsp, + struct isis_area *area, + struct tlvs *tlv_data) { - struct route_table *er_table; - struct route_node *rn; - struct prefix_ipv4 *ipv4; - struct isis_ext_info *info; - struct ipv4_reachability *ipreach; - struct te_ipv4_reachability *te_ipreach; - - er_table = get_ext_reach(area, AF_INET, lsp->level); - if (!er_table) - return; - - for (rn = route_top(er_table); rn; rn = route_next(rn)) - { - if (!rn->info) - continue; - - ipv4 = (struct prefix_ipv4*)&rn->p; - info = rn->info; - if (area->oldmetric) - { - if (tlv_data->ipv4_ext_reachs == NULL) - { - tlv_data->ipv4_ext_reachs = list_new(); - tlv_data->ipv4_ext_reachs->del = free_tlv; - } - ipreach = XMALLOC(MTYPE_ISIS_TLV, sizeof(*ipreach)); - - ipreach->prefix.s_addr = ipv4->prefix.s_addr; - masklen2ip(ipv4->prefixlen, &ipreach->mask); - ipreach->prefix.s_addr &= ipreach->mask.s_addr; - - if ((info->metric & 0x3f) != info->metric) - ipreach->metrics.metric_default = 0x3f; - else - ipreach->metrics.metric_default = info->metric; - ipreach->metrics.metric_expense = METRICS_UNSUPPORTED; - ipreach->metrics.metric_error = METRICS_UNSUPPORTED; - ipreach->metrics.metric_delay = METRICS_UNSUPPORTED; - listnode_add(tlv_data->ipv4_ext_reachs, ipreach); - } - if (area->newmetric) - { - if (tlv_data->te_ipv4_reachs == NULL) - { - tlv_data->te_ipv4_reachs = list_new(); - tlv_data->te_ipv4_reachs->del = free_tlv; - } - te_ipreach = - XCALLOC(MTYPE_ISIS_TLV, - sizeof(*te_ipreach) - 1 + PSIZE(ipv4->prefixlen)); - if (info->metric > MAX_WIDE_PATH_METRIC) - te_ipreach->te_metric = htonl(MAX_WIDE_PATH_METRIC); - else - te_ipreach->te_metric = htonl(info->metric); - te_ipreach->control = ipv4->prefixlen & 0x3f; - memcpy(&te_ipreach->prefix_start, &ipv4->prefix.s_addr, - PSIZE(ipv4->prefixlen)); - listnode_add(tlv_data->te_ipv4_reachs, te_ipreach); - } - } + struct route_table *er_table; + struct route_node *rn; + struct prefix_ipv4 *ipv4; + struct isis_ext_info *info; + struct ipv4_reachability *ipreach; + struct te_ipv4_reachability *te_ipreach; + + er_table = get_ext_reach(area, AF_INET, lsp->level); + if (!er_table) + return; + + for (rn = route_top(er_table); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + + ipv4 = (struct prefix_ipv4 *)&rn->p; + info = rn->info; + if (area->oldmetric) { + if (tlv_data->ipv4_ext_reachs == NULL) { + tlv_data->ipv4_ext_reachs = list_new(); + tlv_data->ipv4_ext_reachs->del = free_tlv; + } + ipreach = XMALLOC(MTYPE_ISIS_TLV, sizeof(*ipreach)); + + ipreach->prefix.s_addr = ipv4->prefix.s_addr; + masklen2ip(ipv4->prefixlen, &ipreach->mask); + ipreach->prefix.s_addr &= ipreach->mask.s_addr; + + if ((info->metric & 0x3f) != info->metric) + ipreach->metrics.metric_default = 0x3f; + else + ipreach->metrics.metric_default = info->metric; + ipreach->metrics.metric_expense = METRICS_UNSUPPORTED; + ipreach->metrics.metric_error = METRICS_UNSUPPORTED; + ipreach->metrics.metric_delay = METRICS_UNSUPPORTED; + listnode_add(tlv_data->ipv4_ext_reachs, ipreach); + } + if (area->newmetric) { + if (tlv_data->te_ipv4_reachs == NULL) { + tlv_data->te_ipv4_reachs = list_new(); + tlv_data->te_ipv4_reachs->del = free_tlv; + } + te_ipreach = XCALLOC(MTYPE_ISIS_TLV, + sizeof(*te_ipreach) - 1 + + PSIZE(ipv4->prefixlen)); + if (info->metric > MAX_WIDE_PATH_METRIC) + te_ipreach->te_metric = + htonl(MAX_WIDE_PATH_METRIC); + else + te_ipreach->te_metric = htonl(info->metric); + te_ipreach->control = ipv4->prefixlen & 0x3f; + memcpy(&te_ipreach->prefix_start, &ipv4->prefix.s_addr, + PSIZE(ipv4->prefixlen)); + listnode_add(tlv_data->te_ipv4_reachs, te_ipreach); + } + } } -static struct list * -tlv_get_ipv6_reach_list(struct isis_area *area, struct tlvs *tlv_data) +static struct list *tlv_get_ipv6_reach_list(struct isis_area *area, + struct tlvs *tlv_data) { - uint16_t mtid = isis_area_ipv6_topology(area); - if (mtid == ISIS_MT_IPV4_UNICAST) - { - if (!tlv_data->ipv6_reachs) - { - tlv_data->ipv6_reachs = list_new(); - tlv_data->ipv6_reachs->del = free_tlv; - } - return tlv_data->ipv6_reachs; - } - - struct tlv_mt_ipv6_reachs *reachs = tlvs_get_mt_ipv6_reachs(tlv_data, mtid); - return reachs->list; + uint16_t mtid = isis_area_ipv6_topology(area); + if (mtid == ISIS_MT_IPV4_UNICAST) { + if (!tlv_data->ipv6_reachs) { + tlv_data->ipv6_reachs = list_new(); + tlv_data->ipv6_reachs->del = free_tlv; + } + return tlv_data->ipv6_reachs; + } + + struct tlv_mt_ipv6_reachs *reachs = + tlvs_get_mt_ipv6_reachs(tlv_data, mtid); + return reachs->list; } -static void -lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, struct isis_area *area, - struct tlvs *tlv_data) +static void lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, + struct isis_area *area, + struct tlvs *tlv_data) { - struct route_table *er_table; - struct route_node *rn; - struct prefix_ipv6 *ipv6; - struct isis_ext_info *info; - struct ipv6_reachability *ip6reach; - struct list *reach_list = NULL; - - er_table = get_ext_reach(area, AF_INET6, lsp->level); - if (!er_table) - return; - - for (rn = route_top(er_table); rn; rn = route_next(rn)) - { - if (!rn->info) - continue; - - ipv6 = (struct prefix_ipv6*)&rn->p; - info = rn->info; - - if (!reach_list) - reach_list = tlv_get_ipv6_reach_list(area, tlv_data); - - ip6reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ip6reach)); - if (info->metric > MAX_WIDE_PATH_METRIC) - ip6reach->metric = htonl(MAX_WIDE_PATH_METRIC); - else - ip6reach->metric = htonl(info->metric); - ip6reach->control_info = DISTRIBUTION_EXTERNAL; - ip6reach->prefix_len = ipv6->prefixlen; - memcpy(ip6reach->prefix, ipv6->prefix.s6_addr, sizeof(ip6reach->prefix)); - listnode_add(reach_list, ip6reach); - } + struct route_table *er_table; + struct route_node *rn; + struct prefix_ipv6 *ipv6; + struct isis_ext_info *info; + struct ipv6_reachability *ip6reach; + struct list *reach_list = NULL; + + er_table = get_ext_reach(area, AF_INET6, lsp->level); + if (!er_table) + return; + + for (rn = route_top(er_table); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + + ipv6 = (struct prefix_ipv6 *)&rn->p; + info = rn->info; + + if (!reach_list) + reach_list = tlv_get_ipv6_reach_list(area, tlv_data); + + ip6reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ip6reach)); + if (info->metric > MAX_WIDE_PATH_METRIC) + ip6reach->metric = htonl(MAX_WIDE_PATH_METRIC); + else + ip6reach->metric = htonl(info->metric); + ip6reach->control_info = DISTRIBUTION_EXTERNAL; + ip6reach->prefix_len = ipv6->prefixlen; + memcpy(ip6reach->prefix, ipv6->prefix.s6_addr, + sizeof(ip6reach->prefix)); + listnode_add(reach_list, ip6reach); + } } -static void -lsp_build_ext_reach (struct isis_lsp *lsp, struct isis_area *area, - struct tlvs *tlv_data) +static void lsp_build_ext_reach(struct isis_lsp *lsp, struct isis_area *area, + struct tlvs *tlv_data) { - lsp_build_ext_reach_ipv4(lsp, area, tlv_data); - lsp_build_ext_reach_ipv6(lsp, area, tlv_data); + lsp_build_ext_reach_ipv4(lsp, area, tlv_data); + lsp_build_ext_reach_ipv6(lsp, area, tlv_data); } /* - * Builds the LSP data part. This func creates a new frag whenever + * Builds the LSP data part. This func creates a new frag whenever * area->lsp_frag_threshold is exceeded. */ -static void -lsp_build (struct isis_lsp *lsp, struct isis_area *area) +static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) { - struct is_neigh *is_neigh; - struct te_is_neigh *te_is_neigh; - struct listnode *node, *ipnode; - int level = lsp->level; - struct isis_circuit *circuit; - struct prefix_ipv4 *ipv4; - struct ipv4_reachability *ipreach; - struct te_ipv4_reachability *te_ipreach; - struct isis_adjacency *nei; - struct prefix_ipv6 *ipv6, ip6prefix; - struct list *ipv6_reachs = NULL; - struct ipv6_reachability *ip6reach; - struct tlvs tlv_data; - struct isis_lsp *lsp0 = lsp; - struct in_addr *routerid; - uint32_t expected = 0, found = 0; - uint32_t metric; - u_char zero_id[ISIS_SYS_ID_LEN + 1]; - int retval = ISIS_OK; - char buf[BUFSIZ]; - - lsp_debug("ISIS (%s): Constructing local system LSP for level %d", area->area_tag, level); - - /* - * Building the zero lsp - */ - memset (zero_id, 0, ISIS_SYS_ID_LEN + 1); - - /* Reset stream endp. Stream is always there and on every LSP refresh only - * TLV part of it is overwritten. So we must seek past header we will not - * touch. */ - stream_reset (lsp->pdu); - stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - - /* - * Add the authentication info if its present - */ - lsp_auth_add (lsp); - - /* - * First add the tlvs related to area - */ - - /* Area addresses */ - if (lsp->tlv_data.area_addrs == NULL) - lsp->tlv_data.area_addrs = list_new (); - list_add_list (lsp->tlv_data.area_addrs, area->area_addrs); - if (listcount (lsp->tlv_data.area_addrs) > 0) - tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu); - - /* Protocols Supported */ - if (area->ip_circuits > 0 || area->ipv6_circuits > 0) - { - lsp->tlv_data.nlpids = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct nlpids)); - lsp->tlv_data.nlpids->count = 0; - if (area->ip_circuits > 0) - { - lsp_debug("ISIS (%s): Found IPv4 circuit, adding IPv4 to NLPIDs", area->area_tag); - lsp->tlv_data.nlpids->count++; - lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP; - } - if (area->ipv6_circuits > 0) - { - lsp_debug("ISIS (%s): Found IPv6 circuit, adding IPv6 to NLPIDs", area->area_tag); - lsp->tlv_data.nlpids->count++; - lsp->tlv_data.nlpids->nlpids[lsp->tlv_data.nlpids->count - 1] = - NLPID_IPV6; - } - tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu); - } - - if (area_is_mt(area)) - { - lsp_debug("ISIS (%s): Adding MT router tlv...", area->area_tag); - lsp->tlv_data.mt_router_info = list_new(); - lsp->tlv_data.mt_router_info->del = free_tlv; - - struct isis_area_mt_setting **mt_settings; - unsigned int mt_count; - - mt_settings = area_mt_settings(area, &mt_count); - for (unsigned int i = 0; i < mt_count; i++) - { - struct mt_router_info *info; - - info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info)); - info->mtid = mt_settings[i]->mtid; - info->overload = mt_settings[i]->overload; - listnode_add(lsp->tlv_data.mt_router_info, info); - lsp_debug("ISIS (%s): MT %s", area->area_tag, isis_mtid2str(info->mtid)); - } - tlv_add_mt_router_info (lsp->tlv_data.mt_router_info, lsp->pdu); - } - else - { - lsp_debug("ISIS (%s): Not adding MT router tlv (disabled)", area->area_tag); - } - /* Dynamic Hostname */ - if (area->dynhostname) - { - const char *hostname = unix_hostname(); - size_t hostname_len = strlen(hostname); - - lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV, - sizeof (struct hostname)); - - strncpy((char *)lsp->tlv_data.hostname->name, hostname, - sizeof(lsp->tlv_data.hostname->name)); - if (hostname_len <= MAX_TLV_LEN) - lsp->tlv_data.hostname->namelen = hostname_len; - else - lsp->tlv_data.hostname->namelen = MAX_TLV_LEN; - - lsp_debug("ISIS (%s): Adding dynamic hostname '%.*s'", area->area_tag, - lsp->tlv_data.hostname->namelen, lsp->tlv_data.hostname->name); - tlv_add_dynamic_hostname (lsp->tlv_data.hostname, lsp->pdu); - } - else - { - lsp_debug("ISIS (%s): Not adding dynamic hostname (disabled)", area->area_tag); - } - - /* IPv4 address and TE router ID TLVs. In case of the first one we don't - * follow "C" vendor, but "J" vendor behavior - one IPv4 address is put into - * LSP and this address is same as router id. */ - if (isis->router_id != 0) - { - inet_ntop(AF_INET, &isis->router_id, buf, sizeof(buf)); - lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.", area->area_tag, buf); - if (lsp->tlv_data.ipv4_addrs == NULL) - { - lsp->tlv_data.ipv4_addrs = list_new (); - lsp->tlv_data.ipv4_addrs->del = free_tlv; - } - - routerid = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct in_addr)); - routerid->s_addr = isis->router_id; - listnode_add (lsp->tlv_data.ipv4_addrs, routerid); - tlv_add_in_addr (routerid, lsp->pdu, IPV4_ADDR); - - /* Exactly same data is put into TE router ID TLV, but only if new style - * TLV's are in use. */ - if (area->newmetric) - { - lsp_debug("ISIS (%s): Adding router ID also as TE router ID tlv.", area->area_tag); - lsp->tlv_data.router_id = XMALLOC (MTYPE_ISIS_TLV, - sizeof (struct in_addr)); - lsp->tlv_data.router_id->id.s_addr = isis->router_id; - tlv_add_in_addr (&lsp->tlv_data.router_id->id, lsp->pdu, - TE_ROUTER_ID); - } - } - else - { - lsp_debug("ISIS (%s): Router ID is unset. Not adding tlv.", area->area_tag); - } - - memset (&tlv_data, 0, sizeof (struct tlvs)); - - lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag); - - /* - * Then build lists of tlvs related to circuits - */ - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) - { - if (!circuit->interface) - lsp_debug("ISIS (%s): Processing %s circuit %p with unknown interface", - area->area_tag, circuit_type2string(circuit->circ_type), circuit); - else - lsp_debug("ISIS (%s): Processing %s circuit %s", - area->area_tag, circuit_type2string(circuit->circ_type), circuit->interface->name); - - if (circuit->state != C_STATE_UP) - { - lsp_debug("ISIS (%s): Circuit is not up, ignoring.", area->area_tag); - continue; - } - - /* - * Add IPv4 internal reachability of this circuit - */ - if (circuit->ip_router && circuit->ip_addrs && - circuit->ip_addrs->count > 0) - { - lsp_debug("ISIS (%s): Circuit has IPv4 active, adding respective TLVs.", area->area_tag); - if (area->oldmetric) - { - if (tlv_data.ipv4_int_reachs == NULL) - { - tlv_data.ipv4_int_reachs = list_new (); - tlv_data.ipv4_int_reachs->del = free_tlv; + struct is_neigh *is_neigh; + struct te_is_neigh *te_is_neigh; + struct listnode *node, *ipnode; + int level = lsp->level; + struct isis_circuit *circuit; + struct prefix_ipv4 *ipv4; + struct ipv4_reachability *ipreach; + struct te_ipv4_reachability *te_ipreach; + struct isis_adjacency *nei; + struct prefix_ipv6 *ipv6, ip6prefix; + struct list *ipv6_reachs = NULL; + struct ipv6_reachability *ip6reach; + struct tlvs tlv_data; + struct isis_lsp *lsp0 = lsp; + struct in_addr *routerid; + uint32_t expected = 0, found = 0; + uint32_t metric; + u_char zero_id[ISIS_SYS_ID_LEN + 1]; + int retval = ISIS_OK; + char buf[BUFSIZ]; + + lsp_debug("ISIS (%s): Constructing local system LSP for level %d", + area->area_tag, level); + + /* + * Building the zero lsp + */ + memset(zero_id, 0, ISIS_SYS_ID_LEN + 1); + + /* Reset stream endp. Stream is always there and on every LSP refresh + * only + * TLV part of it is overwritten. So we must seek past header we will + * not + * touch. */ + stream_reset(lsp->pdu); + stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + + /* + * Add the authentication info if its present + */ + lsp_auth_add(lsp); + + /* + * First add the tlvs related to area + */ + + /* Area addresses */ + if (lsp->tlv_data.area_addrs == NULL) + lsp->tlv_data.area_addrs = list_new(); + list_add_list(lsp->tlv_data.area_addrs, area->area_addrs); + if (listcount(lsp->tlv_data.area_addrs) > 0) + tlv_add_area_addrs(lsp->tlv_data.area_addrs, lsp->pdu); + + /* Protocols Supported */ + if (area->ip_circuits > 0 || area->ipv6_circuits > 0) { + lsp->tlv_data.nlpids = + XCALLOC(MTYPE_ISIS_TLV, sizeof(struct nlpids)); + lsp->tlv_data.nlpids->count = 0; + if (area->ip_circuits > 0) { + lsp_debug( + "ISIS (%s): Found IPv4 circuit, adding IPv4 to NLPIDs", + area->area_tag); + lsp->tlv_data.nlpids->count++; + lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP; + } + if (area->ipv6_circuits > 0) { + lsp_debug( + "ISIS (%s): Found IPv6 circuit, adding IPv6 to NLPIDs", + area->area_tag); + lsp->tlv_data.nlpids->count++; + lsp->tlv_data.nlpids + ->nlpids[lsp->tlv_data.nlpids->count - 1] = + NLPID_IPV6; + } + tlv_add_nlpid(lsp->tlv_data.nlpids, lsp->pdu); + } + + if (area_is_mt(area)) { + lsp_debug("ISIS (%s): Adding MT router tlv...", area->area_tag); + lsp->tlv_data.mt_router_info = list_new(); + lsp->tlv_data.mt_router_info->del = free_tlv; + + struct isis_area_mt_setting **mt_settings; + unsigned int mt_count; + + mt_settings = area_mt_settings(area, &mt_count); + for (unsigned int i = 0; i < mt_count; i++) { + struct mt_router_info *info; + + info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info)); + info->mtid = mt_settings[i]->mtid; + info->overload = mt_settings[i]->overload; + listnode_add(lsp->tlv_data.mt_router_info, info); + lsp_debug("ISIS (%s): MT %s", area->area_tag, + isis_mtid2str(info->mtid)); } - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, ipnode, ipv4)) - { - ipreach = - XMALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv4_reachability)); - ipreach->metrics.metric_default = circuit->metric[level - 1]; - ipreach->metrics.metric_expense = METRICS_UNSUPPORTED; - ipreach->metrics.metric_error = METRICS_UNSUPPORTED; - ipreach->metrics.metric_delay = METRICS_UNSUPPORTED; - masklen2ip (ipv4->prefixlen, &ipreach->mask); - ipreach->prefix.s_addr = ((ipreach->mask.s_addr) & - (ipv4->prefix.s_addr)); - inet_ntop(AF_INET, &ipreach->prefix.s_addr, buf, sizeof(buf)); - lsp_debug("ISIS (%s): Adding old-style IP reachability for %s/%d", - area->area_tag, buf, ipv4->prefixlen); - listnode_add (tlv_data.ipv4_int_reachs, ipreach); + tlv_add_mt_router_info(lsp->tlv_data.mt_router_info, lsp->pdu); + } else { + lsp_debug("ISIS (%s): Not adding MT router tlv (disabled)", + area->area_tag); + } + /* Dynamic Hostname */ + if (area->dynhostname) { + const char *hostname = unix_hostname(); + size_t hostname_len = strlen(hostname); + + lsp->tlv_data.hostname = + XMALLOC(MTYPE_ISIS_TLV, sizeof(struct hostname)); + + strncpy((char *)lsp->tlv_data.hostname->name, hostname, + sizeof(lsp->tlv_data.hostname->name)); + if (hostname_len <= MAX_TLV_LEN) + lsp->tlv_data.hostname->namelen = hostname_len; + else + lsp->tlv_data.hostname->namelen = MAX_TLV_LEN; + + lsp_debug("ISIS (%s): Adding dynamic hostname '%.*s'", + area->area_tag, lsp->tlv_data.hostname->namelen, + lsp->tlv_data.hostname->name); + tlv_add_dynamic_hostname(lsp->tlv_data.hostname, lsp->pdu); + } else { + lsp_debug("ISIS (%s): Not adding dynamic hostname (disabled)", + area->area_tag); + } + + /* IPv4 address and TE router ID TLVs. In case of the first one we don't + * follow "C" vendor, but "J" vendor behavior - one IPv4 address is put + * into + * LSP and this address is same as router id. */ + if (isis->router_id != 0) { + inet_ntop(AF_INET, &isis->router_id, buf, sizeof(buf)); + lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.", + area->area_tag, buf); + if (lsp->tlv_data.ipv4_addrs == NULL) { + lsp->tlv_data.ipv4_addrs = list_new(); + lsp->tlv_data.ipv4_addrs->del = free_tlv; } - } - if (area->newmetric) - { - if (tlv_data.te_ipv4_reachs == NULL) - { - tlv_data.te_ipv4_reachs = list_new (); - tlv_data.te_ipv4_reachs->del = free_tlv; + + routerid = XMALLOC(MTYPE_ISIS_TLV, sizeof(struct in_addr)); + routerid->s_addr = isis->router_id; + listnode_add(lsp->tlv_data.ipv4_addrs, routerid); + tlv_add_in_addr(routerid, lsp->pdu, IPV4_ADDR); + + /* Exactly same data is put into TE router ID TLV, but only if + * new style + * TLV's are in use. */ + if (area->newmetric) { + lsp_debug( + "ISIS (%s): Adding router ID also as TE router ID tlv.", + area->area_tag); + lsp->tlv_data.router_id = + XMALLOC(MTYPE_ISIS_TLV, sizeof(struct in_addr)); + lsp->tlv_data.router_id->id.s_addr = isis->router_id; + tlv_add_in_addr(&lsp->tlv_data.router_id->id, lsp->pdu, + TE_ROUTER_ID); } - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, ipnode, ipv4)) - { - /* FIXME All this assumes that we have no sub TLVs. */ - te_ipreach = XCALLOC (MTYPE_ISIS_TLV, - sizeof (struct te_ipv4_reachability) + - ((ipv4->prefixlen + 7)/8) - 1); - - if (area->oldmetric) - te_ipreach->te_metric = htonl (circuit->metric[level - 1]); - else - te_ipreach->te_metric = htonl (circuit->te_metric[level - 1]); - - te_ipreach->control = (ipv4->prefixlen & 0x3F); - memcpy (&te_ipreach->prefix_start, &ipv4->prefix.s_addr, - (ipv4->prefixlen + 7)/8); - inet_ntop(AF_INET, &ipv4->prefix.s_addr, buf, sizeof(buf)); - lsp_debug("ISIS (%s): Adding te-style IP reachability for %s/%d", - area->area_tag, buf, ipv4->prefixlen); - listnode_add (tlv_data.te_ipv4_reachs, te_ipreach); + } else { + lsp_debug("ISIS (%s): Router ID is unset. Not adding tlv.", + area->area_tag); + } + + memset(&tlv_data, 0, sizeof(struct tlvs)); + + lsp_debug("ISIS (%s): Adding circuit specific information.", + area->area_tag); + + /* + * Then build lists of tlvs related to circuits + */ + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (!circuit->interface) + lsp_debug( + "ISIS (%s): Processing %s circuit %p with unknown interface", + area->area_tag, + circuit_type2string(circuit->circ_type), + circuit); + else + lsp_debug("ISIS (%s): Processing %s circuit %s", + area->area_tag, + circuit_type2string(circuit->circ_type), + circuit->interface->name); + + if (circuit->state != C_STATE_UP) { + lsp_debug("ISIS (%s): Circuit is not up, ignoring.", + area->area_tag); + continue; } - } - } - - /* - * Add IPv6 reachability of this circuit - */ - if (circuit->ipv6_router && circuit->ipv6_non_link && - circuit->ipv6_non_link->count > 0) - { - if (!ipv6_reachs) - ipv6_reachs = tlv_get_ipv6_reach_list(area, &tlv_data); - - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, ipnode, ipv6)) - { - ip6reach = - XCALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv6_reachability)); - - if (area->oldmetric) - ip6reach->metric = - htonl (circuit->metric[level - 1]); - else - ip6reach->metric = htonl (circuit->te_metric[level - 1]); - - ip6reach->control_info = 0; - ip6reach->prefix_len = ipv6->prefixlen; - memcpy(&ip6prefix, ipv6, sizeof(ip6prefix)); - apply_mask_ipv6(&ip6prefix); - - inet_ntop(AF_INET6, &ip6prefix.prefix.s6_addr, buf, sizeof(buf)); - lsp_debug("ISIS (%s): Adding IPv6 reachability for %s/%d", - area->area_tag, buf, ipv6->prefixlen); - - memcpy (ip6reach->prefix, ip6prefix.prefix.s6_addr, - sizeof (ip6reach->prefix)); - listnode_add (ipv6_reachs, ip6reach); - } - } - - switch (circuit->circ_type) - { - case CIRCUIT_T_BROADCAST: - if (level & circuit->is_type) - { - if (area->oldmetric) - { - if (tlv_data.is_neighs == NULL) - { - tlv_data.is_neighs = list_new (); - tlv_data.is_neighs->del = free_tlv; - } - is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh)); - if (level == IS_LEVEL_1) - memcpy (is_neigh->neigh_id, - circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); - else - memcpy (is_neigh->neigh_id, - circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1); - is_neigh->metrics.metric_default = circuit->metric[level - 1]; - is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED; - is_neigh->metrics.metric_error = METRICS_UNSUPPORTED; - is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED; - if (!memcmp (is_neigh->neigh_id, zero_id, - ISIS_SYS_ID_LEN + 1)) - { - XFREE (MTYPE_ISIS_TLV, is_neigh); - lsp_debug("ISIS (%s): No DIS for circuit, not adding old-style IS neighbor.", - area->area_tag); - } - else - { - listnode_add (tlv_data.is_neighs, is_neigh); - lsp_debug("ISIS (%s): Adding DIS %s.%02x as old-style neighbor", - area->area_tag, sysid_print(is_neigh->neigh_id), - LSP_PSEUDO_ID(is_neigh->neigh_id)); - } + + /* + * Add IPv4 internal reachability of this circuit + */ + if (circuit->ip_router && circuit->ip_addrs + && circuit->ip_addrs->count > 0) { + lsp_debug( + "ISIS (%s): Circuit has IPv4 active, adding respective TLVs.", + area->area_tag); + if (area->oldmetric) { + if (tlv_data.ipv4_int_reachs == NULL) { + tlv_data.ipv4_int_reachs = list_new(); + tlv_data.ipv4_int_reachs->del = + free_tlv; + } + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, + ipnode, ipv4)) { + ipreach = XMALLOC( + MTYPE_ISIS_TLV, + sizeof(struct + ipv4_reachability)); + ipreach->metrics.metric_default = + circuit->metric[level - 1]; + ipreach->metrics.metric_expense = + METRICS_UNSUPPORTED; + ipreach->metrics.metric_error = + METRICS_UNSUPPORTED; + ipreach->metrics.metric_delay = + METRICS_UNSUPPORTED; + masklen2ip(ipv4->prefixlen, + &ipreach->mask); + ipreach->prefix.s_addr = + ((ipreach->mask.s_addr) + & (ipv4->prefix.s_addr)); + inet_ntop(AF_INET, + &ipreach->prefix.s_addr, buf, + sizeof(buf)); + lsp_debug( + "ISIS (%s): Adding old-style IP reachability for %s/%d", + area->area_tag, buf, + ipv4->prefixlen); + listnode_add(tlv_data.ipv4_int_reachs, + ipreach); + } + } + if (area->newmetric) { + if (tlv_data.te_ipv4_reachs == NULL) { + tlv_data.te_ipv4_reachs = list_new(); + tlv_data.te_ipv4_reachs->del = free_tlv; + } + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, + ipnode, ipv4)) { + /* FIXME All this assumes that we have + * no sub TLVs. */ + te_ipreach = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct + te_ipv4_reachability) + + ((ipv4->prefixlen + 7) + / 8) + - 1); + + if (area->oldmetric) + te_ipreach->te_metric = htonl( + circuit->metric[level + - 1]); + else + te_ipreach->te_metric = htonl( + circuit->te_metric + [level - 1]); + + te_ipreach->control = + (ipv4->prefixlen & 0x3F); + memcpy(&te_ipreach->prefix_start, + &ipv4->prefix.s_addr, + (ipv4->prefixlen + 7) / 8); + inet_ntop(AF_INET, &ipv4->prefix.s_addr, + buf, sizeof(buf)); + lsp_debug( + "ISIS (%s): Adding te-style IP reachability for %s/%d", + area->area_tag, buf, + ipv4->prefixlen); + listnode_add(tlv_data.te_ipv4_reachs, + te_ipreach); + } + } } - if (area->newmetric) - { - if (tlv_data.te_is_neighs == NULL) - { - tlv_data.te_is_neighs = list_new (); - tlv_data.te_is_neighs->del = free_tlv; - } - te_is_neigh = XCALLOC (MTYPE_ISIS_TLV, - sizeof (struct te_is_neigh)); - if (level == IS_LEVEL_1) - memcpy (te_is_neigh->neigh_id, - circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); - else - memcpy (te_is_neigh->neigh_id, - circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1); - if (area->oldmetric) - metric = circuit->metric[level - 1]; - else - metric = circuit->te_metric[level - 1]; - SET_TE_METRIC(te_is_neigh, metric); - if (!memcmp (te_is_neigh->neigh_id, zero_id, - ISIS_SYS_ID_LEN + 1)) - { - XFREE (MTYPE_ISIS_TLV, te_is_neigh); - lsp_debug("ISIS (%s): No DIS for circuit, not adding te-style IS neighbor.", - area->area_tag); - } - else - { - /* Check if MPLS_TE is activate */ - if (IS_MPLS_TE(isisMplsTE) && HAS_LINK_PARAMS(circuit->interface)) - /* Add SubTLVs & Adjust real size of SubTLVs */ - te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc); - else - /* Or keep only TE metric with no SubTLVs if MPLS_TE is off */ - te_is_neigh->sub_tlvs_length = 0; - - tlvs_add_mt_bcast(&tlv_data, circuit, level, te_is_neigh); - XFREE(MTYPE_ISIS_TLV, te_is_neigh); - } + + /* + * Add IPv6 reachability of this circuit + */ + if (circuit->ipv6_router && circuit->ipv6_non_link + && circuit->ipv6_non_link->count > 0) { + if (!ipv6_reachs) + ipv6_reachs = tlv_get_ipv6_reach_list( + area, &tlv_data); + + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, + ipnode, ipv6)) { + ip6reach = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct ipv6_reachability)); + + if (area->oldmetric) + ip6reach->metric = htonl( + circuit->metric[level - 1]); + else + ip6reach->metric = htonl( + circuit->te_metric[level - 1]); + + ip6reach->control_info = 0; + ip6reach->prefix_len = ipv6->prefixlen; + memcpy(&ip6prefix, ipv6, sizeof(ip6prefix)); + apply_mask_ipv6(&ip6prefix); + + inet_ntop(AF_INET6, &ip6prefix.prefix.s6_addr, + buf, sizeof(buf)); + lsp_debug( + "ISIS (%s): Adding IPv6 reachability for %s/%d", + area->area_tag, buf, ipv6->prefixlen); + + memcpy(ip6reach->prefix, + ip6prefix.prefix.s6_addr, + sizeof(ip6reach->prefix)); + listnode_add(ipv6_reachs, ip6reach); + } } - } - else - { - lsp_debug("ISIS (%s): Circuit is not active for current level. Not adding IS neighbors", - area->area_tag); - } - break; - case CIRCUIT_T_P2P: - nei = circuit->u.p2p.neighbor; - if (nei && (level & nei->circuit_t)) - { - if (area->oldmetric) - { - if (tlv_data.is_neighs == NULL) - { - tlv_data.is_neighs = list_new (); - tlv_data.is_neighs->del = free_tlv; - } - is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh)); - memcpy (is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN); - is_neigh->metrics.metric_default = circuit->metric[level - 1]; - is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED; - is_neigh->metrics.metric_error = METRICS_UNSUPPORTED; - is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED; - listnode_add (tlv_data.is_neighs, is_neigh); - lsp_debug("ISIS (%s): Adding old-style is reach for %s", area->area_tag, - sysid_print(is_neigh->neigh_id)); + + switch (circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + if (level & circuit->is_type) { + if (area->oldmetric) { + if (tlv_data.is_neighs == NULL) { + tlv_data.is_neighs = list_new(); + tlv_data.is_neighs->del = + free_tlv; + } + is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct is_neigh)); + if (level == IS_LEVEL_1) + memcpy(is_neigh->neigh_id, + circuit->u.bc + .l1_desig_is, + ISIS_SYS_ID_LEN + 1); + else + memcpy(is_neigh->neigh_id, + circuit->u.bc + .l2_desig_is, + ISIS_SYS_ID_LEN + 1); + is_neigh->metrics.metric_default = + circuit->metric[level - 1]; + is_neigh->metrics.metric_expense = + METRICS_UNSUPPORTED; + is_neigh->metrics.metric_error = + METRICS_UNSUPPORTED; + is_neigh->metrics.metric_delay = + METRICS_UNSUPPORTED; + if (!memcmp(is_neigh->neigh_id, zero_id, + ISIS_SYS_ID_LEN + 1)) { + XFREE(MTYPE_ISIS_TLV, is_neigh); + lsp_debug( + "ISIS (%s): No DIS for circuit, not adding old-style IS neighbor.", + area->area_tag); + } else { + listnode_add(tlv_data.is_neighs, + is_neigh); + lsp_debug( + "ISIS (%s): Adding DIS %s.%02x as old-style neighbor", + area->area_tag, + sysid_print( + is_neigh->neigh_id), + LSP_PSEUDO_ID( + is_neigh->neigh_id)); + } + } + if (area->newmetric) { + if (tlv_data.te_is_neighs == NULL) { + tlv_data.te_is_neighs = + list_new(); + tlv_data.te_is_neighs->del = + free_tlv; + } + te_is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct te_is_neigh)); + if (level == IS_LEVEL_1) + memcpy(te_is_neigh->neigh_id, + circuit->u.bc + .l1_desig_is, + ISIS_SYS_ID_LEN + 1); + else + memcpy(te_is_neigh->neigh_id, + circuit->u.bc + .l2_desig_is, + ISIS_SYS_ID_LEN + 1); + if (area->oldmetric) + metric = circuit->metric[level + - 1]; + else + metric = + circuit->te_metric[level + - 1]; + SET_TE_METRIC(te_is_neigh, metric); + if (!memcmp(te_is_neigh->neigh_id, + zero_id, + ISIS_SYS_ID_LEN + 1)) { + XFREE(MTYPE_ISIS_TLV, + te_is_neigh); + lsp_debug( + "ISIS (%s): No DIS for circuit, not adding te-style IS neighbor.", + area->area_tag); + } else { + /* Check if MPLS_TE is activate + */ + if (IS_MPLS_TE(isisMplsTE) + && HAS_LINK_PARAMS( + circuit->interface)) + /* Add SubTLVs & Adjust + * real size of SubTLVs + */ + te_is_neigh + ->sub_tlvs_length = add_te_subtlvs( + te_is_neigh + ->sub_tlvs, + circuit->mtc); + else + /* Or keep only TE + * metric with no + * SubTLVs if MPLS_TE is + * off */ + te_is_neigh + ->sub_tlvs_length = + 0; + + tlvs_add_mt_bcast( + &tlv_data, circuit, + level, te_is_neigh); + XFREE(MTYPE_ISIS_TLV, + te_is_neigh); + } + } + } else { + lsp_debug( + "ISIS (%s): Circuit is not active for current level. Not adding IS neighbors", + area->area_tag); + } + break; + case CIRCUIT_T_P2P: + nei = circuit->u.p2p.neighbor; + if (nei && (level & nei->circuit_t)) { + if (area->oldmetric) { + if (tlv_data.is_neighs == NULL) { + tlv_data.is_neighs = list_new(); + tlv_data.is_neighs->del = + free_tlv; + } + is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct is_neigh)); + memcpy(is_neigh->neigh_id, nei->sysid, + ISIS_SYS_ID_LEN); + is_neigh->metrics.metric_default = + circuit->metric[level - 1]; + is_neigh->metrics.metric_expense = + METRICS_UNSUPPORTED; + is_neigh->metrics.metric_error = + METRICS_UNSUPPORTED; + is_neigh->metrics.metric_delay = + METRICS_UNSUPPORTED; + listnode_add(tlv_data.is_neighs, + is_neigh); + lsp_debug( + "ISIS (%s): Adding old-style is reach for %s", + area->area_tag, + sysid_print( + is_neigh->neigh_id)); + } + if (area->newmetric) { + uint32_t metric; + + if (tlv_data.te_is_neighs == NULL) { + tlv_data.te_is_neighs = + list_new(); + tlv_data.te_is_neighs->del = + free_tlv; + } + te_is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct te_is_neigh)); + memcpy(te_is_neigh->neigh_id, + nei->sysid, ISIS_SYS_ID_LEN); + metric = circuit->te_metric[level - 1]; + SET_TE_METRIC(te_is_neigh, metric); + /* Check if MPLS_TE is activate */ + if (IS_MPLS_TE(isisMplsTE) + && HAS_LINK_PARAMS( + circuit->interface)) + /* Update Local and Remote IP + * address for MPLS TE circuit + * parameters */ + /* NOTE sure that it is the + * pertinent place for that + * updates */ + /* Local IP address could be + * updated in isis_circuit.c - + * isis_circuit_add_addr() */ + /* But, where update remote IP + * address ? in isis_pdu.c - + * process_p2p_hello() ? */ + + /* Add SubTLVs & Adjust real + * size of SubTLVs */ + te_is_neigh->sub_tlvs_length = + add_te_subtlvs( + te_is_neigh + ->sub_tlvs, + circuit->mtc); + else + /* Or keep only TE metric with + * no SubTLVs if MPLS_TE is off + */ + te_is_neigh->sub_tlvs_length = + 0; + + tlvs_add_mt_p2p(&tlv_data, circuit, + te_is_neigh); + XFREE(MTYPE_ISIS_TLV, te_is_neigh); + } + } else { + lsp_debug( + "ISIS (%s): No adjacency for given level on this circuit. Not adding IS neighbors", + area->area_tag); + } + break; + case CIRCUIT_T_LOOPBACK: + break; + default: + zlog_warn("lsp_area_create: unknown circuit type"); } - if (area->newmetric) - { - uint32_t metric; - - if (tlv_data.te_is_neighs == NULL) - { - tlv_data.te_is_neighs = list_new (); - tlv_data.te_is_neighs->del = free_tlv; - } - te_is_neigh = XCALLOC (MTYPE_ISIS_TLV, - sizeof (struct te_is_neigh)); - memcpy (te_is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN); - metric = circuit->te_metric[level - 1]; - SET_TE_METRIC(te_is_neigh, metric); - /* Check if MPLS_TE is activate */ - if (IS_MPLS_TE(isisMplsTE) && HAS_LINK_PARAMS(circuit->interface)) - /* Update Local and Remote IP address for MPLS TE circuit parameters */ - /* NOTE sure that it is the pertinent place for that updates */ - /* Local IP address could be updated in isis_circuit.c - isis_circuit_add_addr() */ - /* But, where update remote IP address ? in isis_pdu.c - process_p2p_hello() ? */ - - /* Add SubTLVs & Adjust real size of SubTLVs */ - te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc); - else - /* Or keep only TE metric with no SubTLVs if MPLS_TE is off */ - te_is_neigh->sub_tlvs_length = 0; - - tlvs_add_mt_p2p(&tlv_data, circuit, te_is_neigh); - XFREE(MTYPE_ISIS_TLV, te_is_neigh); + } + + lsp_build_ext_reach(lsp, area, &tlv_data); + + lsp_debug("ISIS (%s): LSP construction is complete. Serializing...", + area->area_tag); + + while (tlv_data.ipv4_int_reachs + && listcount(tlv_data.ipv4_int_reachs)) { + if (lsp->tlv_data.ipv4_int_reachs == NULL) + lsp->tlv_data.ipv4_int_reachs = list_new(); + lsp_tlv_fit(lsp, &tlv_data.ipv4_int_reachs, + &lsp->tlv_data.ipv4_int_reachs, IPV4_REACH_LEN, + area->lsp_frag_threshold, tlv_add_ipv4_int_reachs); + if (tlv_data.ipv4_int_reachs + && listcount(tlv_data.ipv4_int_reachs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + while (tlv_data.ipv4_ext_reachs + && listcount(tlv_data.ipv4_ext_reachs)) { + if (lsp->tlv_data.ipv4_ext_reachs == NULL) + lsp->tlv_data.ipv4_ext_reachs = list_new(); + lsp_tlv_fit(lsp, &tlv_data.ipv4_ext_reachs, + &lsp->tlv_data.ipv4_ext_reachs, IPV4_REACH_LEN, + area->lsp_frag_threshold, tlv_add_ipv4_ext_reachs); + if (tlv_data.ipv4_ext_reachs + && listcount(tlv_data.ipv4_ext_reachs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + while (tlv_data.te_ipv4_reachs && listcount(tlv_data.te_ipv4_reachs)) { + if (lsp->tlv_data.te_ipv4_reachs == NULL) + lsp->tlv_data.te_ipv4_reachs = list_new(); + _lsp_tlv_fit(lsp, &tlv_data.te_ipv4_reachs, + &lsp->tlv_data.te_ipv4_reachs, + area->lsp_frag_threshold, tlv_add_te_ipv4_reachs, + NULL); + if (tlv_data.te_ipv4_reachs + && listcount(tlv_data.te_ipv4_reachs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + struct tlv_mt_ipv4_reachs *mt_ipv4_reachs; + for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv4_reachs, node, + mt_ipv4_reachs)) { + while (mt_ipv4_reachs->list + && listcount(mt_ipv4_reachs->list)) { + struct tlv_mt_ipv4_reachs *frag_mt_ipv4_reachs; + + frag_mt_ipv4_reachs = tlvs_get_mt_ipv4_reachs( + &lsp->tlv_data, mt_ipv4_reachs->mtid); + _lsp_tlv_fit(lsp, &mt_ipv4_reachs->list, + &frag_mt_ipv4_reachs->list, + area->lsp_frag_threshold, + tlv_add_te_ipv4_reachs, + &mt_ipv4_reachs->mtid); + if (mt_ipv4_reachs->list + && listcount(mt_ipv4_reachs->list)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + + 1, + lsp0, area, level); } - } - else - { - lsp_debug("ISIS (%s): No adjacency for given level on this circuit. Not adding IS neighbors", - area->area_tag); - } - break; - case CIRCUIT_T_LOOPBACK: - break; - default: - zlog_warn ("lsp_area_create: unknown circuit type"); - } - } - - lsp_build_ext_reach(lsp, area, &tlv_data); - - lsp_debug("ISIS (%s): LSP construction is complete. Serializing...", area->area_tag); - - while (tlv_data.ipv4_int_reachs && listcount (tlv_data.ipv4_int_reachs)) - { - if (lsp->tlv_data.ipv4_int_reachs == NULL) - lsp->tlv_data.ipv4_int_reachs = list_new (); - lsp_tlv_fit (lsp, &tlv_data.ipv4_int_reachs, - &lsp->tlv_data.ipv4_int_reachs, - IPV4_REACH_LEN, area->lsp_frag_threshold, - tlv_add_ipv4_int_reachs); - if (tlv_data.ipv4_int_reachs && listcount (tlv_data.ipv4_int_reachs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - while (tlv_data.ipv4_ext_reachs && listcount (tlv_data.ipv4_ext_reachs)) - { - if (lsp->tlv_data.ipv4_ext_reachs == NULL) - lsp->tlv_data.ipv4_ext_reachs = list_new (); - lsp_tlv_fit (lsp, &tlv_data.ipv4_ext_reachs, - &lsp->tlv_data.ipv4_ext_reachs, - IPV4_REACH_LEN, area->lsp_frag_threshold, - tlv_add_ipv4_ext_reachs); - if (tlv_data.ipv4_ext_reachs && listcount (tlv_data.ipv4_ext_reachs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - while (tlv_data.te_ipv4_reachs && listcount (tlv_data.te_ipv4_reachs)) - { - if (lsp->tlv_data.te_ipv4_reachs == NULL) - lsp->tlv_data.te_ipv4_reachs = list_new (); - _lsp_tlv_fit (lsp, &tlv_data.te_ipv4_reachs, &lsp->tlv_data.te_ipv4_reachs, - area->lsp_frag_threshold, tlv_add_te_ipv4_reachs, NULL); - if (tlv_data.te_ipv4_reachs && listcount (tlv_data.te_ipv4_reachs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - struct tlv_mt_ipv4_reachs *mt_ipv4_reachs; - for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv4_reachs, node, mt_ipv4_reachs)) - { - while (mt_ipv4_reachs->list && listcount(mt_ipv4_reachs->list)) - { - struct tlv_mt_ipv4_reachs *frag_mt_ipv4_reachs; - - frag_mt_ipv4_reachs = tlvs_get_mt_ipv4_reachs(&lsp->tlv_data, mt_ipv4_reachs->mtid); - _lsp_tlv_fit (lsp, &mt_ipv4_reachs->list, &frag_mt_ipv4_reachs->list, - area->lsp_frag_threshold, tlv_add_te_ipv4_reachs, - &mt_ipv4_reachs->mtid); - if (mt_ipv4_reachs->list && listcount(mt_ipv4_reachs->list)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - } - - while (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs)) - { - if (lsp->tlv_data.ipv6_reachs == NULL) - lsp->tlv_data.ipv6_reachs = list_new (); - _lsp_tlv_fit (lsp, &tlv_data.ipv6_reachs, &lsp->tlv_data.ipv6_reachs, - area->lsp_frag_threshold, tlv_add_ipv6_reachs, NULL); - if (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - struct tlv_mt_ipv6_reachs *mt_ipv6_reachs; - for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv6_reachs, node, mt_ipv6_reachs)) - { - while (mt_ipv6_reachs->list && listcount(mt_ipv6_reachs->list)) - { - struct tlv_mt_ipv6_reachs *frag_mt_ipv6_reachs; - - frag_mt_ipv6_reachs = tlvs_get_mt_ipv6_reachs(&lsp->tlv_data, mt_ipv6_reachs->mtid); - _lsp_tlv_fit (lsp, &mt_ipv6_reachs->list, &frag_mt_ipv6_reachs->list, - area->lsp_frag_threshold, tlv_add_ipv6_reachs, - &mt_ipv6_reachs->mtid); - if (mt_ipv6_reachs->list && listcount(mt_ipv6_reachs->list)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - } - - while (tlv_data.is_neighs && listcount (tlv_data.is_neighs)) - { - if (lsp->tlv_data.is_neighs == NULL) - lsp->tlv_data.is_neighs = list_new (); - lsp_tlv_fit (lsp, &tlv_data.is_neighs, - &lsp->tlv_data.is_neighs, - IS_NEIGHBOURS_LEN, area->lsp_frag_threshold, - tlv_add_is_neighs); - if (tlv_data.is_neighs && listcount (tlv_data.is_neighs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - while (tlv_data.te_is_neighs && listcount (tlv_data.te_is_neighs)) - { - if (lsp->tlv_data.te_is_neighs == NULL) - lsp->tlv_data.te_is_neighs = list_new (); - _lsp_tlv_fit (lsp, &tlv_data.te_is_neighs, &lsp->tlv_data.te_is_neighs, - area->lsp_frag_threshold, tlv_add_te_is_neighs, NULL); - if (tlv_data.te_is_neighs && listcount (tlv_data.te_is_neighs)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - - struct tlv_mt_neighbors *mt_neighs; - for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_is_neighs, node, mt_neighs)) - { - while (mt_neighs->list && listcount(mt_neighs->list)) - { - struct tlv_mt_neighbors *frag_mt_neighs; - - frag_mt_neighs = tlvs_get_mt_neighbors(&lsp->tlv_data, mt_neighs->mtid); - _lsp_tlv_fit (lsp, &mt_neighs->list, &frag_mt_neighs->list, - area->lsp_frag_threshold, tlv_add_te_is_neighs, - &mt_neighs->mtid); - if (mt_neighs->list && listcount(mt_neighs->list)) - lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1, - lsp0, area, level); - } - } - - - lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); - - free_tlvs (&tlv_data); - - /* Validate the LSP */ - retval = parse_tlvs (area->area_tag, STREAM_DATA (lsp->pdu) + - ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN, - stream_get_endp (lsp->pdu) - - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN, - &expected, &found, &tlv_data, NULL); - assert (retval == ISIS_OK); - - return; + } + + while (tlv_data.ipv6_reachs && listcount(tlv_data.ipv6_reachs)) { + if (lsp->tlv_data.ipv6_reachs == NULL) + lsp->tlv_data.ipv6_reachs = list_new(); + _lsp_tlv_fit( + lsp, &tlv_data.ipv6_reachs, &lsp->tlv_data.ipv6_reachs, + area->lsp_frag_threshold, tlv_add_ipv6_reachs, NULL); + if (tlv_data.ipv6_reachs && listcount(tlv_data.ipv6_reachs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + struct tlv_mt_ipv6_reachs *mt_ipv6_reachs; + for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv6_reachs, node, + mt_ipv6_reachs)) { + while (mt_ipv6_reachs->list + && listcount(mt_ipv6_reachs->list)) { + struct tlv_mt_ipv6_reachs *frag_mt_ipv6_reachs; + + frag_mt_ipv6_reachs = tlvs_get_mt_ipv6_reachs( + &lsp->tlv_data, mt_ipv6_reachs->mtid); + _lsp_tlv_fit(lsp, &mt_ipv6_reachs->list, + &frag_mt_ipv6_reachs->list, + area->lsp_frag_threshold, + tlv_add_ipv6_reachs, + &mt_ipv6_reachs->mtid); + if (mt_ipv6_reachs->list + && listcount(mt_ipv6_reachs->list)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + + 1, + lsp0, area, level); + } + } + + while (tlv_data.is_neighs && listcount(tlv_data.is_neighs)) { + if (lsp->tlv_data.is_neighs == NULL) + lsp->tlv_data.is_neighs = list_new(); + lsp_tlv_fit(lsp, &tlv_data.is_neighs, &lsp->tlv_data.is_neighs, + IS_NEIGHBOURS_LEN, area->lsp_frag_threshold, + tlv_add_is_neighs); + if (tlv_data.is_neighs && listcount(tlv_data.is_neighs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + while (tlv_data.te_is_neighs && listcount(tlv_data.te_is_neighs)) { + if (lsp->tlv_data.te_is_neighs == NULL) + lsp->tlv_data.te_is_neighs = list_new(); + _lsp_tlv_fit(lsp, &tlv_data.te_is_neighs, + &lsp->tlv_data.te_is_neighs, + area->lsp_frag_threshold, tlv_add_te_is_neighs, + NULL); + if (tlv_data.te_is_neighs && listcount(tlv_data.te_is_neighs)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0, + area, level); + } + + struct tlv_mt_neighbors *mt_neighs; + for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_is_neighs, node, mt_neighs)) { + while (mt_neighs->list && listcount(mt_neighs->list)) { + struct tlv_mt_neighbors *frag_mt_neighs; + + frag_mt_neighs = tlvs_get_mt_neighbors(&lsp->tlv_data, + mt_neighs->mtid); + _lsp_tlv_fit(lsp, &mt_neighs->list, + &frag_mt_neighs->list, + area->lsp_frag_threshold, + tlv_add_te_is_neighs, &mt_neighs->mtid); + if (mt_neighs->list && listcount(mt_neighs->list)) + lsp = lsp_next_frag( + LSP_FRAGMENT(lsp->lsp_header->lsp_id) + + 1, + lsp0, area, level); + } + } + + + lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu)); + + free_tlvs(&tlv_data); + + /* Validate the LSP */ + retval = parse_tlvs(area->area_tag, + STREAM_DATA(lsp->pdu) + ISIS_FIXED_HDR_LEN + + ISIS_LSP_HDR_LEN, + stream_get_endp(lsp->pdu) - ISIS_FIXED_HDR_LEN + - ISIS_LSP_HDR_LEN, + &expected, &found, &tlv_data, NULL); + assert(retval == ISIS_OK); + + return; } /* * 7.3.7 and 7.3.9 Generation on non-pseudonode LSPs */ -int -lsp_generate (struct isis_area *area, int level) +int lsp_generate(struct isis_area *area, int level) { - struct isis_lsp *oldlsp, *newlsp; - u_int32_t seq_num = 0; - u_char lspid[ISIS_SYS_ID_LEN + 2]; - u_int16_t rem_lifetime, refresh_time; - - if ((area == NULL) || (area->is_type & level) != level) - return ISIS_ERROR; - - memset (&lspid, 0, ISIS_SYS_ID_LEN + 2); - memcpy (&lspid, isis->sysid, ISIS_SYS_ID_LEN); - - /* only builds the lsp if the area shares the level */ - oldlsp = lsp_search (lspid, area->lspdb[level - 1]); - if (oldlsp) - { - /* FIXME: we should actually initiate a purge */ - seq_num = ntohl (oldlsp->lsp_header->seq_num); - lsp_search_and_destroy (oldlsp->lsp_header->lsp_id, - area->lspdb[level - 1]); - } - rem_lifetime = lsp_rem_lifetime (area, level); - newlsp = lsp_new (area, lspid, rem_lifetime, seq_num, - area->is_type | area->overload_bit | area->attached_bit, - 0, level); - newlsp->area = area; - newlsp->own_lsp = 1; - - lsp_insert (newlsp, area->lspdb[level - 1]); - /* build_lsp_data (newlsp, area); */ - lsp_build (newlsp, area); - /* time to calculate our checksum */ - lsp_seqnum_update (newlsp); - newlsp->last_generated = time(NULL); - lsp_set_all_srmflags (newlsp); - - refresh_time = lsp_refresh_time (newlsp, rem_lifetime); - - THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]); - area->lsp_regenerate_pending[level - 1] = 0; - if (level == IS_LEVEL_1) - thread_add_timer(master, lsp_l1_refresh, area, refresh_time, - &area->t_lsp_refresh[level - 1]); - else if (level == IS_LEVEL_2) - thread_add_timer(master, lsp_l2_refresh, area, refresh_time, - &area->t_lsp_refresh[level - 1]); - - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Building L%d LSP %s, len %d, " - "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us", - area->area_tag, level, - rawlspid_print (newlsp->lsp_header->lsp_id), - ntohl (newlsp->lsp_header->pdu_len), - ntohl (newlsp->lsp_header->seq_num), - ntohs (newlsp->lsp_header->checksum), - ntohs (newlsp->lsp_header->rem_lifetime), - refresh_time); - } - sched_debug("ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.", - area->area_tag, level); - - return ISIS_OK; + struct isis_lsp *oldlsp, *newlsp; + u_int32_t seq_num = 0; + u_char lspid[ISIS_SYS_ID_LEN + 2]; + u_int16_t rem_lifetime, refresh_time; + + if ((area == NULL) || (area->is_type & level) != level) + return ISIS_ERROR; + + memset(&lspid, 0, ISIS_SYS_ID_LEN + 2); + memcpy(&lspid, isis->sysid, ISIS_SYS_ID_LEN); + + /* only builds the lsp if the area shares the level */ + oldlsp = lsp_search(lspid, area->lspdb[level - 1]); + if (oldlsp) { + /* FIXME: we should actually initiate a purge */ + seq_num = ntohl(oldlsp->lsp_header->seq_num); + lsp_search_and_destroy(oldlsp->lsp_header->lsp_id, + area->lspdb[level - 1]); + } + rem_lifetime = lsp_rem_lifetime(area, level); + newlsp = + lsp_new(area, lspid, rem_lifetime, seq_num, + area->is_type | area->overload_bit | area->attached_bit, + 0, level); + newlsp->area = area; + newlsp->own_lsp = 1; + + lsp_insert(newlsp, area->lspdb[level - 1]); + /* build_lsp_data (newlsp, area); */ + lsp_build(newlsp, area); + /* time to calculate our checksum */ + lsp_seqnum_update(newlsp); + newlsp->last_generated = time(NULL); + lsp_set_all_srmflags(newlsp); + + refresh_time = lsp_refresh_time(newlsp, rem_lifetime); + + THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]); + area->lsp_regenerate_pending[level - 1] = 0; + if (level == IS_LEVEL_1) + thread_add_timer(master, lsp_l1_refresh, area, refresh_time, + &area->t_lsp_refresh[level - 1]); + else if (level == IS_LEVEL_2) + thread_add_timer(master, lsp_l2_refresh, area, refresh_time, + &area->t_lsp_refresh[level - 1]); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Building L%d LSP %s, len %d, " + "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us", + area->area_tag, level, + rawlspid_print(newlsp->lsp_header->lsp_id), + ntohl(newlsp->lsp_header->pdu_len), + ntohl(newlsp->lsp_header->seq_num), + ntohs(newlsp->lsp_header->checksum), + ntohs(newlsp->lsp_header->rem_lifetime), refresh_time); + } + sched_debug( + "ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.", + area->area_tag, level); + + return ISIS_OK; } /* * Search own LSPs, update holding time and set SRM */ -static int -lsp_regenerate (struct isis_area *area, int level) +static int lsp_regenerate(struct isis_area *area, int level) { - dict_t *lspdb; - struct isis_lsp *lsp, *frag; - struct listnode *node; - u_char lspid[ISIS_SYS_ID_LEN + 2]; - u_int16_t rem_lifetime, refresh_time; - - if ((area == NULL) || (area->is_type & level) != level) - return ISIS_ERROR; - - lspdb = area->lspdb[level - 1]; - - memset (lspid, 0, ISIS_SYS_ID_LEN + 2); - memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN); - - lsp = lsp_search (lspid, lspdb); - - if (!lsp) - { - zlog_err ("ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!", - area->area_tag, level); - return ISIS_ERROR; - } - - lsp_clear_data (lsp); - lsp_build (lsp, area); - lsp->lsp_header->lsp_bits = lsp_bits_generate (level, area->overload_bit, - area->attached_bit); - rem_lifetime = lsp_rem_lifetime (area, level); - lsp->lsp_header->rem_lifetime = htons (rem_lifetime); - lsp_seqnum_update (lsp); - - lsp->last_generated = time (NULL); - lsp_set_all_srmflags (lsp); - for (ALL_LIST_ELEMENTS_RO (lsp->lspu.frags, node, frag)) - { - frag->lsp_header->lsp_bits = lsp_bits_generate (level, - area->overload_bit, - area->attached_bit); - /* Set the lifetime values of all the fragments to the same value, - * so that no fragment expires before the lsp is refreshed. - */ - frag->lsp_header->rem_lifetime = htons (rem_lifetime); - lsp_set_all_srmflags (frag); - } - - refresh_time = lsp_refresh_time (lsp, rem_lifetime); - if (level == IS_LEVEL_1) - thread_add_timer(master, lsp_l1_refresh, area, refresh_time, - &area->t_lsp_refresh[level - 1]); - else if (level == IS_LEVEL_2) - thread_add_timer(master, lsp_l2_refresh, area, refresh_time, - &area->t_lsp_refresh[level - 1]); - area->lsp_regenerate_pending[level - 1] = 0; - - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Refreshing our L%d LSP %s, len %d, " - "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us", - area->area_tag, level, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->pdu_len), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime), - refresh_time); - } - sched_debug("ISIS (%s): Rebuilt L%d LSP. Set triggered regenerate to non-pending.", - area->area_tag, level); - - return ISIS_OK; + dict_t *lspdb; + struct isis_lsp *lsp, *frag; + struct listnode *node; + u_char lspid[ISIS_SYS_ID_LEN + 2]; + u_int16_t rem_lifetime, refresh_time; + + if ((area == NULL) || (area->is_type & level) != level) + return ISIS_ERROR; + + lspdb = area->lspdb[level - 1]; + + memset(lspid, 0, ISIS_SYS_ID_LEN + 2); + memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN); + + lsp = lsp_search(lspid, lspdb); + + if (!lsp) { + zlog_err("ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!", + area->area_tag, level); + return ISIS_ERROR; + } + + lsp_clear_data(lsp); + lsp_build(lsp, area); + lsp->lsp_header->lsp_bits = lsp_bits_generate(level, area->overload_bit, + area->attached_bit); + rem_lifetime = lsp_rem_lifetime(area, level); + lsp->lsp_header->rem_lifetime = htons(rem_lifetime); + lsp_seqnum_update(lsp); + + lsp->last_generated = time(NULL); + lsp_set_all_srmflags(lsp); + for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { + frag->lsp_header->lsp_bits = lsp_bits_generate( + level, area->overload_bit, area->attached_bit); + /* Set the lifetime values of all the fragments to the same + * value, + * so that no fragment expires before the lsp is refreshed. + */ + frag->lsp_header->rem_lifetime = htons(rem_lifetime); + lsp_set_all_srmflags(frag); + } + + refresh_time = lsp_refresh_time(lsp, rem_lifetime); + if (level == IS_LEVEL_1) + thread_add_timer(master, lsp_l1_refresh, area, refresh_time, + &area->t_lsp_refresh[level - 1]); + else if (level == IS_LEVEL_2) + thread_add_timer(master, lsp_l2_refresh, area, refresh_time, + &area->t_lsp_refresh[level - 1]); + area->lsp_regenerate_pending[level - 1] = 0; + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Refreshing our L%d LSP %s, len %d, " + "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us", + area->area_tag, level, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->pdu_len), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime), refresh_time); + } + sched_debug( + "ISIS (%s): Rebuilt L%d LSP. Set triggered regenerate to non-pending.", + area->area_tag, level); + + return ISIS_OK; } /* * Something has changed or periodic refresh -> regenerate LSP */ -static int -lsp_l1_refresh (struct thread *thread) +static int lsp_l1_refresh(struct thread *thread) { - struct isis_area *area; + struct isis_area *area; - area = THREAD_ARG (thread); - assert (area); + area = THREAD_ARG(thread); + assert(area); - area->t_lsp_refresh[0] = NULL; - area->lsp_regenerate_pending[0] = 0; + area->t_lsp_refresh[0] = NULL; + area->lsp_regenerate_pending[0] = 0; - if ((area->is_type & IS_LEVEL_1) == 0) - return ISIS_ERROR; + if ((area->is_type & IS_LEVEL_1) == 0) + return ISIS_ERROR; - sched_debug("ISIS (%s): LSP L1 refresh timer expired. Refreshing LSP...", area->area_tag); - return lsp_regenerate (area, IS_LEVEL_1); + sched_debug( + "ISIS (%s): LSP L1 refresh timer expired. Refreshing LSP...", + area->area_tag); + return lsp_regenerate(area, IS_LEVEL_1); } -static int -lsp_l2_refresh (struct thread *thread) +static int lsp_l2_refresh(struct thread *thread) { - struct isis_area *area; + struct isis_area *area; - area = THREAD_ARG (thread); - assert (area); + area = THREAD_ARG(thread); + assert(area); - area->t_lsp_refresh[1] = NULL; - area->lsp_regenerate_pending[1] = 0; + area->t_lsp_refresh[1] = NULL; + area->lsp_regenerate_pending[1] = 0; - if ((area->is_type & IS_LEVEL_2) == 0) - return ISIS_ERROR; + if ((area->is_type & IS_LEVEL_2) == 0) + return ISIS_ERROR; - sched_debug("ISIS (%s): LSP L2 refresh timer expired. Refreshing LSP...", area->area_tag); - return lsp_regenerate (area, IS_LEVEL_2); + sched_debug( + "ISIS (%s): LSP L2 refresh timer expired. Refreshing LSP...", + area->area_tag); + return lsp_regenerate(area, IS_LEVEL_2); } -int -lsp_regenerate_schedule (struct isis_area *area, int level, int all_pseudo) +int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo) { - struct isis_lsp *lsp; - u_char id[ISIS_SYS_ID_LEN + 2]; - time_t now, diff; - long timeout; - struct listnode *cnode; - struct isis_circuit *circuit; - int lvl; - - if (area == NULL) - return ISIS_ERROR; - - sched_debug("ISIS (%s): Scheduling regeneration of %s LSPs, %sincluding PSNs", - area->area_tag, circuit_t2string(level), all_pseudo ? "" : "not "); - - memcpy (id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (id) = LSP_FRAGMENT (id) = 0; - now = time (NULL); - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) - { - if (!((level & lvl) && (area->is_type & lvl))) - continue; - - sched_debug("ISIS (%s): Checking whether L%d needs to be scheduled", - area->area_tag, lvl); - - if (area->lsp_regenerate_pending[lvl - 1]) - { - struct timeval remain = thread_timer_remain(area->t_lsp_refresh[lvl - 1]); - sched_debug("ISIS (%s): Regeneration is already pending, nothing todo." - " (Due in %lld.%03lld seconds)", area->area_tag, - (long long)remain.tv_sec, (long long)remain.tv_usec / 1000); - continue; - } - - lsp = lsp_search (id, area->lspdb[lvl - 1]); - if (!lsp) - { - sched_debug("ISIS (%s): We do not have any LSPs to regenerate, nothing todo.", - area->area_tag); - continue; - } - - /* - * Throttle avoidance - */ - sched_debug("ISIS (%s): Will schedule regen timer. Last run was: %lld, Now is: %lld", - area->area_tag, (long long)lsp->last_generated, (long long)now); - THREAD_TIMER_OFF (area->t_lsp_refresh[lvl - 1]); - diff = now - lsp->last_generated; - if (diff < area->lsp_gen_interval[lvl - 1]) - { - timeout = 1000 * (area->lsp_gen_interval[lvl - 1] - diff); - sched_debug("ISIS (%s): Scheduling in %ld ms to match configured lsp_gen_interval", - area->area_tag, timeout); - } - else - { - /* - * lsps are not regenerated if lsp_regenerate function is called - * directly. However if the lsp_regenerate call is queued for - * later execution it works. - */ - timeout = 100; - sched_debug("ISIS (%s): Last generation was more than lsp_gen_interval ago." - " Scheduling for execution in %ld ms.", area->area_tag, timeout); - } - - area->lsp_regenerate_pending[lvl - 1] = 1; - if (lvl == IS_LEVEL_1) - { - thread_add_timer_msec(master, lsp_l1_refresh, area, timeout, - &area->t_lsp_refresh[lvl - 1]); - } - else if (lvl == IS_LEVEL_2) - { - thread_add_timer_msec(master, lsp_l2_refresh, area, timeout, - &area->t_lsp_refresh[lvl - 1]); - } - } - - if (all_pseudo) - { - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) - lsp_regenerate_schedule_pseudo (circuit, level); - } - - return ISIS_OK; + struct isis_lsp *lsp; + u_char id[ISIS_SYS_ID_LEN + 2]; + time_t now, diff; + long timeout; + struct listnode *cnode; + struct isis_circuit *circuit; + int lvl; + + if (area == NULL) + return ISIS_ERROR; + + sched_debug( + "ISIS (%s): Scheduling regeneration of %s LSPs, %sincluding PSNs", + area->area_tag, circuit_t2string(level), + all_pseudo ? "" : "not "); + + memcpy(id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(id) = LSP_FRAGMENT(id) = 0; + now = time(NULL); + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!((level & lvl) && (area->is_type & lvl))) + continue; + + sched_debug( + "ISIS (%s): Checking whether L%d needs to be scheduled", + area->area_tag, lvl); + + if (area->lsp_regenerate_pending[lvl - 1]) { + struct timeval remain = thread_timer_remain( + area->t_lsp_refresh[lvl - 1]); + sched_debug( + "ISIS (%s): Regeneration is already pending, nothing todo." + " (Due in %lld.%03lld seconds)", + area->area_tag, (long long)remain.tv_sec, + (long long)remain.tv_usec / 1000); + continue; + } + + lsp = lsp_search(id, area->lspdb[lvl - 1]); + if (!lsp) { + sched_debug( + "ISIS (%s): We do not have any LSPs to regenerate, nothing todo.", + area->area_tag); + continue; + } + + /* + * Throttle avoidance + */ + sched_debug( + "ISIS (%s): Will schedule regen timer. Last run was: %lld, Now is: %lld", + area->area_tag, (long long)lsp->last_generated, + (long long)now); + THREAD_TIMER_OFF(area->t_lsp_refresh[lvl - 1]); + diff = now - lsp->last_generated; + if (diff < area->lsp_gen_interval[lvl - 1]) { + timeout = + 1000 * (area->lsp_gen_interval[lvl - 1] - diff); + sched_debug( + "ISIS (%s): Scheduling in %ld ms to match configured lsp_gen_interval", + area->area_tag, timeout); + } else { + /* + * lsps are not regenerated if lsp_regenerate function + * is called + * directly. However if the lsp_regenerate call is + * queued for + * later execution it works. + */ + timeout = 100; + sched_debug( + "ISIS (%s): Last generation was more than lsp_gen_interval ago." + " Scheduling for execution in %ld ms.", + area->area_tag, timeout); + } + + area->lsp_regenerate_pending[lvl - 1] = 1; + if (lvl == IS_LEVEL_1) { + thread_add_timer_msec(master, lsp_l1_refresh, area, + timeout, + &area->t_lsp_refresh[lvl - 1]); + } else if (lvl == IS_LEVEL_2) { + thread_add_timer_msec(master, lsp_l2_refresh, area, + timeout, + &area->t_lsp_refresh[lvl - 1]); + } + } + + if (all_pseudo) { + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) + lsp_regenerate_schedule_pseudo(circuit, level); + } + + return ISIS_OK; } /* @@ -2271,430 +2345,443 @@ lsp_regenerate_schedule (struct isis_area *area, int level, int all_pseudo) */ /* - * 7.3.8 and 7.3.10 Generation of level 1 and 2 pseudonode LSPs + * 7.3.8 and 7.3.10 Generation of level 1 and 2 pseudonode LSPs */ -static void -lsp_build_pseudo (struct isis_lsp *lsp, struct isis_circuit *circuit, - int level) +static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit, + int level) { - struct isis_adjacency *adj; - struct is_neigh *is_neigh; - struct te_is_neigh *te_is_neigh; - struct es_neigh *es_neigh; - struct list *adj_list; - struct listnode *node; - struct isis_area *area = circuit->area; - - lsp_debug("ISIS (%s): Constructing pseudo LSP %s for interface %s level %d", - area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id), - circuit->interface->name, level); - - lsp->level = level; - /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ - lsp->lsp_header->lsp_bits = lsp_bits_generate (level, 0, - circuit->area->attached_bit); - - /* - * add self to IS neighbours - */ - if (circuit->area->oldmetric) - { - if (lsp->tlv_data.is_neighs == NULL) - { - lsp->tlv_data.is_neighs = list_new (); - lsp->tlv_data.is_neighs->del = free_tlv; - } - is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh)); - - memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN); - listnode_add (lsp->tlv_data.is_neighs, is_neigh); - lsp_debug("ISIS (%s): Adding %s.%02x as old-style neighbor (self)", - area->area_tag, sysid_print(is_neigh->neigh_id), - LSP_PSEUDO_ID(is_neigh->neigh_id)); - } - if (circuit->area->newmetric) - { - if (lsp->tlv_data.te_is_neighs == NULL) - { - lsp->tlv_data.te_is_neighs = list_new (); - lsp->tlv_data.te_is_neighs->del = free_tlv; - } - te_is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct te_is_neigh)); - - memcpy (&te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN); - listnode_add (lsp->tlv_data.te_is_neighs, te_is_neigh); - lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor (self)", - area->area_tag, sysid_print(te_is_neigh->neigh_id), - LSP_PSEUDO_ID(te_is_neigh->neigh_id)); - } - - adj_list = list_new (); - isis_adj_build_up_list (circuit->u.bc.adjdb[level - 1], adj_list); - - for (ALL_LIST_ELEMENTS_RO (adj_list, node, adj)) - { - if (adj->level & level) - { - if ((level == IS_LEVEL_1 && adj->sys_type == ISIS_SYSTYPE_L1_IS) || - (level == IS_LEVEL_1 && adj->sys_type == ISIS_SYSTYPE_L2_IS && - adj->adj_usage == ISIS_ADJ_LEVEL1AND2) || - (level == IS_LEVEL_2 && adj->sys_type == ISIS_SYSTYPE_L2_IS)) - { - /* an IS neighbour -> add it */ - if (circuit->area->oldmetric) - { - is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh)); - - memcpy (&is_neigh->neigh_id, adj->sysid, ISIS_SYS_ID_LEN); - listnode_add (lsp->tlv_data.is_neighs, is_neigh); - lsp_debug("ISIS (%s): Adding %s.%02x as old-style neighbor (peer)", - area->area_tag, sysid_print(is_neigh->neigh_id), - LSP_PSEUDO_ID(is_neigh->neigh_id)); + struct isis_adjacency *adj; + struct is_neigh *is_neigh; + struct te_is_neigh *te_is_neigh; + struct es_neigh *es_neigh; + struct list *adj_list; + struct listnode *node; + struct isis_area *area = circuit->area; + + lsp_debug( + "ISIS (%s): Constructing pseudo LSP %s for interface %s level %d", + area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id), + circuit->interface->name, level); + + lsp->level = level; + /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ + lsp->lsp_header->lsp_bits = + lsp_bits_generate(level, 0, circuit->area->attached_bit); + + /* + * add self to IS neighbours + */ + if (circuit->area->oldmetric) { + if (lsp->tlv_data.is_neighs == NULL) { + lsp->tlv_data.is_neighs = list_new(); + lsp->tlv_data.is_neighs->del = free_tlv; } - if (circuit->area->newmetric) - { - te_is_neigh = XCALLOC (MTYPE_ISIS_TLV, - sizeof (struct te_is_neigh)); - memcpy (&te_is_neigh->neigh_id, adj->sysid, ISIS_SYS_ID_LEN); - listnode_add (lsp->tlv_data.te_is_neighs, te_is_neigh); - lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor (peer)", - area->area_tag, sysid_print(te_is_neigh->neigh_id), - LSP_PSEUDO_ID(te_is_neigh->neigh_id)); + is_neigh = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct is_neigh)); + + memcpy(&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN); + listnode_add(lsp->tlv_data.is_neighs, is_neigh); + lsp_debug( + "ISIS (%s): Adding %s.%02x as old-style neighbor (self)", + area->area_tag, sysid_print(is_neigh->neigh_id), + LSP_PSEUDO_ID(is_neigh->neigh_id)); + } + if (circuit->area->newmetric) { + if (lsp->tlv_data.te_is_neighs == NULL) { + lsp->tlv_data.te_is_neighs = list_new(); + lsp->tlv_data.te_is_neighs->del = free_tlv; } - } - else if (level == IS_LEVEL_1 && adj->sys_type == ISIS_SYSTYPE_ES) - { - /* an ES neigbour add it, if we are building level 1 LSP */ - /* FIXME: the tlv-format is hard to use here */ - if (lsp->tlv_data.es_neighs == NULL) - { - lsp->tlv_data.es_neighs = list_new (); - lsp->tlv_data.es_neighs->del = free_tlv; + te_is_neigh = + XCALLOC(MTYPE_ISIS_TLV, sizeof(struct te_is_neigh)); + + memcpy(&te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN); + listnode_add(lsp->tlv_data.te_is_neighs, te_is_neigh); + lsp_debug( + "ISIS (%s): Adding %s.%02x as te-style neighbor (self)", + area->area_tag, sysid_print(te_is_neigh->neigh_id), + LSP_PSEUDO_ID(te_is_neigh->neigh_id)); + } + + adj_list = list_new(); + isis_adj_build_up_list(circuit->u.bc.adjdb[level - 1], adj_list); + + for (ALL_LIST_ELEMENTS_RO(adj_list, node, adj)) { + if (adj->level & level) { + if ((level == IS_LEVEL_1 + && adj->sys_type == ISIS_SYSTYPE_L1_IS) + || (level == IS_LEVEL_1 + && adj->sys_type == ISIS_SYSTYPE_L2_IS + && adj->adj_usage == ISIS_ADJ_LEVEL1AND2) + || (level == IS_LEVEL_2 + && adj->sys_type == ISIS_SYSTYPE_L2_IS)) { + /* an IS neighbour -> add it */ + if (circuit->area->oldmetric) { + is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct is_neigh)); + + memcpy(&is_neigh->neigh_id, adj->sysid, + ISIS_SYS_ID_LEN); + listnode_add(lsp->tlv_data.is_neighs, + is_neigh); + lsp_debug( + "ISIS (%s): Adding %s.%02x as old-style neighbor (peer)", + area->area_tag, + sysid_print(is_neigh->neigh_id), + LSP_PSEUDO_ID( + is_neigh->neigh_id)); + } + if (circuit->area->newmetric) { + te_is_neigh = XCALLOC( + MTYPE_ISIS_TLV, + sizeof(struct te_is_neigh)); + memcpy(&te_is_neigh->neigh_id, + adj->sysid, ISIS_SYS_ID_LEN); + listnode_add(lsp->tlv_data.te_is_neighs, + te_is_neigh); + lsp_debug( + "ISIS (%s): Adding %s.%02x as te-style neighbor (peer)", + area->area_tag, + sysid_print( + te_is_neigh->neigh_id), + LSP_PSEUDO_ID( + te_is_neigh->neigh_id)); + } + } else if (level == IS_LEVEL_1 + && adj->sys_type == ISIS_SYSTYPE_ES) { + /* an ES neigbour add it, if we are building + * level 1 LSP */ + /* FIXME: the tlv-format is hard to use here */ + if (lsp->tlv_data.es_neighs == NULL) { + lsp->tlv_data.es_neighs = list_new(); + lsp->tlv_data.es_neighs->del = free_tlv; + } + es_neigh = XCALLOC(MTYPE_ISIS_TLV, + sizeof(struct es_neigh)); + + memcpy(&es_neigh->first_es_neigh, adj->sysid, + ISIS_SYS_ID_LEN); + listnode_add(lsp->tlv_data.es_neighs, es_neigh); + lsp_debug( + "ISIS (%s): Adding %s as ES neighbor (peer)", + area->area_tag, + sysid_print(es_neigh->first_es_neigh)); + } else { + lsp_debug( + "ISIS (%s): Ignoring neighbor %s, level does not match", + area->area_tag, + sysid_print(adj->sysid)); + } + } else { + lsp_debug( + "ISIS (%s): Ignoring neighbor %s, level does not intersect", + area->area_tag, sysid_print(adj->sysid)); } - es_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct es_neigh)); - - memcpy (&es_neigh->first_es_neigh, adj->sysid, ISIS_SYS_ID_LEN); - listnode_add (lsp->tlv_data.es_neighs, es_neigh); - lsp_debug("ISIS (%s): Adding %s as ES neighbor (peer)", - area->area_tag, sysid_print(es_neigh->first_es_neigh)); - } - else - { - lsp_debug("ISIS (%s): Ignoring neighbor %s, level does not match", - area->area_tag, sysid_print(adj->sysid)); - } - } - else - { - lsp_debug("ISIS (%s): Ignoring neighbor %s, level does not intersect", - area->area_tag, sysid_print(adj->sysid)); - } - } - list_delete (adj_list); - - lsp_debug("ISIS (%s): Pseudo LSP construction is complete.", area->area_tag); - - /* Reset endp of stream to overwrite only TLV part of it. */ - stream_reset (lsp->pdu); - stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - - /* - * Add the authentication info if it's present - */ - lsp_auth_add (lsp); - - if (lsp->tlv_data.is_neighs && listcount (lsp->tlv_data.is_neighs) > 0) - tlv_add_is_neighs (lsp->tlv_data.is_neighs, lsp->pdu); - - if (lsp->tlv_data.te_is_neighs && listcount (lsp->tlv_data.te_is_neighs) > 0) - tlv_add_te_is_neighs (lsp->tlv_data.te_is_neighs, lsp->pdu, NULL); - - if (lsp->tlv_data.es_neighs && listcount (lsp->tlv_data.es_neighs) > 0) - tlv_add_is_neighs (lsp->tlv_data.es_neighs, lsp->pdu); - - lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); - - /* Recompute authentication and checksum information */ - lsp_auth_update (lsp); - fletcher_checksum(STREAM_DATA (lsp->pdu) + 12, - ntohs (lsp->lsp_header->pdu_len) - 12, 12); - - return; + } + list_delete(adj_list); + + lsp_debug("ISIS (%s): Pseudo LSP construction is complete.", + area->area_tag); + + /* Reset endp of stream to overwrite only TLV part of it. */ + stream_reset(lsp->pdu); + stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + + /* + * Add the authentication info if it's present + */ + lsp_auth_add(lsp); + + if (lsp->tlv_data.is_neighs && listcount(lsp->tlv_data.is_neighs) > 0) + tlv_add_is_neighs(lsp->tlv_data.is_neighs, lsp->pdu); + + if (lsp->tlv_data.te_is_neighs + && listcount(lsp->tlv_data.te_is_neighs) > 0) + tlv_add_te_is_neighs(lsp->tlv_data.te_is_neighs, lsp->pdu, + NULL); + + if (lsp->tlv_data.es_neighs && listcount(lsp->tlv_data.es_neighs) > 0) + tlv_add_is_neighs(lsp->tlv_data.es_neighs, lsp->pdu); + + lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu)); + + /* Recompute authentication and checksum information */ + lsp_auth_update(lsp); + fletcher_checksum(STREAM_DATA(lsp->pdu) + 12, + ntohs(lsp->lsp_header->pdu_len) - 12, 12); + + return; } -int -lsp_generate_pseudo (struct isis_circuit *circuit, int level) +int lsp_generate_pseudo(struct isis_circuit *circuit, int level) { - dict_t *lspdb = circuit->area->lspdb[level - 1]; - struct isis_lsp *lsp; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - u_int16_t rem_lifetime, refresh_time; - - if ((circuit->is_type & level) != level || - (circuit->state != C_STATE_UP) || - (circuit->circ_type != CIRCUIT_T_BROADCAST) || - (circuit->u.bc.is_dr[level - 1] == 0)) - return ISIS_ERROR; - - memcpy (lsp_id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_FRAGMENT (lsp_id) = 0; - LSP_PSEUDO_ID (lsp_id) = circuit->circuit_id; - - /* - * If for some reason have a pseudo LSP in the db already -> regenerate - */ - if (lsp_search (lsp_id, lspdb)) - return lsp_regenerate_schedule_pseudo (circuit, level); - - rem_lifetime = lsp_rem_lifetime (circuit->area, level); - /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ - lsp = lsp_new (circuit->area, lsp_id, rem_lifetime, 1, - circuit->area->is_type | circuit->area->attached_bit, - 0, level); - lsp->area = circuit->area; - - lsp_build_pseudo (lsp, circuit, level); - - lsp->own_lsp = 1; - lsp_insert (lsp, lspdb); - lsp_set_all_srmflags (lsp); - - refresh_time = lsp_refresh_time (lsp, rem_lifetime); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - circuit->lsp_regenerate_pending[level - 1] = 0; - if (level == IS_LEVEL_1) - thread_add_timer(master, lsp_l1_refresh_pseudo, circuit, refresh_time, - &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - else if (level == IS_LEVEL_2) - thread_add_timer(master, lsp_l2_refresh_pseudo, circuit, refresh_time, - &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Building L%d Pseudo LSP %s, len %d, " - "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us", - circuit->area->area_tag, level, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->pdu_len), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime), - refresh_time); - } - - return ISIS_OK; + dict_t *lspdb = circuit->area->lspdb[level - 1]; + struct isis_lsp *lsp; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + u_int16_t rem_lifetime, refresh_time; + + if ((circuit->is_type & level) != level + || (circuit->state != C_STATE_UP) + || (circuit->circ_type != CIRCUIT_T_BROADCAST) + || (circuit->u.bc.is_dr[level - 1] == 0)) + return ISIS_ERROR; + + memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_FRAGMENT(lsp_id) = 0; + LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id; + + /* + * If for some reason have a pseudo LSP in the db already -> regenerate + */ + if (lsp_search(lsp_id, lspdb)) + return lsp_regenerate_schedule_pseudo(circuit, level); + + rem_lifetime = lsp_rem_lifetime(circuit->area, level); + /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ + lsp = lsp_new(circuit->area, lsp_id, rem_lifetime, 1, + circuit->area->is_type | circuit->area->attached_bit, 0, + level); + lsp->area = circuit->area; + + lsp_build_pseudo(lsp, circuit, level); + + lsp->own_lsp = 1; + lsp_insert(lsp, lspdb); + lsp_set_all_srmflags(lsp); + + refresh_time = lsp_refresh_time(lsp, rem_lifetime); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + circuit->lsp_regenerate_pending[level - 1] = 0; + if (level == IS_LEVEL_1) + thread_add_timer( + master, lsp_l1_refresh_pseudo, circuit, refresh_time, + &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + else if (level == IS_LEVEL_2) + thread_add_timer( + master, lsp_l2_refresh_pseudo, circuit, refresh_time, + &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Building L%d Pseudo LSP %s, len %d, " + "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us", + circuit->area->area_tag, level, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->pdu_len), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime), refresh_time); + } + + return ISIS_OK; } -static int -lsp_regenerate_pseudo (struct isis_circuit *circuit, int level) +static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) { - dict_t *lspdb = circuit->area->lspdb[level - 1]; - struct isis_lsp *lsp; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - u_int16_t rem_lifetime, refresh_time; - - if ((circuit->is_type & level) != level || - (circuit->state != C_STATE_UP) || - (circuit->circ_type != CIRCUIT_T_BROADCAST) || - (circuit->u.bc.is_dr[level - 1] == 0)) - return ISIS_ERROR; - - memcpy (lsp_id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = circuit->circuit_id; - LSP_FRAGMENT (lsp_id) = 0; - - lsp = lsp_search (lsp_id, lspdb); - - if (!lsp) - { - zlog_err ("lsp_regenerate_pseudo: no l%d LSP %s found!", - level, rawlspid_print (lsp_id)); - return ISIS_ERROR; - } - lsp_clear_data (lsp); - - lsp_build_pseudo (lsp, circuit, level); - - /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ - lsp->lsp_header->lsp_bits = lsp_bits_generate (level, 0, - circuit->area->attached_bit); - rem_lifetime = lsp_rem_lifetime (circuit->area, level); - lsp->lsp_header->rem_lifetime = htons (rem_lifetime); - lsp_inc_seqnum (lsp, 0); - lsp->last_generated = time (NULL); - lsp_set_all_srmflags (lsp); - - refresh_time = lsp_refresh_time (lsp, rem_lifetime); - if (level == IS_LEVEL_1) - thread_add_timer(master, lsp_l1_refresh_pseudo, circuit, refresh_time, - &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - else if (level == IS_LEVEL_2) - thread_add_timer(master, lsp_l2_refresh_pseudo, circuit, refresh_time, - &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); - - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Refreshing L%d Pseudo LSP %s, len %d, " - "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us", - circuit->area->area_tag, level, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->pdu_len), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime), - refresh_time); - } - - return ISIS_OK; + dict_t *lspdb = circuit->area->lspdb[level - 1]; + struct isis_lsp *lsp; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + u_int16_t rem_lifetime, refresh_time; + + if ((circuit->is_type & level) != level + || (circuit->state != C_STATE_UP) + || (circuit->circ_type != CIRCUIT_T_BROADCAST) + || (circuit->u.bc.is_dr[level - 1] == 0)) + return ISIS_ERROR; + + memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id; + LSP_FRAGMENT(lsp_id) = 0; + + lsp = lsp_search(lsp_id, lspdb); + + if (!lsp) { + zlog_err("lsp_regenerate_pseudo: no l%d LSP %s found!", level, + rawlspid_print(lsp_id)); + return ISIS_ERROR; + } + lsp_clear_data(lsp); + + lsp_build_pseudo(lsp, circuit, level); + + /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */ + lsp->lsp_header->lsp_bits = + lsp_bits_generate(level, 0, circuit->area->attached_bit); + rem_lifetime = lsp_rem_lifetime(circuit->area, level); + lsp->lsp_header->rem_lifetime = htons(rem_lifetime); + lsp_inc_seqnum(lsp, 0); + lsp->last_generated = time(NULL); + lsp_set_all_srmflags(lsp); + + refresh_time = lsp_refresh_time(lsp, rem_lifetime); + if (level == IS_LEVEL_1) + thread_add_timer( + master, lsp_l1_refresh_pseudo, circuit, refresh_time, + &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + else if (level == IS_LEVEL_2) + thread_add_timer( + master, lsp_l2_refresh_pseudo, circuit, refresh_time, + &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Refreshing L%d Pseudo LSP %s, len %d, " + "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us", + circuit->area->area_tag, level, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->pdu_len), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime), refresh_time); + } + + return ISIS_OK; } /* * Something has changed or periodic refresh -> regenerate pseudo LSP */ -static int -lsp_l1_refresh_pseudo (struct thread *thread) +static int lsp_l1_refresh_pseudo(struct thread *thread) { - struct isis_circuit *circuit; - u_char id[ISIS_SYS_ID_LEN + 2]; + struct isis_circuit *circuit; + u_char id[ISIS_SYS_ID_LEN + 2]; - circuit = THREAD_ARG (thread); + circuit = THREAD_ARG(thread); - circuit->u.bc.t_refresh_pseudo_lsp[0] = NULL; - circuit->lsp_regenerate_pending[0] = 0; + circuit->u.bc.t_refresh_pseudo_lsp[0] = NULL; + circuit->lsp_regenerate_pending[0] = 0; - if ((circuit->u.bc.is_dr[0] == 0) || - (circuit->is_type & IS_LEVEL_1) == 0) - { - memcpy (id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (id) = circuit->circuit_id; - LSP_FRAGMENT (id) = 0; - lsp_purge_pseudo (id, circuit, IS_LEVEL_1); - return ISIS_ERROR; - } + if ((circuit->u.bc.is_dr[0] == 0) + || (circuit->is_type & IS_LEVEL_1) == 0) { + memcpy(id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(id) = circuit->circuit_id; + LSP_FRAGMENT(id) = 0; + lsp_purge_pseudo(id, circuit, IS_LEVEL_1); + return ISIS_ERROR; + } - return lsp_regenerate_pseudo (circuit, IS_LEVEL_1); + return lsp_regenerate_pseudo(circuit, IS_LEVEL_1); } -static int -lsp_l2_refresh_pseudo (struct thread *thread) +static int lsp_l2_refresh_pseudo(struct thread *thread) { - struct isis_circuit *circuit; - u_char id[ISIS_SYS_ID_LEN + 2]; + struct isis_circuit *circuit; + u_char id[ISIS_SYS_ID_LEN + 2]; - circuit = THREAD_ARG (thread); + circuit = THREAD_ARG(thread); - circuit->u.bc.t_refresh_pseudo_lsp[1] = NULL; - circuit->lsp_regenerate_pending[1] = 0; + circuit->u.bc.t_refresh_pseudo_lsp[1] = NULL; + circuit->lsp_regenerate_pending[1] = 0; - if ((circuit->u.bc.is_dr[1] == 0) || - (circuit->is_type & IS_LEVEL_2) == 0) - { - memcpy (id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (id) = circuit->circuit_id; - LSP_FRAGMENT (id) = 0; - lsp_purge_pseudo (id, circuit, IS_LEVEL_2); - return ISIS_ERROR; - } + if ((circuit->u.bc.is_dr[1] == 0) + || (circuit->is_type & IS_LEVEL_2) == 0) { + memcpy(id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(id) = circuit->circuit_id; + LSP_FRAGMENT(id) = 0; + lsp_purge_pseudo(id, circuit, IS_LEVEL_2); + return ISIS_ERROR; + } - return lsp_regenerate_pseudo (circuit, IS_LEVEL_2); + return lsp_regenerate_pseudo(circuit, IS_LEVEL_2); } -int -lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level) +int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level) { - struct isis_lsp *lsp; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - time_t now, diff; - long timeout; - int lvl; - struct isis_area *area = circuit->area; - - if (circuit->circ_type != CIRCUIT_T_BROADCAST || - circuit->state != C_STATE_UP) - return ISIS_OK; - - sched_debug("ISIS (%s): Scheduling regeneration of %s pseudo LSP for interface %s", - area->area_tag, circuit_t2string(level), circuit->interface->name); - - memcpy (lsp_id, isis->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = circuit->circuit_id; - LSP_FRAGMENT (lsp_id) = 0; - now = time (NULL); - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) - { - sched_debug("ISIS (%s): Checking whether L%d pseudo LSP needs to be scheduled", - area->area_tag, lvl); - - if (!((level & lvl) && (circuit->is_type & lvl))) - { - sched_debug("ISIS (%s): Level is not active on circuit", - area->area_tag); - continue; - } - - if (circuit->u.bc.is_dr[lvl - 1] == 0) - { - sched_debug("ISIS (%s): This IS is not DR, nothing to do.", - area->area_tag); - continue; - } - - if (circuit->lsp_regenerate_pending[lvl - 1]) - { - struct timeval remain = - thread_timer_remain(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); - sched_debug("ISIS (%s): Regenerate is already pending, nothing todo." - " (Due in %lld.%03lld seconds)", area->area_tag, - (long long)remain.tv_sec, (long long)remain.tv_usec/1000); - continue; - } - - lsp = lsp_search (lsp_id, circuit->area->lspdb[lvl - 1]); - if (!lsp) - { - sched_debug("ISIS (%s): Pseudonode LSP does not exist yet, nothing to regenerate.", - area->area_tag); - continue; - } - - /* - * Throttle avoidance - */ - sched_debug("ISIS (%s): Will schedule PSN regen timer. Last run was: %lld, Now is: %lld", - area->area_tag, (long long)lsp->last_generated, (long long) now); - THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); - diff = now - lsp->last_generated; - if (diff < circuit->area->lsp_gen_interval[lvl - 1]) - { - timeout = 1000 * (circuit->area->lsp_gen_interval[lvl - 1] - diff); - sched_debug("ISIS (%s): Sechduling in %ld ms to match configured lsp_gen_interval", - area->area_tag, timeout); - } - else - { - timeout = 100; - sched_debug("ISIS (%s): Last generation was more than lsp_gen_interval ago." - " Scheduling for execution in %ld ms.", area->area_tag, timeout); - } - - circuit->lsp_regenerate_pending[lvl - 1] = 1; - - if (lvl == IS_LEVEL_1) - { - thread_add_timer_msec(master, lsp_l1_refresh_pseudo, circuit, - timeout, - &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); - } - else if (lvl == IS_LEVEL_2) - { - thread_add_timer_msec(master, lsp_l2_refresh_pseudo, circuit, - timeout, - &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); - } - } - - return ISIS_OK; + struct isis_lsp *lsp; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + time_t now, diff; + long timeout; + int lvl; + struct isis_area *area = circuit->area; + + if (circuit->circ_type != CIRCUIT_T_BROADCAST + || circuit->state != C_STATE_UP) + return ISIS_OK; + + sched_debug( + "ISIS (%s): Scheduling regeneration of %s pseudo LSP for interface %s", + area->area_tag, circuit_t2string(level), + circuit->interface->name); + + memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id; + LSP_FRAGMENT(lsp_id) = 0; + now = time(NULL); + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + sched_debug( + "ISIS (%s): Checking whether L%d pseudo LSP needs to be scheduled", + area->area_tag, lvl); + + if (!((level & lvl) && (circuit->is_type & lvl))) { + sched_debug("ISIS (%s): Level is not active on circuit", + area->area_tag); + continue; + } + + if (circuit->u.bc.is_dr[lvl - 1] == 0) { + sched_debug( + "ISIS (%s): This IS is not DR, nothing to do.", + area->area_tag); + continue; + } + + if (circuit->lsp_regenerate_pending[lvl - 1]) { + struct timeval remain = thread_timer_remain( + circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); + sched_debug( + "ISIS (%s): Regenerate is already pending, nothing todo." + " (Due in %lld.%03lld seconds)", + area->area_tag, (long long)remain.tv_sec, + (long long)remain.tv_usec / 1000); + continue; + } + + lsp = lsp_search(lsp_id, circuit->area->lspdb[lvl - 1]); + if (!lsp) { + sched_debug( + "ISIS (%s): Pseudonode LSP does not exist yet, nothing to regenerate.", + area->area_tag); + continue; + } + + /* + * Throttle avoidance + */ + sched_debug( + "ISIS (%s): Will schedule PSN regen timer. Last run was: %lld, Now is: %lld", + area->area_tag, (long long)lsp->last_generated, + (long long)now); + THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); + diff = now - lsp->last_generated; + if (diff < circuit->area->lsp_gen_interval[lvl - 1]) { + timeout = + 1000 * (circuit->area->lsp_gen_interval[lvl - 1] + - diff); + sched_debug( + "ISIS (%s): Sechduling in %ld ms to match configured lsp_gen_interval", + area->area_tag, timeout); + } else { + timeout = 100; + sched_debug( + "ISIS (%s): Last generation was more than lsp_gen_interval ago." + " Scheduling for execution in %ld ms.", + area->area_tag, timeout); + } + + circuit->lsp_regenerate_pending[lvl - 1] = 1; + + if (lvl == IS_LEVEL_1) { + thread_add_timer_msec( + master, lsp_l1_refresh_pseudo, circuit, timeout, + &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); + } else if (lvl == IS_LEVEL_2) { + thread_add_timer_msec( + master, lsp_l2_refresh_pseudo, circuit, timeout, + &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); + } + } + + return ISIS_OK; } /* @@ -2702,231 +2789,248 @@ lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level) * - set remaining lifetime * - set LSPs with SRMflag set for sending */ -int -lsp_tick (struct thread *thread) +int lsp_tick(struct thread *thread) { - struct isis_area *area; - struct isis_circuit *circuit; - struct isis_lsp *lsp; - struct list *lsp_list; - struct listnode *lspnode, *cnode; - dnode_t *dnode, *dnode_next; - int level; - u_int16_t rem_lifetime; - - lsp_list = list_new (); - - area = THREAD_ARG (thread); - assert (area); - area->t_tick = NULL; - thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); - - /* - * Build a list of LSPs with (any) SRMflag set - * and removed the ones that have aged out - */ - for (level = 0; level < ISIS_LEVELS; level++) - { - if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0) - { - for (dnode = dict_first (area->lspdb[level]); - dnode != NULL; dnode = dnode_next) - { - dnode_next = dict_next (area->lspdb[level], dnode); - lsp = dnode_get (dnode); - - /* - * The lsp rem_lifetime is kept at 0 for MaxAge or - * ZeroAgeLifetime depending on explicit purge or - * natural age out. So schedule spf only once when - * the first time rem_lifetime becomes 0. - */ - rem_lifetime = ntohs(lsp->lsp_header->rem_lifetime); - lsp_set_time (lsp); - - /* - * Schedule may run spf which should be done only after - * the lsp rem_lifetime becomes 0 for the first time. - * ISO 10589 - 7.3.16.4 first paragraph. - */ - if (rem_lifetime == 1 && lsp->lsp_header->seq_num != 0) - { - /* 7.3.16.4 a) set SRM flags on all */ - lsp_set_all_srmflags (lsp); - /* 7.3.16.4 b) retain only the header FIXME */ - /* 7.3.16.4 c) record the time to purge FIXME */ - /* run/schedule spf */ - /* isis_spf_schedule is called inside lsp_destroy() below; - * so it is not needed here. */ - /* isis_spf_schedule (lsp->area, lsp->level); */ - } - - if (lsp->age_out == 0) - { - zlog_debug ("ISIS-Upd (%s): L%u LSP %s seq 0x%08x aged out", - area->area_tag, - lsp->level, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->seq_num)); - lsp_destroy (lsp); - lsp = NULL; - dict_delete_free (area->lspdb[level], dnode); - } - else if (flags_any_set (lsp->SRMflags)) - listnode_add (lsp_list, lsp); - } - - /* - * Send LSPs on circuits indicated by the SRMflags - */ - if (listcount (lsp_list) > 0) - { - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) - { - int diff = time (NULL) - circuit->lsp_queue_last_cleared; - if (circuit->lsp_queue == NULL || - diff < MIN_LSP_TRANS_INTERVAL) - continue; - for (ALL_LIST_ELEMENTS_RO (lsp_list, lspnode, lsp)) - { - if (circuit->upadjcount[lsp->level - 1] && - ISIS_CHECK_FLAG (lsp->SRMflags, circuit)) - { - /* Add the lsp only if it is not already in lsp - * queue */ - if (! listnode_lookup (circuit->lsp_queue, lsp)) - { - listnode_add (circuit->lsp_queue, lsp); - thread_add_event(master, send_lsp, circuit, 0, - NULL); - } - } - } - } - list_delete_all_node (lsp_list); - } - } - } - - list_delete (lsp_list); - - return ISIS_OK; + struct isis_area *area; + struct isis_circuit *circuit; + struct isis_lsp *lsp; + struct list *lsp_list; + struct listnode *lspnode, *cnode; + dnode_t *dnode, *dnode_next; + int level; + u_int16_t rem_lifetime; + + lsp_list = list_new(); + + area = THREAD_ARG(thread); + assert(area); + area->t_tick = NULL; + thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); + + /* + * Build a list of LSPs with (any) SRMflag set + * and removed the ones that have aged out + */ + for (level = 0; level < ISIS_LEVELS; level++) { + if (area->lspdb[level] && dict_count(area->lspdb[level]) > 0) { + for (dnode = dict_first(area->lspdb[level]); + dnode != NULL; dnode = dnode_next) { + dnode_next = + dict_next(area->lspdb[level], dnode); + lsp = dnode_get(dnode); + + /* + * The lsp rem_lifetime is kept at 0 for MaxAge + * or + * ZeroAgeLifetime depending on explicit purge + * or + * natural age out. So schedule spf only once + * when + * the first time rem_lifetime becomes 0. + */ + rem_lifetime = + ntohs(lsp->lsp_header->rem_lifetime); + lsp_set_time(lsp); + + /* + * Schedule may run spf which should be done + * only after + * the lsp rem_lifetime becomes 0 for the first + * time. + * ISO 10589 - 7.3.16.4 first paragraph. + */ + if (rem_lifetime == 1 + && lsp->lsp_header->seq_num != 0) { + /* 7.3.16.4 a) set SRM flags on all */ + lsp_set_all_srmflags(lsp); + /* 7.3.16.4 b) retain only the header + * FIXME */ + /* 7.3.16.4 c) record the time to purge + * FIXME */ + /* run/schedule spf */ + /* isis_spf_schedule is called inside + * lsp_destroy() below; + * so it is not needed here. */ + /* isis_spf_schedule (lsp->area, + * lsp->level); */ + } + + if (lsp->age_out == 0) { + zlog_debug( + "ISIS-Upd (%s): L%u LSP %s seq 0x%08x aged out", + area->area_tag, lsp->level, + rawlspid_print( + lsp->lsp_header + ->lsp_id), + ntohl(lsp->lsp_header + ->seq_num)); + lsp_destroy(lsp); + lsp = NULL; + dict_delete_free(area->lspdb[level], + dnode); + } else if (flags_any_set(lsp->SRMflags)) + listnode_add(lsp_list, lsp); + } + + /* + * Send LSPs on circuits indicated by the SRMflags + */ + if (listcount(lsp_list) > 0) { + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, + cnode, circuit)) { + int diff = + time(NULL) + - circuit->lsp_queue_last_cleared; + if (circuit->lsp_queue == NULL + || diff < MIN_LSP_TRANS_INTERVAL) + continue; + for (ALL_LIST_ELEMENTS_RO( + lsp_list, lspnode, lsp)) { + if (circuit->upadjcount + [lsp->level - 1] + && ISIS_CHECK_FLAG( + lsp->SRMflags, + circuit)) { + /* Add the lsp only if + * it is not already in + * lsp + * queue */ + if (!listnode_lookup( + circuit->lsp_queue, + lsp)) { + listnode_add( + circuit->lsp_queue, + lsp); + thread_add_event( + master, + send_lsp, + circuit, + 0, + NULL); + } + } + } + } + list_delete_all_node(lsp_list); + } + } + } + + list_delete(lsp_list); + + return ISIS_OK; } -void -lsp_purge_pseudo (u_char * id, struct isis_circuit *circuit, int level) +void lsp_purge_pseudo(u_char *id, struct isis_circuit *circuit, int level) { - struct isis_lsp *lsp; - u_int16_t seq_num; - u_int8_t lsp_bits; - - lsp = lsp_search (id, circuit->area->lspdb[level - 1]); - if (!lsp) - return; - - /* store old values */ - seq_num = lsp->lsp_header->seq_num; - lsp_bits = lsp->lsp_header->lsp_bits; - - /* reset stream */ - lsp_clear_data (lsp); - stream_reset (lsp->pdu); - - /* update header */ - lsp->lsp_header->pdu_len = htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - memcpy (lsp->lsp_header->lsp_id, id, ISIS_SYS_ID_LEN + 2); - lsp->lsp_header->checksum = 0; - lsp->lsp_header->seq_num = seq_num; - lsp->lsp_header->rem_lifetime = 0; - lsp->lsp_header->lsp_bits = lsp_bits; - lsp->level = level; - lsp->age_out = lsp->area->max_lsp_lifetime[level-1]; - stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - - /* - * Add and update the authentication info if its present - */ - lsp_auth_add (lsp); - lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); - lsp_auth_update (lsp); - fletcher_checksum(STREAM_DATA (lsp->pdu) + 12, - ntohs (lsp->lsp_header->pdu_len) - 12, 12); - - lsp_set_all_srmflags (lsp); - - return; + struct isis_lsp *lsp; + u_int16_t seq_num; + u_int8_t lsp_bits; + + lsp = lsp_search(id, circuit->area->lspdb[level - 1]); + if (!lsp) + return; + + /* store old values */ + seq_num = lsp->lsp_header->seq_num; + lsp_bits = lsp->lsp_header->lsp_bits; + + /* reset stream */ + lsp_clear_data(lsp); + stream_reset(lsp->pdu); + + /* update header */ + lsp->lsp_header->pdu_len = htons(ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + memcpy(lsp->lsp_header->lsp_id, id, ISIS_SYS_ID_LEN + 2); + lsp->lsp_header->checksum = 0; + lsp->lsp_header->seq_num = seq_num; + lsp->lsp_header->rem_lifetime = 0; + lsp->lsp_header->lsp_bits = lsp_bits; + lsp->level = level; + lsp->age_out = lsp->area->max_lsp_lifetime[level - 1]; + stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + + /* + * Add and update the authentication info if its present + */ + lsp_auth_add(lsp); + lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu)); + lsp_auth_update(lsp); + fletcher_checksum(STREAM_DATA(lsp->pdu) + 12, + ntohs(lsp->lsp_header->pdu_len) - 12, 12); + + lsp_set_all_srmflags(lsp); + + return; } /* - * Purge own LSP that is received and we don't have. + * Purge own LSP that is received and we don't have. * -> Do as in 7.3.16.4 */ -void -lsp_purge_non_exist (int level, - struct isis_link_state_hdr *lsp_hdr, - struct isis_area *area) +void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr, + struct isis_area *area) { - struct isis_lsp *lsp; - - /* - * We need to create the LSP to be purged - */ - lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp)); - lsp->area = area; - lsp->level = level; - lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu); - lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu); - fill_fixed_hdr (lsp->isis_header, (lsp->level == IS_LEVEL_1) ? L1_LINK_STATE - : L2_LINK_STATE); - lsp->lsp_header = (struct isis_link_state_hdr *) (STREAM_DATA (lsp->pdu) + - ISIS_FIXED_HDR_LEN); - memcpy (lsp->lsp_header, lsp_hdr, ISIS_LSP_HDR_LEN); - stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); - - /* - * Set the remaining lifetime to 0 - */ - lsp->lsp_header->rem_lifetime = 0; - - /* - * Add and update the authentication info if its present - */ - lsp_auth_add (lsp); - lsp_auth_update (lsp); - - /* - * Update the PDU length to header plus any authentication TLV. - */ - lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); - - /* - * Put the lsp into LSPdb - */ - lsp_insert (lsp, area->lspdb[lsp->level - 1]); - - /* - * Send in to whole area - */ - lsp_set_all_srmflags (lsp); - - return; + struct isis_lsp *lsp; + + /* + * We need to create the LSP to be purged + */ + lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp)); + lsp->area = area; + lsp->level = level; + lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu); + lsp->isis_header = (struct isis_fixed_hdr *)STREAM_DATA(lsp->pdu); + fill_fixed_hdr(lsp->isis_header, + (lsp->level == IS_LEVEL_1) ? L1_LINK_STATE + : L2_LINK_STATE); + lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu) + + ISIS_FIXED_HDR_LEN); + memcpy(lsp->lsp_header, lsp_hdr, ISIS_LSP_HDR_LEN); + stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); + + /* + * Set the remaining lifetime to 0 + */ + lsp->lsp_header->rem_lifetime = 0; + + /* + * Add and update the authentication info if its present + */ + lsp_auth_add(lsp); + lsp_auth_update(lsp); + + /* + * Update the PDU length to header plus any authentication TLV. + */ + lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu)); + + /* + * Put the lsp into LSPdb + */ + lsp_insert(lsp, area->lspdb[lsp->level - 1]); + + /* + * Send in to whole area + */ + lsp_set_all_srmflags(lsp); + + return; } -void lsp_set_all_srmflags (struct isis_lsp *lsp) +void lsp_set_all_srmflags(struct isis_lsp *lsp) { - struct listnode *node; - struct isis_circuit *circuit; + struct listnode *node; + struct isis_circuit *circuit; - assert (lsp); + assert(lsp); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); - if (lsp->area) - { - struct list *circuit_list = lsp->area->circuit_list; - for (ALL_LIST_ELEMENTS_RO (circuit_list, node, circuit)) - { - ISIS_SET_FLAG(lsp->SRMflags, circuit); - } - } + if (lsp->area) { + struct list *circuit_list = lsp->area->circuit_list; + for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) { + ISIS_SET_FLAG(lsp->SRMflags, circuit); + } + } } diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 0d1dd6740..7bec16271 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -1,19 +1,19 @@ /* - * IS-IS Rout(e)ing protocol - isis_lsp.h + * IS-IS Rout(e)ing protocol - isis_lsp.h * LSP processing * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -28,64 +28,58 @@ * System ID (Currently 6) (atleast for now). In order to support more * We will have to split the header into two parts, and for readability * sake it should better be avoided */ -struct isis_lsp -{ - struct isis_fixed_hdr *isis_header; /* normally equals pdu */ - struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */ - struct stream *pdu; /* full pdu lsp */ - union - { - struct list *frags; - struct isis_lsp *zero_lsp; - } lspu; - u_int32_t auth_tlv_offset; /* authentication TLV position in the pdu */ - u_int32_t SRMflags[ISIS_MAX_CIRCUITS]; - u_int32_t SSNflags[ISIS_MAX_CIRCUITS]; - int level; /* L1 or L2? */ - int scheduled; /* scheduled for sending */ - time_t installed; - time_t last_generated; - int own_lsp; - /* used for 60 second counting when rem_lifetime is zero */ - int age_out; - struct isis_area *area; - struct tlvs tlv_data; /* Simplifies TLV access */ +struct isis_lsp { + struct isis_fixed_hdr *isis_header; /* normally equals pdu */ + struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */ + struct stream *pdu; /* full pdu lsp */ + union { + struct list *frags; + struct isis_lsp *zero_lsp; + } lspu; + u_int32_t auth_tlv_offset; /* authentication TLV position in the pdu */ + u_int32_t SRMflags[ISIS_MAX_CIRCUITS]; + u_int32_t SSNflags[ISIS_MAX_CIRCUITS]; + int level; /* L1 or L2? */ + int scheduled; /* scheduled for sending */ + time_t installed; + time_t last_generated; + int own_lsp; + /* used for 60 second counting when rem_lifetime is zero */ + int age_out; + struct isis_area *area; + struct tlvs tlv_data; /* Simplifies TLV access */ }; -dict_t *lsp_db_init (void); -void lsp_db_destroy (dict_t * lspdb); -int lsp_tick (struct thread *thread); +dict_t *lsp_db_init(void); +void lsp_db_destroy(dict_t *lspdb); +int lsp_tick(struct thread *thread); -int lsp_generate (struct isis_area *area, int level); -int lsp_regenerate_schedule (struct isis_area *area, int level, - int all_pseudo); -int lsp_generate_pseudo (struct isis_circuit *circuit, int level); -int lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level); +int lsp_generate(struct isis_area *area, int level); +int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo); +int lsp_generate_pseudo(struct isis_circuit *circuit, int level); +int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level); -struct isis_lsp *lsp_new (struct isis_area *area, u_char * lsp_id, - u_int16_t rem_lifetime, - u_int32_t seq_num, u_int8_t lsp_bits, - u_int16_t checksum, int level); -struct isis_lsp *lsp_new_from_stream_ptr (struct stream *stream, - u_int16_t pdu_len, - struct isis_lsp *lsp0, - struct isis_area *area, - int level); -void lsp_insert (struct isis_lsp *lsp, dict_t * lspdb); -struct isis_lsp *lsp_search (u_char * id, dict_t * lspdb); +struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id, + u_int16_t rem_lifetime, u_int32_t seq_num, + u_int8_t lsp_bits, u_int16_t checksum, int level); +struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream, + u_int16_t pdu_len, + struct isis_lsp *lsp0, + struct isis_area *area, int level); +void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb); +struct isis_lsp *lsp_search(u_char *id, dict_t *lspdb); -void lsp_build_list (u_char * start_id, u_char * stop_id, u_char num_lsps, - struct list *list, dict_t * lspdb); -void lsp_build_list_nonzero_ht (u_char * start_id, u_char * stop_id, - struct list *list, dict_t * lspdb); -void lsp_build_list_ssn (struct isis_circuit *circuit, u_char num_lsps, - struct list *list, dict_t * lspdb); +void lsp_build_list(u_char *start_id, u_char *stop_id, u_char num_lsps, + struct list *list, dict_t *lspdb); +void lsp_build_list_nonzero_ht(u_char *start_id, u_char *stop_id, + struct list *list, dict_t *lspdb); +void lsp_build_list_ssn(struct isis_circuit *circuit, u_char num_lsps, + struct list *list, dict_t *lspdb); -void lsp_search_and_destroy (u_char * id, dict_t * lspdb); -void lsp_purge_pseudo (u_char * id, struct isis_circuit *circuit, int level); -void lsp_purge_non_exist (int level, - struct isis_link_state_hdr *lsp_hdr, - struct isis_area *area); +void lsp_search_and_destroy(u_char *id, dict_t *lspdb); +void lsp_purge_pseudo(u_char *id, struct isis_circuit *circuit, int level); +void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr, + struct isis_area *area); #define LSP_EQUAL 1 #define LSP_NEWER 2 @@ -93,23 +87,22 @@ void lsp_purge_non_exist (int level, #define LSP_PSEUDO_ID(I) ((I)[ISIS_SYS_ID_LEN]) #define LSP_FRAGMENT(I) ((I)[ISIS_SYS_ID_LEN + 1]) -#define OWNLSPID(I) \ - memcpy ((I), isis->sysid, ISIS_SYS_ID_LEN);\ - (I)[ISIS_SYS_ID_LEN] = 0;\ - (I)[ISIS_SYS_ID_LEN + 1] = 0 -int lsp_id_cmp (u_char * id1, u_char * id2); -int lsp_compare (char *areatag, struct isis_lsp *lsp, u_int32_t seq_num, - u_int16_t checksum, u_int16_t rem_lifetime); -void lsp_update (struct isis_lsp *lsp, struct stream *stream, - struct isis_area *area, int level); -void lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num); -void lsp_print (struct isis_lsp *lsp, struct vty *vty, char dynhost); -void lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost); -int lsp_print_all (struct vty *vty, dict_t * lspdb, char detail, - char dynhost); -const char *lsp_bits2string (u_char *); +#define OWNLSPID(I) \ + memcpy((I), isis->sysid, ISIS_SYS_ID_LEN); \ + (I)[ISIS_SYS_ID_LEN] = 0; \ + (I)[ISIS_SYS_ID_LEN + 1] = 0 +int lsp_id_cmp(u_char *id1, u_char *id2); +int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num, + u_int16_t checksum, u_int16_t rem_lifetime); +void lsp_update(struct isis_lsp *lsp, struct stream *stream, + struct isis_area *area, int level); +void lsp_inc_seqnum(struct isis_lsp *lsp, u_int32_t seq_num); +void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost); +void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost); +int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost); +const char *lsp_bits2string(u_char *); /* sets SRMflags for all active circuits of an lsp */ -void lsp_set_all_srmflags (struct isis_lsp *lsp); +void lsp_set_all_srmflags(struct isis_lsp *lsp); #endif /* ISIS_LSP */ diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 674592f46..463e3abcf 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_main.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -61,30 +61,24 @@ #define ISISD_VTY_PORT 2608 /* isisd privileges */ -zebra_capabilities_t _caps_p[] = { - ZCAP_NET_RAW, - ZCAP_BIND -}; +zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; struct zebra_privs_t isisd_privs = { #if defined(FRR_USER) - .user = FRR_USER, + .user = FRR_USER, #endif #if defined FRR_GROUP - .group = FRR_GROUP, + .group = FRR_GROUP, #endif #ifdef VTY_GROUP - .vty_group = VTY_GROUP, + .vty_group = VTY_GROUP, #endif - .caps_p = _caps_p, - .cap_num_p = sizeof (_caps_p) / sizeof (*_caps_p), - .cap_num_i = 0 -}; + .caps_p = _caps_p, + .cap_num_p = sizeof(_caps_p) / sizeof(*_caps_p), + .cap_num_i = 0}; /* isisd options */ -struct option longopts[] = { - {0} -}; +struct option longopts[] = {{0}}; /* Master of threads. */ struct thread_master *master; @@ -98,132 +92,122 @@ void sigterm(void); void sigusr1(void); -static __attribute__((__noreturn__)) void -terminate (int i) +static __attribute__((__noreturn__)) void terminate(int i) { - isis_zebra_stop (); - exit (i); + isis_zebra_stop(); + exit(i); } /* * Signal handlers */ -void -sighup (void) +void sighup(void) { - zlog_err ("SIGHUP/reload is not implemented for isisd"); - return; + zlog_err("SIGHUP/reload is not implemented for isisd"); + return; } -__attribute__((__noreturn__)) void -sigint (void) +__attribute__((__noreturn__)) void sigint(void) { - zlog_notice ("Terminating on signal SIGINT"); - terminate (0); + zlog_notice("Terminating on signal SIGINT"); + terminate(0); } -__attribute__((__noreturn__)) void -sigterm (void) +__attribute__((__noreturn__)) void sigterm(void) { - zlog_notice ("Terminating on signal SIGTERM"); - terminate (0); + zlog_notice("Terminating on signal SIGTERM"); + terminate(0); } -void -sigusr1 (void) +void sigusr1(void) { - zlog_debug ("SIGUSR1 received"); - zlog_rotate(); + zlog_debug("SIGUSR1 received"); + zlog_rotate(); } -struct quagga_signal_t isisd_signals[] = -{ - { - .signal = SIGHUP, - .handler = &sighup, - }, - { - .signal = SIGUSR1, - .handler = &sigusr1, - }, - { - .signal = SIGINT, - .handler = &sigint, - }, - { - .signal = SIGTERM, - .handler = &sigterm, - }, +struct quagga_signal_t isisd_signals[] = { + { + .signal = SIGHUP, + .handler = &sighup, + }, + { + .signal = SIGUSR1, + .handler = &sigusr1, + }, + { + .signal = SIGINT, + .handler = &sigint, + }, + { + .signal = SIGTERM, + .handler = &sigterm, + }, }; -FRR_DAEMON_INFO(isisd, ISIS, - .vty_port = ISISD_VTY_PORT, +FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT, - .proghelp = "Implementation of the IS-IS routing protocol.", - .copyright = "Copyright (c) 2001-2002 Sampo Saaristo," - " Ofer Wald and Hannes Gredler", + .proghelp = "Implementation of the IS-IS routing protocol.", + .copyright = + "Copyright (c) 2001-2002 Sampo Saaristo," + " Ofer Wald and Hannes Gredler", - .signals = isisd_signals, - .n_signals = array_size(isisd_signals), + .signals = isisd_signals, + .n_signals = array_size(isisd_signals), - .privs = &isisd_privs, -) + .privs = &isisd_privs, ) /* * Main routine of isisd. Parse arguments and handle IS-IS state machine. */ -int -main (int argc, char **argv, char **envp) +int main(int argc, char **argv, char **envp) { - int opt; + int opt; - frr_preinit (&isisd_di, argc, argv); - frr_opt_add ("", longopts, ""); + frr_preinit(&isisd_di, argc, argv); + frr_opt_add("", longopts, ""); - /* Command line argument treatment. */ - while (1) - { - opt = frr_getopt (argc, argv, NULL); + /* Command line argument treatment. */ + while (1) { + opt = frr_getopt(argc, argv, NULL); - if (opt == EOF) - break; + if (opt == EOF) + break; - switch (opt) - { - case 0: - break; - default: - frr_help_exit (1); - break; + switch (opt) { + case 0: + break; + default: + frr_help_exit(1); + break; + } } - } - - vty_config_lockless (); - /* thread master */ - master = frr_init (); - - /* - * initializations - */ - access_list_init(); - vrf_init (NULL, NULL, NULL, NULL); - prefix_list_init(); - isis_init (); - isis_circuit_init (); - isis_spf_cmds_init (); - isis_redist_init (); - isis_route_map_init(); - isis_mpls_te_init(); - - /* create the global 'isis' instance */ - isis_new (1); - - isis_zebra_init(master); - - frr_config_fork (); - frr_run (master); - - /* Not reached. */ - exit (0); + + vty_config_lockless(); + /* thread master */ + master = frr_init(); + + /* + * initializations + */ + access_list_init(); + vrf_init(NULL, NULL, NULL, NULL); + prefix_list_init(); + isis_init(); + isis_circuit_init(); + isis_spf_cmds_init(); + isis_redist_init(); + isis_route_map_init(); + isis_mpls_te_init(); + + /* create the global 'isis' instance */ + isis_new(1); + + isis_zebra_init(master); + + frr_config_fork(); + frr_run(master); + + /* Not reached. */ + exit(0); } diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c index 101fdcc69..4ad26cf91 100644 --- a/isisd/isis_memory.c +++ b/isisd/isis_memory.c @@ -26,22 +26,22 @@ #include "isis_memory.h" DEFINE_MGROUP(ISISD, "isisd") -DEFINE_MTYPE(ISISD, ISIS, "ISIS") -DEFINE_MTYPE(ISISD, ISIS_TMP, "ISIS TMP") -DEFINE_MTYPE(ISISD, ISIS_CIRCUIT, "ISIS circuit") -DEFINE_MTYPE(ISISD, ISIS_LSP, "ISIS LSP") -DEFINE_MTYPE(ISISD, ISIS_ADJACENCY, "ISIS adjacency") -DEFINE_MTYPE(ISISD, ISIS_AREA, "ISIS area") -DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address") -DEFINE_MTYPE(ISISD, ISIS_TLV, "ISIS TLV") -DEFINE_MTYPE(ISISD, ISIS_DYNHN, "ISIS dyn hostname") -DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree") -DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex") -DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info") -DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop") -DEFINE_MTYPE(ISISD, ISIS_NEXTHOP6, "ISIS nexthop6") -DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary") -DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node") -DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") -DEFINE_MTYPE(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info") -DEFINE_MTYPE(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters") +DEFINE_MTYPE(ISISD, ISIS, "ISIS") +DEFINE_MTYPE(ISISD, ISIS_TMP, "ISIS TMP") +DEFINE_MTYPE(ISISD, ISIS_CIRCUIT, "ISIS circuit") +DEFINE_MTYPE(ISISD, ISIS_LSP, "ISIS LSP") +DEFINE_MTYPE(ISISD, ISIS_ADJACENCY, "ISIS adjacency") +DEFINE_MTYPE(ISISD, ISIS_AREA, "ISIS area") +DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address") +DEFINE_MTYPE(ISISD, ISIS_TLV, "ISIS TLV") +DEFINE_MTYPE(ISISD, ISIS_DYNHN, "ISIS dyn hostname") +DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree") +DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex") +DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info") +DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop") +DEFINE_MTYPE(ISISD, ISIS_NEXTHOP6, "ISIS nexthop6") +DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary") +DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node") +DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") +DEFINE_MTYPE(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info") +DEFINE_MTYPE(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters") diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 3869159a0..16c789ff5 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -3,17 +3,17 @@ * Miscellanous routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -62,147 +62,121 @@ char nlpidstring[30]; /* * This converts the isonet to its printable format */ -const char * -isonet_print (const u_char * from, int len) +const char *isonet_print(const u_char *from, int len) { - int i = 0; - char *pos = isonet; - - if (!from) - return "unknown"; - - while (i < len) - { - if (i & 1) - { - sprintf (pos, "%02x", *(from + i)); - pos += 2; + int i = 0; + char *pos = isonet; + + if (!from) + return "unknown"; + + while (i < len) { + if (i & 1) { + sprintf(pos, "%02x", *(from + i)); + pos += 2; + } else { + if (i == (len - 1)) { /* No dot at the end of address */ + sprintf(pos, "%02x", *(from + i)); + pos += 2; + } else { + sprintf(pos, "%02x.", *(from + i)); + pos += 3; + } + } + i++; } - else - { - if (i == (len - 1)) - { /* No dot at the end of address */ - sprintf (pos, "%02x", *(from + i)); - pos += 2; - } - else - { - sprintf (pos, "%02x.", *(from + i)); - pos += 3; - } - } - i++; - } - *(pos) = '\0'; - return isonet; + *(pos) = '\0'; + return isonet; } /* * Returns 0 on error, length of buff on ok - * extract dot from the dotted str, and insert all the number in a buff + * extract dot from the dotted str, and insert all the number in a buff */ -int -dotformat2buff (u_char * buff, const char * dotted) +int dotformat2buff(u_char *buff, const char *dotted) { - int dotlen, len = 0; - const char *pos = dotted; - u_char number[3]; - int nextdotpos = 2; - - number[2] = '\0'; - dotlen = strlen(dotted); - if (dotlen > 50) - { - /* this can't be an iso net, its too long */ - return 0; - } - - while ((pos - dotted) < dotlen && len < 20) - { - if (*pos == '.') - { - /* we expect the . at 2, and than every 5 */ - if ((pos - dotted) != nextdotpos) - { - len = 0; - break; - } - nextdotpos += 5; - pos++; - continue; - } - /* we must have at least two chars left here */ - if (dotlen - (pos - dotted) < 2) - { - len = 0; - break; + int dotlen, len = 0; + const char *pos = dotted; + u_char number[3]; + int nextdotpos = 2; + + number[2] = '\0'; + dotlen = strlen(dotted); + if (dotlen > 50) { + /* this can't be an iso net, its too long */ + return 0; } - if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1)))) - { - memcpy (number, pos, 2); - pos += 2; + while ((pos - dotted) < dotlen && len < 20) { + if (*pos == '.') { + /* we expect the . at 2, and than every 5 */ + if ((pos - dotted) != nextdotpos) { + len = 0; + break; + } + nextdotpos += 5; + pos++; + continue; + } + /* we must have at least two chars left here */ + if (dotlen - (pos - dotted) < 2) { + len = 0; + break; + } + + if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos + 1)))) { + memcpy(number, pos, 2); + pos += 2; + } else { + len = 0; + break; + } + + *(buff + len) = (char)strtol((char *)number, NULL, 16); + len++; } - else - { - len = 0; - break; - } - - *(buff + len) = (char) strtol ((char *)number, NULL, 16); - len++; - } - return len; + return len; } /* * conversion of XXXX.XXXX.XXXX to memory */ -int -sysid2buff (u_char * buff, const char * dotted) +int sysid2buff(u_char *buff, const char *dotted) { - int len = 0; - const char *pos = dotted; - u_char number[3]; - - number[2] = '\0'; - // surely not a sysid_string if not 14 length - if (strlen (dotted) != 14) - { - return 0; - } - - while (len < ISIS_SYS_ID_LEN) - { - if (*pos == '.') - { - /* the . is not positioned correctly */ - if (((pos - dotted) != 4) && ((pos - dotted) != 9)) - { - len = 0; - break; - } - pos++; - continue; - } - if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1)))) - { - memcpy (number, pos, 2); - pos += 2; - } - else - { - len = 0; - break; + int len = 0; + const char *pos = dotted; + u_char number[3]; + + number[2] = '\0'; + // surely not a sysid_string if not 14 length + if (strlen(dotted) != 14) { + return 0; } - *(buff + len) = (char) strtol ((char *)number, NULL, 16); - len++; - } - - return len; + while (len < ISIS_SYS_ID_LEN) { + if (*pos == '.') { + /* the . is not positioned correctly */ + if (((pos - dotted) != 4) && ((pos - dotted) != 9)) { + len = 0; + break; + } + pos++; + continue; + } + if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos + 1)))) { + memcpy(number, pos, 2); + pos += 2; + } else { + len = 0; + break; + } + + *(buff + len) = (char)strtol((char *)number, NULL, 16); + len++; + } + return len; } /* @@ -210,280 +184,251 @@ sysid2buff (u_char * buff, const char * dotted) * into a string */ -char * -nlpid2string (struct nlpids *nlpids) +char *nlpid2string(struct nlpids *nlpids) { - char *pos = nlpidstring; - int i; - - for (i = 0; i < nlpids->count; i++) - { - switch (nlpids->nlpids[i]) - { - case NLPID_IP: - pos += sprintf (pos, "IPv4"); - break; - case NLPID_IPV6: - pos += sprintf (pos, "IPv6"); - break; - case NLPID_SNAP: - pos += sprintf (pos, "SNAP"); - break; - case NLPID_CLNP: - pos += sprintf (pos, "CLNP"); - break; - case NLPID_ESIS: - pos += sprintf (pos, "ES-IS"); - break; - default: - pos += sprintf (pos, "unknown"); - break; + char *pos = nlpidstring; + int i; + + for (i = 0; i < nlpids->count; i++) { + switch (nlpids->nlpids[i]) { + case NLPID_IP: + pos += sprintf(pos, "IPv4"); + break; + case NLPID_IPV6: + pos += sprintf(pos, "IPv6"); + break; + case NLPID_SNAP: + pos += sprintf(pos, "SNAP"); + break; + case NLPID_CLNP: + pos += sprintf(pos, "CLNP"); + break; + case NLPID_ESIS: + pos += sprintf(pos, "ES-IS"); + break; + default: + pos += sprintf(pos, "unknown"); + break; + } + if (nlpids->count - i > 1) + pos += sprintf(pos, ", "); } - if (nlpids->count - i > 1) - pos += sprintf (pos, ", "); - - } - *(pos) = '\0'; + *(pos) = '\0'; - return nlpidstring; + return nlpidstring; } /* * supports the given af ? */ -int -speaks (struct nlpids *nlpids, int family) +int speaks(struct nlpids *nlpids, int family) { - int i, speaks = 0; - - if (nlpids == (struct nlpids *) NULL) - return speaks; - for (i = 0; i < nlpids->count; i++) - { - if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP) - speaks = 1; - if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6) - speaks = 1; - } - - return speaks; + int i, speaks = 0; + + if (nlpids == (struct nlpids *)NULL) + return speaks; + for (i = 0; i < nlpids->count; i++) { + if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP) + speaks = 1; + if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6) + speaks = 1; + } + + return speaks; } /* * Returns 0 on error, IS-IS Circuit Type on ok */ -int -string2circuit_t (const char * str) +int string2circuit_t(const char *str) { - if (!str) - return 0; + if (!str) + return 0; - if (!strcmp (str, "level-1")) - return IS_LEVEL_1; + if (!strcmp(str, "level-1")) + return IS_LEVEL_1; - if (!strcmp (str, "level-2-only") || !strcmp (str, "level-2")) - return IS_LEVEL_2; + if (!strcmp(str, "level-2-only") || !strcmp(str, "level-2")) + return IS_LEVEL_2; - if (!strcmp (str, "level-1-2")) - return IS_LEVEL_1_AND_2; + if (!strcmp(str, "level-1-2")) + return IS_LEVEL_1_AND_2; - return 0; + return 0; } -const char * -circuit_state2string (int state) +const char *circuit_state2string(int state) { - switch (state) - { - case C_STATE_INIT: - return "Init"; - case C_STATE_CONF: - return "Config"; - case C_STATE_UP: - return "Up"; - default: - return "Unknown"; - } - return NULL; + switch (state) { + case C_STATE_INIT: + return "Init"; + case C_STATE_CONF: + return "Config"; + case C_STATE_UP: + return "Up"; + default: + return "Unknown"; + } + return NULL; } -const char * -circuit_type2string (int type) +const char *circuit_type2string(int type) { - switch (type) - { - case CIRCUIT_T_P2P: - return "p2p"; - case CIRCUIT_T_BROADCAST: - return "lan"; - case CIRCUIT_T_LOOPBACK: - return "loopback"; - default: - return "Unknown"; - } - return NULL; + switch (type) { + case CIRCUIT_T_P2P: + return "p2p"; + case CIRCUIT_T_BROADCAST: + return "lan"; + case CIRCUIT_T_LOOPBACK: + return "loopback"; + default: + return "Unknown"; + } + return NULL; } -const char * -circuit_t2string (int circuit_t) +const char *circuit_t2string(int circuit_t) { - switch (circuit_t) - { - case IS_LEVEL_1: - return "L1"; - case IS_LEVEL_2: - return "L2"; - case IS_LEVEL_1_AND_2: - return "L1L2"; - default: - return "??"; - } - - return NULL; /* not reached */ + switch (circuit_t) { + case IS_LEVEL_1: + return "L1"; + case IS_LEVEL_2: + return "L2"; + case IS_LEVEL_1_AND_2: + return "L1L2"; + default: + return "??"; + } + + return NULL; /* not reached */ } -const char * -syst2string (int type) +const char *syst2string(int type) { - switch (type) - { - case ISIS_SYSTYPE_ES: - return "ES"; - case ISIS_SYSTYPE_IS: - return "IS"; - case ISIS_SYSTYPE_L1_IS: - return "1"; - case ISIS_SYSTYPE_L2_IS: - return "2"; - default: - return "??"; - } - - return NULL; /* not reached */ + switch (type) { + case ISIS_SYSTYPE_ES: + return "ES"; + case ISIS_SYSTYPE_IS: + return "IS"; + case ISIS_SYSTYPE_L1_IS: + return "1"; + case ISIS_SYSTYPE_L2_IS: + return "2"; + default: + return "??"; + } + + return NULL; /* not reached */ } /* * Print functions - we print to static vars */ -const char * -snpa_print (const u_char * from) +const char *snpa_print(const u_char *from) { - int i = 0; - u_char *pos = (u_char *)snpa; - - if (!from) - return "unknown"; - - while (i < ETH_ALEN - 1) - { - if (i & 1) - { - sprintf ((char *)pos, "%02x.", *(from + i)); - pos += 3; + int i = 0; + u_char *pos = (u_char *)snpa; + + if (!from) + return "unknown"; + + while (i < ETH_ALEN - 1) { + if (i & 1) { + sprintf((char *)pos, "%02x.", *(from + i)); + pos += 3; + } else { + sprintf((char *)pos, "%02x", *(from + i)); + pos += 2; + } + i++; } - else - { - sprintf ((char *)pos, "%02x", *(from + i)); - pos += 2; - } - i++; - } - - sprintf ((char *)pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1))); - pos += 2; - *(pos) = '\0'; + sprintf((char *)pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1))); + pos += 2; + *(pos) = '\0'; - return snpa; + return snpa; } -const char * -sysid_print (const u_char * from) +const char *sysid_print(const u_char *from) { - int i = 0; - char *pos = sysid; - - if (!from) - return "unknown"; - - while (i < ISIS_SYS_ID_LEN - 1) - { - if (i & 1) - { - sprintf (pos, "%02x.", *(from + i)); - pos += 3; - } - else - { - sprintf (pos, "%02x", *(from + i)); - pos += 2; - + int i = 0; + char *pos = sysid; + + if (!from) + return "unknown"; + + while (i < ISIS_SYS_ID_LEN - 1) { + if (i & 1) { + sprintf(pos, "%02x.", *(from + i)); + pos += 3; + } else { + sprintf(pos, "%02x", *(from + i)); + pos += 2; + } + i++; } - i++; - } - sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1))); - pos += 2; - *(pos) = '\0'; + sprintf(pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1))); + pos += 2; + *(pos) = '\0'; - return sysid; + return sysid; } -const char * -rawlspid_print (const u_char * from) +const char *rawlspid_print(const u_char *from) { - char *pos = lspid; - if (!from) - return "unknown"; - memcpy (pos, sysid_print (from), 15); - pos += 14; - sprintf (pos, ".%02x", LSP_PSEUDO_ID (from)); - pos += 3; - sprintf (pos, "-%02x", LSP_FRAGMENT (from)); - pos += 3; - - *(pos) = '\0'; - - return lspid; + char *pos = lspid; + if (!from) + return "unknown"; + memcpy(pos, sysid_print(from), 15); + pos += 14; + sprintf(pos, ".%02x", LSP_PSEUDO_ID(from)); + pos += 3; + sprintf(pos, "-%02x", LSP_FRAGMENT(from)); + pos += 3; + + *(pos) = '\0'; + + return lspid; } -const char * -time2string (u_int32_t time) +const char *time2string(u_int32_t time) { - char *pos = datestring; - u_int32_t rest; - - if (time == 0) - return "-"; - - if (time / SECS_PER_YEAR) - pos += sprintf (pos, "%uY", time / SECS_PER_YEAR); - rest = time % SECS_PER_YEAR; - if (rest / SECS_PER_MONTH) - pos += sprintf (pos, "%uM", rest / SECS_PER_MONTH); - rest = rest % SECS_PER_MONTH; - if (rest / SECS_PER_WEEK) - pos += sprintf (pos, "%uw", rest / SECS_PER_WEEK); - rest = rest % SECS_PER_WEEK; - if (rest / SECS_PER_DAY) - pos += sprintf (pos, "%ud", rest / SECS_PER_DAY); - rest = rest % SECS_PER_DAY; - if (rest / SECS_PER_HOUR) - pos += sprintf (pos, "%uh", rest / SECS_PER_HOUR); - rest = rest % SECS_PER_HOUR; - if (rest / SECS_PER_MINUTE) - pos += sprintf (pos, "%um", rest / SECS_PER_MINUTE); - rest = rest % SECS_PER_MINUTE; - if (rest) - pos += sprintf (pos, "%us", rest); - - *(pos) = 0; - - return datestring; + char *pos = datestring; + u_int32_t rest; + + if (time == 0) + return "-"; + + if (time / SECS_PER_YEAR) + pos += sprintf(pos, "%uY", time / SECS_PER_YEAR); + rest = time % SECS_PER_YEAR; + if (rest / SECS_PER_MONTH) + pos += sprintf(pos, "%uM", rest / SECS_PER_MONTH); + rest = rest % SECS_PER_MONTH; + if (rest / SECS_PER_WEEK) + pos += sprintf(pos, "%uw", rest / SECS_PER_WEEK); + rest = rest % SECS_PER_WEEK; + if (rest / SECS_PER_DAY) + pos += sprintf(pos, "%ud", rest / SECS_PER_DAY); + rest = rest % SECS_PER_DAY; + if (rest / SECS_PER_HOUR) + pos += sprintf(pos, "%uh", rest / SECS_PER_HOUR); + rest = rest % SECS_PER_HOUR; + if (rest / SECS_PER_MINUTE) + pos += sprintf(pos, "%um", rest / SECS_PER_MINUTE); + rest = rest % SECS_PER_MINUTE; + if (rest) + pos += sprintf(pos, "%us", rest); + + *(pos) = 0; + + return datestring; } /* @@ -493,141 +438,137 @@ time2string (u_int32_t time) * first argument is the timer and the second is * the jitter */ -unsigned long -isis_jitter (unsigned long timer, unsigned long jitter) +unsigned long isis_jitter(unsigned long timer, unsigned long jitter) { - int j, k; + int j, k; - if (jitter >= 100) - return timer; + if (jitter >= 100) + return timer; - if (timer == 1) - return timer; - /* - * randomizing just the percent value provides - * no good random numbers - hence the spread - * to RANDOM_SPREAD (100000), which is ok as - * most IS-IS timers are no longer than 16 bit - */ + if (timer == 1) + return timer; + /* + * randomizing just the percent value provides + * no good random numbers - hence the spread + * to RANDOM_SPREAD (100000), which is ok as + * most IS-IS timers are no longer than 16 bit + */ - j = 1 + (int) ((RANDOM_SPREAD * random ()) / (RAND_MAX + 1.0)); + j = 1 + (int)((RANDOM_SPREAD * random()) / (RAND_MAX + 1.0)); - k = timer - (timer * (100 - jitter)) / 100; + k = timer - (timer * (100 - jitter)) / 100; - timer = timer - (k * j / RANDOM_SPREAD); + timer = timer - (k * j / RANDOM_SPREAD); - return timer; + return timer; } -struct in_addr -newprefix2inaddr (u_char * prefix_start, u_char prefix_masklen) +struct in_addr newprefix2inaddr(u_char *prefix_start, u_char prefix_masklen) { - memset (&new_prefix, 0, sizeof (new_prefix)); - memcpy (&new_prefix, prefix_start, (prefix_masklen & 0x3F) ? - ((((prefix_masklen & 0x3F) - 1) >> 3) + 1) : 0); - return new_prefix; + memset(&new_prefix, 0, sizeof(new_prefix)); + memcpy(&new_prefix, prefix_start, + (prefix_masklen & 0x3F) + ? ((((prefix_masklen & 0x3F) - 1) >> 3) + 1) + : 0); + return new_prefix; } /* * Returns host.name if any, otherwise * it returns the system hostname. */ -const char * -unix_hostname (void) +const char *unix_hostname(void) { - static struct utsname names; - const char *hostname; + static struct utsname names; + const char *hostname; - hostname = host.name; - if (!hostname) - { - uname (&names); - hostname = names.nodename; - } + hostname = host.name; + if (!hostname) { + uname(&names); + hostname = names.nodename; + } - return hostname; + return hostname; } /* * Returns the dynamic hostname associated with the passed system ID. * If no dynamic hostname found then returns formatted system ID. */ -const char * -print_sys_hostname (const u_char *sysid) +const char *print_sys_hostname(const u_char *sysid) { - struct isis_dynhn *dyn; + struct isis_dynhn *dyn; - if (!sysid) - return "nullsysid"; + if (!sysid) + return "nullsysid"; - /* For our system ID return our host name */ - if (memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN) == 0) - return unix_hostname(); + /* For our system ID return our host name */ + if (memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN) == 0) + return unix_hostname(); - dyn = dynhn_find_by_id (sysid); - if (dyn) - return (const char *)dyn->name.name; + dyn = dynhn_find_by_id(sysid); + if (dyn) + return (const char *)dyn->name.name; - return sysid_print (sysid); + return sysid_print(sysid); } /* * This function is a generic utility that logs data of given length. * Move this to a shared lib so that any protocol can use it. */ -void -zlog_dump_data (void *data, int len) +void zlog_dump_data(void *data, int len) { - int i; - unsigned char *p; - unsigned char c; - char bytestr[4]; - char addrstr[10]; - char hexstr[ 16*3 + 5]; - char charstr[16*1 + 5]; - - p = data; - memset (bytestr, 0, sizeof(bytestr)); - memset (addrstr, 0, sizeof(addrstr)); - memset (hexstr, 0, sizeof(hexstr)); - memset (charstr, 0, sizeof(charstr)); - - for (i = 1; i <= len; i++) - { - c = *p; - if (isalnum (c) == 0) - c = '.'; - - /* store address for this line */ - if ((i % 16) == 1) - snprintf (addrstr, sizeof(addrstr), "%p", p); - - /* store hex str (for left side) */ - snprintf (bytestr, sizeof (bytestr), "%02X ", *p); - strncat (hexstr, bytestr, sizeof (hexstr) - strlen (hexstr) - 1); - - /* store char str (for right side) */ - snprintf (bytestr, sizeof (bytestr), "%c", c); - strncat (charstr, bytestr, sizeof (charstr) - strlen (charstr) - 1); - - if ((i % 16) == 0) - { - /* line completed */ - zlog_debug ("[%8.8s] %-50.50s %s", addrstr, hexstr, charstr); - hexstr[0] = 0; - charstr[0] = 0; - } - else if ((i % 8) == 0) - { - /* half line: add whitespaces */ - strncat (hexstr, " ", sizeof (hexstr) - strlen (hexstr) - 1); - strncat (charstr, " ", sizeof (charstr) - strlen (charstr) - 1); - } - p++; /* next byte */ - } - - /* print rest of buffer if not empty */ - if (strlen (hexstr) > 0) - zlog_debug ("[%8.8s] %-50.50s %s", addrstr, hexstr, charstr); - return; + int i; + unsigned char *p; + unsigned char c; + char bytestr[4]; + char addrstr[10]; + char hexstr[16 * 3 + 5]; + char charstr[16 * 1 + 5]; + + p = data; + memset(bytestr, 0, sizeof(bytestr)); + memset(addrstr, 0, sizeof(addrstr)); + memset(hexstr, 0, sizeof(hexstr)); + memset(charstr, 0, sizeof(charstr)); + + for (i = 1; i <= len; i++) { + c = *p; + if (isalnum(c) == 0) + c = '.'; + + /* store address for this line */ + if ((i % 16) == 1) + snprintf(addrstr, sizeof(addrstr), "%p", p); + + /* store hex str (for left side) */ + snprintf(bytestr, sizeof(bytestr), "%02X ", *p); + strncat(hexstr, bytestr, sizeof(hexstr) - strlen(hexstr) - 1); + + /* store char str (for right side) */ + snprintf(bytestr, sizeof(bytestr), "%c", c); + strncat(charstr, bytestr, + sizeof(charstr) - strlen(charstr) - 1); + + if ((i % 16) == 0) { + /* line completed */ + zlog_debug("[%8.8s] %-50.50s %s", addrstr, hexstr, + charstr); + hexstr[0] = 0; + charstr[0] = 0; + } else if ((i % 8) == 0) { + /* half line: add whitespaces */ + strncat(hexstr, " ", + sizeof(hexstr) - strlen(hexstr) - 1); + strncat(charstr, " ", + sizeof(charstr) - strlen(charstr) - 1); + } + p++; /* next byte */ + } + + /* print rest of buffer if not empty */ + if (strlen(hexstr) > 0) + zlog_debug("[%8.8s] %-50.50s %s", addrstr, hexstr, charstr); + return; } diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h index a71edd8e6..12ab0fac1 100644 --- a/isisd/isis_misc.h +++ b/isisd/isis_misc.h @@ -3,17 +3,17 @@ * Miscellanous routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -24,45 +24,44 @@ #ifndef _ZEBRA_ISIS_MISC_H #define _ZEBRA_ISIS_MISC_H -int string2circuit_t (const char *); -const char *circuit_t2string (int); -const char *circuit_state2string (int state); -const char *circuit_type2string (int type); -const char *syst2string (int); -struct in_addr newprefix2inaddr (u_char * prefix_start, - u_char prefix_masklen); +int string2circuit_t(const char *); +const char *circuit_t2string(int); +const char *circuit_state2string(int state); +const char *circuit_type2string(int type); +const char *syst2string(int); +struct in_addr newprefix2inaddr(u_char *prefix_start, u_char prefix_masklen); /* * Converting input to memory stored format * return value of 0 indicates wrong input */ -int dotformat2buff (u_char *, const char *); -int sysid2buff (u_char *, const char *); +int dotformat2buff(u_char *, const char *); +int sysid2buff(u_char *, const char *); /* * Printing functions */ -const char *isonet_print (const u_char *, int len); -const char *sysid_print (const u_char *); -const char *snpa_print (const u_char *); -const char *rawlspid_print (const u_char *); -const char *time2string (u_int32_t); +const char *isonet_print(const u_char *, int len); +const char *sysid_print(const u_char *); +const char *snpa_print(const u_char *); +const char *rawlspid_print(const u_char *); +const char *time2string(u_int32_t); /* typedef struct nlpids nlpids; */ -char *nlpid2string (struct nlpids *); -const char *print_sys_hostname (const u_char *sysid); -void zlog_dump_data (void *data, int len); +char *nlpid2string(struct nlpids *); +const char *print_sys_hostname(const u_char *sysid); +void zlog_dump_data(void *data, int len); /* * misc functions */ -int speaks (struct nlpids *nlpids, int family); -unsigned long isis_jitter (unsigned long timer, unsigned long jitter); -const char *unix_hostname (void); +int speaks(struct nlpids *nlpids, int family); +unsigned long isis_jitter(unsigned long timer, unsigned long jitter); +const char *unix_hostname(void); /* * macros */ -#define GETSYSID(A) (A->area_addr + (A->addr_len - \ - (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN))) +#define GETSYSID(A) \ + (A->area_addr + (A->addr_len - (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN))) /* used for calculating nice string representation instead of plain seconds */ @@ -73,11 +72,9 @@ const char *unix_hostname (void); #define SECS_PER_MONTH 2628000 #define SECS_PER_YEAR 31536000 -enum -{ - ISIS_UI_LEVEL_BRIEF, - ISIS_UI_LEVEL_DETAIL, - ISIS_UI_LEVEL_EXTENSIVE, +enum { ISIS_UI_LEVEL_BRIEF, + ISIS_UI_LEVEL_DETAIL, + ISIS_UI_LEVEL_EXTENSIVE, }; #endif diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 26e02498b..46b57510a 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -33,59 +33,60 @@ DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting") DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting") DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info") DEFINE_MTYPE_STATIC(ISISD, MT_NEIGHBORS, "ISIS MT Neighbors for TLV") -DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS, "ISIS MT IPv4 Reachabilities for TLV") -DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS, "ISIS MT IPv6 Reachabilities for TLV") +DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS, + "ISIS MT IPv4 Reachabilities for TLV") +DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS, + "ISIS MT IPv6 Reachabilities for TLV") uint16_t isis_area_ipv6_topology(struct isis_area *area) { - struct isis_area_mt_setting *area_mt_setting; - area_mt_setting = area_lookup_mt_setting(area, ISIS_MT_IPV6_UNICAST); + struct isis_area_mt_setting *area_mt_setting; + area_mt_setting = area_lookup_mt_setting(area, ISIS_MT_IPV6_UNICAST); - if (area_mt_setting && area_mt_setting->enabled) - return ISIS_MT_IPV6_UNICAST; - return ISIS_MT_IPV4_UNICAST; + if (area_mt_setting && area_mt_setting->enabled) + return ISIS_MT_IPV6_UNICAST; + return ISIS_MT_IPV4_UNICAST; } /* MT naming api */ const char *isis_mtid2str(uint16_t mtid) { - static char buf[sizeof("65535")]; - - switch(mtid) - { - case ISIS_MT_IPV4_UNICAST: - return "ipv4-unicast"; - case ISIS_MT_IPV4_MGMT: - return "ipv4-mgmt"; - case ISIS_MT_IPV6_UNICAST: - return "ipv6-unicast"; - case ISIS_MT_IPV4_MULTICAST: - return "ipv4-multicast"; - case ISIS_MT_IPV6_MULTICAST: - return "ipv6-multicast"; - case ISIS_MT_IPV6_MGMT: - return "ipv6-mgmt"; - default: - snprintf(buf, sizeof(buf), "%" PRIu16, mtid); - return buf; - } + static char buf[sizeof("65535")]; + + switch (mtid) { + case ISIS_MT_IPV4_UNICAST: + return "ipv4-unicast"; + case ISIS_MT_IPV4_MGMT: + return "ipv4-mgmt"; + case ISIS_MT_IPV6_UNICAST: + return "ipv6-unicast"; + case ISIS_MT_IPV4_MULTICAST: + return "ipv4-multicast"; + case ISIS_MT_IPV6_MULTICAST: + return "ipv6-multicast"; + case ISIS_MT_IPV6_MGMT: + return "ipv6-mgmt"; + default: + snprintf(buf, sizeof(buf), "%" PRIu16, mtid); + return buf; + } } uint16_t isis_str2mtid(const char *name) { - if (!strcmp(name,"ipv4-unicast")) - return ISIS_MT_IPV4_UNICAST; - if (!strcmp(name,"ipv4-mgmt")) - return ISIS_MT_IPV4_MGMT; - if (!strcmp(name,"ipv6-unicast")) - return ISIS_MT_IPV6_UNICAST; - if (!strcmp(name,"ipv4-multicast")) - return ISIS_MT_IPV4_MULTICAST; - if (!strcmp(name,"ipv6-multicast")) - return ISIS_MT_IPV6_MULTICAST; - if (!strcmp(name,"ipv6-mgmt")) - return ISIS_MT_IPV6_MGMT; - return -1; + if (!strcmp(name, "ipv4-unicast")) + return ISIS_MT_IPV4_UNICAST; + if (!strcmp(name, "ipv4-mgmt")) + return ISIS_MT_IPV4_MGMT; + if (!strcmp(name, "ipv6-unicast")) + return ISIS_MT_IPV6_UNICAST; + if (!strcmp(name, "ipv4-multicast")) + return ISIS_MT_IPV4_MULTICAST; + if (!strcmp(name, "ipv6-multicast")) + return ISIS_MT_IPV6_MULTICAST; + if (!strcmp(name, "ipv6-mgmt")) + return ISIS_MT_IPV6_MGMT; + return -1; } /* General MT settings api */ @@ -94,649 +95,603 @@ struct mt_setting { ISIS_MT_INFO_FIELDS; }; -static void * -lookup_mt_setting(struct list *mt_list, uint16_t mtid) +static void *lookup_mt_setting(struct list *mt_list, uint16_t mtid) { - struct listnode *node; - struct mt_setting *setting; + struct listnode *node; + struct mt_setting *setting; - for (ALL_LIST_ELEMENTS_RO(mt_list, node, setting)) - { - if (setting->mtid == mtid) - return setting; - } - return NULL; + for (ALL_LIST_ELEMENTS_RO(mt_list, node, setting)) { + if (setting->mtid == mtid) + return setting; + } + return NULL; } -static void -add_mt_setting(struct list **mt_list, void *setting) +static void add_mt_setting(struct list **mt_list, void *setting) { - if (!*mt_list) - *mt_list = list_new(); - listnode_add(*mt_list, setting); + if (!*mt_list) + *mt_list = list_new(); + listnode_add(*mt_list, setting); } /* Area specific MT settings api */ -struct isis_area_mt_setting* -area_lookup_mt_setting(struct isis_area *area, uint16_t mtid) +struct isis_area_mt_setting *area_lookup_mt_setting(struct isis_area *area, + uint16_t mtid) { - return lookup_mt_setting(area->mt_settings, mtid); + return lookup_mt_setting(area->mt_settings, mtid); } -struct isis_area_mt_setting* -area_new_mt_setting(struct isis_area *area, uint16_t mtid) +struct isis_area_mt_setting *area_new_mt_setting(struct isis_area *area, + uint16_t mtid) { - struct isis_area_mt_setting *setting; + struct isis_area_mt_setting *setting; - setting = XCALLOC(MTYPE_MT_AREA_SETTING, sizeof(*setting)); - setting->mtid = mtid; - return setting; + setting = XCALLOC(MTYPE_MT_AREA_SETTING, sizeof(*setting)); + setting->mtid = mtid; + return setting; } -static void -area_free_mt_setting(void *setting) +static void area_free_mt_setting(void *setting) { - XFREE(MTYPE_MT_AREA_SETTING, setting); + XFREE(MTYPE_MT_AREA_SETTING, setting); } -void -area_add_mt_setting(struct isis_area *area, struct isis_area_mt_setting *setting) +void area_add_mt_setting(struct isis_area *area, + struct isis_area_mt_setting *setting) { - add_mt_setting(&area->mt_settings, setting); + add_mt_setting(&area->mt_settings, setting); } -void -area_mt_init(struct isis_area *area) +void area_mt_init(struct isis_area *area) { - struct isis_area_mt_setting *v4_unicast_setting; + struct isis_area_mt_setting *v4_unicast_setting; - /* MTID 0 is always enabled */ - v4_unicast_setting = area_new_mt_setting(area, ISIS_MT_IPV4_UNICAST); - v4_unicast_setting->enabled = true; - add_mt_setting(&area->mt_settings, v4_unicast_setting); - area->mt_settings->del = area_free_mt_setting; + /* MTID 0 is always enabled */ + v4_unicast_setting = area_new_mt_setting(area, ISIS_MT_IPV4_UNICAST); + v4_unicast_setting->enabled = true; + add_mt_setting(&area->mt_settings, v4_unicast_setting); + area->mt_settings->del = area_free_mt_setting; } -void -area_mt_finish(struct isis_area *area) +void area_mt_finish(struct isis_area *area) { - list_delete(area->mt_settings); - area->mt_settings = NULL; + list_delete(area->mt_settings); + area->mt_settings = NULL; } -struct isis_area_mt_setting * -area_get_mt_setting(struct isis_area *area, uint16_t mtid) +struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area, + uint16_t mtid) { - struct isis_area_mt_setting *setting; + struct isis_area_mt_setting *setting; - setting = area_lookup_mt_setting(area, mtid); - if (!setting) - { - setting = area_new_mt_setting(area, mtid); - area_add_mt_setting(area, setting); - } - return setting; + setting = area_lookup_mt_setting(area, mtid); + if (!setting) { + setting = area_new_mt_setting(area, mtid); + area_add_mt_setting(area, setting); + } + return setting; } -int -area_write_mt_settings(struct isis_area *area, struct vty *vty) +int area_write_mt_settings(struct isis_area *area, struct vty *vty) { - int written = 0; - struct listnode *node; - struct isis_area_mt_setting *setting; + int written = 0; + struct listnode *node; + struct isis_area_mt_setting *setting; - for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) - { - const char *name = isis_mtid2str(setting->mtid); - if (name && setting->enabled) - { - if (setting->mtid == ISIS_MT_IPV4_UNICAST) - continue; /* always enabled, no need to write out config */ - vty_out (vty, " topology %s%s\n", name, - setting->overload ? " overload" : ""); - written++; - } - } - return written; + for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) { + const char *name = isis_mtid2str(setting->mtid); + if (name && setting->enabled) { + if (setting->mtid == ISIS_MT_IPV4_UNICAST) + continue; /* always enabled, no need to write + out config */ + vty_out(vty, " topology %s%s\n", name, + setting->overload ? " overload" : ""); + written++; + } + } + return written; } bool area_is_mt(struct isis_area *area) { - struct listnode *node, *node2; - struct isis_area_mt_setting *setting; - struct isis_circuit *circuit; - struct isis_circuit_mt_setting *csetting; + struct listnode *node, *node2; + struct isis_area_mt_setting *setting; + struct isis_circuit *circuit; + struct isis_circuit_mt_setting *csetting; - for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) - { - if (setting->enabled && setting->mtid != ISIS_MT_IPV4_UNICAST) - return true; - } - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) - { - for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node2, csetting)) - { - if (!csetting->enabled && csetting->mtid == ISIS_MT_IPV4_UNICAST) - return true; - } - } + for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) { + if (setting->enabled && setting->mtid != ISIS_MT_IPV4_UNICAST) + return true; + } + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node2, + csetting)) { + if (!csetting->enabled + && csetting->mtid == ISIS_MT_IPV4_UNICAST) + return true; + } + } - return false; + return false; } -struct isis_area_mt_setting** -area_mt_settings(struct isis_area *area, unsigned int *mt_count) +struct isis_area_mt_setting **area_mt_settings(struct isis_area *area, + unsigned int *mt_count) { - static unsigned int size = 0; - static struct isis_area_mt_setting **rv = NULL; + static unsigned int size = 0; + static struct isis_area_mt_setting **rv = NULL; - unsigned int count = 0; - struct listnode *node; - struct isis_area_mt_setting *setting; + unsigned int count = 0; + struct listnode *node; + struct isis_area_mt_setting *setting; - for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) - { - if (!setting->enabled) - continue; + for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting)) { + if (!setting->enabled) + continue; - count++; - if (count > size) - { - rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv)); - size = count; - } - rv[count-1] = setting; - } + count++; + if (count > size) { + rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv)); + size = count; + } + rv[count - 1] = setting; + } - *mt_count = count; - return rv; + *mt_count = count; + return rv; } /* Circuit specific MT settings api */ -struct isis_circuit_mt_setting* +struct isis_circuit_mt_setting * circuit_lookup_mt_setting(struct isis_circuit *circuit, uint16_t mtid) { - return lookup_mt_setting(circuit->mt_settings, mtid); + return lookup_mt_setting(circuit->mt_settings, mtid); } -struct isis_circuit_mt_setting* +struct isis_circuit_mt_setting * circuit_new_mt_setting(struct isis_circuit *circuit, uint16_t mtid) { - struct isis_circuit_mt_setting *setting; + struct isis_circuit_mt_setting *setting; - setting = XCALLOC(MTYPE_MT_CIRCUIT_SETTING, sizeof(*setting)); - setting->mtid = mtid; - setting->enabled = true; /* Enabled is default for circuit */ - return setting; + setting = XCALLOC(MTYPE_MT_CIRCUIT_SETTING, sizeof(*setting)); + setting->mtid = mtid; + setting->enabled = true; /* Enabled is default for circuit */ + return setting; } -static void -circuit_free_mt_setting(void *setting) +static void circuit_free_mt_setting(void *setting) { - XFREE(MTYPE_MT_CIRCUIT_SETTING, setting); + XFREE(MTYPE_MT_CIRCUIT_SETTING, setting); } -void -circuit_add_mt_setting(struct isis_circuit *circuit, - struct isis_circuit_mt_setting *setting) +void circuit_add_mt_setting(struct isis_circuit *circuit, + struct isis_circuit_mt_setting *setting) { - add_mt_setting(&circuit->mt_settings, setting); + add_mt_setting(&circuit->mt_settings, setting); } -void -circuit_mt_init(struct isis_circuit *circuit) +void circuit_mt_init(struct isis_circuit *circuit) { - circuit->mt_settings = list_new(); - circuit->mt_settings->del = circuit_free_mt_setting; + circuit->mt_settings = list_new(); + circuit->mt_settings->del = circuit_free_mt_setting; } -void -circuit_mt_finish(struct isis_circuit *circuit) +void circuit_mt_finish(struct isis_circuit *circuit) { - list_delete(circuit->mt_settings); - circuit->mt_settings = NULL; + list_delete(circuit->mt_settings); + circuit->mt_settings = NULL; } -struct isis_circuit_mt_setting* +struct isis_circuit_mt_setting * circuit_get_mt_setting(struct isis_circuit *circuit, uint16_t mtid) { - struct isis_circuit_mt_setting *setting; + struct isis_circuit_mt_setting *setting; - setting = circuit_lookup_mt_setting(circuit, mtid); - if (!setting) - { - setting = circuit_new_mt_setting(circuit, mtid); - circuit_add_mt_setting(circuit, setting); - } - return setting; + setting = circuit_lookup_mt_setting(circuit, mtid); + if (!setting) { + setting = circuit_new_mt_setting(circuit, mtid); + circuit_add_mt_setting(circuit, setting); + } + return setting; } -int -circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty) +int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty) { - int written = 0; - struct listnode *node; - struct isis_circuit_mt_setting *setting; + int written = 0; + struct listnode *node; + struct isis_circuit_mt_setting *setting; - for (ALL_LIST_ELEMENTS_RO (circuit->mt_settings, node, setting)) - { - const char *name = isis_mtid2str(setting->mtid); - if (name && !setting->enabled) - { - vty_out (vty, " no isis topology %s\n", name); - written++; - } - } - return written; + for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) { + const char *name = isis_mtid2str(setting->mtid); + if (name && !setting->enabled) { + vty_out(vty, " no isis topology %s\n", name); + written++; + } + } + return written; } -struct isis_circuit_mt_setting** +struct isis_circuit_mt_setting ** circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count) { - static unsigned int size = 0; - static struct isis_circuit_mt_setting **rv = NULL; + static unsigned int size = 0; + static struct isis_circuit_mt_setting **rv = NULL; - struct isis_area_mt_setting **area_settings; - unsigned int area_count; + struct isis_area_mt_setting **area_settings; + unsigned int area_count; - unsigned int count = 0; + unsigned int count = 0; - struct listnode *node; - struct isis_circuit_mt_setting *setting; + struct listnode *node; + struct isis_circuit_mt_setting *setting; - area_settings = area_mt_settings(circuit->area, &area_count); + area_settings = area_mt_settings(circuit->area, &area_count); - for (unsigned int i = 0; i < area_count; i++) - { - for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) - { - if (setting->mtid != area_settings[i]->mtid) - continue; - break; - } - if (!setting) - setting = circuit_get_mt_setting(circuit, area_settings[i]->mtid); + for (unsigned int i = 0; i < area_count; i++) { + for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, + setting)) { + if (setting->mtid != area_settings[i]->mtid) + continue; + break; + } + if (!setting) + setting = circuit_get_mt_setting( + circuit, area_settings[i]->mtid); - if (!setting->enabled) - continue; + if (!setting->enabled) + continue; - count++; - if (count > size) - { - rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv)); - size = count; - } - rv[count-1] = setting; - } + count++; + if (count > size) { + rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv)); + size = count; + } + rv[count - 1] = setting; + } - *mt_count = count; - return rv; + *mt_count = count; + return rv; } /* ADJ specific MT API */ static void adj_mt_set(struct isis_adjacency *adj, unsigned int index, - uint16_t mtid) -{ - if (adj->mt_count < index + 1) - { - adj->mt_set = XREALLOC(MTYPE_MT_ADJ_INFO, adj->mt_set, - (index + 1) * sizeof(*adj->mt_set)); - adj->mt_count = index + 1; - } - adj->mt_set[index] = mtid; -} - -bool -tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable, - struct isis_adjacency *adj) -{ - struct isis_circuit_mt_setting **mt_settings; - unsigned int circuit_mt_count; - - unsigned int intersect_count = 0; - - uint16_t *old_mt_set = NULL; - unsigned int old_mt_count; - - old_mt_count = adj->mt_count; - if (old_mt_count) - { - old_mt_set = XCALLOC(MTYPE_TMP, old_mt_count * sizeof(*old_mt_set)); - memcpy(old_mt_set, adj->mt_set, old_mt_count * sizeof(*old_mt_set)); - } - - mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count); - for (unsigned int i = 0; i < circuit_mt_count; i++) - { - if (!tlvs->mt_router_info) - { - /* Other end does not have MT enabled */ - if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST && v4_usable) - adj_mt_set(adj, intersect_count++, ISIS_MT_IPV4_UNICAST); - } - else - { - struct listnode *node; - struct mt_router_info *info; - for (ALL_LIST_ELEMENTS_RO(tlvs->mt_router_info, node, info)) - { - if (mt_settings[i]->mtid == info->mtid) - { - bool usable; - switch (info->mtid) - { - case ISIS_MT_IPV4_UNICAST: - case ISIS_MT_IPV4_MGMT: - case ISIS_MT_IPV4_MULTICAST: - usable = v4_usable; - break; - case ISIS_MT_IPV6_UNICAST: - case ISIS_MT_IPV6_MGMT: - case ISIS_MT_IPV6_MULTICAST: - usable = v6_usable; - break; - default: - usable = true; - break; - } - if (usable) - adj_mt_set(adj, intersect_count++, info->mtid); - } - } - } - } - adj->mt_count = intersect_count; - - bool changed = false; - - if (adj->mt_count != old_mt_count) - changed = true; - - if (!changed && old_mt_count - && memcmp(adj->mt_set, old_mt_set, - old_mt_count * sizeof(*old_mt_set))) - changed = true; - - if (old_mt_count) - XFREE(MTYPE_TMP, old_mt_set); - - return changed; -} - -bool -adj_has_mt(struct isis_adjacency *adj, uint16_t mtid) -{ - for (unsigned int i = 0; i < adj->mt_count; i++) - if (adj->mt_set[i] == mtid) - return true; - return false; -} - -void -adj_mt_finish(struct isis_adjacency *adj) -{ - XFREE(MTYPE_MT_ADJ_INFO, adj->mt_set); - adj->mt_count = 0; + uint16_t mtid) +{ + if (adj->mt_count < index + 1) { + adj->mt_set = XREALLOC(MTYPE_MT_ADJ_INFO, adj->mt_set, + (index + 1) * sizeof(*adj->mt_set)); + adj->mt_count = index + 1; + } + adj->mt_set[index] = mtid; +} + +bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable, + struct isis_adjacency *adj) +{ + struct isis_circuit_mt_setting **mt_settings; + unsigned int circuit_mt_count; + + unsigned int intersect_count = 0; + + uint16_t *old_mt_set = NULL; + unsigned int old_mt_count; + + old_mt_count = adj->mt_count; + if (old_mt_count) { + old_mt_set = + XCALLOC(MTYPE_TMP, old_mt_count * sizeof(*old_mt_set)); + memcpy(old_mt_set, adj->mt_set, + old_mt_count * sizeof(*old_mt_set)); + } + + mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count); + for (unsigned int i = 0; i < circuit_mt_count; i++) { + if (!tlvs->mt_router_info) { + /* Other end does not have MT enabled */ + if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST + && v4_usable) + adj_mt_set(adj, intersect_count++, + ISIS_MT_IPV4_UNICAST); + } else { + struct listnode *node; + struct mt_router_info *info; + for (ALL_LIST_ELEMENTS_RO(tlvs->mt_router_info, node, + info)) { + if (mt_settings[i]->mtid == info->mtid) { + bool usable; + switch (info->mtid) { + case ISIS_MT_IPV4_UNICAST: + case ISIS_MT_IPV4_MGMT: + case ISIS_MT_IPV4_MULTICAST: + usable = v4_usable; + break; + case ISIS_MT_IPV6_UNICAST: + case ISIS_MT_IPV6_MGMT: + case ISIS_MT_IPV6_MULTICAST: + usable = v6_usable; + break; + default: + usable = true; + break; + } + if (usable) + adj_mt_set(adj, + intersect_count++, + info->mtid); + } + } + } + } + adj->mt_count = intersect_count; + + bool changed = false; + + if (adj->mt_count != old_mt_count) + changed = true; + + if (!changed && old_mt_count + && memcmp(adj->mt_set, old_mt_set, + old_mt_count * sizeof(*old_mt_set))) + changed = true; + + if (old_mt_count) + XFREE(MTYPE_TMP, old_mt_set); + + return changed; +} + +bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid) +{ + for (unsigned int i = 0; i < adj->mt_count; i++) + if (adj->mt_set[i] == mtid) + return true; + return false; +} + +void adj_mt_finish(struct isis_adjacency *adj) +{ + XFREE(MTYPE_MT_ADJ_INFO, adj->mt_set); + adj->mt_count = 0; } /* TLV Router info api */ -struct mt_router_info* -tlvs_lookup_mt_router_info(struct tlvs *tlvs, uint16_t mtid) +struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs, + uint16_t mtid) { - return lookup_mt_setting(tlvs->mt_router_info, mtid); + return lookup_mt_setting(tlvs->mt_router_info, mtid); } /* TLV MT Neighbors api */ -struct tlv_mt_neighbors* -tlvs_lookup_mt_neighbors(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs, + uint16_t mtid) { - return lookup_mt_setting(tlvs->mt_is_neighs, mtid); + return lookup_mt_setting(tlvs->mt_is_neighs, mtid); } -static struct tlv_mt_neighbors* -tlvs_new_mt_neighbors(uint16_t mtid) +static struct tlv_mt_neighbors *tlvs_new_mt_neighbors(uint16_t mtid) { - struct tlv_mt_neighbors *rv; + struct tlv_mt_neighbors *rv; - rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv)); - rv->mtid = mtid; - rv->list = list_new(); + rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv)); + rv->mtid = mtid; + rv->list = list_new(); - return rv; + return rv; }; -static void -tlvs_free_mt_neighbors(void *arg) +static void tlvs_free_mt_neighbors(void *arg) { - struct tlv_mt_neighbors *neighbors = arg; + struct tlv_mt_neighbors *neighbors = arg; - if (neighbors && neighbors->list) - list_delete(neighbors->list); - XFREE(MTYPE_MT_NEIGHBORS, neighbors); + if (neighbors && neighbors->list) + list_delete(neighbors->list); + XFREE(MTYPE_MT_NEIGHBORS, neighbors); } -static void -tlvs_add_mt_neighbors(struct tlvs *tlvs, struct tlv_mt_neighbors *neighbors) +static void tlvs_add_mt_neighbors(struct tlvs *tlvs, + struct tlv_mt_neighbors *neighbors) { - add_mt_setting(&tlvs->mt_is_neighs, neighbors); - tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors; + add_mt_setting(&tlvs->mt_is_neighs, neighbors); + tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors; } -struct tlv_mt_neighbors* -tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid) { - struct tlv_mt_neighbors *neighbors; + struct tlv_mt_neighbors *neighbors; - neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid); - if (!neighbors) - { - neighbors = tlvs_new_mt_neighbors(mtid); - tlvs_add_mt_neighbors(tlvs, neighbors); - } - return neighbors; + neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid); + if (!neighbors) { + neighbors = tlvs_new_mt_neighbors(mtid); + tlvs_add_mt_neighbors(tlvs, neighbors); + } + return neighbors; } /* TLV MT IPv4 reach api */ -struct tlv_mt_ipv4_reachs* -tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, + uint16_t mtid) { - return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid); + return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid); } -static struct tlv_mt_ipv4_reachs* -tlvs_new_mt_ipv4_reachs(uint16_t mtid) +static struct tlv_mt_ipv4_reachs *tlvs_new_mt_ipv4_reachs(uint16_t mtid) { - struct tlv_mt_ipv4_reachs *rv; + struct tlv_mt_ipv4_reachs *rv; - rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv)); - rv->mtid = mtid; - rv->list = list_new(); + rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv)); + rv->mtid = mtid; + rv->list = list_new(); - return rv; + return rv; }; -static void -tlvs_free_mt_ipv4_reachs(void *arg) +static void tlvs_free_mt_ipv4_reachs(void *arg) { - struct tlv_mt_ipv4_reachs *reachs = arg; + struct tlv_mt_ipv4_reachs *reachs = arg; - if (reachs && reachs->list) - list_delete(reachs->list); - XFREE(MTYPE_MT_IPV4_REACHS, reachs); + if (reachs && reachs->list) + list_delete(reachs->list); + XFREE(MTYPE_MT_IPV4_REACHS, reachs); } -static void -tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs, struct tlv_mt_ipv4_reachs *reachs) +static void tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs, + struct tlv_mt_ipv4_reachs *reachs) { - add_mt_setting(&tlvs->mt_ipv4_reachs, reachs); - tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs; + add_mt_setting(&tlvs->mt_ipv4_reachs, reachs); + tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs; } -struct tlv_mt_ipv4_reachs* -tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, + uint16_t mtid) { - struct tlv_mt_ipv4_reachs *reachs; + struct tlv_mt_ipv4_reachs *reachs; - reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid); - if (!reachs) - { - reachs = tlvs_new_mt_ipv4_reachs(mtid); - tlvs_add_mt_ipv4_reachs(tlvs, reachs); - } - return reachs; + reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid); + if (!reachs) { + reachs = tlvs_new_mt_ipv4_reachs(mtid); + tlvs_add_mt_ipv4_reachs(tlvs, reachs); + } + return reachs; } /* TLV MT IPv6 reach api */ -struct tlv_mt_ipv6_reachs* -tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, + uint16_t mtid) { - return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid); + return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid); } -static struct tlv_mt_ipv6_reachs* -tlvs_new_mt_ipv6_reachs(uint16_t mtid) +static struct tlv_mt_ipv6_reachs *tlvs_new_mt_ipv6_reachs(uint16_t mtid) { - struct tlv_mt_ipv6_reachs *rv; + struct tlv_mt_ipv6_reachs *rv; - rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv)); - rv->mtid = mtid; - rv->list = list_new(); + rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv)); + rv->mtid = mtid; + rv->list = list_new(); - return rv; + return rv; }; -static void -tlvs_free_mt_ipv6_reachs(void *arg) +static void tlvs_free_mt_ipv6_reachs(void *arg) { - struct tlv_mt_ipv6_reachs *reachs = arg; + struct tlv_mt_ipv6_reachs *reachs = arg; - if (reachs && reachs->list) - list_delete(reachs->list); - XFREE(MTYPE_MT_IPV6_REACHS, reachs); + if (reachs && reachs->list) + list_delete(reachs->list); + XFREE(MTYPE_MT_IPV6_REACHS, reachs); } -static void -tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs, struct tlv_mt_ipv6_reachs *reachs) +static void tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs, + struct tlv_mt_ipv6_reachs *reachs) { - add_mt_setting(&tlvs->mt_ipv6_reachs, reachs); - tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs; + add_mt_setting(&tlvs->mt_ipv6_reachs, reachs); + tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs; } -struct tlv_mt_ipv6_reachs* -tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid) +struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, + uint16_t mtid) { - struct tlv_mt_ipv6_reachs *reachs; + struct tlv_mt_ipv6_reachs *reachs; - reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid); - if (!reachs) - { - reachs = tlvs_new_mt_ipv6_reachs(mtid); - tlvs_add_mt_ipv6_reachs(tlvs, reachs); - } - return reachs; + reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid); + if (!reachs) { + reachs = tlvs_new_mt_ipv6_reachs(mtid); + tlvs_add_mt_ipv6_reachs(tlvs, reachs); + } + return reachs; } -static void -mt_set_add(uint16_t **mt_set, unsigned int *size, - unsigned int *index, uint16_t mtid) +static void mt_set_add(uint16_t **mt_set, unsigned int *size, + unsigned int *index, uint16_t mtid) { - for (unsigned int i = 0; i < *index; i++) - { - if ((*mt_set)[i] == mtid) - return; - } + for (unsigned int i = 0; i < *index; i++) { + if ((*mt_set)[i] == mtid) + return; + } - if (*index >= *size) - { - *mt_set = XREALLOC(MTYPE_TMP, *mt_set, sizeof(**mt_set) * ((*index) + 1)); - *size = (*index) + 1; - } + if (*index >= *size) { + *mt_set = XREALLOC(MTYPE_TMP, *mt_set, + sizeof(**mt_set) * ((*index) + 1)); + *size = (*index) + 1; + } - (*mt_set)[*index] = mtid; - *index = (*index) + 1; + (*mt_set)[*index] = mtid; + *index = (*index) + 1; } -static uint16_t * -circuit_bcast_mt_set(struct isis_circuit *circuit, int level, - unsigned int *mt_count) +static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level, + unsigned int *mt_count) { - static uint16_t *rv; - static unsigned int size; - struct listnode *node; - struct isis_adjacency *adj; + static uint16_t *rv; + static unsigned int size; + struct listnode *node; + struct isis_adjacency *adj; - unsigned int count = 0; + unsigned int count = 0; - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - { - *mt_count = 0; - return NULL; - } + if (circuit->circ_type != CIRCUIT_T_BROADCAST) { + *mt_count = 0; + return NULL; + } - for (ALL_LIST_ELEMENTS_RO(circuit->u.bc.adjdb[level - 1], node, adj)) - { - if (adj->adj_state != ISIS_ADJ_UP) - continue; - for (unsigned int i = 0; i < adj->mt_count; i++) - mt_set_add(&rv, &size, &count, adj->mt_set[i]); - } + for (ALL_LIST_ELEMENTS_RO(circuit->u.bc.adjdb[level - 1], node, adj)) { + if (adj->adj_state != ISIS_ADJ_UP) + continue; + for (unsigned int i = 0; i < adj->mt_count; i++) + mt_set_add(&rv, &size, &count, adj->mt_set[i]); + } - *mt_count = count; - return rv; + *mt_count = count; + return rv; } -static void -tlvs_add_mt_set(struct isis_area *area, - struct tlvs *tlvs, unsigned int mt_count, - uint16_t *mt_set, struct te_is_neigh *neigh) +static void tlvs_add_mt_set(struct isis_area *area, struct tlvs *tlvs, + unsigned int mt_count, uint16_t *mt_set, + struct te_is_neigh *neigh) { - for (unsigned int i = 0; i < mt_count; i++) - { - uint16_t mtid = mt_set[i]; - struct te_is_neigh *ne_copy; + for (unsigned int i = 0; i < mt_count; i++) { + uint16_t mtid = mt_set[i]; + struct te_is_neigh *ne_copy; - ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy)); - memcpy(ne_copy, neigh, sizeof(*ne_copy)); + ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy)); + memcpy(ne_copy, neigh, sizeof(*ne_copy)); - if (mt_set[i] == ISIS_MT_IPV4_UNICAST) - { - listnode_add(tlvs->te_is_neighs, ne_copy); - lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor", - area->area_tag, sysid_print(ne_copy->neigh_id), - LSP_PSEUDO_ID(ne_copy->neigh_id)); - } - else - { - struct tlv_mt_neighbors *neighbors; + if (mt_set[i] == ISIS_MT_IPV4_UNICAST) { + listnode_add(tlvs->te_is_neighs, ne_copy); + lsp_debug( + "ISIS (%s): Adding %s.%02x as te-style neighbor", + area->area_tag, sysid_print(ne_copy->neigh_id), + LSP_PSEUDO_ID(ne_copy->neigh_id)); + } else { + struct tlv_mt_neighbors *neighbors; - neighbors = tlvs_get_mt_neighbors(tlvs, mtid); - neighbors->list->del = free_tlv; - listnode_add(neighbors->list, ne_copy); - lsp_debug("ISIS (%s): Adding %s.%02x as mt-style neighbor for %s", - area->area_tag, sysid_print(ne_copy->neigh_id), - LSP_PSEUDO_ID(ne_copy->neigh_id), isis_mtid2str(mtid)); - } - } + neighbors = tlvs_get_mt_neighbors(tlvs, mtid); + neighbors->list->del = free_tlv; + listnode_add(neighbors->list, ne_copy); + lsp_debug( + "ISIS (%s): Adding %s.%02x as mt-style neighbor for %s", + area->area_tag, sysid_print(ne_copy->neigh_id), + LSP_PSEUDO_ID(ne_copy->neigh_id), + isis_mtid2str(mtid)); + } + } } -void -tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit, - int level, struct te_is_neigh *neigh) +void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit, + int level, struct te_is_neigh *neigh) { - unsigned int mt_count; - uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, - &mt_count); + unsigned int mt_count; + uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &mt_count); - tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh); -} - -void -tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit, - struct te_is_neigh *neigh) + tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh); +} + +void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit, + struct te_is_neigh *neigh) { - struct isis_adjacency *adj = circuit->u.p2p.neighbor; + struct isis_adjacency *adj = circuit->u.p2p.neighbor; - tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh); + tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh); } diff --git a/isisd/isis_mt.h b/isisd/isis_mt.h index e90f1756f..eec089228 100644 --- a/isisd/isis_mt.h +++ b/isisd/isis_mt.h @@ -32,52 +32,51 @@ #define ISIS_MT_IPV6_MULTICAST 4 #define ISIS_MT_IPV6_MGMT 5 -#define ISIS_MT_NAMES \ - "<ipv4-unicast" \ - "|ipv4-mgmt" \ - "|ipv6-unicast" \ - "|ipv4-multicast" \ - "|ipv6-multicast" \ - "|ipv6-mgmt" \ - ">" - -#define ISIS_MT_DESCRIPTIONS \ - "IPv4 unicast topology\n" \ - "IPv4 management topology\n" \ - "IPv6 unicast topology\n" \ - "IPv4 multicast topology\n" \ - "IPv6 multicast topology\n" \ - "IPv6 management topology\n" - -#define ISIS_MT_INFO_FIELDS \ - uint16_t mtid; +#define ISIS_MT_NAMES \ + "<ipv4-unicast" \ + "|ipv4-mgmt" \ + "|ipv6-unicast" \ + "|ipv4-multicast" \ + "|ipv6-multicast" \ + "|ipv6-mgmt" \ + ">" + +#define ISIS_MT_DESCRIPTIONS \ + "IPv4 unicast topology\n" \ + "IPv4 management topology\n" \ + "IPv6 unicast topology\n" \ + "IPv4 multicast topology\n" \ + "IPv6 multicast topology\n" \ + "IPv6 management topology\n" + +#define ISIS_MT_INFO_FIELDS uint16_t mtid; struct list; struct isis_area_mt_setting { - ISIS_MT_INFO_FIELDS - bool enabled; - bool overload; + ISIS_MT_INFO_FIELDS + bool enabled; + bool overload; }; struct isis_circuit_mt_setting { - ISIS_MT_INFO_FIELDS - bool enabled; + ISIS_MT_INFO_FIELDS + bool enabled; }; struct tlv_mt_neighbors { - ISIS_MT_INFO_FIELDS - struct list *list; + ISIS_MT_INFO_FIELDS + struct list *list; }; struct tlv_mt_ipv4_reachs { - ISIS_MT_INFO_FIELDS - struct list *list; + ISIS_MT_INFO_FIELDS + struct list *list; }; struct tlv_mt_ipv6_reachs { - ISIS_MT_INFO_FIELDS - struct list *list; + ISIS_MT_INFO_FIELDS + struct list *list; }; const char *isis_mtid2str(uint16_t mtid); @@ -91,55 +90,59 @@ struct te_is_neigh; uint16_t isis_area_ipv6_topology(struct isis_area *area); -struct mt_router_info* tlvs_lookup_mt_router_info(struct tlvs *tlvs, uint16_t mtid); +struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs, + uint16_t mtid); -struct tlv_mt_neighbors* tlvs_lookup_mt_neighbors(struct tlvs *tlvs, uint16_t mtid); -struct tlv_mt_neighbors* tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid); +struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs, + uint16_t mtid); +struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs, + uint16_t mtid); -struct tlv_mt_ipv4_reachs* tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid); -struct tlv_mt_ipv4_reachs* tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid); +struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, + uint16_t mtid); +struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, + uint16_t mtid); -struct tlv_mt_ipv6_reachs* tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid); -struct tlv_mt_ipv6_reachs* tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid); +struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, + uint16_t mtid); +struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, + uint16_t mtid); -struct isis_area_mt_setting* area_lookup_mt_setting(struct isis_area *area, - uint16_t mtid); -struct isis_area_mt_setting* area_new_mt_setting(struct isis_area *area, - uint16_t mtid); +struct isis_area_mt_setting *area_lookup_mt_setting(struct isis_area *area, + uint16_t mtid); +struct isis_area_mt_setting *area_new_mt_setting(struct isis_area *area, + uint16_t mtid); void area_add_mt_setting(struct isis_area *area, - struct isis_area_mt_setting *setting); + struct isis_area_mt_setting *setting); void area_mt_init(struct isis_area *area); void area_mt_finish(struct isis_area *area); -struct isis_area_mt_setting* area_get_mt_setting(struct isis_area *area, - uint16_t mtid); +struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area, + uint16_t mtid); int area_write_mt_settings(struct isis_area *area, struct vty *vty); bool area_is_mt(struct isis_area *area); -struct isis_area_mt_setting** area_mt_settings(struct isis_area *area, - unsigned int *mt_count); - -struct isis_circuit_mt_setting* circuit_lookup_mt_setting( - struct isis_circuit *circuit, - uint16_t mtid); -struct isis_circuit_mt_setting* circuit_new_mt_setting( - struct isis_circuit *circuit, - uint16_t mtid); +struct isis_area_mt_setting **area_mt_settings(struct isis_area *area, + unsigned int *mt_count); + +struct isis_circuit_mt_setting * +circuit_lookup_mt_setting(struct isis_circuit *circuit, uint16_t mtid); +struct isis_circuit_mt_setting * +circuit_new_mt_setting(struct isis_circuit *circuit, uint16_t mtid); void circuit_add_mt_setting(struct isis_circuit *circuit, - struct isis_circuit_mt_setting *setting); + struct isis_circuit_mt_setting *setting); void circuit_mt_init(struct isis_circuit *circuit); void circuit_mt_finish(struct isis_circuit *circuit); -struct isis_circuit_mt_setting* circuit_get_mt_setting( - struct isis_circuit *circuit, - uint16_t mtid); +struct isis_circuit_mt_setting * +circuit_get_mt_setting(struct isis_circuit *circuit, uint16_t mtid); int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty); -struct isis_circuit_mt_setting** circuit_mt_settings(struct isis_circuit *circuit, - unsigned int *mt_count); +struct isis_circuit_mt_setting ** +circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count); bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable, - struct isis_adjacency *adj); + struct isis_adjacency *adj); bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid); void adj_mt_finish(struct isis_adjacency *adj); void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit, - int level, struct te_is_neigh *neigh); + int level, struct te_is_neigh *neigh); void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit, - struct te_is_neigh *neigh); + struct te_is_neigh *neigh); #endif diff --git a/isisd/isis_network.h b/isisd/isis_network.h index 41788e69f..4b2531606 100644 --- a/isisd/isis_network.h +++ b/isisd/isis_network.h @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isis_network.h + * IS-IS Rout(e)ing protocol - isis_network.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -27,11 +27,11 @@ extern u_char ALL_L1_ISYSTEMS[]; extern u_char ALL_L2_ISYSTEMS[]; -int isis_sock_init (struct isis_circuit *circuit); +int isis_sock_init(struct isis_circuit *circuit); -int isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa); -int isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa); -int isis_send_pdu_bcast (struct isis_circuit *circuit, int level); -int isis_send_pdu_p2p (struct isis_circuit *circuit, int level); +int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa); +int isis_recv_pdu_p2p(struct isis_circuit *circuit, u_char *ssnpa); +int isis_send_pdu_bcast(struct isis_circuit *circuit, int level); +int isis_send_pdu_p2p(struct isis_circuit *circuit, int level); #endif /* _ZEBRA_ISIS_NETWORK_H */ diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index d62682b10..a3706179a 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1,19 +1,19 @@ /* - * IS-IS Rout(e)ing protocol - isis_pdu.c + * IS-IS Rout(e)ing protocol - isis_pdu.c * PDU processing * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -69,253 +69,238 @@ /* * Compares two sets of area addresses */ -static int -area_match (struct list *left, struct list *right) +static int area_match(struct list *left, struct list *right) { - struct area_addr *addr1, *addr2; - struct listnode *node1, *node2; - - for (ALL_LIST_ELEMENTS_RO (left, node1, addr1)) - { - for (ALL_LIST_ELEMENTS_RO (right, node2, addr2)) - { - if (addr1->addr_len == addr2->addr_len && - !memcmp (addr1->area_addr, addr2->area_addr, (int) addr1->addr_len)) - return 1; /* match */ - } - } + struct area_addr *addr1, *addr2; + struct listnode *node1, *node2; + + for (ALL_LIST_ELEMENTS_RO(left, node1, addr1)) { + for (ALL_LIST_ELEMENTS_RO(right, node2, addr2)) { + if (addr1->addr_len == addr2->addr_len + && !memcmp(addr1->area_addr, addr2->area_addr, + (int)addr1->addr_len)) + return 1; /* match */ + } + } - return 0; /* mismatch */ + return 0; /* mismatch */ } /* - * Checks whether we should accept a PDU of given level + * Checks whether we should accept a PDU of given level */ -static int -accept_level (int level, int circuit_t) +static int accept_level(int level, int circuit_t) { - int retval = ((circuit_t & level) == level); /* simple approach */ + int retval = ((circuit_t & level) == level); /* simple approach */ - return retval; + return retval; } /* * Verify authentication information * Support cleartext and HMAC MD5 authentication */ -static int -authentication_check (struct isis_passwd *remote, struct isis_passwd *local, - struct stream *stream, uint32_t auth_tlv_offset) +static int authentication_check(struct isis_passwd *remote, + struct isis_passwd *local, + struct stream *stream, uint32_t auth_tlv_offset) { - unsigned char digest[ISIS_AUTH_MD5_SIZE]; - - /* Auth fail () - passwd type mismatch */ - if (local->type != remote->type) - return ISIS_ERROR; - - switch (local->type) - { - /* No authentication required */ - case ISIS_PASSWD_TYPE_UNUSED: - break; - - /* Cleartext (ISO 10589) */ - case ISIS_PASSWD_TYPE_CLEARTXT: - /* Auth fail () - passwd len mismatch */ - if (remote->len != local->len) - return ISIS_ERROR; - return memcmp (local->passwd, remote->passwd, local->len); - - /* HMAC MD5 (RFC 3567) */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - /* Auth fail () - passwd len mismatch */ - if (remote->len != ISIS_AUTH_MD5_SIZE) - return ISIS_ERROR; - /* Set the authentication value to 0 before the check */ - memset (STREAM_DATA (stream) + auth_tlv_offset + 3, 0, - ISIS_AUTH_MD5_SIZE); - /* Compute the digest */ - hmac_md5 (STREAM_DATA (stream), stream_get_endp (stream), - (unsigned char *) &(local->passwd), local->len, - (unsigned char *) &digest); - /* Copy back the authentication value after the check */ - memcpy (STREAM_DATA (stream) + auth_tlv_offset + 3, - remote->passwd, ISIS_AUTH_MD5_SIZE); - return memcmp (digest, remote->passwd, ISIS_AUTH_MD5_SIZE); - - default: - zlog_err ("Unsupported authentication type"); - return ISIS_ERROR; - } - - /* Authentication pass when no authentication is configured */ - return ISIS_OK; + unsigned char digest[ISIS_AUTH_MD5_SIZE]; + + /* Auth fail () - passwd type mismatch */ + if (local->type != remote->type) + return ISIS_ERROR; + + switch (local->type) { + /* No authentication required */ + case ISIS_PASSWD_TYPE_UNUSED: + break; + + /* Cleartext (ISO 10589) */ + case ISIS_PASSWD_TYPE_CLEARTXT: + /* Auth fail () - passwd len mismatch */ + if (remote->len != local->len) + return ISIS_ERROR; + return memcmp(local->passwd, remote->passwd, local->len); + + /* HMAC MD5 (RFC 3567) */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + /* Auth fail () - passwd len mismatch */ + if (remote->len != ISIS_AUTH_MD5_SIZE) + return ISIS_ERROR; + /* Set the authentication value to 0 before the check */ + memset(STREAM_DATA(stream) + auth_tlv_offset + 3, 0, + ISIS_AUTH_MD5_SIZE); + /* Compute the digest */ + hmac_md5(STREAM_DATA(stream), stream_get_endp(stream), + (unsigned char *)&(local->passwd), local->len, + (unsigned char *)&digest); + /* Copy back the authentication value after the check */ + memcpy(STREAM_DATA(stream) + auth_tlv_offset + 3, + remote->passwd, ISIS_AUTH_MD5_SIZE); + return memcmp(digest, remote->passwd, ISIS_AUTH_MD5_SIZE); + + default: + zlog_err("Unsupported authentication type"); + return ISIS_ERROR; + } + + /* Authentication pass when no authentication is configured */ + return ISIS_OK; } -static int -lsp_authentication_check (struct stream *stream, struct isis_area *area, - int level, struct isis_passwd *passwd) +static int lsp_authentication_check(struct stream *stream, + struct isis_area *area, int level, + struct isis_passwd *passwd) { - struct isis_link_state_hdr *hdr; - uint32_t expected = 0, found = 0, auth_tlv_offset = 0; - uint16_t checksum, rem_lifetime, pdu_len; - struct tlvs tlvs; - int retval = ISIS_OK; - - hdr = (struct isis_link_state_hdr *) (STREAM_PNT (stream)); - pdu_len = ntohs (hdr->pdu_len); - expected |= TLVFLAG_AUTH_INFO; - auth_tlv_offset = stream_get_getp (stream) + ISIS_LSP_HDR_LEN; - retval = parse_tlvs (area->area_tag, STREAM_PNT (stream) + ISIS_LSP_HDR_LEN, - pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN, - &expected, &found, &tlvs, &auth_tlv_offset); - - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Upd (%s): Parse failed L%d LSP %s, seq 0x%08x, " - "cksum 0x%04x, lifetime %us, len %u", - area->area_tag, level, rawlspid_print (hdr->lsp_id), - ntohl (hdr->seq_num), ntohs (hdr->checksum), - ntohs (hdr->rem_lifetime), pdu_len); - if ((isis->debugs & DEBUG_UPDATE_PACKETS) && - (isis->debugs & DEBUG_PACKET_DUMP)) - zlog_dump_data (STREAM_DATA (stream), stream_get_endp (stream)); - return retval; - } + struct isis_link_state_hdr *hdr; + uint32_t expected = 0, found = 0, auth_tlv_offset = 0; + uint16_t checksum, rem_lifetime, pdu_len; + struct tlvs tlvs; + int retval = ISIS_OK; + + hdr = (struct isis_link_state_hdr *)(STREAM_PNT(stream)); + pdu_len = ntohs(hdr->pdu_len); + expected |= TLVFLAG_AUTH_INFO; + auth_tlv_offset = stream_get_getp(stream) + ISIS_LSP_HDR_LEN; + retval = parse_tlvs(area->area_tag, + STREAM_PNT(stream) + ISIS_LSP_HDR_LEN, + pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN, + &expected, &found, &tlvs, &auth_tlv_offset); + + if (retval != ISIS_OK) { + zlog_err( + "ISIS-Upd (%s): Parse failed L%d LSP %s, seq 0x%08x, " + "cksum 0x%04x, lifetime %us, len %u", + area->area_tag, level, rawlspid_print(hdr->lsp_id), + ntohl(hdr->seq_num), ntohs(hdr->checksum), + ntohs(hdr->rem_lifetime), pdu_len); + if ((isis->debugs & DEBUG_UPDATE_PACKETS) + && (isis->debugs & DEBUG_PACKET_DUMP)) + zlog_dump_data(STREAM_DATA(stream), + stream_get_endp(stream)); + return retval; + } - if (!(found & TLVFLAG_AUTH_INFO)) - { - zlog_err ("No authentication tlv in LSP"); - return ISIS_ERROR; - } + if (!(found & TLVFLAG_AUTH_INFO)) { + zlog_err("No authentication tlv in LSP"); + return ISIS_ERROR; + } - if (tlvs.auth_info.type != ISIS_PASSWD_TYPE_CLEARTXT && - tlvs.auth_info.type != ISIS_PASSWD_TYPE_HMAC_MD5) - { - zlog_err ("Unknown authentication type in LSP"); - return ISIS_ERROR; - } + if (tlvs.auth_info.type != ISIS_PASSWD_TYPE_CLEARTXT + && tlvs.auth_info.type != ISIS_PASSWD_TYPE_HMAC_MD5) { + zlog_err("Unknown authentication type in LSP"); + return ISIS_ERROR; + } - /* - * RFC 5304 set checksum and remaining lifetime to zero before - * verification and reset to old values after verification. - */ - checksum = hdr->checksum; - rem_lifetime = hdr->rem_lifetime; - hdr->checksum = 0; - hdr->rem_lifetime = 0; - retval = authentication_check (&tlvs.auth_info, passwd, stream, - auth_tlv_offset); - hdr->checksum = checksum; - hdr->rem_lifetime = rem_lifetime; - - return retval; + /* + * RFC 5304 set checksum and remaining lifetime to zero before + * verification and reset to old values after verification. + */ + checksum = hdr->checksum; + rem_lifetime = hdr->rem_lifetime; + hdr->checksum = 0; + hdr->rem_lifetime = 0; + retval = authentication_check(&tlvs.auth_info, passwd, stream, + auth_tlv_offset); + hdr->checksum = checksum; + hdr->rem_lifetime = rem_lifetime; + + return retval; } /* * Processing helper functions */ -static void -del_addr (void *val) +static void del_addr(void *val) { - XFREE (MTYPE_ISIS_TMP, val); + XFREE(MTYPE_ISIS_TMP, val); } -static void -tlvs_to_adj_area_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) +static void tlvs_to_adj_area_addrs(struct tlvs *tlvs, + struct isis_adjacency *adj) { - struct listnode *node; - struct area_addr *area_addr, *malloced; + struct listnode *node; + struct area_addr *area_addr, *malloced; - if (adj->area_addrs) - { - adj->area_addrs->del = del_addr; - list_delete (adj->area_addrs); - } - adj->area_addrs = list_new (); - if (tlvs->area_addrs) - { - for (ALL_LIST_ELEMENTS_RO (tlvs->area_addrs, node, area_addr)) - { - malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct area_addr)); - memcpy (malloced, area_addr, sizeof (struct area_addr)); - listnode_add (adj->area_addrs, malloced); - } - } + if (adj->area_addrs) { + adj->area_addrs->del = del_addr; + list_delete(adj->area_addrs); + } + adj->area_addrs = list_new(); + if (tlvs->area_addrs) { + for (ALL_LIST_ELEMENTS_RO(tlvs->area_addrs, node, area_addr)) { + malloced = XMALLOC(MTYPE_ISIS_TMP, + sizeof(struct area_addr)); + memcpy(malloced, area_addr, sizeof(struct area_addr)); + listnode_add(adj->area_addrs, malloced); + } + } } -static int -tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) +static int tlvs_to_adj_nlpids(struct tlvs *tlvs, struct isis_adjacency *adj) { - int i; - struct nlpids *tlv_nlpids; + int i; + struct nlpids *tlv_nlpids; - if (tlvs->nlpids) - { + if (tlvs->nlpids) { - tlv_nlpids = tlvs->nlpids; - if (tlv_nlpids->count > array_size (adj->nlpids.nlpids)) - return 1; + tlv_nlpids = tlvs->nlpids; + if (tlv_nlpids->count > array_size(adj->nlpids.nlpids)) + return 1; - adj->nlpids.count = tlv_nlpids->count; + adj->nlpids.count = tlv_nlpids->count; - for (i = 0; i < tlv_nlpids->count; i++) - { - adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i]; + for (i = 0; i < tlv_nlpids->count; i++) { + adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i]; + } } - } - return 0; + return 0; } -static void -tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) +static void tlvs_to_adj_ipv4_addrs(struct tlvs *tlvs, + struct isis_adjacency *adj) { - struct listnode *node; - struct in_addr *ipv4_addr, *malloced; + struct listnode *node; + struct in_addr *ipv4_addr, *malloced; - if (adj->ipv4_addrs) - { - adj->ipv4_addrs->del = del_addr; - list_delete (adj->ipv4_addrs); - } - adj->ipv4_addrs = list_new (); - if (tlvs->ipv4_addrs) - { - for (ALL_LIST_ELEMENTS_RO (tlvs->ipv4_addrs, node, ipv4_addr)) - { - malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in_addr)); - memcpy (malloced, ipv4_addr, sizeof (struct in_addr)); - listnode_add (adj->ipv4_addrs, malloced); - } - } + if (adj->ipv4_addrs) { + adj->ipv4_addrs->del = del_addr; + list_delete(adj->ipv4_addrs); + } + adj->ipv4_addrs = list_new(); + if (tlvs->ipv4_addrs) { + for (ALL_LIST_ELEMENTS_RO(tlvs->ipv4_addrs, node, ipv4_addr)) { + malloced = + XMALLOC(MTYPE_ISIS_TMP, sizeof(struct in_addr)); + memcpy(malloced, ipv4_addr, sizeof(struct in_addr)); + listnode_add(adj->ipv4_addrs, malloced); + } + } } -static void -tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) +static void tlvs_to_adj_ipv6_addrs(struct tlvs *tlvs, + struct isis_adjacency *adj) { - struct listnode *node; - struct in6_addr *ipv6_addr, *malloced; - - if (adj->ipv6_addrs) - { - adj->ipv6_addrs->del = del_addr; - list_delete (adj->ipv6_addrs); - } - adj->ipv6_addrs = list_new (); - if (tlvs->ipv6_addrs) - { - for (ALL_LIST_ELEMENTS_RO (tlvs->ipv6_addrs, node, ipv6_addr)) - { - malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in6_addr)); - memcpy (malloced, ipv6_addr, sizeof (struct in6_addr)); - listnode_add (adj->ipv6_addrs, malloced); - } - } + struct listnode *node; + struct in6_addr *ipv6_addr, *malloced; + if (adj->ipv6_addrs) { + adj->ipv6_addrs->del = del_addr; + list_delete(adj->ipv6_addrs); + } + adj->ipv6_addrs = list_new(); + if (tlvs->ipv6_addrs) { + for (ALL_LIST_ELEMENTS_RO(tlvs->ipv6_addrs, node, ipv6_addr)) { + malloced = XMALLOC(MTYPE_ISIS_TMP, + sizeof(struct in6_addr)); + memcpy(malloced, ipv6_addr, sizeof(struct in6_addr)); + listnode_add(adj->ipv6_addrs, malloced); + } + } } /* - * RECEIVE SIDE + * RECEIVE SIDE */ /* @@ -324,584 +309,559 @@ tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) * Section 8.2.5 - Receiving point-to-point IIH PDUs * */ -static int -process_p2p_hello (struct isis_circuit *circuit) +static int process_p2p_hello(struct isis_circuit *circuit) { - int retval = ISIS_OK; - struct isis_p2p_hello_hdr *hdr; - struct isis_adjacency *adj; - u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; - uint16_t pdu_len; - struct tlvs tlvs; - int v4_usable = 0, v6_usable = 0; - - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Rcvd P2P IIH on %s, cirType %s, cirID %u", - circuit->area->area_tag, circuit->interface->name, - circuit_t2string (circuit->is_type), circuit->circuit_id); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->rcv_stream), - stream_get_endp (circuit->rcv_stream)); - } - - if (circuit->circ_type != CIRCUIT_T_P2P) - { - zlog_warn ("p2p hello on non p2p circuit"); - return ISIS_WARNING; - } - - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_P2PHELLO_HDRLEN) - { - zlog_warn ("Packet too short"); - return ISIS_WARNING; - } - - /* 8.2.5.1 PDU acceptance tests */ - - /* 8.2.5.1 a) external domain untrue */ - /* FIXME: not useful at all? */ - - /* 8.2.5.1 b) ID Length mismatch */ - /* checked at the handle_pdu */ - - /* 8.2.5.2 IIH PDU Processing */ - - /* 8.2.5.2 a) 1) Maximum Area Addresses */ - /* Already checked, and can also be ommited */ - - /* - * Get the header - */ - hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream); - pdu_len = ntohs (hdr->pdu_len); - - if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_P2PHELLO_HDRLEN) || - pdu_len > ISO_MTU(circuit) || - pdu_len > stream_get_endp (circuit->rcv_stream)) - { - zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with " - "invalid pdu length %d", - circuit->area->area_tag, circuit->interface->name, pdu_len); - return ISIS_WARNING; - } - - /* - * Set the stream endp to PDU length, ignoring additional padding - * introduced by transport chips. - */ - if (pdu_len < stream_get_endp (circuit->rcv_stream)) - stream_set_endp (circuit->rcv_stream, pdu_len); - - stream_forward_getp (circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN); - - /* - * Lets get the TLVS now - */ - expected |= TLVFLAG_AREA_ADDRS; - expected |= TLVFLAG_AUTH_INFO; - expected |= TLVFLAG_NLPID; - expected |= TLVFLAG_IPV4_ADDR; - expected |= TLVFLAG_IPV6_ADDR; - expected |= TLVFLAG_MT_ROUTER_INFORMATION; - - auth_tlv_offset = stream_get_getp (circuit->rcv_stream); - retval = parse_tlvs (circuit->area->area_tag, - STREAM_PNT (circuit->rcv_stream), - pdu_len - ISIS_P2PHELLO_HDRLEN - ISIS_FIXED_HDR_LEN, - &expected, &found, &tlvs, &auth_tlv_offset); - - if (retval > ISIS_WARNING) - { - zlog_warn ("parse_tlvs() failed"); - free_tlvs (&tlvs); - return retval; - }; - - if (!(found & TLVFLAG_AREA_ADDRS)) - { - zlog_warn ("No Area addresses TLV in P2P IS to IS hello"); - free_tlvs (&tlvs); - return ISIS_WARNING; - } + int retval = ISIS_OK; + struct isis_p2p_hello_hdr *hdr; + struct isis_adjacency *adj; + u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; + uint16_t pdu_len; + struct tlvs tlvs; + int v4_usable = 0, v6_usable = 0; + + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Rcvd P2P IIH on %s, cirType %s, cirID %u", + circuit->area->area_tag, circuit->interface->name, + circuit_t2string(circuit->is_type), + circuit->circuit_id); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->rcv_stream), + stream_get_endp(circuit->rcv_stream)); + } - if (!(found & TLVFLAG_NLPID)) - { - zlog_warn ("No supported protocols TLV in P2P IS to IS hello"); - free_tlvs (&tlvs); - return ISIS_WARNING; - } + if (circuit->circ_type != CIRCUIT_T_P2P) { + zlog_warn("p2p hello on non p2p circuit"); + return ISIS_WARNING; + } - /* 8.2.5.1 c) Authentication */ - if (circuit->passwd.type) - { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (&tlvs.auth_info, &circuit->passwd, - circuit->rcv_stream, auth_tlv_offset)) - { - isis_event_auth_failure (circuit->area->area_tag, - "P2P hello authentication failure", - hdr->source_id); - free_tlvs (&tlvs); - return ISIS_OK; - } - } + if ((stream_get_endp(circuit->rcv_stream) + - stream_get_getp(circuit->rcv_stream)) + < ISIS_P2PHELLO_HDRLEN) { + zlog_warn("Packet too short"); + return ISIS_WARNING; + } - /* - * check if both ends have an IPv4 address - */ - if (circuit->ip_addrs && listcount(circuit->ip_addrs) - && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs)) - { - v4_usable = 1; - } + /* 8.2.5.1 PDU acceptance tests */ - if (found & TLVFLAG_IPV6_ADDR) - { - /* TBA: check that we have a linklocal ourselves? */ - struct listnode *node; - struct in6_addr *ip; - for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip)) - if (IN6_IS_ADDR_LINKLOCAL (ip)) - { - v6_usable = 1; - break; - } - - if (!v6_usable) - zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local " - "in P2P IIH from %s\n", circuit->interface->name); - } + /* 8.2.5.1 a) external domain untrue */ + /* FIXME: not useful at all? */ - if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR))) - zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n", - circuit->interface->name); + /* 8.2.5.1 b) ID Length mismatch */ + /* checked at the handle_pdu */ - if (!v6_usable && !v4_usable) - { - free_tlvs (&tlvs); - return ISIS_WARNING; - } + /* 8.2.5.2 IIH PDU Processing */ - /* - * it's own p2p IIH PDU - discard - */ - if (!memcmp (hdr->source_id, isis->sysid, ISIS_SYS_ID_LEN)) - { - zlog_warn ("ISIS-Adj (%s): it's own IIH PDU - discarded", - circuit->area->area_tag); - free_tlvs (&tlvs); - return ISIS_WARNING; - } + /* 8.2.5.2 a) 1) Maximum Area Addresses */ + /* Already checked, and can also be ommited */ - /* - * My interpertation of the ISO, if no adj exists we will create one for - * the circuit - */ - adj = circuit->u.p2p.neighbor; - /* If an adjacency exists, check it is with the source of the hello - * packets */ - if (adj) - { - if (memcmp(hdr->source_id, adj->sysid, ISIS_SYS_ID_LEN)) - { - zlog_debug("hello source and adjacency do not match, set adj down\n"); - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "adj do not exist"); - return 0; - } - } - if (!adj || adj->level != hdr->circuit_t) - { - if (!adj) - { - adj = isis_new_adj (hdr->source_id, NULL, hdr->circuit_t, circuit); - if (adj == NULL) - return ISIS_ERROR; - } - else - { - adj->level = hdr->circuit_t; - } - circuit->u.p2p.neighbor = adj; - /* Build lsp with the new neighbor entry when a new - * adjacency is formed. Set adjacency circuit type to - * IIH PDU header circuit type before lsp is regenerated - * when an adjacency is up. This will result in the new - * adjacency entry getting added to the lsp tlv neighbor list. - */ - adj->circuit_t = hdr->circuit_t; - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - } + /* + * Get the header + */ + hdr = (struct isis_p2p_hello_hdr *)STREAM_PNT(circuit->rcv_stream); + pdu_len = ntohs(hdr->pdu_len); - /* 8.2.6 Monitoring point-to-point adjacencies */ - adj->hold_time = ntohs (hdr->hold_time); - adj->last_upd = time (NULL); + if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_P2PHELLO_HDRLEN) + || pdu_len > ISO_MTU(circuit) + || pdu_len > stream_get_endp(circuit->rcv_stream)) { + zlog_warn( + "ISIS-Adj (%s): Rcvd P2P IIH from (%s) with " + "invalid pdu length %d", + circuit->area->area_tag, circuit->interface->name, + pdu_len); + return ISIS_WARNING; + } - /* we do this now because the adj may not survive till the end... */ - tlvs_to_adj_area_addrs (&tlvs, adj); + /* + * Set the stream endp to PDU length, ignoring additional padding + * introduced by transport chips. + */ + if (pdu_len < stream_get_endp(circuit->rcv_stream)) + stream_set_endp(circuit->rcv_stream, pdu_len); + + stream_forward_getp(circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN); + + /* + * Lets get the TLVS now + */ + expected |= TLVFLAG_AREA_ADDRS; + expected |= TLVFLAG_AUTH_INFO; + expected |= TLVFLAG_NLPID; + expected |= TLVFLAG_IPV4_ADDR; + expected |= TLVFLAG_IPV6_ADDR; + expected |= TLVFLAG_MT_ROUTER_INFORMATION; + + auth_tlv_offset = stream_get_getp(circuit->rcv_stream); + retval = parse_tlvs(circuit->area->area_tag, + STREAM_PNT(circuit->rcv_stream), + pdu_len - ISIS_P2PHELLO_HDRLEN - ISIS_FIXED_HDR_LEN, + &expected, &found, &tlvs, &auth_tlv_offset); + + if (retval > ISIS_WARNING) { + zlog_warn("parse_tlvs() failed"); + free_tlvs(&tlvs); + return retval; + }; + + if (!(found & TLVFLAG_AREA_ADDRS)) { + zlog_warn("No Area addresses TLV in P2P IS to IS hello"); + free_tlvs(&tlvs); + return ISIS_WARNING; + } - /* which protocol are spoken ??? */ - if (tlvs_to_adj_nlpids (&tlvs, adj)) - { - free_tlvs (&tlvs); - return ISIS_WARNING; - } + if (!(found & TLVFLAG_NLPID)) { + zlog_warn("No supported protocols TLV in P2P IS to IS hello"); + free_tlvs(&tlvs); + return ISIS_WARNING; + } - /* we need to copy addresses to the adj */ - if (found & TLVFLAG_IPV4_ADDR) - tlvs_to_adj_ipv4_addrs (&tlvs, adj); + /* 8.2.5.1 c) Authentication */ + if (circuit->passwd.type) { + if (!(found & TLVFLAG_AUTH_INFO) + || authentication_check(&tlvs.auth_info, &circuit->passwd, + circuit->rcv_stream, + auth_tlv_offset)) { + isis_event_auth_failure( + circuit->area->area_tag, + "P2P hello authentication failure", + hdr->source_id); + free_tlvs(&tlvs); + return ISIS_OK; + } + } - /* Update MPLS TE Remote IP address parameter if possible */ - if (IS_MPLS_TE(isisMplsTE) && circuit->mtc && IS_CIRCUIT_TE(circuit->mtc)) - if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0) - { - struct in_addr *ip_addr; - ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs)); - set_circuitparams_rmt_ipaddr (circuit->mtc, *ip_addr); - } + /* + * check if both ends have an IPv4 address + */ + if (circuit->ip_addrs && listcount(circuit->ip_addrs) && tlvs.ipv4_addrs + && listcount(tlvs.ipv4_addrs)) { + v4_usable = 1; + } - if (found & TLVFLAG_IPV6_ADDR) - tlvs_to_adj_ipv6_addrs (&tlvs, adj); + if (found & TLVFLAG_IPV6_ADDR) { + /* TBA: check that we have a linklocal ourselves? */ + struct listnode *node; + struct in6_addr *ip; + for (ALL_LIST_ELEMENTS_RO(tlvs.ipv6_addrs, node, ip)) + if (IN6_IS_ADDR_LINKLOCAL(ip)) { + v6_usable = 1; + break; + } + + if (!v6_usable) + zlog_warn( + "ISIS-Adj: IPv6 addresses present but no link-local " + "in P2P IIH from %s\n", + circuit->interface->name); + } - bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj); + if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR))) + zlog_warn( + "ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n", + circuit->interface->name); - /* lets take care of the expiry */ - THREAD_TIMER_OFF (adj->t_expire); - thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, - &adj->t_expire); + if (!v6_usable && !v4_usable) { + free_tlvs(&tlvs); + return ISIS_WARNING; + } - /* 8.2.5.2 a) a match was detected */ - if (area_match (circuit->area->area_addrs, tlvs.area_addrs)) - { - /* 8.2.5.2 a) 2) If the system is L1 - table 5 */ - if (circuit->area->is_type == IS_LEVEL_1) - { - switch (hdr->circuit_t) - { - case IS_LEVEL_1: - case IS_LEVEL_1_AND_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (4) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (5) adj usage level 1 */ - adj->adj_usage = ISIS_ADJ_LEVEL1; - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1) - { - ; /* accept */ - } - break; - case IS_LEVEL_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (7) reject - wrong system type event */ - zlog_warn ("wrongSystemType"); - free_tlvs (&tlvs); - return ISIS_WARNING; /* Reject */ - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1) - { - /* (6) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - break; - } + /* + * it's own p2p IIH PDU - discard + */ + if (!memcmp(hdr->source_id, isis->sysid, ISIS_SYS_ID_LEN)) { + zlog_warn("ISIS-Adj (%s): it's own IIH PDU - discarded", + circuit->area->area_tag); + free_tlvs(&tlvs); + return ISIS_WARNING; } - /* 8.2.5.2 a) 3) If the system is L1L2 - table 6 */ - if (circuit->area->is_type == IS_LEVEL_1_AND_2) - { - switch (hdr->circuit_t) - { - case IS_LEVEL_1: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (6) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (7) adj usage level 1 */ - adj->adj_usage = ISIS_ADJ_LEVEL1; - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1) - { - ; /* accept */ + /* + * My interpertation of the ISO, if no adj exists we will create one for + * the circuit + */ + adj = circuit->u.p2p.neighbor; + /* If an adjacency exists, check it is with the source of the hello + * packets */ + if (adj) { + if (memcmp(hdr->source_id, adj->sysid, ISIS_SYS_ID_LEN)) { + zlog_debug( + "hello source and adjacency do not match, set adj down\n"); + isis_adj_state_change(adj, ISIS_ADJ_DOWN, + "adj do not exist"); + return 0; } - else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) || - (adj->adj_usage == ISIS_ADJ_LEVEL2)) - { - /* (8) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - break; - case IS_LEVEL_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (6) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (9) adj usage level 2 */ - adj->adj_usage = ISIS_ADJ_LEVEL2; - } - else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) || - (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)) - { - /* (8) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL2) - { - ; /* Accept */ - } - break; - case IS_LEVEL_1_AND_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (6) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (10) adj usage level 1 */ - adj->adj_usage = ISIS_ADJ_LEVEL1AND2; - } - else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) || - (adj->adj_usage == ISIS_ADJ_LEVEL2)) - { - /* (8) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) - { - ; /* Accept */ + } + if (!adj || adj->level != hdr->circuit_t) { + if (!adj) { + adj = isis_new_adj(hdr->source_id, NULL, hdr->circuit_t, + circuit); + if (adj == NULL) + return ISIS_ERROR; + } else { + adj->level = hdr->circuit_t; } - break; - } + circuit->u.p2p.neighbor = adj; + /* Build lsp with the new neighbor entry when a new + * adjacency is formed. Set adjacency circuit type to + * IIH PDU header circuit type before lsp is regenerated + * when an adjacency is up. This will result in the new + * adjacency entry getting added to the lsp tlv neighbor list. + */ + adj->circuit_t = hdr->circuit_t; + isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; } - /* 8.2.5.2 a) 4) If the system is L2 - table 7 */ - if (circuit->area->is_type == IS_LEVEL_2) - { - switch (hdr->circuit_t) - { - case IS_LEVEL_1: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (5) reject - wrong system type event */ - zlog_warn ("wrongSystemType"); - free_tlvs (&tlvs); - return ISIS_WARNING; /* Reject */ - } - else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) || - (adj->adj_usage == ISIS_ADJ_LEVEL2)) - { - /* (6) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - break; - case IS_LEVEL_1_AND_2: - case IS_LEVEL_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (7) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (8) adj usage level 2 */ - adj->adj_usage = ISIS_ADJ_LEVEL2; - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) - { - /* (6) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL2) - { - ; /* Accept */ - } - break; - } + /* 8.2.6 Monitoring point-to-point adjacencies */ + adj->hold_time = ntohs(hdr->hold_time); + adj->last_upd = time(NULL); + + /* we do this now because the adj may not survive till the end... */ + tlvs_to_adj_area_addrs(&tlvs, adj); + + /* which protocol are spoken ??? */ + if (tlvs_to_adj_nlpids(&tlvs, adj)) { + free_tlvs(&tlvs); + return ISIS_WARNING; } - } - /* 8.2.5.2 b) if no match was detected */ - else if (listcount (circuit->area->area_addrs) > 0) - { - if (circuit->area->is_type == IS_LEVEL_1) - { - /* 8.2.5.2 b) 1) is_type L1 and adj is not up */ - if (adj->adj_state != ISIS_ADJ_UP) - { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch"); - /* 8.2.5.2 b) 2)is_type L1 and adj is up */ - } - else - { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, - "Down - Area Mismatch"); - } - } - /* 8.2.5.2 b 3 If the system is L2 or L1L2 - table 8 */ - else - { - switch (hdr->circuit_t) - { - case IS_LEVEL_1: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (6) reject - Area Mismatch event */ - zlog_warn ("AreaMismatch"); - free_tlvs (&tlvs); - return ISIS_WARNING; /* Reject */ - } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1) - { - /* (7) down - area mismatch */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch"); + /* we need to copy addresses to the adj */ + if (found & TLVFLAG_IPV4_ADDR) + tlvs_to_adj_ipv4_addrs(&tlvs, adj); + + /* Update MPLS TE Remote IP address parameter if possible */ + if (IS_MPLS_TE(isisMplsTE) && circuit->mtc + && IS_CIRCUIT_TE(circuit->mtc)) + if (adj->ipv4_addrs != NULL + && listcount(adj->ipv4_addrs) != 0) { + struct in_addr *ip_addr; + ip_addr = (struct in_addr *)listgetdata( + (struct listnode *)listhead(adj->ipv4_addrs)); + set_circuitparams_rmt_ipaddr(circuit->mtc, *ip_addr); } - else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) || - (adj->adj_usage == ISIS_ADJ_LEVEL2)) - { - /* (7) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); + + if (found & TLVFLAG_IPV6_ADDR) + tlvs_to_adj_ipv6_addrs(&tlvs, adj); + + bool mt_set_changed = + tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj); + + /* lets take care of the expiry */ + THREAD_TIMER_OFF(adj->t_expire); + thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, + &adj->t_expire); + + /* 8.2.5.2 a) a match was detected */ + if (area_match(circuit->area->area_addrs, tlvs.area_addrs)) { + /* 8.2.5.2 a) 2) If the system is L1 - table 5 */ + if (circuit->area->is_type == IS_LEVEL_1) { + switch (hdr->circuit_t) { + case IS_LEVEL_1: + case IS_LEVEL_1_AND_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (4) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (5) adj usage level 1 */ + adj->adj_usage = ISIS_ADJ_LEVEL1; + } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { + ; /* accept */ + } + break; + case IS_LEVEL_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (7) reject - wrong system type event + */ + zlog_warn("wrongSystemType"); + free_tlvs(&tlvs); + return ISIS_WARNING; /* Reject */ + } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { + /* (6) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } + break; + } } - break; - case IS_LEVEL_1_AND_2: - case IS_LEVEL_2: - if (adj->adj_state != ISIS_ADJ_UP) - { - /* (8) adj state up */ - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL); - /* (9) adj usage level 2 */ - adj->adj_usage = ISIS_ADJ_LEVEL2; + + /* 8.2.5.2 a) 3) If the system is L1L2 - table 6 */ + if (circuit->area->is_type == IS_LEVEL_1_AND_2) { + switch (hdr->circuit_t) { + case IS_LEVEL_1: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (6) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (7) adj usage level 1 */ + adj->adj_usage = ISIS_ADJ_LEVEL1; + } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { + ; /* accept */ + } else if ((adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) + || (adj->adj_usage + == ISIS_ADJ_LEVEL2)) { + /* (8) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } + break; + case IS_LEVEL_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (6) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (9) adj usage level 2 */ + adj->adj_usage = ISIS_ADJ_LEVEL2; + } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) + || (adj->adj_usage + == ISIS_ADJ_LEVEL1AND2)) { + /* (8) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) { + ; /* Accept */ + } + break; + case IS_LEVEL_1_AND_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (6) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (10) adj usage level 1 */ + adj->adj_usage = ISIS_ADJ_LEVEL1AND2; + } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) + || (adj->adj_usage + == ISIS_ADJ_LEVEL2)) { + /* (8) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } else if (adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) { + ; /* Accept */ + } + break; + } } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1) - { - /* (7) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System"); + + /* 8.2.5.2 a) 4) If the system is L2 - table 7 */ + if (circuit->area->is_type == IS_LEVEL_2) { + switch (hdr->circuit_t) { + case IS_LEVEL_1: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (5) reject - wrong system type event + */ + zlog_warn("wrongSystemType"); + free_tlvs(&tlvs); + return ISIS_WARNING; /* Reject */ + } else if ((adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) + || (adj->adj_usage + == ISIS_ADJ_LEVEL2)) { + /* (6) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } + break; + case IS_LEVEL_1_AND_2: + case IS_LEVEL_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (7) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (8) adj usage level 2 */ + adj->adj_usage = ISIS_ADJ_LEVEL2; + } else if (adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) { + /* (6) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) { + ; /* Accept */ + } + break; + } } - else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) - { - if (hdr->circuit_t == IS_LEVEL_2) - { - /* (7) down - wrong system */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, - "Wrong System"); - } - else - { - /* (7) down - area mismatch */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, - "Area Mismatch"); - } + } + /* 8.2.5.2 b) if no match was detected */ + else if (listcount(circuit->area->area_addrs) > 0) { + if (circuit->area->is_type == IS_LEVEL_1) { + /* 8.2.5.2 b) 1) is_type L1 and adj is not up */ + if (adj->adj_state != ISIS_ADJ_UP) { + isis_adj_state_change(adj, ISIS_ADJ_DOWN, + "Area Mismatch"); + /* 8.2.5.2 b) 2)is_type L1 and adj is up */ + } else { + isis_adj_state_change(adj, ISIS_ADJ_DOWN, + "Down - Area Mismatch"); + } } - else if (adj->adj_usage == ISIS_ADJ_LEVEL2) - { - ; /* Accept */ + /* 8.2.5.2 b 3 If the system is L2 or L1L2 - table 8 */ + else { + switch (hdr->circuit_t) { + case IS_LEVEL_1: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (6) reject - Area Mismatch event */ + zlog_warn("AreaMismatch"); + free_tlvs(&tlvs); + return ISIS_WARNING; /* Reject */ + } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { + /* (7) down - area mismatch */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Area Mismatch"); + + } else if ((adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) + || (adj->adj_usage + == ISIS_ADJ_LEVEL2)) { + /* (7) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } + break; + case IS_LEVEL_1_AND_2: + case IS_LEVEL_2: + if (adj->adj_state != ISIS_ADJ_UP) { + /* (8) adj state up */ + isis_adj_state_change(adj, ISIS_ADJ_UP, + NULL); + /* (9) adj usage level 2 */ + adj->adj_usage = ISIS_ADJ_LEVEL2; + } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { + /* (7) down - wrong system */ + isis_adj_state_change(adj, + ISIS_ADJ_DOWN, + "Wrong System"); + } else if (adj->adj_usage + == ISIS_ADJ_LEVEL1AND2) { + if (hdr->circuit_t == IS_LEVEL_2) { + /* (7) down - wrong system */ + isis_adj_state_change( + adj, ISIS_ADJ_DOWN, + "Wrong System"); + } else { + /* (7) down - area mismatch */ + isis_adj_state_change( + adj, ISIS_ADJ_DOWN, + "Area Mismatch"); + } + } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) { + ; /* Accept */ + } + break; + } } - break; - } + } else { + /* down - area mismatch */ + isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Area Mismatch"); } - } - else - { - /* down - area mismatch */ - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch"); - } - if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed) - { - lsp_regenerate_schedule(adj->circuit->area, - isis_adj_usage2levels(adj->adj_usage), 0); - } - - /* 8.2.5.2 c) if the action was up - comparing circuit IDs */ - /* FIXME - Missing parts */ + if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed) { + lsp_regenerate_schedule(adj->circuit->area, + isis_adj_usage2levels(adj->adj_usage), + 0); + } - /* some of my own understanding of the ISO, why the heck does - * it not say what should I change the system_type to... - */ - switch (adj->adj_usage) - { - case ISIS_ADJ_LEVEL1: - adj->sys_type = ISIS_SYSTYPE_L1_IS; - break; - case ISIS_ADJ_LEVEL2: - adj->sys_type = ISIS_SYSTYPE_L2_IS; - break; - case ISIS_ADJ_LEVEL1AND2: - adj->sys_type = ISIS_SYSTYPE_L2_IS; - break; - case ISIS_ADJ_NONE: - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - break; - } + /* 8.2.5.2 c) if the action was up - comparing circuit IDs */ + /* FIXME - Missing parts */ + + /* some of my own understanding of the ISO, why the heck does + * it not say what should I change the system_type to... + */ + switch (adj->adj_usage) { + case ISIS_ADJ_LEVEL1: + adj->sys_type = ISIS_SYSTYPE_L1_IS; + break; + case ISIS_ADJ_LEVEL2: + adj->sys_type = ISIS_SYSTYPE_L2_IS; + break; + case ISIS_ADJ_LEVEL1AND2: + adj->sys_type = ISIS_SYSTYPE_L2_IS; + break; + case ISIS_ADJ_NONE: + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; + break; + } - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Rcvd P2P IIH from (%s), cir type %s," - " cir id %02d, length %d", - circuit->area->area_tag, circuit->interface->name, - circuit_t2string (circuit->is_type), - circuit->circuit_id, pdu_len); - } + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Rcvd P2P IIH from (%s), cir type %s," + " cir id %02d, length %d", + circuit->area->area_tag, circuit->interface->name, + circuit_t2string(circuit->is_type), circuit->circuit_id, + pdu_len); + } - free_tlvs (&tlvs); + free_tlvs(&tlvs); - return retval; + return retval; } /* * Process IS-IS LAN Level 1/2 Hello PDU */ -static int -process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa) +static int process_lan_hello(int level, struct isis_circuit *circuit, + const u_char *ssnpa) { - int retval = ISIS_OK; - struct isis_lan_hello_hdr hdr; - struct isis_adjacency *adj; - u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; - struct tlvs tlvs; - u_char *snpa; - struct listnode *node; - int v4_usable = 0, v6_usable = 0; - - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH on %s, cirType %s, " - "cirID %u", - circuit->area->area_tag, level, circuit->interface->name, - circuit_t2string (circuit->is_type), circuit->circuit_id); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->rcv_stream), - stream_get_endp (circuit->rcv_stream)); - } + int retval = ISIS_OK; + struct isis_lan_hello_hdr hdr; + struct isis_adjacency *adj; + u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; + struct tlvs tlvs; + u_char *snpa; + struct listnode *node; + int v4_usable = 0, v6_usable = 0; + + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Rcvd L%d LAN IIH on %s, cirType %s, " + "cirID %u", + circuit->area->area_tag, level, + circuit->interface->name, + circuit_t2string(circuit->is_type), + circuit->circuit_id); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->rcv_stream), + stream_get_endp(circuit->rcv_stream)); + } - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - { - zlog_warn ("lan hello on non broadcast circuit"); - return ISIS_WARNING; - } + if (circuit->circ_type != CIRCUIT_T_BROADCAST) { + zlog_warn("lan hello on non broadcast circuit"); + return ISIS_WARNING; + } - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_LANHELLO_HDRLEN) - { - zlog_warn ("Packet too short"); - return ISIS_WARNING; - } + if ((stream_get_endp(circuit->rcv_stream) + - stream_get_getp(circuit->rcv_stream)) + < ISIS_LANHELLO_HDRLEN) { + zlog_warn("Packet too short"); + return ISIS_WARNING; + } - if (circuit->ext_domain) - { - zlog_debug ("level %d LAN Hello received over circuit with " - "externalDomain = true", level); - return ISIS_WARNING; - } + if (circuit->ext_domain) { + zlog_debug( + "level %d LAN Hello received over circuit with " + "externalDomain = true", + level); + return ISIS_WARNING; + } - if (!accept_level (level, circuit->is_type)) - { - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Interface level mismatch, %s", - circuit->area->area_tag, circuit->interface->name); + if (!accept_level(level, circuit->is_type)) { + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Interface level mismatch, %s", + circuit->area->area_tag, + circuit->interface->name); + } + return ISIS_WARNING; } - return ISIS_WARNING; - } #if 0 /* Cisco's debug message compatability */ @@ -915,319 +875,304 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa) return ISIS_WARNING; } #endif - /* - * Fill the header - */ - hdr.circuit_t = stream_getc (circuit->rcv_stream); - stream_get (hdr.source_id, circuit->rcv_stream, ISIS_SYS_ID_LEN); - hdr.hold_time = stream_getw (circuit->rcv_stream); - hdr.pdu_len = stream_getw (circuit->rcv_stream); - hdr.prio = stream_getc (circuit->rcv_stream); - stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1); - - if (hdr.pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LANHELLO_HDRLEN) || - hdr.pdu_len > ISO_MTU(circuit) || - hdr.pdu_len > stream_get_endp (circuit->rcv_stream)) - { - zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with " - "invalid pdu length %d", - circuit->area->area_tag, circuit->interface->name, - hdr.pdu_len); - return ISIS_WARNING; - } - - /* - * Set the stream endp to PDU length, ignoring additional padding - * introduced by transport chips. - */ - if (hdr.pdu_len < stream_get_endp (circuit->rcv_stream)) - stream_set_endp (circuit->rcv_stream, hdr.pdu_len); - - if (hdr.circuit_t != IS_LEVEL_1 && - hdr.circuit_t != IS_LEVEL_2 && - hdr.circuit_t != IS_LEVEL_1_AND_2 && - (level & hdr.circuit_t) == 0) - { - zlog_err ("Level %d LAN Hello with Circuit Type %d", level, - hdr.circuit_t); - return ISIS_ERROR; - } + /* + * Fill the header + */ + hdr.circuit_t = stream_getc(circuit->rcv_stream); + stream_get(hdr.source_id, circuit->rcv_stream, ISIS_SYS_ID_LEN); + hdr.hold_time = stream_getw(circuit->rcv_stream); + hdr.pdu_len = stream_getw(circuit->rcv_stream); + hdr.prio = stream_getc(circuit->rcv_stream); + stream_get(hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1); + + if (hdr.pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LANHELLO_HDRLEN) + || hdr.pdu_len > ISO_MTU(circuit) + || hdr.pdu_len > stream_get_endp(circuit->rcv_stream)) { + zlog_warn( + "ISIS-Adj (%s): Rcvd LAN IIH from (%s) with " + "invalid pdu length %d", + circuit->area->area_tag, circuit->interface->name, + hdr.pdu_len); + return ISIS_WARNING; + } - /* - * Then get the tlvs - */ - expected |= TLVFLAG_AUTH_INFO; - expected |= TLVFLAG_AREA_ADDRS; - expected |= TLVFLAG_LAN_NEIGHS; - expected |= TLVFLAG_NLPID; - expected |= TLVFLAG_IPV4_ADDR; - expected |= TLVFLAG_IPV6_ADDR; - expected |= TLVFLAG_MT_ROUTER_INFORMATION; - - auth_tlv_offset = stream_get_getp (circuit->rcv_stream); - retval = parse_tlvs (circuit->area->area_tag, - STREAM_PNT (circuit->rcv_stream), - hdr.pdu_len - ISIS_LANHELLO_HDRLEN - ISIS_FIXED_HDR_LEN, - &expected, &found, &tlvs, - &auth_tlv_offset); - - if (retval > ISIS_WARNING) - { - zlog_warn ("parse_tlvs() failed"); - goto out; - } + /* + * Set the stream endp to PDU length, ignoring additional padding + * introduced by transport chips. + */ + if (hdr.pdu_len < stream_get_endp(circuit->rcv_stream)) + stream_set_endp(circuit->rcv_stream, hdr.pdu_len); + + if (hdr.circuit_t != IS_LEVEL_1 && hdr.circuit_t != IS_LEVEL_2 + && hdr.circuit_t != IS_LEVEL_1_AND_2 + && (level & hdr.circuit_t) == 0) { + zlog_err("Level %d LAN Hello with Circuit Type %d", level, + hdr.circuit_t); + return ISIS_ERROR; + } - if (!(found & TLVFLAG_AREA_ADDRS)) - { - zlog_warn ("No Area addresses TLV in Level %d LAN IS to IS hello", - level); - retval = ISIS_WARNING; - goto out; - } + /* + * Then get the tlvs + */ + expected |= TLVFLAG_AUTH_INFO; + expected |= TLVFLAG_AREA_ADDRS; + expected |= TLVFLAG_LAN_NEIGHS; + expected |= TLVFLAG_NLPID; + expected |= TLVFLAG_IPV4_ADDR; + expected |= TLVFLAG_IPV6_ADDR; + expected |= TLVFLAG_MT_ROUTER_INFORMATION; + + auth_tlv_offset = stream_get_getp(circuit->rcv_stream); + retval = parse_tlvs( + circuit->area->area_tag, STREAM_PNT(circuit->rcv_stream), + hdr.pdu_len - ISIS_LANHELLO_HDRLEN - ISIS_FIXED_HDR_LEN, + &expected, &found, &tlvs, &auth_tlv_offset); + + if (retval > ISIS_WARNING) { + zlog_warn("parse_tlvs() failed"); + goto out; + } - if (!(found & TLVFLAG_NLPID)) - { - zlog_warn ("No supported protocols TLV in Level %d LAN IS to IS hello", - level); - retval = ISIS_WARNING; - goto out; - } + if (!(found & TLVFLAG_AREA_ADDRS)) { + zlog_warn( + "No Area addresses TLV in Level %d LAN IS to IS hello", + level); + retval = ISIS_WARNING; + goto out; + } - /* Verify authentication, either cleartext of HMAC MD5 */ - if (circuit->passwd.type) - { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (&tlvs.auth_info, &circuit->passwd, - circuit->rcv_stream, auth_tlv_offset)) - { - isis_event_auth_failure (circuit->area->area_tag, - "LAN hello authentication failure", - hdr.source_id); - retval = ISIS_WARNING; - goto out; - } - } + if (!(found & TLVFLAG_NLPID)) { + zlog_warn( + "No supported protocols TLV in Level %d LAN IS to IS hello", + level); + retval = ISIS_WARNING; + goto out; + } - if (!memcmp (hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN)) - { - zlog_warn ("ISIS-Adj (%s): duplicate system ID on interface %s", - circuit->area->area_tag, circuit->interface->name); - return ISIS_WARNING; - } + /* Verify authentication, either cleartext of HMAC MD5 */ + if (circuit->passwd.type) { + if (!(found & TLVFLAG_AUTH_INFO) + || authentication_check(&tlvs.auth_info, &circuit->passwd, + circuit->rcv_stream, + auth_tlv_offset)) { + isis_event_auth_failure( + circuit->area->area_tag, + "LAN hello authentication failure", + hdr.source_id); + retval = ISIS_WARNING; + goto out; + } + } - /* - * Accept the level 1 adjacency only if a match between local and - * remote area addresses is found - */ - if (listcount (circuit->area->area_addrs) == 0 || - (level == IS_LEVEL_1 && - area_match (circuit->area->area_addrs, tlvs.area_addrs) == 0)) - { - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Area mismatch, level %d IIH on %s", - circuit->area->area_tag, level, - circuit->interface->name); + if (!memcmp(hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN)) { + zlog_warn("ISIS-Adj (%s): duplicate system ID on interface %s", + circuit->area->area_tag, circuit->interface->name); + return ISIS_WARNING; } - retval = ISIS_OK; - goto out; - } - /* - * it's own IIH PDU - discard silently - */ - if (!memcmp (circuit->u.bc.snpa, ssnpa, ETH_ALEN)) - { - zlog_debug ("ISIS-Adj (%s): it's own IIH PDU - discarded", - circuit->area->area_tag); + /* + * Accept the level 1 adjacency only if a match between local and + * remote area addresses is found + */ + if (listcount(circuit->area->area_addrs) == 0 + || (level == IS_LEVEL_1 + && area_match(circuit->area->area_addrs, tlvs.area_addrs) + == 0)) { + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Area mismatch, level %d IIH on %s", + circuit->area->area_tag, level, + circuit->interface->name); + } + retval = ISIS_OK; + goto out; + } - retval = ISIS_OK; - goto out; - } + /* + * it's own IIH PDU - discard silently + */ + if (!memcmp(circuit->u.bc.snpa, ssnpa, ETH_ALEN)) { + zlog_debug("ISIS-Adj (%s): it's own IIH PDU - discarded", + circuit->area->area_tag); - /* - * check if both ends have an IPv4 address - */ - if (circuit->ip_addrs && listcount(circuit->ip_addrs) - && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs)) - { - v4_usable = 1; - } + retval = ISIS_OK; + goto out; + } - if (found & TLVFLAG_IPV6_ADDR) - { - /* TBA: check that we have a linklocal ourselves? */ - struct listnode *node; - struct in6_addr *ip; - for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip)) - if (IN6_IS_ADDR_LINKLOCAL (ip)) - { - v6_usable = 1; - break; - } - - if (!v6_usable) - zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local " - "in LAN IIH from %s\n", circuit->interface->name); - } + /* + * check if both ends have an IPv4 address + */ + if (circuit->ip_addrs && listcount(circuit->ip_addrs) && tlvs.ipv4_addrs + && listcount(tlvs.ipv4_addrs)) { + v4_usable = 1; + } - if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR))) - zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n", - circuit->interface->name); + if (found & TLVFLAG_IPV6_ADDR) { + /* TBA: check that we have a linklocal ourselves? */ + struct listnode *node; + struct in6_addr *ip; + for (ALL_LIST_ELEMENTS_RO(tlvs.ipv6_addrs, node, ip)) + if (IN6_IS_ADDR_LINKLOCAL(ip)) { + v6_usable = 1; + break; + } + + if (!v6_usable) + zlog_warn( + "ISIS-Adj: IPv6 addresses present but no link-local " + "in LAN IIH from %s\n", + circuit->interface->name); + } - if (!v6_usable && !v4_usable) - { - free_tlvs (&tlvs); - return ISIS_WARNING; - } + if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR))) + zlog_warn( + "ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n", + circuit->interface->name); + if (!v6_usable && !v4_usable) { + free_tlvs(&tlvs); + return ISIS_WARNING; + } - adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]); - if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) || - (adj->level != level)) - { - if (!adj) - { - /* - * Do as in 8.4.2.5 - */ - adj = isis_new_adj (hdr.source_id, ssnpa, level, circuit); - if (adj == NULL) - { - retval = ISIS_ERROR; - goto out; - } - } - else - { - if (ssnpa) { - memcpy (adj->snpa, ssnpa, 6); - } else { - memset (adj->snpa, ' ', 6); - } - adj->level = level; - } - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); - - if (level == IS_LEVEL_1) - adj->sys_type = ISIS_SYSTYPE_L1_IS; - else - adj->sys_type = ISIS_SYSTYPE_L2_IS; - list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]); - isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1], - circuit->u.bc.lan_neighs[level - 1]); - } - if(adj->dis_record[level-1].dis==ISIS_IS_DIS) - switch (level) - { - case 1: - if (memcmp (circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1)) - { - thread_add_event(master, isis_event_dis_status_change, circuit, 0, - NULL); - memcpy (&circuit->u.bc.l1_desig_is, hdr.lan_id, - ISIS_SYS_ID_LEN + 1); - } - break; - case 2: - if (memcmp (circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1)) - { - thread_add_event(master, isis_event_dis_status_change, circuit, 0, - NULL); - memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id, - ISIS_SYS_ID_LEN + 1); - } - break; - } - - adj->hold_time = hdr.hold_time; - adj->last_upd = time (NULL); - adj->prio[level - 1] = hdr.prio; - - memcpy (adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1); - - tlvs_to_adj_area_addrs (&tlvs, adj); - - /* which protocol are spoken ??? */ - if (tlvs_to_adj_nlpids (&tlvs, adj)) - { - retval = ISIS_WARNING; - goto out; - } + adj = isis_adj_lookup(hdr.source_id, circuit->u.bc.adjdb[level - 1]); + if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) + || (adj->level != level)) { + if (!adj) { + /* + * Do as in 8.4.2.5 + */ + adj = isis_new_adj(hdr.source_id, ssnpa, level, + circuit); + if (adj == NULL) { + retval = ISIS_ERROR; + goto out; + } + } else { + if (ssnpa) { + memcpy(adj->snpa, ssnpa, 6); + } else { + memset(adj->snpa, ' ', 6); + } + adj->level = level; + } + isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); - /* we need to copy addresses to the adj */ - if (found & TLVFLAG_IPV4_ADDR) - tlvs_to_adj_ipv4_addrs (&tlvs, adj); + if (level == IS_LEVEL_1) + adj->sys_type = ISIS_SYSTYPE_L1_IS; + else + adj->sys_type = ISIS_SYSTYPE_L2_IS; + list_delete_all_node(circuit->u.bc.lan_neighs[level - 1]); + isis_adj_build_neigh_list(circuit->u.bc.adjdb[level - 1], + circuit->u.bc.lan_neighs[level - 1]); + } - if (found & TLVFLAG_IPV6_ADDR) - tlvs_to_adj_ipv6_addrs (&tlvs, adj); + if (adj->dis_record[level - 1].dis == ISIS_IS_DIS) + switch (level) { + case 1: + if (memcmp(circuit->u.bc.l1_desig_is, hdr.lan_id, + ISIS_SYS_ID_LEN + 1)) { + thread_add_event(master, + isis_event_dis_status_change, + circuit, 0, NULL); + memcpy(&circuit->u.bc.l1_desig_is, hdr.lan_id, + ISIS_SYS_ID_LEN + 1); + } + break; + case 2: + if (memcmp(circuit->u.bc.l2_desig_is, hdr.lan_id, + ISIS_SYS_ID_LEN + 1)) { + thread_add_event(master, + isis_event_dis_status_change, + circuit, 0, NULL); + memcpy(&circuit->u.bc.l2_desig_is, hdr.lan_id, + ISIS_SYS_ID_LEN + 1); + } + break; + } - adj->circuit_t = hdr.circuit_t; + adj->hold_time = hdr.hold_time; + adj->last_upd = time(NULL); + adj->prio[level - 1] = hdr.prio; - bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj); + memcpy(adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1); - /* lets take care of the expiry */ - THREAD_TIMER_OFF (adj->t_expire); - thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, - &adj->t_expire); + tlvs_to_adj_area_addrs(&tlvs, adj); - /* - * If the snpa for this circuit is found from LAN Neighbours TLV - * we have two-way communication -> adjacency can be put to state "up" - */ + /* which protocol are spoken ??? */ + if (tlvs_to_adj_nlpids(&tlvs, adj)) { + retval = ISIS_WARNING; + goto out; + } - if (found & TLVFLAG_LAN_NEIGHS) - { - if (adj->adj_state != ISIS_ADJ_UP) - { - for (ALL_LIST_ELEMENTS_RO (tlvs.lan_neighs, node, snpa)) - { - if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN)) - { - isis_adj_state_change (adj, ISIS_ADJ_UP, - "own SNPA found in LAN Neighbours TLV"); - } - } - } - else - { - int found = 0; - for (ALL_LIST_ELEMENTS_RO (tlvs.lan_neighs, node, snpa)) - if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN)) - { - found = 1; - break; - } - if (found == 0) - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, - "own SNPA not found in LAN Neighbours TLV"); - } - } - else if (adj->adj_state == ISIS_ADJ_UP) - { - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, - "no LAN Neighbours TLV found"); - } + /* we need to copy addresses to the adj */ + if (found & TLVFLAG_IPV4_ADDR) + tlvs_to_adj_ipv4_addrs(&tlvs, adj); + + if (found & TLVFLAG_IPV6_ADDR) + tlvs_to_adj_ipv6_addrs(&tlvs, adj); + + adj->circuit_t = hdr.circuit_t; + + bool mt_set_changed = + tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj); + + /* lets take care of the expiry */ + THREAD_TIMER_OFF(adj->t_expire); + thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, + &adj->t_expire); + + /* + * If the snpa for this circuit is found from LAN Neighbours TLV + * we have two-way communication -> adjacency can be put to state "up" + */ + + if (found & TLVFLAG_LAN_NEIGHS) { + if (adj->adj_state != ISIS_ADJ_UP) { + for (ALL_LIST_ELEMENTS_RO(tlvs.lan_neighs, node, + snpa)) { + if (!memcmp(snpa, circuit->u.bc.snpa, + ETH_ALEN)) { + isis_adj_state_change( + adj, ISIS_ADJ_UP, + "own SNPA found in LAN Neighbours TLV"); + } + } + } else { + int found = 0; + for (ALL_LIST_ELEMENTS_RO(tlvs.lan_neighs, node, snpa)) + if (!memcmp(snpa, circuit->u.bc.snpa, + ETH_ALEN)) { + found = 1; + break; + } + if (found == 0) + isis_adj_state_change( + adj, ISIS_ADJ_INITIALIZING, + "own SNPA not found in LAN Neighbours TLV"); + } + } else if (adj->adj_state == ISIS_ADJ_UP) { + isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, + "no LAN Neighbours TLV found"); + } - if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed) - lsp_regenerate_schedule(adj->circuit->area, level, 0); + if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed) + lsp_regenerate_schedule(adj->circuit->area, level, 0); out: - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " - "cirID %u, length %zd", - circuit->area->area_tag, - level, snpa_print (ssnpa), circuit->interface->name, - circuit_t2string (circuit->is_type), - circuit->circuit_id, - stream_get_endp (circuit->rcv_stream)); - } + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_debug( + "ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " + "cirID %u, length %zd", + circuit->area->area_tag, level, snpa_print(ssnpa), + circuit->interface->name, + circuit_t2string(circuit->is_type), circuit->circuit_id, + stream_get_endp(circuit->rcv_stream)); + } - free_tlvs (&tlvs); + free_tlvs(&tlvs); - return retval; + return retval; } /* @@ -1235,364 +1180,363 @@ out: * ISO - 10589 * Section 7.3.15.1 - Action on receipt of a link state PDU */ -static int -process_lsp (int level, struct isis_circuit *circuit, const u_char *ssnpa) +static int process_lsp(int level, struct isis_circuit *circuit, + const u_char *ssnpa) { - struct isis_link_state_hdr *hdr; - struct isis_adjacency *adj = NULL; - struct isis_lsp *lsp, *lsp0 = NULL; - int retval = ISIS_OK, comp = 0; - u_char lspid[ISIS_SYS_ID_LEN + 2]; - struct isis_passwd *passwd; - uint16_t pdu_len; - int lsp_confusion; - - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, circuit->interface->name, - circuit_t2string (circuit->is_type), circuit->circuit_id); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->rcv_stream), - stream_get_endp (circuit->rcv_stream)); - } - - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_LSP_HDR_LEN) - { - zlog_warn ("Packet too short"); - return ISIS_WARNING; - } - - /* Reference the header */ - hdr = (struct isis_link_state_hdr *) STREAM_PNT (circuit->rcv_stream); - pdu_len = ntohs (hdr->pdu_len); - - /* lsp length check */ - if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN) || - pdu_len > ISO_MTU(circuit) || - pdu_len > stream_get_endp (circuit->rcv_stream)) - { - zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP length %d", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), pdu_len); - - return ISIS_WARNING; - } - - /* - * Set the stream endp to PDU length, ignoring additional padding - * introduced by transport chips. - */ - if (pdu_len < stream_get_endp (circuit->rcv_stream)) - stream_set_endp (circuit->rcv_stream, pdu_len); + struct isis_link_state_hdr *hdr; + struct isis_adjacency *adj = NULL; + struct isis_lsp *lsp, *lsp0 = NULL; + int retval = ISIS_OK, comp = 0; + u_char lspid[ISIS_SYS_ID_LEN + 2]; + struct isis_passwd *passwd; + uint16_t pdu_len; + int lsp_confusion; + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u", + circuit->area->area_tag, level, + circuit->interface->name, + circuit_t2string(circuit->is_type), + circuit->circuit_id); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->rcv_stream), + stream_get_endp(circuit->rcv_stream)); + } - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug ("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, " - "lifetime %us, len %u, on %s", - circuit->area->area_tag, - level, - rawlspid_print (hdr->lsp_id), - ntohl (hdr->seq_num), - ntohs (hdr->checksum), - ntohs (hdr->rem_lifetime), - pdu_len, - circuit->interface->name); - } + if ((stream_get_endp(circuit->rcv_stream) + - stream_get_getp(circuit->rcv_stream)) + < ISIS_LSP_HDR_LEN) { + zlog_warn("Packet too short"); + return ISIS_WARNING; + } - /* lsp is_type check */ - if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1 && - (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2) - { - zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP is type %x", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), hdr->lsp_bits); - /* continue as per RFC1122 Be liberal in what you accept, and - * conservative in what you send */ - } + /* Reference the header */ + hdr = (struct isis_link_state_hdr *)STREAM_PNT(circuit->rcv_stream); + pdu_len = ntohs(hdr->pdu_len); - /* Checksum sanity check - FIXME: move to correct place */ - /* 12 = sysid+pdu+remtime */ - if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4, - pdu_len - 12, hdr->checksum, - offsetof(struct isis_link_state_hdr, checksum) - 4)) - { - zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), ntohs (hdr->checksum)); + /* lsp length check */ + if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN) + || pdu_len > ISO_MTU(circuit) + || pdu_len > stream_get_endp(circuit->rcv_stream)) { + zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %d", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + pdu_len); - return ISIS_WARNING; - } + return ISIS_WARNING; + } - /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */ - if (circuit->ext_domain) - { - zlog_debug - ("ISIS-Upd (%s): LSP %s received at level %d over circuit with " - "externalDomain = true", circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), level); + /* + * Set the stream endp to PDU length, ignoring additional padding + * introduced by transport chips. + */ + if (pdu_len < stream_get_endp(circuit->rcv_stream)) + stream_set_endp(circuit->rcv_stream, pdu_len); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, " + "lifetime %us, len %u, on %s", + circuit->area->area_tag, level, + rawlspid_print(hdr->lsp_id), ntohl(hdr->seq_num), + ntohs(hdr->checksum), ntohs(hdr->rem_lifetime), pdu_len, + circuit->interface->name); + } - return ISIS_WARNING; - } + /* lsp is_type check */ + if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1 + && (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2) { + zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP is type %x", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + hdr->lsp_bits); + /* continue as per RFC1122 Be liberal in what you accept, and + * conservative in what you send */ + } - /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */ - if (!accept_level (level, circuit->is_type)) - { - zlog_debug ("ISIS-Upd (%s): LSP %s received at level %d over circuit of" - " type %s", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), - level, circuit_t2string (circuit->is_type)); + /* Checksum sanity check - FIXME: move to correct place */ + /* 12 = sysid+pdu+remtime */ + if (iso_csum_verify(STREAM_PNT(circuit->rcv_stream) + 4, pdu_len - 12, + hdr->checksum, + offsetof(struct isis_link_state_hdr, checksum) + - 4)) { + zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + ntohs(hdr->checksum)); + + return ISIS_WARNING; + } - return ISIS_WARNING; - } + /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */ + if (circuit->ext_domain) { + zlog_debug( + "ISIS-Upd (%s): LSP %s received at level %d over circuit with " + "externalDomain = true", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + level); - /* 7.3.15.1 a) 4 - need to make sure IDLength matches */ + return ISIS_WARNING; + } - /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use 3 */ + /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */ + if (!accept_level(level, circuit->is_type)) { + zlog_debug( + "ISIS-Upd (%s): LSP %s received at level %d over circuit of" + " type %s", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + level, circuit_t2string(circuit->is_type)); - /* 7.3.15.1 a) 7 - password check */ - (level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd) : - (passwd = &circuit->area->domain_passwd); - if (passwd->type) - { - if (lsp_authentication_check (circuit->rcv_stream, circuit->area, - level, passwd)) - { - isis_event_auth_failure (circuit->area->area_tag, - "LSP authentication failure", hdr->lsp_id); - return ISIS_WARNING; + return ISIS_WARNING; } - } - /* Find the LSP in our database and compare it to this Link State header */ - lsp = lsp_search (hdr->lsp_id, circuit->area->lspdb[level - 1]); - if (lsp) - comp = lsp_compare (circuit->area->area_tag, lsp, hdr->seq_num, - hdr->checksum, hdr->rem_lifetime); - if (lsp && (lsp->own_lsp)) - goto dontcheckadj; - - /* 7.3.15.1 a) 6 - Must check that we have an adjacency of the same level */ - /* for broadcast circuits, snpa should be compared */ - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - adj = isis_adj_lookup_snpa (ssnpa, circuit->u.bc.adjdb[level - 1]); - if (!adj) - { - zlog_debug ("(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, " - "lifetime %us on %s", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), - ntohl (hdr->seq_num), - ntohs (hdr->checksum), - ntohs (hdr->rem_lifetime), circuit->interface->name); - return ISIS_WARNING; /* Silently discard */ + + /* 7.3.15.1 a) 4 - need to make sure IDLength matches */ + + /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use + * 3 */ + + /* 7.3.15.1 a) 7 - password check */ + (level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd) + : (passwd = &circuit->area->domain_passwd); + if (passwd->type) { + if (lsp_authentication_check(circuit->rcv_stream, circuit->area, + level, passwd)) { + isis_event_auth_failure(circuit->area->area_tag, + "LSP authentication failure", + hdr->lsp_id); + return ISIS_WARNING; + } } - } - /* for non broadcast, we just need to find same level adj */ - else - { - /* If no adj, or no sharing of level */ - if (!circuit->u.p2p.neighbor) - { - return ISIS_OK; /* Silently discard */ + /* Find the LSP in our database and compare it to this Link State header + */ + lsp = lsp_search(hdr->lsp_id, circuit->area->lspdb[level - 1]); + if (lsp) + comp = lsp_compare(circuit->area->area_tag, lsp, hdr->seq_num, + hdr->checksum, hdr->rem_lifetime); + if (lsp && (lsp->own_lsp)) + goto dontcheckadj; + + /* 7.3.15.1 a) 6 - Must check that we have an adjacency of the same + * level */ + /* for broadcast circuits, snpa should be compared */ + + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + adj = isis_adj_lookup_snpa(ssnpa, + circuit->u.bc.adjdb[level - 1]); + if (!adj) { + zlog_debug( + "(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, " + "lifetime %us on %s", + circuit->area->area_tag, + rawlspid_print(hdr->lsp_id), + ntohl(hdr->seq_num), ntohs(hdr->checksum), + ntohs(hdr->rem_lifetime), + circuit->interface->name); + return ISIS_WARNING; /* Silently discard */ + } } - else - { - if (((level == IS_LEVEL_1) && - (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL2)) || - ((level == IS_LEVEL_2) && - (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL1))) - return ISIS_WARNING; /* Silently discard */ + /* for non broadcast, we just need to find same level adj */ + else { + /* If no adj, or no sharing of level */ + if (!circuit->u.p2p.neighbor) { + return ISIS_OK; /* Silently discard */ + } else { + if (((level == IS_LEVEL_1) + && (circuit->u.p2p.neighbor->adj_usage + == ISIS_ADJ_LEVEL2)) + || ((level == IS_LEVEL_2) + && (circuit->u.p2p.neighbor->adj_usage + == ISIS_ADJ_LEVEL1))) + return ISIS_WARNING; /* Silently discard */ + } } - } dontcheckadj: - /* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */ - - /* 7.3.15.1 a) 8 - Passwords for level 2 - not implemented */ - - /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do it */ - - /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num but - * wrong checksum, initiate a purge. */ - if (lsp - && (lsp->lsp_header->seq_num == hdr->seq_num) - && (lsp->lsp_header->checksum != hdr->checksum)) - { - zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.", - circuit->area->area_tag, rawlspid_print(hdr->lsp_id), - ntohl(hdr->seq_num)); - hdr->rem_lifetime = 0; - lsp_confusion = 1; - } - else - lsp_confusion = 0; - - /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */ - if (hdr->rem_lifetime == 0) - { - if (!lsp) - { - /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't save */ - /* only needed on explicit update, eg - p2p */ - if (circuit->circ_type == CIRCUIT_T_P2P) - ack_lsp (hdr, circuit, level); - return retval; /* FIXME: do we need a purge? */ - } - else - { - if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) - { - /* LSP by some other system -> do 7.3.16.4 b) */ - /* 7.3.16.4 b) 1) */ - if (comp == LSP_NEWER) - { - lsp_update (lsp, circuit->rcv_stream, circuit->area, level); - /* ii */ - lsp_set_all_srmflags (lsp); - /* v */ - ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c */ - - /* For the case of lsp confusion, flood the purge back to its - * originator so that it can react. Otherwise, don't reflood - * through incoming circuit as usual */ - if (!lsp_confusion) - { - /* iii */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - /* iv */ - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - ISIS_SET_FLAG (lsp->SSNflags, circuit); - } - } /* 7.3.16.4 b) 2) */ - else if (comp == LSP_EQUAL) - { - /* i */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - /* ii */ - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - ISIS_SET_FLAG (lsp->SSNflags, circuit); - } /* 7.3.16.4 b) 3) */ - else - { - ISIS_SET_FLAG (lsp->SRMflags, circuit); - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); + /* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */ + + /* 7.3.15.1 a) 8 - Passwords for level 2 - not implemented */ + + /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do + * it */ + + /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num + * but + * wrong checksum, initiate a purge. */ + if (lsp && (lsp->lsp_header->seq_num == hdr->seq_num) + && (lsp->lsp_header->checksum != hdr->checksum)) { + zlog_warn( + "ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.", + circuit->area->area_tag, rawlspid_print(hdr->lsp_id), + ntohl(hdr->seq_num)); + hdr->rem_lifetime = 0; + lsp_confusion = 1; + } else + lsp_confusion = 0; + + /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */ + if (hdr->rem_lifetime == 0) { + if (!lsp) { + /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't + * save */ + /* only needed on explicit update, eg - p2p */ + if (circuit->circ_type == CIRCUIT_T_P2P) + ack_lsp(hdr, circuit, level); + return retval; /* FIXME: do we need a purge? */ + } else { + if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) { + /* LSP by some other system -> do 7.3.16.4 b) */ + /* 7.3.16.4 b) 1) */ + if (comp == LSP_NEWER) { + lsp_update(lsp, circuit->rcv_stream, + circuit->area, level); + /* ii */ + lsp_set_all_srmflags(lsp); + /* v */ + ISIS_FLAGS_CLEAR_ALL( + lsp + ->SSNflags); /* FIXME: + OTHER + than c + */ + + /* For the case of lsp confusion, flood + * the purge back to its + * originator so that it can react. + * Otherwise, don't reflood + * through incoming circuit as usual */ + if (!lsp_confusion) { + /* iii */ + ISIS_CLEAR_FLAG(lsp->SRMflags, + circuit); + /* iv */ + if (circuit->circ_type + != CIRCUIT_T_BROADCAST) + ISIS_SET_FLAG( + lsp->SSNflags, + circuit); + } + } /* 7.3.16.4 b) 2) */ + else if (comp == LSP_EQUAL) { + /* i */ + ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + /* ii */ + if (circuit->circ_type + != CIRCUIT_T_BROADCAST) + ISIS_SET_FLAG(lsp->SSNflags, + circuit); + } /* 7.3.16.4 b) 3) */ + else { + ISIS_SET_FLAG(lsp->SRMflags, circuit); + ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); + } + } else if (lsp->lsp_header->rem_lifetime != 0) { + /* our own LSP -> 7.3.16.4 c) */ + if (comp == LSP_NEWER) { + lsp_inc_seqnum(lsp, + ntohl(hdr->seq_num)); + lsp_set_all_srmflags(lsp); + } else { + ISIS_SET_FLAG(lsp->SRMflags, circuit); + ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); + } + if (isis->debugs & DEBUG_UPDATE_PACKETS) + zlog_debug( + "ISIS-Upd (%s): (1) re-originating LSP %s new " + "seq 0x%08x", + circuit->area->area_tag, + rawlspid_print(hdr->lsp_id), + ntohl(lsp->lsp_header + ->seq_num)); + } } - } - else if (lsp->lsp_header->rem_lifetime != 0) - { - /* our own LSP -> 7.3.16.4 c) */ - if (comp == LSP_NEWER) - { - lsp_inc_seqnum (lsp, ntohl (hdr->seq_num)); - lsp_set_all_srmflags (lsp); - } - else - { - ISIS_SET_FLAG (lsp->SRMflags, circuit); - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); - } - if (isis->debugs & DEBUG_UPDATE_PACKETS) - zlog_debug ("ISIS-Upd (%s): (1) re-originating LSP %s new " - "seq 0x%08x", circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), - ntohl (lsp->lsp_header->seq_num)); - } - } - return retval; - } - /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a - * purge */ - if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) - { - if (!lsp) - { - /* 7.3.16.4: initiate a purge */ - lsp_purge_non_exist(level, hdr, circuit->area); - return ISIS_OK; + return retval; } - /* 7.3.15.1 d) - If this is our own lsp and we have it */ - - /* In 7.3.16.1, If an Intermediate system R somewhere in the domain - * has information that the current sequence number for source S is - * "greater" than that held by S, ... */ - - if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num)) - { - /* 7.3.16.1 */ - lsp_inc_seqnum (lsp, ntohl (hdr->seq_num)); - if (isis->debugs & DEBUG_UPDATE_PACKETS) - zlog_debug ("ISIS-Upd (%s): (2) re-originating LSP %s new seq " - "0x%08x", circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), - ntohl (lsp->lsp_header->seq_num)); - } - /* If the received LSP is older or equal, - * resend the LSP which will act as ACK */ - lsp_set_all_srmflags (lsp); - } - else - { - /* 7.3.15.1 e) - This lsp originated on another system */ - - /* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db */ - if ((!lsp || comp == LSP_NEWER)) - { - /* - * If this lsp is a frag, need to see if we have zero lsp present - */ - if (LSP_FRAGMENT (hdr->lsp_id) != 0) - { - memcpy (lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT (lspid) = 0; - lsp0 = lsp_search (lspid, circuit->area->lspdb[level - 1]); - if (!lsp0) - { - zlog_debug ("Got lsp frag, while zero lsp not in database"); - return ISIS_OK; + /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a + * purge */ + if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) { + if (!lsp) { + /* 7.3.16.4: initiate a purge */ + lsp_purge_non_exist(level, hdr, circuit->area); + return ISIS_OK; + } + /* 7.3.15.1 d) - If this is our own lsp and we have it */ + + /* In 7.3.16.1, If an Intermediate system R somewhere in the + * domain + * has information that the current sequence number for source S + * is + * "greater" than that held by S, ... */ + + if (ntohl(hdr->seq_num) > ntohl(lsp->lsp_header->seq_num)) { + /* 7.3.16.1 */ + lsp_inc_seqnum(lsp, ntohl(hdr->seq_num)); + if (isis->debugs & DEBUG_UPDATE_PACKETS) + zlog_debug( + "ISIS-Upd (%s): (2) re-originating LSP %s new seq " + "0x%08x", + circuit->area->area_tag, + rawlspid_print(hdr->lsp_id), + ntohl(lsp->lsp_header->seq_num)); + } + /* If the received LSP is older or equal, + * resend the LSP which will act as ACK */ + lsp_set_all_srmflags(lsp); + } else { + /* 7.3.15.1 e) - This lsp originated on another system */ + + /* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db + */ + if ((!lsp || comp == LSP_NEWER)) { + /* + * If this lsp is a frag, need to see if we have zero + * lsp present + */ + if (LSP_FRAGMENT(hdr->lsp_id) != 0) { + memcpy(lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(lspid) = 0; + lsp0 = lsp_search( + lspid, circuit->area->lspdb[level - 1]); + if (!lsp0) { + zlog_debug( + "Got lsp frag, while zero lsp not in database"); + return ISIS_OK; + } + } + /* i */ + if (!lsp) { + lsp = lsp_new_from_stream_ptr( + circuit->rcv_stream, pdu_len, lsp0, + circuit->area, level); + lsp_insert(lsp, + circuit->area->lspdb[level - 1]); + } else /* exists, so we overwrite */ + { + lsp_update(lsp, circuit->rcv_stream, + circuit->area, level); + } + /* ii */ + lsp_set_all_srmflags(lsp); + /* iii */ + ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + + /* iv */ + if (circuit->circ_type != CIRCUIT_T_BROADCAST) + ISIS_SET_FLAG(lsp->SSNflags, circuit); + /* FIXME: v) */ + } + /* 7.3.15.1 e) 2) LSP equal to the one in db */ + else if (comp == LSP_EQUAL) { + ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + lsp_update(lsp, circuit->rcv_stream, circuit->area, + level); + if (circuit->circ_type != CIRCUIT_T_BROADCAST) + ISIS_SET_FLAG(lsp->SSNflags, circuit); + } + /* 7.3.15.1 e) 3) LSP older than the one in db */ + else { + ISIS_SET_FLAG(lsp->SRMflags, circuit); + ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } - } - /* i */ - if (!lsp) - { - lsp = lsp_new_from_stream_ptr (circuit->rcv_stream, - pdu_len, lsp0, - circuit->area, level); - lsp_insert (lsp, circuit->area->lspdb[level - 1]); - } - else /* exists, so we overwrite */ - { - lsp_update (lsp, circuit->rcv_stream, circuit->area, level); - } - /* ii */ - lsp_set_all_srmflags (lsp); - /* iii */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - - /* iv */ - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - ISIS_SET_FLAG (lsp->SSNflags, circuit); - /* FIXME: v) */ - } - /* 7.3.15.1 e) 2) LSP equal to the one in db */ - else if (comp == LSP_EQUAL) - { - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - lsp_update (lsp, circuit->rcv_stream, circuit->area, level); - if (circuit->circ_type != CIRCUIT_T_BROADCAST) - ISIS_SET_FLAG (lsp->SSNflags, circuit); - } - /* 7.3.15.1 e) 3) LSP older than the one in db */ - else - { - ISIS_SET_FLAG (lsp->SRMflags, circuit); - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); } - } - return retval; + return retval; } /* @@ -1601,1570 +1545,1528 @@ dontcheckadj: * Section 7.3.15.2 - Action on receipt of a sequence numbers PDU */ -static int -process_snp (int snp_type, int level, struct isis_circuit *circuit, - const u_char *ssnpa) +static int process_snp(int snp_type, int level, struct isis_circuit *circuit, + const u_char *ssnpa) { - int retval = ISIS_OK; - int cmp, own_lsp; - char typechar = ' '; - uint16_t pdu_len; - struct isis_adjacency *adj; - struct isis_complete_seqnum_hdr *chdr = NULL; - struct isis_partial_seqnum_hdr *phdr = NULL; - uint32_t found = 0, expected = 0, auth_tlv_offset = 0; - struct isis_lsp *lsp; - struct lsp_entry *entry; - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct tlvs tlvs; - struct list *lsp_list = NULL; - struct isis_passwd *passwd; - - if (snp_type == ISIS_SNP_CSNP_FLAG) - { - /* getting the header info */ - typechar = 'C'; - chdr = - (struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); - stream_forward_getp (circuit->rcv_stream, ISIS_CSNP_HDRLEN); - pdu_len = ntohs (chdr->pdu_len); - if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_CSNP_HDRLEN) || - pdu_len > ISO_MTU(circuit) || - pdu_len > stream_get_endp (circuit->rcv_stream)) - { - zlog_warn ("Received a CSNP with bogus length %d", pdu_len); - return ISIS_WARNING; - } - } - else - { - typechar = 'P'; - phdr = - (struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); - stream_forward_getp (circuit->rcv_stream, ISIS_PSNP_HDRLEN); - pdu_len = ntohs (phdr->pdu_len); - if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_PSNP_HDRLEN) || - pdu_len > ISO_MTU(circuit) || - pdu_len > stream_get_endp (circuit->rcv_stream)) - { - zlog_warn ("Received a PSNP with bogus length %d", pdu_len); - return ISIS_WARNING; + int retval = ISIS_OK; + int cmp, own_lsp; + char typechar = ' '; + uint16_t pdu_len; + struct isis_adjacency *adj; + struct isis_complete_seqnum_hdr *chdr = NULL; + struct isis_partial_seqnum_hdr *phdr = NULL; + uint32_t found = 0, expected = 0, auth_tlv_offset = 0; + struct isis_lsp *lsp; + struct lsp_entry *entry; + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct tlvs tlvs; + struct list *lsp_list = NULL; + struct isis_passwd *passwd; + + if (snp_type == ISIS_SNP_CSNP_FLAG) { + /* getting the header info */ + typechar = 'C'; + chdr = (struct isis_complete_seqnum_hdr *)STREAM_PNT( + circuit->rcv_stream); + stream_forward_getp(circuit->rcv_stream, ISIS_CSNP_HDRLEN); + pdu_len = ntohs(chdr->pdu_len); + if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_CSNP_HDRLEN) + || pdu_len > ISO_MTU(circuit) + || pdu_len > stream_get_endp(circuit->rcv_stream)) { + zlog_warn("Received a CSNP with bogus length %d", + pdu_len); + return ISIS_WARNING; + } + } else { + typechar = 'P'; + phdr = (struct isis_partial_seqnum_hdr *)STREAM_PNT( + circuit->rcv_stream); + stream_forward_getp(circuit->rcv_stream, ISIS_PSNP_HDRLEN); + pdu_len = ntohs(phdr->pdu_len); + if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_PSNP_HDRLEN) + || pdu_len > ISO_MTU(circuit) + || pdu_len > stream_get_endp(circuit->rcv_stream)) { + zlog_warn("Received a PSNP with bogus length %d", + pdu_len); + return ISIS_WARNING; + } } - } - - /* - * Set the stream endp to PDU length, ignoring additional padding - * introduced by transport chips. - */ - if (pdu_len < stream_get_endp (circuit->rcv_stream)) - stream_set_endp (circuit->rcv_stream, pdu_len); - /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */ - if (circuit->ext_domain) - { - - zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " - "skipping: circuit externalDomain = true", - circuit->area->area_tag, - level, typechar, circuit->interface->name); + /* + * Set the stream endp to PDU length, ignoring additional padding + * introduced by transport chips. + */ + if (pdu_len < stream_get_endp(circuit->rcv_stream)) + stream_set_endp(circuit->rcv_stream, pdu_len); - return ISIS_OK; - } + /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */ + if (circuit->ext_domain) { - /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */ - if (!accept_level (level, circuit->is_type)) - { + zlog_debug( + "ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " + "skipping: circuit externalDomain = true", + circuit->area->area_tag, level, typechar, + circuit->interface->name); - zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " - "skipping: circuit type %s does not match level %d", - circuit->area->area_tag, - level, - typechar, - circuit->interface->name, - circuit_t2string (circuit->is_type), level); - - return ISIS_OK; - } - - /* 7.3.15.2 a) 4 - not applicable for CSNP only PSNPs on broadcast */ - if ((snp_type == ISIS_SNP_PSNP_FLAG) && - (circuit->circ_type == CIRCUIT_T_BROADCAST) && - (!circuit->u.bc.is_dr[level - 1])) - { - zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, " - "skipping: we are not the DIS", - circuit->area->area_tag, - level, - typechar, snpa_print (ssnpa), circuit->interface->name); - - return ISIS_OK; - } + return ISIS_OK; + } - /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked */ + /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */ + if (!accept_level(level, circuit->is_type)) { - /* 7.3.15.2 a) 6 - maximum area match, can be ommited since we only use 3 - * - already checked */ + zlog_debug( + "ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " + "skipping: circuit type %s does not match level %d", + circuit->area->area_tag, level, typechar, + circuit->interface->name, + circuit_t2string(circuit->is_type), level); - /* 7.3.15.2 a) 7 - Must check that we have an adjacency of the same level */ - /* for broadcast circuits, snpa should be compared */ - /* FIXME : Do we need to check SNPA? */ - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - if (snp_type == ISIS_SNP_CSNP_FLAG) - { - adj = - isis_adj_lookup (chdr->source_id, circuit->u.bc.adjdb[level - 1]); - } - else - { - /* a psnp on a broadcast, how lovely of Juniper :) */ - adj = - isis_adj_lookup (phdr->source_id, circuit->u.bc.adjdb[level - 1]); + return ISIS_OK; } - if (!adj) - return ISIS_OK; /* Silently discard */ - } - else - { - if (!circuit->u.p2p.neighbor) - { - zlog_warn ("no p2p neighbor on circuit %s", circuit->interface->name); - return ISIS_OK; /* Silently discard */ - } - } - /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented */ - - /* 7.3.15.2 a) 9 - Passwords for level 2 - not implemented */ + /* 7.3.15.2 a) 4 - not applicable for CSNP only PSNPs on broadcast */ + if ((snp_type == ISIS_SNP_PSNP_FLAG) + && (circuit->circ_type == CIRCUIT_T_BROADCAST) + && (!circuit->u.bc.is_dr[level - 1])) { + zlog_debug( + "ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, " + "skipping: we are not the DIS", + circuit->area->area_tag, level, typechar, + snpa_print(ssnpa), circuit->interface->name); + + return ISIS_OK; + } - memset (&tlvs, 0, sizeof (struct tlvs)); + /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked + */ + + /* 7.3.15.2 a) 6 - maximum area match, can be ommited since we only use + * 3 + * - already checked */ + + /* 7.3.15.2 a) 7 - Must check that we have an adjacency of the same + * level */ + /* for broadcast circuits, snpa should be compared */ + /* FIXME : Do we need to check SNPA? */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + if (snp_type == ISIS_SNP_CSNP_FLAG) { + adj = isis_adj_lookup(chdr->source_id, + circuit->u.bc.adjdb[level - 1]); + } else { + /* a psnp on a broadcast, how lovely of Juniper :) */ + adj = isis_adj_lookup(phdr->source_id, + circuit->u.bc.adjdb[level - 1]); + } + if (!adj) + return ISIS_OK; /* Silently discard */ + } else { + if (!circuit->u.p2p.neighbor) { + zlog_warn("no p2p neighbor on circuit %s", + circuit->interface->name); + return ISIS_OK; /* Silently discard */ + } + } - /* parse the SNP */ - expected |= TLVFLAG_LSP_ENTRIES; - expected |= TLVFLAG_AUTH_INFO; + /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented */ - auth_tlv_offset = stream_get_getp (circuit->rcv_stream); - retval = parse_tlvs (circuit->area->area_tag, - STREAM_PNT (circuit->rcv_stream), - pdu_len - stream_get_getp (circuit->rcv_stream), - &expected, &found, &tlvs, &auth_tlv_offset); + /* 7.3.15.2 a) 9 - Passwords for level 2 - not implemented */ - if (retval > ISIS_WARNING) - { - zlog_warn ("something went very wrong processing SNP"); - free_tlvs (&tlvs); - return retval; - } + memset(&tlvs, 0, sizeof(struct tlvs)); - if (level == IS_LEVEL_1) - passwd = &circuit->area->area_passwd; - else - passwd = &circuit->area->domain_passwd; + /* parse the SNP */ + expected |= TLVFLAG_LSP_ENTRIES; + expected |= TLVFLAG_AUTH_INFO; - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) - { - if (passwd->type) - { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (&tlvs.auth_info, passwd, - circuit->rcv_stream, auth_tlv_offset)) - { - isis_event_auth_failure (circuit->area->area_tag, - "SNP authentication" " failure", - phdr ? phdr->source_id : - chdr->source_id); - free_tlvs (&tlvs); - return ISIS_OK; - } - } - } + auth_tlv_offset = stream_get_getp(circuit->rcv_stream); + retval = parse_tlvs(circuit->area->area_tag, + STREAM_PNT(circuit->rcv_stream), + pdu_len - stream_get_getp(circuit->rcv_stream), + &expected, &found, &tlvs, &auth_tlv_offset); - /* debug isis snp-packets */ - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s", - circuit->area->area_tag, - level, - typechar, snpa_print (ssnpa), circuit->interface->name); - if (tlvs.lsp_entries) - { - for (ALL_LIST_ELEMENTS_RO (tlvs.lsp_entries, node, entry)) - { - zlog_debug ("ISIS-Snp (%s): %cSNP entry %s, seq 0x%08x," - " cksum 0x%04x, lifetime %us", - circuit->area->area_tag, - typechar, - rawlspid_print (entry->lsp_id), - ntohl (entry->seq_num), - ntohs (entry->checksum), ntohs (entry->rem_lifetime)); - } + if (retval > ISIS_WARNING) { + zlog_warn("something went very wrong processing SNP"); + free_tlvs(&tlvs); + return retval; } - } - /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */ - if (tlvs.lsp_entries) - { - for (ALL_LIST_ELEMENTS_RO (tlvs.lsp_entries, node, entry)) - { - lsp = lsp_search (entry->lsp_id, circuit->area->lspdb[level - 1]); - own_lsp = !memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN); - if (lsp) - { - /* 7.3.15.2 b) 1) is this LSP newer */ - cmp = lsp_compare (circuit->area->area_tag, lsp, entry->seq_num, - entry->checksum, entry->rem_lifetime); - /* 7.3.15.2 b) 2) if it equals, clear SRM on p2p */ - if (cmp == LSP_EQUAL) - { - /* if (circuit->circ_type != CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - } - /* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM */ - else if (cmp == LSP_OLDER) - { - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); - ISIS_SET_FLAG (lsp->SRMflags, circuit); - } - /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p */ - else - { - if (own_lsp) - { - lsp_inc_seqnum (lsp, ntohl (entry->seq_num)); - ISIS_SET_FLAG (lsp->SRMflags, circuit); - } - else - { - ISIS_SET_FLAG (lsp->SSNflags, circuit); - /* if (circuit->circ_type != CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - } - } - } + if (level == IS_LEVEL_1) + passwd = &circuit->area->area_passwd; else - { - /* 7.3.15.2 b) 5) if it was not found, and all of those are not 0, - * insert it and set SSN on it */ - if (entry->rem_lifetime && entry->checksum && entry->seq_num && - memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) - { - lsp = lsp_new(circuit->area, entry->lsp_id, - ntohs(entry->rem_lifetime), - 0, 0, entry->checksum, level); - lsp_insert (lsp, circuit->area->lspdb[level - 1]); - ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags); - ISIS_SET_FLAG (lsp->SSNflags, circuit); - } - } - } - } + passwd = &circuit->area->domain_passwd; + + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) { + if (passwd->type) { + if (!(found & TLVFLAG_AUTH_INFO) + || authentication_check(&tlvs.auth_info, passwd, + circuit->rcv_stream, + auth_tlv_offset)) { + isis_event_auth_failure(circuit->area->area_tag, + "SNP authentication" + " failure", + phdr ? phdr->source_id + : chdr->source_id); + free_tlvs(&tlvs); + return ISIS_OK; + } + } + } - /* 7.3.15.2 c) on CSNP set SRM for all in range which were not reported */ - if (snp_type == ISIS_SNP_CSNP_FLAG) - { - /* - * Build a list from our own LSP db bounded with - * start_lsp_id and stop_lsp_id - */ - lsp_list = list_new (); - lsp_build_list_nonzero_ht (chdr->start_lsp_id, chdr->stop_lsp_id, - lsp_list, circuit->area->lspdb[level - 1]); - - /* Fixme: Find a better solution */ - if (tlvs.lsp_entries) - { - for (ALL_LIST_ELEMENTS (tlvs.lsp_entries, node, nnode, entry)) - { - for (ALL_LIST_ELEMENTS (lsp_list, node2, nnode2, lsp)) - { - if (lsp_id_cmp (lsp->lsp_header->lsp_id, entry->lsp_id) == 0) - { - list_delete_node (lsp_list, node2); - break; + /* debug isis snp-packets */ + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s", + circuit->area->area_tag, level, typechar, + snpa_print(ssnpa), circuit->interface->name); + if (tlvs.lsp_entries) { + for (ALL_LIST_ELEMENTS_RO(tlvs.lsp_entries, node, + entry)) { + zlog_debug( + "ISIS-Snp (%s): %cSNP entry %s, seq 0x%08x," + " cksum 0x%04x, lifetime %us", + circuit->area->area_tag, typechar, + rawlspid_print(entry->lsp_id), + ntohl(entry->seq_num), + ntohs(entry->checksum), + ntohs(entry->rem_lifetime)); + } } - } - } } - /* on remaining LSPs we set SRM (neighbor knew not of) */ - for (ALL_LIST_ELEMENTS_RO (lsp_list, node, lsp)) - ISIS_SET_FLAG (lsp->SRMflags, circuit); - /* lets free it */ - list_delete (lsp_list); - } + /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */ + if (tlvs.lsp_entries) { + for (ALL_LIST_ELEMENTS_RO(tlvs.lsp_entries, node, entry)) { + lsp = lsp_search(entry->lsp_id, + circuit->area->lspdb[level - 1]); + own_lsp = !memcmp(entry->lsp_id, isis->sysid, + ISIS_SYS_ID_LEN); + if (lsp) { + /* 7.3.15.2 b) 1) is this LSP newer */ + cmp = lsp_compare(circuit->area->area_tag, lsp, + entry->seq_num, + entry->checksum, + entry->rem_lifetime); + /* 7.3.15.2 b) 2) if it equals, clear SRM on p2p + */ + if (cmp == LSP_EQUAL) { + /* if (circuit->circ_type != + * CIRCUIT_T_BROADCAST) */ + ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + } + /* 7.3.15.2 b) 3) if it is older, clear SSN and + set SRM */ + else if (cmp == LSP_OLDER) { + ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); + ISIS_SET_FLAG(lsp->SRMflags, circuit); + } + /* 7.3.15.2 b) 4) if it is newer, set SSN and + clear SRM on p2p */ + else { + if (own_lsp) { + lsp_inc_seqnum( + lsp, + ntohl(entry->seq_num)); + ISIS_SET_FLAG(lsp->SRMflags, + circuit); + } else { + ISIS_SET_FLAG(lsp->SSNflags, + circuit); + /* if (circuit->circ_type != + * CIRCUIT_T_BROADCAST) */ + ISIS_CLEAR_FLAG(lsp->SRMflags, + circuit); + } + } + } else { + /* 7.3.15.2 b) 5) if it was not found, and all + * of those are not 0, + * insert it and set SSN on it */ + if (entry->rem_lifetime && entry->checksum + && entry->seq_num + && memcmp(entry->lsp_id, isis->sysid, + ISIS_SYS_ID_LEN)) { + lsp = lsp_new( + circuit->area, entry->lsp_id, + ntohs(entry->rem_lifetime), 0, + 0, entry->checksum, level); + lsp_insert(lsp, + circuit->area + ->lspdb[level - 1]); + ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + ISIS_SET_FLAG(lsp->SSNflags, circuit); + } + } + } + } - free_tlvs (&tlvs); - return retval; + /* 7.3.15.2 c) on CSNP set SRM for all in range which were not reported + */ + if (snp_type == ISIS_SNP_CSNP_FLAG) { + /* + * Build a list from our own LSP db bounded with + * start_lsp_id and stop_lsp_id + */ + lsp_list = list_new(); + lsp_build_list_nonzero_ht(chdr->start_lsp_id, chdr->stop_lsp_id, + lsp_list, + circuit->area->lspdb[level - 1]); + + /* Fixme: Find a better solution */ + if (tlvs.lsp_entries) { + for (ALL_LIST_ELEMENTS(tlvs.lsp_entries, node, nnode, + entry)) { + for (ALL_LIST_ELEMENTS(lsp_list, node2, nnode2, + lsp)) { + if (lsp_id_cmp(lsp->lsp_header->lsp_id, + entry->lsp_id) + == 0) { + list_delete_node(lsp_list, + node2); + break; + } + } + } + } + /* on remaining LSPs we set SRM (neighbor knew not of) */ + for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) + ISIS_SET_FLAG(lsp->SRMflags, circuit); + /* lets free it */ + list_delete(lsp_list); + } + + free_tlvs(&tlvs); + return retval; } -static int -process_csnp (int level, struct isis_circuit *circuit, const u_char *ssnpa) +static int process_csnp(int level, struct isis_circuit *circuit, + const u_char *ssnpa) { - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Rcvd L%d CSNP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, circuit->interface->name, - circuit_t2string (circuit->is_type), circuit->circuit_id); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->rcv_stream), - stream_get_endp (circuit->rcv_stream)); - } + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Rcvd L%d CSNP on %s, cirType %s, cirID %u", + circuit->area->area_tag, level, + circuit->interface->name, + circuit_t2string(circuit->is_type), + circuit->circuit_id); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->rcv_stream), + stream_get_endp(circuit->rcv_stream)); + } - /* Sanity check - FIXME: move to correct place */ - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_CSNP_HDRLEN) - { - zlog_warn ("Packet too short ( < %d)", ISIS_CSNP_HDRLEN); - return ISIS_WARNING; - } + /* Sanity check - FIXME: move to correct place */ + if ((stream_get_endp(circuit->rcv_stream) + - stream_get_getp(circuit->rcv_stream)) + < ISIS_CSNP_HDRLEN) { + zlog_warn("Packet too short ( < %d)", ISIS_CSNP_HDRLEN); + return ISIS_WARNING; + } - return process_snp (ISIS_SNP_CSNP_FLAG, level, circuit, ssnpa); + return process_snp(ISIS_SNP_CSNP_FLAG, level, circuit, ssnpa); } -static int -process_psnp (int level, struct isis_circuit *circuit, const u_char *ssnpa) +static int process_psnp(int level, struct isis_circuit *circuit, + const u_char *ssnpa) { - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Rcvd L%d PSNP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, circuit->interface->name, - circuit_t2string (circuit->is_type), circuit->circuit_id); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->rcv_stream), - stream_get_endp (circuit->rcv_stream)); - } + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Rcvd L%d PSNP on %s, cirType %s, cirID %u", + circuit->area->area_tag, level, + circuit->interface->name, + circuit_t2string(circuit->is_type), + circuit->circuit_id); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->rcv_stream), + stream_get_endp(circuit->rcv_stream)); + } - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_PSNP_HDRLEN) - { - zlog_warn ("Packet too short ( < %d)", ISIS_PSNP_HDRLEN); - return ISIS_WARNING; - } + if ((stream_get_endp(circuit->rcv_stream) + - stream_get_getp(circuit->rcv_stream)) + < ISIS_PSNP_HDRLEN) { + zlog_warn("Packet too short ( < %d)", ISIS_PSNP_HDRLEN); + return ISIS_WARNING; + } - return process_snp (ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa); + return process_snp(ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa); } /* * PDU Dispatcher */ -static int -isis_handle_pdu (struct isis_circuit *circuit, u_char * ssnpa) +static int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa) { - struct isis_fixed_hdr *hdr; + struct isis_fixed_hdr *hdr; - int retval = ISIS_OK; + int retval = ISIS_OK; - /* - * Let's first read data from stream to the header - */ - hdr = (struct isis_fixed_hdr *) STREAM_DATA (circuit->rcv_stream); + /* + * Let's first read data from stream to the header + */ + hdr = (struct isis_fixed_hdr *)STREAM_DATA(circuit->rcv_stream); - if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS)) - { - zlog_err ("Not an IS-IS or ES-IS packet IDRP=%02x", hdr->idrp); - return ISIS_ERROR; - } + if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS)) { + zlog_err("Not an IS-IS or ES-IS packet IDRP=%02x", hdr->idrp); + return ISIS_ERROR; + } - /* now we need to know if this is an ISO 9542 packet and - * take real good care of it, waaa! - */ - if (hdr->idrp == ISO9542_ESIS) - { - zlog_err ("No support for ES-IS packet IDRP=%02x", hdr->idrp); - return ISIS_ERROR; - } - stream_set_getp (circuit->rcv_stream, ISIS_FIXED_HDR_LEN); + /* now we need to know if this is an ISO 9542 packet and + * take real good care of it, waaa! + */ + if (hdr->idrp == ISO9542_ESIS) { + zlog_err("No support for ES-IS packet IDRP=%02x", hdr->idrp); + return ISIS_ERROR; + } + stream_set_getp(circuit->rcv_stream, ISIS_FIXED_HDR_LEN); - /* - * and then process it - */ + /* + * and then process it + */ - if (hdr->length < ISIS_MINIMUM_FIXED_HDR_LEN) - { - zlog_err ("Fixed header length = %d", hdr->length); - return ISIS_ERROR; - } + if (hdr->length < ISIS_MINIMUM_FIXED_HDR_LEN) { + zlog_err("Fixed header length = %d", hdr->length); + return ISIS_ERROR; + } - if (hdr->version1 != 1) - { - zlog_warn ("Unsupported ISIS version %u", hdr->version1); - return ISIS_WARNING; - } - /* either 6 or 0 */ - if ((hdr->id_len != 0) && (hdr->id_len != ISIS_SYS_ID_LEN)) - { - zlog_err - ("IDFieldLengthMismatch: ID Length field in a received PDU %u, " - "while the parameter for this IS is %u", hdr->id_len, - ISIS_SYS_ID_LEN); - return ISIS_ERROR; - } + if (hdr->version1 != 1) { + zlog_warn("Unsupported ISIS version %u", hdr->version1); + return ISIS_WARNING; + } + /* either 6 or 0 */ + if ((hdr->id_len != 0) && (hdr->id_len != ISIS_SYS_ID_LEN)) { + zlog_err( + "IDFieldLengthMismatch: ID Length field in a received PDU %u, " + "while the parameter for this IS is %u", + hdr->id_len, ISIS_SYS_ID_LEN); + return ISIS_ERROR; + } - if (hdr->version2 != 1) - { - zlog_warn ("Unsupported ISIS version %u", hdr->version2); - return ISIS_WARNING; - } + if (hdr->version2 != 1) { + zlog_warn("Unsupported ISIS version %u", hdr->version2); + return ISIS_WARNING; + } - if (circuit->is_passive) - { - zlog_warn ("Received ISIS PDU on passive circuit %s", - circuit->interface->name); - return ISIS_WARNING; - } + if (circuit->is_passive) { + zlog_warn("Received ISIS PDU on passive circuit %s", + circuit->interface->name); + return ISIS_WARNING; + } - /* either 3 or 0 */ - if ((hdr->max_area_addrs != 0) - && (hdr->max_area_addrs != isis->max_area_addrs)) - { - zlog_err ("maximumAreaAddressesMismatch: maximumAreaAdresses in a " - "received PDU %u while the parameter for this IS is %u", - hdr->max_area_addrs, isis->max_area_addrs); - return ISIS_ERROR; - } + /* either 3 or 0 */ + if ((hdr->max_area_addrs != 0) + && (hdr->max_area_addrs != isis->max_area_addrs)) { + zlog_err( + "maximumAreaAddressesMismatch: maximumAreaAdresses in a " + "received PDU %u while the parameter for this IS is %u", + hdr->max_area_addrs, isis->max_area_addrs); + return ISIS_ERROR; + } - switch (hdr->pdu_type) - { - case L1_LAN_HELLO: - retval = process_lan_hello (ISIS_LEVEL1, circuit, ssnpa); - break; - case L2_LAN_HELLO: - retval = process_lan_hello (ISIS_LEVEL2, circuit, ssnpa); - break; - case P2P_HELLO: - retval = process_p2p_hello (circuit); - break; - case L1_LINK_STATE: - retval = process_lsp (ISIS_LEVEL1, circuit, ssnpa); - break; - case L2_LINK_STATE: - retval = process_lsp (ISIS_LEVEL2, circuit, ssnpa); - break; - case L1_COMPLETE_SEQ_NUM: - retval = process_csnp (ISIS_LEVEL1, circuit, ssnpa); - break; - case L2_COMPLETE_SEQ_NUM: - retval = process_csnp (ISIS_LEVEL2, circuit, ssnpa); - break; - case L1_PARTIAL_SEQ_NUM: - retval = process_psnp (ISIS_LEVEL1, circuit, ssnpa); - break; - case L2_PARTIAL_SEQ_NUM: - retval = process_psnp (ISIS_LEVEL2, circuit, ssnpa); - break; - default: - return ISIS_ERROR; - } + switch (hdr->pdu_type) { + case L1_LAN_HELLO: + retval = process_lan_hello(ISIS_LEVEL1, circuit, ssnpa); + break; + case L2_LAN_HELLO: + retval = process_lan_hello(ISIS_LEVEL2, circuit, ssnpa); + break; + case P2P_HELLO: + retval = process_p2p_hello(circuit); + break; + case L1_LINK_STATE: + retval = process_lsp(ISIS_LEVEL1, circuit, ssnpa); + break; + case L2_LINK_STATE: + retval = process_lsp(ISIS_LEVEL2, circuit, ssnpa); + break; + case L1_COMPLETE_SEQ_NUM: + retval = process_csnp(ISIS_LEVEL1, circuit, ssnpa); + break; + case L2_COMPLETE_SEQ_NUM: + retval = process_csnp(ISIS_LEVEL2, circuit, ssnpa); + break; + case L1_PARTIAL_SEQ_NUM: + retval = process_psnp(ISIS_LEVEL1, circuit, ssnpa); + break; + case L2_PARTIAL_SEQ_NUM: + retval = process_psnp(ISIS_LEVEL2, circuit, ssnpa); + break; + default: + return ISIS_ERROR; + } - return retval; + return retval; } -int -isis_receive (struct thread *thread) +int isis_receive(struct thread *thread) { - struct isis_circuit *circuit; - u_char ssnpa[ETH_ALEN]; - int retval; + struct isis_circuit *circuit; + u_char ssnpa[ETH_ALEN]; + int retval; - /* - * Get the circuit - */ - circuit = THREAD_ARG (thread); - assert (circuit); + /* + * Get the circuit + */ + circuit = THREAD_ARG(thread); + assert(circuit); - circuit->t_read = NULL; + circuit->t_read = NULL; - isis_circuit_stream(circuit, &circuit->rcv_stream); + isis_circuit_stream(circuit, &circuit->rcv_stream); - retval = circuit->rx (circuit, ssnpa); + retval = circuit->rx(circuit, ssnpa); - if (retval == ISIS_OK) - retval = isis_handle_pdu (circuit, ssnpa); + if (retval == ISIS_OK) + retval = isis_handle_pdu(circuit, ssnpa); - /* - * prepare for next packet. - */ - if (!circuit->is_passive) - isis_circuit_prepare (circuit); + /* + * prepare for next packet. + */ + if (!circuit->is_passive) + isis_circuit_prepare(circuit); - return retval; + return retval; } - /* filling of the fixed isis header */ -void -fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type) +/* filling of the fixed isis header */ +void fill_fixed_hdr(struct isis_fixed_hdr *hdr, u_char pdu_type) { - memset (hdr, 0, sizeof (struct isis_fixed_hdr)); - - hdr->idrp = ISO10589_ISIS; - - switch (pdu_type) - { - case L1_LAN_HELLO: - case L2_LAN_HELLO: - hdr->length = ISIS_LANHELLO_HDRLEN; - break; - case P2P_HELLO: - hdr->length = ISIS_P2PHELLO_HDRLEN; - break; - case L1_LINK_STATE: - case L2_LINK_STATE: - hdr->length = ISIS_LSP_HDR_LEN; - break; - case L1_COMPLETE_SEQ_NUM: - case L2_COMPLETE_SEQ_NUM: - hdr->length = ISIS_CSNP_HDRLEN; - break; - case L1_PARTIAL_SEQ_NUM: - case L2_PARTIAL_SEQ_NUM: - hdr->length = ISIS_PSNP_HDRLEN; - break; - default: - zlog_warn ("fill_fixed_hdr(): unknown pdu type %d", pdu_type); - return; - } - hdr->length += ISIS_FIXED_HDR_LEN; - hdr->pdu_type = pdu_type; - hdr->version1 = 1; - hdr->id_len = 0; /* ISIS_SYS_ID_LEN - 0==6 */ - hdr->version2 = 1; - hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */ + memset(hdr, 0, sizeof(struct isis_fixed_hdr)); + + hdr->idrp = ISO10589_ISIS; + + switch (pdu_type) { + case L1_LAN_HELLO: + case L2_LAN_HELLO: + hdr->length = ISIS_LANHELLO_HDRLEN; + break; + case P2P_HELLO: + hdr->length = ISIS_P2PHELLO_HDRLEN; + break; + case L1_LINK_STATE: + case L2_LINK_STATE: + hdr->length = ISIS_LSP_HDR_LEN; + break; + case L1_COMPLETE_SEQ_NUM: + case L2_COMPLETE_SEQ_NUM: + hdr->length = ISIS_CSNP_HDRLEN; + break; + case L1_PARTIAL_SEQ_NUM: + case L2_PARTIAL_SEQ_NUM: + hdr->length = ISIS_PSNP_HDRLEN; + break; + default: + zlog_warn("fill_fixed_hdr(): unknown pdu type %d", pdu_type); + return; + } + hdr->length += ISIS_FIXED_HDR_LEN; + hdr->pdu_type = pdu_type; + hdr->version1 = 1; + hdr->id_len = 0; /* ISIS_SYS_ID_LEN - 0==6 */ + hdr->version2 = 1; + hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */ } /* - * SEND SIDE + * SEND SIDE */ -static void -fill_fixed_hdr_andstream (struct isis_fixed_hdr *hdr, u_char pdu_type, - struct stream *stream) +static void fill_fixed_hdr_andstream(struct isis_fixed_hdr *hdr, + u_char pdu_type, struct stream *stream) { - fill_fixed_hdr (hdr, pdu_type); - - stream_putc (stream, hdr->idrp); - stream_putc (stream, hdr->length); - stream_putc (stream, hdr->version1); - stream_putc (stream, hdr->id_len); - stream_putc (stream, hdr->pdu_type); - stream_putc (stream, hdr->version2); - stream_putc (stream, hdr->reserved); - stream_putc (stream, hdr->max_area_addrs); - - return; + fill_fixed_hdr(hdr, pdu_type); + + stream_putc(stream, hdr->idrp); + stream_putc(stream, hdr->length); + stream_putc(stream, hdr->version1); + stream_putc(stream, hdr->id_len); + stream_putc(stream, hdr->pdu_type); + stream_putc(stream, hdr->version2); + stream_putc(stream, hdr->reserved); + stream_putc(stream, hdr->max_area_addrs); + + return; } -int -send_hello (struct isis_circuit *circuit, int level) +int send_hello(struct isis_circuit *circuit, int level) { - struct isis_fixed_hdr fixed_hdr; - struct isis_lan_hello_hdr hello_hdr; - struct isis_p2p_hello_hdr p2p_hello_hdr; - unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; - size_t len_pointer, length, auth_tlv_offset = 0; - u_int32_t interval; - int retval; - - if (circuit->is_passive) - return ISIS_OK; - - if (circuit->interface->mtu == 0) - { - zlog_warn ("circuit has zero MTU"); - return ISIS_WARNING; - } - - isis_circuit_stream(circuit, &circuit->snd_stream); - - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - if (level == IS_LEVEL_1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_LAN_HELLO, - circuit->snd_stream); - else - fill_fixed_hdr_andstream (&fixed_hdr, L2_LAN_HELLO, - circuit->snd_stream); - else - fill_fixed_hdr_andstream (&fixed_hdr, P2P_HELLO, circuit->snd_stream); - - /* - * Fill LAN Level 1 or 2 Hello PDU header - */ - memset (&hello_hdr, 0, sizeof (struct isis_lan_hello_hdr)); - interval = circuit->hello_multiplier[level - 1] * - circuit->hello_interval[level - 1]; - if (interval > USHRT_MAX) - interval = USHRT_MAX; - hello_hdr.circuit_t = circuit->is_type; - memcpy (hello_hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN); - hello_hdr.hold_time = htons ((u_int16_t) interval); - - hello_hdr.pdu_len = 0; /* Update the PDU Length later */ - len_pointer = stream_get_endp (circuit->snd_stream) + 3 + ISIS_SYS_ID_LEN; - - /* copy the shared part of the hello to the p2p hello if needed */ - if (circuit->circ_type == CIRCUIT_T_P2P) - { - memcpy (&p2p_hello_hdr, &hello_hdr, 5 + ISIS_SYS_ID_LEN); - p2p_hello_hdr.local_id = circuit->circuit_id; - /* FIXME: need better understanding */ - stream_put (circuit->snd_stream, &p2p_hello_hdr, ISIS_P2PHELLO_HDRLEN); - } - else - { - hello_hdr.prio = circuit->priority[level - 1]; - if (level == IS_LEVEL_1) - { - memcpy (hello_hdr.lan_id, circuit->u.bc.l1_desig_is, - ISIS_SYS_ID_LEN + 1); - } - else if (level == IS_LEVEL_2) - { - memcpy (hello_hdr.lan_id, circuit->u.bc.l2_desig_is, - ISIS_SYS_ID_LEN + 1); + struct isis_fixed_hdr fixed_hdr; + struct isis_lan_hello_hdr hello_hdr; + struct isis_p2p_hello_hdr p2p_hello_hdr; + unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; + size_t len_pointer, length, auth_tlv_offset = 0; + u_int32_t interval; + int retval; + + if (circuit->is_passive) + return ISIS_OK; + + if (circuit->interface->mtu == 0) { + zlog_warn("circuit has zero MTU"); + return ISIS_WARNING; } - stream_put (circuit->snd_stream, &hello_hdr, ISIS_LANHELLO_HDRLEN); - } - /* - * Then the variable length part. - */ - - /* add circuit password */ - switch (circuit->passwd.type) - { - /* Cleartext */ - case ISIS_PASSWD_TYPE_CLEARTXT: - if (tlv_add_authinfo (circuit->passwd.type, circuit->passwd.len, - circuit->passwd.passwd, circuit->snd_stream)) - return ISIS_WARNING; - break; - - /* HMAC MD5 */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - /* Remember where TLV is written so we can later overwrite the MD5 hash */ - auth_tlv_offset = stream_get_endp (circuit->snd_stream); - memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); - if (tlv_add_authinfo (circuit->passwd.type, ISIS_AUTH_MD5_SIZE, - hmac_md5_hash, circuit->snd_stream)) - return ISIS_WARNING; - break; - - default: - break; - } - - /* Area Addresses TLV */ - if (listcount (circuit->area->area_addrs) == 0) - return ISIS_WARNING; - if (tlv_add_area_addrs (circuit->area->area_addrs, circuit->snd_stream)) - return ISIS_WARNING; - - /* LAN Neighbors TLV */ - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - if (level == IS_LEVEL_1 && circuit->u.bc.lan_neighs[0] && - listcount (circuit->u.bc.lan_neighs[0]) > 0) - if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0], - circuit->snd_stream)) - return ISIS_WARNING; - if (level == IS_LEVEL_2 && circuit->u.bc.lan_neighs[1] && - listcount (circuit->u.bc.lan_neighs[1]) > 0) - if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1], - circuit->snd_stream)) - return ISIS_WARNING; - } - - /* Protocols Supported TLV */ - if (circuit->nlpids.count > 0) - if (tlv_add_nlpid (&circuit->nlpids, circuit->snd_stream)) - return ISIS_WARNING; - /* IP interface Address TLV */ - if (circuit->ip_router && circuit->ip_addrs && - listcount (circuit->ip_addrs) > 0) - if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream)) - return ISIS_WARNING; + isis_circuit_stream(circuit, &circuit->snd_stream); - /* - * MT Supported TLV - * - * TLV gets included if no topology is enabled on the interface, - * if one topology other than #0 is enabled, or if multiple topologies - * are enabled. - */ - struct isis_circuit_mt_setting **mt_settings; - unsigned int mt_count; - - mt_settings = circuit_mt_settings(circuit, &mt_count); - if ((mt_count == 0 && area_is_mt(circuit->area)) - || (mt_count == 1 && mt_settings[0]->mtid != ISIS_MT_IPV4_UNICAST) - || (mt_count > 1)) - { - struct list *mt_info = list_new(); - mt_info->del = free_tlv; - - for (unsigned int i = 0; i < mt_count; i++) - { - struct mt_router_info *info; - - info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info)); - info->mtid = mt_settings[i]->mtid; - /* overload info is not valid in IIH, so it's not included here */ - listnode_add(mt_info, info); - } - tlv_add_mt_router_info (mt_info, circuit->snd_stream); - list_free(mt_info); - } - - /* IPv6 Interface Address TLV */ - if (circuit->ipv6_router && circuit->ipv6_link && - listcount (circuit->ipv6_link) > 0) - if (tlv_add_ipv6_addrs (circuit->ipv6_link, circuit->snd_stream)) - return ISIS_WARNING; + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + if (level == IS_LEVEL_1) + fill_fixed_hdr_andstream(&fixed_hdr, L1_LAN_HELLO, + circuit->snd_stream); + else + fill_fixed_hdr_andstream(&fixed_hdr, L2_LAN_HELLO, + circuit->snd_stream); + else + fill_fixed_hdr_andstream(&fixed_hdr, P2P_HELLO, + circuit->snd_stream); + + /* + * Fill LAN Level 1 or 2 Hello PDU header + */ + memset(&hello_hdr, 0, sizeof(struct isis_lan_hello_hdr)); + interval = circuit->hello_multiplier[level - 1] + * circuit->hello_interval[level - 1]; + if (interval > USHRT_MAX) + interval = USHRT_MAX; + hello_hdr.circuit_t = circuit->is_type; + memcpy(hello_hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN); + hello_hdr.hold_time = htons((u_int16_t)interval); + + hello_hdr.pdu_len = 0; /* Update the PDU Length later */ + len_pointer = + stream_get_endp(circuit->snd_stream) + 3 + ISIS_SYS_ID_LEN; + + /* copy the shared part of the hello to the p2p hello if needed */ + if (circuit->circ_type == CIRCUIT_T_P2P) { + memcpy(&p2p_hello_hdr, &hello_hdr, 5 + ISIS_SYS_ID_LEN); + p2p_hello_hdr.local_id = circuit->circuit_id; + /* FIXME: need better understanding */ + stream_put(circuit->snd_stream, &p2p_hello_hdr, + ISIS_P2PHELLO_HDRLEN); + } else { + hello_hdr.prio = circuit->priority[level - 1]; + if (level == IS_LEVEL_1) { + memcpy(hello_hdr.lan_id, circuit->u.bc.l1_desig_is, + ISIS_SYS_ID_LEN + 1); + } else if (level == IS_LEVEL_2) { + memcpy(hello_hdr.lan_id, circuit->u.bc.l2_desig_is, + ISIS_SYS_ID_LEN + 1); + } + stream_put(circuit->snd_stream, &hello_hdr, + ISIS_LANHELLO_HDRLEN); + } - if (circuit->pad_hellos) - if (tlv_add_padding (circuit->snd_stream)) - return ISIS_WARNING; + /* + * Then the variable length part. + */ + + /* add circuit password */ + switch (circuit->passwd.type) { + /* Cleartext */ + case ISIS_PASSWD_TYPE_CLEARTXT: + if (tlv_add_authinfo(circuit->passwd.type, circuit->passwd.len, + circuit->passwd.passwd, + circuit->snd_stream)) + return ISIS_WARNING; + break; + + /* HMAC MD5 */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + /* Remember where TLV is written so we can later overwrite the + * MD5 hash */ + auth_tlv_offset = stream_get_endp(circuit->snd_stream); + memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); + if (tlv_add_authinfo(circuit->passwd.type, ISIS_AUTH_MD5_SIZE, + hmac_md5_hash, circuit->snd_stream)) + return ISIS_WARNING; + break; + + default: + break; + } - length = stream_get_endp (circuit->snd_stream); - /* Update PDU length */ - stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t) length); + /* Area Addresses TLV */ + if (listcount(circuit->area->area_addrs) == 0) + return ISIS_WARNING; + if (tlv_add_area_addrs(circuit->area->area_addrs, circuit->snd_stream)) + return ISIS_WARNING; + + /* LAN Neighbors TLV */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + if (level == IS_LEVEL_1 && circuit->u.bc.lan_neighs[0] + && listcount(circuit->u.bc.lan_neighs[0]) > 0) + if (tlv_add_lan_neighs(circuit->u.bc.lan_neighs[0], + circuit->snd_stream)) + return ISIS_WARNING; + if (level == IS_LEVEL_2 && circuit->u.bc.lan_neighs[1] + && listcount(circuit->u.bc.lan_neighs[1]) > 0) + if (tlv_add_lan_neighs(circuit->u.bc.lan_neighs[1], + circuit->snd_stream)) + return ISIS_WARNING; + } - /* For HMAC MD5 we need to compute the md5 hash and store it */ - if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - hmac_md5 (STREAM_DATA (circuit->snd_stream), - stream_get_endp (circuit->snd_stream), - (unsigned char *) &circuit->passwd.passwd, circuit->passwd.len, - (unsigned char *) &hmac_md5_hash); - /* Copy the hash into the stream */ - memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, - hmac_md5_hash, ISIS_AUTH_MD5_SIZE); - } + /* Protocols Supported TLV */ + if (circuit->nlpids.count > 0) + if (tlv_add_nlpid(&circuit->nlpids, circuit->snd_stream)) + return ISIS_WARNING; + /* IP interface Address TLV */ + if (circuit->ip_router && circuit->ip_addrs + && listcount(circuit->ip_addrs) > 0) + if (tlv_add_ip_addrs(circuit->ip_addrs, circuit->snd_stream)) + return ISIS_WARNING; + + /* + * MT Supported TLV + * + * TLV gets included if no topology is enabled on the interface, + * if one topology other than #0 is enabled, or if multiple topologies + * are enabled. + */ + struct isis_circuit_mt_setting **mt_settings; + unsigned int mt_count; + + mt_settings = circuit_mt_settings(circuit, &mt_count); + if ((mt_count == 0 && area_is_mt(circuit->area)) + || (mt_count == 1 && mt_settings[0]->mtid != ISIS_MT_IPV4_UNICAST) + || (mt_count > 1)) { + struct list *mt_info = list_new(); + mt_info->del = free_tlv; + + for (unsigned int i = 0; i < mt_count; i++) { + struct mt_router_info *info; + + info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info)); + info->mtid = mt_settings[i]->mtid; + /* overload info is not valid in IIH, so it's not + * included here */ + listnode_add(mt_info, info); + } + tlv_add_mt_router_info(mt_info, circuit->snd_stream); + list_free(mt_info); + } - if (isis->debugs & DEBUG_ADJ_PACKETS) - { - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - zlog_debug ("ISIS-Adj (%s): Sending L%d LAN IIH on %s, length %zd", - circuit->area->area_tag, level, circuit->interface->name, - length); + /* IPv6 Interface Address TLV */ + if (circuit->ipv6_router && circuit->ipv6_link + && listcount(circuit->ipv6_link) > 0) + if (tlv_add_ipv6_addrs(circuit->ipv6_link, circuit->snd_stream)) + return ISIS_WARNING; + + if (circuit->pad_hellos) + if (tlv_add_padding(circuit->snd_stream)) + return ISIS_WARNING; + + length = stream_get_endp(circuit->snd_stream); + /* Update PDU length */ + stream_putw_at(circuit->snd_stream, len_pointer, (u_int16_t)length); + + /* For HMAC MD5 we need to compute the md5 hash and store it */ + if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) { + hmac_md5(STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream), + (unsigned char *)&circuit->passwd.passwd, + circuit->passwd.len, (unsigned char *)&hmac_md5_hash); + /* Copy the hash into the stream */ + memcpy(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3, + hmac_md5_hash, ISIS_AUTH_MD5_SIZE); } - else - { - zlog_debug ("ISIS-Adj (%s): Sending P2P IIH on %s, length %zd", - circuit->area->area_tag, circuit->interface->name, - length); + + if (isis->debugs & DEBUG_ADJ_PACKETS) { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + zlog_debug( + "ISIS-Adj (%s): Sending L%d LAN IIH on %s, length %zd", + circuit->area->area_tag, level, + circuit->interface->name, length); + } else { + zlog_debug( + "ISIS-Adj (%s): Sending P2P IIH on %s, length %zd", + circuit->area->area_tag, + circuit->interface->name, length); + } + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream)); } - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->snd_stream), - stream_get_endp (circuit->snd_stream)); - } - retval = circuit->tx (circuit, level); - if (retval != ISIS_OK) - zlog_err ("ISIS-Adj (%s): Send L%d IIH on %s failed", - circuit->area->area_tag, level, circuit->interface->name); + retval = circuit->tx(circuit, level); + if (retval != ISIS_OK) + zlog_err("ISIS-Adj (%s): Send L%d IIH on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); - return retval; + return retval; } -int -send_lan_l1_hello (struct thread *thread) +int send_lan_l1_hello(struct thread *thread) { - struct isis_circuit *circuit; - int retval; - - circuit = THREAD_ARG (thread); - assert (circuit); - circuit->u.bc.t_send_lan_hello[0] = NULL; - - if (!(circuit->area->is_type & IS_LEVEL_1)) - { - zlog_warn ("ISIS-Hello (%s): Trying to send L1 IIH in L2-only area", - circuit->area->area_tag); - return 1; - } + struct isis_circuit *circuit; + int retval; + + circuit = THREAD_ARG(thread); + assert(circuit); + circuit->u.bc.t_send_lan_hello[0] = NULL; + + if (!(circuit->area->is_type & IS_LEVEL_1)) { + zlog_warn( + "ISIS-Hello (%s): Trying to send L1 IIH in L2-only area", + circuit->area->area_tag); + return 1; + } - if (circuit->u.bc.run_dr_elect[0]) - isis_dr_elect (circuit, 1); + if (circuit->u.bc.run_dr_elect[0]) + isis_dr_elect(circuit, 1); - retval = send_hello (circuit, 1); + retval = send_hello(circuit, 1); - /* set next timer thread */ - thread_add_timer(master, send_lan_l1_hello, circuit, - isis_jitter(circuit->hello_interval[0], IIH_JITTER), - &circuit->u.bc.t_send_lan_hello[0]); + /* set next timer thread */ + thread_add_timer(master, send_lan_l1_hello, circuit, + isis_jitter(circuit->hello_interval[0], IIH_JITTER), + &circuit->u.bc.t_send_lan_hello[0]); - return retval; + return retval; } -int -send_lan_l2_hello (struct thread *thread) +int send_lan_l2_hello(struct thread *thread) { - struct isis_circuit *circuit; - int retval; + struct isis_circuit *circuit; + int retval; - circuit = THREAD_ARG (thread); - assert (circuit); - circuit->u.bc.t_send_lan_hello[1] = NULL; + circuit = THREAD_ARG(thread); + assert(circuit); + circuit->u.bc.t_send_lan_hello[1] = NULL; - if (!(circuit->area->is_type & IS_LEVEL_2)) - { - zlog_warn ("ISIS-Hello (%s): Trying to send L2 IIH in L1 area", - circuit->area->area_tag); - return 1; - } + if (!(circuit->area->is_type & IS_LEVEL_2)) { + zlog_warn("ISIS-Hello (%s): Trying to send L2 IIH in L1 area", + circuit->area->area_tag); + return 1; + } - if (circuit->u.bc.run_dr_elect[1]) - isis_dr_elect (circuit, 2); + if (circuit->u.bc.run_dr_elect[1]) + isis_dr_elect(circuit, 2); - retval = send_hello (circuit, 2); + retval = send_hello(circuit, 2); - /* set next timer thread */ - thread_add_timer(master, send_lan_l2_hello, circuit, - isis_jitter(circuit->hello_interval[1], IIH_JITTER), - &circuit->u.bc.t_send_lan_hello[1]); + /* set next timer thread */ + thread_add_timer(master, send_lan_l2_hello, circuit, + isis_jitter(circuit->hello_interval[1], IIH_JITTER), + &circuit->u.bc.t_send_lan_hello[1]); - return retval; + return retval; } -int -send_p2p_hello (struct thread *thread) +int send_p2p_hello(struct thread *thread) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - circuit = THREAD_ARG (thread); - assert (circuit); - circuit->u.p2p.t_send_p2p_hello = NULL; + circuit = THREAD_ARG(thread); + assert(circuit); + circuit->u.p2p.t_send_p2p_hello = NULL; - send_hello (circuit, 1); + send_hello(circuit, 1); - /* set next timer thread */ - thread_add_timer(master, send_p2p_hello, circuit, - isis_jitter(circuit->hello_interval[1], IIH_JITTER), - &circuit->u.p2p.t_send_p2p_hello); + /* set next timer thread */ + thread_add_timer(master, send_p2p_hello, circuit, + isis_jitter(circuit->hello_interval[1], IIH_JITTER), + &circuit->u.p2p.t_send_p2p_hello); - return ISIS_OK; + return ISIS_OK; } -static int -build_csnp (int level, u_char * start, u_char * stop, struct list *lsps, - struct isis_circuit *circuit) +static int build_csnp(int level, u_char *start, u_char *stop, struct list *lsps, + struct isis_circuit *circuit) { - struct isis_fixed_hdr fixed_hdr; - struct isis_passwd *passwd; - unsigned long lenp; - u_int16_t length; - unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; - unsigned long auth_tlv_offset = 0; - int retval = ISIS_OK; - - isis_circuit_stream(circuit, &circuit->snd_stream); - - if (level == IS_LEVEL_1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM, - circuit->snd_stream); - else - fill_fixed_hdr_andstream (&fixed_hdr, L2_COMPLETE_SEQ_NUM, - circuit->snd_stream); - - /* - * Fill Level 1 or 2 Complete Sequence Numbers header - */ - - lenp = stream_get_endp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */ - /* no need to send the source here, it is always us if we csnp */ - stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); - /* with zero circuit id - ref 9.10, 9.11 */ - stream_putc (circuit->snd_stream, 0x00); - - stream_put (circuit->snd_stream, start, ISIS_SYS_ID_LEN + 2); - stream_put (circuit->snd_stream, stop, ISIS_SYS_ID_LEN + 2); - - /* - * And TLVs - */ - if (level == IS_LEVEL_1) - passwd = &circuit->area->area_passwd; - else - passwd = &circuit->area->domain_passwd; - - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) - { - switch (passwd->type) - { - /* Cleartext */ - case ISIS_PASSWD_TYPE_CLEARTXT: - if (tlv_add_authinfo (ISIS_PASSWD_TYPE_CLEARTXT, passwd->len, - passwd->passwd, circuit->snd_stream)) - return ISIS_WARNING; - break; - - /* HMAC MD5 */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - /* Remember where TLV is written so we can later overwrite the MD5 hash */ - auth_tlv_offset = stream_get_endp (circuit->snd_stream); - memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); - if (tlv_add_authinfo (ISIS_PASSWD_TYPE_HMAC_MD5, ISIS_AUTH_MD5_SIZE, - hmac_md5_hash, circuit->snd_stream)) - return ISIS_WARNING; - break; - - default: - break; - } - } - - retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); - if (retval != ISIS_OK) - return retval; - - length = (u_int16_t) stream_get_endp (circuit->snd_stream); - /* Update PU length */ - stream_putw_at (circuit->snd_stream, lenp, length); + struct isis_fixed_hdr fixed_hdr; + struct isis_passwd *passwd; + unsigned long lenp; + u_int16_t length; + unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; + unsigned long auth_tlv_offset = 0; + int retval = ISIS_OK; + + isis_circuit_stream(circuit, &circuit->snd_stream); + + if (level == IS_LEVEL_1) + fill_fixed_hdr_andstream(&fixed_hdr, L1_COMPLETE_SEQ_NUM, + circuit->snd_stream); + else + fill_fixed_hdr_andstream(&fixed_hdr, L2_COMPLETE_SEQ_NUM, + circuit->snd_stream); + + /* + * Fill Level 1 or 2 Complete Sequence Numbers header + */ + + lenp = stream_get_endp(circuit->snd_stream); + stream_putw(circuit->snd_stream, 0); /* PDU length - when we know it */ + /* no need to send the source here, it is always us if we csnp */ + stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); + /* with zero circuit id - ref 9.10, 9.11 */ + stream_putc(circuit->snd_stream, 0x00); + + stream_put(circuit->snd_stream, start, ISIS_SYS_ID_LEN + 2); + stream_put(circuit->snd_stream, stop, ISIS_SYS_ID_LEN + 2); + + /* + * And TLVs + */ + if (level == IS_LEVEL_1) + passwd = &circuit->area->area_passwd; + else + passwd = &circuit->area->domain_passwd; + + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) { + switch (passwd->type) { + /* Cleartext */ + case ISIS_PASSWD_TYPE_CLEARTXT: + if (tlv_add_authinfo(ISIS_PASSWD_TYPE_CLEARTXT, + passwd->len, passwd->passwd, + circuit->snd_stream)) + return ISIS_WARNING; + break; + + /* HMAC MD5 */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + /* Remember where TLV is written so we can later + * overwrite the MD5 hash */ + auth_tlv_offset = stream_get_endp(circuit->snd_stream); + memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); + if (tlv_add_authinfo(ISIS_PASSWD_TYPE_HMAC_MD5, + ISIS_AUTH_MD5_SIZE, hmac_md5_hash, + circuit->snd_stream)) + return ISIS_WARNING; + break; + + default: + break; + } + } - /* For HMAC MD5 we need to compute the md5 hash and store it */ - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) && - passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - hmac_md5 (STREAM_DATA (circuit->snd_stream), - stream_get_endp(circuit->snd_stream), - (unsigned char *) &passwd->passwd, passwd->len, - (unsigned char *) &hmac_md5_hash); - /* Copy the hash into the stream */ - memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, - hmac_md5_hash, ISIS_AUTH_MD5_SIZE); - } + retval = tlv_add_lsp_entries(lsps, circuit->snd_stream); + if (retval != ISIS_OK) + return retval; + + length = (u_int16_t)stream_get_endp(circuit->snd_stream); + /* Update PU length */ + stream_putw_at(circuit->snd_stream, lenp, length); + + /* For HMAC MD5 we need to compute the md5 hash and store it */ + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) + && passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) { + hmac_md5(STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream), + (unsigned char *)&passwd->passwd, passwd->len, + (unsigned char *)&hmac_md5_hash); + /* Copy the hash into the stream */ + memcpy(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3, + hmac_md5_hash, ISIS_AUTH_MD5_SIZE); + } - return retval; + return retval; } /* * Count the maximum number of lsps that can be accomodated by a given size. */ -static uint16_t -get_max_lsp_count (uint16_t size) +static uint16_t get_max_lsp_count(uint16_t size) { - uint16_t tlv_count; - uint16_t lsp_count; - uint16_t remaining_size; + uint16_t tlv_count; + uint16_t lsp_count; + uint16_t remaining_size; - /* First count the full size TLVs */ - tlv_count = size / MAX_LSP_ENTRIES_TLV_SIZE; - lsp_count = tlv_count * (MAX_LSP_ENTRIES_TLV_SIZE / LSP_ENTRIES_LEN); + /* First count the full size TLVs */ + tlv_count = size / MAX_LSP_ENTRIES_TLV_SIZE; + lsp_count = tlv_count * (MAX_LSP_ENTRIES_TLV_SIZE / LSP_ENTRIES_LEN); - /* The last TLV, if any */ - remaining_size = size % MAX_LSP_ENTRIES_TLV_SIZE; - if (remaining_size - 2 >= LSP_ENTRIES_LEN) - lsp_count += (remaining_size - 2) / LSP_ENTRIES_LEN; + /* The last TLV, if any */ + remaining_size = size % MAX_LSP_ENTRIES_TLV_SIZE; + if (remaining_size - 2 >= LSP_ENTRIES_LEN) + lsp_count += (remaining_size - 2) / LSP_ENTRIES_LEN; - return lsp_count; + return lsp_count; } /* * Calculate the length of Authentication Info. TLV. */ -static uint16_t -auth_tlv_length (int level, struct isis_circuit *circuit) +static uint16_t auth_tlv_length(int level, struct isis_circuit *circuit) { - struct isis_passwd *passwd; - uint16_t length; - - if (level == IS_LEVEL_1) - passwd = &circuit->area->area_passwd; - else - passwd = &circuit->area->domain_passwd; - - /* Also include the length of TLV header */ - length = AUTH_INFO_HDRLEN; - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) - { - switch (passwd->type) - { - /* Cleartext */ - case ISIS_PASSWD_TYPE_CLEARTXT: - length += passwd->len; - break; - - /* HMAC MD5 */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - length += ISIS_AUTH_MD5_SIZE; - break; - - default: - break; - } - } + struct isis_passwd *passwd; + uint16_t length; + + if (level == IS_LEVEL_1) + passwd = &circuit->area->area_passwd; + else + passwd = &circuit->area->domain_passwd; + + /* Also include the length of TLV header */ + length = AUTH_INFO_HDRLEN; + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) { + switch (passwd->type) { + /* Cleartext */ + case ISIS_PASSWD_TYPE_CLEARTXT: + length += passwd->len; + break; + + /* HMAC MD5 */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + length += ISIS_AUTH_MD5_SIZE; + break; + + default: + break; + } + } - return length; + return length; } /* * Calculate the maximum number of lsps that can be accomodated in a CSNP/PSNP. */ -static uint16_t -max_lsps_per_snp (int snp_type, int level, struct isis_circuit *circuit) +static uint16_t max_lsps_per_snp(int snp_type, int level, + struct isis_circuit *circuit) { - int snp_hdr_len; - int auth_tlv_len; - uint16_t lsp_count; - - snp_hdr_len = ISIS_FIXED_HDR_LEN; - if (snp_type == ISIS_SNP_CSNP_FLAG) - snp_hdr_len += ISIS_CSNP_HDRLEN; - else - snp_hdr_len += ISIS_PSNP_HDRLEN; - - auth_tlv_len = auth_tlv_length (level, circuit); - lsp_count = get_max_lsp_count ( - stream_get_size (circuit->snd_stream) - snp_hdr_len - auth_tlv_len); - return lsp_count; + int snp_hdr_len; + int auth_tlv_len; + uint16_t lsp_count; + + snp_hdr_len = ISIS_FIXED_HDR_LEN; + if (snp_type == ISIS_SNP_CSNP_FLAG) + snp_hdr_len += ISIS_CSNP_HDRLEN; + else + snp_hdr_len += ISIS_PSNP_HDRLEN; + + auth_tlv_len = auth_tlv_length(level, circuit); + lsp_count = get_max_lsp_count(stream_get_size(circuit->snd_stream) + - snp_hdr_len - auth_tlv_len); + return lsp_count; } /* * FIXME: support multiple CSNPs */ -int -send_csnp (struct isis_circuit *circuit, int level) +int send_csnp(struct isis_circuit *circuit, int level) { - u_char start[ISIS_SYS_ID_LEN + 2]; - u_char stop[ISIS_SYS_ID_LEN + 2]; - struct list *list = NULL; - struct listnode *node; - struct isis_lsp *lsp; - u_char num_lsps, loop = 1; - int i, retval = ISIS_OK; + u_char start[ISIS_SYS_ID_LEN + 2]; + u_char stop[ISIS_SYS_ID_LEN + 2]; + struct list *list = NULL; + struct listnode *node; + struct isis_lsp *lsp; + u_char num_lsps, loop = 1; + int i, retval = ISIS_OK; + + if (circuit->area->lspdb[level - 1] == NULL + || dict_count(circuit->area->lspdb[level - 1]) == 0) + return retval; + + memset(start, 0x00, ISIS_SYS_ID_LEN + 2); + memset(stop, 0xff, ISIS_SYS_ID_LEN + 2); + + num_lsps = max_lsps_per_snp(ISIS_SNP_CSNP_FLAG, level, circuit); + + while (loop) { + list = list_new(); + lsp_build_list(start, stop, num_lsps, list, + circuit->area->lspdb[level - 1]); + /* + * Update the stop lsp_id before encoding this CSNP. + */ + if (listcount(list) < num_lsps) { + memset(stop, 0xff, ISIS_SYS_ID_LEN + 2); + } else { + node = listtail(list); + lsp = listgetdata(node); + memcpy(stop, lsp->lsp_header->lsp_id, + ISIS_SYS_ID_LEN + 2); + } - if (circuit->area->lspdb[level - 1] == NULL || - dict_count (circuit->area->lspdb[level - 1]) == 0) - return retval; + retval = build_csnp(level, start, stop, list, circuit); + if (retval != ISIS_OK) { + zlog_err("ISIS-Snp (%s): Build L%d CSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); + list_delete(list); + return retval; + } - memset (start, 0x00, ISIS_SYS_ID_LEN + 2); - memset (stop, 0xff, ISIS_SYS_ID_LEN + 2); + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Sending L%d CSNP on %s, length %zd", + circuit->area->area_tag, level, + circuit->interface->name, + stream_get_endp(circuit->snd_stream)); + for (ALL_LIST_ELEMENTS_RO(list, node, lsp)) { + zlog_debug( + "ISIS-Snp (%s): CSNP entry %s, seq 0x%08x," + " cksum 0x%04x, lifetime %us", + circuit->area->area_tag, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime)); + } + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data( + STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream)); + } - num_lsps = max_lsps_per_snp (ISIS_SNP_CSNP_FLAG, level, circuit); + retval = circuit->tx(circuit, level); + if (retval != ISIS_OK) { + zlog_err("ISIS-Snp (%s): Send L%d CSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); + list_delete(list); + return retval; + } - while (loop) - { - list = list_new (); - lsp_build_list (start, stop, num_lsps, list, - circuit->area->lspdb[level - 1]); - /* - * Update the stop lsp_id before encoding this CSNP. - */ - if (listcount (list) < num_lsps) - { - memset (stop, 0xff, ISIS_SYS_ID_LEN + 2); - } - else - { - node = listtail (list); - lsp = listgetdata (node); - memcpy (stop, lsp->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 2); - } - - retval = build_csnp (level, start, stop, list, circuit); - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Snp (%s): Build L%d CSNP on %s failed", - circuit->area->area_tag, level, circuit->interface->name); - list_delete (list); - return retval; - } - - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Sending L%d CSNP on %s, length %zd", - circuit->area->area_tag, level, circuit->interface->name, - stream_get_endp (circuit->snd_stream)); - for (ALL_LIST_ELEMENTS_RO (list, node, lsp)) - { - zlog_debug ("ISIS-Snp (%s): CSNP entry %s, seq 0x%08x," - " cksum 0x%04x, lifetime %us", - circuit->area->area_tag, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime)); - } - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->snd_stream), - stream_get_endp (circuit->snd_stream)); - } - - retval = circuit->tx (circuit, level); - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Snp (%s): Send L%d CSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); - list_delete (list); - return retval; - } - - /* - * Start lsp_id of the next CSNP should be one plus the - * stop lsp_id in this current CSNP. - */ - memcpy (start, stop, ISIS_SYS_ID_LEN + 2); - loop = 0; - for (i = ISIS_SYS_ID_LEN + 1; i >= 0; --i) - { - if (start[i] < (u_char)0xff) - { - start[i] += 1; - loop = 1; - break; - } - } - memset (stop, 0xff, ISIS_SYS_ID_LEN + 2); - list_delete (list); - } + /* + * Start lsp_id of the next CSNP should be one plus the + * stop lsp_id in this current CSNP. + */ + memcpy(start, stop, ISIS_SYS_ID_LEN + 2); + loop = 0; + for (i = ISIS_SYS_ID_LEN + 1; i >= 0; --i) { + if (start[i] < (u_char)0xff) { + start[i] += 1; + loop = 1; + break; + } + } + memset(stop, 0xff, ISIS_SYS_ID_LEN + 2); + list_delete(list); + } - return retval; + return retval; } -int -send_l1_csnp (struct thread *thread) +int send_l1_csnp(struct thread *thread) { - struct isis_circuit *circuit; - int retval = ISIS_OK; + struct isis_circuit *circuit; + int retval = ISIS_OK; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - circuit->t_send_csnp[0] = NULL; + circuit->t_send_csnp[0] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[0]) - { - send_csnp (circuit, 1); - } - /* set next timer thread */ - thread_add_timer(master, send_l1_csnp, circuit, - isis_jitter(circuit->csnp_interval[0], CSNP_JITTER), - &circuit->t_send_csnp[0]); + if (circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[0]) { + send_csnp(circuit, 1); + } + /* set next timer thread */ + thread_add_timer(master, send_l1_csnp, circuit, + isis_jitter(circuit->csnp_interval[0], CSNP_JITTER), + &circuit->t_send_csnp[0]); - return retval; + return retval; } -int -send_l2_csnp (struct thread *thread) +int send_l2_csnp(struct thread *thread) { - struct isis_circuit *circuit; - int retval = ISIS_OK; + struct isis_circuit *circuit; + int retval = ISIS_OK; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - circuit->t_send_csnp[1] = NULL; + circuit->t_send_csnp[1] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[1]) - { - send_csnp (circuit, 2); - } - /* set next timer thread */ - thread_add_timer(master, send_l2_csnp, circuit, - isis_jitter(circuit->csnp_interval[1], CSNP_JITTER), - &circuit->t_send_csnp[1]); + if (circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[1]) { + send_csnp(circuit, 2); + } + /* set next timer thread */ + thread_add_timer(master, send_l2_csnp, circuit, + isis_jitter(circuit->csnp_interval[1], CSNP_JITTER), + &circuit->t_send_csnp[1]); - return retval; + return retval; } -static int -build_psnp (int level, struct isis_circuit *circuit, struct list *lsps) +static int build_psnp(int level, struct isis_circuit *circuit, + struct list *lsps) { - struct isis_fixed_hdr fixed_hdr; - unsigned long lenp; - u_int16_t length; - struct isis_lsp *lsp; - struct isis_passwd *passwd; - struct listnode *node; - unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; - unsigned long auth_tlv_offset = 0; - int retval = ISIS_OK; - - isis_circuit_stream(circuit, &circuit->snd_stream); - - if (level == IS_LEVEL_1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, - circuit->snd_stream); - else - fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM, - circuit->snd_stream); - - /* - * Fill Level 1 or 2 Partial Sequence Numbers header - */ - lenp = stream_get_endp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */ - stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); - stream_putc (circuit->snd_stream, circuit->idx); - - /* - * And TLVs - */ - - if (level == IS_LEVEL_1) - passwd = &circuit->area->area_passwd; - else - passwd = &circuit->area->domain_passwd; - - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) - { - switch (passwd->type) - { - /* Cleartext */ - case ISIS_PASSWD_TYPE_CLEARTXT: - if (tlv_add_authinfo (ISIS_PASSWD_TYPE_CLEARTXT, passwd->len, - passwd->passwd, circuit->snd_stream)) - return ISIS_WARNING; - break; - - /* HMAC MD5 */ - case ISIS_PASSWD_TYPE_HMAC_MD5: - /* Remember where TLV is written so we can later overwrite the MD5 hash */ - auth_tlv_offset = stream_get_endp (circuit->snd_stream); - memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); - if (tlv_add_authinfo (ISIS_PASSWD_TYPE_HMAC_MD5, ISIS_AUTH_MD5_SIZE, - hmac_md5_hash, circuit->snd_stream)) - return ISIS_WARNING; - break; - - default: - break; - } - } - - retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); - if (retval != ISIS_OK) - return retval; - - if (isis->debugs & DEBUG_SNP_PACKETS) - { - for (ALL_LIST_ELEMENTS_RO (lsps, node, lsp)) - { - zlog_debug ("ISIS-Snp (%s): PSNP entry %s, seq 0x%08x," - " cksum 0x%04x, lifetime %us", - circuit->area->area_tag, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime)); - } - } + struct isis_fixed_hdr fixed_hdr; + unsigned long lenp; + u_int16_t length; + struct isis_lsp *lsp; + struct isis_passwd *passwd; + struct listnode *node; + unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; + unsigned long auth_tlv_offset = 0; + int retval = ISIS_OK; + + isis_circuit_stream(circuit, &circuit->snd_stream); + + if (level == IS_LEVEL_1) + fill_fixed_hdr_andstream(&fixed_hdr, L1_PARTIAL_SEQ_NUM, + circuit->snd_stream); + else + fill_fixed_hdr_andstream(&fixed_hdr, L2_PARTIAL_SEQ_NUM, + circuit->snd_stream); + + /* + * Fill Level 1 or 2 Partial Sequence Numbers header + */ + lenp = stream_get_endp(circuit->snd_stream); + stream_putw(circuit->snd_stream, 0); /* PDU length - when we know it */ + stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); + stream_putc(circuit->snd_stream, circuit->idx); + + /* + * And TLVs + */ + + if (level == IS_LEVEL_1) + passwd = &circuit->area->area_passwd; + else + passwd = &circuit->area->domain_passwd; + + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) { + switch (passwd->type) { + /* Cleartext */ + case ISIS_PASSWD_TYPE_CLEARTXT: + if (tlv_add_authinfo(ISIS_PASSWD_TYPE_CLEARTXT, + passwd->len, passwd->passwd, + circuit->snd_stream)) + return ISIS_WARNING; + break; + + /* HMAC MD5 */ + case ISIS_PASSWD_TYPE_HMAC_MD5: + /* Remember where TLV is written so we can later + * overwrite the MD5 hash */ + auth_tlv_offset = stream_get_endp(circuit->snd_stream); + memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE); + if (tlv_add_authinfo(ISIS_PASSWD_TYPE_HMAC_MD5, + ISIS_AUTH_MD5_SIZE, hmac_md5_hash, + circuit->snd_stream)) + return ISIS_WARNING; + break; + + default: + break; + } + } - length = (u_int16_t) stream_get_endp (circuit->snd_stream); - /* Update PDU length */ - stream_putw_at (circuit->snd_stream, lenp, length); + retval = tlv_add_lsp_entries(lsps, circuit->snd_stream); + if (retval != ISIS_OK) + return retval; + + if (isis->debugs & DEBUG_SNP_PACKETS) { + for (ALL_LIST_ELEMENTS_RO(lsps, node, lsp)) { + zlog_debug( + "ISIS-Snp (%s): PSNP entry %s, seq 0x%08x," + " cksum 0x%04x, lifetime %us", + circuit->area->area_tag, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime)); + } + } - /* For HMAC MD5 we need to compute the md5 hash and store it */ - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) && - passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - hmac_md5 (STREAM_DATA (circuit->snd_stream), - stream_get_endp(circuit->snd_stream), - (unsigned char *) &passwd->passwd, passwd->len, - (unsigned char *) &hmac_md5_hash); - /* Copy the hash into the stream */ - memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, - hmac_md5_hash, ISIS_AUTH_MD5_SIZE); - } + length = (u_int16_t)stream_get_endp(circuit->snd_stream); + /* Update PDU length */ + stream_putw_at(circuit->snd_stream, lenp, length); + + /* For HMAC MD5 we need to compute the md5 hash and store it */ + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) + && passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) { + hmac_md5(STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream), + (unsigned char *)&passwd->passwd, passwd->len, + (unsigned char *)&hmac_md5_hash); + /* Copy the hash into the stream */ + memcpy(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3, + hmac_md5_hash, ISIS_AUTH_MD5_SIZE); + } - return ISIS_OK; + return ISIS_OK; } /* * 7.3.15.4 action on expiration of partial SNP interval * level 1 */ -static int -send_psnp (int level, struct isis_circuit *circuit) +static int send_psnp(int level, struct isis_circuit *circuit) { - struct isis_lsp *lsp; - struct list *list = NULL; - struct listnode *node; - u_char num_lsps; - int retval = ISIS_OK; + struct isis_lsp *lsp; + struct list *list = NULL; + struct listnode *node; + u_char num_lsps; + int retval = ISIS_OK; - if (circuit->circ_type == CIRCUIT_T_BROADCAST && - circuit->u.bc.is_dr[level - 1]) - return ISIS_OK; + if (circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[level - 1]) + return ISIS_OK; - if (circuit->area->lspdb[level - 1] == NULL || - dict_count (circuit->area->lspdb[level - 1]) == 0) - return ISIS_OK; + if (circuit->area->lspdb[level - 1] == NULL + || dict_count(circuit->area->lspdb[level - 1]) == 0) + return ISIS_OK; - if (! circuit->snd_stream) - return ISIS_ERROR; + if (!circuit->snd_stream) + return ISIS_ERROR; - num_lsps = max_lsps_per_snp (ISIS_SNP_PSNP_FLAG, level, circuit); + num_lsps = max_lsps_per_snp(ISIS_SNP_PSNP_FLAG, level, circuit); - while (1) - { - list = list_new (); - lsp_build_list_ssn (circuit, num_lsps, list, - circuit->area->lspdb[level - 1]); - - if (listcount (list) == 0) - { - list_delete (list); - return ISIS_OK; - } - - retval = build_psnp (level, circuit, list); - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Snp (%s): Build L%d PSNP on %s failed", - circuit->area->area_tag, level, circuit->interface->name); - list_delete (list); - return retval; - } - - if (isis->debugs & DEBUG_SNP_PACKETS) - { - zlog_debug ("ISIS-Snp (%s): Sending L%d PSNP on %s, length %zd", - circuit->area->area_tag, level, - circuit->interface->name, - stream_get_endp (circuit->snd_stream)); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->snd_stream), - stream_get_endp (circuit->snd_stream)); - } - - retval = circuit->tx (circuit, level); - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Snp (%s): Send L%d PSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); - list_delete (list); - return retval; - } - - /* - * sending succeeded, we can clear SSN flags of this circuit - * for the LSPs in list - */ - for (ALL_LIST_ELEMENTS_RO (list, node, lsp)) - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); - list_delete (list); - } + while (1) { + list = list_new(); + lsp_build_list_ssn(circuit, num_lsps, list, + circuit->area->lspdb[level - 1]); + + if (listcount(list) == 0) { + list_delete(list); + return ISIS_OK; + } + + retval = build_psnp(level, circuit, list); + if (retval != ISIS_OK) { + zlog_err("ISIS-Snp (%s): Build L%d PSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); + list_delete(list); + return retval; + } + + if (isis->debugs & DEBUG_SNP_PACKETS) { + zlog_debug( + "ISIS-Snp (%s): Sending L%d PSNP on %s, length %zd", + circuit->area->area_tag, level, + circuit->interface->name, + stream_get_endp(circuit->snd_stream)); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data( + STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream)); + } + + retval = circuit->tx(circuit, level); + if (retval != ISIS_OK) { + zlog_err("ISIS-Snp (%s): Send L%d PSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); + list_delete(list); + return retval; + } - return retval; + /* + * sending succeeded, we can clear SSN flags of this circuit + * for the LSPs in list + */ + for (ALL_LIST_ELEMENTS_RO(list, node, lsp)) + ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); + list_delete(list); + } + + return retval; } -int -send_l1_psnp (struct thread *thread) +int send_l1_psnp(struct thread *thread) { - struct isis_circuit *circuit; - int retval = ISIS_OK; + struct isis_circuit *circuit; + int retval = ISIS_OK; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - circuit->t_send_psnp[0] = NULL; + circuit->t_send_psnp[0] = NULL; - send_psnp (1, circuit); - /* set next timer thread */ - thread_add_timer(master, send_l1_psnp, circuit, - isis_jitter(circuit->psnp_interval[0], PSNP_JITTER), - &circuit->t_send_psnp[0]); + send_psnp(1, circuit); + /* set next timer thread */ + thread_add_timer(master, send_l1_psnp, circuit, + isis_jitter(circuit->psnp_interval[0], PSNP_JITTER), + &circuit->t_send_psnp[0]); - return retval; + return retval; } /* * 7.3.15.4 action on expiration of partial SNP interval * level 2 */ -int -send_l2_psnp (struct thread *thread) +int send_l2_psnp(struct thread *thread) { - struct isis_circuit *circuit; - int retval = ISIS_OK; + struct isis_circuit *circuit; + int retval = ISIS_OK; - circuit = THREAD_ARG (thread); - assert (circuit); + circuit = THREAD_ARG(thread); + assert(circuit); - circuit->t_send_psnp[1] = NULL; + circuit->t_send_psnp[1] = NULL; - send_psnp (2, circuit); + send_psnp(2, circuit); - /* set next timer thread */ - thread_add_timer(master, send_l2_psnp, circuit, - isis_jitter(circuit->psnp_interval[1], PSNP_JITTER), - &circuit->t_send_psnp[1]); + /* set next timer thread */ + thread_add_timer(master, send_l2_psnp, circuit, + isis_jitter(circuit->psnp_interval[1], PSNP_JITTER), + &circuit->t_send_psnp[1]); - return retval; + return retval; } /* * ISO 10589 - 7.3.14.3 */ -int -send_lsp (struct thread *thread) +int send_lsp(struct thread *thread) { - struct isis_circuit *circuit; - struct isis_lsp *lsp; - struct listnode *node; - int clear_srm = 1; - int retval = ISIS_OK; - - circuit = THREAD_ARG (thread); - assert (circuit); - - if (!circuit->lsp_queue) - return ISIS_OK; - - node = listhead (circuit->lsp_queue); - - /* - * Handle case where there are no LSPs on the queue. This can - * happen, for instance, if an adjacency goes down before this - * thread gets a chance to run. - */ - if (!node) - return ISIS_OK; - - /* - * Delete LSP from lsp_queue. If it's still in queue, it is assumed - * as 'transmit pending', but send_lsp may never be called again. - * Retry will happen because SRM flag will not be cleared. - */ - lsp = listgetdata(node); - list_delete_node (circuit->lsp_queue, node); - - /* Set the last-cleared time if the queue is empty. */ - /* TODO: Is is possible that new lsps keep being added to the queue - * that the queue is never empty? */ - if (list_isempty (circuit->lsp_queue)) - circuit->lsp_queue_last_cleared = time (NULL); - - if (circuit->state != C_STATE_UP || circuit->is_passive == 1) - goto out; - - /* - * Do not send if levels do not match - */ - if (!(lsp->level & circuit->is_type)) - goto out; - - /* - * Do not send if we do not have adjacencies in state up on the circuit - */ - if (circuit->upadjcount[lsp->level - 1] == 0) - goto out; - - /* stream_copy will assert and stop program execution if LSP is larger than - * the circuit's MTU. So handle and log this case here. */ - if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) - { - zlog_err("ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x," - " cksum 0x%04x, lifetime %us on %s. LSP Size is %zu" - " while interface stream size is %zu.", - circuit->area->area_tag, lsp->level, - rawlspid_print(lsp->lsp_header->lsp_id), - ntohl(lsp->lsp_header->seq_num), - ntohs(lsp->lsp_header->checksum), - ntohs(lsp->lsp_header->rem_lifetime), - circuit->interface->name, - stream_get_endp(lsp->pdu), - stream_get_size(circuit->snd_stream)); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data(STREAM_DATA(lsp->pdu), stream_get_endp(lsp->pdu)); - retval = ISIS_ERROR; - goto out; - } - - /* copy our lsp to the send buffer */ - stream_copy (circuit->snd_stream, lsp->pdu); + struct isis_circuit *circuit; + struct isis_lsp *lsp; + struct listnode *node; + int clear_srm = 1; + int retval = ISIS_OK; + + circuit = THREAD_ARG(thread); + assert(circuit); + + if (!circuit->lsp_queue) + return ISIS_OK; + + node = listhead(circuit->lsp_queue); + + /* + * Handle case where there are no LSPs on the queue. This can + * happen, for instance, if an adjacency goes down before this + * thread gets a chance to run. + */ + if (!node) + return ISIS_OK; + + /* + * Delete LSP from lsp_queue. If it's still in queue, it is assumed + * as 'transmit pending', but send_lsp may never be called again. + * Retry will happen because SRM flag will not be cleared. + */ + lsp = listgetdata(node); + list_delete_node(circuit->lsp_queue, node); + + /* Set the last-cleared time if the queue is empty. */ + /* TODO: Is is possible that new lsps keep being added to the queue + * that the queue is never empty? */ + if (list_isempty(circuit->lsp_queue)) + circuit->lsp_queue_last_cleared = time(NULL); + + if (circuit->state != C_STATE_UP || circuit->is_passive == 1) + goto out; + + /* + * Do not send if levels do not match + */ + if (!(lsp->level & circuit->is_type)) + goto out; + + /* + * Do not send if we do not have adjacencies in state up on the circuit + */ + if (circuit->upadjcount[lsp->level - 1] == 0) + goto out; + + /* stream_copy will assert and stop program execution if LSP is larger + * than + * the circuit's MTU. So handle and log this case here. */ + if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) { + zlog_err( + "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x," + " cksum 0x%04x, lifetime %us on %s. LSP Size is %zu" + " while interface stream size is %zu.", + circuit->area->area_tag, lsp->level, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime), + circuit->interface->name, stream_get_endp(lsp->pdu), + stream_get_size(circuit->snd_stream)); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(lsp->pdu), + stream_get_endp(lsp->pdu)); + retval = ISIS_ERROR; + goto out; + } - if (isis->debugs & DEBUG_UPDATE_PACKETS) - { - zlog_debug - ("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08x, cksum 0x%04x," - " lifetime %us on %s", circuit->area->area_tag, lsp->level, - rawlspid_print (lsp->lsp_header->lsp_id), - ntohl (lsp->lsp_header->seq_num), - ntohs (lsp->lsp_header->checksum), - ntohs (lsp->lsp_header->rem_lifetime), - circuit->interface->name); - if (isis->debugs & DEBUG_PACKET_DUMP) - zlog_dump_data (STREAM_DATA (circuit->snd_stream), - stream_get_endp (circuit->snd_stream)); - } + /* copy our lsp to the send buffer */ + stream_copy(circuit->snd_stream, lsp->pdu); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) { + zlog_debug( + "ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08x, cksum 0x%04x," + " lifetime %us on %s", + circuit->area->area_tag, lsp->level, + rawlspid_print(lsp->lsp_header->lsp_id), + ntohl(lsp->lsp_header->seq_num), + ntohs(lsp->lsp_header->checksum), + ntohs(lsp->lsp_header->rem_lifetime), + circuit->interface->name); + if (isis->debugs & DEBUG_PACKET_DUMP) + zlog_dump_data(STREAM_DATA(circuit->snd_stream), + stream_get_endp(circuit->snd_stream)); + } - clear_srm = 0; - retval = circuit->tx (circuit, lsp->level); - if (retval != ISIS_OK) - { - zlog_err ("ISIS-Upd (%s): Send L%d LSP on %s failed %s", - circuit->area->area_tag, lsp->level, - circuit->interface->name, - (retval == ISIS_WARNING) ? "temporarily" : "permanently"); - } + clear_srm = 0; + retval = circuit->tx(circuit, lsp->level); + if (retval != ISIS_OK) { + zlog_err("ISIS-Upd (%s): Send L%d LSP on %s failed %s", + circuit->area->area_tag, lsp->level, + circuit->interface->name, + (retval == ISIS_WARNING) ? "temporarily" + : "permanently"); + } out: - if (clear_srm - || (retval == ISIS_OK && circuit->circ_type == CIRCUIT_T_BROADCAST) - || (retval != ISIS_OK && retval != ISIS_WARNING)) - { - /* SRM flag will trigger retransmission. We will not retransmit if we - * encountered a fatal error. - * On success, they should only be cleared if it's a broadcast circuit. - * On a P2P circuit, we will wait for the ack from the neighbor to clear - * the fag. - */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - } + if (clear_srm + || (retval == ISIS_OK && circuit->circ_type == CIRCUIT_T_BROADCAST) + || (retval != ISIS_OK && retval != ISIS_WARNING)) { + /* SRM flag will trigger retransmission. We will not retransmit + * if we + * encountered a fatal error. + * On success, they should only be cleared if it's a broadcast + * circuit. + * On a P2P circuit, we will wait for the ack from the neighbor + * to clear + * the fag. + */ + ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + } - return retval; + return retval; } -int -ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, - int level) +int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, + int level) { - unsigned long lenp; - int retval; - u_int16_t length; - struct isis_fixed_hdr fixed_hdr; - - isis_circuit_stream(circuit, &circuit->snd_stream); - - // fill_llc_hdr (stream); - if (level == IS_LEVEL_1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, - circuit->snd_stream); - else - fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM, - circuit->snd_stream); - - - lenp = stream_get_endp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length */ - stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); - stream_putc (circuit->snd_stream, circuit->idx); - stream_putc (circuit->snd_stream, 9); /* code */ - stream_putc (circuit->snd_stream, 16); /* len */ - - stream_putw (circuit->snd_stream, ntohs (hdr->rem_lifetime)); - stream_put (circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2); - stream_putl (circuit->snd_stream, ntohl (hdr->seq_num)); - stream_putw (circuit->snd_stream, ntohs (hdr->checksum)); - - length = (u_int16_t) stream_get_endp (circuit->snd_stream); - /* Update PDU length */ - stream_putw_at (circuit->snd_stream, lenp, length); - - retval = circuit->tx (circuit, level); - if (retval != ISIS_OK) - zlog_err ("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); - - return retval; + unsigned long lenp; + int retval; + u_int16_t length; + struct isis_fixed_hdr fixed_hdr; + + isis_circuit_stream(circuit, &circuit->snd_stream); + + // fill_llc_hdr (stream); + if (level == IS_LEVEL_1) + fill_fixed_hdr_andstream(&fixed_hdr, L1_PARTIAL_SEQ_NUM, + circuit->snd_stream); + else + fill_fixed_hdr_andstream(&fixed_hdr, L2_PARTIAL_SEQ_NUM, + circuit->snd_stream); + + + lenp = stream_get_endp(circuit->snd_stream); + stream_putw(circuit->snd_stream, 0); /* PDU length */ + stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); + stream_putc(circuit->snd_stream, circuit->idx); + stream_putc(circuit->snd_stream, 9); /* code */ + stream_putc(circuit->snd_stream, 16); /* len */ + + stream_putw(circuit->snd_stream, ntohs(hdr->rem_lifetime)); + stream_put(circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2); + stream_putl(circuit->snd_stream, ntohl(hdr->seq_num)); + stream_putw(circuit->snd_stream, ntohs(hdr->checksum)); + + length = (u_int16_t)stream_get_endp(circuit->snd_stream); + /* Update PDU length */ + stream_putw_at(circuit->snd_stream, lenp, length); + + retval = circuit->tx(circuit, level); + if (retval != ISIS_OK) + zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); + + return retval; } diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h index e512b6b1b..fa8006cda 100644 --- a/isisd/isis_pdu.h +++ b/isisd/isis_pdu.h @@ -3,17 +3,17 @@ * PDU processing * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -49,16 +49,15 @@ * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct esis_fixed_hdr -{ - u_char idrp; - u_char length; - u_char version; - u_char id_len; - u_char pdu_type; - u_int16_t holdtime; - u_int16_t checksum; -} __attribute__ ((packed)); +struct esis_fixed_hdr { + u_char idrp; + u_char length; + u_char version; + u_char id_len; + u_char pdu_type; + u_int16_t holdtime; + u_int16_t checksum; +} __attribute__((packed)); #define ESIS_FIXED_HDR_LEN 9 @@ -69,33 +68,32 @@ struct esis_fixed_hdr /* * IS to IS Fixed Header * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Intradomain Routeing Protocol Discriminator | + * | Intradomain Routeing Protocol Discriminator | * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Length Indicator | * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Version/Protocol ID extension | * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | R | R | R | PDU Type | + * | R | R | R | PDU Type | * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Version | * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Reserved | * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Maximum Area Addresses | + * | Maximum Area Addresses | * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct isis_fixed_hdr -{ - u_char idrp; - u_char length; - u_char version1; - u_char id_len; - u_char pdu_type; - u_char version2; - u_char reserved; - u_char max_area_addrs; -} __attribute__ ((packed)); +struct isis_fixed_hdr { + u_char idrp; + u_char length; + u_char version1; + u_char id_len; + u_char pdu_type; + u_char version2; + u_char reserved; + u_char max_area_addrs; +} __attribute__((packed)); #define ISIS_FIXED_HDR_LEN 8 @@ -110,26 +108,25 @@ struct isis_fixed_hdr * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Reserved | Circuit Type | 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + Source ID + id_len + * + Source ID + id_len * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Holding Time | 2 + * | Holding Time | 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | PDU Length | 2 + * | PDU Length | 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ * | R | Priority | 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ * | LAN ID | id_len + 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct isis_lan_hello_hdr -{ - u_char circuit_t; - u_char source_id[ISIS_SYS_ID_LEN]; - u_int16_t hold_time; - u_int16_t pdu_len; - u_char prio; - u_char lan_id[ISIS_SYS_ID_LEN + 1]; -} __attribute__ ((packed)); +struct isis_lan_hello_hdr { + u_char circuit_t; + u_char source_id[ISIS_SYS_ID_LEN]; + u_int16_t hold_time; + u_int16_t pdu_len; + u_char prio; + u_char lan_id[ISIS_SYS_ID_LEN + 1]; +} __attribute__((packed)); #define ISIS_LANHELLO_HDRLEN 19 #define P2P_HELLO 17 @@ -138,23 +135,22 @@ struct isis_lan_hello_hdr * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Reserved | Circuit Type | 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + Source ID + id_len + * + Source ID + id_len * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + Holding Time + 2 + * + Holding Time + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + PDU Length + 2 + * + PDU Length + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ * | Local Circuit ID | 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct isis_p2p_hello_hdr -{ - u_char circuit_t; - u_char source_id[ISIS_SYS_ID_LEN]; - u_int16_t hold_time; - u_int16_t pdu_len; - u_char local_id; -} __attribute__ ((packed)); +struct isis_p2p_hello_hdr { + u_char circuit_t; + u_char source_id[ISIS_SYS_ID_LEN]; + u_int16_t hold_time; + u_int16_t pdu_len; + u_char local_id; +} __attribute__((packed)); #define ISIS_P2PHELLO_HDRLEN 12 #define L1_LINK_STATE 18 @@ -164,7 +160,7 @@ struct isis_p2p_hello_hdr * +-------+-------+-------+-------+-------+-------+-------+-------+ * + PDU Length + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + Remaining Lifetime + 2 + * + Remaining Lifetime + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ * | LSP ID | id_len + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ @@ -175,15 +171,14 @@ struct isis_p2p_hello_hdr * | P | ATT |LSPDBOL| ISTYPE | * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct isis_link_state_hdr -{ - u_int16_t pdu_len; - u_int16_t rem_lifetime; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - u_int32_t seq_num; - u_int16_t checksum; - u_int8_t lsp_bits; -} __attribute__ ((packed)); +struct isis_link_state_hdr { + u_int16_t pdu_len; + u_int16_t rem_lifetime; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + u_int32_t seq_num; + u_int16_t checksum; + u_int8_t lsp_bits; +} __attribute__((packed)); #define ISIS_LSP_HDR_LEN 19 /* @@ -191,7 +186,7 @@ struct isis_link_state_hdr * entry is LSP_ENTRIES_LEN (16) bytes long, the maximum number of LSP entries * can be accomodated in a TLV is * 255 / 16 = 15. - * + * * Therefore, the maximum length of the LSP Entries TLV is * 16 * 15 + 2 (header) = 242 bytes. */ @@ -202,7 +197,7 @@ struct isis_link_state_hdr /* * L1 and L2 IS to IS complete sequence numbers PDU header * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + PDU Length + 2 + * + PDU Length + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ * + Source ID + id_len + 1 * +-------+-------+-------+-------+-------+-------+-------+-------+ @@ -211,12 +206,11 @@ struct isis_link_state_hdr * + End LSP ID + id_len + 2 * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -struct isis_complete_seqnum_hdr -{ - u_int16_t pdu_len; - u_char source_id[ISIS_SYS_ID_LEN + 1]; - u_char start_lsp_id[ISIS_SYS_ID_LEN + 2]; - u_char stop_lsp_id[ISIS_SYS_ID_LEN + 2]; +struct isis_complete_seqnum_hdr { + u_int16_t pdu_len; + u_char source_id[ISIS_SYS_ID_LEN + 1]; + u_char start_lsp_id[ISIS_SYS_ID_LEN + 2]; + u_char stop_lsp_id[ISIS_SYS_ID_LEN + 2]; }; #define ISIS_CSNP_HDRLEN 25 @@ -230,10 +224,9 @@ struct isis_complete_seqnum_hdr * + Source ID + id_len + 1 * +---------------------------------------------------------------+ */ -struct isis_partial_seqnum_hdr -{ - u_int16_t pdu_len; - u_char source_id[ISIS_SYS_ID_LEN + 1]; +struct isis_partial_seqnum_hdr { + u_int16_t pdu_len; + u_char source_id[ISIS_SYS_ID_LEN + 1]; }; #define ISIS_PSNP_HDRLEN 9 @@ -244,7 +237,7 @@ struct isis_partial_seqnum_hdr /* * Function for receiving IS-IS PDUs */ -int isis_receive (struct thread *thread); +int isis_receive(struct thread *thread); /* * calling arguments for snp_process () @@ -257,18 +250,18 @@ int isis_receive (struct thread *thread); /* * Sending functions */ -int send_lan_l1_hello (struct thread *thread); -int send_lan_l2_hello (struct thread *thread); -int send_p2p_hello (struct thread *thread); -int send_csnp (struct isis_circuit *circuit, int level); -int send_l1_csnp (struct thread *thread); -int send_l2_csnp (struct thread *thread); -int send_l1_psnp (struct thread *thread); -int send_l2_psnp (struct thread *thread); -int send_lsp (struct thread *thread); -int ack_lsp (struct isis_link_state_hdr *hdr, - struct isis_circuit *circuit, int level); -void fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type); -int send_hello (struct isis_circuit *circuit, int level); +int send_lan_l1_hello(struct thread *thread); +int send_lan_l2_hello(struct thread *thread); +int send_p2p_hello(struct thread *thread); +int send_csnp(struct isis_circuit *circuit, int level); +int send_l1_csnp(struct thread *thread); +int send_l2_csnp(struct thread *thread); +int send_l1_psnp(struct thread *thread); +int send_l2_psnp(struct thread *thread); +int send_lsp(struct thread *thread); +int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, + int level); +void fill_fixed_hdr(struct isis_fixed_hdr *hdr, u_char pdu_type); +int send_hello(struct isis_circuit *circuit, int level); #endif /* _ZEBRA_ISIS_PDU_H */ diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c index c5985dcd8..e24901b0d 100644 --- a/isisd/isis_pfpacket.c +++ b/isisd/isis_pfpacket.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isis_pfpacket.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -22,7 +22,7 @@ #include <zebra.h> #if ISIS_METHOD == ISIS_METHOD_PFPACKET -#include <net/ethernet.h> /* the L2 protocols */ +#include <net/ethernet.h> /* the L2 protocols */ #include <netpacket/packet.h> #include <linux/filter.h> @@ -47,17 +47,17 @@ extern struct zebra_privs_t isisd_privs; /* tcpdump -i eth0 'isis' -dd */ -static struct sock_filter isisfilter[] = { -/* NB: we're in SOCK_DGRAM, so src/dst mac + length are stripped off! - * (OTOH it's a bit more lower-layer agnostic and might work over GRE?) */ -/* { 0x28, 0, 0, 0x0000000c - 14 }, */ -/* { 0x25, 5, 0, 0x000005dc }, */ - { 0x28, 0, 0, 0x0000000e - 14 }, - { 0x15, 0, 3, 0x0000fefe }, - { 0x30, 0, 0, 0x00000011 - 14 }, - { 0x15, 0, 1, 0x00000083 }, - { 0x6, 0, 0, 0x00040000 }, - { 0x6, 0, 0, 0x00000000 }, +static struct sock_filter isisfilter[] = + { + /* NB: we're in SOCK_DGRAM, so src/dst mac + length are stripped + * off! + * (OTOH it's a bit more lower-layer agnostic and might work + * over GRE?) */ + /* { 0x28, 0, 0, 0x0000000c - 14 }, */ + /* { 0x25, 5, 0, 0x000005dc }, */ + {0x28, 0, 0, 0x0000000e - 14}, {0x15, 0, 3, 0x0000fefe}, + {0x30, 0, 0, 0x00000011 - 14}, {0x15, 0, 1, 0x00000083}, + {0x6, 0, 0, 0x00040000}, {0x6, 0, 0, 0x00000000}, }; static struct sock_fprog bpf = { @@ -70,10 +70,10 @@ static struct sock_fprog bpf = { * ISO 10589 - 8.4.8 */ -u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 }; -u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 }; -u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 }; -u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 }; +u_char ALL_L1_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x14}; +u_char ALL_L2_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x15}; +u_char ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05}; +u_char ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04}; static uint8_t discard_buff[8192]; static uint8_t sock_buff[8192]; @@ -82,367 +82,346 @@ static uint8_t sock_buff[8192]; * if level is 0 we are joining p2p multicast * FIXME: and the p2p multicast being ??? */ -static int -isis_multicast_join (int fd, int registerto, int if_num) +static int isis_multicast_join(int fd, int registerto, int if_num) { - struct packet_mreq mreq; - - memset (&mreq, 0, sizeof (mreq)); - mreq.mr_ifindex = if_num; - if (registerto) - { - mreq.mr_type = PACKET_MR_MULTICAST; - mreq.mr_alen = ETH_ALEN; - if (registerto == 1) - memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN); - else if (registerto == 2) - memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN); - else if (registerto == 3) - memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN); - else - memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN); - - } - else - { - mreq.mr_type = PACKET_MR_ALLMULTI; - } + struct packet_mreq mreq; + + memset(&mreq, 0, sizeof(mreq)); + mreq.mr_ifindex = if_num; + if (registerto) { + mreq.mr_type = PACKET_MR_MULTICAST; + mreq.mr_alen = ETH_ALEN; + if (registerto == 1) + memcpy(&mreq.mr_address, ALL_L1_ISS, ETH_ALEN); + else if (registerto == 2) + memcpy(&mreq.mr_address, ALL_L2_ISS, ETH_ALEN); + else if (registerto == 3) + memcpy(&mreq.mr_address, ALL_ISS, ETH_ALEN); + else + memcpy(&mreq.mr_address, ALL_ESS, ETH_ALEN); + + } else { + mreq.mr_type = PACKET_MR_ALLMULTI; + } #ifdef EXTREME_DEBUG - zlog_debug ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, " - "address = %02x:%02x:%02x:%02x:%02x:%02x", - fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1], - mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4], - mreq.mr_address[5]); + zlog_debug( + "isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, " + "address = %02x:%02x:%02x:%02x:%02x:%02x", + fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1], + mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4], + mreq.mr_address[5]); #endif /* EXTREME_DEBUG */ - if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, - sizeof (struct packet_mreq))) - { - zlog_warn ("isis_multicast_join(): setsockopt(): %s", safe_strerror (errno)); - return ISIS_WARNING; - } - - return ISIS_OK; + if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, + sizeof(struct packet_mreq))) { + zlog_warn("isis_multicast_join(): setsockopt(): %s", + safe_strerror(errno)); + return ISIS_WARNING; + } + + return ISIS_OK; } -static int -open_packet_socket (struct isis_circuit *circuit) +static int open_packet_socket(struct isis_circuit *circuit) { - struct sockaddr_ll s_addr; - int fd, retval = ISIS_OK; - - fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL)); - if (fd < 0) - { - zlog_warn ("open_packet_socket(): socket() failed %s", - safe_strerror (errno)); - return ISIS_WARNING; - } - - if (setsockopt (fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof (bpf))) - { - zlog_warn ("open_packet_socket(): SO_ATTACH_FILTER failed: %s", - safe_strerror (errno)); - } - - /* - * Bind to the physical interface - */ - memset (&s_addr, 0, sizeof (struct sockaddr_ll)); - s_addr.sll_family = AF_PACKET; - s_addr.sll_protocol = htons (ETH_P_ALL); - s_addr.sll_ifindex = circuit->interface->ifindex; - - if (bind (fd, (struct sockaddr *) (&s_addr), - sizeof (struct sockaddr_ll)) < 0) - { - zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno)); - close (fd); - return ISIS_WARNING; - } - - circuit->fd = fd; - - if (if_is_broadcast (circuit->interface)) - { - /* - * Join to multicast groups - * according to - * 8.4.2 - Broadcast subnetwork IIH PDUs - * FIXME: is there a case only one will fail?? - */ - /* joining ALL_L1_ISS */ - retval |= isis_multicast_join (circuit->fd, 1, - circuit->interface->ifindex); - /* joining ALL_L2_ISS */ - retval |= isis_multicast_join (circuit->fd, 2, - circuit->interface->ifindex); - /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */ - retval |= isis_multicast_join (circuit->fd, 3, - circuit->interface->ifindex); - } - else - { - retval = - isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex); - } - - return retval; + struct sockaddr_ll s_addr; + int fd, retval = ISIS_OK; + + fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); + if (fd < 0) { + zlog_warn("open_packet_socket(): socket() failed %s", + safe_strerror(errno)); + return ISIS_WARNING; + } + + if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))) { + zlog_warn("open_packet_socket(): SO_ATTACH_FILTER failed: %s", + safe_strerror(errno)); + } + + /* + * Bind to the physical interface + */ + memset(&s_addr, 0, sizeof(struct sockaddr_ll)); + s_addr.sll_family = AF_PACKET; + s_addr.sll_protocol = htons(ETH_P_ALL); + s_addr.sll_ifindex = circuit->interface->ifindex; + + if (bind(fd, (struct sockaddr *)(&s_addr), sizeof(struct sockaddr_ll)) + < 0) { + zlog_warn("open_packet_socket(): bind() failed: %s", + safe_strerror(errno)); + close(fd); + return ISIS_WARNING; + } + + circuit->fd = fd; + + if (if_is_broadcast(circuit->interface)) { + /* + * Join to multicast groups + * according to + * 8.4.2 - Broadcast subnetwork IIH PDUs + * FIXME: is there a case only one will fail?? + */ + /* joining ALL_L1_ISS */ + retval |= isis_multicast_join(circuit->fd, 1, + circuit->interface->ifindex); + /* joining ALL_L2_ISS */ + retval |= isis_multicast_join(circuit->fd, 2, + circuit->interface->ifindex); + /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */ + retval |= isis_multicast_join(circuit->fd, 3, + circuit->interface->ifindex); + } else { + retval = isis_multicast_join(circuit->fd, 0, + circuit->interface->ifindex); + } + + return retval; } /* * Create the socket and set the tx/rx funcs */ -int -isis_sock_init (struct isis_circuit *circuit) +int isis_sock_init(struct isis_circuit *circuit) { - int retval = ISIS_OK; - - if (isisd_privs.change (ZPRIVS_RAISE)) - zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno)); - - retval = open_packet_socket (circuit); - - if (retval != ISIS_OK) - { - zlog_warn ("%s: could not initialize the socket", __func__); - goto end; - } - - /* Assign Rx and Tx callbacks are based on real if type */ - if (if_is_broadcast (circuit->interface)) - { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } - else if (if_is_pointopoint (circuit->interface)) - { - circuit->tx = isis_send_pdu_p2p; - circuit->rx = isis_recv_pdu_p2p; - } - else - { - zlog_warn ("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; - } + int retval = ISIS_OK; + + if (isisd_privs.change(ZPRIVS_RAISE)) + zlog_err("%s: could not raise privs, %s", __func__, + safe_strerror(errno)); + + retval = open_packet_socket(circuit); + + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", __func__); + goto end; + } + + /* Assign Rx and Tx callbacks are based on real if type */ + if (if_is_broadcast(circuit->interface)) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else if (if_is_pointopoint(circuit->interface)) { + circuit->tx = isis_send_pdu_p2p; + circuit->rx = isis_recv_pdu_p2p; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + goto end; + } end: - if (isisd_privs.change (ZPRIVS_LOWER)) - zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno)); + if (isisd_privs.change(ZPRIVS_LOWER)) + zlog_err("%s: could not lower privs, %s", __func__, + safe_strerror(errno)); - return retval; + return retval; } -static inline int -llc_check (u_char * llc) +static inline int llc_check(u_char *llc) { - if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3) - return 0; + if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3) + return 0; - return 1; + return 1; } -int -isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa) +int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) { - int bytesread, addr_len; - struct sockaddr_ll s_addr; - u_char llc[LLC_LEN]; - - addr_len = sizeof (s_addr); - - memset (&s_addr, 0, sizeof (struct sockaddr_ll)); - - bytesread = recvfrom (circuit->fd, (void *) &llc, - LLC_LEN, MSG_PEEK, - (struct sockaddr *) &s_addr, (socklen_t *) &addr_len); - - if ((bytesread < 0) || (s_addr.sll_ifindex != (int)circuit->interface->ifindex)) - { - if (bytesread < 0) - { - zlog_warn ("isis_recv_packet_bcast(): ifname %s, fd %d, " - "bytesread %d, recvfrom(): %s", - circuit->interface->name, circuit->fd, bytesread, - safe_strerror (errno)); - } - if (s_addr.sll_ifindex != (int)circuit->interface->ifindex) - { - zlog_warn("packet is received on multiple interfaces: " - "socket interface %d, circuit interface %d, " - "packet type %u", - s_addr.sll_ifindex, circuit->interface->ifindex, - s_addr.sll_pkttype); - } - - /* get rid of the packet */ - bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff), - MSG_DONTWAIT, (struct sockaddr *) &s_addr, - (socklen_t *) &addr_len); - - if (bytesread < 0) - zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed"); - - return ISIS_WARNING; - } - /* - * Filtering by llc field, discard packets sent by this host (other circuit) - */ - if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING) - { - /* Read the packet into discard buff */ - bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff), - MSG_DONTWAIT, (struct sockaddr *) &s_addr, - (socklen_t *) &addr_len); - if (bytesread < 0) - zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed"); - return ISIS_WARNING; - } - - /* on lan we have to read to the static buff first */ - bytesread = recvfrom (circuit->fd, sock_buff, sizeof (sock_buff), MSG_DONTWAIT, - (struct sockaddr *) &s_addr, (socklen_t *) &addr_len); - if (bytesread < 0) - { - zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed"); - return ISIS_WARNING; - } - - /* then we lose the LLC */ - stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN); - - memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen); - - return ISIS_OK; + int bytesread, addr_len; + struct sockaddr_ll s_addr; + u_char llc[LLC_LEN]; + + addr_len = sizeof(s_addr); + + memset(&s_addr, 0, sizeof(struct sockaddr_ll)); + + bytesread = + recvfrom(circuit->fd, (void *)&llc, LLC_LEN, MSG_PEEK, + (struct sockaddr *)&s_addr, (socklen_t *)&addr_len); + + if ((bytesread < 0) + || (s_addr.sll_ifindex != (int)circuit->interface->ifindex)) { + if (bytesread < 0) { + zlog_warn( + "isis_recv_packet_bcast(): ifname %s, fd %d, " + "bytesread %d, recvfrom(): %s", + circuit->interface->name, circuit->fd, + bytesread, safe_strerror(errno)); + } + if (s_addr.sll_ifindex != (int)circuit->interface->ifindex) { + zlog_warn( + "packet is received on multiple interfaces: " + "socket interface %d, circuit interface %d, " + "packet type %u", + s_addr.sll_ifindex, circuit->interface->ifindex, + s_addr.sll_pkttype); + } + + /* get rid of the packet */ + bytesread = recvfrom(circuit->fd, discard_buff, + sizeof(discard_buff), MSG_DONTWAIT, + (struct sockaddr *)&s_addr, + (socklen_t *)&addr_len); + + if (bytesread < 0) + zlog_warn("isis_recv_pdu_bcast(): recvfrom() failed"); + + return ISIS_WARNING; + } + /* + * Filtering by llc field, discard packets sent by this host (other + * circuit) + */ + if (!llc_check(llc) || s_addr.sll_pkttype == PACKET_OUTGOING) { + /* Read the packet into discard buff */ + bytesread = recvfrom(circuit->fd, discard_buff, + sizeof(discard_buff), MSG_DONTWAIT, + (struct sockaddr *)&s_addr, + (socklen_t *)&addr_len); + if (bytesread < 0) + zlog_warn("isis_recv_pdu_bcast(): recvfrom() failed"); + return ISIS_WARNING; + } + + /* on lan we have to read to the static buff first */ + bytesread = recvfrom(circuit->fd, sock_buff, sizeof(sock_buff), + MSG_DONTWAIT, (struct sockaddr *)&s_addr, + (socklen_t *)&addr_len); + if (bytesread < 0) { + zlog_warn("isis_recv_pdu_bcast(): recvfrom() failed"); + return ISIS_WARNING; + } + + /* then we lose the LLC */ + stream_write(circuit->rcv_stream, sock_buff + LLC_LEN, + bytesread - LLC_LEN); + + memcpy(ssnpa, &s_addr.sll_addr, s_addr.sll_halen); + + return ISIS_OK; } -int -isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa) +int isis_recv_pdu_p2p(struct isis_circuit *circuit, u_char *ssnpa) { - int bytesread, addr_len; - struct sockaddr_ll s_addr; - - memset (&s_addr, 0, sizeof (struct sockaddr_ll)); - addr_len = sizeof (s_addr); - - /* we can read directly to the stream */ - stream_recvfrom (circuit->rcv_stream, circuit->fd, - circuit->interface->mtu, 0, - (struct sockaddr *) &s_addr, - (socklen_t *) &addr_len); - - if (s_addr.sll_pkttype == PACKET_OUTGOING) - { - /* Read the packet into discard buff */ - bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff), - MSG_DONTWAIT, (struct sockaddr *) &s_addr, - (socklen_t *) &addr_len); - if (bytesread < 0) - zlog_warn ("isis_recv_pdu_p2p(): recvfrom() failed"); - return ISIS_WARNING; - } - - /* If we don't have protocol type 0x00FE which is - * ISO over GRE we exit with pain :) - */ - if (ntohs (s_addr.sll_protocol) != 0x00FE) - { - zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X", - ntohs (s_addr.sll_protocol)); - return ISIS_WARNING; - } - - memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen); - - return ISIS_OK; + int bytesread, addr_len; + struct sockaddr_ll s_addr; + + memset(&s_addr, 0, sizeof(struct sockaddr_ll)); + addr_len = sizeof(s_addr); + + /* we can read directly to the stream */ + stream_recvfrom(circuit->rcv_stream, circuit->fd, + circuit->interface->mtu, 0, (struct sockaddr *)&s_addr, + (socklen_t *)&addr_len); + + if (s_addr.sll_pkttype == PACKET_OUTGOING) { + /* Read the packet into discard buff */ + bytesread = recvfrom(circuit->fd, discard_buff, + sizeof(discard_buff), MSG_DONTWAIT, + (struct sockaddr *)&s_addr, + (socklen_t *)&addr_len); + if (bytesread < 0) + zlog_warn("isis_recv_pdu_p2p(): recvfrom() failed"); + return ISIS_WARNING; + } + + /* If we don't have protocol type 0x00FE which is + * ISO over GRE we exit with pain :) + */ + if (ntohs(s_addr.sll_protocol) != 0x00FE) { + zlog_warn("isis_recv_pdu_p2p(): protocol mismatch(): %X", + ntohs(s_addr.sll_protocol)); + return ISIS_WARNING; + } + + memcpy(ssnpa, &s_addr.sll_addr, s_addr.sll_halen); + + return ISIS_OK; } -int -isis_send_pdu_bcast (struct isis_circuit *circuit, int level) +int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) { - struct msghdr msg; - struct iovec iov[2]; - - /* we need to do the LLC in here because of P2P circuits, which will - * not need it - */ - struct sockaddr_ll sa; - - stream_set_getp (circuit->snd_stream, 0); - memset (&sa, 0, sizeof (struct sockaddr_ll)); - sa.sll_family = AF_PACKET; - - size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN; - sa.sll_protocol = htons(isis_ethertype(frame_size)); - sa.sll_ifindex = circuit->interface->ifindex; - sa.sll_halen = ETH_ALEN; - /* RFC5309 section 4.1 recommends ALL_ISS */ - if (circuit->circ_type == CIRCUIT_T_P2P) - memcpy (&sa.sll_addr, ALL_ISS, ETH_ALEN); - else if (level == 1) - memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN); - else - memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN); - - /* on a broadcast circuit */ - /* first we put the LLC in */ - sock_buff[0] = 0xFE; - sock_buff[1] = 0xFE; - sock_buff[2] = 0x03; - - memset (&msg, 0, sizeof (msg)); - msg.msg_name = &sa; - msg.msg_namelen = sizeof (struct sockaddr_ll); - msg.msg_iov = iov; - msg.msg_iovlen = 2; - iov[0].iov_base = sock_buff; - iov[0].iov_len = LLC_LEN; - iov[1].iov_base = circuit->snd_stream->data; - iov[1].iov_len = stream_get_endp (circuit->snd_stream); - - if (sendmsg(circuit->fd, &msg, 0) < 0) - { - zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s", - circuit->interface->name, safe_strerror(errno)); - if (ERRNO_IO_RETRY(errno)) - return ISIS_WARNING; - return ISIS_ERROR; - } - return ISIS_OK; + struct msghdr msg; + struct iovec iov[2]; + + /* we need to do the LLC in here because of P2P circuits, which will + * not need it + */ + struct sockaddr_ll sa; + + stream_set_getp(circuit->snd_stream, 0); + memset(&sa, 0, sizeof(struct sockaddr_ll)); + sa.sll_family = AF_PACKET; + + size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN; + sa.sll_protocol = htons(isis_ethertype(frame_size)); + sa.sll_ifindex = circuit->interface->ifindex; + sa.sll_halen = ETH_ALEN; + /* RFC5309 section 4.1 recommends ALL_ISS */ + if (circuit->circ_type == CIRCUIT_T_P2P) + memcpy(&sa.sll_addr, ALL_ISS, ETH_ALEN); + else if (level == 1) + memcpy(&sa.sll_addr, ALL_L1_ISS, ETH_ALEN); + else + memcpy(&sa.sll_addr, ALL_L2_ISS, ETH_ALEN); + + /* on a broadcast circuit */ + /* first we put the LLC in */ + sock_buff[0] = 0xFE; + sock_buff[1] = 0xFE; + sock_buff[2] = 0x03; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(struct sockaddr_ll); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + iov[0].iov_base = sock_buff; + iov[0].iov_len = LLC_LEN; + iov[1].iov_base = circuit->snd_stream->data; + iov[1].iov_len = stream_get_endp(circuit->snd_stream); + + if (sendmsg(circuit->fd, &msg, 0) < 0) { + zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s", + circuit->interface->name, safe_strerror(errno)); + if (ERRNO_IO_RETRY(errno)) + return ISIS_WARNING; + return ISIS_ERROR; + } + return ISIS_OK; } -int -isis_send_pdu_p2p (struct isis_circuit *circuit, int level) +int isis_send_pdu_p2p(struct isis_circuit *circuit, int level) { - struct sockaddr_ll sa; - ssize_t rv; - - stream_set_getp (circuit->snd_stream, 0); - memset (&sa, 0, sizeof (struct sockaddr_ll)); - sa.sll_family = AF_PACKET; - sa.sll_ifindex = circuit->interface->ifindex; - sa.sll_halen = ETH_ALEN; - if (level == 1) - memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN); - else - memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN); - - - /* lets try correcting the protocol */ - sa.sll_protocol = htons (0x00FE); - rv = sendto(circuit->fd, circuit->snd_stream->data, - stream_get_endp (circuit->snd_stream), 0, - (struct sockaddr *) &sa, - sizeof (struct sockaddr_ll)); - if (rv < 0) - { - zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s", - circuit->interface->name, safe_strerror(errno)); - if (ERRNO_IO_RETRY(errno)) - return ISIS_WARNING; - return ISIS_ERROR; - } - return ISIS_OK; + struct sockaddr_ll sa; + ssize_t rv; + + stream_set_getp(circuit->snd_stream, 0); + memset(&sa, 0, sizeof(struct sockaddr_ll)); + sa.sll_family = AF_PACKET; + sa.sll_ifindex = circuit->interface->ifindex; + sa.sll_halen = ETH_ALEN; + if (level == 1) + memcpy(&sa.sll_addr, ALL_L1_ISS, ETH_ALEN); + else + memcpy(&sa.sll_addr, ALL_L2_ISS, ETH_ALEN); + + + /* lets try correcting the protocol */ + sa.sll_protocol = htons(0x00FE); + rv = sendto(circuit->fd, circuit->snd_stream->data, + stream_get_endp(circuit->snd_stream), 0, + (struct sockaddr *)&sa, sizeof(struct sockaddr_ll)); + if (rv < 0) { + zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s", + circuit->interface->name, safe_strerror(errno)); + if (ERRNO_IO_RETRY(errno)) + return ISIS_WARNING; + return ISIS_ERROR; + } + return ISIS_OK; } #endif /* ISIS_METHOD == ISIS_METHOD_PFPACKET */ diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index b3f29fd20..8e329494d 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -3,14 +3,14 @@ * * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program 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 of the License, or (at your option) + * This program 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 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -43,514 +43,490 @@ #include "isisd/isis_route.h" #include "isisd/isis_zebra.h" -static int -redist_protocol(int family) +static int redist_protocol(int family) { - if (family == AF_INET) - return 0; - if (family == AF_INET6) - return 1; + if (family == AF_INET) + return 0; + if (family == AF_INET6) + return 1; - assert(!"Unsupported address family!"); - return 0; + assert(!"Unsupported address family!"); + return 0; } -static afi_t -afi_for_redist_protocol(int protocol) +static afi_t afi_for_redist_protocol(int protocol) { - if (protocol == 0) - return AFI_IP; - if (protocol == 1) - return AFI_IP6; + if (protocol == 0) + return AFI_IP; + if (protocol == 1) + return AFI_IP6; - assert(!"Unknown redist protocol!"); - return AFI_IP; + assert(!"Unknown redist protocol!"); + return AFI_IP; } -static int -is_default(struct prefix *p) +static int is_default(struct prefix *p) { - if (p->family == AF_INET) - if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0) - return 1; - if (p->family == AF_INET6) - if (IN6_IS_ADDR_UNSPECIFIED(&p->u.prefix6) && p->prefixlen == 0) - return 1; - return 0; + if (p->family == AF_INET) + if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0) + return 1; + if (p->family == AF_INET6) + if (IN6_IS_ADDR_UNSPECIFIED(&p->u.prefix6) && p->prefixlen == 0) + return 1; + return 0; } -static struct route_table* -get_ext_info(struct isis *i, int family) +static struct route_table *get_ext_info(struct isis *i, int family) { - int protocol = redist_protocol(family); + int protocol = redist_protocol(family); - return i->ext_info[protocol]; + return i->ext_info[protocol]; } -static struct isis_redist* -get_redist_settings(struct isis_area *area, int family, int type, int level) +static struct isis_redist *get_redist_settings(struct isis_area *area, + int family, int type, int level) { - int protocol = redist_protocol(family); + int protocol = redist_protocol(family); - return &area->redist_settings[protocol][type][level-1]; + return &area->redist_settings[protocol][type][level - 1]; } -struct route_table* -get_ext_reach(struct isis_area *area, int family, int level) +struct route_table *get_ext_reach(struct isis_area *area, int family, int level) { - int protocol = redist_protocol(family); + int protocol = redist_protocol(family); - return area->ext_reach[protocol][level-1]; + return area->ext_reach[protocol][level - 1]; } static struct route_node * isis_redist_route_node_create(route_table_delegate_t *delegate, - struct route_table *table) + struct route_table *table) { - struct route_node *node; - node = XCALLOC(MTYPE_ISIS_EXT_ROUTE, sizeof(*node)); - return node; + struct route_node *node; + node = XCALLOC(MTYPE_ISIS_EXT_ROUTE, sizeof(*node)); + return node; } -static void -isis_redist_route_node_destroy(route_table_delegate_t *delegate, - struct route_table *table, - struct route_node *node) +static void isis_redist_route_node_destroy(route_table_delegate_t *delegate, + struct route_table *table, + struct route_node *node) { - if (node->info) - XFREE(MTYPE_ISIS_EXT_INFO, node->info); - XFREE (MTYPE_ISIS_EXT_ROUTE, node); + if (node->info) + XFREE(MTYPE_ISIS_EXT_INFO, node->info); + XFREE(MTYPE_ISIS_EXT_ROUTE, node); } static route_table_delegate_t isis_redist_rt_delegate = { - .create_node = isis_redist_route_node_create, - .destroy_node = isis_redist_route_node_destroy -}; + .create_node = isis_redist_route_node_create, + .destroy_node = isis_redist_route_node_destroy}; /* Install external reachability information into a * specific area for a specific level. * Schedule an lsp regenerate if necessary */ -static void -isis_redist_install(struct isis_area *area, int level, - struct prefix *p, struct isis_ext_info *info) +static void isis_redist_install(struct isis_area *area, int level, + struct prefix *p, struct isis_ext_info *info) { - int family = p->family; - struct route_table *er_table = get_ext_reach(area, family, level); - struct route_node *er_node; - - if (!er_table) - { - zlog_warn("%s: External reachability table of area %s" - " is not initialized.", __func__, area->area_tag); - return; - } - - er_node = route_node_get(er_table, p); - if (er_node->info) - { - route_unlock_node(er_node); - - /* Don't update/reschedule lsp generation if nothing changed. */ - if (!memcmp(er_node->info, info, sizeof(*info))) - return; - } - else - { - er_node->info = XMALLOC(MTYPE_ISIS_EXT_INFO, sizeof(*info)); - } - - memcpy(er_node->info, info, sizeof(*info)); - lsp_regenerate_schedule(area, level, 0); + int family = p->family; + struct route_table *er_table = get_ext_reach(area, family, level); + struct route_node *er_node; + + if (!er_table) { + zlog_warn( + "%s: External reachability table of area %s" + " is not initialized.", + __func__, area->area_tag); + return; + } + + er_node = route_node_get(er_table, p); + if (er_node->info) { + route_unlock_node(er_node); + + /* Don't update/reschedule lsp generation if nothing changed. */ + if (!memcmp(er_node->info, info, sizeof(*info))) + return; + } else { + er_node->info = XMALLOC(MTYPE_ISIS_EXT_INFO, sizeof(*info)); + } + + memcpy(er_node->info, info, sizeof(*info)); + lsp_regenerate_schedule(area, level, 0); } /* Remove external reachability information from a * specific area for a specific level. * Schedule an lsp regenerate if necessary. */ -static void -isis_redist_uninstall(struct isis_area *area, int level, struct prefix *p) +static void isis_redist_uninstall(struct isis_area *area, int level, + struct prefix *p) { - int family = p->family; - struct route_table *er_table = get_ext_reach(area, family, level); - struct route_node *er_node; - - if (!er_table) - { - zlog_warn("%s: External reachability table of area %s" - " is not initialized.", __func__, area->area_tag); - return; - } - - er_node = route_node_lookup(er_table, p); - if (!er_node) - return; - else - route_unlock_node(er_node); - - if (!er_node->info) - return; - - XFREE(MTYPE_ISIS_EXT_INFO, er_node->info); - route_unlock_node(er_node); - lsp_regenerate_schedule(area, level, 0); + int family = p->family; + struct route_table *er_table = get_ext_reach(area, family, level); + struct route_node *er_node; + + if (!er_table) { + zlog_warn( + "%s: External reachability table of area %s" + " is not initialized.", + __func__, area->area_tag); + return; + } + + er_node = route_node_lookup(er_table, p); + if (!er_node) + return; + else + route_unlock_node(er_node); + + if (!er_node->info) + return; + + XFREE(MTYPE_ISIS_EXT_INFO, er_node->info); + route_unlock_node(er_node); + lsp_regenerate_schedule(area, level, 0); } /* Update external reachability info of area for a given level * and prefix, using the given redistribution settings. */ -static void -isis_redist_update_ext_reach(struct isis_area *area, int level, - struct isis_redist *redist, struct prefix *p, - struct isis_ext_info *info) +static void isis_redist_update_ext_reach(struct isis_area *area, int level, + struct isis_redist *redist, + struct prefix *p, + struct isis_ext_info *info) { - struct isis_ext_info area_info; - route_map_result_t map_ret; - - memcpy(&area_info, info, sizeof(area_info)); - if (redist->metric != 0xffffffff) - area_info.metric = redist->metric; - - if (redist->map_name) - { - map_ret = route_map_apply(redist->map, p, RMAP_ISIS, &area_info); - if (map_ret == RMAP_DENYMATCH) - area_info.distance = 255; - } - - /* Allow synthesized default routes only on always orignate */ - if (area_info.origin == DEFAULT_ROUTE - && redist->redist != DEFAULT_ORIGINATE_ALWAYS) - area_info.distance = 255; - - if (area_info.distance < 255) - isis_redist_install(area, level, p, &area_info); - else - isis_redist_uninstall(area, level, p); + struct isis_ext_info area_info; + route_map_result_t map_ret; + + memcpy(&area_info, info, sizeof(area_info)); + if (redist->metric != 0xffffffff) + area_info.metric = redist->metric; + + if (redist->map_name) { + map_ret = + route_map_apply(redist->map, p, RMAP_ISIS, &area_info); + if (map_ret == RMAP_DENYMATCH) + area_info.distance = 255; + } + + /* Allow synthesized default routes only on always orignate */ + if (area_info.origin == DEFAULT_ROUTE + && redist->redist != DEFAULT_ORIGINATE_ALWAYS) + area_info.distance = 255; + + if (area_info.distance < 255) + isis_redist_install(area, level, p, &area_info); + else + isis_redist_uninstall(area, level, p); } -static void -isis_redist_ensure_default(struct isis *isis, int family) +static void isis_redist_ensure_default(struct isis *isis, int family) { - struct prefix p; - struct route_table *ei_table = get_ext_info(isis, family); - struct route_node *ei_node; - struct isis_ext_info *info; - - if (family == AF_INET) - { - p.family = AF_INET; - p.prefixlen = 0; - memset(&p.u.prefix4, 0, sizeof(p.u.prefix4)); - } - else if (family == AF_INET6) - { - p.family = AF_INET6; - p.prefixlen = 0; - memset(&p.u.prefix6, 0, sizeof(p.u.prefix6)); - } - else - assert(!"Unknown family!"); - - ei_node = route_node_get(ei_table, &p); - if (ei_node->info) - { - route_unlock_node(ei_node); - return; - } - - ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info)); - - info = ei_node->info; - info->origin = DEFAULT_ROUTE; - info->distance = 254; - info->metric = MAX_WIDE_PATH_METRIC; + struct prefix p; + struct route_table *ei_table = get_ext_info(isis, family); + struct route_node *ei_node; + struct isis_ext_info *info; + + if (family == AF_INET) { + p.family = AF_INET; + p.prefixlen = 0; + memset(&p.u.prefix4, 0, sizeof(p.u.prefix4)); + } else if (family == AF_INET6) { + p.family = AF_INET6; + p.prefixlen = 0; + memset(&p.u.prefix6, 0, sizeof(p.u.prefix6)); + } else + assert(!"Unknown family!"); + + ei_node = route_node_get(ei_table, &p); + if (ei_node->info) { + route_unlock_node(ei_node); + return; + } + + ei_node->info = + XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info)); + + info = ei_node->info; + info->origin = DEFAULT_ROUTE; + info->distance = 254; + info->metric = MAX_WIDE_PATH_METRIC; } /* Handle notification about route being added */ -void -isis_redist_add(int type, struct prefix *p, u_char distance, uint32_t metric) +void isis_redist_add(int type, struct prefix *p, u_char distance, + uint32_t metric) { - int family = p->family; - struct route_table *ei_table = get_ext_info(isis, family); - struct route_node *ei_node; - struct isis_ext_info *info; - struct listnode *node; - struct isis_area *area; - int level; - struct isis_redist *redist; - - char debug_buf[BUFSIZ]; - prefix2str(p, debug_buf, sizeof(debug_buf)); - - zlog_debug("%s: New route %s from %s.", __func__, debug_buf, - zebra_route_string(type)); - - if (!ei_table) - { - zlog_warn("%s: External information table not initialized.", - __func__); - return; - } - - ei_node = route_node_get(ei_table, p); - if (ei_node->info) - route_unlock_node(ei_node); - else - ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info)); - - info = ei_node->info; - info->origin = type; - info->distance = distance; - info->metric = metric; - - if (is_default(p)) - type = DEFAULT_ROUTE; - - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) - for (level = 1; level <= ISIS_LEVELS; level++) - { - redist = get_redist_settings(area, family, type, level); - if (!redist->redist) - continue; - - isis_redist_update_ext_reach(area, level, redist, p, info); - } + int family = p->family; + struct route_table *ei_table = get_ext_info(isis, family); + struct route_node *ei_node; + struct isis_ext_info *info; + struct listnode *node; + struct isis_area *area; + int level; + struct isis_redist *redist; + + char debug_buf[BUFSIZ]; + prefix2str(p, debug_buf, sizeof(debug_buf)); + + zlog_debug("%s: New route %s from %s.", __func__, debug_buf, + zebra_route_string(type)); + + if (!ei_table) { + zlog_warn("%s: External information table not initialized.", + __func__); + return; + } + + ei_node = route_node_get(ei_table, p); + if (ei_node->info) + route_unlock_node(ei_node); + else + ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, + sizeof(struct isis_ext_info)); + + info = ei_node->info; + info->origin = type; + info->distance = distance; + info->metric = metric; + + if (is_default(p)) + type = DEFAULT_ROUTE; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + for (level = 1; level <= ISIS_LEVELS; level++) { + redist = get_redist_settings(area, family, type, level); + if (!redist->redist) + continue; + + isis_redist_update_ext_reach(area, level, redist, p, + info); + } } -void -isis_redist_delete(int type, struct prefix *p) +void isis_redist_delete(int type, struct prefix *p) { - int family = p->family; - struct route_table *ei_table = get_ext_info(isis, family); - struct route_node *ei_node; - struct listnode *node; - struct isis_area *area; - int level; - struct isis_redist *redist; - - char debug_buf[BUFSIZ]; - prefix2str(p, debug_buf, sizeof(debug_buf)); - - zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf, - zebra_route_string(type)); - - if (is_default(p)) - { - /* Don't remove default route but add synthetic route for use - * by "default-information originate always". Areas without the - * "always" setting will ignore routes with origin DEFAULT_ROUTE. */ - isis_redist_add(DEFAULT_ROUTE, p, 254, MAX_WIDE_PATH_METRIC); - return; - } - - if (!ei_table) - { - zlog_warn("%s: External information table not initialized.", - __func__); - return; - } - - ei_node = route_node_lookup(ei_table, p); - if (!ei_node || !ei_node->info) - { - char buf[BUFSIZ]; - prefix2str(p, buf, sizeof(buf)); - zlog_warn("%s: Got a delete for %s route %s, but that route" - " was never added.", __func__, zebra_route_string(type), - buf); - if (ei_node) - route_unlock_node(ei_node); - return; - } - route_unlock_node(ei_node); - - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) - for (level = 1; level < ISIS_LEVELS; level++) - { - redist = get_redist_settings(area, family, type, level); - if (!redist->redist) - continue; - - isis_redist_uninstall(area, level, p); - } - - XFREE(MTYPE_ISIS_EXT_INFO, ei_node->info); - route_unlock_node(ei_node); + int family = p->family; + struct route_table *ei_table = get_ext_info(isis, family); + struct route_node *ei_node; + struct listnode *node; + struct isis_area *area; + int level; + struct isis_redist *redist; + + char debug_buf[BUFSIZ]; + prefix2str(p, debug_buf, sizeof(debug_buf)); + + zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf, + zebra_route_string(type)); + + if (is_default(p)) { + /* Don't remove default route but add synthetic route for use + * by "default-information originate always". Areas without the + * "always" setting will ignore routes with origin + * DEFAULT_ROUTE. */ + isis_redist_add(DEFAULT_ROUTE, p, 254, MAX_WIDE_PATH_METRIC); + return; + } + + if (!ei_table) { + zlog_warn("%s: External information table not initialized.", + __func__); + return; + } + + ei_node = route_node_lookup(ei_table, p); + if (!ei_node || !ei_node->info) { + char buf[BUFSIZ]; + prefix2str(p, buf, sizeof(buf)); + zlog_warn( + "%s: Got a delete for %s route %s, but that route" + " was never added.", + __func__, zebra_route_string(type), buf); + if (ei_node) + route_unlock_node(ei_node); + return; + } + route_unlock_node(ei_node); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + for (level = 1; level < ISIS_LEVELS; level++) { + redist = get_redist_settings(area, family, type, level); + if (!redist->redist) + continue; + + isis_redist_uninstall(area, level, p); + } + + XFREE(MTYPE_ISIS_EXT_INFO, ei_node->info); + route_unlock_node(ei_node); } -static void -isis_redist_routemap_set(struct isis_redist *redist, const char *routemap) +static void isis_redist_routemap_set(struct isis_redist *redist, + const char *routemap) { - if (redist->map_name) { - XFREE(MTYPE_ISIS, redist->map_name); - redist->map = NULL; - } - - if (routemap && strlen(routemap)) { - redist->map_name = XSTRDUP(MTYPE_ISIS, routemap); - redist->map = route_map_lookup_by_name(routemap); - } + if (redist->map_name) { + XFREE(MTYPE_ISIS, redist->map_name); + redist->map = NULL; + } + + if (routemap && strlen(routemap)) { + redist->map_name = XSTRDUP(MTYPE_ISIS, routemap); + redist->map = route_map_lookup_by_name(routemap); + } } -static void -isis_redist_update_zebra_subscriptions(struct isis *isis) +static void isis_redist_update_zebra_subscriptions(struct isis *isis) { - struct listnode *node; - struct isis_area *area; - int type; - int level; - int protocol; - - char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]; - - memset(do_subscribe, 0, sizeof(do_subscribe)); - - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) - for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) - for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) - for (level = 0; level < ISIS_LEVELS; level++) - if (area->redist_settings[protocol][type][level].redist) - do_subscribe[protocol][type] = 1; - - for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) - for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) - { - /* This field is actually controlling transmission of the IS-IS - * routes to Zebra and has nothing to do with redistribution, - * so skip it. */ - if (type == ZEBRA_ROUTE_ISIS) - continue; - - afi_t afi = afi_for_redist_protocol(protocol); - - if (do_subscribe[protocol][type]) - isis_zebra_redistribute_set(afi, type); - else - isis_zebra_redistribute_unset(afi, type); - } + struct listnode *node; + struct isis_area *area; + int type; + int level; + int protocol; + + char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]; + + memset(do_subscribe, 0, sizeof(do_subscribe)); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) + for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) + for (level = 0; level < ISIS_LEVELS; level++) + if (area->redist_settings[protocol] + [type] + [level].redist) + do_subscribe[protocol][type] = + 1; + + for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) + for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) { + /* This field is actually controlling transmission of + * the IS-IS + * routes to Zebra and has nothing to do with + * redistribution, + * so skip it. */ + if (type == ZEBRA_ROUTE_ISIS) + continue; + + afi_t afi = afi_for_redist_protocol(protocol); + + if (do_subscribe[protocol][type]) + isis_zebra_redistribute_set(afi, type); + else + isis_zebra_redistribute_unset(afi, type); + } } -static void -isis_redist_set(struct isis_area *area, int level, - int family, int type, uint32_t metric, - const char *routemap, int originate_type) +static void isis_redist_set(struct isis_area *area, int level, int family, + int type, uint32_t metric, const char *routemap, + int originate_type) { - int protocol = redist_protocol(family); - struct isis_redist *redist = get_redist_settings(area, family, type, level); - int i; - struct route_table *ei_table; - struct route_node *rn; - struct isis_ext_info *info; - - redist->redist = (type == DEFAULT_ROUTE) ? originate_type : 1; - redist->metric = metric; - isis_redist_routemap_set(redist, routemap); - - if (!area->ext_reach[protocol][level-1]) - { - area->ext_reach[protocol][level-1] = - route_table_init_with_delegate(&isis_redist_rt_delegate); - } - - for (i = 0; i < REDIST_PROTOCOL_COUNT; i++) - if (!area->isis->ext_info[i]) - { - area->isis->ext_info[i] = - route_table_init_with_delegate(&isis_redist_rt_delegate); - } - - isis_redist_update_zebra_subscriptions(area->isis); - - if (type == DEFAULT_ROUTE && originate_type == DEFAULT_ORIGINATE_ALWAYS) - isis_redist_ensure_default(area->isis, family); - - ei_table = get_ext_info(area->isis, family); - for (rn = route_top(ei_table); rn; rn = route_next(rn)) - { - if (!rn->info) - continue; - info = rn->info; - - if (type == DEFAULT_ROUTE) - { - if (!is_default(&rn->p)) - continue; - } - else - { - if (info->origin != type) - continue; - } - - isis_redist_update_ext_reach(area, level, redist, &rn->p, info); - } + int protocol = redist_protocol(family); + struct isis_redist *redist = + get_redist_settings(area, family, type, level); + int i; + struct route_table *ei_table; + struct route_node *rn; + struct isis_ext_info *info; + + redist->redist = (type == DEFAULT_ROUTE) ? originate_type : 1; + redist->metric = metric; + isis_redist_routemap_set(redist, routemap); + + if (!area->ext_reach[protocol][level - 1]) { + area->ext_reach[protocol][level - 1] = + route_table_init_with_delegate( + &isis_redist_rt_delegate); + } + + for (i = 0; i < REDIST_PROTOCOL_COUNT; i++) + if (!area->isis->ext_info[i]) { + area->isis->ext_info[i] = + route_table_init_with_delegate( + &isis_redist_rt_delegate); + } + + isis_redist_update_zebra_subscriptions(area->isis); + + if (type == DEFAULT_ROUTE && originate_type == DEFAULT_ORIGINATE_ALWAYS) + isis_redist_ensure_default(area->isis, family); + + ei_table = get_ext_info(area->isis, family); + for (rn = route_top(ei_table); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + info = rn->info; + + if (type == DEFAULT_ROUTE) { + if (!is_default(&rn->p)) + continue; + } else { + if (info->origin != type) + continue; + } + + isis_redist_update_ext_reach(area, level, redist, &rn->p, info); + } } -static void -isis_redist_unset(struct isis_area *area, int level, - int family, int type) +static void isis_redist_unset(struct isis_area *area, int level, int family, + int type) { - struct isis_redist *redist = get_redist_settings(area, family, type, level); - struct route_table *er_table = get_ext_reach(area, family, level); - struct route_node *rn; - struct isis_ext_info *info; - - if (!redist->redist) - return; - - redist->redist = 0; - if (!er_table) - { - zlog_warn("%s: External reachability table uninitialized.", __func__); - return; - } - - for (rn = route_top(er_table); rn; rn = route_next(rn)) - { - if (!rn->info) - continue; - info = rn->info; - - if (type == DEFAULT_ROUTE) - { - if (!is_default(&rn->p)) - continue; - } - else - { - if (info->origin != type) - continue; - } - - XFREE(MTYPE_ISIS_EXT_INFO, rn->info); - route_unlock_node(rn); - } - - lsp_regenerate_schedule(area, level, 0); - isis_redist_update_zebra_subscriptions(area->isis); + struct isis_redist *redist = + get_redist_settings(area, family, type, level); + struct route_table *er_table = get_ext_reach(area, family, level); + struct route_node *rn; + struct isis_ext_info *info; + + if (!redist->redist) + return; + + redist->redist = 0; + if (!er_table) { + zlog_warn("%s: External reachability table uninitialized.", + __func__); + return; + } + + for (rn = route_top(er_table); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + info = rn->info; + + if (type == DEFAULT_ROUTE) { + if (!is_default(&rn->p)) + continue; + } else { + if (info->origin != type) + continue; + } + + XFREE(MTYPE_ISIS_EXT_INFO, rn->info); + route_unlock_node(rn); + } + + lsp_regenerate_schedule(area, level, 0); + isis_redist_update_zebra_subscriptions(area->isis); } -void -isis_redist_area_finish(struct isis_area *area) +void isis_redist_area_finish(struct isis_area *area) { - int protocol; - int level; - int type; - - for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) - for (level = 0; level < ISIS_LEVELS; level++) - { - for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) - { - struct isis_redist *redist; - - redist = &area->redist_settings[protocol][type][level]; - redist->redist = 0; - if (redist->map_name) - XFREE(MTYPE_ISIS, redist->map_name); - } - route_table_finish(area->ext_reach[protocol][level]); - } - - isis_redist_update_zebra_subscriptions(area->isis); + int protocol; + int level; + int type; + + for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) + for (level = 0; level < ISIS_LEVELS; level++) { + for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) { + struct isis_redist *redist; + + redist = &area->redist_settings[protocol][type] + [level]; + redist->redist = 0; + if (redist->map_name) + XFREE(MTYPE_ISIS, redist->map_name); + } + route_table_finish(area->ext_reach[protocol][level]); + } + + isis_redist_update_zebra_subscriptions(area->isis); } DEFUN (isis_redistribute, @@ -567,67 +543,63 @@ DEFUN (isis_redistribute, "Route map reference\n" "Pointer to route-map entries\n") { - int idx_afi = 1; - int idx_protocol = 2; - int idx_level = 3; - int idx_metric_rmap = 4; - VTY_DECLVAR_CONTEXT (isis_area, area); - int family; - int afi; - int type; - int level; - unsigned long metric; - const char *routemap = NULL; - - family = str2family(argv[idx_afi]->text); - if (family < 0) - return CMD_WARNING_CONFIG_FAILED; - - afi = family2afi(family); - if (!afi) - return CMD_WARNING_CONFIG_FAILED; - - type = proto_redistnum(afi, argv[idx_protocol]->text); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; - - if (!strcmp("level-1", argv[idx_level]->arg)) - level = 1; - else if (!strcmp("level-2", argv[idx_level]->arg)) - level = 2; - else - return CMD_WARNING_CONFIG_FAILED; - - if ((area->is_type & level) != level) - { - vty_out (vty, "Node is not a level-%d IS\n", level); - return CMD_WARNING_CONFIG_FAILED; - } - - metric = 0xffffffff; - routemap = NULL; - - if (argc > idx_metric_rmap + 1) - { - if (argv[idx_metric_rmap + 1]->arg[0] == '\0') - return CMD_WARNING_CONFIG_FAILED; - - if (strmatch(argv[idx_metric_rmap]->text, "metric")) - { - char *endp; - metric = strtoul(argv[idx_metric_rmap + 1]->arg, &endp, 10); - - if (*endp != '\0') - return CMD_WARNING_CONFIG_FAILED; - } - else - { - routemap = argv[idx_metric_rmap + 1]->arg; - } - } - - isis_redist_set(area, level, family, type, metric, routemap, 0); - return 0; + int idx_afi = 1; + int idx_protocol = 2; + int idx_level = 3; + int idx_metric_rmap = 4; + VTY_DECLVAR_CONTEXT(isis_area, area); + int family; + int afi; + int type; + int level; + unsigned long metric; + const char *routemap = NULL; + + family = str2family(argv[idx_afi]->text); + if (family < 0) + return CMD_WARNING_CONFIG_FAILED; + + afi = family2afi(family); + if (!afi) + return CMD_WARNING_CONFIG_FAILED; + + type = proto_redistnum(afi, argv[idx_protocol]->text); + if (type < 0) + return CMD_WARNING_CONFIG_FAILED; + + if (!strcmp("level-1", argv[idx_level]->arg)) + level = 1; + else if (!strcmp("level-2", argv[idx_level]->arg)) + level = 2; + else + return CMD_WARNING_CONFIG_FAILED; + + if ((area->is_type & level) != level) { + vty_out(vty, "Node is not a level-%d IS\n", level); + return CMD_WARNING_CONFIG_FAILED; + } + + metric = 0xffffffff; + routemap = NULL; + + if (argc > idx_metric_rmap + 1) { + if (argv[idx_metric_rmap + 1]->arg[0] == '\0') + return CMD_WARNING_CONFIG_FAILED; + + if (strmatch(argv[idx_metric_rmap]->text, "metric")) { + char *endp; + metric = strtoul(argv[idx_metric_rmap + 1]->arg, &endp, + 10); + + if (*endp != '\0') + return CMD_WARNING_CONFIG_FAILED; + } else { + routemap = argv[idx_metric_rmap + 1]->arg; + } + } + + isis_redist_set(area, level, family, type, metric, routemap, 0); + return 0; } DEFUN (no_isis_redistribute, @@ -641,31 +613,31 @@ DEFUN (no_isis_redistribute, "Redistribute into level-1\n" "Redistribute into level-2\n") { - int idx_afi = 2; - int idx_protocol = 3; - int idx_level = 4; - VTY_DECLVAR_CONTEXT (isis_area, area); - int type; - int level; - int family; - int afi; - - family = str2family(argv[idx_afi]->arg); - if (family < 0) - return CMD_WARNING_CONFIG_FAILED; - - afi = family2afi(family); - if (!afi) - return CMD_WARNING_CONFIG_FAILED; - - type = proto_redistnum(afi, argv[idx_protocol]->text); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; - - level = strmatch ("level-1", argv[idx_level]->text) ? 1 : 2; - - isis_redist_unset(area, level, family, type); - return 0; + int idx_afi = 2; + int idx_protocol = 3; + int idx_level = 4; + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; + int level; + int family; + int afi; + + family = str2family(argv[idx_afi]->arg); + if (family < 0) + return CMD_WARNING_CONFIG_FAILED; + + afi = family2afi(family); + if (!afi) + return CMD_WARNING_CONFIG_FAILED; + + type = proto_redistnum(afi, argv[idx_protocol]->text); + if (type < 0) + return CMD_WARNING_CONFIG_FAILED; + + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + + isis_redist_unset(area, level, family, type); + return 0; } DEFUN (isis_default_originate, @@ -683,52 +655,51 @@ DEFUN (isis_default_originate, "Route map reference\n" "Pointer to route-map entries\n") { - int idx_afi = 2; - int idx_level = 3; - int idx_always = 4; - int idx_metric_rmap = 4; - VTY_DECLVAR_CONTEXT (isis_area, area); - int family; - int originate_type = DEFAULT_ORIGINATE; - int level; - unsigned long metric = 0xffffffff; - const char *routemap = NULL; - - family = str2family(argv[idx_afi]->text); - if (family < 0) - return CMD_WARNING_CONFIG_FAILED; - - level = strmatch ("level-1", argv[idx_level]->text) ? 1 : 2; - - if ((area->is_type & level) != level) - { - vty_out (vty, "Node is not a level-%d IS\n", level); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > idx_always && strmatch (argv[idx_always]->text, "always")) - { - originate_type = DEFAULT_ORIGINATE_ALWAYS; - idx_metric_rmap++; - } - - if (argc > idx_metric_rmap) - { - if (strmatch(argv[idx_metric_rmap]->text, "metric")) - metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL, 10); - else - routemap = argv[idx_metric_rmap + 1]->arg; - } - - if (family == AF_INET6 && originate_type != DEFAULT_ORIGINATE_ALWAYS) - { - vty_out (vty, - "Zebra doesn't implement default-originate for IPv6 yet\n"); - vty_out (vty, "so use with care or use default-originate always.\n"); - } - - isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap, originate_type); - return 0; + int idx_afi = 2; + int idx_level = 3; + int idx_always = 4; + int idx_metric_rmap = 4; + VTY_DECLVAR_CONTEXT(isis_area, area); + int family; + int originate_type = DEFAULT_ORIGINATE; + int level; + unsigned long metric = 0xffffffff; + const char *routemap = NULL; + + family = str2family(argv[idx_afi]->text); + if (family < 0) + return CMD_WARNING_CONFIG_FAILED; + + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + + if ((area->is_type & level) != level) { + vty_out(vty, "Node is not a level-%d IS\n", level); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > idx_always && strmatch(argv[idx_always]->text, "always")) { + originate_type = DEFAULT_ORIGINATE_ALWAYS; + idx_metric_rmap++; + } + + if (argc > idx_metric_rmap) { + if (strmatch(argv[idx_metric_rmap]->text, "metric")) + metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL, + 10); + else + routemap = argv[idx_metric_rmap + 1]->arg; + } + + if (family == AF_INET6 && originate_type != DEFAULT_ORIGINATE_ALWAYS) { + vty_out(vty, + "Zebra doesn't implement default-originate for IPv6 yet\n"); + vty_out(vty, + "so use with care or use default-originate always.\n"); + } + + isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap, + originate_type); + return 0; } DEFUN (no_isis_default_originate, @@ -742,90 +713,86 @@ DEFUN (no_isis_default_originate, "Distribute default route into level-1\n" "Distribute default route into level-2\n") { - int idx_afi = 3; - int idx_level = 4; - VTY_DECLVAR_CONTEXT (isis_area, area); - int family; - int level; - - family = str2family(argv[idx_afi]->text); - if (family < 0) - return CMD_WARNING_CONFIG_FAILED; - - if (strmatch ("level-1", argv[idx_level]->text)) - level = 1; - else if (strmatch ("level-2", argv[idx_level]->text)) - level = 2; - else - return CMD_WARNING_CONFIG_FAILED; - - isis_redist_unset(area, level, family, DEFAULT_ROUTE); - return 0; + int idx_afi = 3; + int idx_level = 4; + VTY_DECLVAR_CONTEXT(isis_area, area); + int family; + int level; + + family = str2family(argv[idx_afi]->text); + if (family < 0) + return CMD_WARNING_CONFIG_FAILED; + + if (strmatch("level-1", argv[idx_level]->text)) + level = 1; + else if (strmatch("level-2", argv[idx_level]->text)) + level = 2; + else + return CMD_WARNING_CONFIG_FAILED; + + isis_redist_unset(area, level, family, DEFAULT_ROUTE); + return 0; } -int -isis_redist_config_write(struct vty *vty, struct isis_area *area, - int family) +int isis_redist_config_write(struct vty *vty, struct isis_area *area, + int family) { - int type; - int level; - int write = 0; - struct isis_redist *redist; - const char *family_str; - - if (family == AF_INET) - family_str = "ipv4"; - else if (family == AF_INET6) - family_str = "ipv6"; - else - return 0; - - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - if (type == ZEBRA_ROUTE_ISIS) - continue; - - for (level = 1; level <= ISIS_LEVELS; level++) - { - redist = get_redist_settings(area, family, type, level); - if (!redist->redist) - continue; - vty_out(vty, " redistribute %s %s level-%d", - family_str, zebra_route_string(type), level); - if (redist->metric != 0xffffffff) - vty_out(vty, " metric %u", redist->metric); - if (redist->map_name) - vty_out(vty, " route-map %s", redist->map_name); - vty_out (vty, "\n"); - write++; - } - } - - for (level = 1; level <= ISIS_LEVELS; level++) - { - redist = get_redist_settings(area, family, DEFAULT_ROUTE, level); - if (!redist->redist) - continue; - vty_out(vty, " default-information originate %s level-%d", - family_str, level); - if (redist->redist == DEFAULT_ORIGINATE_ALWAYS) - vty_out(vty, " always"); - if (redist->metric != 0xffffffff) - vty_out(vty, " metric %u", redist->metric); - if (redist->map_name) - vty_out(vty, " route-map %s", redist->map_name); - vty_out (vty, "\n"); - write++; - } - - return write; + int type; + int level; + int write = 0; + struct isis_redist *redist; + const char *family_str; + + if (family == AF_INET) + family_str = "ipv4"; + else if (family == AF_INET6) + family_str = "ipv6"; + else + return 0; + + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (type == ZEBRA_ROUTE_ISIS) + continue; + + for (level = 1; level <= ISIS_LEVELS; level++) { + redist = get_redist_settings(area, family, type, level); + if (!redist->redist) + continue; + vty_out(vty, " redistribute %s %s level-%d", family_str, + zebra_route_string(type), level); + if (redist->metric != 0xffffffff) + vty_out(vty, " metric %u", redist->metric); + if (redist->map_name) + vty_out(vty, " route-map %s", redist->map_name); + vty_out(vty, "\n"); + write++; + } + } + + for (level = 1; level <= ISIS_LEVELS; level++) { + redist = + get_redist_settings(area, family, DEFAULT_ROUTE, level); + if (!redist->redist) + continue; + vty_out(vty, " default-information originate %s level-%d", + family_str, level); + if (redist->redist == DEFAULT_ORIGINATE_ALWAYS) + vty_out(vty, " always"); + if (redist->metric != 0xffffffff) + vty_out(vty, " metric %u", redist->metric); + if (redist->map_name) + vty_out(vty, " route-map %s", redist->map_name); + vty_out(vty, "\n"); + write++; + } + + return write; } -void -isis_redist_init(void) +void isis_redist_init(void) { - install_element(ISIS_NODE, &isis_redistribute_cmd); - install_element(ISIS_NODE, &no_isis_redistribute_cmd); - install_element(ISIS_NODE, &isis_default_originate_cmd); - install_element(ISIS_NODE, &no_isis_default_originate_cmd); + install_element(ISIS_NODE, &isis_redistribute_cmd); + install_element(ISIS_NODE, &no_isis_redistribute_cmd); + install_element(ISIS_NODE, &isis_default_originate_cmd); + install_element(ISIS_NODE, &no_isis_default_originate_cmd); } diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h index 11b3c31e2..2bd40e849 100644 --- a/isisd/isis_redist.h +++ b/isisd/isis_redist.h @@ -3,14 +3,14 @@ * * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program 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 of the License, or (at your option) + * This program 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 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -27,32 +27,30 @@ #define DEFAULT_ORIGINATE 1 #define DEFAULT_ORIGINATE_ALWAYS 2 -struct isis_ext_info -{ - int origin; - uint32_t metric; - u_char distance; +struct isis_ext_info { + int origin; + uint32_t metric; + u_char distance; }; -struct isis_redist -{ - int redist; - uint32_t metric; - char *map_name; - struct route_map *map; +struct isis_redist { + int redist; + uint32_t metric; + char *map_name; + struct route_map *map; }; struct isis_area; struct prefix; struct vty; -struct route_table *get_ext_reach(struct isis_area *area, - int family, int level); -void isis_redist_add(int type, struct prefix *p, - u_char distance, uint32_t metric); +struct route_table *get_ext_reach(struct isis_area *area, int family, + int level); +void isis_redist_add(int type, struct prefix *p, u_char distance, + uint32_t metric); void isis_redist_delete(int type, struct prefix *p); int isis_redist_config_write(struct vty *vty, struct isis_area *area, - int family); + int family); void isis_redist_init(void); void isis_redist_area_finish(struct isis_area *area); diff --git a/isisd/isis_route.c b/isisd/isis_route.c index bceb70ce0..afc4f6512 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -1,20 +1,20 @@ /* * IS-IS Rout(e)ing protocol - isis_route.c * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * * based on ../ospf6d/ospf6_route.[ch] * by Yasuhiro Ohara * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -49,502 +49,489 @@ #include "isis_route.h" #include "isis_zebra.h" -static struct isis_nexthop * -isis_nexthop_create (struct in_addr *ip, ifindex_t ifindex) +static struct isis_nexthop *isis_nexthop_create(struct in_addr *ip, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop *nexthop; + struct listnode *node; + struct isis_nexthop *nexthop; - for (ALL_LIST_ELEMENTS_RO (isis->nexthops, node, nexthop)) - { - if (nexthop->ifindex != ifindex) - continue; - if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0) - continue; + for (ALL_LIST_ELEMENTS_RO(isis->nexthops, node, nexthop)) { + if (nexthop->ifindex != ifindex) + continue; + if (ip && memcmp(&nexthop->ip, ip, sizeof(struct in_addr)) != 0) + continue; - nexthop->lock++; - return nexthop; - } + nexthop->lock++; + return nexthop; + } - nexthop = XCALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop)); + nexthop = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop)); - nexthop->ifindex = ifindex; - memcpy (&nexthop->ip, ip, sizeof (struct in_addr)); - listnode_add (isis->nexthops, nexthop); - nexthop->lock++; + nexthop->ifindex = ifindex; + memcpy(&nexthop->ip, ip, sizeof(struct in_addr)); + listnode_add(isis->nexthops, nexthop); + nexthop->lock++; - return nexthop; + return nexthop; } -static void -isis_nexthop_delete (struct isis_nexthop *nexthop) +static void isis_nexthop_delete(struct isis_nexthop *nexthop) { - nexthop->lock--; - if (nexthop->lock == 0) - { - listnode_delete (isis->nexthops, nexthop); - XFREE (MTYPE_ISIS_NEXTHOP, nexthop); - } - - return; + nexthop->lock--; + if (nexthop->lock == 0) { + listnode_delete(isis->nexthops, nexthop); + XFREE(MTYPE_ISIS_NEXTHOP, nexthop); + } + + return; } -static int -nexthoplookup (struct list *nexthops, struct in_addr *ip, - ifindex_t ifindex) +static int nexthoplookup(struct list *nexthops, struct in_addr *ip, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop *nh; + struct listnode *node; + struct isis_nexthop *nh; - for (ALL_LIST_ELEMENTS_RO (nexthops, node, nh)) - { - if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) && - ifindex == nh->ifindex) - return 1; - } + for (ALL_LIST_ELEMENTS_RO(nexthops, node, nh)) { + if (!(memcmp(ip, &nh->ip, sizeof(struct in_addr))) + && ifindex == nh->ifindex) + return 1; + } - return 0; + return 0; } #ifdef EXTREME_DEBUG -static void -nexthop_print (struct isis_nexthop *nh) +static void nexthop_print(struct isis_nexthop *nh) { - u_char buf[BUFSIZ]; + u_char buf[BUFSIZ]; - inet_ntop (AF_INET, &nh->ip, (char *) buf, BUFSIZ); + inet_ntop(AF_INET, &nh->ip, (char *)buf, BUFSIZ); - zlog_debug (" %s %u", buf, nh->ifindex); + zlog_debug(" %s %u", buf, nh->ifindex); } -static void -nexthops_print (struct list *nhs) +static void nexthops_print(struct list *nhs) { - struct listnode *node; - struct isis_nexthop *nh; + struct listnode *node; + struct isis_nexthop *nh; - for (ALL_LIST_ELEMENTS_RO (nhs, node, nh)) - nexthop_print (nh); + for (ALL_LIST_ELEMENTS_RO(nhs, node, nh)) + nexthop_print(nh); } #endif /* EXTREME_DEBUG */ -static struct isis_nexthop6 * -isis_nexthop6_new (struct in6_addr *ip6, ifindex_t ifindex) +static struct isis_nexthop6 *isis_nexthop6_new(struct in6_addr *ip6, + ifindex_t ifindex) { - struct isis_nexthop6 *nexthop6; + struct isis_nexthop6 *nexthop6; - nexthop6 = XCALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6)); + nexthop6 = XCALLOC(MTYPE_ISIS_NEXTHOP6, sizeof(struct isis_nexthop6)); - nexthop6->ifindex = ifindex; - memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr)); - nexthop6->lock++; + nexthop6->ifindex = ifindex; + memcpy(&nexthop6->ip6, ip6, sizeof(struct in6_addr)); + nexthop6->lock++; - return nexthop6; + return nexthop6; } -static struct isis_nexthop6 * -isis_nexthop6_create (struct in6_addr *ip6, ifindex_t ifindex) +static struct isis_nexthop6 *isis_nexthop6_create(struct in6_addr *ip6, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop6 *nexthop6; - - for (ALL_LIST_ELEMENTS_RO (isis->nexthops6, node, nexthop6)) - { - if (nexthop6->ifindex != ifindex) - continue; - if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0) - continue; - - nexthop6->lock++; - return nexthop6; - } + struct listnode *node; + struct isis_nexthop6 *nexthop6; + + for (ALL_LIST_ELEMENTS_RO(isis->nexthops6, node, nexthop6)) { + if (nexthop6->ifindex != ifindex) + continue; + if (ip6 + && memcmp(&nexthop6->ip6, ip6, sizeof(struct in6_addr)) + != 0) + continue; + + nexthop6->lock++; + return nexthop6; + } - nexthop6 = isis_nexthop6_new (ip6, ifindex); + nexthop6 = isis_nexthop6_new(ip6, ifindex); - return nexthop6; + return nexthop6; } -static void -isis_nexthop6_delete (struct isis_nexthop6 *nexthop6) +static void isis_nexthop6_delete(struct isis_nexthop6 *nexthop6) { - nexthop6->lock--; - if (nexthop6->lock == 0) - { - listnode_delete (isis->nexthops6, nexthop6); - XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6); - } + nexthop6->lock--; + if (nexthop6->lock == 0) { + listnode_delete(isis->nexthops6, nexthop6); + XFREE(MTYPE_ISIS_NEXTHOP6, nexthop6); + } - return; + return; } -static int -nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6, - ifindex_t ifindex) +static int nexthop6lookup(struct list *nexthops6, struct in6_addr *ip6, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop6 *nh6; + struct listnode *node; + struct isis_nexthop6 *nh6; - for (ALL_LIST_ELEMENTS_RO (nexthops6, node, nh6)) - { - if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) && - ifindex == nh6->ifindex) - return 1; - } + for (ALL_LIST_ELEMENTS_RO(nexthops6, node, nh6)) { + if (!(memcmp(ip6, &nh6->ip6, sizeof(struct in6_addr))) + && ifindex == nh6->ifindex) + return 1; + } - return 0; + return 0; } #ifdef EXTREME_DEBUG -static void -nexthop6_print (struct isis_nexthop6 *nh6) +static void nexthop6_print(struct isis_nexthop6 *nh6) { - u_char buf[BUFSIZ]; + u_char buf[BUFSIZ]; - inet_ntop (AF_INET6, &nh6->ip6, (char *) buf, BUFSIZ); + inet_ntop(AF_INET6, &nh6->ip6, (char *)buf, BUFSIZ); - zlog_debug (" %s %u", buf, nh6->ifindex); + zlog_debug(" %s %u", buf, nh6->ifindex); } -static void -nexthops6_print (struct list *nhs6) +static void nexthops6_print(struct list *nhs6) { - struct listnode *node; - struct isis_nexthop6 *nh6; + struct listnode *node; + struct isis_nexthop6 *nh6; - for (ALL_LIST_ELEMENTS_RO (nhs6, node, nh6)) - nexthop6_print (nh6); + for (ALL_LIST_ELEMENTS_RO(nhs6, node, nh6)) + nexthop6_print(nh6); } #endif /* EXTREME_DEBUG */ -static void -adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj) +static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj) { - struct isis_nexthop *nh; - struct listnode *node; - struct in_addr *ipv4_addr; - - if (adj->ipv4_addrs == NULL) - return; - - for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr)) - { - if (!nexthoplookup (nexthops, ipv4_addr, - adj->circuit->interface->ifindex)) - { - nh = isis_nexthop_create (ipv4_addr, - adj->circuit->interface->ifindex); - nh->router_address = adj->router_address; - listnode_add (nexthops, nh); + struct isis_nexthop *nh; + struct listnode *node; + struct in_addr *ipv4_addr; + + if (adj->ipv4_addrs == NULL) + return; + + for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, ipv4_addr)) { + if (!nexthoplookup(nexthops, ipv4_addr, + adj->circuit->interface->ifindex)) { + nh = isis_nexthop_create( + ipv4_addr, adj->circuit->interface->ifindex); + nh->router_address = adj->router_address; + listnode_add(nexthops, nh); + } } - } } -static void -adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj) +static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj) { - struct listnode *node; - struct in6_addr *ipv6_addr; - struct isis_nexthop6 *nh6; - - if (!adj->ipv6_addrs) - return; - - for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr)) - { - if (!nexthop6lookup (nexthops6, ipv6_addr, - adj->circuit->interface->ifindex)) - { - nh6 = isis_nexthop6_create (ipv6_addr, - adj->circuit->interface->ifindex); - nh6->router_address6 = adj->router_address6; - listnode_add (nexthops6, nh6); + struct listnode *node; + struct in6_addr *ipv6_addr; + struct isis_nexthop6 *nh6; + + if (!adj->ipv6_addrs) + return; + + for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, ipv6_addr)) { + if (!nexthop6lookup(nexthops6, ipv6_addr, + adj->circuit->interface->ifindex)) { + nh6 = isis_nexthop6_create( + ipv6_addr, adj->circuit->interface->ifindex); + nh6->router_address6 = adj->router_address6; + listnode_add(nexthops6, nh6); + } } - } } -static struct isis_route_info * -isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth, - struct list *adjacencies) +static struct isis_route_info *isis_route_info_new(struct prefix *prefix, + uint32_t cost, + uint32_t depth, + struct list *adjacencies) { - struct isis_route_info *rinfo; - struct isis_adjacency *adj; - struct listnode *node; - - rinfo = XCALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info)); - - if (prefix->family == AF_INET) - { - rinfo->nexthops = list_new (); - for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj)) - { - /* check for force resync this route */ - if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) - SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - /* update neighbor router address */ - if (depth == 2 && prefix->prefixlen == 32) - adj->router_address = prefix->u.prefix4; - adjinfo2nexthop (rinfo->nexthops, adj); - } - } - if (prefix->family == AF_INET6) - { - rinfo->nexthops6 = list_new (); - for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj)) - { - /* check for force resync this route */ - if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) - SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - /* update neighbor router address */ - if (depth == 2 && prefix->prefixlen == 128) - adj->router_address6 = prefix->u.prefix6; - adjinfo2nexthop6 (rinfo->nexthops6, adj); - } - } - - rinfo->cost = cost; - rinfo->depth = depth; - - return rinfo; + struct isis_route_info *rinfo; + struct isis_adjacency *adj; + struct listnode *node; + + rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info)); + + if (prefix->family == AF_INET) { + rinfo->nexthops = list_new(); + for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) { + /* check for force resync this route */ + if (CHECK_FLAG(adj->circuit->flags, + ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) + SET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + /* update neighbor router address */ + if (depth == 2 && prefix->prefixlen == 32) + adj->router_address = prefix->u.prefix4; + adjinfo2nexthop(rinfo->nexthops, adj); + } + } + if (prefix->family == AF_INET6) { + rinfo->nexthops6 = list_new(); + for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) { + /* check for force resync this route */ + if (CHECK_FLAG(adj->circuit->flags, + ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) + SET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + /* update neighbor router address */ + if (depth == 2 && prefix->prefixlen == 128) + adj->router_address6 = prefix->u.prefix6; + adjinfo2nexthop6(rinfo->nexthops6, adj); + } + } + + rinfo->cost = cost; + rinfo->depth = depth; + + return rinfo; } -static void -isis_route_info_delete (struct isis_route_info *route_info) +static void isis_route_info_delete(struct isis_route_info *route_info) { - if (route_info->nexthops) - { - route_info->nexthops->del = (void (*)(void *)) isis_nexthop_delete; - list_delete (route_info->nexthops); - } - - if (route_info->nexthops6) - { - route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete; - list_delete (route_info->nexthops6); - } - - XFREE (MTYPE_ISIS_ROUTE_INFO, route_info); + if (route_info->nexthops) { + route_info->nexthops->del = + (void (*)(void *))isis_nexthop_delete; + list_delete(route_info->nexthops); + } + + if (route_info->nexthops6) { + route_info->nexthops6->del = + (void (*)(void *))isis_nexthop6_delete; + list_delete(route_info->nexthops6); + } + + XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); } -static int -isis_route_info_same_attrib (struct isis_route_info *new, - struct isis_route_info *old) +static int isis_route_info_same_attrib(struct isis_route_info *new, + struct isis_route_info *old) { - if (new->cost != old->cost) - return 0; - if (new->depth != old->depth) - return 0; + if (new->cost != old->cost) + return 0; + if (new->depth != old->depth) + return 0; - return 1; + return 1; } -static int -isis_route_info_same (struct isis_route_info *new, - struct isis_route_info *old, u_char family) +static int isis_route_info_same(struct isis_route_info *new, + struct isis_route_info *old, u_char family) { - struct listnode *node; - struct isis_nexthop *nexthop; - struct isis_nexthop6 *nexthop6; - - if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return 0; - - if (CHECK_FLAG (new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) - return 0; - - if (!isis_route_info_same_attrib (new, old)) - return 0; - - if (family == AF_INET) - { - for (ALL_LIST_ELEMENTS_RO (new->nexthops, node, nexthop)) - if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) - == 0) - return 0; - - for (ALL_LIST_ELEMENTS_RO (old->nexthops, node, nexthop)) - if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) - == 0) - return 0; - } - else if (family == AF_INET6) - { - for (ALL_LIST_ELEMENTS_RO (new->nexthops6, node, nexthop6)) - if (nexthop6lookup (old->nexthops6, &nexthop6->ip6, - nexthop6->ifindex) == 0) - return 0; - - for (ALL_LIST_ELEMENTS_RO (old->nexthops6, node, nexthop6)) - if (nexthop6lookup (new->nexthops6, &nexthop6->ip6, - nexthop6->ifindex) == 0) - return 0; - } - - return 1; + struct listnode *node; + struct isis_nexthop *nexthop; + struct isis_nexthop6 *nexthop6; + + if (!CHECK_FLAG(old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + return 0; + + if (CHECK_FLAG(new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) + return 0; + + if (!isis_route_info_same_attrib(new, old)) + return 0; + + if (family == AF_INET) { + for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) + if (nexthoplookup(old->nexthops, &nexthop->ip, + nexthop->ifindex) + == 0) + return 0; + + for (ALL_LIST_ELEMENTS_RO(old->nexthops, node, nexthop)) + if (nexthoplookup(new->nexthops, &nexthop->ip, + nexthop->ifindex) + == 0) + return 0; + } else if (family == AF_INET6) { + for (ALL_LIST_ELEMENTS_RO(new->nexthops6, node, nexthop6)) + if (nexthop6lookup(old->nexthops6, &nexthop6->ip6, + nexthop6->ifindex) + == 0) + return 0; + + for (ALL_LIST_ELEMENTS_RO(old->nexthops6, node, nexthop6)) + if (nexthop6lookup(new->nexthops6, &nexthop6->ip6, + nexthop6->ifindex) + == 0) + return 0; + } + + return 1; } -struct isis_route_info * -isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth, - struct list *adjacencies, struct isis_area *area, - int level) +struct isis_route_info *isis_route_create(struct prefix *prefix, u_int32_t cost, + u_int32_t depth, + struct list *adjacencies, + struct isis_area *area, int level) { - struct route_node *route_node; - struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; - char buff[PREFIX2STR_BUFFER]; - u_char family; - - family = prefix->family; - /* for debugs */ - prefix2str (prefix, buff, sizeof (buff)); - - rinfo_new = isis_route_info_new (prefix, cost, depth, adjacencies); - - if (family == AF_INET) - route_node = route_node_get (area->route_table[level - 1], prefix); - else if (family == AF_INET6) - route_node = route_node_get (area->route_table6[level - 1], prefix); - else - { - isis_route_info_delete (rinfo_new); - return NULL; - } - - rinfo_old = route_node->info; - if (!rinfo_old) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route created: %s", area->area_tag, buff); - route_info = rinfo_new; - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - else - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route already exists: %s", area->area_tag, - buff); - if (isis_route_info_same (rinfo_new, rinfo_old, family)) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, - buff); - isis_route_info_delete (rinfo_new); - route_info = rinfo_old; - } - else - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route changed: %s", area->area_tag, - buff); - isis_route_info_delete (rinfo_old); - route_info = rinfo_new; - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - } - - SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE); - route_node->info = route_info; - - return route_info; + struct route_node *route_node; + struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; + char buff[PREFIX2STR_BUFFER]; + u_char family; + + family = prefix->family; + /* for debugs */ + prefix2str(prefix, buff, sizeof(buff)); + + rinfo_new = isis_route_info_new(prefix, cost, depth, adjacencies); + + if (family == AF_INET) + route_node = + route_node_get(area->route_table[level - 1], prefix); + else if (family == AF_INET6) + route_node = + route_node_get(area->route_table6[level - 1], prefix); + else { + isis_route_info_delete(rinfo_new); + return NULL; + } + + rinfo_old = route_node->info; + if (!rinfo_old) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route created: %s", + area->area_tag, buff); + route_info = rinfo_new; + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } else { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route already exists: %s", + area->area_tag, buff); + if (isis_route_info_same(rinfo_new, rinfo_old, family)) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route unchanged: %s", + area->area_tag, buff); + isis_route_info_delete(rinfo_new); + route_info = rinfo_old; + } else { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route changed: %s", + area->area_tag, buff); + isis_route_info_delete(rinfo_old); + route_info = rinfo_new; + UNSET_FLAG(route_info->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } + } + + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE); + route_node->info = route_info; + + return route_info; } -static void -isis_route_delete (struct prefix *prefix, struct route_table *table) +static void isis_route_delete(struct prefix *prefix, struct route_table *table) { - struct route_node *rode; - struct isis_route_info *rinfo; - char buff[PREFIX2STR_BUFFER]; - - /* for log */ - prefix2str (prefix, buff, sizeof (buff)); - - - rode = route_node_get (table, prefix); - rinfo = rode->info; - - if (rinfo == NULL) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte: tried to delete non-existant route %s", buff); - return; - } - - if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - { - UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte: route delete %s", buff); - isis_zebra_route_update (prefix, rinfo); - } - isis_route_info_delete (rinfo); - rode->info = NULL; - - return; + struct route_node *rode; + struct isis_route_info *rinfo; + char buff[PREFIX2STR_BUFFER]; + + /* for log */ + prefix2str(prefix, buff, sizeof(buff)); + + + rode = route_node_get(table, prefix); + rinfo = rode->info; + + if (rinfo == NULL) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug( + "ISIS-Rte: tried to delete non-existant route %s", + buff); + return; + } + + if (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) { + UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte: route delete %s", buff); + isis_zebra_route_update(prefix, rinfo); + } + isis_route_info_delete(rinfo); + rode->info = NULL; + + return; } /* Validating routes in particular table. */ -static void -isis_route_validate_table (struct isis_area *area, struct route_table *table) +static void isis_route_validate_table(struct isis_area *area, + struct route_table *table) { - struct route_node *rnode, *drnode; - struct isis_route_info *rinfo; - char buff[PREFIX2STR_BUFFER]; - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - rinfo = rnode->info; - - if (isis->debugs & DEBUG_RTE_EVENTS) - { - prefix2str (&rnode->p, buff, sizeof (buff)); - zlog_debug ("ISIS-Rte (%s): route validate: %s %s %s %s", - area->area_tag, - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED) ? - "synced" : "not-synced"), - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC) ? - "resync" : "not-resync"), - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ? - "active" : "inactive"), buff); + struct route_node *rnode, *drnode; + struct isis_route_info *rinfo; + char buff[PREFIX2STR_BUFFER]; + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + rinfo = rnode->info; + + if (isis->debugs & DEBUG_RTE_EVENTS) { + prefix2str(&rnode->p, buff, sizeof(buff)); + zlog_debug( + "ISIS-Rte (%s): route validate: %s %s %s %s", + area->area_tag, + (CHECK_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED) + ? "synced" + : "not-synced"), + (CHECK_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC) + ? "resync" + : "not-resync"), + (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) + ? "active" + : "inactive"), + buff); + } + + isis_zebra_route_update(&rnode->p, rinfo); + if (!CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE)) { + /* Area is either L1 or L2 => we use level route tables + * directly for + * validating => no problems with deleting routes. */ + if (area->is_type != IS_LEVEL_1_AND_2) { + isis_route_delete(&rnode->p, table); + continue; + } + /* If area is L1L2, we work with merge table and + * therefore must + * delete node from level tables as well before deleting + * route info. + * FIXME: Is it performance problem? There has to be the + * better way. + * Like not to deal with it here at all (see the next + * comment)? */ + if (rnode->p.family == AF_INET) { + drnode = route_node_get(area->route_table[0], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + drnode = route_node_get(area->route_table[1], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + } + + if (rnode->p.family == AF_INET6) { + drnode = route_node_get(area->route_table6[0], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + drnode = route_node_get(area->route_table6[1], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + } + + isis_route_delete(&rnode->p, table); + } } - - isis_zebra_route_update (&rnode->p, rinfo); - if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE)) - { - /* Area is either L1 or L2 => we use level route tables directly for - * validating => no problems with deleting routes. */ - if (area->is_type != IS_LEVEL_1_AND_2) - { - isis_route_delete (&rnode->p, table); - continue; - } - /* If area is L1L2, we work with merge table and therefore must - * delete node from level tables as well before deleting route info. - * FIXME: Is it performance problem? There has to be the better way. - * Like not to deal with it here at all (see the next comment)? */ - if (rnode->p.family == AF_INET) - { - drnode = route_node_get (area->route_table[0], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - drnode = route_node_get (area->route_table[1], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - } - - if (rnode->p.family == AF_INET6) - { - drnode = route_node_get (area->route_table6[0], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - drnode = route_node_get (area->route_table6[1], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - } - - isis_route_delete (&rnode->p, table); - } - } } /* Function to validate route tables for L1L2 areas. In this case we can't use @@ -557,106 +544,99 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table) * * FIXME: Is it right place to do it at all? Maybe we should push both levels * to the RIB with different zebra route types and let RIB handle this? */ -static void -isis_route_validate_merge (struct isis_area *area, int family) +static void isis_route_validate_merge(struct isis_area *area, int family) { - struct route_table *table = NULL; - struct route_table *merge; - struct route_node *rnode, *mrnode; - - merge = route_table_init (); - - if (family == AF_INET) - table = area->route_table[0]; - else if (family == AF_INET6) - table = area->route_table6[0]; - else - { - zlog_warn ("ISIS-Rte (%s) %s called for unknown family %d", - area->area_tag, __func__, family); - route_table_finish(merge); - return; - } - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - mrnode = route_node_get (merge, &rnode->p); - mrnode->info = rnode->info; - } - - if (family == AF_INET) - table = area->route_table[1]; - else if (family == AF_INET6) - table = area->route_table6[1]; - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - mrnode = route_node_get (merge, &rnode->p); - if (mrnode->info != NULL) - continue; - mrnode->info = rnode->info; - } - - isis_route_validate_table (area, merge); - route_table_finish (merge); + struct route_table *table = NULL; + struct route_table *merge; + struct route_node *rnode, *mrnode; + + merge = route_table_init(); + + if (family == AF_INET) + table = area->route_table[0]; + else if (family == AF_INET6) + table = area->route_table6[0]; + else { + zlog_warn("ISIS-Rte (%s) %s called for unknown family %d", + area->area_tag, __func__, family); + route_table_finish(merge); + return; + } + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + mrnode = route_node_get(merge, &rnode->p); + mrnode->info = rnode->info; + } + + if (family == AF_INET) + table = area->route_table[1]; + else if (family == AF_INET6) + table = area->route_table6[1]; + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + mrnode = route_node_get(merge, &rnode->p); + if (mrnode->info != NULL) + continue; + mrnode->info = rnode->info; + } + + isis_route_validate_table(area, merge); + route_table_finish(merge); } /* Walk through route tables and propagate necessary changes into RIB. In case * of L1L2 area, level tables have to be merged at first. */ -void -isis_route_validate (struct isis_area *area) +void isis_route_validate(struct isis_area *area) { - struct listnode *node; - struct isis_circuit *circuit; - - if (area->is_type == IS_LEVEL_1) - isis_route_validate_table (area, area->route_table[0]); - else if (area->is_type == IS_LEVEL_2) - isis_route_validate_table (area, area->route_table[1]); - else - isis_route_validate_merge (area, AF_INET); - - if (area->is_type == IS_LEVEL_1) - isis_route_validate_table (area, area->route_table6[0]); - else if (area->is_type == IS_LEVEL_2) - isis_route_validate_table (area, area->route_table6[1]); - else - isis_route_validate_merge (area, AF_INET6); - - if (!area->circuit_list) { - return; - } - /* walk all circuits and reset any spf specific flags */ - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) - UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); - - return; + struct listnode *node; + struct isis_circuit *circuit; + + if (area->is_type == IS_LEVEL_1) + isis_route_validate_table(area, area->route_table[0]); + else if (area->is_type == IS_LEVEL_2) + isis_route_validate_table(area, area->route_table[1]); + else + isis_route_validate_merge(area, AF_INET); + + if (area->is_type == IS_LEVEL_1) + isis_route_validate_table(area, area->route_table6[0]); + else if (area->is_type == IS_LEVEL_2) + isis_route_validate_table(area, area->route_table6[1]); + else + isis_route_validate_merge(area, AF_INET6); + + if (!area->circuit_list) { + return; + } + /* walk all circuits and reset any spf specific flags */ + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) + UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); + + return; } -void -isis_route_invalidate_table (struct isis_area *area, struct route_table *table) +void isis_route_invalidate_table(struct isis_area *area, + struct route_table *table) { - struct route_node *rode; - struct isis_route_info *rinfo; - for (rode = route_top (table); rode; rode = route_next (rode)) - { - if (rode->info == NULL) - continue; - rinfo = rode->info; - - UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); - } + struct route_node *rode; + struct isis_route_info *rinfo; + for (rode = route_top(table); rode; rode = route_next(rode)) { + if (rode->info == NULL) + continue; + rinfo = rode->info; + + UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); + } } -void -isis_route_invalidate (struct isis_area *area) +void isis_route_invalidate(struct isis_area *area) { - if (area->is_type & IS_LEVEL_1) - isis_route_invalidate_table (area, area->route_table[0]); - if (area->is_type & IS_LEVEL_2) - isis_route_invalidate_table (area, area->route_table[1]); + if (area->is_type & IS_LEVEL_1) + isis_route_invalidate_table(area, area->route_table[0]); + if (area->is_type & IS_LEVEL_2) + isis_route_invalidate_table(area, area->route_table[1]); } diff --git a/isisd/isis_route.h b/isisd/isis_route.h index 24bd786fa..6c7d9aea9 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -2,20 +2,20 @@ * IS-IS Rout(e)ing protocol - isis_route.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * * based on ../ospf6d/ospf6_route.[ch] * by Yasuhiro Ohara * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -25,42 +25,39 @@ #ifndef _ZEBRA_ISIS_ROUTE_H #define _ZEBRA_ISIS_ROUTE_H -struct isis_nexthop6 -{ - ifindex_t ifindex; - struct in6_addr ip6; - struct in6_addr router_address6; - unsigned int lock; +struct isis_nexthop6 { + ifindex_t ifindex; + struct in6_addr ip6; + struct in6_addr router_address6; + unsigned int lock; }; -struct isis_nexthop -{ - ifindex_t ifindex; - struct in_addr ip; - struct in_addr router_address; - unsigned int lock; +struct isis_nexthop { + ifindex_t ifindex; + struct in_addr ip; + struct in_addr router_address; + unsigned int lock; }; -struct isis_route_info -{ +struct isis_route_info { #define ISIS_ROUTE_FLAG_ACTIVE 0x01 /* active route for the prefix */ #define ISIS_ROUTE_FLAG_ZEBRA_SYNCED 0x02 /* set when route synced to zebra */ #define ISIS_ROUTE_FLAG_ZEBRA_RESYNC 0x04 /* set when route needs to sync */ - u_char flag; - u_int32_t cost; - u_int32_t depth; - struct list *nexthops; - struct list *nexthops6; + u_char flag; + u_int32_t cost; + u_int32_t depth; + struct list *nexthops; + struct list *nexthops6; }; -struct isis_route_info *isis_route_create (struct prefix *prefix, - u_int32_t cost, u_int32_t depth, - struct list *adjacencies, - struct isis_area *area, int level); +struct isis_route_info *isis_route_create(struct prefix *prefix, u_int32_t cost, + u_int32_t depth, + struct list *adjacencies, + struct isis_area *area, int level); -void isis_route_validate (struct isis_area *area); -void isis_route_invalidate_table (struct isis_area *area, - struct route_table *table); -void isis_route_invalidate (struct isis_area *area); +void isis_route_validate(struct isis_area *area); +void isis_route_invalidate_table(struct isis_area *area, + struct route_table *table); +void isis_route_invalidate(struct isis_area *area); #endif /* _ZEBRA_ISIS_ROUTE_H */ diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c index cf4562dbc..44d7fa040 100644 --- a/isisd/isis_routemap.c +++ b/isisd/isis_routemap.c @@ -3,14 +3,14 @@ * * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program 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 of the License, or (at your option) + * This program 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 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -50,229 +50,201 @@ #include "isis_zebra.h" #include "isis_routemap.h" -static route_map_result_t -route_match_ip_address(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_match_ip_address(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - struct access_list *alist; + struct access_list *alist; - if (type != RMAP_ISIS) - return RMAP_NOMATCH; + if (type != RMAP_ISIS) + return RMAP_NOMATCH; - alist = access_list_lookup(AFI_IP, (char*)rule); - if (access_list_apply(alist, prefix) != FILTER_DENY) - return RMAP_MATCH; + alist = access_list_lookup(AFI_IP, (char *)rule); + if (access_list_apply(alist, prefix) != FILTER_DENY) + return RMAP_MATCH; - return RMAP_NOMATCH; + return RMAP_NOMATCH; } -static void * -route_match_ip_address_compile(const char *arg) +static void *route_match_ip_address_compile(const char *arg) { - return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ip_address_free(void *rule) +static void route_match_ip_address_free(void *rule) { - XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -static struct route_map_rule_cmd route_match_ip_address_cmd = -{ - "ip address", - route_match_ip_address, - route_match_ip_address_compile, - route_match_ip_address_free -}; +static struct route_map_rule_cmd route_match_ip_address_cmd = { + "ip address", route_match_ip_address, route_match_ip_address_compile, + route_match_ip_address_free}; /* ------------------------------------------------------------*/ static route_map_result_t route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) + route_map_object_t type, void *object) { - struct prefix_list *plist; + struct prefix_list *plist; - if (type != RMAP_ISIS) - return RMAP_NOMATCH; + if (type != RMAP_ISIS) + return RMAP_NOMATCH; - plist = prefix_list_lookup(AFI_IP, (char*)rule); - if (prefix_list_apply(plist, prefix) != PREFIX_DENY) - return RMAP_MATCH; + plist = prefix_list_lookup(AFI_IP, (char *)rule); + if (prefix_list_apply(plist, prefix) != PREFIX_DENY) + return RMAP_MATCH; - return RMAP_NOMATCH; + return RMAP_NOMATCH; } -static void * -route_match_ip_address_prefix_list_compile(const char *arg) +static void *route_match_ip_address_prefix_list_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ip_address_prefix_list_free (void *rule) +static void route_match_ip_address_prefix_list_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = -{ - "ip address prefix-list", - route_match_ip_address_prefix_list, - route_match_ip_address_prefix_list_compile, - route_match_ip_address_prefix_list_free -}; +struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { + "ip address prefix-list", route_match_ip_address_prefix_list, + route_match_ip_address_prefix_list_compile, + route_match_ip_address_prefix_list_free}; /* ------------------------------------------------------------*/ -static route_map_result_t -route_match_ipv6_address(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_match_ipv6_address(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - struct access_list *alist; + struct access_list *alist; - if (type != RMAP_ISIS) - return RMAP_NOMATCH; + if (type != RMAP_ISIS) + return RMAP_NOMATCH; - alist = access_list_lookup(AFI_IP6, (char*)rule); - if (access_list_apply(alist, prefix) != FILTER_DENY) - return RMAP_MATCH; + alist = access_list_lookup(AFI_IP6, (char *)rule); + if (access_list_apply(alist, prefix) != FILTER_DENY) + return RMAP_MATCH; - return RMAP_NOMATCH; + return RMAP_NOMATCH; } -static void * -route_match_ipv6_address_compile(const char *arg) +static void *route_match_ipv6_address_compile(const char *arg) { - return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ipv6_address_free(void *rule) +static void route_match_ipv6_address_free(void *rule) { - XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -static struct route_map_rule_cmd route_match_ipv6_address_cmd = -{ - "ipv6 address", - route_match_ipv6_address, - route_match_ipv6_address_compile, - route_match_ipv6_address_free -}; +static struct route_map_rule_cmd route_match_ipv6_address_cmd = { + "ipv6 address", route_match_ipv6_address, + route_match_ipv6_address_compile, route_match_ipv6_address_free}; /* ------------------------------------------------------------*/ static route_map_result_t route_match_ipv6_address_prefix_list(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) + route_map_object_t type, void *object) { - struct prefix_list *plist; + struct prefix_list *plist; - if (type != RMAP_ISIS) - return RMAP_NOMATCH; + if (type != RMAP_ISIS) + return RMAP_NOMATCH; - plist = prefix_list_lookup(AFI_IP6, (char*)rule); - if (prefix_list_apply(plist, prefix) != PREFIX_DENY) - return RMAP_MATCH; + plist = prefix_list_lookup(AFI_IP6, (char *)rule); + if (prefix_list_apply(plist, prefix) != PREFIX_DENY) + return RMAP_MATCH; - return RMAP_NOMATCH; + return RMAP_NOMATCH; } -static void * -route_match_ipv6_address_prefix_list_compile(const char *arg) +static void *route_match_ipv6_address_prefix_list_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ipv6_address_prefix_list_free (void *rule) +static void route_match_ipv6_address_prefix_list_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = -{ - "ipv6 address prefix-list", - route_match_ipv6_address_prefix_list, - route_match_ipv6_address_prefix_list_compile, - route_match_ipv6_address_prefix_list_free -}; +struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { + "ipv6 address prefix-list", route_match_ipv6_address_prefix_list, + route_match_ipv6_address_prefix_list_compile, + route_match_ipv6_address_prefix_list_free}; /* ------------------------------------------------------------*/ -static route_map_result_t -route_set_metric(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, + route_map_object_t type, + void *object) { - uint32_t *metric; - struct isis_ext_info *info; + uint32_t *metric; + struct isis_ext_info *info; - if (type == RMAP_ISIS) - { - metric = rule; - info = object; + if (type == RMAP_ISIS) { + metric = rule; + info = object; - info->metric = *metric; - } - return RMAP_OKAY; + info->metric = *metric; + } + return RMAP_OKAY; } -static void * -route_set_metric_compile(const char *arg) +static void *route_set_metric_compile(const char *arg) { - unsigned long metric; - char *endp; - uint32_t *ret; + unsigned long metric; + char *endp; + uint32_t *ret; - metric = strtoul(arg, &endp, 10); - if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) - return NULL; + metric = strtoul(arg, &endp, 10); + if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) + return NULL; - ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); - *ret = metric; + ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); + *ret = metric; - return ret; + return ret; } -static void -route_set_metric_free(void *rule) +static void route_set_metric_free(void *rule) { - XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -static struct route_map_rule_cmd route_set_metric_cmd = -{ - "metric", - route_set_metric, - route_set_metric_compile, - route_set_metric_free -}; - -void -isis_route_map_init(void) +static struct route_map_rule_cmd route_set_metric_cmd = { + "metric", route_set_metric, route_set_metric_compile, + route_set_metric_free}; + +void isis_route_map_init(void) { - route_map_init(); + route_map_init(); - route_map_match_ip_address_hook (generic_match_add); - route_map_no_match_ip_address_hook (generic_match_delete); + route_map_match_ip_address_hook(generic_match_add); + route_map_no_match_ip_address_hook(generic_match_delete); - route_map_match_ip_address_prefix_list_hook (generic_match_add); - route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); + route_map_match_ip_address_prefix_list_hook(generic_match_add); + route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); - route_map_match_ipv6_address_hook (generic_match_add); - route_map_no_match_ipv6_address_hook (generic_match_delete); + route_map_match_ipv6_address_hook(generic_match_add); + route_map_no_match_ipv6_address_hook(generic_match_delete); - route_map_match_ipv6_address_prefix_list_hook (generic_match_add); - route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete); + route_map_match_ipv6_address_prefix_list_hook(generic_match_add); + route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); - route_map_set_metric_hook (generic_set_add); - route_map_no_set_metric_hook (generic_set_delete); + route_map_set_metric_hook(generic_set_add); + route_map_no_set_metric_hook(generic_set_delete); - route_map_install_match(&route_match_ip_address_cmd); - route_map_install_match(&route_match_ip_address_prefix_list_cmd); - route_map_install_match(&route_match_ipv6_address_cmd); - route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); - route_map_install_set(&route_set_metric_cmd); + route_map_install_match(&route_match_ip_address_cmd); + route_map_install_match(&route_match_ip_address_prefix_list_cmd); + route_map_install_match(&route_match_ipv6_address_cmd); + route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); + route_map_install_set(&route_set_metric_cmd); } diff --git a/isisd/isis_routemap.h b/isisd/isis_routemap.h index b0ff559ac..f1577666b 100644 --- a/isisd/isis_routemap.h +++ b/isisd/isis_routemap.h @@ -3,14 +3,14 @@ * * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program 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 of the License, or (at your option) + * This program 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 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 4b5592c15..615c2eeaa 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -3,18 +3,18 @@ * The SPT algorithm * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org> * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -56,1319 +56,1311 @@ DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); struct isis_spf_run { - struct isis_area *area; - int level; + struct isis_area *area; + int level; }; /* 7.2.7 */ -static void -remove_excess_adjs (struct list *adjs) +static void remove_excess_adjs(struct list *adjs) { - struct listnode *node, *excess = NULL; - struct isis_adjacency *adj, *candidate = NULL; - int comp; - - for (ALL_LIST_ELEMENTS_RO (adjs, node, adj)) - { - if (excess == NULL) - excess = node; - candidate = listgetdata (excess); - - if (candidate->sys_type < adj->sys_type) - { - excess = node; - continue; - } - if (candidate->sys_type > adj->sys_type) - continue; + struct listnode *node, *excess = NULL; + struct isis_adjacency *adj, *candidate = NULL; + int comp; + + for (ALL_LIST_ELEMENTS_RO(adjs, node, adj)) { + if (excess == NULL) + excess = node; + candidate = listgetdata(excess); + + if (candidate->sys_type < adj->sys_type) { + excess = node; + continue; + } + if (candidate->sys_type > adj->sys_type) + continue; - comp = memcmp (candidate->sysid, adj->sysid, ISIS_SYS_ID_LEN); - if (comp > 0) - { - excess = node; - continue; - } - if (comp < 0) - continue; + comp = memcmp(candidate->sysid, adj->sysid, ISIS_SYS_ID_LEN); + if (comp > 0) { + excess = node; + continue; + } + if (comp < 0) + continue; - if (candidate->circuit->circuit_id > adj->circuit->circuit_id) - { - excess = node; - continue; - } + if (candidate->circuit->circuit_id > adj->circuit->circuit_id) { + excess = node; + continue; + } - if (candidate->circuit->circuit_id < adj->circuit->circuit_id) - continue; + if (candidate->circuit->circuit_id < adj->circuit->circuit_id) + continue; - comp = memcmp (candidate->snpa, adj->snpa, ETH_ALEN); - if (comp > 0) - { - excess = node; - continue; + comp = memcmp(candidate->snpa, adj->snpa, ETH_ALEN); + if (comp > 0) { + excess = node; + continue; + } } - } - list_delete_node (adjs, excess); + list_delete_node(adjs, excess); - return; + return; } -static const char * -vtype2string (enum vertextype vtype) +static const char *vtype2string(enum vertextype vtype) { - switch (vtype) - { - case VTYPE_PSEUDO_IS: - return "pseudo_IS"; - break; - case VTYPE_PSEUDO_TE_IS: - return "pseudo_TE-IS"; - break; - case VTYPE_NONPSEUDO_IS: - return "IS"; - break; - case VTYPE_NONPSEUDO_TE_IS: - return "TE-IS"; - break; - case VTYPE_ES: - return "ES"; - break; - case VTYPE_IPREACH_INTERNAL: - return "IP internal"; - break; - case VTYPE_IPREACH_EXTERNAL: - return "IP external"; - break; - case VTYPE_IPREACH_TE: - return "IP TE"; - break; - case VTYPE_IP6REACH_INTERNAL: - return "IP6 internal"; - break; - case VTYPE_IP6REACH_EXTERNAL: - return "IP6 external"; - break; - default: - return "UNKNOWN"; - } - return NULL; /* Not reached */ + switch (vtype) { + case VTYPE_PSEUDO_IS: + return "pseudo_IS"; + break; + case VTYPE_PSEUDO_TE_IS: + return "pseudo_TE-IS"; + break; + case VTYPE_NONPSEUDO_IS: + return "IS"; + break; + case VTYPE_NONPSEUDO_TE_IS: + return "TE-IS"; + break; + case VTYPE_ES: + return "ES"; + break; + case VTYPE_IPREACH_INTERNAL: + return "IP internal"; + break; + case VTYPE_IPREACH_EXTERNAL: + return "IP external"; + break; + case VTYPE_IPREACH_TE: + return "IP TE"; + break; + case VTYPE_IP6REACH_INTERNAL: + return "IP6 internal"; + break; + case VTYPE_IP6REACH_EXTERNAL: + return "IP6 external"; + break; + default: + return "UNKNOWN"; + } + return NULL; /* Not reached */ } -static const char * -vid2string (struct isis_vertex *vertex, char * buff, int size) +static const char *vid2string(struct isis_vertex *vertex, char *buff, int size) { - if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) - { - return print_sys_hostname (vertex->N.id); - } - - if (VTYPE_IP(vertex->type)) - { - prefix2str ((struct prefix *) &vertex->N.prefix, buff, size); - return buff; - } - - return "UNKNOWN"; + if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) { + return print_sys_hostname(vertex->N.id); + } + + if (VTYPE_IP(vertex->type)) { + prefix2str((struct prefix *)&vertex->N.prefix, buff, size); + return buff; + } + + return "UNKNOWN"; } -static struct isis_vertex * -isis_vertex_new (void *id, enum vertextype vtype) +static struct isis_vertex *isis_vertex_new(void *id, enum vertextype vtype) { - struct isis_vertex *vertex; - - vertex = XCALLOC (MTYPE_ISIS_VERTEX, sizeof (struct isis_vertex)); - - vertex->type = vtype; - - if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) - { - memcpy (vertex->N.id, (u_char *) id, ISIS_SYS_ID_LEN + 1); - } - else if (VTYPE_IP(vtype)) - { - memcpy (&vertex->N.prefix, (struct prefix *) id, sizeof (struct prefix)); - } - else - { - zlog_err ("WTF!"); - } - - vertex->Adj_N = list_new (); - vertex->parents = list_new (); - vertex->children = list_new (); - - return vertex; + struct isis_vertex *vertex; + + vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex)); + + vertex->type = vtype; + + if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) { + memcpy(vertex->N.id, (u_char *)id, ISIS_SYS_ID_LEN + 1); + } else if (VTYPE_IP(vtype)) { + memcpy(&vertex->N.prefix, (struct prefix *)id, + sizeof(struct prefix)); + } else { + zlog_err("WTF!"); + } + + vertex->Adj_N = list_new(); + vertex->parents = list_new(); + vertex->children = list_new(); + + return vertex; } -static void -isis_vertex_del (struct isis_vertex *vertex) +static void isis_vertex_del(struct isis_vertex *vertex) { - list_delete (vertex->Adj_N); - vertex->Adj_N = NULL; - list_delete (vertex->parents); - vertex->parents = NULL; - list_delete (vertex->children); - vertex->children = NULL; + list_delete(vertex->Adj_N); + vertex->Adj_N = NULL; + list_delete(vertex->parents); + vertex->parents = NULL; + list_delete(vertex->children); + vertex->children = NULL; - memset(vertex, 0, sizeof(struct isis_vertex)); - XFREE (MTYPE_ISIS_VERTEX, vertex); + memset(vertex, 0, sizeof(struct isis_vertex)); + XFREE(MTYPE_ISIS_VERTEX, vertex); - return; + return; } -static void -isis_vertex_adj_del (struct isis_vertex *vertex, struct isis_adjacency *adj) +static void isis_vertex_adj_del(struct isis_vertex *vertex, + struct isis_adjacency *adj) { - struct listnode *node, *nextnode; - if (!vertex) - return; - for (node = listhead (vertex->Adj_N); node; node = nextnode) - { - nextnode = listnextnode(node); - if (listgetdata(node) == adj) - list_delete_node(vertex->Adj_N, node); - } - return; + struct listnode *node, *nextnode; + if (!vertex) + return; + for (node = listhead(vertex->Adj_N); node; node = nextnode) { + nextnode = listnextnode(node); + if (listgetdata(node) == adj) + list_delete_node(vertex->Adj_N, node); + } + return; } -struct isis_spftree * -isis_spftree_new (struct isis_area *area) +struct isis_spftree *isis_spftree_new(struct isis_area *area) { - struct isis_spftree *tree; - - tree = XCALLOC (MTYPE_ISIS_SPFTREE, sizeof (struct isis_spftree)); - if (tree == NULL) - { - zlog_err ("ISIS-Spf: isis_spftree_new Out of memory!"); - return NULL; - } - - tree->tents = list_new (); - tree->paths = list_new (); - tree->area = area; - tree->last_run_timestamp = 0; - tree->last_run_duration = 0; - tree->runcount = 0; - return tree; + struct isis_spftree *tree; + + tree = XCALLOC(MTYPE_ISIS_SPFTREE, sizeof(struct isis_spftree)); + if (tree == NULL) { + zlog_err("ISIS-Spf: isis_spftree_new Out of memory!"); + return NULL; + } + + tree->tents = list_new(); + tree->paths = list_new(); + tree->area = area; + tree->last_run_timestamp = 0; + tree->last_run_duration = 0; + tree->runcount = 0; + return tree; } -void -isis_spftree_del (struct isis_spftree *spftree) +void isis_spftree_del(struct isis_spftree *spftree) { - spftree->tents->del = (void (*)(void *)) isis_vertex_del; - list_delete (spftree->tents); - spftree->tents = NULL; + spftree->tents->del = (void (*)(void *))isis_vertex_del; + list_delete(spftree->tents); + spftree->tents = NULL; - spftree->paths->del = (void (*)(void *)) isis_vertex_del; - list_delete (spftree->paths); - spftree->paths = NULL; + spftree->paths->del = (void (*)(void *))isis_vertex_del; + list_delete(spftree->paths); + spftree->paths = NULL; - XFREE (MTYPE_ISIS_SPFTREE, spftree); + XFREE(MTYPE_ISIS_SPFTREE, spftree); - return; + return; } -static void -isis_spftree_adj_del (struct isis_spftree *spftree, struct isis_adjacency *adj) +static void isis_spftree_adj_del(struct isis_spftree *spftree, + struct isis_adjacency *adj) { - struct listnode *node; - if (!adj) - return; - for (node = listhead (spftree->tents); node; node = listnextnode (node)) - isis_vertex_adj_del (listgetdata (node), adj); - for (node = listhead (spftree->paths); node; node = listnextnode (node)) - isis_vertex_adj_del (listgetdata (node), adj); - return; + struct listnode *node; + if (!adj) + return; + for (node = listhead(spftree->tents); node; node = listnextnode(node)) + isis_vertex_adj_del(listgetdata(node), adj); + for (node = listhead(spftree->paths); node; node = listnextnode(node)) + isis_vertex_adj_del(listgetdata(node), adj); + return; } -void -spftree_area_init (struct isis_area *area) +void spftree_area_init(struct isis_area *area) { - if (area->is_type & IS_LEVEL_1) - { - if (area->spftree[0] == NULL) - area->spftree[0] = isis_spftree_new (area); - if (area->spftree6[0] == NULL) - area->spftree6[0] = isis_spftree_new (area); - } - - if (area->is_type & IS_LEVEL_2) - { - if (area->spftree[1] == NULL) - area->spftree[1] = isis_spftree_new (area); - if (area->spftree6[1] == NULL) - area->spftree6[1] = isis_spftree_new (area); - } - - return; + if (area->is_type & IS_LEVEL_1) { + if (area->spftree[0] == NULL) + area->spftree[0] = isis_spftree_new(area); + if (area->spftree6[0] == NULL) + area->spftree6[0] = isis_spftree_new(area); + } + + if (area->is_type & IS_LEVEL_2) { + if (area->spftree[1] == NULL) + area->spftree[1] = isis_spftree_new(area); + if (area->spftree6[1] == NULL) + area->spftree6[1] = isis_spftree_new(area); + } + + return; } -void -spftree_area_del (struct isis_area *area) +void spftree_area_del(struct isis_area *area) { - if (area->is_type & IS_LEVEL_1) - { - if (area->spftree[0] != NULL) - { - isis_spftree_del (area->spftree[0]); - area->spftree[0] = NULL; - } - if (area->spftree6[0]) - { - isis_spftree_del (area->spftree6[0]); - area->spftree6[0] = NULL; - } - } - - if (area->is_type & IS_LEVEL_2) - { - if (area->spftree[1] != NULL) - { - isis_spftree_del (area->spftree[1]); - area->spftree[1] = NULL; - } - if (area->spftree6[1] != NULL) - { - isis_spftree_del (area->spftree6[1]); - area->spftree6[1] = NULL; - } - } - - return; + if (area->is_type & IS_LEVEL_1) { + if (area->spftree[0] != NULL) { + isis_spftree_del(area->spftree[0]); + area->spftree[0] = NULL; + } + if (area->spftree6[0]) { + isis_spftree_del(area->spftree6[0]); + area->spftree6[0] = NULL; + } + } + + if (area->is_type & IS_LEVEL_2) { + if (area->spftree[1] != NULL) { + isis_spftree_del(area->spftree[1]); + area->spftree[1] = NULL; + } + if (area->spftree6[1] != NULL) { + isis_spftree_del(area->spftree6[1]); + area->spftree6[1] = NULL; + } + } + + return; } -void -spftree_area_adj_del (struct isis_area *area, struct isis_adjacency *adj) +void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj) { - if (area->is_type & IS_LEVEL_1) - { - if (area->spftree[0] != NULL) - isis_spftree_adj_del (area->spftree[0], adj); - if (area->spftree6[0] != NULL) - isis_spftree_adj_del (area->spftree6[0], adj); - } - - if (area->is_type & IS_LEVEL_2) - { - if (area->spftree[1] != NULL) - isis_spftree_adj_del (area->spftree[1], adj); - if (area->spftree6[1] != NULL) - isis_spftree_adj_del (area->spftree6[1], adj); - } - - return; + if (area->is_type & IS_LEVEL_1) { + if (area->spftree[0] != NULL) + isis_spftree_adj_del(area->spftree[0], adj); + if (area->spftree6[0] != NULL) + isis_spftree_adj_del(area->spftree6[0], adj); + } + + if (area->is_type & IS_LEVEL_2) { + if (area->spftree[1] != NULL) + isis_spftree_adj_del(area->spftree[1], adj); + if (area->spftree6[1] != NULL) + isis_spftree_adj_del(area->spftree6[1], adj); + } + + return; } -/* - * Find the system LSP: returns the LSP in our LSP database +/* + * Find the system LSP: returns the LSP in our LSP database * associated with the given system ID. */ -static struct isis_lsp * -isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid) +static struct isis_lsp *isis_root_system_lsp(struct isis_area *area, int level, + u_char *sysid) { - struct isis_lsp *lsp; - u_char lspid[ISIS_SYS_ID_LEN + 2]; - - memcpy (lspid, sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lspid) = 0; - LSP_FRAGMENT (lspid) = 0; - lsp = lsp_search (lspid, area->lspdb[level - 1]); - if (lsp && lsp->lsp_header->rem_lifetime != 0) - return lsp; - return NULL; + struct isis_lsp *lsp; + u_char lspid[ISIS_SYS_ID_LEN + 2]; + + memcpy(lspid, sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lspid) = 0; + LSP_FRAGMENT(lspid) = 0; + lsp = lsp_search(lspid, area->lspdb[level - 1]); + if (lsp && lsp->lsp_header->rem_lifetime != 0) + return lsp; + return NULL; } /* * Add this IS to the root of SPT */ -static struct isis_vertex * -isis_spf_add_root (struct isis_spftree *spftree, u_char *sysid) +static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree, + u_char *sysid) { - struct isis_vertex *vertex; - struct isis_lsp *lsp; + struct isis_vertex *vertex; + struct isis_lsp *lsp; #ifdef EXTREME_DEBUG - char buff[PREFIX2STR_BUFFER]; + char buff[PREFIX2STR_BUFFER]; #endif /* EXTREME_DEBUG */ - u_char id[ISIS_SYS_ID_LEN + 1]; + u_char id[ISIS_SYS_ID_LEN + 1]; - memcpy(id, sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID(id) = 0; + memcpy(id, sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(id) = 0; - lsp = isis_root_system_lsp (spftree->area, spftree->level, sysid); - if (lsp == NULL) - zlog_warn ("ISIS-Spf: could not find own l%d LSP!", spftree->level); + lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid); + if (lsp == NULL) + zlog_warn("ISIS-Spf: could not find own l%d LSP!", + spftree->level); - vertex = isis_vertex_new (id, spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS - : VTYPE_NONPSEUDO_TE_IS); - listnode_add (spftree->paths, vertex); + vertex = isis_vertex_new(id, + spftree->area->oldmetric + ? VTYPE_NONPSEUDO_IS + : VTYPE_NONPSEUDO_TE_IS); + listnode_add(spftree->paths, vertex); #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: added this IS %s %s depth %d dist %d to PATHS", - vtype2string (vertex->type), vid2string (vertex, buff, sizeof (buff)), - vertex->depth, vertex->d_N); + zlog_debug("ISIS-Spf: added this IS %s %s depth %d dist %d to PATHS", + vtype2string(vertex->type), + vid2string(vertex, buff, sizeof(buff)), vertex->depth, + vertex->d_N); #endif /* EXTREME_DEBUG */ - return vertex; + return vertex; } -static struct isis_vertex * -isis_find_vertex (struct list *list, void *id, enum vertextype vtype) +static struct isis_vertex *isis_find_vertex(struct list *list, void *id, + enum vertextype vtype) { - struct listnode *node; - struct isis_vertex *vertex; - struct prefix *p1, *p2; - - for (ALL_LIST_ELEMENTS_RO (list, node, vertex)) - { - if (vertex->type != vtype) - continue; - if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) - { - if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN + 1) == 0) - return vertex; - } - if (VTYPE_IP(vertex->type)) - { - p1 = (struct prefix *) id; - p2 = (struct prefix *) &vertex->N.id; - if (p1->family == p2->family - && p1->prefixlen == p2->prefixlen - && !memcmp(&p1->u.prefix, &p2->u.prefix, PSIZE (p1->prefixlen))) - { - return vertex; - } - } - } - - return NULL; + struct listnode *node; + struct isis_vertex *vertex; + struct prefix *p1, *p2; + + for (ALL_LIST_ELEMENTS_RO(list, node, vertex)) { + if (vertex->type != vtype) + continue; + if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) { + if (memcmp((u_char *)id, vertex->N.id, + ISIS_SYS_ID_LEN + 1) + == 0) + return vertex; + } + if (VTYPE_IP(vertex->type)) { + p1 = (struct prefix *)id; + p2 = (struct prefix *)&vertex->N.id; + if (p1->family == p2->family + && p1->prefixlen == p2->prefixlen + && !memcmp(&p1->u.prefix, &p2->u.prefix, + PSIZE(p1->prefixlen))) { + return vertex; + } + } + } + + return NULL; } /* * Compares vertizes for sorting in the TENT list. Returns true * if candidate should be considered before current, false otherwise. */ -static bool -tent_cmp (struct isis_vertex *current, struct isis_vertex *candidate) +static bool tent_cmp(struct isis_vertex *current, struct isis_vertex *candidate) { - if (current->d_N > candidate->d_N) - return true; + if (current->d_N > candidate->d_N) + return true; - if (current->d_N == candidate->d_N - && current->type > candidate->type) - return true; + if (current->d_N == candidate->d_N && current->type > candidate->type) + return true; - return false; + return false; } /* * Add a vertex to TENT sorted by cost and by vertextype on tie break situation */ -static struct isis_vertex * -isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype, - void *id, uint32_t cost, int depth, - struct isis_adjacency *adj, struct isis_vertex *parent) +static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, + enum vertextype vtype, void *id, + uint32_t cost, int depth, + struct isis_adjacency *adj, + struct isis_vertex *parent) { - struct isis_vertex *vertex, *v; - struct listnode *node; - struct isis_adjacency *parent_adj; + struct isis_vertex *vertex, *v; + struct listnode *node; + struct isis_adjacency *parent_adj; #ifdef EXTREME_DEBUG - char buff[PREFIX2STR_BUFFER]; + char buff[PREFIX2STR_BUFFER]; #endif - assert (isis_find_vertex (spftree->paths, id, vtype) == NULL); - assert (isis_find_vertex (spftree->tents, id, vtype) == NULL); - vertex = isis_vertex_new (id, vtype); - vertex->d_N = cost; - vertex->depth = depth; - - if (parent) { - listnode_add (vertex->parents, parent); - if (listnode_lookup (parent->children, vertex) == NULL) - listnode_add (parent->children, vertex); - } - - if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) { - for (ALL_LIST_ELEMENTS_RO (parent->Adj_N, node, parent_adj)) - listnode_add (vertex->Adj_N, parent_adj); - } else if (adj) { - listnode_add (vertex->Adj_N, adj); - } + assert(isis_find_vertex(spftree->paths, id, vtype) == NULL); + assert(isis_find_vertex(spftree->tents, id, vtype) == NULL); + vertex = isis_vertex_new(id, vtype); + vertex->d_N = cost; + vertex->depth = depth; + + if (parent) { + listnode_add(vertex->parents, parent); + if (listnode_lookup(parent->children, vertex) == NULL) + listnode_add(parent->children, vertex); + } + + if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) { + for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_adj)) + listnode_add(vertex->Adj_N, parent_adj); + } else if (adj) { + listnode_add(vertex->Adj_N, adj); + } #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d", - print_sys_hostname (vertex->N.id), - vtype2string (vertex->type), vid2string (vertex, buff, sizeof (buff)), - vertex->depth, vertex->d_N, listcount(vertex->Adj_N)); + zlog_debug( + "ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d", + print_sys_hostname(vertex->N.id), vtype2string(vertex->type), + vid2string(vertex, buff, sizeof(buff)), vertex->depth, + vertex->d_N, listcount(vertex->Adj_N)); #endif /* EXTREME_DEBUG */ - if (list_isempty (spftree->tents)) - { - listnode_add (spftree->tents, vertex); - return vertex; - } - - /* XXX: This cant use the standard ALL_LIST_ELEMENTS macro */ - for (node = listhead (spftree->tents); node; node = listnextnode (node)) - { - v = listgetdata (node); - if (tent_cmp(v, vertex)) - { - listnode_add_before (spftree->tents, node, vertex); - break; - } - } - - if (node == NULL) - listnode_add (spftree->tents, vertex); - - return vertex; -} + if (list_isempty(spftree->tents)) { + listnode_add(spftree->tents, vertex); + return vertex; + } -static void -isis_spf_add_local (struct isis_spftree *spftree, enum vertextype vtype, - void *id, struct isis_adjacency *adj, uint32_t cost, - struct isis_vertex *parent) -{ - struct isis_vertex *vertex; + /* XXX: This cant use the standard ALL_LIST_ELEMENTS macro */ + for (node = listhead(spftree->tents); node; node = listnextnode(node)) { + v = listgetdata(node); + if (tent_cmp(v, vertex)) { + listnode_add_before(spftree->tents, node, vertex); + break; + } + } - vertex = isis_find_vertex (spftree->tents, id, vtype); + if (node == NULL) + listnode_add(spftree->tents, vertex); - if (vertex) - { - /* C.2.5 c) */ - if (vertex->d_N == cost) - { - if (adj) - listnode_add (vertex->Adj_N, adj); - /* d) */ - if (listcount (vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) - remove_excess_adjs (vertex->Adj_N); - if (parent && (listnode_lookup (vertex->parents, parent) == NULL)) - listnode_add (vertex->parents, parent); - if (parent && (listnode_lookup (parent->children, vertex) == NULL)) - listnode_add (parent->children, vertex); - return; - } - else if (vertex->d_N < cost) - { - /* e) do nothing */ - return; + return vertex; +} + +static void isis_spf_add_local(struct isis_spftree *spftree, + enum vertextype vtype, void *id, + struct isis_adjacency *adj, uint32_t cost, + struct isis_vertex *parent) +{ + struct isis_vertex *vertex; + + vertex = isis_find_vertex(spftree->tents, id, vtype); + + if (vertex) { + /* C.2.5 c) */ + if (vertex->d_N == cost) { + if (adj) + listnode_add(vertex->Adj_N, adj); + /* d) */ + if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) + remove_excess_adjs(vertex->Adj_N); + if (parent && (listnode_lookup(vertex->parents, parent) + == NULL)) + listnode_add(vertex->parents, parent); + if (parent && (listnode_lookup(parent->children, vertex) + == NULL)) + listnode_add(parent->children, vertex); + return; + } else if (vertex->d_N < cost) { + /* e) do nothing */ + return; + } else { /* vertex->d_N > cost */ + /* f) */ + struct listnode *pnode, *pnextnode; + struct isis_vertex *pvertex; + listnode_delete(spftree->tents, vertex); + assert(listcount(vertex->children) == 0); + for (ALL_LIST_ELEMENTS(vertex->parents, pnode, + pnextnode, pvertex)) + listnode_delete(pvertex->children, vertex); + isis_vertex_del(vertex); + } } - else { /* vertex->d_N > cost */ - /* f) */ - struct listnode *pnode, *pnextnode; - struct isis_vertex *pvertex; - listnode_delete (spftree->tents, vertex); - assert (listcount (vertex->children) == 0); - for (ALL_LIST_ELEMENTS (vertex->parents, pnode, pnextnode, pvertex)) - listnode_delete(pvertex->children, vertex); - isis_vertex_del (vertex); - } - } - - isis_spf_add2tent (spftree, vtype, id, cost, 1, adj, parent); - return; + + isis_spf_add2tent(spftree, vtype, id, cost, 1, adj, parent); + return; } -static void -process_N (struct isis_spftree *spftree, enum vertextype vtype, void *id, - uint32_t dist, uint16_t depth, - struct isis_vertex *parent) +static void process_N(struct isis_spftree *spftree, enum vertextype vtype, + void *id, uint32_t dist, uint16_t depth, + struct isis_vertex *parent) { - struct isis_vertex *vertex; + struct isis_vertex *vertex; #ifdef EXTREME_DEBUG - char buff[PREFIX2STR_BUFFER]; + char buff[PREFIX2STR_BUFFER]; #endif - assert (spftree && parent); - - /* RFC3787 section 5.1 */ - if (spftree->area->newmetric == 1) - { - if (dist > MAX_WIDE_PATH_METRIC) - return; - } - /* C.2.6 b) */ - else if (spftree->area->oldmetric == 1) - { - if (dist > MAX_NARROW_PATH_METRIC) - return; - } - - /* c) */ - vertex = isis_find_vertex (spftree->paths, id, vtype); - if (vertex) - { + assert(spftree && parent); + + /* RFC3787 section 5.1 */ + if (spftree->area->newmetric == 1) { + if (dist > MAX_WIDE_PATH_METRIC) + return; + } + /* C.2.6 b) */ + else if (spftree->area->oldmetric == 1) { + if (dist > MAX_NARROW_PATH_METRIC) + return; + } + + /* c) */ + vertex = isis_find_vertex(spftree->paths, id, vtype); + if (vertex) { #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: process_N %s %s %s dist %d already found from PATH", - print_sys_hostname (vertex->N.id), - vtype2string (vtype), vid2string (vertex, buff, sizeof (buff)), dist); + zlog_debug( + "ISIS-Spf: process_N %s %s %s dist %d already found from PATH", + print_sys_hostname(vertex->N.id), vtype2string(vtype), + vid2string(vertex, buff, sizeof(buff)), dist); #endif /* EXTREME_DEBUG */ - assert (dist >= vertex->d_N); - return; - } - - vertex = isis_find_vertex (spftree->tents, id, vtype); - /* d) */ - if (vertex) - { - /* 1) */ + assert(dist >= vertex->d_N); + return; + } + + vertex = isis_find_vertex(spftree->tents, id, vtype); + /* d) */ + if (vertex) { +/* 1) */ #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: process_N %s %s %s dist %d parent %s adjcount %d", - print_sys_hostname (vertex->N.id), - vtype2string (vtype), vid2string (vertex, buff, sizeof (buff)), dist, - (parent ? print_sys_hostname (parent->N.id) : "null"), - (parent ? listcount (parent->Adj_N) : 0)); + zlog_debug( + "ISIS-Spf: process_N %s %s %s dist %d parent %s adjcount %d", + print_sys_hostname(vertex->N.id), vtype2string(vtype), + vid2string(vertex, buff, sizeof(buff)), dist, + (parent ? print_sys_hostname(parent->N.id) : "null"), + (parent ? listcount(parent->Adj_N) : 0)); #endif /* EXTREME_DEBUG */ - if (vertex->d_N == dist) - { - struct listnode *node; - struct isis_adjacency *parent_adj; - for (ALL_LIST_ELEMENTS_RO (parent->Adj_N, node, parent_adj)) - if (listnode_lookup(vertex->Adj_N, parent_adj) == NULL) - listnode_add (vertex->Adj_N, parent_adj); - /* 2) */ - if (listcount (vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) - remove_excess_adjs (vertex->Adj_N); - if (listnode_lookup (vertex->parents, parent) == NULL) - listnode_add (vertex->parents, parent); - if (listnode_lookup (parent->children, vertex) == NULL) - listnode_add (parent->children, vertex); - /* 3) */ - return; - } - else if (vertex->d_N < dist) - { - return; - /* 4) */ - } - else - { - struct listnode *pnode, *pnextnode; - struct isis_vertex *pvertex; - listnode_delete (spftree->tents, vertex); - assert (listcount (vertex->children) == 0); - for (ALL_LIST_ELEMENTS (vertex->parents, pnode, pnextnode, pvertex)) - listnode_delete(pvertex->children, vertex); - isis_vertex_del (vertex); + if (vertex->d_N == dist) { + struct listnode *node; + struct isis_adjacency *parent_adj; + for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, + parent_adj)) + if (listnode_lookup(vertex->Adj_N, parent_adj) + == NULL) + listnode_add(vertex->Adj_N, parent_adj); + /* 2) */ + if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) + remove_excess_adjs(vertex->Adj_N); + if (listnode_lookup(vertex->parents, parent) == NULL) + listnode_add(vertex->parents, parent); + if (listnode_lookup(parent->children, vertex) == NULL) + listnode_add(parent->children, vertex); + /* 3) */ + return; + } else if (vertex->d_N < dist) { + return; + /* 4) */ + } else { + struct listnode *pnode, *pnextnode; + struct isis_vertex *pvertex; + listnode_delete(spftree->tents, vertex); + assert(listcount(vertex->children) == 0); + for (ALL_LIST_ELEMENTS(vertex->parents, pnode, + pnextnode, pvertex)) + listnode_delete(pvertex->children, vertex); + isis_vertex_del(vertex); + } } - } #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: process_N add2tent %s %s dist %d parent %s", - print_sys_hostname(id), vtype2string (vtype), dist, - (parent ? print_sys_hostname (parent->N.id) : "null")); + zlog_debug("ISIS-Spf: process_N add2tent %s %s dist %d parent %s", + print_sys_hostname(id), vtype2string(vtype), dist, + (parent ? print_sys_hostname(parent->N.id) : "null")); #endif /* EXTREME_DEBUG */ - isis_spf_add2tent (spftree, vtype, id, dist, depth, NULL, parent); - return; + isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, parent); + return; } /* * C.2.6 Step 1 */ -static int -isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp, - uint32_t cost, uint16_t depth, - u_char *root_sysid, struct isis_vertex *parent) +static int isis_spf_process_lsp(struct isis_spftree *spftree, + struct isis_lsp *lsp, uint32_t cost, + uint16_t depth, u_char *root_sysid, + struct isis_vertex *parent) { - bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id); - struct listnode *node, *fragnode = NULL; - uint32_t dist; - struct is_neigh *is_neigh; - struct te_is_neigh *te_is_neigh; - struct ipv4_reachability *ipreach; - struct te_ipv4_reachability *te_ipv4_reach; - enum vertextype vtype; - struct prefix prefix; - struct ipv6_reachability *ip6reach; - static const u_char null_sysid[ISIS_SYS_ID_LEN]; - struct mt_router_info *mt_router_info = NULL; - - if (spftree->mtid != ISIS_MT_IPV4_UNICAST) - mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data, spftree->mtid); - - if (!pseudo_lsp - && (spftree->mtid == ISIS_MT_IPV4_UNICAST && !speaks(lsp->tlv_data.nlpids, spftree->family)) - && !mt_router_info) - return ISIS_OK; + bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id); + struct listnode *node, *fragnode = NULL; + uint32_t dist; + struct is_neigh *is_neigh; + struct te_is_neigh *te_is_neigh; + struct ipv4_reachability *ipreach; + struct te_ipv4_reachability *te_ipv4_reach; + enum vertextype vtype; + struct prefix prefix; + struct ipv6_reachability *ip6reach; + static const u_char null_sysid[ISIS_SYS_ID_LEN]; + struct mt_router_info *mt_router_info = NULL; + + if (spftree->mtid != ISIS_MT_IPV4_UNICAST) + mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data, + spftree->mtid); + + if (!pseudo_lsp && (spftree->mtid == ISIS_MT_IPV4_UNICAST + && !speaks(lsp->tlv_data.nlpids, spftree->family)) + && !mt_router_info) + return ISIS_OK; lspfragloop: - if (lsp->lsp_header->seq_num == 0) - { - zlog_warn ("isis_spf_process_lsp(): lsp with 0 seq_num - ignore"); - return ISIS_WARNING; - } + if (lsp->lsp_header->seq_num == 0) { + zlog_warn( + "isis_spf_process_lsp(): lsp with 0 seq_num - ignore"); + return ISIS_WARNING; + } #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: process_lsp %s", print_sys_hostname(lsp->lsp_header->lsp_id)); + zlog_debug("ISIS-Spf: process_lsp %s", + print_sys_hostname(lsp->lsp_header->lsp_id)); #endif /* EXTREME_DEBUG */ - /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */ - if (pseudo_lsp - || (spftree->mtid == ISIS_MT_IPV4_UNICAST && !ISIS_MASK_LSP_OL_BIT (lsp->lsp_header->lsp_bits)) - || (mt_router_info && !mt_router_info->overload)) - - { - if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) - { - for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.is_neighs, node, is_neigh)) - { - /* C.2.6 a) */ - /* Two way connectivity */ - if (!memcmp (is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN)) - continue; - if (!pseudo_lsp && !memcmp (is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN)) - continue; - dist = cost + is_neigh->metrics.metric_default; - process_N (spftree, LSP_PSEUDO_ID(is_neigh->neigh_id) ? VTYPE_PSEUDO_IS - : VTYPE_NONPSEUDO_IS, - (void *) is_neigh->neigh_id, dist, depth + 1, parent); - } - } - - struct list *te_is_neighs = NULL; - if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) - { - te_is_neighs = lsp->tlv_data.te_is_neighs; - } - else - { - struct tlv_mt_neighbors *mt_neighbors; - mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data, spftree->mtid); - if (mt_neighbors) - te_is_neighs = mt_neighbors->list; - } - for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh)) - { - if (!memcmp (te_is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN)) - continue; - if (!pseudo_lsp && !memcmp (te_is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN)) - continue; - dist = cost + GET_TE_METRIC(te_is_neigh); - process_N (spftree, LSP_PSEUDO_ID(te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS - : VTYPE_NONPSEUDO_TE_IS, - (void *) te_is_neigh->neigh_id, dist, depth + 1, parent); - } - } - - if (!pseudo_lsp - && spftree->family == AF_INET - && spftree->mtid == ISIS_MT_IPV4_UNICAST) - { - struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs, - lsp->tlv_data.ipv4_ext_reachs}; - - prefix.family = AF_INET; - for (unsigned int i = 0; i < array_size(reachs); i++) - { - vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs) ? VTYPE_IPREACH_INTERNAL - : VTYPE_IPREACH_EXTERNAL; - for (ALL_LIST_ELEMENTS_RO (reachs[i], node, ipreach)) - { - dist = cost + ipreach->metrics.metric_default; - prefix.u.prefix4 = ipreach->prefix; - prefix.prefixlen = ip_masklen (ipreach->mask); - apply_mask (&prefix); - process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - parent); - } - } - } - - if (!pseudo_lsp && spftree->family == AF_INET) - { - struct list *ipv4reachs = NULL; - - if (spftree->mtid == ISIS_MT_IPV4_UNICAST) - { - ipv4reachs = lsp->tlv_data.te_ipv4_reachs; - } - else - { - struct tlv_mt_ipv4_reachs *mt_reachs; - mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data, spftree->mtid); - if (mt_reachs) - ipv4reachs = mt_reachs->list; - } - - prefix.family = AF_INET; - for (ALL_LIST_ELEMENTS_RO (ipv4reachs, node, te_ipv4_reach)) - { - assert ((te_ipv4_reach->control & 0x3F) <= IPV4_MAX_BITLEN); - - dist = cost + ntohl (te_ipv4_reach->te_metric); - prefix.u.prefix4 = newprefix2inaddr (&te_ipv4_reach->prefix_start, - te_ipv4_reach->control); - prefix.prefixlen = (te_ipv4_reach->control & 0x3F); - apply_mask (&prefix); - process_N (spftree, VTYPE_IPREACH_TE, (void *) &prefix, dist, depth + 1, - parent); - } - } - - if (!pseudo_lsp - && spftree->family == AF_INET6) - { - struct list *ipv6reachs = NULL; - - if (spftree->mtid == ISIS_MT_IPV4_UNICAST) - { - ipv6reachs = lsp->tlv_data.ipv6_reachs; - } - else - { - struct tlv_mt_ipv6_reachs *mt_reachs; - mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data, spftree->mtid); - if (mt_reachs) - ipv6reachs = mt_reachs->list; - } - - prefix.family = AF_INET6; - for (ALL_LIST_ELEMENTS_RO (ipv6reachs, node, ip6reach)) - { - assert (ip6reach->prefix_len <= IPV6_MAX_BITLEN); - - dist = cost + ntohl(ip6reach->metric); - vtype = (ip6reach->control_info & CTRL_INFO_DISTRIBUTION) ? - VTYPE_IP6REACH_EXTERNAL : VTYPE_IP6REACH_INTERNAL; - prefix.prefixlen = ip6reach->prefix_len; - memcpy (&prefix.u.prefix6.s6_addr, ip6reach->prefix, - PSIZE (ip6reach->prefix_len)); - apply_mask (&prefix); - process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - parent); - } - } - - if (fragnode == NULL) - fragnode = listhead (lsp->lspu.frags); - else - fragnode = listnextnode (fragnode); - - if (fragnode) - { - lsp = listgetdata (fragnode); - goto lspfragloop; - } - - return ISIS_OK; -} + /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */ + if (pseudo_lsp || (spftree->mtid == ISIS_MT_IPV4_UNICAST + && !ISIS_MASK_LSP_OL_BIT(lsp->lsp_header->lsp_bits)) + || (mt_router_info && !mt_router_info->overload)) -static int -isis_spf_preload_tent (struct isis_spftree *spftree, - u_char *root_sysid, - struct isis_vertex *parent) -{ - struct isis_circuit *circuit; - struct listnode *cnode, *anode, *ipnode; - struct isis_adjacency *adj; - struct isis_lsp *lsp; - struct list *adj_list; - struct list *adjdb; - struct prefix_ipv4 *ipv4; - struct prefix prefix; - int retval = ISIS_OK; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - static u_char null_lsp_id[ISIS_SYS_ID_LEN + 2]; - struct prefix_ipv6 *ipv6; - struct isis_circuit_mt_setting *circuit_mt; - - for (ALL_LIST_ELEMENTS_RO (spftree->area->circuit_list, cnode, circuit)) - { - circuit_mt = circuit_lookup_mt_setting(circuit, spftree->mtid); - if (circuit_mt && !circuit_mt->enabled) - continue; - if (circuit->state != C_STATE_UP) - continue; - if (!(circuit->is_type & spftree->level)) - continue; - if (spftree->family == AF_INET && !circuit->ip_router) - continue; - if (spftree->family == AF_INET6 && !circuit->ipv6_router) - continue; - /* - * Add IP(v6) addresses of this circuit - */ - if (spftree->family == AF_INET) { - prefix.family = AF_INET; - for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, ipnode, ipv4)) - { - prefix.u.prefix4 = ipv4->prefix; - prefix.prefixlen = ipv4->prefixlen; - apply_mask (&prefix); - isis_spf_add_local (spftree, VTYPE_IPREACH_INTERNAL, &prefix, - NULL, 0, parent); - } + if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { + for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, node, + is_neigh)) { + /* C.2.6 a) */ + /* Two way connectivity */ + if (!memcmp(is_neigh->neigh_id, root_sysid, + ISIS_SYS_ID_LEN)) + continue; + if (!pseudo_lsp + && !memcmp(is_neigh->neigh_id, null_sysid, + ISIS_SYS_ID_LEN)) + continue; + dist = cost + is_neigh->metrics.metric_default; + process_N(spftree, + LSP_PSEUDO_ID(is_neigh->neigh_id) + ? VTYPE_PSEUDO_IS + : VTYPE_NONPSEUDO_IS, + (void *)is_neigh->neigh_id, dist, + depth + 1, parent); + } + } + + struct list *te_is_neighs = NULL; + if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { + te_is_neighs = lsp->tlv_data.te_is_neighs; + } else { + struct tlv_mt_neighbors *mt_neighbors; + mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data, + spftree->mtid); + if (mt_neighbors) + te_is_neighs = mt_neighbors->list; + } + for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) { + if (!memcmp(te_is_neigh->neigh_id, root_sysid, + ISIS_SYS_ID_LEN)) + continue; + if (!pseudo_lsp + && !memcmp(te_is_neigh->neigh_id, null_sysid, + ISIS_SYS_ID_LEN)) + continue; + dist = cost + GET_TE_METRIC(te_is_neigh); + process_N(spftree, + LSP_PSEUDO_ID(te_is_neigh->neigh_id) + ? VTYPE_PSEUDO_TE_IS + : VTYPE_NONPSEUDO_TE_IS, + (void *)te_is_neigh->neigh_id, dist, + depth + 1, parent); + } } - if (spftree->family == AF_INET6) - { - prefix.family = AF_INET6; - for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, ipnode, ipv6)) - { - prefix.prefixlen = ipv6->prefixlen; - prefix.u.prefix6 = ipv6->prefix; - apply_mask (&prefix); - isis_spf_add_local (spftree, VTYPE_IP6REACH_INTERNAL, - &prefix, NULL, 0, parent); - } + + if (!pseudo_lsp && spftree->family == AF_INET + && spftree->mtid == ISIS_MT_IPV4_UNICAST) { + struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs, + lsp->tlv_data.ipv4_ext_reachs}; + + prefix.family = AF_INET; + for (unsigned int i = 0; i < array_size(reachs); i++) { + vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs) + ? VTYPE_IPREACH_INTERNAL + : VTYPE_IPREACH_EXTERNAL; + for (ALL_LIST_ELEMENTS_RO(reachs[i], node, ipreach)) { + dist = cost + ipreach->metrics.metric_default; + prefix.u.prefix4 = ipreach->prefix; + prefix.prefixlen = ip_masklen(ipreach->mask); + apply_mask(&prefix); + process_N(spftree, vtype, (void *)&prefix, dist, + depth + 1, parent); + } + } } - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - /* - * Add the adjacencies - */ - adj_list = list_new (); - adjdb = circuit->u.bc.adjdb[spftree->level - 1]; - isis_adj_build_up_list (adjdb, adj_list); - if (listcount (adj_list) == 0) - { - list_delete (adj_list); - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf: no L%d adjacencies on circuit %s", - spftree->level, circuit->interface->name); - continue; - } - for (ALL_LIST_ELEMENTS_RO (adj_list, anode, adj)) - { - if (!adj_has_mt(adj, spftree->mtid)) - continue; - if (spftree->mtid == ISIS_MT_IPV4_UNICAST && !speaks (&adj->nlpids, spftree->family)) - continue; - switch (adj->sys_type) - { - case ISIS_SYSTYPE_ES: - memcpy(lsp_id, adj->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = 0; - isis_spf_add_local (spftree, VTYPE_ES, lsp_id, adj, - circuit->te_metric[spftree->level - 1], - parent); - break; - case ISIS_SYSTYPE_IS: - case ISIS_SYSTYPE_L1_IS: - case ISIS_SYSTYPE_L2_IS: - memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = 0; - LSP_FRAGMENT (lsp_id) = 0; - isis_spf_add_local (spftree, - spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS - : VTYPE_NONPSEUDO_TE_IS, - lsp_id, adj, - circuit->te_metric[spftree->level - 1], - parent); - lsp = lsp_search (lsp_id, spftree->area->lspdb[spftree->level - 1]); - if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) - zlog_warn ("ISIS-Spf: No LSP %s found for IS adjacency " - "L%d on %s (ID %u)", - rawlspid_print (lsp_id), spftree->level, - circuit->interface->name, circuit->circuit_id); - break; - case ISIS_SYSTYPE_UNKNOWN: - default: - zlog_warn ("isis_spf_preload_tent unknow adj type"); + + if (!pseudo_lsp && spftree->family == AF_INET) { + struct list *ipv4reachs = NULL; + + if (spftree->mtid == ISIS_MT_IPV4_UNICAST) { + ipv4reachs = lsp->tlv_data.te_ipv4_reachs; + } else { + struct tlv_mt_ipv4_reachs *mt_reachs; + mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data, + spftree->mtid); + if (mt_reachs) + ipv4reachs = mt_reachs->list; + } + + prefix.family = AF_INET; + for (ALL_LIST_ELEMENTS_RO(ipv4reachs, node, te_ipv4_reach)) { + assert((te_ipv4_reach->control & 0x3F) + <= IPV4_MAX_BITLEN); + + dist = cost + ntohl(te_ipv4_reach->te_metric); + prefix.u.prefix4 = + newprefix2inaddr(&te_ipv4_reach->prefix_start, + te_ipv4_reach->control); + prefix.prefixlen = (te_ipv4_reach->control & 0x3F); + apply_mask(&prefix); + process_N(spftree, VTYPE_IPREACH_TE, (void *)&prefix, + dist, depth + 1, parent); } - } - list_delete (adj_list); - /* - * Add the pseudonode - */ - if (spftree->level == 1) - memcpy (lsp_id, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); - else - memcpy (lsp_id, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1); - /* can happen during DR reboot */ - if (memcmp (lsp_id, null_lsp_id, ISIS_SYS_ID_LEN + 1) == 0) - { - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf: No L%d DR on %s (ID %d)", - spftree->level, circuit->interface->name, circuit->circuit_id); - continue; - } - adj = isis_adj_lookup (lsp_id, adjdb); - /* if no adj, we are the dis or error */ - if (!adj && !circuit->u.bc.is_dr[spftree->level - 1]) - { - zlog_warn ("ISIS-Spf: No adjacency found from root " - "to L%d DR %s on %s (ID %d)", - spftree->level, rawlspid_print (lsp_id), - circuit->interface->name, circuit->circuit_id); - continue; - } - lsp = lsp_search (lsp_id, spftree->area->lspdb[spftree->level - 1]); - if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) - { - zlog_warn ("ISIS-Spf: No lsp (%p) found from root " - "to L%d DR %s on %s (ID %d)", - (void *)lsp, spftree->level, rawlspid_print (lsp_id), - circuit->interface->name, circuit->circuit_id); - continue; - } - isis_spf_process_lsp (spftree, lsp, - circuit->te_metric[spftree->level - 1], 0, - root_sysid, parent); } - else if (circuit->circ_type == CIRCUIT_T_P2P) - { - adj = circuit->u.p2p.neighbor; - if (!adj) - continue; - if (!adj_has_mt(adj, spftree->mtid)) - continue; - switch (adj->sys_type) - { - case ISIS_SYSTYPE_ES: - memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = 0; - isis_spf_add_local (spftree, VTYPE_ES, lsp_id, adj, - circuit->te_metric[spftree->level - 1], - parent); - break; - case ISIS_SYSTYPE_IS: - case ISIS_SYSTYPE_L1_IS: - case ISIS_SYSTYPE_L2_IS: - memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID (lsp_id) = 0; - LSP_FRAGMENT (lsp_id) = 0; - if (spftree->mtid != ISIS_MT_IPV4_UNICAST || speaks (&adj->nlpids, spftree->family)) - isis_spf_add_local (spftree, - spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS - : VTYPE_NONPSEUDO_TE_IS, - lsp_id, - adj, circuit->te_metric[spftree->level - 1], - parent); - break; - case ISIS_SYSTYPE_UNKNOWN: - default: - zlog_warn ("isis_spf_preload_tent unknown adj type"); - break; - } + + if (!pseudo_lsp && spftree->family == AF_INET6) { + struct list *ipv6reachs = NULL; + + if (spftree->mtid == ISIS_MT_IPV4_UNICAST) { + ipv6reachs = lsp->tlv_data.ipv6_reachs; + } else { + struct tlv_mt_ipv6_reachs *mt_reachs; + mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data, + spftree->mtid); + if (mt_reachs) + ipv6reachs = mt_reachs->list; + } + + prefix.family = AF_INET6; + for (ALL_LIST_ELEMENTS_RO(ipv6reachs, node, ip6reach)) { + assert(ip6reach->prefix_len <= IPV6_MAX_BITLEN); + + dist = cost + ntohl(ip6reach->metric); + vtype = (ip6reach->control_info + & CTRL_INFO_DISTRIBUTION) + ? VTYPE_IP6REACH_EXTERNAL + : VTYPE_IP6REACH_INTERNAL; + prefix.prefixlen = ip6reach->prefix_len; + memcpy(&prefix.u.prefix6.s6_addr, ip6reach->prefix, + PSIZE(ip6reach->prefix_len)); + apply_mask(&prefix); + process_N(spftree, vtype, (void *)&prefix, dist, + depth + 1, parent); + } } - else if (circuit->circ_type == CIRCUIT_T_LOOPBACK) - { - continue; - } - else - { - zlog_warn ("isis_spf_preload_tent unsupported media"); - retval = ISIS_WARNING; + + if (fragnode == NULL) + fragnode = listhead(lsp->lspu.frags); + else + fragnode = listnextnode(fragnode); + + if (fragnode) { + lsp = listgetdata(fragnode); + goto lspfragloop; + } + + return ISIS_OK; +} + +static int isis_spf_preload_tent(struct isis_spftree *spftree, + u_char *root_sysid, struct isis_vertex *parent) +{ + struct isis_circuit *circuit; + struct listnode *cnode, *anode, *ipnode; + struct isis_adjacency *adj; + struct isis_lsp *lsp; + struct list *adj_list; + struct list *adjdb; + struct prefix_ipv4 *ipv4; + struct prefix prefix; + int retval = ISIS_OK; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + static u_char null_lsp_id[ISIS_SYS_ID_LEN + 2]; + struct prefix_ipv6 *ipv6; + struct isis_circuit_mt_setting *circuit_mt; + + for (ALL_LIST_ELEMENTS_RO(spftree->area->circuit_list, cnode, + circuit)) { + circuit_mt = circuit_lookup_mt_setting(circuit, spftree->mtid); + if (circuit_mt && !circuit_mt->enabled) + continue; + if (circuit->state != C_STATE_UP) + continue; + if (!(circuit->is_type & spftree->level)) + continue; + if (spftree->family == AF_INET && !circuit->ip_router) + continue; + if (spftree->family == AF_INET6 && !circuit->ipv6_router) + continue; + /* + * Add IP(v6) addresses of this circuit + */ + if (spftree->family == AF_INET) { + prefix.family = AF_INET; + for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode, + ipv4)) { + prefix.u.prefix4 = ipv4->prefix; + prefix.prefixlen = ipv4->prefixlen; + apply_mask(&prefix); + isis_spf_add_local(spftree, + VTYPE_IPREACH_INTERNAL, + &prefix, NULL, 0, parent); + } + } + if (spftree->family == AF_INET6) { + prefix.family = AF_INET6; + for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, + ipnode, ipv6)) { + prefix.prefixlen = ipv6->prefixlen; + prefix.u.prefix6 = ipv6->prefix; + apply_mask(&prefix); + isis_spf_add_local(spftree, + VTYPE_IP6REACH_INTERNAL, + &prefix, NULL, 0, parent); + } + } + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + /* + * Add the adjacencies + */ + adj_list = list_new(); + adjdb = circuit->u.bc.adjdb[spftree->level - 1]; + isis_adj_build_up_list(adjdb, adj_list); + if (listcount(adj_list) == 0) { + list_delete(adj_list); + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-Spf: no L%d adjacencies on circuit %s", + spftree->level, + circuit->interface->name); + continue; + } + for (ALL_LIST_ELEMENTS_RO(adj_list, anode, adj)) { + if (!adj_has_mt(adj, spftree->mtid)) + continue; + if (spftree->mtid == ISIS_MT_IPV4_UNICAST + && !speaks(&adj->nlpids, spftree->family)) + continue; + switch (adj->sys_type) { + case ISIS_SYSTYPE_ES: + memcpy(lsp_id, adj->sysid, + ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = 0; + isis_spf_add_local( + spftree, VTYPE_ES, lsp_id, adj, + circuit->te_metric + [spftree->level - 1], + parent); + break; + case ISIS_SYSTYPE_IS: + case ISIS_SYSTYPE_L1_IS: + case ISIS_SYSTYPE_L2_IS: + memcpy(lsp_id, adj->sysid, + ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = 0; + LSP_FRAGMENT(lsp_id) = 0; + isis_spf_add_local( + spftree, + spftree->area->oldmetric + ? VTYPE_NONPSEUDO_IS + : VTYPE_NONPSEUDO_TE_IS, + lsp_id, adj, + circuit->te_metric + [spftree->level - 1], + parent); + lsp = lsp_search( + lsp_id, + spftree->area + ->lspdb[spftree->level + - 1]); + if (lsp == NULL + || lsp->lsp_header->rem_lifetime + == 0) + zlog_warn( + "ISIS-Spf: No LSP %s found for IS adjacency " + "L%d on %s (ID %u)", + rawlspid_print(lsp_id), + spftree->level, + circuit->interface->name, + circuit->circuit_id); + break; + case ISIS_SYSTYPE_UNKNOWN: + default: + zlog_warn( + "isis_spf_preload_tent unknow adj type"); + } + } + list_delete(adj_list); + /* + * Add the pseudonode + */ + if (spftree->level == 1) + memcpy(lsp_id, circuit->u.bc.l1_desig_is, + ISIS_SYS_ID_LEN + 1); + else + memcpy(lsp_id, circuit->u.bc.l2_desig_is, + ISIS_SYS_ID_LEN + 1); + /* can happen during DR reboot */ + if (memcmp(lsp_id, null_lsp_id, ISIS_SYS_ID_LEN + 1) + == 0) { + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-Spf: No L%d DR on %s (ID %d)", + spftree->level, + circuit->interface->name, + circuit->circuit_id); + continue; + } + adj = isis_adj_lookup(lsp_id, adjdb); + /* if no adj, we are the dis or error */ + if (!adj && !circuit->u.bc.is_dr[spftree->level - 1]) { + zlog_warn( + "ISIS-Spf: No adjacency found from root " + "to L%d DR %s on %s (ID %d)", + spftree->level, rawlspid_print(lsp_id), + circuit->interface->name, + circuit->circuit_id); + continue; + } + lsp = lsp_search( + lsp_id, + spftree->area->lspdb[spftree->level - 1]); + if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) { + zlog_warn( + "ISIS-Spf: No lsp (%p) found from root " + "to L%d DR %s on %s (ID %d)", + (void *)lsp, spftree->level, + rawlspid_print(lsp_id), + circuit->interface->name, + circuit->circuit_id); + continue; + } + isis_spf_process_lsp( + spftree, lsp, + circuit->te_metric[spftree->level - 1], 0, + root_sysid, parent); + } else if (circuit->circ_type == CIRCUIT_T_P2P) { + adj = circuit->u.p2p.neighbor; + if (!adj) + continue; + if (!adj_has_mt(adj, spftree->mtid)) + continue; + switch (adj->sys_type) { + case ISIS_SYSTYPE_ES: + memcpy(lsp_id, adj->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = 0; + isis_spf_add_local( + spftree, VTYPE_ES, lsp_id, adj, + circuit->te_metric[spftree->level - 1], + parent); + break; + case ISIS_SYSTYPE_IS: + case ISIS_SYSTYPE_L1_IS: + case ISIS_SYSTYPE_L2_IS: + memcpy(lsp_id, adj->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(lsp_id) = 0; + LSP_FRAGMENT(lsp_id) = 0; + if (spftree->mtid != ISIS_MT_IPV4_UNICAST + || speaks(&adj->nlpids, spftree->family)) + isis_spf_add_local( + spftree, + spftree->area->oldmetric + ? VTYPE_NONPSEUDO_IS + : VTYPE_NONPSEUDO_TE_IS, + lsp_id, adj, + circuit->te_metric + [spftree->level - 1], + parent); + break; + case ISIS_SYSTYPE_UNKNOWN: + default: + zlog_warn( + "isis_spf_preload_tent unknown adj type"); + break; + } + } else if (circuit->circ_type == CIRCUIT_T_LOOPBACK) { + continue; + } else { + zlog_warn("isis_spf_preload_tent unsupported media"); + retval = ISIS_WARNING; + } } - } - return retval; + return retval; } /* * The parent(s) for vertex is set when added to TENT list * now we just put the child pointer(s) in place */ -static void -add_to_paths (struct isis_spftree *spftree, struct isis_vertex *vertex) +static void add_to_paths(struct isis_spftree *spftree, + struct isis_vertex *vertex) { - char buff[PREFIX2STR_BUFFER]; + char buff[PREFIX2STR_BUFFER]; - if (isis_find_vertex (spftree->paths, vertex->N.id, vertex->type)) - return; - listnode_add (spftree->paths, vertex); + if (isis_find_vertex(spftree->paths, vertex->N.id, vertex->type)) + return; + listnode_add(spftree->paths, vertex); #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: added %s %s %s depth %d dist %d to PATHS", - print_sys_hostname (vertex->N.id), - vtype2string (vertex->type), vid2string (vertex, buff, sizeof (buff)), - vertex->depth, vertex->d_N); + zlog_debug("ISIS-Spf: added %s %s %s depth %d dist %d to PATHS", + print_sys_hostname(vertex->N.id), vtype2string(vertex->type), + vid2string(vertex, buff, sizeof(buff)), vertex->depth, + vertex->d_N); #endif /* EXTREME_DEBUG */ - if (VTYPE_IP(vertex->type)) - { - if (listcount (vertex->Adj_N) > 0) - isis_route_create ((struct prefix *) &vertex->N.prefix, vertex->d_N, - vertex->depth, vertex->Adj_N, spftree->area, spftree->level); - else if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf: no adjacencies do not install route for " - "%s depth %d dist %d", vid2string (vertex, buff, sizeof (buff)), - vertex->depth, vertex->d_N); - } - - return; + if (VTYPE_IP(vertex->type)) { + if (listcount(vertex->Adj_N) > 0) + isis_route_create((struct prefix *)&vertex->N.prefix, + vertex->d_N, vertex->depth, + vertex->Adj_N, spftree->area, + spftree->level); + else if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-Spf: no adjacencies do not install route for " + "%s depth %d dist %d", + vid2string(vertex, buff, sizeof(buff)), + vertex->depth, vertex->d_N); + } + + return; } -static void -init_spt (struct isis_spftree *spftree, int mtid, int level, int family) +static void init_spt(struct isis_spftree *spftree, int mtid, int level, + int family) { - spftree->tents->del = spftree->paths->del = (void (*)(void *)) isis_vertex_del; - list_delete_all_node (spftree->tents); - list_delete_all_node (spftree->paths); - spftree->tents->del = spftree->paths->del = NULL; - - spftree->mtid = mtid; - spftree->level = level; - spftree->family = family; - return; + spftree->tents->del = spftree->paths->del = + (void (*)(void *))isis_vertex_del; + list_delete_all_node(spftree->tents); + list_delete_all_node(spftree->paths); + spftree->tents->del = spftree->paths->del = NULL; + + spftree->mtid = mtid; + spftree->level = level; + spftree->family = family; + return; } -static int -isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid) +static int isis_run_spf(struct isis_area *area, int level, int family, + u_char *sysid) { - int retval = ISIS_OK; - struct listnode *node; - struct isis_vertex *vertex; - struct isis_vertex *root_vertex; - struct isis_spftree *spftree = NULL; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - struct isis_lsp *lsp; - struct route_table *table = NULL; - struct timeval time_now; - unsigned long long start_time, end_time; - uint16_t mtid; - - /* Get time that can't roll backwards. */ - monotime(&time_now); - start_time = time_now.tv_sec; - start_time = (start_time * 1000000) + time_now.tv_usec; - - if (family == AF_INET) - spftree = area->spftree[level - 1]; - else if (family == AF_INET6) - spftree = area->spftree6[level - 1]; - assert (spftree); - assert (sysid); - - /* Make all routes in current route table inactive. */ - if (family == AF_INET) - table = area->route_table[level - 1]; - else if (family == AF_INET6) - table = area->route_table6[level - 1]; - - isis_route_invalidate_table (area, table); - - /* We only support ipv4-unicast and ipv6-unicast as topologies for now */ - if (family == AF_INET6) - mtid = isis_area_ipv6_topology(area); - else - mtid = ISIS_MT_IPV4_UNICAST; - - /* - * C.2.5 Step 0 - */ - init_spt (spftree, mtid, level, family); - /* a) */ - root_vertex = isis_spf_add_root (spftree, sysid); - /* b) */ - retval = isis_spf_preload_tent (spftree, sysid, root_vertex); - if (retval != ISIS_OK) - { - zlog_warn ("ISIS-Spf: failed to load TENT SPF-root:%s", print_sys_hostname(sysid)); - goto out; - } - - /* - * C.2.7 Step 2 - */ - if (listcount (spftree->tents) == 0) - { - zlog_warn ("ISIS-Spf: TENT is empty SPF-root:%s", print_sys_hostname(sysid)); - goto out; - } - - while (listcount (spftree->tents) > 0) - { - node = listhead (spftree->tents); - vertex = listgetdata (node); + int retval = ISIS_OK; + struct listnode *node; + struct isis_vertex *vertex; + struct isis_vertex *root_vertex; + struct isis_spftree *spftree = NULL; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + struct isis_lsp *lsp; + struct route_table *table = NULL; + struct timeval time_now; + unsigned long long start_time, end_time; + uint16_t mtid; + + /* Get time that can't roll backwards. */ + monotime(&time_now); + start_time = time_now.tv_sec; + start_time = (start_time * 1000000) + time_now.tv_usec; + + if (family == AF_INET) + spftree = area->spftree[level - 1]; + else if (family == AF_INET6) + spftree = area->spftree6[level - 1]; + assert(spftree); + assert(sysid); + + /* Make all routes in current route table inactive. */ + if (family == AF_INET) + table = area->route_table[level - 1]; + else if (family == AF_INET6) + table = area->route_table6[level - 1]; + + isis_route_invalidate_table(area, table); + + /* We only support ipv4-unicast and ipv6-unicast as topologies for now + */ + if (family == AF_INET6) + mtid = isis_area_ipv6_topology(area); + else + mtid = ISIS_MT_IPV4_UNICAST; + + /* + * C.2.5 Step 0 + */ + init_spt(spftree, mtid, level, family); + /* a) */ + root_vertex = isis_spf_add_root(spftree, sysid); + /* b) */ + retval = isis_spf_preload_tent(spftree, sysid, root_vertex); + if (retval != ISIS_OK) { + zlog_warn("ISIS-Spf: failed to load TENT SPF-root:%s", + print_sys_hostname(sysid)); + goto out; + } + + /* + * C.2.7 Step 2 + */ + if (listcount(spftree->tents) == 0) { + zlog_warn("ISIS-Spf: TENT is empty SPF-root:%s", + print_sys_hostname(sysid)); + goto out; + } + + while (listcount(spftree->tents) > 0) { + node = listhead(spftree->tents); + vertex = listgetdata(node); #ifdef EXTREME_DEBUG - zlog_debug ("ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", - print_sys_hostname (vertex->N.id), - vtype2string (vertex->type), vertex->depth, vertex->d_N); + zlog_debug( + "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", + print_sys_hostname(vertex->N.id), + vtype2string(vertex->type), vertex->depth, vertex->d_N); #endif /* EXTREME_DEBUG */ - /* Remove from tent list and add to paths list */ - list_delete_node (spftree->tents, node); - add_to_paths (spftree, vertex); - if (VTYPE_IS(vertex->type)) - { - memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT (lsp_id) = 0; - lsp = lsp_search (lsp_id, area->lspdb[level - 1]); - if (lsp && lsp->lsp_header->rem_lifetime != 0) - { - isis_spf_process_lsp (spftree, lsp, vertex->d_N, - vertex->depth, sysid, vertex); - } - else - { - zlog_warn ("ISIS-Spf: No LSP found for %s", - rawlspid_print (lsp_id)); - } + /* Remove from tent list and add to paths list */ + list_delete_node(spftree->tents, node); + add_to_paths(spftree, vertex); + if (VTYPE_IS(vertex->type)) { + memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(lsp_id) = 0; + lsp = lsp_search(lsp_id, area->lspdb[level - 1]); + if (lsp && lsp->lsp_header->rem_lifetime != 0) { + isis_spf_process_lsp(spftree, lsp, vertex->d_N, + vertex->depth, sysid, + vertex); + } else { + zlog_warn("ISIS-Spf: No LSP found for %s", + rawlspid_print(lsp_id)); + } + } } - } out: - isis_route_validate (area); - spftree->runcount++; - spftree->last_run_timestamp = time (NULL); - monotime(&time_now); - end_time = time_now.tv_sec; - end_time = (end_time * 1000000) + time_now.tv_usec; - spftree->last_run_duration = end_time - start_time; - - return retval; + isis_route_validate(area); + spftree->runcount++; + spftree->last_run_timestamp = time(NULL); + monotime(&time_now); + end_time = time_now.tv_sec; + end_time = (end_time * 1000000) + time_now.tv_usec; + spftree->last_run_duration = end_time - start_time; + + return retval; } -static int -isis_run_spf_cb (struct thread *thread) +static int isis_run_spf_cb(struct thread *thread) { - struct isis_spf_run *run = THREAD_ARG (thread); - struct isis_area *area = run->area; - int level = run->level; - int retval = ISIS_OK; - - XFREE(MTYPE_ISIS_SPF_RUN, run); - area->spf_timer[level - 1] = NULL; - - if (!(area->is_type & level)) - { - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_warn ("ISIS-SPF (%s) area does not share level", - area->area_tag); - return ISIS_WARNING; - } - - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf (%s) L%d SPF needed, periodic SPF", - area->area_tag, level); - - if (area->ip_circuits) - retval = isis_run_spf (area, level, AF_INET, isis->sysid); - if (area->ipv6_circuits) - retval = isis_run_spf (area, level, AF_INET6, isis->sysid); - - return retval; -} + struct isis_spf_run *run = THREAD_ARG(thread); + struct isis_area *area = run->area; + int level = run->level; + int retval = ISIS_OK; + + XFREE(MTYPE_ISIS_SPF_RUN, run); + area->spf_timer[level - 1] = NULL; + + if (!(area->is_type & level)) { + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_warn("ISIS-SPF (%s) area does not share level", + area->area_tag); + return ISIS_WARNING; + } -static struct isis_spf_run* -isis_run_spf_arg(struct isis_area *area, int level) -{ - struct isis_spf_run *run = XMALLOC(MTYPE_ISIS_SPF_RUN, sizeof(*run)); + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug("ISIS-Spf (%s) L%d SPF needed, periodic SPF", + area->area_tag, level); - run->area = area; - run->level = level; + if (area->ip_circuits) + retval = isis_run_spf(area, level, AF_INET, isis->sysid); + if (area->ipv6_circuits) + retval = isis_run_spf(area, level, AF_INET6, isis->sysid); - return run; + return retval; } -int -isis_spf_schedule (struct isis_area *area, int level) +static struct isis_spf_run *isis_run_spf_arg(struct isis_area *area, int level) { - struct isis_spftree *spftree = area->spftree[level - 1]; - time_t now = time (NULL); - int diff = now - spftree->last_run_timestamp; - - assert (diff >= 0); - assert (area->is_type & level); - - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago", - area->area_tag, level, diff); - - if (area->spf_delay_ietf[level - 1]) - { - /* Need to call schedule function also if spf delay is running to - * restart holdoff timer - compare draft-ietf-rtgwg-backoff-algo-04 */ - long delay = spf_backoff_schedule(area->spf_delay_ietf[level -1]); - if (area->spf_timer[level - 1]) - return ISIS_OK; - - thread_add_timer_msec (master, isis_run_spf_cb, - isis_run_spf_arg(area, level), - delay, &area->spf_timer[level-1]); - return ISIS_OK; - } - - if (area->spf_timer[level -1]) - return ISIS_OK; - - /* wait configured min_spf_interval before doing the SPF */ - if (diff >= area->min_spf_interval[level-1]) - { - int retval = ISIS_OK; - - if (area->ip_circuits) - retval = isis_run_spf (area, level, AF_INET, isis->sysid); - if (area->ipv6_circuits) - retval = isis_run_spf (area, level, AF_INET6, isis->sysid); - - return retval; - } - - thread_add_timer (master, isis_run_spf_cb, isis_run_spf_arg(area, level), - area->min_spf_interval[level-1] - diff, - &area->spf_timer[level-1]); - - if (isis->debugs & DEBUG_SPF_EVENTS) - zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now", - area->area_tag, level, area->min_spf_interval[level-1] - diff); - - return ISIS_OK; + struct isis_spf_run *run = XMALLOC(MTYPE_ISIS_SPF_RUN, sizeof(*run)); + + run->area = area; + run->level = level; + + return run; } -static void -isis_print_paths (struct vty *vty, struct list *paths, u_char *root_sysid) +int isis_spf_schedule(struct isis_area *area, int level) { - struct listnode *node; - struct listnode *anode; - struct isis_vertex *vertex; - struct isis_adjacency *adj; - char buff[PREFIX2STR_BUFFER]; - - vty_out (vty, - "Vertex Type Metric Next-Hop Interface Parent\n"); - - for (ALL_LIST_ELEMENTS_RO (paths, node, vertex)) { - if (memcmp (vertex->N.id, root_sysid, ISIS_SYS_ID_LEN) == 0) { - vty_out (vty, "%-20s %-12s %-6s", print_sys_hostname (root_sysid), - "", ""); - vty_out (vty, "%-30s", ""); - } else { - int rows = 0; - vty_out (vty, "%-20s %-12s %-6u ", vid2string (vertex, buff, sizeof (buff)), - vtype2string (vertex->type), vertex->d_N); - for (ALL_LIST_ELEMENTS_RO (vertex->Adj_N, anode, adj)) { - if (adj) { - if (rows) { - vty_out (vty, "\n"); - vty_out (vty, "%-20s %-12s %-6s ", "", "", ""); - } - vty_out (vty, "%-20s %-9s ", - print_sys_hostname (adj->sysid), - adj->circuit->interface->name); - ++rows; - } + struct isis_spftree *spftree = area->spftree[level - 1]; + time_t now = time(NULL); + int diff = now - spftree->last_run_timestamp; + + assert(diff >= 0); + assert(area->is_type & level); + + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago", + area->area_tag, level, diff); + + if (area->spf_delay_ietf[level - 1]) { + /* Need to call schedule function also if spf delay is running + * to + * restart holdoff timer - compare + * draft-ietf-rtgwg-backoff-algo-04 */ + long delay = + spf_backoff_schedule(area->spf_delay_ietf[level - 1]); + if (area->spf_timer[level - 1]) + return ISIS_OK; + + thread_add_timer_msec(master, isis_run_spf_cb, + isis_run_spf_arg(area, level), delay, + &area->spf_timer[level - 1]); + return ISIS_OK; } - if (rows == 0) - vty_out (vty, "%-30s ", ""); - } - - /* Print list of parents for the ECMP DAG */ - if (listcount (vertex->parents) > 0) { - struct listnode *pnode; - struct isis_vertex *pvertex; - int rows = 0; - for (ALL_LIST_ELEMENTS_RO (vertex->parents, pnode, pvertex)) { - if (rows) { - vty_out (vty, "\n"); - vty_out (vty, "%-72s", ""); - } - vty_out (vty, "%s(%d)", - vid2string (pvertex, buff, sizeof (buff)), pvertex->type); - ++rows; + + if (area->spf_timer[level - 1]) + return ISIS_OK; + + /* wait configured min_spf_interval before doing the SPF */ + if (diff >= area->min_spf_interval[level - 1]) { + int retval = ISIS_OK; + + if (area->ip_circuits) + retval = + isis_run_spf(area, level, AF_INET, isis->sysid); + if (area->ipv6_circuits) + retval = isis_run_spf(area, level, AF_INET6, + isis->sysid); + + return retval; } - } else { - vty_out (vty, " NULL "); - } - vty_out (vty, "\n"); - } + thread_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level), + area->min_spf_interval[level - 1] - diff, + &area->spf_timer[level - 1]); + + if (isis->debugs & DEBUG_SPF_EVENTS) + zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %d sec from now", + area->area_tag, level, + area->min_spf_interval[level - 1] - diff); + + return ISIS_OK; +} + +static void isis_print_paths(struct vty *vty, struct list *paths, + u_char *root_sysid) +{ + struct listnode *node; + struct listnode *anode; + struct isis_vertex *vertex; + struct isis_adjacency *adj; + char buff[PREFIX2STR_BUFFER]; + + vty_out(vty, + "Vertex Type Metric Next-Hop Interface Parent\n"); + + for (ALL_LIST_ELEMENTS_RO(paths, node, vertex)) { + if (memcmp(vertex->N.id, root_sysid, ISIS_SYS_ID_LEN) == 0) { + vty_out(vty, "%-20s %-12s %-6s", + print_sys_hostname(root_sysid), "", ""); + vty_out(vty, "%-30s", ""); + } else { + int rows = 0; + vty_out(vty, "%-20s %-12s %-6u ", + vid2string(vertex, buff, sizeof(buff)), + vtype2string(vertex->type), vertex->d_N); + for (ALL_LIST_ELEMENTS_RO(vertex->Adj_N, anode, adj)) { + if (adj) { + if (rows) { + vty_out(vty, "\n"); + vty_out(vty, + "%-20s %-12s %-6s ", "", + "", ""); + } + vty_out(vty, "%-20s %-9s ", + print_sys_hostname(adj->sysid), + adj->circuit->interface->name); + ++rows; + } + } + if (rows == 0) + vty_out(vty, "%-30s ", ""); + } + + /* Print list of parents for the ECMP DAG */ + if (listcount(vertex->parents) > 0) { + struct listnode *pnode; + struct isis_vertex *pvertex; + int rows = 0; + for (ALL_LIST_ELEMENTS_RO(vertex->parents, pnode, + pvertex)) { + if (rows) { + vty_out(vty, "\n"); + vty_out(vty, "%-72s", ""); + } + vty_out(vty, "%s(%d)", + vid2string(pvertex, buff, sizeof(buff)), + pvertex->type); + ++rows; + } + } else { + vty_out(vty, " NULL "); + } + + vty_out(vty, "\n"); + } } DEFUN (show_isis_topology, @@ -1380,56 +1372,57 @@ DEFUN (show_isis_topology, "Paths to all level-1 routers in the area\n" "Paths to all level-2 routers in the domain\n") { - int levels; - struct listnode *node; - struct isis_area *area; - - if (argc < 4) - levels = ISIS_LEVEL1|ISIS_LEVEL2; - else if (strmatch(argv[3]->text, "level-1")) - levels = ISIS_LEVEL1; - else - levels = ISIS_LEVEL2; - - if (!isis->area_list || isis->area_list->count == 0) - return CMD_SUCCESS; - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - vty_out (vty, "Area %s:\n",area->area_tag ? area->area_tag : "null"); + int levels; + struct listnode *node; + struct isis_area *area; + + if (argc < 4) + levels = ISIS_LEVEL1 | ISIS_LEVEL2; + else if (strmatch(argv[3]->text, "level-1")) + levels = ISIS_LEVEL1; + else + levels = ISIS_LEVEL2; + + if (!isis->area_list || isis->area_list->count == 0) + return CMD_SUCCESS; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + vty_out(vty, "Area %s:\n", + area->area_tag ? area->area_tag : "null"); + + for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { + if ((level & levels) == 0) + continue; + + if (area->ip_circuits > 0 && area->spftree[level - 1] + && area->spftree[level - 1]->paths->count > 0) { + vty_out(vty, + "IS-IS paths to level-%d routers that speak IP\n", + level); + isis_print_paths( + vty, area->spftree[level - 1]->paths, + isis->sysid); + vty_out(vty, "\n"); + } + if (area->ipv6_circuits > 0 && area->spftree6[level - 1] + && area->spftree6[level - 1]->paths->count > 0) { + vty_out(vty, + "IS-IS paths to level-%d routers that speak IPv6\n", + level); + isis_print_paths( + vty, area->spftree6[level - 1]->paths, + isis->sysid); + vty_out(vty, "\n"); + } + } - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) - { - if ((level & levels) == 0) - continue; - - if (area->ip_circuits > 0 && area->spftree[level-1] - && area->spftree[level-1]->paths->count > 0) - { - vty_out (vty, "IS-IS paths to level-%d routers that speak IP\n", - level); - isis_print_paths (vty, area->spftree[level-1]->paths, isis->sysid); - vty_out (vty, "\n"); - } - if (area->ipv6_circuits > 0 && area->spftree6[level-1] - && area->spftree6[level-1]->paths->count > 0) - { - vty_out (vty, - "IS-IS paths to level-%d routers that speak IPv6\n", - level); - isis_print_paths (vty, area->spftree6[level-1]->paths, isis->sysid); - vty_out (vty, "\n"); - } + vty_out(vty, "\n"); } - vty_out (vty, "\n"); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } -void -isis_spf_cmds_init () +void isis_spf_cmds_init() { - install_element (VIEW_NODE, &show_isis_topology_cmd); + install_element(VIEW_NODE, &show_isis_topology_cmd); } diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index 8c72f45c5..c7a505489 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -1,19 +1,19 @@ /* * IS-IS Rout(e)ing protocol - isis_spf.h - * IS-IS Shortest Path First algorithm + * IS-IS Shortest Path First algorithm * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -24,18 +24,17 @@ #ifndef _ZEBRA_ISIS_SPF_H #define _ZEBRA_ISIS_SPF_H -enum vertextype -{ - VTYPE_PSEUDO_IS = 1, - VTYPE_PSEUDO_TE_IS, - VTYPE_NONPSEUDO_IS, - VTYPE_NONPSEUDO_TE_IS, - VTYPE_ES, - VTYPE_IPREACH_INTERNAL, - VTYPE_IPREACH_EXTERNAL, - VTYPE_IPREACH_TE, - VTYPE_IP6REACH_INTERNAL, - VTYPE_IP6REACH_EXTERNAL +enum vertextype { + VTYPE_PSEUDO_IS = 1, + VTYPE_PSEUDO_TE_IS, + VTYPE_NONPSEUDO_IS, + VTYPE_NONPSEUDO_TE_IS, + VTYPE_ES, + VTYPE_IPREACH_INTERNAL, + VTYPE_IPREACH_EXTERNAL, + VTYPE_IPREACH_TE, + VTYPE_IP6REACH_INTERNAL, + VTYPE_IP6REACH_EXTERNAL }; #define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS) @@ -43,45 +42,41 @@ enum vertextype #define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL) /* - * Triple <N, d(N), {Adj(N)}> + * Triple <N, d(N), {Adj(N)}> */ -struct isis_vertex -{ - enum vertextype type; +struct isis_vertex { + enum vertextype type; - union - { - u_char id[ISIS_SYS_ID_LEN + 1]; - struct prefix prefix; - } N; + union { + u_char id[ISIS_SYS_ID_LEN + 1]; + struct prefix prefix; + } N; - u_int32_t d_N; /* d(N) Distance from this IS */ - u_int16_t depth; /* The depth in the imaginary tree */ - struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ - struct list *parents; /* list of parents for ECMP */ - struct list *children; /* list of children used for tree dump */ + u_int32_t d_N; /* d(N) Distance from this IS */ + u_int16_t depth; /* The depth in the imaginary tree */ + struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ + struct list *parents; /* list of parents for ECMP */ + struct list *children; /* list of children used for tree dump */ }; -struct isis_spftree -{ - struct list *paths; /* the SPT */ - struct list *tents; /* TENT */ - struct isis_area *area; /* back pointer to area */ - unsigned int runcount; /* number of runs since uptime */ - time_t last_run_timestamp; /* last run timestamp for scheduling */ - time_t last_run_duration; /* last run duration in msec */ +struct isis_spftree { + struct list *paths; /* the SPT */ + struct list *tents; /* TENT */ + struct isis_area *area; /* back pointer to area */ + unsigned int runcount; /* number of runs since uptime */ + time_t last_run_timestamp; /* last run timestamp for scheduling */ + time_t last_run_duration; /* last run duration in msec */ - uint16_t mtid; - int family; - int level; + uint16_t mtid; + int family; + int level; }; -struct isis_spftree * isis_spftree_new (struct isis_area *area); -void isis_spftree_del (struct isis_spftree *spftree); -void spftree_area_init (struct isis_area *area); -void spftree_area_del (struct isis_area *area); -void spftree_area_adj_del (struct isis_area *area, - struct isis_adjacency *adj); -int isis_spf_schedule (struct isis_area *area, int level); -void isis_spf_cmds_init (void); +struct isis_spftree *isis_spftree_new(struct isis_area *area); +void isis_spftree_del(struct isis_spftree *spftree); +void spftree_area_init(struct isis_area *area); +void spftree_area_del(struct isis_area *area); +void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj); +int isis_spf_schedule(struct isis_area *area, int level); +void isis_spf_cmds_init(void); #endif /* _ZEBRA_ISIS_SPF_H */ diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 271545744..5296d9948 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -61,1020 +61,1034 @@ /* Global varial for MPLS TE management */ struct isis_mpls_te isisMplsTE; -const char *mode2text[] = { "Disable", "Area", "AS", "Emulate" }; +const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"}; /*------------------------------------------------------------------------* * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ /* Search MPLS TE Circuit context from Interface */ -static struct mpls_te_circuit * -lookup_mpls_params_by_ifp (struct interface *ifp) +static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - if ((circuit = circuit_scan_by_ifp (ifp)) == NULL) - return NULL; + if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) + return NULL; - return circuit->mtc; + return circuit->mtc; } /* Create new MPLS TE Circuit context */ -struct mpls_te_circuit * -mpls_te_circuit_new() +struct mpls_te_circuit *mpls_te_circuit_new() { - struct mpls_te_circuit *mtc; + struct mpls_te_circuit *mtc; - zlog_debug ("ISIS MPLS-TE: Create new MPLS TE Circuit context"); + zlog_debug("ISIS MPLS-TE: Create new MPLS TE Circuit context"); - mtc = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof (struct mpls_te_circuit)); + mtc = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_circuit)); - if (mtc == NULL) - return NULL; + if (mtc == NULL) + return NULL; - mtc->status = disable; - mtc->type = STD_TE; - mtc->length = 0; - - return mtc; + mtc->status = disable; + mtc->type = STD_TE; + mtc->length = 0; + return mtc; } -/* Copy SUB TLVs parameters into a buffer - No space verification are performed */ +/* Copy SUB TLVs parameters into a buffer - No space verification are performed + */ /* Caller must verify before that there is enough free space in the buffer */ -u_char -add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc) +u_char add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc) { - u_char size, *tlvs = buf; - - zlog_debug ("ISIS MPLS-TE: Add TE Sub TLVs to buffer"); - - if (mtc == NULL) - { - zlog_debug("ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified"); - return 0; - } - - /* Create buffer if not provided */ - if (buf == NULL) - { - zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified"); - return 0; - } - - /* TE_SUBTLV_ADMIN_GRP */ - if (SUBTLV_TYPE(mtc->admin_grp) != 0) - { - size = SUBTLV_SIZE (&(mtc->admin_grp.header)); - memcpy(tlvs, &(mtc->admin_grp), size); - tlvs += size; - } - - /* TE_SUBTLV_LLRI */ - if (SUBTLV_TYPE(mtc->llri) != 0) - { - size = SUBTLV_SIZE (&(mtc->llri.header)); - memcpy(tlvs, &(mtc->llri), size); - tlvs += size; - } - - /* TE_SUBTLV_LCLIF_IPADDR */ - if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) - { - size = SUBTLV_SIZE (&(mtc->local_ipaddr.header)); - memcpy(tlvs, &(mtc->local_ipaddr), size); - tlvs += size; - } - - /* TE_SUBTLV_RMTIF_IPADDR */ - if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) - { - size = SUBTLV_SIZE (&(mtc->rmt_ipaddr.header)); - memcpy(tlvs, &(mtc->rmt_ipaddr), size); - tlvs += size; - } - - /* TE_SUBTLV_MAX_BW */ - if (SUBTLV_TYPE(mtc->max_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->max_bw.header)); - memcpy(tlvs, &(mtc->max_bw), size); - tlvs += size; - } - - /* TE_SUBTLV_MAX_RSV_BW */ - if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->max_rsv_bw.header)); - memcpy(tlvs, &(mtc->max_rsv_bw), size); - tlvs += size; - } - - /* TE_SUBTLV_UNRSV_BW */ - if (SUBTLV_TYPE(mtc->unrsv_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->unrsv_bw.header)); - memcpy(tlvs, &(mtc->unrsv_bw), size); - tlvs += size; - } - - /* TE_SUBTLV_TE_METRIC */ - if (SUBTLV_TYPE(mtc->te_metric) != 0) - { - size = SUBTLV_SIZE (&(mtc->te_metric.header)); - memcpy(tlvs, &(mtc->te_metric), size); - tlvs += size; - } - - /* TE_SUBTLV_AV_DELAY */ - if (SUBTLV_TYPE(mtc->av_delay) != 0) - { - size = SUBTLV_SIZE (&(mtc->av_delay.header)); - memcpy(tlvs, &(mtc->av_delay), size); - tlvs += size; - } - - /* TE_SUBTLV_MM_DELAY */ - if (SUBTLV_TYPE(mtc->mm_delay) != 0) - { - size = SUBTLV_SIZE (&(mtc->mm_delay.header)); - memcpy(tlvs, &(mtc->mm_delay), size); - tlvs += size; - } - - /* TE_SUBTLV_DELAY_VAR */ - if (SUBTLV_TYPE(mtc->delay_var) != 0) - { - size = SUBTLV_SIZE (&(mtc->delay_var.header)); - memcpy(tlvs, &(mtc->delay_var), size); - tlvs += size; - } - - /* TE_SUBTLV_PKT_LOSS */ - if (SUBTLV_TYPE(mtc->pkt_loss) != 0) - { - size = SUBTLV_SIZE (&(mtc->pkt_loss.header)); - memcpy(tlvs, &(mtc->pkt_loss), size); - tlvs += size; - } - - /* TE_SUBTLV_RES_BW */ - if (SUBTLV_TYPE(mtc->res_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->res_bw.header)); - memcpy(tlvs, &(mtc->res_bw), size); - tlvs += size; - } - - /* TE_SUBTLV_AVA_BW */ - if (SUBTLV_TYPE(mtc->ava_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->ava_bw.header)); - memcpy(tlvs, &(mtc->ava_bw), size); - tlvs += size; - } - - /* TE_SUBTLV_USE_BW */ - if (SUBTLV_TYPE(mtc->use_bw) != 0) - { - size = SUBTLV_SIZE (&(mtc->use_bw.header)); - memcpy(tlvs, &(mtc->use_bw), size); - tlvs += size; - } - - /* Update SubTLVs length */ - mtc->length = subtlvs_len(mtc); - - zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc->length); - - return mtc->length; + u_char size, *tlvs = buf; + + zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer"); + + if (mtc == NULL) { + zlog_debug( + "ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified"); + return 0; + } + + /* Create buffer if not provided */ + if (buf == NULL) { + zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified"); + return 0; + } + + /* TE_SUBTLV_ADMIN_GRP */ + if (SUBTLV_TYPE(mtc->admin_grp) != 0) { + size = SUBTLV_SIZE(&(mtc->admin_grp.header)); + memcpy(tlvs, &(mtc->admin_grp), size); + tlvs += size; + } + + /* TE_SUBTLV_LLRI */ + if (SUBTLV_TYPE(mtc->llri) != 0) { + size = SUBTLV_SIZE(&(mtc->llri.header)); + memcpy(tlvs, &(mtc->llri), size); + tlvs += size; + } + + /* TE_SUBTLV_LCLIF_IPADDR */ + if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) { + size = SUBTLV_SIZE(&(mtc->local_ipaddr.header)); + memcpy(tlvs, &(mtc->local_ipaddr), size); + tlvs += size; + } + + /* TE_SUBTLV_RMTIF_IPADDR */ + if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) { + size = SUBTLV_SIZE(&(mtc->rmt_ipaddr.header)); + memcpy(tlvs, &(mtc->rmt_ipaddr), size); + tlvs += size; + } + + /* TE_SUBTLV_MAX_BW */ + if (SUBTLV_TYPE(mtc->max_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->max_bw.header)); + memcpy(tlvs, &(mtc->max_bw), size); + tlvs += size; + } + + /* TE_SUBTLV_MAX_RSV_BW */ + if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->max_rsv_bw.header)); + memcpy(tlvs, &(mtc->max_rsv_bw), size); + tlvs += size; + } + + /* TE_SUBTLV_UNRSV_BW */ + if (SUBTLV_TYPE(mtc->unrsv_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->unrsv_bw.header)); + memcpy(tlvs, &(mtc->unrsv_bw), size); + tlvs += size; + } + + /* TE_SUBTLV_TE_METRIC */ + if (SUBTLV_TYPE(mtc->te_metric) != 0) { + size = SUBTLV_SIZE(&(mtc->te_metric.header)); + memcpy(tlvs, &(mtc->te_metric), size); + tlvs += size; + } + + /* TE_SUBTLV_AV_DELAY */ + if (SUBTLV_TYPE(mtc->av_delay) != 0) { + size = SUBTLV_SIZE(&(mtc->av_delay.header)); + memcpy(tlvs, &(mtc->av_delay), size); + tlvs += size; + } + + /* TE_SUBTLV_MM_DELAY */ + if (SUBTLV_TYPE(mtc->mm_delay) != 0) { + size = SUBTLV_SIZE(&(mtc->mm_delay.header)); + memcpy(tlvs, &(mtc->mm_delay), size); + tlvs += size; + } + + /* TE_SUBTLV_DELAY_VAR */ + if (SUBTLV_TYPE(mtc->delay_var) != 0) { + size = SUBTLV_SIZE(&(mtc->delay_var.header)); + memcpy(tlvs, &(mtc->delay_var), size); + tlvs += size; + } + + /* TE_SUBTLV_PKT_LOSS */ + if (SUBTLV_TYPE(mtc->pkt_loss) != 0) { + size = SUBTLV_SIZE(&(mtc->pkt_loss.header)); + memcpy(tlvs, &(mtc->pkt_loss), size); + tlvs += size; + } + + /* TE_SUBTLV_RES_BW */ + if (SUBTLV_TYPE(mtc->res_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->res_bw.header)); + memcpy(tlvs, &(mtc->res_bw), size); + tlvs += size; + } + + /* TE_SUBTLV_AVA_BW */ + if (SUBTLV_TYPE(mtc->ava_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->ava_bw.header)); + memcpy(tlvs, &(mtc->ava_bw), size); + tlvs += size; + } + + /* TE_SUBTLV_USE_BW */ + if (SUBTLV_TYPE(mtc->use_bw) != 0) { + size = SUBTLV_SIZE(&(mtc->use_bw.header)); + memcpy(tlvs, &(mtc->use_bw), size); + tlvs += size; + } + + /* Update SubTLVs length */ + mtc->length = subtlvs_len(mtc); + + zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc->length); + + return mtc->length; } /* Compute total Sub-TLVs size */ -u_char -subtlvs_len (struct mpls_te_circuit *mtc) +u_char subtlvs_len(struct mpls_te_circuit *mtc) { - int length = 0; + int length = 0; - /* Sanity Check */ - if (mtc == NULL) - return 0; + /* Sanity Check */ + if (mtc == NULL) + return 0; - /* TE_SUBTLV_ADMIN_GRP */ - if (SUBTLV_TYPE(mtc->admin_grp) != 0) - length += SUBTLV_SIZE (&(mtc->admin_grp.header)); + /* TE_SUBTLV_ADMIN_GRP */ + if (SUBTLV_TYPE(mtc->admin_grp) != 0) + length += SUBTLV_SIZE(&(mtc->admin_grp.header)); - /* TE_SUBTLV_LLRI */ - if (SUBTLV_TYPE(mtc->llri) != 0) - length += SUBTLV_SIZE (&mtc->llri.header); + /* TE_SUBTLV_LLRI */ + if (SUBTLV_TYPE(mtc->llri) != 0) + length += SUBTLV_SIZE(&mtc->llri.header); - /* TE_SUBTLV_LCLIF_IPADDR */ - if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) - length += SUBTLV_SIZE (&mtc->local_ipaddr.header); + /* TE_SUBTLV_LCLIF_IPADDR */ + if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) + length += SUBTLV_SIZE(&mtc->local_ipaddr.header); - /* TE_SUBTLV_RMTIF_IPADDR */ - if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) - length += SUBTLV_SIZE (&mtc->rmt_ipaddr.header); + /* TE_SUBTLV_RMTIF_IPADDR */ + if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) + length += SUBTLV_SIZE(&mtc->rmt_ipaddr.header); - /* TE_SUBTLV_MAX_BW */ - if (SUBTLV_TYPE(mtc->max_bw) != 0) - length += SUBTLV_SIZE (&mtc->max_bw.header); + /* TE_SUBTLV_MAX_BW */ + if (SUBTLV_TYPE(mtc->max_bw) != 0) + length += SUBTLV_SIZE(&mtc->max_bw.header); - /* TE_SUBTLV_MAX_RSV_BW */ - if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0) - length += SUBTLV_SIZE (&mtc->max_rsv_bw.header); + /* TE_SUBTLV_MAX_RSV_BW */ + if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0) + length += SUBTLV_SIZE(&mtc->max_rsv_bw.header); - /* TE_SUBTLV_UNRSV_BW */ - if (SUBTLV_TYPE(mtc->unrsv_bw) != 0) - length += SUBTLV_SIZE (&mtc->unrsv_bw.header); + /* TE_SUBTLV_UNRSV_BW */ + if (SUBTLV_TYPE(mtc->unrsv_bw) != 0) + length += SUBTLV_SIZE(&mtc->unrsv_bw.header); - /* TE_SUBTLV_TE_METRIC */ - if (SUBTLV_TYPE(mtc->te_metric) != 0) - length += SUBTLV_SIZE (&mtc->te_metric.header); + /* TE_SUBTLV_TE_METRIC */ + if (SUBTLV_TYPE(mtc->te_metric) != 0) + length += SUBTLV_SIZE(&mtc->te_metric.header); - /* TE_SUBTLV_AV_DELAY */ - if (SUBTLV_TYPE(mtc->av_delay) != 0) - length += SUBTLV_SIZE (&mtc->av_delay.header); + /* TE_SUBTLV_AV_DELAY */ + if (SUBTLV_TYPE(mtc->av_delay) != 0) + length += SUBTLV_SIZE(&mtc->av_delay.header); - /* TE_SUBTLV_MM_DELAY */ - if (SUBTLV_TYPE(mtc->mm_delay) != 0) - length += SUBTLV_SIZE (&mtc->mm_delay.header); + /* TE_SUBTLV_MM_DELAY */ + if (SUBTLV_TYPE(mtc->mm_delay) != 0) + length += SUBTLV_SIZE(&mtc->mm_delay.header); - /* TE_SUBTLV_DELAY_VAR */ - if (SUBTLV_TYPE(mtc->delay_var) != 0) - length += SUBTLV_SIZE (&mtc->delay_var.header); + /* TE_SUBTLV_DELAY_VAR */ + if (SUBTLV_TYPE(mtc->delay_var) != 0) + length += SUBTLV_SIZE(&mtc->delay_var.header); - /* TE_SUBTLV_PKT_LOSS */ - if (SUBTLV_TYPE(mtc->pkt_loss) != 0) - length += SUBTLV_SIZE (&mtc->pkt_loss.header); + /* TE_SUBTLV_PKT_LOSS */ + if (SUBTLV_TYPE(mtc->pkt_loss) != 0) + length += SUBTLV_SIZE(&mtc->pkt_loss.header); - /* TE_SUBTLV_RES_BW */ - if (SUBTLV_TYPE(mtc->res_bw) != 0) - length += SUBTLV_SIZE (&mtc->res_bw.header); + /* TE_SUBTLV_RES_BW */ + if (SUBTLV_TYPE(mtc->res_bw) != 0) + length += SUBTLV_SIZE(&mtc->res_bw.header); - /* TE_SUBTLV_AVA_BW */ - if (SUBTLV_TYPE(mtc->ava_bw) != 0) - length += SUBTLV_SIZE (&mtc->ava_bw.header); + /* TE_SUBTLV_AVA_BW */ + if (SUBTLV_TYPE(mtc->ava_bw) != 0) + length += SUBTLV_SIZE(&mtc->ava_bw.header); - /* TE_SUBTLV_USE_BW */ - if (SUBTLV_TYPE(mtc->use_bw) != 0) - length += SUBTLV_SIZE (&mtc->use_bw.header); + /* TE_SUBTLV_USE_BW */ + if (SUBTLV_TYPE(mtc->use_bw) != 0) + length += SUBTLV_SIZE(&mtc->use_bw.header); - /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */ - if (length > MAX_SUBTLV_SIZE) - { - mtc->length = 0; - return 0; - } + /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */ + if (length > MAX_SUBTLV_SIZE) { + mtc->length = 0; + return 0; + } - mtc->length = (u_char)length; + mtc->length = (u_char)length; - return mtc->length; + return mtc->length; } /* Following are various functions to set MPLS TE parameters */ -static void -set_circuitparams_admin_grp (struct mpls_te_circuit *mtc, u_int32_t admingrp) +static void set_circuitparams_admin_grp(struct mpls_te_circuit *mtc, + u_int32_t admingrp) { - SUBTLV_TYPE(mtc->admin_grp) = TE_SUBTLV_ADMIN_GRP; - SUBTLV_LEN(mtc->admin_grp) = SUBTLV_DEF_SIZE; - mtc->admin_grp.value = htonl(admingrp); - return; + SUBTLV_TYPE(mtc->admin_grp) = TE_SUBTLV_ADMIN_GRP; + SUBTLV_LEN(mtc->admin_grp) = SUBTLV_DEF_SIZE; + mtc->admin_grp.value = htonl(admingrp); + return; } -static void __attribute__ ((unused)) -set_circuitparams_llri (struct mpls_te_circuit *mtc, u_int32_t local, u_int32_t remote) +static void __attribute__((unused)) +set_circuitparams_llri(struct mpls_te_circuit *mtc, u_int32_t local, + u_int32_t remote) { - SUBTLV_TYPE(mtc->llri) = TE_SUBTLV_LLRI; - SUBTLV_LEN(mtc->llri) = TE_SUBTLV_LLRI_SIZE; - mtc->llri.local = htonl(local); - mtc->llri.remote = htonl(remote); + SUBTLV_TYPE(mtc->llri) = TE_SUBTLV_LLRI; + SUBTLV_LEN(mtc->llri) = TE_SUBTLV_LLRI_SIZE; + mtc->llri.local = htonl(local); + mtc->llri.remote = htonl(remote); } -void -set_circuitparams_local_ipaddr (struct mpls_te_circuit *mtc, struct in_addr addr) +void set_circuitparams_local_ipaddr(struct mpls_te_circuit *mtc, + struct in_addr addr) { - SUBTLV_TYPE(mtc->local_ipaddr) = TE_SUBTLV_LOCAL_IPADDR; - SUBTLV_LEN(mtc->local_ipaddr) = SUBTLV_DEF_SIZE; - mtc->local_ipaddr.value.s_addr = addr.s_addr; - return; + SUBTLV_TYPE(mtc->local_ipaddr) = TE_SUBTLV_LOCAL_IPADDR; + SUBTLV_LEN(mtc->local_ipaddr) = SUBTLV_DEF_SIZE; + mtc->local_ipaddr.value.s_addr = addr.s_addr; + return; } -void -set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *mtc, struct in_addr addr) +void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *mtc, + struct in_addr addr) { - SUBTLV_TYPE(mtc->rmt_ipaddr) = TE_SUBTLV_RMT_IPADDR; - SUBTLV_LEN(mtc->rmt_ipaddr) = SUBTLV_DEF_SIZE; - mtc->rmt_ipaddr.value.s_addr = addr.s_addr; - return; + SUBTLV_TYPE(mtc->rmt_ipaddr) = TE_SUBTLV_RMT_IPADDR; + SUBTLV_LEN(mtc->rmt_ipaddr) = SUBTLV_DEF_SIZE; + mtc->rmt_ipaddr.value.s_addr = addr.s_addr; + return; } -static void -set_circuitparams_max_bw (struct mpls_te_circuit *mtc, float fp) +static void set_circuitparams_max_bw(struct mpls_te_circuit *mtc, float fp) { - SUBTLV_TYPE(mtc->max_bw) = TE_SUBTLV_MAX_BW; - SUBTLV_LEN(mtc->max_bw) = SUBTLV_DEF_SIZE; - mtc->max_bw.value = htonf(fp); - return; + SUBTLV_TYPE(mtc->max_bw) = TE_SUBTLV_MAX_BW; + SUBTLV_LEN(mtc->max_bw) = SUBTLV_DEF_SIZE; + mtc->max_bw.value = htonf(fp); + return; } -static void -set_circuitparams_max_rsv_bw (struct mpls_te_circuit *mtc, float fp) +static void set_circuitparams_max_rsv_bw(struct mpls_te_circuit *mtc, float fp) { - SUBTLV_TYPE(mtc->max_rsv_bw) = TE_SUBTLV_MAX_RSV_BW; - SUBTLV_LEN(mtc->max_rsv_bw) = SUBTLV_DEF_SIZE; - mtc->max_rsv_bw.value = htonf(fp); - return; + SUBTLV_TYPE(mtc->max_rsv_bw) = TE_SUBTLV_MAX_RSV_BW; + SUBTLV_LEN(mtc->max_rsv_bw) = SUBTLV_DEF_SIZE; + mtc->max_rsv_bw.value = htonf(fp); + return; } -static void -set_circuitparams_unrsv_bw (struct mpls_te_circuit *mtc, int priority, float fp) +static void set_circuitparams_unrsv_bw(struct mpls_te_circuit *mtc, + int priority, float fp) { - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_BW; - SUBTLV_LEN(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_SIZE; - mtc->unrsv_bw.value[priority] = htonf(fp); - return; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_BW; + SUBTLV_LEN(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_SIZE; + mtc->unrsv_bw.value[priority] = htonf(fp); + return; } -static void -set_circuitparams_te_metric (struct mpls_te_circuit *mtc, u_int32_t te_metric) +static void set_circuitparams_te_metric(struct mpls_te_circuit *mtc, + u_int32_t te_metric) { - SUBTLV_TYPE(mtc->te_metric) = TE_SUBTLV_TE_METRIC; - SUBTLV_LEN(mtc->te_metric) = TE_SUBTLV_TE_METRIC_SIZE; - mtc->te_metric.value[0] = (te_metric >> 16) & 0xFF; - mtc->te_metric.value[1] = (te_metric >> 8) & 0xFF; - mtc->te_metric.value[2] = te_metric & 0xFF; - return; + SUBTLV_TYPE(mtc->te_metric) = TE_SUBTLV_TE_METRIC; + SUBTLV_LEN(mtc->te_metric) = TE_SUBTLV_TE_METRIC_SIZE; + mtc->te_metric.value[0] = (te_metric >> 16) & 0xFF; + mtc->te_metric.value[1] = (te_metric >> 8) & 0xFF; + mtc->te_metric.value[2] = te_metric & 0xFF; + return; } -static void -set_circuitparams_inter_as (struct mpls_te_circuit *mtc, struct in_addr addr, u_int32_t as) +static void set_circuitparams_inter_as(struct mpls_te_circuit *mtc, + struct in_addr addr, u_int32_t as) { - /* Set the Remote ASBR IP address and then the associated AS number */ - SUBTLV_TYPE(mtc->rip) = TE_SUBTLV_RIP; - SUBTLV_LEN(mtc->rip) = SUBTLV_DEF_SIZE; - mtc->rip.value.s_addr = addr.s_addr; + /* Set the Remote ASBR IP address and then the associated AS number */ + SUBTLV_TYPE(mtc->rip) = TE_SUBTLV_RIP; + SUBTLV_LEN(mtc->rip) = SUBTLV_DEF_SIZE; + mtc->rip.value.s_addr = addr.s_addr; - SUBTLV_TYPE(mtc->ras) = TE_SUBTLV_RAS; - SUBTLV_LEN(mtc->ras) = SUBTLV_DEF_SIZE; - mtc->ras.value = htonl(as); + SUBTLV_TYPE(mtc->ras) = TE_SUBTLV_RAS; + SUBTLV_LEN(mtc->ras) = SUBTLV_DEF_SIZE; + mtc->ras.value = htonl(as); } -static void -unset_circuitparams_inter_as (struct mpls_te_circuit *mtc) +static void unset_circuitparams_inter_as(struct mpls_te_circuit *mtc) { - /* Reset the Remote ASBR IP address and then the associated AS number */ - SUBTLV_TYPE(mtc->rip) = 0; - SUBTLV_LEN(mtc->rip) = 0; - mtc->rip.value.s_addr = 0; + /* Reset the Remote ASBR IP address and then the associated AS number */ + SUBTLV_TYPE(mtc->rip) = 0; + SUBTLV_LEN(mtc->rip) = 0; + mtc->rip.value.s_addr = 0; - SUBTLV_TYPE(mtc->ras) = 0; - SUBTLV_LEN(mtc->ras) = 0; - mtc->ras.value = 0; + SUBTLV_TYPE(mtc->ras) = 0; + SUBTLV_LEN(mtc->ras) = 0; + mtc->ras.value = 0; } -static void -set_circuitparams_av_delay (struct mpls_te_circuit *mtc, u_int32_t delay, u_char anormal) +static void set_circuitparams_av_delay(struct mpls_te_circuit *mtc, + u_int32_t delay, u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->av_delay) = TE_SUBTLV_AV_DELAY; - SUBTLV_LEN(mtc->av_delay) = SUBTLV_DEF_SIZE; - tmp = delay & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - mtc->av_delay.value = htonl(tmp); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->av_delay) = TE_SUBTLV_AV_DELAY; + SUBTLV_LEN(mtc->av_delay) = SUBTLV_DEF_SIZE; + tmp = delay & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + mtc->av_delay.value = htonl(tmp); + return; } -static void -set_circuitparams_mm_delay (struct mpls_te_circuit *mtc, u_int32_t low, u_int32_t high, u_char anormal) +static void set_circuitparams_mm_delay(struct mpls_te_circuit *mtc, + u_int32_t low, u_int32_t high, + u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->mm_delay) = TE_SUBTLV_MM_DELAY; - SUBTLV_LEN(mtc->mm_delay) = TE_SUBTLV_MM_DELAY_SIZE; - tmp = low & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - mtc->mm_delay.low = htonl(tmp); - mtc->mm_delay.high = htonl(high); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->mm_delay) = TE_SUBTLV_MM_DELAY; + SUBTLV_LEN(mtc->mm_delay) = TE_SUBTLV_MM_DELAY_SIZE; + tmp = low & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + mtc->mm_delay.low = htonl(tmp); + mtc->mm_delay.high = htonl(high); + return; } -static void -set_circuitparams_delay_var (struct mpls_te_circuit *mtc, u_int32_t jitter) +static void set_circuitparams_delay_var(struct mpls_te_circuit *mtc, + u_int32_t jitter) { - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->delay_var) = TE_SUBTLV_DELAY_VAR; - SUBTLV_LEN(mtc->delay_var) = SUBTLV_DEF_SIZE; - mtc->delay_var.value = htonl(jitter & TE_EXT_MASK); - return; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->delay_var) = TE_SUBTLV_DELAY_VAR; + SUBTLV_LEN(mtc->delay_var) = SUBTLV_DEF_SIZE; + mtc->delay_var.value = htonl(jitter & TE_EXT_MASK); + return; } -static void -set_circuitparams_pkt_loss (struct mpls_te_circuit *mtc, u_int32_t loss, u_char anormal) +static void set_circuitparams_pkt_loss(struct mpls_te_circuit *mtc, + u_int32_t loss, u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->pkt_loss) = TE_SUBTLV_PKT_LOSS; - SUBTLV_LEN(mtc->pkt_loss) = SUBTLV_DEF_SIZE; - tmp = loss & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - mtc->pkt_loss.value = htonl(tmp); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->pkt_loss) = TE_SUBTLV_PKT_LOSS; + SUBTLV_LEN(mtc->pkt_loss) = SUBTLV_DEF_SIZE; + tmp = loss & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + mtc->pkt_loss.value = htonl(tmp); + return; } -static void -set_circuitparams_res_bw (struct mpls_te_circuit *mtc, float fp) +static void set_circuitparams_res_bw(struct mpls_te_circuit *mtc, float fp) { - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->res_bw) = TE_SUBTLV_RES_BW; - SUBTLV_LEN(mtc->res_bw) = SUBTLV_DEF_SIZE; - mtc->res_bw.value = htonf(fp); - return; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->res_bw) = TE_SUBTLV_RES_BW; + SUBTLV_LEN(mtc->res_bw) = SUBTLV_DEF_SIZE; + mtc->res_bw.value = htonf(fp); + return; } -static void -set_circuitparams_ava_bw (struct mpls_te_circuit *mtc, float fp) +static void set_circuitparams_ava_bw(struct mpls_te_circuit *mtc, float fp) { - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->ava_bw) = TE_SUBTLV_AVA_BW; - SUBTLV_LEN(mtc->ava_bw) = SUBTLV_DEF_SIZE; - mtc->ava_bw.value = htonf(fp); - return; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->ava_bw) = TE_SUBTLV_AVA_BW; + SUBTLV_LEN(mtc->ava_bw) = SUBTLV_DEF_SIZE; + mtc->ava_bw.value = htonf(fp); + return; } -static void -set_circuitparams_use_bw (struct mpls_te_circuit *mtc, float fp) +static void set_circuitparams_use_bw(struct mpls_te_circuit *mtc, float fp) { - /* Note that TLV-length field is the size of array. */ - SUBTLV_TYPE(mtc->use_bw) = TE_SUBTLV_USE_BW; - SUBTLV_LEN(mtc->use_bw) = SUBTLV_DEF_SIZE; - mtc->use_bw.value = htonf(fp); - return; + /* Note that TLV-length field is the size of array. */ + SUBTLV_TYPE(mtc->use_bw) = TE_SUBTLV_USE_BW; + SUBTLV_LEN(mtc->use_bw) = SUBTLV_DEF_SIZE; + mtc->use_bw.value = htonf(fp); + return; } /* Main initialization / update function of the MPLS TE Circuit context */ /* Call when interface TE Link parameters are modified */ -void -isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp) +void isis_link_params_update(struct isis_circuit *circuit, + struct interface *ifp) { - int i; - struct prefix_ipv4 *addr; - struct mpls_te_circuit *mtc; - - /* Sanity Check */ - if ((circuit == NULL) || (ifp == NULL)) - return; - - zlog_info ("MPLS-TE: Initialize circuit parameters for interface %s", ifp->name); - - /* Check if MPLS TE Circuit context has not been already created */ - if (circuit->mtc == NULL) - circuit->mtc = mpls_te_circuit_new(); - - mtc = circuit->mtc; - - /* Fulfil MTC TLV from ifp TE Link parameters */ - if (HAS_LINK_PARAMS(ifp)) - { - mtc->status = enable; - /* STD_TE metrics */ - if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP)) - set_circuitparams_admin_grp (mtc, ifp->link_params->admin_grp); - else - SUBTLV_TYPE(mtc->admin_grp) = 0; - - /* If not already set, register local IP addr from ip_addr list if it exists */ - if (SUBTLV_TYPE(mtc->local_ipaddr) == 0) - { - if (circuit->ip_addrs != NULL && listcount(circuit->ip_addrs) != 0) - { - addr = (struct prefix_ipv4 *)listgetdata ((struct listnode *)listhead (circuit->ip_addrs)); - set_circuitparams_local_ipaddr (mtc, addr->prefix); - } - } - - /* If not already set, try to determine Remote IP addr if circuit is P2P */ - if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) && (circuit->circ_type == CIRCUIT_T_P2P)) - { - struct isis_adjacency *adj = circuit->u.p2p.neighbor; - if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0) - { - struct in_addr *ip_addr; - ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs)); - set_circuitparams_rmt_ipaddr (mtc, *ip_addr); - } - } - - if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) - set_circuitparams_max_bw (mtc, ifp->link_params->max_bw); - else - SUBTLV_TYPE(mtc->max_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW)) - set_circuitparams_max_rsv_bw (mtc, ifp->link_params->max_rsv_bw); - else - SUBTLV_TYPE(mtc->max_rsv_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW)) - for (i = 0; i < MAX_CLASS_TYPE; i++) - set_circuitparams_unrsv_bw (mtc, i, ifp->link_params->unrsv_bw[i]); - else - SUBTLV_TYPE(mtc->unrsv_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC)) - set_circuitparams_te_metric(mtc, ifp->link_params->te_metric); - else - SUBTLV_TYPE(mtc->te_metric) = 0; - - /* TE metric Extensions */ - if (IS_PARAM_SET(ifp->link_params, LP_DELAY)) - set_circuitparams_av_delay(mtc, ifp->link_params->av_delay, 0); - else - SUBTLV_TYPE(mtc->av_delay) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY)) - set_circuitparams_mm_delay(mtc, ifp->link_params->min_delay, ifp->link_params->max_delay, 0); - else - SUBTLV_TYPE(mtc->mm_delay) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR)) - set_circuitparams_delay_var(mtc, ifp->link_params->delay_var); - else - SUBTLV_TYPE(mtc->delay_var) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS)) - set_circuitparams_pkt_loss(mtc, ifp->link_params->pkt_loss, 0); - else - SUBTLV_TYPE(mtc->pkt_loss) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_RES_BW)) - set_circuitparams_res_bw(mtc, ifp->link_params->res_bw); - else - SUBTLV_TYPE(mtc->res_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW)) - set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw); - else - SUBTLV_TYPE(mtc->ava_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_USE_BW)) - set_circuitparams_use_bw(mtc, ifp->link_params->use_bw); - else - SUBTLV_TYPE(mtc->use_bw) = 0; - - /* INTER_AS */ - if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS)) - set_circuitparams_inter_as(mtc, ifp->link_params->rmt_ip, ifp->link_params->rmt_as); - else - /* reset inter-as TE params */ - unset_circuitparams_inter_as (mtc); - - /* Compute total length of SUB TLVs */ - mtc->length = subtlvs_len(mtc); - - } - else - mtc->status = disable; - - /* Finally Update LSP */ + int i; + struct prefix_ipv4 *addr; + struct mpls_te_circuit *mtc; + + /* Sanity Check */ + if ((circuit == NULL) || (ifp == NULL)) + return; + + zlog_info("MPLS-TE: Initialize circuit parameters for interface %s", + ifp->name); + + /* Check if MPLS TE Circuit context has not been already created */ + if (circuit->mtc == NULL) + circuit->mtc = mpls_te_circuit_new(); + + mtc = circuit->mtc; + + /* Fulfil MTC TLV from ifp TE Link parameters */ + if (HAS_LINK_PARAMS(ifp)) { + mtc->status = enable; + /* STD_TE metrics */ + if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP)) + set_circuitparams_admin_grp( + mtc, ifp->link_params->admin_grp); + else + SUBTLV_TYPE(mtc->admin_grp) = 0; + + /* If not already set, register local IP addr from ip_addr list + * if it exists */ + if (SUBTLV_TYPE(mtc->local_ipaddr) == 0) { + if (circuit->ip_addrs != NULL + && listcount(circuit->ip_addrs) != 0) { + addr = (struct prefix_ipv4 *)listgetdata( + (struct listnode *)listhead( + circuit->ip_addrs)); + set_circuitparams_local_ipaddr(mtc, + addr->prefix); + } + } + + /* If not already set, try to determine Remote IP addr if + * circuit is P2P */ + if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) + && (circuit->circ_type == CIRCUIT_T_P2P)) { + struct isis_adjacency *adj = circuit->u.p2p.neighbor; + if (adj->ipv4_addrs != NULL + && listcount(adj->ipv4_addrs) != 0) { + struct in_addr *ip_addr; + ip_addr = (struct in_addr *)listgetdata( + (struct listnode *)listhead( + adj->ipv4_addrs)); + set_circuitparams_rmt_ipaddr(mtc, *ip_addr); + } + } + + if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) + set_circuitparams_max_bw(mtc, ifp->link_params->max_bw); + else + SUBTLV_TYPE(mtc->max_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW)) + set_circuitparams_max_rsv_bw( + mtc, ifp->link_params->max_rsv_bw); + else + SUBTLV_TYPE(mtc->max_rsv_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW)) + for (i = 0; i < MAX_CLASS_TYPE; i++) + set_circuitparams_unrsv_bw( + mtc, i, ifp->link_params->unrsv_bw[i]); + else + SUBTLV_TYPE(mtc->unrsv_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC)) + set_circuitparams_te_metric( + mtc, ifp->link_params->te_metric); + else + SUBTLV_TYPE(mtc->te_metric) = 0; + + /* TE metric Extensions */ + if (IS_PARAM_SET(ifp->link_params, LP_DELAY)) + set_circuitparams_av_delay( + mtc, ifp->link_params->av_delay, 0); + else + SUBTLV_TYPE(mtc->av_delay) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY)) + set_circuitparams_mm_delay( + mtc, ifp->link_params->min_delay, + ifp->link_params->max_delay, 0); + else + SUBTLV_TYPE(mtc->mm_delay) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR)) + set_circuitparams_delay_var( + mtc, ifp->link_params->delay_var); + else + SUBTLV_TYPE(mtc->delay_var) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS)) + set_circuitparams_pkt_loss( + mtc, ifp->link_params->pkt_loss, 0); + else + SUBTLV_TYPE(mtc->pkt_loss) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_RES_BW)) + set_circuitparams_res_bw(mtc, ifp->link_params->res_bw); + else + SUBTLV_TYPE(mtc->res_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW)) + set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw); + else + SUBTLV_TYPE(mtc->ava_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_USE_BW)) + set_circuitparams_use_bw(mtc, ifp->link_params->use_bw); + else + SUBTLV_TYPE(mtc->use_bw) = 0; + + /* INTER_AS */ + if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS)) + set_circuitparams_inter_as(mtc, + ifp->link_params->rmt_ip, + ifp->link_params->rmt_as); + else + /* reset inter-as TE params */ + unset_circuitparams_inter_as(mtc); + + /* Compute total length of SUB TLVs */ + mtc->length = subtlvs_len(mtc); + + } else + mtc->status = disable; + +/* Finally Update LSP */ #if 0 if (IS_MPLS_TE(isisMplsTE) && circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); #endif - return; + return; } -void -isis_mpls_te_update (struct interface *ifp) +void isis_mpls_te_update(struct interface *ifp) { - struct isis_circuit *circuit; + struct isis_circuit *circuit; - /* Sanity Check */ - if (ifp == NULL) - return; + /* Sanity Check */ + if (ifp == NULL) + return; - /* Get circuit context from interface */ - if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) - return; + /* Get circuit context from interface */ + if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) + return; - /* Update TE TLVs ... */ - isis_link_params_update(circuit, ifp); + /* Update TE TLVs ... */ + isis_link_params_update(circuit, ifp); - /* ... and LSP */ - if (IS_MPLS_TE(isisMplsTE) && circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); + /* ... and LSP */ + if (IS_MPLS_TE(isisMplsTE) && circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); - return; + return; } /*------------------------------------------------------------------------* * Followings are vty session control functions. *------------------------------------------------------------------------*/ -static u_char -show_vty_subtlv_admin_grp (struct vty *vty, struct te_subtlv_admin_grp *tlv) +static u_char show_vty_subtlv_admin_grp(struct vty *vty, + struct te_subtlv_admin_grp *tlv) { - if (vty != NULL) - vty_out (vty, " Administrative Group: 0x%x\n", - (u_int32_t)ntohl(tlv->value)); - else - zlog_debug (" Administrative Group: 0x%x", - (u_int32_t) ntohl (tlv->value)); + if (vty != NULL) + vty_out(vty, " Administrative Group: 0x%x\n", + (u_int32_t)ntohl(tlv->value)); + else + zlog_debug(" Administrative Group: 0x%x", + (u_int32_t)ntohl(tlv->value)); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_llri (struct vty *vty, struct te_subtlv_llri *tlv) +static u_char show_vty_subtlv_llri(struct vty *vty, struct te_subtlv_llri *tlv) { - if (vty != NULL) - { - vty_out (vty, " Link Local ID: %d\n",(u_int32_t)ntohl(tlv->local)); - vty_out (vty, " Link Remote ID: %d\n", - (u_int32_t)ntohl(tlv->remote)); - } - else - { - zlog_debug (" Link Local ID: %d", (u_int32_t) ntohl (tlv->local)); - zlog_debug (" Link Remote ID: %d", (u_int32_t) ntohl (tlv->remote)); - } - - return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE); + if (vty != NULL) { + vty_out(vty, " Link Local ID: %d\n", + (u_int32_t)ntohl(tlv->local)); + vty_out(vty, " Link Remote ID: %d\n", + (u_int32_t)ntohl(tlv->remote)); + } else { + zlog_debug(" Link Local ID: %d", + (u_int32_t)ntohl(tlv->local)); + zlog_debug(" Link Remote ID: %d", + (u_int32_t)ntohl(tlv->remote)); + } + + return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE); } -static u_char -show_vty_subtlv_local_ipaddr (struct vty *vty, struct te_subtlv_local_ipaddr *tlv) +static u_char show_vty_subtlv_local_ipaddr(struct vty *vty, + struct te_subtlv_local_ipaddr *tlv) { - if (vty != NULL) - vty_out (vty, " Local Interface IP Address(es): %s\n", - inet_ntoa(tlv->value)); - else - zlog_debug (" Local Interface IP Address(es): %s", inet_ntoa (tlv->value)); - - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + if (vty != NULL) + vty_out(vty, " Local Interface IP Address(es): %s\n", + inet_ntoa(tlv->value)); + else + zlog_debug(" Local Interface IP Address(es): %s", + inet_ntoa(tlv->value)); + + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_rmt_ipaddr (struct vty *vty, struct te_subtlv_rmt_ipaddr *tlv) +static u_char show_vty_subtlv_rmt_ipaddr(struct vty *vty, + struct te_subtlv_rmt_ipaddr *tlv) { - if (vty != NULL) - vty_out (vty, " Remote Interface IP Address(es): %s\n", - inet_ntoa(tlv->value)); - else - zlog_debug (" Remote Interface IP Address(es): %s", inet_ntoa (tlv->value)); - - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + if (vty != NULL) + vty_out(vty, " Remote Interface IP Address(es): %s\n", + inet_ntoa(tlv->value)); + else + zlog_debug(" Remote Interface IP Address(es): %s", + inet_ntoa(tlv->value)); + + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_max_bw (struct vty *vty, struct te_subtlv_max_bw *tlv) +static u_char show_vty_subtlv_max_bw(struct vty *vty, + struct te_subtlv_max_bw *tlv) { - float fval; + float fval; - fval = ntohf (tlv->value); + fval = ntohf(tlv->value); - if (vty != NULL) - vty_out (vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval); - else - zlog_debug (" Maximum Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval); + else + zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_max_rsv_bw (struct vty *vty, struct te_subtlv_max_rsv_bw *tlv) +static u_char show_vty_subtlv_max_rsv_bw(struct vty *vty, + struct te_subtlv_max_rsv_bw *tlv) { - float fval; + float fval; - fval = ntohf (tlv->value); + fval = ntohf(tlv->value); - if (vty != NULL) - vty_out (vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",fval); - else - zlog_debug (" Maximum Reservable Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, + " Maximum Reservable Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)", + fval); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_unrsv_bw (struct vty *vty, struct te_subtlv_unrsv_bw *tlv) +static u_char show_vty_subtlv_unrsv_bw(struct vty *vty, + struct te_subtlv_unrsv_bw *tlv) { - float fval1, fval2; - int i; - - if (vty != NULL) - vty_out (vty, " Unreserved Bandwidth:\n"); - else - zlog_debug (" Unreserved Bandwidth:"); - - for (i = 0; i < MAX_CLASS_TYPE; i+=2) - { - fval1 = ntohf (tlv->value[i]); - fval2 = ntohf (tlv->value[i+1]); - if (vty != NULL) - vty_out (vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", i, fval1, i+1, - fval2); - else - zlog_debug (" [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)", i, fval1, i+1, fval2); - } - - return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE); + float fval1, fval2; + int i; + + if (vty != NULL) + vty_out(vty, " Unreserved Bandwidth:\n"); + else + zlog_debug(" Unreserved Bandwidth:"); + + for (i = 0; i < MAX_CLASS_TYPE; i += 2) { + fval1 = ntohf(tlv->value[i]); + fval2 = ntohf(tlv->value[i + 1]); + if (vty != NULL) + vty_out(vty, + " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", + i, fval1, i + 1, fval2); + else + zlog_debug( + " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)", + i, fval1, i + 1, fval2); + } + + return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE); } -static u_char -show_vty_subtlv_te_metric (struct vty *vty, struct te_subtlv_te_metric *tlv) +static u_char show_vty_subtlv_te_metric(struct vty *vty, + struct te_subtlv_te_metric *tlv) { - u_int32_t te_metric; + u_int32_t te_metric; - te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16; - if (vty != NULL) - vty_out (vty, " Traffic Engineering Metric: %u\n", te_metric); - else - zlog_debug (" Traffic Engineering Metric: %u", te_metric); + te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16; + if (vty != NULL) + vty_out(vty, " Traffic Engineering Metric: %u\n", te_metric); + else + zlog_debug(" Traffic Engineering Metric: %u", te_metric); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_ras (struct vty *vty, struct te_subtlv_ras *tlv) +static u_char show_vty_subtlv_ras(struct vty *vty, struct te_subtlv_ras *tlv) { - if (vty != NULL) - vty_out (vty, " Inter-AS TE Remote AS number: %u\n", - ntohl(tlv->value)); - else - zlog_debug (" Inter-AS TE Remote AS number: %u", ntohl (tlv->value)); - - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + if (vty != NULL) + vty_out(vty, " Inter-AS TE Remote AS number: %u\n", + ntohl(tlv->value)); + else + zlog_debug(" Inter-AS TE Remote AS number: %u", + ntohl(tlv->value)); + + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_rip (struct vty *vty, struct te_subtlv_rip *tlv) +static u_char show_vty_subtlv_rip(struct vty *vty, struct te_subtlv_rip *tlv) { - if (vty != NULL) - vty_out (vty, " Inter-AS TE Remote ASBR IP address: %s\n", - inet_ntoa(tlv->value)); - else - zlog_debug (" Inter-AS TE Remote ASBR IP address: %s", inet_ntoa (tlv->value)); - - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + if (vty != NULL) + vty_out(vty, " Inter-AS TE Remote ASBR IP address: %s\n", + inet_ntoa(tlv->value)); + else + zlog_debug(" Inter-AS TE Remote ASBR IP address: %s", + inet_ntoa(tlv->value)); + + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_av_delay (struct vty *vty, struct te_subtlv_av_delay *tlv) +static u_char show_vty_subtlv_av_delay(struct vty *vty, + struct te_subtlv_av_delay *tlv) { - u_int32_t delay; - u_int32_t A; + u_int32_t delay; + u_int32_t A; - delay = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK; - A = (u_int32_t) ntohl (tlv->value) & TE_EXT_ANORMAL; + delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; + A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL; - if (vty != NULL) - vty_out (vty, " %s Average Link Delay: %d (micro-sec)\n", A ? "Anomalous" : "Normal", - delay); - else - zlog_debug (" %s Average Link Delay: %d (micro-sec)", A ? "Anomalous" : "Normal", delay); + if (vty != NULL) + vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n", + A ? "Anomalous" : "Normal", delay); + else + zlog_debug(" %s Average Link Delay: %d (micro-sec)", + A ? "Anomalous" : "Normal", delay); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_mm_delay (struct vty *vty, struct te_subtlv_mm_delay *tlv) +static u_char show_vty_subtlv_mm_delay(struct vty *vty, + struct te_subtlv_mm_delay *tlv) { - u_int32_t low, high; - u_int32_t A; + u_int32_t low, high; + u_int32_t A; - low = (u_int32_t) ntohl (tlv->low) & TE_EXT_MASK; - A = (u_int32_t) ntohl (tlv->low) & TE_EXT_ANORMAL; - high = (u_int32_t) ntohl (tlv->high) & TE_EXT_MASK; + low = (u_int32_t)ntohl(tlv->low) & TE_EXT_MASK; + A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL; + high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK; - if (vty != NULL) - vty_out (vty, " %s Min/Max Link Delay: %d / %d (micro-sec)\n", A ? "Anomalous" : "Normal", low, - high); - else - zlog_debug (" %s Min/Max Link Delay: %d / %d (micro-sec)", A ? "Anomalous" : "Normal", low, high); + if (vty != NULL) + vty_out(vty, " %s Min/Max Link Delay: %d / %d (micro-sec)\n", + A ? "Anomalous" : "Normal", low, high); + else + zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)", + A ? "Anomalous" : "Normal", low, high); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_delay_var (struct vty *vty, struct te_subtlv_delay_var *tlv) +static u_char show_vty_subtlv_delay_var(struct vty *vty, + struct te_subtlv_delay_var *tlv) { - u_int32_t jitter; + u_int32_t jitter; - jitter = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK; + jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; - if (vty != NULL) - vty_out (vty, " Delay Variation: %d (micro-sec)\n", jitter); - else - zlog_debug (" Delay Variation: %d (micro-sec)", jitter); + if (vty != NULL) + vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter); + else + zlog_debug(" Delay Variation: %d (micro-sec)", jitter); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_pkt_loss (struct vty *vty, struct te_subtlv_pkt_loss *tlv) +static u_char show_vty_subtlv_pkt_loss(struct vty *vty, + struct te_subtlv_pkt_loss *tlv) { - u_int32_t loss; - u_int32_t A; - float fval; - - loss = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK; - fval = (float) (loss * LOSS_PRECISION); - A = (u_int32_t) ntohl (tlv->value) & TE_EXT_ANORMAL; - - if (vty != NULL) - vty_out (vty, " %s Link Packet Loss: %g (%%)\n", A ? "Anomalous" : "Normal", - fval); - else - zlog_debug (" %s Link Packet Loss: %g (%%)", A ? "Anomalous" : "Normal", fval); - - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + u_int32_t loss; + u_int32_t A; + float fval; + + loss = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; + fval = (float)(loss * LOSS_PRECISION); + A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL; + + if (vty != NULL) + vty_out(vty, " %s Link Packet Loss: %g (%%)\n", + A ? "Anomalous" : "Normal", fval); + else + zlog_debug(" %s Link Packet Loss: %g (%%)", + A ? "Anomalous" : "Normal", fval); + + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_res_bw (struct vty *vty, struct te_subtlv_res_bw *tlv) +static u_char show_vty_subtlv_res_bw(struct vty *vty, + struct te_subtlv_res_bw *tlv) { - float fval; + float fval; - fval = ntohf(tlv->value); + fval = ntohf(tlv->value); - if (vty != NULL) - vty_out (vty, " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Residual Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, + " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Residual Bandwidth: %g (Bytes/sec)", + fval); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_ava_bw (struct vty *vty, struct te_subtlv_ava_bw *tlv) +static u_char show_vty_subtlv_ava_bw(struct vty *vty, + struct te_subtlv_ava_bw *tlv) { - float fval; + float fval; - fval = ntohf (tlv->value); + fval = ntohf(tlv->value); - if (vty != NULL) - vty_out (vty, " Unidirectional Available Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Available Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, + " Unidirectional Available Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Available Bandwidth: %g (Bytes/sec)", + fval); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_subtlv_use_bw (struct vty *vty, struct te_subtlv_use_bw *tlv) +static u_char show_vty_subtlv_use_bw(struct vty *vty, + struct te_subtlv_use_bw *tlv) { - float fval; + float fval; - fval = ntohf (tlv->value); + fval = ntohf(tlv->value); - if (vty != NULL) - vty_out (vty, " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Utilized Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, + " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Utilized Bandwidth: %g (Bytes/sec)", + fval); - return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); + return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); } -static u_char -show_vty_unknown_tlv (struct vty *vty, struct subtlv_header *tlvh) +static u_char show_vty_unknown_tlv(struct vty *vty, struct subtlv_header *tlvh) { - int i, rtn = 1; - u_char *v = (u_char *)tlvh; - - if (vty != NULL) - { - if (tlvh->length != 0) - { - vty_out (vty, " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", - tlvh->type, tlvh->length); - vty_out(vty, " Dump: [00]"); - rtn = 1; /* initialize end of line counter */ - for (i = 0; i < tlvh->length; i++) - { - vty_out (vty, " %#.2x", v[i]); - if (rtn == 8) - { - vty_out (vty, "\n [%.2x]", i + 1); - rtn = 1; - } - else - rtn++; - } - vty_out (vty, "\n"); - } - else - vty_out (vty, " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", - tlvh->type, tlvh->length); - } - else - { - zlog_debug (" Unknown TLV: [type(%#.2x), length(%#.2x)]", - tlvh->type, tlvh->length); - } - - return SUBTLV_SIZE(tlvh); + int i, rtn = 1; + u_char *v = (u_char *)tlvh; + + if (vty != NULL) { + if (tlvh->length != 0) { + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->type, tlvh->length); + vty_out(vty, " Dump: [00]"); + rtn = 1; /* initialize end of line counter */ + for (i = 0; i < tlvh->length; i++) { + vty_out(vty, " %#.2x", v[i]); + if (rtn == 8) { + vty_out(vty, "\n [%.2x]", + i + 1); + rtn = 1; + } else + rtn++; + } + vty_out(vty, "\n"); + } else + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->type, tlvh->length); + } else { + zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]", + tlvh->type, tlvh->length); + } + + return SUBTLV_SIZE(tlvh); } /* Main Show function */ -void -mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te) +void mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te) { - struct subtlv_header *tlvh; - u_int16_t sum = 0; - - zlog_debug ("ISIS MPLS-TE: Show database TE detail"); - - tlvh = (struct subtlv_header *)te->sub_tlvs; - - for (; sum < te->sub_tlvs_length; tlvh = SUBTLV_HDR_NEXT (tlvh)) - { - switch (tlvh->type) - { - case TE_SUBTLV_ADMIN_GRP: - sum += show_vty_subtlv_admin_grp (vty, (struct te_subtlv_admin_grp *)tlvh); - break; - case TE_SUBTLV_LLRI: - sum += show_vty_subtlv_llri (vty, (struct te_subtlv_llri *)tlvh); - break; - case TE_SUBTLV_LOCAL_IPADDR: - sum += show_vty_subtlv_local_ipaddr (vty, (struct te_subtlv_local_ipaddr *)tlvh); - break; - case TE_SUBTLV_RMT_IPADDR: - sum += show_vty_subtlv_rmt_ipaddr (vty, (struct te_subtlv_rmt_ipaddr *)tlvh); - break; - case TE_SUBTLV_MAX_BW: - sum += show_vty_subtlv_max_bw (vty, (struct te_subtlv_max_bw *)tlvh); - break; - case TE_SUBTLV_MAX_RSV_BW: - sum += show_vty_subtlv_max_rsv_bw (vty, (struct te_subtlv_max_rsv_bw *)tlvh); - break; - case TE_SUBTLV_UNRSV_BW: - sum += show_vty_subtlv_unrsv_bw (vty, (struct te_subtlv_unrsv_bw *)tlvh); - break; - case TE_SUBTLV_TE_METRIC: - sum += show_vty_subtlv_te_metric (vty, (struct te_subtlv_te_metric *)tlvh); - break; - case TE_SUBTLV_RAS: - sum += show_vty_subtlv_ras (vty, (struct te_subtlv_ras *)tlvh); - break; - case TE_SUBTLV_RIP: - sum += show_vty_subtlv_rip (vty, (struct te_subtlv_rip *)tlvh); - break; - case TE_SUBTLV_AV_DELAY: - sum += show_vty_subtlv_av_delay (vty, (struct te_subtlv_av_delay *)tlvh); - break; - case TE_SUBTLV_MM_DELAY: - sum += show_vty_subtlv_mm_delay (vty, (struct te_subtlv_mm_delay *)tlvh); - break; - case TE_SUBTLV_DELAY_VAR: - sum += show_vty_subtlv_delay_var (vty, (struct te_subtlv_delay_var *)tlvh); - break; - case TE_SUBTLV_PKT_LOSS: - sum += show_vty_subtlv_pkt_loss (vty, (struct te_subtlv_pkt_loss *)tlvh); - break; - case TE_SUBTLV_RES_BW: - sum += show_vty_subtlv_res_bw (vty, (struct te_subtlv_res_bw *)tlvh); - break; - case TE_SUBTLV_AVA_BW: - sum += show_vty_subtlv_ava_bw (vty, (struct te_subtlv_ava_bw *)tlvh); - break; - case TE_SUBTLV_USE_BW: - sum += show_vty_subtlv_use_bw (vty, (struct te_subtlv_use_bw *)tlvh); - break; - default: - sum += show_vty_unknown_tlv (vty, tlvh); - break; - } - } - return; + struct subtlv_header *tlvh; + u_int16_t sum = 0; + + zlog_debug("ISIS MPLS-TE: Show database TE detail"); + + tlvh = (struct subtlv_header *)te->sub_tlvs; + + for (; sum < te->sub_tlvs_length; tlvh = SUBTLV_HDR_NEXT(tlvh)) { + switch (tlvh->type) { + case TE_SUBTLV_ADMIN_GRP: + sum += show_vty_subtlv_admin_grp( + vty, (struct te_subtlv_admin_grp *)tlvh); + break; + case TE_SUBTLV_LLRI: + sum += show_vty_subtlv_llri( + vty, (struct te_subtlv_llri *)tlvh); + break; + case TE_SUBTLV_LOCAL_IPADDR: + sum += show_vty_subtlv_local_ipaddr( + vty, (struct te_subtlv_local_ipaddr *)tlvh); + break; + case TE_SUBTLV_RMT_IPADDR: + sum += show_vty_subtlv_rmt_ipaddr( + vty, (struct te_subtlv_rmt_ipaddr *)tlvh); + break; + case TE_SUBTLV_MAX_BW: + sum += show_vty_subtlv_max_bw( + vty, (struct te_subtlv_max_bw *)tlvh); + break; + case TE_SUBTLV_MAX_RSV_BW: + sum += show_vty_subtlv_max_rsv_bw( + vty, (struct te_subtlv_max_rsv_bw *)tlvh); + break; + case TE_SUBTLV_UNRSV_BW: + sum += show_vty_subtlv_unrsv_bw( + vty, (struct te_subtlv_unrsv_bw *)tlvh); + break; + case TE_SUBTLV_TE_METRIC: + sum += show_vty_subtlv_te_metric( + vty, (struct te_subtlv_te_metric *)tlvh); + break; + case TE_SUBTLV_RAS: + sum += show_vty_subtlv_ras( + vty, (struct te_subtlv_ras *)tlvh); + break; + case TE_SUBTLV_RIP: + sum += show_vty_subtlv_rip( + vty, (struct te_subtlv_rip *)tlvh); + break; + case TE_SUBTLV_AV_DELAY: + sum += show_vty_subtlv_av_delay( + vty, (struct te_subtlv_av_delay *)tlvh); + break; + case TE_SUBTLV_MM_DELAY: + sum += show_vty_subtlv_mm_delay( + vty, (struct te_subtlv_mm_delay *)tlvh); + break; + case TE_SUBTLV_DELAY_VAR: + sum += show_vty_subtlv_delay_var( + vty, (struct te_subtlv_delay_var *)tlvh); + break; + case TE_SUBTLV_PKT_LOSS: + sum += show_vty_subtlv_pkt_loss( + vty, (struct te_subtlv_pkt_loss *)tlvh); + break; + case TE_SUBTLV_RES_BW: + sum += show_vty_subtlv_res_bw( + vty, (struct te_subtlv_res_bw *)tlvh); + break; + case TE_SUBTLV_AVA_BW: + sum += show_vty_subtlv_ava_bw( + vty, (struct te_subtlv_ava_bw *)tlvh); + break; + case TE_SUBTLV_USE_BW: + sum += show_vty_subtlv_use_bw( + vty, (struct te_subtlv_use_bw *)tlvh); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return; } /* Specific MPLS TE router parameters write function */ -void -isis_mpls_te_config_write_router (struct vty *vty) +void isis_mpls_te_config_write_router(struct vty *vty) { - if (IS_MPLS_TE(isisMplsTE)) - { - vty_out (vty, " mpls-te on\n"); - vty_out (vty, " mpls-te router-address %s\n", - inet_ntoa(isisMplsTE.router_id)); - } - - return; + if (IS_MPLS_TE(isisMplsTE)) { + vty_out(vty, " mpls-te on\n"); + vty_out(vty, " mpls-te router-address %s\n", + inet_ntoa(isisMplsTE.router_id)); + } + + return; } @@ -1088,41 +1102,42 @@ DEFUN (isis_mpls_te_on, MPLS_TE_STR "Enable MPLS-TE functionality\n") { - struct listnode *node; - struct isis_circuit *circuit; - - if (IS_MPLS_TE(isisMplsTE)) - return CMD_SUCCESS; - - if (IS_DEBUG_ISIS(DEBUG_TE)) - zlog_debug ("ISIS MPLS-TE: OFF -> ON"); - - isisMplsTE.status = enable; - - /* - * Following code is intended to handle two cases; - * - * 1) MPLS-TE was disabled at startup time, but now become enabled. - * In this case, we must enable MPLS-TE Circuit regarding interface MPLS_TE flag - * 2) MPLS-TE was once enabled then disabled, and now enabled again. - */ - for (ALL_LIST_ELEMENTS_RO (isisMplsTE.cir_list, node, circuit)) - { - if (circuit->mtc == NULL || IS_FLOOD_AS (circuit->mtc->type)) - continue; - - if ((circuit->mtc->status == disable) - && HAS_LINK_PARAMS(circuit->interface)) - circuit->mtc->status = enable; - else - continue; - - /* Reoriginate STD_TE & GMPLS circuits */ - if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); - } - - return CMD_SUCCESS; + struct listnode *node; + struct isis_circuit *circuit; + + if (IS_MPLS_TE(isisMplsTE)) + return CMD_SUCCESS; + + if (IS_DEBUG_ISIS(DEBUG_TE)) + zlog_debug("ISIS MPLS-TE: OFF -> ON"); + + isisMplsTE.status = enable; + + /* + * Following code is intended to handle two cases; + * + * 1) MPLS-TE was disabled at startup time, but now become enabled. + * In this case, we must enable MPLS-TE Circuit regarding interface + * MPLS_TE flag + * 2) MPLS-TE was once enabled then disabled, and now enabled again. + */ + for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) { + if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type)) + continue; + + if ((circuit->mtc->status == disable) + && HAS_LINK_PARAMS(circuit->interface)) + circuit->mtc->status = enable; + else + continue; + + /* Reoriginate STD_TE & GMPLS circuits */ + if (circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, + 0); + } + + return CMD_SUCCESS; } DEFUN (no_isis_mpls_te_on, @@ -1131,32 +1146,32 @@ DEFUN (no_isis_mpls_te_on, NO_STR "Disable the MPLS-TE functionality\n") { - struct listnode *node; - struct isis_circuit *circuit; + struct listnode *node; + struct isis_circuit *circuit; - if (isisMplsTE.status == disable) - return CMD_SUCCESS; + if (isisMplsTE.status == disable) + return CMD_SUCCESS; - if (IS_DEBUG_ISIS(DEBUG_TE)) - zlog_debug ("ISIS MPLS-TE: ON -> OFF"); + if (IS_DEBUG_ISIS(DEBUG_TE)) + zlog_debug("ISIS MPLS-TE: ON -> OFF"); - isisMplsTE.status = disable; + isisMplsTE.status = disable; - /* Flush LSP if circuit engage */ - for (ALL_LIST_ELEMENTS_RO (isisMplsTE.cir_list, node, circuit)) - { - if (circuit->mtc == NULL || (circuit->mtc->status == disable)) - continue; + /* Flush LSP if circuit engage */ + for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) { + if (circuit->mtc == NULL || (circuit->mtc->status == disable)) + continue; - /* disable MPLS_TE Circuit */ - circuit->mtc->status = disable; + /* disable MPLS_TE Circuit */ + circuit->mtc->status = disable; - /* Re-originate circuit without STD_TE & GMPLS parameters */ - if (circuit->area) - lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); - } + /* Re-originate circuit without STD_TE & GMPLS parameters */ + if (circuit->area) + lsp_regenerate_schedule(circuit->area, circuit->is_type, + 0); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (isis_mpls_te_router_addr, @@ -1166,30 +1181,29 @@ DEFUN (isis_mpls_te_router_addr, "Stable IP address of the advertising router\n" "MPLS-TE router address in IPv4 address format\n") { - int idx_ipv4 = 2; - struct in_addr value; - struct listnode *node; - struct isis_area *area; - - if (! inet_aton (argv[idx_ipv4]->arg, &value)) - { - vty_out (vty, "Please specify Router-Addr by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - isisMplsTE.router_id.s_addr = value.s_addr; - - if (isisMplsTE.status == disable) - return CMD_SUCCESS; - - /* Update main Router ID in isis global structure */ - isis->router_id = value.s_addr; - /* And re-schedule LSP update */ - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - if (listcount (area->area_addrs) > 0) - lsp_regenerate_schedule (area, area->is_type, 0); - - return CMD_SUCCESS; + int idx_ipv4 = 2; + struct in_addr value; + struct listnode *node; + struct isis_area *area; + + if (!inet_aton(argv[idx_ipv4]->arg, &value)) { + vty_out(vty, "Please specify Router-Addr by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + isisMplsTE.router_id.s_addr = value.s_addr; + + if (isisMplsTE.status == disable) + return CMD_SUCCESS; + + /* Update main Router ID in isis global structure */ + isis->router_id = value.s_addr; + /* And re-schedule LSP update */ + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + if (listcount(area->area_addrs) > 0) + lsp_regenerate_schedule(area, area->is_type, 0); + + return CMD_SUCCESS; } DEFUN (isis_mpls_te_inter_as, @@ -1201,8 +1215,8 @@ DEFUN (isis_mpls_te_inter_as, "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n" "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n") { - vty_out (vty, "Not yet supported\n"); - return CMD_SUCCESS; + vty_out(vty, "Not yet supported\n"); + return CMD_SUCCESS; } DEFUN (no_isis_mpls_te_inter_as, @@ -1213,8 +1227,8 @@ DEFUN (no_isis_mpls_te_inter_as, "Disable MPLS-TE Inter-AS support\n") { - vty_out (vty, "Not yet supported\n"); - return CMD_SUCCESS; + vty_out(vty, "Not yet supported\n"); + return CMD_SUCCESS; } DEFUN (show_isis_mpls_te_router, @@ -1225,89 +1239,80 @@ DEFUN (show_isis_mpls_te_router, MPLS_TE_STR "Router information\n") { - if (IS_MPLS_TE(isisMplsTE)) - { - vty_out (vty, "--- MPLS-TE router parameters ---\n"); - - if (ntohs (isisMplsTE.router_id.s_addr) != 0) - vty_out (vty, " Router-Address: %s\n", - inet_ntoa(isisMplsTE.router_id)); - else - vty_out (vty, " N/A\n"); - } - else - vty_out (vty, " MPLS-TE is disable on this router\n"); - - return CMD_SUCCESS; + if (IS_MPLS_TE(isisMplsTE)) { + vty_out(vty, "--- MPLS-TE router parameters ---\n"); + + if (ntohs(isisMplsTE.router_id.s_addr) != 0) + vty_out(vty, " Router-Address: %s\n", + inet_ntoa(isisMplsTE.router_id)); + else + vty_out(vty, " N/A\n"); + } else + vty_out(vty, " MPLS-TE is disable on this router\n"); + + return CMD_SUCCESS; } -static void -show_mpls_te_sub (struct vty *vty, struct interface *ifp) +static void show_mpls_te_sub(struct vty *vty, struct interface *ifp) { - struct mpls_te_circuit *mtc; - - if ((IS_MPLS_TE(isisMplsTE)) - && ((mtc = lookup_mpls_params_by_ifp (ifp)) != NULL)) - { - /* Continue only if interface is not passive or support Inter-AS TEv2 */ - if (mtc->status != enable) - { - if (IS_INTER_AS(mtc->type)) - { - vty_out (vty, "-- Inter-AS TEv2 link parameters for %s --\n", - ifp->name); - } - else - { - /* MPLS-TE is not activate on this interface */ - /* or this interface is passive and Inter-AS TEv2 is not activate */ - vty_out (vty, " %s: MPLS-TE is disabled on this interface\n", - ifp->name); - return; - } - } - else - { - vty_out (vty, "-- MPLS-TE link parameters for %s --\n", - ifp->name); - } - - show_vty_subtlv_admin_grp (vty, &mtc->admin_grp); - - if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) - show_vty_subtlv_local_ipaddr (vty, &mtc->local_ipaddr); - if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) - show_vty_subtlv_rmt_ipaddr (vty, &mtc->rmt_ipaddr); - - show_vty_subtlv_max_bw (vty, &mtc->max_bw); - show_vty_subtlv_max_rsv_bw (vty, &mtc->max_rsv_bw); - show_vty_subtlv_unrsv_bw (vty, &mtc->unrsv_bw); - show_vty_subtlv_te_metric (vty, &mtc->te_metric); - - if (IS_INTER_AS(mtc->type)) - { - if (SUBTLV_TYPE(mtc->ras) != 0) - show_vty_subtlv_ras (vty, &mtc->ras); - if (SUBTLV_TYPE(mtc->rip) != 0) - show_vty_subtlv_rip (vty, &mtc->rip); - } - - show_vty_subtlv_av_delay (vty, &mtc->av_delay); - show_vty_subtlv_mm_delay (vty, &mtc->mm_delay); - show_vty_subtlv_delay_var (vty, &mtc->delay_var); - show_vty_subtlv_pkt_loss (vty, &mtc->pkt_loss); - show_vty_subtlv_res_bw (vty, &mtc->res_bw); - show_vty_subtlv_ava_bw (vty, &mtc->ava_bw); - show_vty_subtlv_use_bw (vty, &mtc->use_bw); - vty_out (vty, "---------------\n\n"); - } - else - { - vty_out (vty, " %s: MPLS-TE is disabled on this interface\n", - ifp->name); - } - - return; + struct mpls_te_circuit *mtc; + + if ((IS_MPLS_TE(isisMplsTE)) + && ((mtc = lookup_mpls_params_by_ifp(ifp)) != NULL)) { + /* Continue only if interface is not passive or support Inter-AS + * TEv2 */ + if (mtc->status != enable) { + if (IS_INTER_AS(mtc->type)) { + vty_out(vty, + "-- Inter-AS TEv2 link parameters for %s --\n", + ifp->name); + } else { + /* MPLS-TE is not activate on this interface */ + /* or this interface is passive and Inter-AS + * TEv2 is not activate */ + vty_out(vty, + " %s: MPLS-TE is disabled on this interface\n", + ifp->name); + return; + } + } else { + vty_out(vty, "-- MPLS-TE link parameters for %s --\n", + ifp->name); + } + + show_vty_subtlv_admin_grp(vty, &mtc->admin_grp); + + if (SUBTLV_TYPE(mtc->local_ipaddr) != 0) + show_vty_subtlv_local_ipaddr(vty, &mtc->local_ipaddr); + if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0) + show_vty_subtlv_rmt_ipaddr(vty, &mtc->rmt_ipaddr); + + show_vty_subtlv_max_bw(vty, &mtc->max_bw); + show_vty_subtlv_max_rsv_bw(vty, &mtc->max_rsv_bw); + show_vty_subtlv_unrsv_bw(vty, &mtc->unrsv_bw); + show_vty_subtlv_te_metric(vty, &mtc->te_metric); + + if (IS_INTER_AS(mtc->type)) { + if (SUBTLV_TYPE(mtc->ras) != 0) + show_vty_subtlv_ras(vty, &mtc->ras); + if (SUBTLV_TYPE(mtc->rip) != 0) + show_vty_subtlv_rip(vty, &mtc->rip); + } + + show_vty_subtlv_av_delay(vty, &mtc->av_delay); + show_vty_subtlv_mm_delay(vty, &mtc->mm_delay); + show_vty_subtlv_delay_var(vty, &mtc->delay_var); + show_vty_subtlv_pkt_loss(vty, &mtc->pkt_loss); + show_vty_subtlv_res_bw(vty, &mtc->res_bw); + show_vty_subtlv_ava_bw(vty, &mtc->ava_bw); + show_vty_subtlv_use_bw(vty, &mtc->use_bw); + vty_out(vty, "---------------\n\n"); + } else { + vty_out(vty, " %s: MPLS-TE is disabled on this interface\n", + ifp->name); + } + + return; } DEFUN (show_isis_mpls_te_interface, @@ -1319,52 +1324,51 @@ DEFUN (show_isis_mpls_te_interface, "Interface information\n" "Interface name\n") { - int idx_interface = 4; - struct interface *ifp; - struct listnode *node; - - /* Show All Interfaces. */ - if (argc == 4) - { - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - show_mpls_te_sub (vty, ifp); - } - /* Interface name is specified. */ - else - { - if ((ifp = if_lookup_by_name (argv[idx_interface]->arg, VRF_DEFAULT)) == NULL) - vty_out (vty, "No such interface name\n"); - else - show_mpls_te_sub (vty, ifp); - } - - return CMD_SUCCESS; + int idx_interface = 4; + struct interface *ifp; + struct listnode *node; + + /* Show All Interfaces. */ + if (argc == 4) { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + show_mpls_te_sub(vty, ifp); + } + /* Interface name is specified. */ + else { + if ((ifp = if_lookup_by_name(argv[idx_interface]->arg, + VRF_DEFAULT)) + == NULL) + vty_out(vty, "No such interface name\n"); + else + show_mpls_te_sub(vty, ifp); + } + + return CMD_SUCCESS; } /* Initialize MPLS_TE */ -void -isis_mpls_te_init (void) +void isis_mpls_te_init(void) { - zlog_debug("ISIS MPLS-TE: Initialize"); + zlog_debug("ISIS MPLS-TE: Initialize"); - /* Initialize MPLS_TE structure */ - isisMplsTE.status = disable; - isisMplsTE.level = 0; - isisMplsTE.inter_as = off; - isisMplsTE.interas_areaid.s_addr = 0; - isisMplsTE.cir_list = list_new(); - isisMplsTE.router_id.s_addr = 0; + /* Initialize MPLS_TE structure */ + isisMplsTE.status = disable; + isisMplsTE.level = 0; + isisMplsTE.inter_as = off; + isisMplsTE.interas_areaid.s_addr = 0; + isisMplsTE.cir_list = list_new(); + isisMplsTE.router_id.s_addr = 0; - /* Register new VTY commands */ - install_element (VIEW_NODE, &show_isis_mpls_te_router_cmd); - install_element (VIEW_NODE, &show_isis_mpls_te_interface_cmd); + /* Register new VTY commands */ + install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd); + install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd); - install_element (ISIS_NODE, &isis_mpls_te_on_cmd); - install_element (ISIS_NODE, &no_isis_mpls_te_on_cmd); - install_element (ISIS_NODE, &isis_mpls_te_router_addr_cmd); - install_element (ISIS_NODE, &isis_mpls_te_inter_as_cmd); - install_element (ISIS_NODE, &no_isis_mpls_te_inter_as_cmd); + install_element(ISIS_NODE, &isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); + install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_inter_as_cmd); - return; + return; } diff --git a/isisd/isis_te.h b/isisd/isis_te.h index 3c99c9085..0bd076af1 100644 --- a/isisd/isis_te.h +++ b/isisd/isis_te.h @@ -76,10 +76,9 @@ * Following section defines subTLV (tag, length, value) structures, * used for Traffic Engineering. */ -struct subtlv_header -{ - u_char type; /* sub_TLV_XXX type (see above) */ - u_char length; /* Value portion only, in byte */ +struct subtlv_header { + u_char type; /* sub_TLV_XXX type (see above) */ + u_char length; /* Value portion only, in byte */ }; #define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */ @@ -99,149 +98,140 @@ struct subtlv_header /* Link Sub-TLV: Resource Class/Color - RFC 5305 */ #define TE_SUBTLV_ADMIN_GRP 3 -struct te_subtlv_admin_grp -{ - struct subtlv_header header; /* Value length is 4 octets. */ - u_int32_t value; /* Admin. group membership. */ +struct te_subtlv_admin_grp { + struct subtlv_header header; /* Value length is 4 octets. */ + u_int32_t value; /* Admin. group membership. */ } __attribute__((__packed__)); /* Link Local/Remote Identifiers - RFC 5307 */ #define TE_SUBTLV_LLRI 4 #define TE_SUBTLV_LLRI_SIZE 8 -struct te_subtlv_llri -{ - struct subtlv_header header; /* Value length is 8 octets. */ - u_int32_t local; /* Link Local Identifier */ - u_int32_t remote; /* Link Remote Identifier */ +struct te_subtlv_llri { + struct subtlv_header header; /* Value length is 8 octets. */ + u_int32_t local; /* Link Local Identifier */ + u_int32_t remote; /* Link Remote Identifier */ } __attribute__((__packed__)); /* Link Sub-TLV: Local Interface IP Address - RFC 5305 */ #define TE_SUBTLV_LOCAL_IPADDR 6 -struct te_subtlv_local_ipaddr -{ - struct subtlv_header header; /* Value length is 4 x N octets. */ - struct in_addr value; /* Local IP address(es). */ +struct te_subtlv_local_ipaddr { + struct subtlv_header header; /* Value length is 4 x N octets. */ + struct in_addr value; /* Local IP address(es). */ } __attribute__((__packed__)); /* Link Sub-TLV: Neighbor Interface IP Address - RFC 5305 */ #define TE_SUBTLV_RMT_IPADDR 8 -struct te_subtlv_rmt_ipaddr -{ - struct subtlv_header header; /* Value length is 4 x N octets. */ - struct in_addr value; /* Neighbor's IP address(es). */ +struct te_subtlv_rmt_ipaddr { + struct subtlv_header header; /* Value length is 4 x N octets. */ + struct in_addr value; /* Neighbor's IP address(es). */ } __attribute__((__packed__)); /* Link Sub-TLV: Maximum Bandwidth - RFC 5305 */ #define TE_SUBTLV_MAX_BW 9 -struct te_subtlv_max_bw -{ - struct subtlv_header header; /* Value length is 4 octets. */ - float value; /* bytes/sec */ +struct te_subtlv_max_bw { + struct subtlv_header header; /* Value length is 4 octets. */ + float value; /* bytes/sec */ } __attribute__((__packed__)); /* Link Sub-TLV: Maximum Reservable Bandwidth - RFC 5305 */ #define TE_SUBTLV_MAX_RSV_BW 10 -struct te_subtlv_max_rsv_bw -{ - struct subtlv_header header; /* Value length is 4 octets. */ - float value; /* bytes/sec */ +struct te_subtlv_max_rsv_bw { + struct subtlv_header header; /* Value length is 4 octets. */ + float value; /* bytes/sec */ } __attribute__((__packed__)); /* Link Sub-TLV: Unreserved Bandwidth - RFC 5305 */ #define TE_SUBTLV_UNRSV_BW 11 #define TE_SUBTLV_UNRSV_SIZE 32 -struct te_subtlv_unrsv_bw -{ - struct subtlv_header header; /* Value length is 32 octets. */ - float value[8]; /* One for each priority level. */ +struct te_subtlv_unrsv_bw { + struct subtlv_header header; /* Value length is 32 octets. */ + float value[8]; /* One for each priority level. */ } __attribute__((__packed__)); /* Link Sub-TLV: Traffic Engineering Metric - RFC 5305 */ #define TE_SUBTLV_TE_METRIC 18 #define TE_SUBTLV_TE_METRIC_SIZE 3 -struct te_subtlv_te_metric -{ - struct subtlv_header header; /* Value length is 4 octets. */ - u_char value[3]; /* Link metric for TE purpose. */ +struct te_subtlv_te_metric { + struct subtlv_header header; /* Value length is 4 octets. */ + u_char value[3]; /* Link metric for TE purpose. */ } __attribute__((__packed__)); /* Remote AS Number sub-TLV - RFC5316 */ #define TE_SUBTLV_RAS 24 -struct te_subtlv_ras -{ - struct subtlv_header header; /* Value length is 4 octets. */ - u_int32_t value; /* Remote AS number */ +struct te_subtlv_ras { + struct subtlv_header header; /* Value length is 4 octets. */ + u_int32_t value; /* Remote AS number */ } __attribute__((__packed__)); /* IPv4 Remote ASBR ID Sub-TLV - RFC5316 */ #define TE_SUBTLV_RIP 25 -struct te_subtlv_rip -{ - struct subtlv_header header; /* Value length is 4 octets. */ - struct in_addr value; /* Remote ASBR IP address */ +struct te_subtlv_rip { + struct subtlv_header header; /* Value length is 4 octets. */ + struct in_addr value; /* Remote ASBR IP address */ } __attribute__((__packed__)); /* TE Metric Extensions - RFC 7810 */ /* Link Sub-TLV: Average Link Delay */ #define TE_SUBTLV_AV_DELAY 33 -struct te_subtlv_av_delay -{ - struct subtlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* Average delay in micro-seconds only 24 bits => 0 ... 16777215 - with Anomalous Bit (A) as Upper most bit */ +struct te_subtlv_av_delay { + struct subtlv_header header; /* Value length is 4 bytes. */ + u_int32_t value; /* Average delay in micro-seconds only 24 bits => 0 ... + 16777215 + with Anomalous Bit (A) as Upper most bit */ } __attribute__((__packed__)); /* Link Sub-TLV: Low/High Link Delay */ #define TE_SUBTLV_MM_DELAY 34 #define TE_SUBTLV_MM_DELAY_SIZE 8 -struct te_subtlv_mm_delay -{ - struct subtlv_header header; /* Value length is 8 bytes. */ - u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215 - with Anomalous Bit (A) as Upper most bit */ - u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */ +struct te_subtlv_mm_delay { + struct subtlv_header header; /* Value length is 8 bytes. */ + u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... + 16777215 + with Anomalous Bit (A) as Upper most bit */ + u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... + 16777215 */ } __attribute__((__packed__)); /* Link Sub-TLV: Link Delay Variation i.e. Jitter */ #define TE_SUBTLV_DELAY_VAR 35 -struct te_subtlv_delay_var -{ - struct subtlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... 16777215 */ +struct te_subtlv_delay_var { + struct subtlv_header header; /* Value length is 4 bytes. */ + u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... + 16777215 */ } __attribute__((__packed__)); /* Link Sub-TLV: Routine Unidirectional Link Packet Loss */ #define TE_SUBTLV_PKT_LOSS 36 -struct te_subtlv_pkt_loss -{ - struct subtlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* in percentage of total traffic only 24 bits (2^24 - 2) - with Anomalous Bit (A) as Upper most bit */ +struct te_subtlv_pkt_loss { + struct subtlv_header header; /* Value length is 4 bytes. */ + u_int32_t + value; /* in percentage of total traffic only 24 bits (2^24 - 2) + with Anomalous Bit (A) as Upper most bit */ } __attribute__((__packed__)); /* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */ #define TE_SUBTLV_RES_BW 37 -struct te_subtlv_res_bw -{ - struct subtlv_header header; /* Value length is 4 bytes. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_subtlv_res_bw { + struct subtlv_header header; /* Value length is 4 bytes. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ } __attribute__((__packed__)); /* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */ #define TE_SUBTLV_AVA_BW 38 -struct te_subtlv_ava_bw -{ - struct subtlv_header header; /* Value length is 4 octets. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_subtlv_ava_bw { + struct subtlv_header header; /* Value length is 4 octets. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ } __attribute__((__packed__)); /* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */ #define TE_SUBTLV_USE_BW 39 -struct te_subtlv_use_bw -{ - struct subtlv_header header; /* Value length is 4 octets. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_subtlv_use_bw { + struct subtlv_header header; /* Value length is 4 octets. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ } __attribute__((__packed__)); #define TE_SUBTLV_MAX 40 /* Last SUBTLV + 1 */ @@ -256,75 +246,74 @@ typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t; #define IS_CIRCUIT_TE(c) (c->status == enable) /* Following structure are internal use only. */ -struct isis_mpls_te -{ - /* Status of MPLS-TE: enable or disable */ - status_t status; +struct isis_mpls_te { + /* Status of MPLS-TE: enable or disable */ + status_t status; - /* L1, L1-L2, L2-Only */ - u_int8_t level; + /* L1, L1-L2, L2-Only */ + u_int8_t level; - /* RFC5316 */ - interas_mode_t inter_as; - struct in_addr interas_areaid; + /* RFC5316 */ + interas_mode_t inter_as; + struct in_addr interas_areaid; - /* Circuit list on which TE are enable */ - struct list *cir_list; + /* Circuit list on which TE are enable */ + struct list *cir_list; - /* MPLS_TE router ID */ - struct in_addr router_id; + /* MPLS_TE router ID */ + struct in_addr router_id; }; extern struct isis_mpls_te isisMplsTE; -struct mpls_te_circuit -{ - - /* Status of MPLS-TE on this interface */ - status_t status; - - /* Type of MPLS-TE circuit: STD_TE(RFC5305), INTER_AS(RFC5316), INTER_AS_EMU(RFC5316 emulated) */ - u_int8_t type; - - /* Total size of sub_tlvs */ - u_char length; - - /* Store subTLV in network byte order. */ - /* RFC5305 */ - struct te_subtlv_admin_grp admin_grp; - /* RFC5307 */ - struct te_subtlv_llri llri; - /* RFC5305 */ - struct te_subtlv_local_ipaddr local_ipaddr; - struct te_subtlv_rmt_ipaddr rmt_ipaddr; - struct te_subtlv_max_bw max_bw; - struct te_subtlv_max_rsv_bw max_rsv_bw; - struct te_subtlv_unrsv_bw unrsv_bw; - struct te_subtlv_te_metric te_metric; - /* RFC5316 */ - struct te_subtlv_ras ras; - struct te_subtlv_rip rip; - /* RFC7810 */ - struct te_subtlv_av_delay av_delay; - struct te_subtlv_mm_delay mm_delay; - struct te_subtlv_delay_var delay_var; - struct te_subtlv_pkt_loss pkt_loss; - struct te_subtlv_res_bw res_bw; - struct te_subtlv_ava_bw ava_bw; - struct te_subtlv_use_bw use_bw; +struct mpls_te_circuit { + + /* Status of MPLS-TE on this interface */ + status_t status; + + /* Type of MPLS-TE circuit: STD_TE(RFC5305), INTER_AS(RFC5316), + * INTER_AS_EMU(RFC5316 emulated) */ + u_int8_t type; + + /* Total size of sub_tlvs */ + u_char length; + + /* Store subTLV in network byte order. */ + /* RFC5305 */ + struct te_subtlv_admin_grp admin_grp; + /* RFC5307 */ + struct te_subtlv_llri llri; + /* RFC5305 */ + struct te_subtlv_local_ipaddr local_ipaddr; + struct te_subtlv_rmt_ipaddr rmt_ipaddr; + struct te_subtlv_max_bw max_bw; + struct te_subtlv_max_rsv_bw max_rsv_bw; + struct te_subtlv_unrsv_bw unrsv_bw; + struct te_subtlv_te_metric te_metric; + /* RFC5316 */ + struct te_subtlv_ras ras; + struct te_subtlv_rip rip; + /* RFC7810 */ + struct te_subtlv_av_delay av_delay; + struct te_subtlv_mm_delay mm_delay; + struct te_subtlv_delay_var delay_var; + struct te_subtlv_pkt_loss pkt_loss; + struct te_subtlv_res_bw res_bw; + struct te_subtlv_ava_bw ava_bw; + struct te_subtlv_use_bw use_bw; }; /* Prototypes. */ -void isis_mpls_te_init (void); +void isis_mpls_te_init(void); struct mpls_te_circuit *mpls_te_circuit_new(void); void mpls_te_print_detail(struct vty *, struct te_is_neigh *); -void set_circuitparams_local_ipaddr (struct mpls_te_circuit *, struct in_addr); -void set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *, struct in_addr); -u_char subtlvs_len (struct mpls_te_circuit *); +void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr); +void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr); +u_char subtlvs_len(struct mpls_te_circuit *); u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *); u_char build_te_subtlvs(u_char *, struct isis_circuit *); void isis_link_params_update(struct isis_circuit *, struct interface *); void isis_mpls_te_update(struct interface *); -void isis_mpls_te_config_write_router (struct vty *); +void isis_mpls_te_config_write_router(struct vty *); #endif /* _ZEBRA_ISIS_MPLS_TE_H */ diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c index 7ffa7509c..a295f4dd3 100644 --- a/isisd/isis_tlv.c +++ b/isisd/isis_tlv.c @@ -3,17 +3,17 @@ * IS-IS TLV related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -45,1461 +45,1409 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" -void -free_tlv (void *val) +void free_tlv(void *val) { - XFREE (MTYPE_ISIS_TLV, val); + XFREE(MTYPE_ISIS_TLV, val); - return; + return; } /* * Called after parsing of a PDU. There shouldn't be any tlv's left, so this * is only a caution to avoid memory leaks */ -void -free_tlvs (struct tlvs *tlvs) +void free_tlvs(struct tlvs *tlvs) { - if (tlvs->area_addrs) - list_delete (tlvs->area_addrs); - if (tlvs->mt_router_info) - list_delete (tlvs->mt_router_info); - if (tlvs->is_neighs) - list_delete (tlvs->is_neighs); - if (tlvs->te_is_neighs) - list_delete (tlvs->te_is_neighs); - if (tlvs->mt_is_neighs) - list_delete (tlvs->mt_is_neighs); - if (tlvs->es_neighs) - list_delete (tlvs->es_neighs); - if (tlvs->lsp_entries) - list_delete (tlvs->lsp_entries); - if (tlvs->prefix_neighs) - list_delete (tlvs->prefix_neighs); - if (tlvs->lan_neighs) - list_delete (tlvs->lan_neighs); - if (tlvs->ipv4_addrs) - list_delete (tlvs->ipv4_addrs); - if (tlvs->ipv4_int_reachs) - list_delete (tlvs->ipv4_int_reachs); - if (tlvs->ipv4_ext_reachs) - list_delete (tlvs->ipv4_ext_reachs); - if (tlvs->te_ipv4_reachs) - list_delete (tlvs->te_ipv4_reachs); - if (tlvs->mt_ipv4_reachs) - list_delete (tlvs->mt_ipv4_reachs); - if (tlvs->ipv6_addrs) - list_delete (tlvs->ipv6_addrs); - if (tlvs->ipv6_reachs) - list_delete (tlvs->ipv6_reachs); - if (tlvs->mt_ipv6_reachs) - list_delete (tlvs->mt_ipv6_reachs); - - memset (tlvs, 0, sizeof (struct tlvs)); - - return; + if (tlvs->area_addrs) + list_delete(tlvs->area_addrs); + if (tlvs->mt_router_info) + list_delete(tlvs->mt_router_info); + if (tlvs->is_neighs) + list_delete(tlvs->is_neighs); + if (tlvs->te_is_neighs) + list_delete(tlvs->te_is_neighs); + if (tlvs->mt_is_neighs) + list_delete(tlvs->mt_is_neighs); + if (tlvs->es_neighs) + list_delete(tlvs->es_neighs); + if (tlvs->lsp_entries) + list_delete(tlvs->lsp_entries); + if (tlvs->prefix_neighs) + list_delete(tlvs->prefix_neighs); + if (tlvs->lan_neighs) + list_delete(tlvs->lan_neighs); + if (tlvs->ipv4_addrs) + list_delete(tlvs->ipv4_addrs); + if (tlvs->ipv4_int_reachs) + list_delete(tlvs->ipv4_int_reachs); + if (tlvs->ipv4_ext_reachs) + list_delete(tlvs->ipv4_ext_reachs); + if (tlvs->te_ipv4_reachs) + list_delete(tlvs->te_ipv4_reachs); + if (tlvs->mt_ipv4_reachs) + list_delete(tlvs->mt_ipv4_reachs); + if (tlvs->ipv6_addrs) + list_delete(tlvs->ipv6_addrs); + if (tlvs->ipv6_reachs) + list_delete(tlvs->ipv6_reachs); + if (tlvs->mt_ipv6_reachs) + list_delete(tlvs->mt_ipv6_reachs); + + memset(tlvs, 0, sizeof(struct tlvs)); + + return; } -static int -parse_mtid(uint16_t *mtid, bool read_mtid, - unsigned int *length, u_char **pnt) +static int parse_mtid(uint16_t *mtid, bool read_mtid, unsigned int *length, + u_char **pnt) { - if (!read_mtid) - { - *mtid = ISIS_MT_IPV4_UNICAST; - return ISIS_OK; - } - - uint16_t mtid_buf; - - if (*length < sizeof(mtid_buf)) - { - zlog_warn("ISIS-TLV: mt tlv too short to contain MT id"); - return ISIS_WARNING; - } - - memcpy(&mtid_buf, *pnt, sizeof(mtid_buf)); - *pnt += sizeof(mtid_buf); - *length -= sizeof(mtid_buf); - - *mtid = ntohs(mtid_buf) & ISIS_MT_MASK; - return ISIS_OK; + if (!read_mtid) { + *mtid = ISIS_MT_IPV4_UNICAST; + return ISIS_OK; + } + + uint16_t mtid_buf; + + if (*length < sizeof(mtid_buf)) { + zlog_warn("ISIS-TLV: mt tlv too short to contain MT id"); + return ISIS_WARNING; + } + + memcpy(&mtid_buf, *pnt, sizeof(mtid_buf)); + *pnt += sizeof(mtid_buf); + *length -= sizeof(mtid_buf); + + *mtid = ntohs(mtid_buf) & ISIS_MT_MASK; + return ISIS_OK; } -static int -parse_mt_is_neighs(struct tlvs *tlvs, bool read_mtid, - unsigned int length, u_char *pnt) +static int parse_mt_is_neighs(struct tlvs *tlvs, bool read_mtid, + unsigned int length, u_char *pnt) { - struct list *neigh_list; - uint16_t mtid; - int rv; - - rv = parse_mtid(&mtid, read_mtid, &length, &pnt); - if (rv != ISIS_OK) - return rv; - - if (mtid == ISIS_MT_IPV4_UNICAST) - { - if (!tlvs->te_is_neighs) - { - tlvs->te_is_neighs = list_new(); - tlvs->te_is_neighs->del = free_tlv; - } - neigh_list = tlvs->te_is_neighs; - } - else - { - struct tlv_mt_neighbors *neighbors; - - neighbors = tlvs_get_mt_neighbors(tlvs, mtid); - neighbors->list->del = free_tlv; - neigh_list = neighbors->list; - } - - while (length >= IS_NEIGHBOURS_LEN) - { - struct te_is_neigh *neigh = XCALLOC(MTYPE_ISIS_TLV, sizeof(*neigh)); - - memcpy(neigh, pnt, IS_NEIGHBOURS_LEN); - pnt += IS_NEIGHBOURS_LEN; - length -= IS_NEIGHBOURS_LEN; - - if (neigh->sub_tlvs_length > length) - { - zlog_warn("ISIS-TLV: neighbor subtlv length exceeds TLV size"); - XFREE(MTYPE_ISIS_TLV, neigh); - return ISIS_WARNING; - } - - memcpy(neigh->sub_tlvs, pnt, neigh->sub_tlvs_length); - pnt += neigh->sub_tlvs_length; - length -= neigh->sub_tlvs_length; - - listnode_add(neigh_list, neigh); - } - - if (length) - { - zlog_warn("ISIS-TLV: TE/MT neighor TLV has trailing data"); - return ISIS_WARNING; - } - - return ISIS_OK; + struct list *neigh_list; + uint16_t mtid; + int rv; + + rv = parse_mtid(&mtid, read_mtid, &length, &pnt); + if (rv != ISIS_OK) + return rv; + + if (mtid == ISIS_MT_IPV4_UNICAST) { + if (!tlvs->te_is_neighs) { + tlvs->te_is_neighs = list_new(); + tlvs->te_is_neighs->del = free_tlv; + } + neigh_list = tlvs->te_is_neighs; + } else { + struct tlv_mt_neighbors *neighbors; + + neighbors = tlvs_get_mt_neighbors(tlvs, mtid); + neighbors->list->del = free_tlv; + neigh_list = neighbors->list; + } + + while (length >= IS_NEIGHBOURS_LEN) { + struct te_is_neigh *neigh = + XCALLOC(MTYPE_ISIS_TLV, sizeof(*neigh)); + + memcpy(neigh, pnt, IS_NEIGHBOURS_LEN); + pnt += IS_NEIGHBOURS_LEN; + length -= IS_NEIGHBOURS_LEN; + + if (neigh->sub_tlvs_length > length) { + zlog_warn( + "ISIS-TLV: neighbor subtlv length exceeds TLV size"); + XFREE(MTYPE_ISIS_TLV, neigh); + return ISIS_WARNING; + } + + memcpy(neigh->sub_tlvs, pnt, neigh->sub_tlvs_length); + pnt += neigh->sub_tlvs_length; + length -= neigh->sub_tlvs_length; + + listnode_add(neigh_list, neigh); + } + + if (length) { + zlog_warn("ISIS-TLV: TE/MT neighor TLV has trailing data"); + return ISIS_WARNING; + } + + return ISIS_OK; } -static int -parse_mt_ipv4_reachs(struct tlvs *tlvs, bool read_mtid, - unsigned int length, u_char *pnt) +static int parse_mt_ipv4_reachs(struct tlvs *tlvs, bool read_mtid, + unsigned int length, u_char *pnt) { - struct list *reach_list; - uint16_t mtid; - int rv; - - rv = parse_mtid(&mtid, read_mtid, &length, &pnt); - if (rv != ISIS_OK) - return rv; - - if (mtid == ISIS_MT_IPV4_UNICAST) - { - if (!tlvs->te_ipv4_reachs) - { - tlvs->te_ipv4_reachs = list_new(); - tlvs->te_ipv4_reachs->del = free_tlv; - } - reach_list = tlvs->te_ipv4_reachs; - } - else - { - struct tlv_mt_ipv4_reachs *reachs; - - reachs = tlvs_get_mt_ipv4_reachs(tlvs, mtid); - reachs->list->del = free_tlv; - reach_list = reachs->list; - } - - while (length >= 5) /* Metric + Control */ - { - struct te_ipv4_reachability *reach = XCALLOC(MTYPE_ISIS_TLV, TE_IPV4_REACH_LEN); - - memcpy(reach, pnt, 5); /* Metric + Control */ - pnt += 5; - length -= 5; - - unsigned char prefixlen = reach->control & 0x3F; - - if (prefixlen > IPV4_MAX_BITLEN) - { - zlog_warn("ISIS-TLV: invalid IPv4 extended reachability prefix length %d", prefixlen); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - if (length < (unsigned int)PSIZE(prefixlen)) - { - zlog_warn("ISIS-TLV: invalid IPv4 extended reachability prefix too long for tlv"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - memcpy(&reach->prefix_start, pnt, PSIZE(prefixlen)); - pnt += PSIZE(prefixlen); - length -= PSIZE(prefixlen); - - if (reach->control & TE_IPV4_HAS_SUBTLV) - { - if (length < 1) - { - zlog_warn("ISIS-TLV: invalid IPv4 extended reachability SubTLV missing"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - u_char subtlv_len = *pnt; - pnt++; - length--; - - if (length < subtlv_len) - { - zlog_warn("ISIS-TLV: invalid IPv4 extended reachability SubTLVs have oversize"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - /* Skip Sub-TLVs for now */ - pnt += subtlv_len; - length -= subtlv_len; - } - listnode_add(reach_list, reach); - } - - if (length) - { - zlog_warn("ISIS-TLV: TE/MT ipv4 reachability TLV has trailing data"); - return ISIS_WARNING; - } - - return ISIS_OK; + struct list *reach_list; + uint16_t mtid; + int rv; + + rv = parse_mtid(&mtid, read_mtid, &length, &pnt); + if (rv != ISIS_OK) + return rv; + + if (mtid == ISIS_MT_IPV4_UNICAST) { + if (!tlvs->te_ipv4_reachs) { + tlvs->te_ipv4_reachs = list_new(); + tlvs->te_ipv4_reachs->del = free_tlv; + } + reach_list = tlvs->te_ipv4_reachs; + } else { + struct tlv_mt_ipv4_reachs *reachs; + + reachs = tlvs_get_mt_ipv4_reachs(tlvs, mtid); + reachs->list->del = free_tlv; + reach_list = reachs->list; + } + + while (length >= 5) /* Metric + Control */ + { + struct te_ipv4_reachability *reach = + XCALLOC(MTYPE_ISIS_TLV, TE_IPV4_REACH_LEN); + + memcpy(reach, pnt, 5); /* Metric + Control */ + pnt += 5; + length -= 5; + + unsigned char prefixlen = reach->control & 0x3F; + + if (prefixlen > IPV4_MAX_BITLEN) { + zlog_warn( + "ISIS-TLV: invalid IPv4 extended reachability prefix length %d", + prefixlen); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + if (length < (unsigned int)PSIZE(prefixlen)) { + zlog_warn( + "ISIS-TLV: invalid IPv4 extended reachability prefix too long for tlv"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + memcpy(&reach->prefix_start, pnt, PSIZE(prefixlen)); + pnt += PSIZE(prefixlen); + length -= PSIZE(prefixlen); + + if (reach->control & TE_IPV4_HAS_SUBTLV) { + if (length < 1) { + zlog_warn( + "ISIS-TLV: invalid IPv4 extended reachability SubTLV missing"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + u_char subtlv_len = *pnt; + pnt++; + length--; + + if (length < subtlv_len) { + zlog_warn( + "ISIS-TLV: invalid IPv4 extended reachability SubTLVs have oversize"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + /* Skip Sub-TLVs for now */ + pnt += subtlv_len; + length -= subtlv_len; + } + listnode_add(reach_list, reach); + } + + if (length) { + zlog_warn( + "ISIS-TLV: TE/MT ipv4 reachability TLV has trailing data"); + return ISIS_WARNING; + } + + return ISIS_OK; } -static int -parse_mt_ipv6_reachs(struct tlvs *tlvs, bool read_mtid, - unsigned int length, u_char *pnt) +static int parse_mt_ipv6_reachs(struct tlvs *tlvs, bool read_mtid, + unsigned int length, u_char *pnt) { - struct list *reach_list; - uint16_t mtid; - int rv; - - rv = parse_mtid(&mtid, read_mtid, &length, &pnt); - if (rv != ISIS_OK) - return rv; - - if (mtid == ISIS_MT_IPV4_UNICAST) - { - if (!tlvs->ipv6_reachs) - { - tlvs->ipv6_reachs = list_new(); - tlvs->ipv6_reachs->del = free_tlv; - } - reach_list = tlvs->ipv6_reachs; - } - else - { - struct tlv_mt_ipv6_reachs *reachs; - - reachs = tlvs_get_mt_ipv6_reachs(tlvs, mtid); - reachs->list->del = free_tlv; - reach_list = reachs->list; - } - - while (length >= 6) /* Metric + Control + Prefixlen */ - { - struct ipv6_reachability *reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*reach)); - - memcpy(reach, pnt, 6); /* Metric + Control + Prefixlen */ - pnt += 6; - length -= 6; - - if (reach->prefix_len > IPV6_MAX_BITLEN) - { - zlog_warn("ISIS-TLV: invalid IPv6 reachability prefix length %d", reach->prefix_len); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - if (length < (unsigned int)PSIZE(reach->prefix_len)) - { - zlog_warn("ISIS-TLV: invalid IPv6 reachability prefix too long for tlv"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - memcpy(&reach->prefix, pnt, PSIZE(reach->prefix_len)); - pnt += PSIZE(reach->prefix_len); - length -= PSIZE(reach->prefix_len); - - if (reach->control_info & CTRL_INFO_SUBTLVS) - { - if (length < 1) - { - zlog_warn("ISIS-TLV: invalid IPv6 reachability SubTLV missing"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - u_char subtlv_len = *pnt; - pnt++; - length--; - - if (length < subtlv_len) - { - zlog_warn("ISIS-TLV: invalid IPv6 reachability SubTLVs have oversize"); - XFREE(MTYPE_ISIS_TLV, reach); - return ISIS_WARNING; - } - - /* Skip Sub-TLVs for now */ - pnt += subtlv_len; - length -= subtlv_len; - } - listnode_add(reach_list, reach); - } - - if (length) - { - zlog_warn("ISIS-TLV: (MT) IPv6 reachability TLV has trailing data"); - return ISIS_WARNING; - } - - return ISIS_OK; + struct list *reach_list; + uint16_t mtid; + int rv; + + rv = parse_mtid(&mtid, read_mtid, &length, &pnt); + if (rv != ISIS_OK) + return rv; + + if (mtid == ISIS_MT_IPV4_UNICAST) { + if (!tlvs->ipv6_reachs) { + tlvs->ipv6_reachs = list_new(); + tlvs->ipv6_reachs->del = free_tlv; + } + reach_list = tlvs->ipv6_reachs; + } else { + struct tlv_mt_ipv6_reachs *reachs; + + reachs = tlvs_get_mt_ipv6_reachs(tlvs, mtid); + reachs->list->del = free_tlv; + reach_list = reachs->list; + } + + while (length >= 6) /* Metric + Control + Prefixlen */ + { + struct ipv6_reachability *reach = + XCALLOC(MTYPE_ISIS_TLV, sizeof(*reach)); + + memcpy(reach, pnt, 6); /* Metric + Control + Prefixlen */ + pnt += 6; + length -= 6; + + if (reach->prefix_len > IPV6_MAX_BITLEN) { + zlog_warn( + "ISIS-TLV: invalid IPv6 reachability prefix length %d", + reach->prefix_len); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + if (length < (unsigned int)PSIZE(reach->prefix_len)) { + zlog_warn( + "ISIS-TLV: invalid IPv6 reachability prefix too long for tlv"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + memcpy(&reach->prefix, pnt, PSIZE(reach->prefix_len)); + pnt += PSIZE(reach->prefix_len); + length -= PSIZE(reach->prefix_len); + + if (reach->control_info & CTRL_INFO_SUBTLVS) { + if (length < 1) { + zlog_warn( + "ISIS-TLV: invalid IPv6 reachability SubTLV missing"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + u_char subtlv_len = *pnt; + pnt++; + length--; + + if (length < subtlv_len) { + zlog_warn( + "ISIS-TLV: invalid IPv6 reachability SubTLVs have oversize"); + XFREE(MTYPE_ISIS_TLV, reach); + return ISIS_WARNING; + } + + /* Skip Sub-TLVs for now */ + pnt += subtlv_len; + length -= subtlv_len; + } + listnode_add(reach_list, reach); + } + + if (length) { + zlog_warn( + "ISIS-TLV: (MT) IPv6 reachability TLV has trailing data"); + return ISIS_WARNING; + } + + return ISIS_OK; } /* * Parses the tlvs found in the variant length part of the PDU. * Caller tells with flags in "expected" which TLV's it is interested in. */ -int -parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, - u_int32_t * found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset) +int parse_tlvs(char *areatag, u_char *stream, int size, u_int32_t *expected, + u_int32_t *found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset) { - u_char type, length; - struct lan_neigh *lan_nei; - struct area_addr *area_addr; - struct is_neigh *is_nei; - struct es_neigh *es_nei; - struct lsp_entry *lsp_entry; - struct in_addr *ipv4_addr; - struct ipv4_reachability *ipv4_reach; - struct in6_addr *ipv6_addr; - int value_len, retval = ISIS_OK; - u_char *start = stream, *pnt = stream; - - *found = 0; - memset (tlvs, 0, sizeof (struct tlvs)); - - while (pnt < stream + size - 2) - { - type = *pnt; - length = *(pnt + 1); - pnt += 2; - value_len = 0; - if (pnt + length > stream + size) - { - zlog_warn ("ISIS-TLV (%s): TLV (type %d, length %d) exceeds packet " - "boundaries", areatag, type, length); - retval = ISIS_WARNING; - break; - } - switch (type) - { - case AREA_ADDRESSES: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Address Length | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Area Address | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_AREA_ADDRS; + u_char type, length; + struct lan_neigh *lan_nei; + struct area_addr *area_addr; + struct is_neigh *is_nei; + struct es_neigh *es_nei; + struct lsp_entry *lsp_entry; + struct in_addr *ipv4_addr; + struct ipv4_reachability *ipv4_reach; + struct in6_addr *ipv6_addr; + int value_len, retval = ISIS_OK; + u_char *start = stream, *pnt = stream; + + *found = 0; + memset(tlvs, 0, sizeof(struct tlvs)); + + while (pnt < stream + size - 2) { + type = *pnt; + length = *(pnt + 1); + pnt += 2; + value_len = 0; + if (pnt + length > stream + size) { + zlog_warn( + "ISIS-TLV (%s): TLV (type %d, length %d) exceeds packet " + "boundaries", + areatag, type, length); + retval = ISIS_WARNING; + break; + } + switch (type) { + case AREA_ADDRESSES: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Address Length | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Area Address | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_AREA_ADDRS; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("TLV Area Adresses len %d", length); + zlog_debug("TLV Area Adresses len %d", length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_AREA_ADDRS) - { - while (length > value_len) - { - area_addr = (struct area_addr *) pnt; - value_len += area_addr->addr_len + 1; - pnt += area_addr->addr_len + 1; - if (!tlvs->area_addrs) - tlvs->area_addrs = list_new (); - listnode_add (tlvs->area_addrs, area_addr); - } - } - else - { - pnt += length; - } - break; - - case IS_NEIGHBOURS: - *found |= TLVFLAG_IS_NEIGHS; + if (*expected & TLVFLAG_AREA_ADDRS) { + while (length > value_len) { + area_addr = (struct area_addr *)pnt; + value_len += area_addr->addr_len + 1; + pnt += area_addr->addr_len + 1; + if (!tlvs->area_addrs) + tlvs->area_addrs = list_new(); + listnode_add(tlvs->area_addrs, + area_addr); + } + } else { + pnt += length; + } + break; + + case IS_NEIGHBOURS: + *found |= TLVFLAG_IS_NEIGHS; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IS Neighbours length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): IS Neighbours length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (TLVFLAG_IS_NEIGHS & *expected) - { - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Virtual Flag | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - */ - pnt++; - value_len++; - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | 0 | I/E | Default Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Delay Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Expense Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Error Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Neighbour ID | - * +---------------------------------------------------------------+ - * : : - */ - while (length > value_len) - { - is_nei = (struct is_neigh *) pnt; - value_len += 4 + ISIS_SYS_ID_LEN + 1; - pnt += 4 + ISIS_SYS_ID_LEN + 1; - if (!tlvs->is_neighs) - tlvs->is_neighs = list_new (); - listnode_add (tlvs->is_neighs, is_nei); - } - } - else - { - pnt += length; - } - break; - - case TE_IS_NEIGHBOURS: - *found |= TLVFLAG_TE_IS_NEIGHS; + if (TLVFLAG_IS_NEIGHS & *expected) { + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Virtual Flag | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + */ + pnt++; + value_len++; + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | 0 | I/E | Default + * Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Delay Metric + * | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Expense + * Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Error Metric + * | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Neighbour ID | + * +---------------------------------------------------------------+ + * : : + */ + while (length > value_len) { + is_nei = (struct is_neigh *)pnt; + value_len += 4 + ISIS_SYS_ID_LEN + 1; + pnt += 4 + ISIS_SYS_ID_LEN + 1; + if (!tlvs->is_neighs) + tlvs->is_neighs = list_new(); + listnode_add(tlvs->is_neighs, is_nei); + } + } else { + pnt += length; + } + break; + + case TE_IS_NEIGHBOURS: + *found |= TLVFLAG_TE_IS_NEIGHS; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): Extended IS Neighbours length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): Extended IS Neighbours length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (TLVFLAG_TE_IS_NEIGHS & *expected) - retval = parse_mt_is_neighs(tlvs, false, length, pnt); - pnt += length; - break; - - case MT_IS_NEIGHBOURS: - *found |= TLVFLAG_TE_IS_NEIGHS; + if (TLVFLAG_TE_IS_NEIGHS & *expected) + retval = parse_mt_is_neighs(tlvs, false, length, + pnt); + pnt += length; + break; + + case MT_IS_NEIGHBOURS: + *found |= TLVFLAG_TE_IS_NEIGHS; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): MT IS Neighbours length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): MT IS Neighbours length %d", + areatag, length); #endif - if (TLVFLAG_TE_IS_NEIGHS & *expected) - retval = parse_mt_is_neighs(tlvs, true, length, pnt); - pnt += length; - break; - - case ES_NEIGHBOURS: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | 0 | I/E | Default Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Delay Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Expense Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Error Metric | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Neighbour ID | - * +---------------------------------------------------------------+ - * | Neighbour ID | - * +---------------------------------------------------------------+ - * : : - */ + if (TLVFLAG_TE_IS_NEIGHS & *expected) + retval = parse_mt_is_neighs(tlvs, true, length, + pnt); + pnt += length; + break; + + case ES_NEIGHBOURS: +/* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | 0 | I/E | Default Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Delay Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Expense Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Error Metric | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Neighbour ID | + * +---------------------------------------------------------------+ + * | Neighbour ID | + * +---------------------------------------------------------------+ + * : : + */ #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): ES Neighbours length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): ES Neighbours length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - *found |= TLVFLAG_ES_NEIGHS; - if (*expected & TLVFLAG_ES_NEIGHS) - { - es_nei = (struct es_neigh *) pnt; - value_len += 4; - pnt += 4; - while (length > value_len) - { - /* FIXME FIXME FIXME - add to the list */ - /* sys_id->id = pnt; */ - value_len += ISIS_SYS_ID_LEN; - pnt += ISIS_SYS_ID_LEN; - /* if (!es_nei->neigh_ids) es_nei->neigh_ids = sysid; */ - } - if (!tlvs->es_neighs) - tlvs->es_neighs = list_new (); - listnode_add (tlvs->es_neighs, es_nei); - } - else - { - pnt += length; - } - break; - - case LAN_NEIGHBOURS: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | LAN Address | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_LAN_NEIGHS; + *found |= TLVFLAG_ES_NEIGHS; + if (*expected & TLVFLAG_ES_NEIGHS) { + es_nei = (struct es_neigh *)pnt; + value_len += 4; + pnt += 4; + while (length > value_len) { + /* FIXME FIXME FIXME - add to the list + */ + /* sys_id->id = pnt; */ + value_len += ISIS_SYS_ID_LEN; + pnt += ISIS_SYS_ID_LEN; + /* if (!es_nei->neigh_ids) + * es_nei->neigh_ids = sysid; */ + } + if (!tlvs->es_neighs) + tlvs->es_neighs = list_new(); + listnode_add(tlvs->es_neighs, es_nei); + } else { + pnt += length; + } + break; + + case LAN_NEIGHBOURS: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | LAN Address | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_LAN_NEIGHS; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): LAN Neigbours length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): LAN Neigbours length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (TLVFLAG_LAN_NEIGHS & *expected) - { - while (length > value_len) - { - lan_nei = (struct lan_neigh *) pnt; - if (!tlvs->lan_neighs) - tlvs->lan_neighs = list_new (); - listnode_add (tlvs->lan_neighs, lan_nei); - value_len += ETH_ALEN; - pnt += ETH_ALEN; - } - } - else - { - pnt += length; - } - break; - - case PADDING: + if (TLVFLAG_LAN_NEIGHS & *expected) { + while (length > value_len) { + lan_nei = (struct lan_neigh *)pnt; + if (!tlvs->lan_neighs) + tlvs->lan_neighs = list_new(); + listnode_add(tlvs->lan_neighs, lan_nei); + value_len += ETH_ALEN; + pnt += ETH_ALEN; + } + } else { + pnt += length; + } + break; + + case PADDING: #ifdef EXTREME_TLV_DEBUG - zlog_debug ("TLV padding %d", length); + zlog_debug("TLV padding %d", length); #endif /* EXTREME_TLV_DEBUG */ - pnt += length; - break; - - case LSP_ENTRIES: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Remaining Lifetime | 2 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | LSP ID | id+2 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | LSP Sequence Number | 4 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Checksum | 2 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - */ + pnt += length; + break; + + case LSP_ENTRIES: +/* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Remaining Lifetime | 2 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | LSP ID | id+2 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | LSP Sequence Number | 4 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Checksum | 2 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + */ #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): LSP Entries length %d", areatag, length); + zlog_debug("ISIS-TLV (%s): LSP Entries length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - *found |= TLVFLAG_LSP_ENTRIES; - if (TLVFLAG_LSP_ENTRIES & *expected) - { - while (length > value_len) - { - lsp_entry = (struct lsp_entry *) pnt; - value_len += 10 + ISIS_SYS_ID_LEN; - pnt += 10 + ISIS_SYS_ID_LEN; - if (!tlvs->lsp_entries) - tlvs->lsp_entries = list_new (); - listnode_add (tlvs->lsp_entries, lsp_entry); - } - } - else - { - pnt += length; - } - break; - - case CHECKSUM: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | 16 bit fletcher CHECKSUM | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_CHECKSUM; + *found |= TLVFLAG_LSP_ENTRIES; + if (TLVFLAG_LSP_ENTRIES & *expected) { + while (length > value_len) { + lsp_entry = (struct lsp_entry *)pnt; + value_len += 10 + ISIS_SYS_ID_LEN; + pnt += 10 + ISIS_SYS_ID_LEN; + if (!tlvs->lsp_entries) + tlvs->lsp_entries = list_new(); + listnode_add(tlvs->lsp_entries, + lsp_entry); + } + } else { + pnt += length; + } + break; + + case CHECKSUM: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | 16 bit fletcher CHECKSUM | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_CHECKSUM; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): Checksum length %d", areatag, length); + zlog_debug("ISIS-TLV (%s): Checksum length %d", areatag, + length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_CHECKSUM) - { - tlvs->checksum = (struct checksum *) pnt; - } - pnt += length; - break; - - case PROTOCOLS_SUPPORTED: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | NLPID | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_NLPID; + if (*expected & TLVFLAG_CHECKSUM) { + tlvs->checksum = (struct checksum *)pnt; + } + pnt += length; + break; + + case PROTOCOLS_SUPPORTED: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | NLPID | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_NLPID; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): Protocols Supported length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): Protocols Supported length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_NLPID) - { - tlvs->nlpids = (struct nlpids *) (pnt - 1); - } - pnt += length; - break; - - case IPV4_ADDR: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * + IP version 4 address + 4 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_IPV4_ADDR; + if (*expected & TLVFLAG_NLPID) { + tlvs->nlpids = (struct nlpids *)(pnt - 1); + } + pnt += length; + break; + + case IPV4_ADDR: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * + IP version 4 address + 4 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_IPV4_ADDR; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv4 Address length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): IPv4 Address length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV4_ADDR) - { - while (length > value_len) - { - ipv4_addr = (struct in_addr *) pnt; + if (*expected & TLVFLAG_IPV4_ADDR) { + while (length > value_len) { + ipv4_addr = (struct in_addr *)pnt; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s) : IP ADDR %s, pnt %p", areatag, - inet_ntoa (*ipv4_addr), pnt); + zlog_debug( + "ISIS-TLV (%s) : IP ADDR %s, pnt %p", + areatag, inet_ntoa(*ipv4_addr), + pnt); #endif /* EXTREME_TLV_DEBUG */ - if (!tlvs->ipv4_addrs) - tlvs->ipv4_addrs = list_new (); - listnode_add (tlvs->ipv4_addrs, ipv4_addr); - value_len += 4; - pnt += 4; - } - } - else - { - pnt += length; - } - break; - - case AUTH_INFO: - *found |= TLVFLAG_AUTH_INFO; + if (!tlvs->ipv4_addrs) + tlvs->ipv4_addrs = list_new(); + listnode_add(tlvs->ipv4_addrs, + ipv4_addr); + value_len += 4; + pnt += 4; + } + } else { + pnt += length; + } + break; + + case AUTH_INFO: + *found |= TLVFLAG_AUTH_INFO; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IS-IS Authentication Information", - areatag); + zlog_debug( + "ISIS-TLV (%s): IS-IS Authentication Information", + areatag); #endif - if (*expected & TLVFLAG_AUTH_INFO) - { - tlvs->auth_info.type = *pnt; - if (length == 0) - { - zlog_warn ("ISIS-TLV (%s): TLV (type %d, length %d) " - "incorrect.", areatag, type, length); - return ISIS_WARNING; - } - --length; - tlvs->auth_info.len = length; - pnt++; - memcpy (tlvs->auth_info.passwd, pnt, length); - /* Return the authentication tlv pos for later computation - * of MD5 (RFC 5304, 2) - */ - if (auth_tlv_offset) - *auth_tlv_offset += (pnt - start - 3); - pnt += length; - } - else - { - pnt += length; - } - break; - - case DYNAMIC_HOSTNAME: - *found |= TLVFLAG_DYN_HOSTNAME; + if (*expected & TLVFLAG_AUTH_INFO) { + tlvs->auth_info.type = *pnt; + if (length == 0) { + zlog_warn( + "ISIS-TLV (%s): TLV (type %d, length %d) " + "incorrect.", + areatag, type, length); + return ISIS_WARNING; + } + --length; + tlvs->auth_info.len = length; + pnt++; + memcpy(tlvs->auth_info.passwd, pnt, length); + /* Return the authentication tlv pos for later + * computation + * of MD5 (RFC 5304, 2) + */ + if (auth_tlv_offset) + *auth_tlv_offset += (pnt - start - 3); + pnt += length; + } else { + pnt += length; + } + break; + + case DYNAMIC_HOSTNAME: + *found |= TLVFLAG_DYN_HOSTNAME; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): Dynamic Hostname length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): Dynamic Hostname length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_DYN_HOSTNAME) - { - /* the length is also included in the pointed struct */ - tlvs->hostname = (struct hostname *) (pnt - 1); - } - pnt += length; - break; - - case TE_ROUTER_ID: - /* +---------------------------------------------------------------+ - * + Router ID + 4 - * +---------------------------------------------------------------+ - */ - *found |= TLVFLAG_TE_ROUTER_ID; + if (*expected & TLVFLAG_DYN_HOSTNAME) { + /* the length is also included in the pointed + * struct */ + tlvs->hostname = (struct hostname *)(pnt - 1); + } + pnt += length; + break; + + case TE_ROUTER_ID: + /* +---------------------------------------------------------------+ + * + Router ID + 4 + * +---------------------------------------------------------------+ + */ + *found |= TLVFLAG_TE_ROUTER_ID; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): TE Router ID %d", areatag, length); + zlog_debug("ISIS-TLV (%s): TE Router ID %d", areatag, + length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_TE_ROUTER_ID) - tlvs->router_id = (struct te_router_id *) (pnt); - pnt += length; - break; - - case IPV4_INT_REACHABILITY: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | 0 | I/E | Default Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Delay Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Expense Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Error Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | ip address | 4 - * +---------------------------------------------------------------+ - * | address mask | 4 - * +---------------------------------------------------------------+ - * : : - */ - *found |= TLVFLAG_IPV4_INT_REACHABILITY; + if (*expected & TLVFLAG_TE_ROUTER_ID) + tlvs->router_id = (struct te_router_id *)(pnt); + pnt += length; + break; + + case IPV4_INT_REACHABILITY: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | 0 | I/E | Default Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Delay Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Expense Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Error Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | ip address | 4 + * +---------------------------------------------------------------+ + * | address mask | 4 + * +---------------------------------------------------------------+ + * : : + */ + *found |= TLVFLAG_IPV4_INT_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv4 internal Reachability length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): IPv4 internal Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV4_INT_REACHABILITY) - { - while (length > value_len) - { - ipv4_reach = (struct ipv4_reachability *) pnt; - if (!tlvs->ipv4_int_reachs) - tlvs->ipv4_int_reachs = list_new (); - listnode_add (tlvs->ipv4_int_reachs, ipv4_reach); - value_len += 12; - pnt += 12; - } - } - else - { - pnt += length; - } - break; - - case IPV4_EXT_REACHABILITY: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | 0 | I/E | Default Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Delay Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Expense Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | S | I/E | Error Metric | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | ip address | 4 - * +---------------------------------------------------------------+ - * | address mask | 4 - * +---------------------------------------------------------------+ - * : : - */ - *found |= TLVFLAG_IPV4_EXT_REACHABILITY; + if (*expected & TLVFLAG_IPV4_INT_REACHABILITY) { + while (length > value_len) { + ipv4_reach = + (struct ipv4_reachability *)pnt; + if (!tlvs->ipv4_int_reachs) + tlvs->ipv4_int_reachs = + list_new(); + listnode_add(tlvs->ipv4_int_reachs, + ipv4_reach); + value_len += 12; + pnt += 12; + } + } else { + pnt += length; + } + break; + + case IPV4_EXT_REACHABILITY: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | 0 | I/E | Default Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Delay Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Expense Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | S | I/E | Error Metric | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | ip address | 4 + * +---------------------------------------------------------------+ + * | address mask | 4 + * +---------------------------------------------------------------+ + * : : + */ + *found |= TLVFLAG_IPV4_EXT_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv4 external Reachability length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): IPv4 external Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV4_EXT_REACHABILITY) - { - while (length > value_len) - { - ipv4_reach = (struct ipv4_reachability *) pnt; - if (!tlvs->ipv4_ext_reachs) - tlvs->ipv4_ext_reachs = list_new (); - listnode_add (tlvs->ipv4_ext_reachs, ipv4_reach); - value_len += 12; - pnt += 12; - } - } - else - { - pnt += length; - } - break; - - case TE_IPV4_REACHABILITY: - *found |= TLVFLAG_TE_IPV4_REACHABILITY; + if (*expected & TLVFLAG_IPV4_EXT_REACHABILITY) { + while (length > value_len) { + ipv4_reach = + (struct ipv4_reachability *)pnt; + if (!tlvs->ipv4_ext_reachs) + tlvs->ipv4_ext_reachs = + list_new(); + listnode_add(tlvs->ipv4_ext_reachs, + ipv4_reach); + value_len += 12; + pnt += 12; + } + } else { + pnt += length; + } + break; + + case TE_IPV4_REACHABILITY: + *found |= TLVFLAG_TE_IPV4_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): IPv4 extended Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) - retval = parse_mt_ipv4_reachs(tlvs, false, length, pnt); - pnt += length; - break; - case MT_IPV4_REACHABILITY: - *found |= TLVFLAG_TE_IPV4_REACHABILITY; + if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) + retval = parse_mt_ipv4_reachs(tlvs, false, + length, pnt); + pnt += length; + break; + case MT_IPV4_REACHABILITY: + *found |= TLVFLAG_TE_IPV4_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv4 MT Reachability length %d", - areatag, length); + zlog_debug( + "ISIS-TLV (%s): IPv4 MT Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) - retval = parse_mt_ipv4_reachs(tlvs, true, length, pnt); - pnt += length; - break; - case IPV6_ADDR: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * + IP version 6 address + 16 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * : : - */ - *found |= TLVFLAG_IPV6_ADDR; + if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) + retval = parse_mt_ipv4_reachs(tlvs, true, + length, pnt); + pnt += length; + break; + case IPV6_ADDR: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * + IP version 6 address + 16 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * : : + */ + *found |= TLVFLAG_IPV6_ADDR; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv6 Address length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): IPv6 Address length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV6_ADDR) - { - while (length > value_len) - { - ipv6_addr = (struct in6_addr *) pnt; - if (!tlvs->ipv6_addrs) - tlvs->ipv6_addrs = list_new (); - listnode_add (tlvs->ipv6_addrs, ipv6_addr); - value_len += 16; - pnt += 16; - } - } - else - { - pnt += length; - } - break; - - case IPV6_REACHABILITY: - *found |= TLVFLAG_IPV6_REACHABILITY; + if (*expected & TLVFLAG_IPV6_ADDR) { + while (length > value_len) { + ipv6_addr = (struct in6_addr *)pnt; + if (!tlvs->ipv6_addrs) + tlvs->ipv6_addrs = list_new(); + listnode_add(tlvs->ipv6_addrs, + ipv6_addr); + value_len += 16; + pnt += 16; + } + } else { + pnt += length; + } + break; + + case IPV6_REACHABILITY: + *found |= TLVFLAG_IPV6_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv6 Reachability length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): IPv6 Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV6_REACHABILITY) - retval = parse_mt_ipv6_reachs(tlvs, false, length, pnt); - pnt += length; - break; - case MT_IPV6_REACHABILITY: - *found |= TLVFLAG_IPV6_REACHABILITY; + if (*expected & TLVFLAG_IPV6_REACHABILITY) + retval = parse_mt_ipv6_reachs(tlvs, false, + length, pnt); + pnt += length; + break; + case MT_IPV6_REACHABILITY: + *found |= TLVFLAG_IPV6_REACHABILITY; #ifdef EXTREME_TLV_DEBUG - zlog_debug ("ISIS-TLV (%s): IPv6 Reachability length %d", - areatag, length); + zlog_debug("ISIS-TLV (%s): IPv6 Reachability length %d", + areatag, length); #endif /* EXTREME_TLV_DEBUG */ - if (*expected & TLVFLAG_IPV6_REACHABILITY) - retval = parse_mt_ipv6_reachs(tlvs, true, length, pnt); - pnt += length; - break; - case WAY3_HELLO: - /* +---------------------------------------------------------------+ - * | Adjacency state | 1 - * +---------------------------------------------------------------+ - * | Extended Local Circuit ID | 4 - * +---------------------------------------------------------------+ - * | Neighbor System ID (If known) | 0-8 - * (probably 6) - * +---------------------------------------------------------------+ - * | Neighbor Local Circuit ID (If known) | 4 - * +---------------------------------------------------------------+ - */ - *found |= TLVFLAG_3WAY_HELLO; - if (*expected & TLVFLAG_3WAY_HELLO) - { - while (length > value_len) - { - /* FIXME: make this work */ -/* Adjacency State (one octet): - 0 = Up - 1 = Initializing - 2 = Down - Extended Local Circuit ID (four octets) - Neighbor System ID if known (zero to eight octets) - Neighbor Extended Local Circuit ID (four octets, if Neighbor - System ID is present) */ - pnt += length; - value_len += length; + if (*expected & TLVFLAG_IPV6_REACHABILITY) + retval = parse_mt_ipv6_reachs(tlvs, true, + length, pnt); + pnt += length; + break; + case WAY3_HELLO: + /* +---------------------------------------------------------------+ + * | Adjacency state | 1 + * +---------------------------------------------------------------+ + * | Extended Local Circuit ID | 4 + * +---------------------------------------------------------------+ + * | Neighbor System ID (If known) + * | 0-8 + * (probably 6) + * +---------------------------------------------------------------+ + * | Neighbor Local Circuit ID (If + * known) | 4 + * +---------------------------------------------------------------+ + */ + *found |= TLVFLAG_3WAY_HELLO; + if (*expected & TLVFLAG_3WAY_HELLO) { + while (length > value_len) { + /* FIXME: make this work */ + /* Adjacency State (one + octet): + 0 = Up + 1 = Initializing + 2 = Down + Extended Local Circuit ID + (four octets) + Neighbor System ID if known + (zero to eight octets) + Neighbor Extended Local + Circuit ID (four octets, if Neighbor + System ID is present) */ + pnt += length; + value_len += length; + } + } else { + pnt += length; + } + + break; + case GRACEFUL_RESTART: + /* +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Reserved | SA | RA + * | RR | 1 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Remaining Time | 2 + * +---------------------------------------------------------------+ + * | Restarting Neighbor ID (If known) + * | 0-8 + * +---------------------------------------------------------------+ + */ + *found |= TLVFLAG_GRACEFUL_RESTART; + if (*expected & TLVFLAG_GRACEFUL_RESTART) { + /* FIXME: make this work */ + } + pnt += length; + break; + + case MT_ROUTER_INFORMATION: + *found |= TLVFLAG_MT_ROUTER_INFORMATION; + if (*expected & TLVFLAG_MT_ROUTER_INFORMATION) { + if (!tlvs->mt_router_info) { + tlvs->mt_router_info = list_new(); + tlvs->mt_router_info->del = free_tlv; + } + while (length > value_len) { + uint16_t mt_info; + struct mt_router_info *info; + + if (value_len + sizeof(mt_info) + > length) { + zlog_warn( + "ISIS-TLV (%s): TLV 229 is truncated.", + areatag); + pnt += length - value_len; + break; + } + + memcpy(&mt_info, pnt, sizeof(mt_info)); + pnt += sizeof(mt_info); + value_len += sizeof(mt_info); + + mt_info = ntohs(mt_info); + info = XCALLOC(MTYPE_ISIS_TLV, + sizeof(*info)); + info->mtid = mt_info & ISIS_MT_MASK; + info->overload = + mt_info & ISIS_MT_OL_MASK; + listnode_add(tlvs->mt_router_info, + info); + } + } else { + pnt += length; + } + break; + default: + zlog_warn( + "ISIS-TLV (%s): unsupported TLV type %d, length %d", + areatag, type, length); + + pnt += length; + break; } - } - else - { - pnt += length; - } - - break; - case GRACEFUL_RESTART: - /* +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Reserved | SA | RA | RR | 1 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | Remaining Time | 2 - * +---------------------------------------------------------------+ - * | Restarting Neighbor ID (If known) | 0-8 - * +---------------------------------------------------------------+ - */ - *found |= TLVFLAG_GRACEFUL_RESTART; - if (*expected & TLVFLAG_GRACEFUL_RESTART) - { - /* FIXME: make this work */ - } - pnt += length; - break; - - case MT_ROUTER_INFORMATION: - *found |= TLVFLAG_MT_ROUTER_INFORMATION; - if (*expected & TLVFLAG_MT_ROUTER_INFORMATION) - { - if (!tlvs->mt_router_info) - { - tlvs->mt_router_info = list_new(); - tlvs->mt_router_info->del = free_tlv; - } - while (length > value_len) - { - uint16_t mt_info; - struct mt_router_info *info; - - if (value_len + sizeof(mt_info) > length) { - zlog_warn("ISIS-TLV (%s): TLV 229 is truncated.", areatag); - pnt += length - value_len; - break; - } - - memcpy(&mt_info, pnt, sizeof(mt_info)); - pnt += sizeof(mt_info); - value_len += sizeof(mt_info); - - mt_info = ntohs(mt_info); - info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info)); - info->mtid = mt_info & ISIS_MT_MASK; - info->overload = mt_info & ISIS_MT_OL_MASK; - listnode_add(tlvs->mt_router_info, info); - } - } - else - { - pnt += length; - } - break; - default: - zlog_warn ("ISIS-TLV (%s): unsupported TLV type %d, length %d", - areatag, type, length); - - pnt += length; - break; + /* Abort Parsing if error occured */ + if (retval != ISIS_OK) + return retval; } - /* Abort Parsing if error occured */ - if (retval != ISIS_OK) - return retval; - } - return retval; + return retval; } -int -add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream) +int add_tlv(u_char tag, u_char len, u_char *value, struct stream *stream) { - if ((stream_get_size (stream) - stream_get_endp (stream)) < - (((unsigned)len) + 2)) - { - zlog_warn ("No room for TLV of type %d " - "(total size %d available %d required %d)", - tag, (int)stream_get_size (stream), - (int)(stream_get_size (stream) - stream_get_endp (stream)), - len+2); - return ISIS_WARNING; - } - - stream_putc (stream, tag); /* TAG */ - stream_putc (stream, len); /* LENGTH */ - stream_put (stream, value, (int) len); /* VALUE */ + if ((stream_get_size(stream) - stream_get_endp(stream)) + < (((unsigned)len) + 2)) { + zlog_warn( + "No room for TLV of type %d " + "(total size %d available %d required %d)", + tag, (int)stream_get_size(stream), + (int)(stream_get_size(stream) + - stream_get_endp(stream)), + len + 2); + return ISIS_WARNING; + } + + stream_putc(stream, tag); /* TAG */ + stream_putc(stream, len); /* LENGTH */ + stream_put(stream, value, (int)len); /* VALUE */ #ifdef EXTREME_DEBUG - zlog_debug ("Added TLV %d len %d", tag, len); + zlog_debug("Added TLV %d len %d", tag, len); #endif /* EXTREME DEBUG */ - return ISIS_OK; + return ISIS_OK; } -int -tlv_add_mt_router_info (struct list *mt_router_info, struct stream *stream) +int tlv_add_mt_router_info(struct list *mt_router_info, struct stream *stream) { - struct listnode *node; - struct mt_router_info *info; + struct listnode *node; + struct mt_router_info *info; - uint16_t value[127]; - uint16_t *pos = value; + uint16_t value[127]; + uint16_t *pos = value; - for (ALL_LIST_ELEMENTS_RO(mt_router_info, node, info)) - { - uint16_t mt_info; + for (ALL_LIST_ELEMENTS_RO(mt_router_info, node, info)) { + uint16_t mt_info; - mt_info = info->mtid; - if (info->overload) - mt_info |= ISIS_MT_OL_MASK; + mt_info = info->mtid; + if (info->overload) + mt_info |= ISIS_MT_OL_MASK; - *pos = htons(mt_info); - pos++; - } + *pos = htons(mt_info); + pos++; + } - return add_tlv(MT_ROUTER_INFORMATION, (pos - value) * sizeof(*pos), - (u_char*)value, stream); + return add_tlv(MT_ROUTER_INFORMATION, (pos - value) * sizeof(*pos), + (u_char *)value, stream); } -int -tlv_add_area_addrs (struct list *area_addrs, struct stream *stream) +int tlv_add_area_addrs(struct list *area_addrs, struct stream *stream) { - struct listnode *node; - struct area_addr *area_addr; - - u_char value[255]; - u_char *pos = value; - - for (ALL_LIST_ELEMENTS_RO (area_addrs, node, area_addr)) - { - if (pos - value + area_addr->addr_len > 255) - goto err; - *pos = area_addr->addr_len; - pos++; - memcpy (pos, area_addr->area_addr, (int) area_addr->addr_len); - pos += area_addr->addr_len; - } + struct listnode *node; + struct area_addr *area_addr; + + u_char value[255]; + u_char *pos = value; + + for (ALL_LIST_ELEMENTS_RO(area_addrs, node, area_addr)) { + if (pos - value + area_addr->addr_len > 255) + goto err; + *pos = area_addr->addr_len; + pos++; + memcpy(pos, area_addr->area_addr, (int)area_addr->addr_len); + pos += area_addr->addr_len; + } - return add_tlv (AREA_ADDRESSES, pos - value, value, stream); + return add_tlv(AREA_ADDRESSES, pos - value, value, stream); err: - zlog_warn ("tlv_add_area_addrs(): TLV longer than 255"); - return ISIS_WARNING; + zlog_warn("tlv_add_area_addrs(): TLV longer than 255"); + return ISIS_WARNING; } -int -tlv_add_is_neighs (struct list *is_neighs, struct stream *stream) +int tlv_add_is_neighs(struct list *is_neighs, struct stream *stream) { - struct listnode *node; - struct is_neigh *is_neigh; - u_char value[255]; - u_char *pos = value; - int retval; - - *pos = 0; /*is_neigh->virtual; */ - pos++; - - for (ALL_LIST_ELEMENTS_RO (is_neighs, node, is_neigh)) - { - if (pos - value + IS_NEIGHBOURS_LEN > 255) - { - retval = add_tlv (IS_NEIGHBOURS, pos - value, value, stream); - if (retval != ISIS_OK) - return retval; - pos = value; + struct listnode *node; + struct is_neigh *is_neigh; + u_char value[255]; + u_char *pos = value; + int retval; + + *pos = 0; /*is_neigh->virtual; */ + pos++; + + for (ALL_LIST_ELEMENTS_RO(is_neighs, node, is_neigh)) { + if (pos - value + IS_NEIGHBOURS_LEN > 255) { + retval = add_tlv(IS_NEIGHBOURS, pos - value, value, + stream); + if (retval != ISIS_OK) + return retval; + pos = value; + } + *pos = is_neigh->metrics.metric_default; + pos++; + *pos = is_neigh->metrics.metric_delay; + pos++; + *pos = is_neigh->metrics.metric_expense; + pos++; + *pos = is_neigh->metrics.metric_error; + pos++; + memcpy(pos, is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1); + pos += ISIS_SYS_ID_LEN + 1; } - *pos = is_neigh->metrics.metric_default; - pos++; - *pos = is_neigh->metrics.metric_delay; - pos++; - *pos = is_neigh->metrics.metric_expense; - pos++; - *pos = is_neigh->metrics.metric_error; - pos++; - memcpy (pos, is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1); - pos += ISIS_SYS_ID_LEN + 1; - } - - return add_tlv (IS_NEIGHBOURS, pos - value, value, stream); + + return add_tlv(IS_NEIGHBOURS, pos - value, value, stream); } -static size_t -max_tlv_size(struct stream *stream) +static size_t max_tlv_size(struct stream *stream) { - size_t avail = stream_get_size (stream) - stream_get_endp(stream); + size_t avail = stream_get_size(stream) - stream_get_endp(stream); - if (avail < 2) - return 0; + if (avail < 2) + return 0; - if (avail < 257) - return avail - 2; + if (avail < 257) + return avail - 2; - return 255; + return 255; } -unsigned int -tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream, void *arg) +unsigned int tlv_add_te_is_neighs(struct list *te_is_neighs, + struct stream *stream, void *arg) { - struct listnode *node; - struct te_is_neigh *te_is_neigh; - u_char value[255]; - u_char *pos = value; - uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST; - unsigned int consumed = 0; - size_t max_size = max_tlv_size(stream); - - if (mtid != ISIS_MT_IPV4_UNICAST) - { - uint16_t mtid_conversion = ntohs(mtid); - memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); - pos += sizeof(mtid_conversion); - } - - for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh)) - { - /* FIXME: Check if Total SubTLVs size doesn't exceed 255 */ - if ((size_t)(pos - value) + IS_NEIGHBOURS_LEN + te_is_neigh->sub_tlvs_length > max_size) - break; - - memcpy (pos, te_is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1); - pos += ISIS_SYS_ID_LEN + 1; - memcpy (pos, te_is_neigh->te_metric, 3); - pos += 3; - /* Set the total size of Sub TLVs */ - *pos = te_is_neigh->sub_tlvs_length; - pos++; - /* Copy Sub TLVs if any */ - if (te_is_neigh->sub_tlvs_length > 0) - { - memcpy (pos, te_is_neigh->sub_tlvs, te_is_neigh->sub_tlvs_length); - pos += te_is_neigh->sub_tlvs_length; - } - consumed++; - } - - if (consumed) - { - int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IS_NEIGHBOURS - : TE_IS_NEIGHBOURS, - pos - value, value, stream); - assert(rv == ISIS_OK); - } - return consumed; + struct listnode *node; + struct te_is_neigh *te_is_neigh; + u_char value[255]; + u_char *pos = value; + uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST; + unsigned int consumed = 0; + size_t max_size = max_tlv_size(stream); + + if (mtid != ISIS_MT_IPV4_UNICAST) { + uint16_t mtid_conversion = ntohs(mtid); + memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); + pos += sizeof(mtid_conversion); + } + + for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) { + /* FIXME: Check if Total SubTLVs size doesn't exceed 255 */ + if ((size_t)(pos - value) + IS_NEIGHBOURS_LEN + + te_is_neigh->sub_tlvs_length + > max_size) + break; + + memcpy(pos, te_is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1); + pos += ISIS_SYS_ID_LEN + 1; + memcpy(pos, te_is_neigh->te_metric, 3); + pos += 3; + /* Set the total size of Sub TLVs */ + *pos = te_is_neigh->sub_tlvs_length; + pos++; + /* Copy Sub TLVs if any */ + if (te_is_neigh->sub_tlvs_length > 0) { + memcpy(pos, te_is_neigh->sub_tlvs, + te_is_neigh->sub_tlvs_length); + pos += te_is_neigh->sub_tlvs_length; + } + consumed++; + } + + if (consumed) { + int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST) + ? MT_IS_NEIGHBOURS + : TE_IS_NEIGHBOURS, + pos - value, value, stream); + assert(rv == ISIS_OK); + } + return consumed; } -int -tlv_add_lan_neighs (struct list *lan_neighs, struct stream *stream) +int tlv_add_lan_neighs(struct list *lan_neighs, struct stream *stream) { - struct listnode *node; - u_char *snpa; - u_char value[255]; - u_char *pos = value; - int retval; - - for (ALL_LIST_ELEMENTS_RO (lan_neighs, node, snpa)) - { - if (pos - value + ETH_ALEN > 255) - { - retval = add_tlv (LAN_NEIGHBOURS, pos - value, value, stream); - if (retval != ISIS_OK) - return retval; - pos = value; + struct listnode *node; + u_char *snpa; + u_char value[255]; + u_char *pos = value; + int retval; + + for (ALL_LIST_ELEMENTS_RO(lan_neighs, node, snpa)) { + if (pos - value + ETH_ALEN > 255) { + retval = add_tlv(LAN_NEIGHBOURS, pos - value, value, + stream); + if (retval != ISIS_OK) + return retval; + pos = value; + } + memcpy(pos, snpa, ETH_ALEN); + pos += ETH_ALEN; } - memcpy (pos, snpa, ETH_ALEN); - pos += ETH_ALEN; - } - return add_tlv (LAN_NEIGHBOURS, pos - value, value, stream); + return add_tlv(LAN_NEIGHBOURS, pos - value, value, stream); } -int -tlv_add_nlpid (struct nlpids *nlpids, struct stream *stream) +int tlv_add_nlpid(struct nlpids *nlpids, struct stream *stream) { - return add_tlv (PROTOCOLS_SUPPORTED, nlpids->count, nlpids->nlpids, stream); + return add_tlv(PROTOCOLS_SUPPORTED, nlpids->count, nlpids->nlpids, + stream); } -int -tlv_add_authinfo (u_char auth_type, u_char auth_len, u_char *auth_value, - struct stream *stream) +int tlv_add_authinfo(u_char auth_type, u_char auth_len, u_char *auth_value, + struct stream *stream) { - u_char value[255]; - u_char *pos = value; - *pos++ = auth_type; - memcpy (pos, auth_value, auth_len); + u_char value[255]; + u_char *pos = value; + *pos++ = auth_type; + memcpy(pos, auth_value, auth_len); - return add_tlv (AUTH_INFO, auth_len + 1, value, stream); + return add_tlv(AUTH_INFO, auth_len + 1, value, stream); } -int -tlv_add_checksum (struct checksum *checksum, struct stream *stream) +int tlv_add_checksum(struct checksum *checksum, struct stream *stream) { - u_char value[255]; - u_char *pos = value; - return add_tlv (CHECKSUM, pos - value, value, stream); + u_char value[255]; + u_char *pos = value; + return add_tlv(CHECKSUM, pos - value, value, stream); } -int -tlv_add_ip_addrs (struct list *ip_addrs, struct stream *stream) +int tlv_add_ip_addrs(struct list *ip_addrs, struct stream *stream) { - struct listnode *node; - struct prefix_ipv4 *ipv4; - u_char value[255]; - u_char *pos = value; - - for (ALL_LIST_ELEMENTS_RO (ip_addrs, node, ipv4)) - { - if (pos - value + IPV4_MAX_BYTELEN > 255) - { - /* RFC 1195 s4.2: only one tuple of 63 allowed. */ - zlog_warn ("tlv_add_ip_addrs(): cutting off at 63 IP addresses"); - break; + struct listnode *node; + struct prefix_ipv4 *ipv4; + u_char value[255]; + u_char *pos = value; + + for (ALL_LIST_ELEMENTS_RO(ip_addrs, node, ipv4)) { + if (pos - value + IPV4_MAX_BYTELEN > 255) { + /* RFC 1195 s4.2: only one tuple of 63 allowed. */ + zlog_warn( + "tlv_add_ip_addrs(): cutting off at 63 IP addresses"); + break; + } + *(u_int32_t *)pos = ipv4->prefix.s_addr; + pos += IPV4_MAX_BYTELEN; } - *(u_int32_t *) pos = ipv4->prefix.s_addr; - pos += IPV4_MAX_BYTELEN; - } - return add_tlv (IPV4_ADDR, pos - value, value, stream); + return add_tlv(IPV4_ADDR, pos - value, value, stream); } /* Used to add TLV containing just one IPv4 address - either IPv4 address TLV * (in case of LSP) or TE router ID TLV. */ -int -tlv_add_in_addr (struct in_addr *addr, struct stream *stream, u_char tag) +int tlv_add_in_addr(struct in_addr *addr, struct stream *stream, u_char tag) { - u_char value[255]; - u_char *pos = value; - - memcpy (pos, addr, IPV4_MAX_BYTELEN); - pos += IPV4_MAX_BYTELEN; + u_char value[255]; + u_char *pos = value; + + memcpy(pos, addr, IPV4_MAX_BYTELEN); + pos += IPV4_MAX_BYTELEN; - return add_tlv (tag, pos - value, value, stream); + return add_tlv(tag, pos - value, value, stream); } -int -tlv_add_dynamic_hostname (struct hostname *hostname, struct stream *stream) +int tlv_add_dynamic_hostname(struct hostname *hostname, struct stream *stream) { - return add_tlv (DYNAMIC_HOSTNAME, hostname->namelen, hostname->name, - stream); + return add_tlv(DYNAMIC_HOSTNAME, hostname->namelen, hostname->name, + stream); } -int -tlv_add_lsp_entries (struct list *lsps, struct stream *stream) +int tlv_add_lsp_entries(struct list *lsps, struct stream *stream) { - struct listnode *node; - struct isis_lsp *lsp; - u_char value[255]; - u_char *pos = value; - int retval; - - for (ALL_LIST_ELEMENTS_RO (lsps, node, lsp)) - { - if (pos - value + LSP_ENTRIES_LEN > 255) - { - retval = add_tlv (LSP_ENTRIES, pos - value, value, stream); - if (retval != ISIS_OK) - return retval; - pos = value; + struct listnode *node; + struct isis_lsp *lsp; + u_char value[255]; + u_char *pos = value; + int retval; + + for (ALL_LIST_ELEMENTS_RO(lsps, node, lsp)) { + if (pos - value + LSP_ENTRIES_LEN > 255) { + retval = add_tlv(LSP_ENTRIES, pos - value, value, + stream); + if (retval != ISIS_OK) + return retval; + pos = value; + } + *((u_int16_t *)pos) = lsp->lsp_header->rem_lifetime; + pos += 2; + memcpy(pos, lsp->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 2); + pos += ISIS_SYS_ID_LEN + 2; + *((u_int32_t *)pos) = lsp->lsp_header->seq_num; + pos += 4; + *((u_int16_t *)pos) = lsp->lsp_header->checksum; + pos += 2; } - *((u_int16_t *) pos) = lsp->lsp_header->rem_lifetime; - pos += 2; - memcpy (pos, lsp->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 2); - pos += ISIS_SYS_ID_LEN + 2; - *((u_int32_t *) pos) = lsp->lsp_header->seq_num; - pos += 4; - *((u_int16_t *) pos) = lsp->lsp_header->checksum; - pos += 2; - } - - return add_tlv (LSP_ENTRIES, pos - value, value, stream); + + return add_tlv(LSP_ENTRIES, pos - value, value, stream); } -static int -tlv_add_ipv4_reachs (u_char tag, struct list *ipv4_reachs, struct stream *stream) +static int tlv_add_ipv4_reachs(u_char tag, struct list *ipv4_reachs, + struct stream *stream) { - struct listnode *node; - struct ipv4_reachability *reach; - u_char value[255]; - u_char *pos = value; - int retval; - - for (ALL_LIST_ELEMENTS_RO (ipv4_reachs, node, reach)) - { - if (pos - value + IPV4_REACH_LEN > 255) - { - retval = - add_tlv (tag, pos - value, value, stream); - if (retval != ISIS_OK) - return retval; - pos = value; + struct listnode *node; + struct ipv4_reachability *reach; + u_char value[255]; + u_char *pos = value; + int retval; + + for (ALL_LIST_ELEMENTS_RO(ipv4_reachs, node, reach)) { + if (pos - value + IPV4_REACH_LEN > 255) { + retval = add_tlv(tag, pos - value, value, stream); + if (retval != ISIS_OK) + return retval; + pos = value; + } + *pos = reach->metrics.metric_default; + pos++; + *pos = reach->metrics.metric_delay; + pos++; + *pos = reach->metrics.metric_expense; + pos++; + *pos = reach->metrics.metric_error; + pos++; + *(u_int32_t *)pos = reach->prefix.s_addr; + pos += IPV4_MAX_BYTELEN; + *(u_int32_t *)pos = reach->mask.s_addr; + pos += IPV4_MAX_BYTELEN; } - *pos = reach->metrics.metric_default; - pos++; - *pos = reach->metrics.metric_delay; - pos++; - *pos = reach->metrics.metric_expense; - pos++; - *pos = reach->metrics.metric_error; - pos++; - *(u_int32_t *) pos = reach->prefix.s_addr; - pos += IPV4_MAX_BYTELEN; - *(u_int32_t *) pos = reach->mask.s_addr; - pos += IPV4_MAX_BYTELEN; - } - - return add_tlv (tag, pos - value, value, stream); + + return add_tlv(tag, pos - value, value, stream); } -int -tlv_add_ipv4_int_reachs (struct list *ipv4_reachs, struct stream *stream) +int tlv_add_ipv4_int_reachs(struct list *ipv4_reachs, struct stream *stream) { - return tlv_add_ipv4_reachs(IPV4_INT_REACHABILITY, ipv4_reachs, stream); + return tlv_add_ipv4_reachs(IPV4_INT_REACHABILITY, ipv4_reachs, stream); } -int -tlv_add_ipv4_ext_reachs (struct list *ipv4_reachs, struct stream *stream) +int tlv_add_ipv4_ext_reachs(struct list *ipv4_reachs, struct stream *stream) { - return tlv_add_ipv4_reachs(IPV4_EXT_REACHABILITY, ipv4_reachs, stream); + return tlv_add_ipv4_reachs(IPV4_EXT_REACHABILITY, ipv4_reachs, stream); } -unsigned int -tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream, void *arg) +unsigned int tlv_add_te_ipv4_reachs(struct list *te_ipv4_reachs, + struct stream *stream, void *arg) { - struct listnode *node; - struct te_ipv4_reachability *te_reach; - u_char value[255]; - u_char *pos = value; - uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST; - unsigned int consumed = 0; - size_t max_size = max_tlv_size(stream); - - if (mtid != ISIS_MT_IPV4_UNICAST) - { - uint16_t mtid_conversion = ntohs(mtid); - memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); - pos += sizeof(mtid_conversion); - } - - for (ALL_LIST_ELEMENTS_RO (te_ipv4_reachs, node, te_reach)) - { - unsigned char prefixlen = te_reach->control & 0x3F; - - if ((size_t)(pos - value) + 5 + PSIZE(prefixlen) > max_size) - break; - - *(u_int32_t *) pos = te_reach->te_metric; - pos += 4; - *pos = te_reach->control; - pos++; - memcpy (pos, &te_reach->prefix_start, PSIZE(prefixlen)); - pos += PSIZE(prefixlen); - consumed++; - } - - if (consumed) - { - int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IPV4_REACHABILITY - : TE_IPV4_REACHABILITY, - pos - value, value, stream); - assert(rv == ISIS_OK); - } - - return consumed; + struct listnode *node; + struct te_ipv4_reachability *te_reach; + u_char value[255]; + u_char *pos = value; + uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST; + unsigned int consumed = 0; + size_t max_size = max_tlv_size(stream); + + if (mtid != ISIS_MT_IPV4_UNICAST) { + uint16_t mtid_conversion = ntohs(mtid); + memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); + pos += sizeof(mtid_conversion); + } + + for (ALL_LIST_ELEMENTS_RO(te_ipv4_reachs, node, te_reach)) { + unsigned char prefixlen = te_reach->control & 0x3F; + + if ((size_t)(pos - value) + 5 + PSIZE(prefixlen) > max_size) + break; + + *(u_int32_t *)pos = te_reach->te_metric; + pos += 4; + *pos = te_reach->control; + pos++; + memcpy(pos, &te_reach->prefix_start, PSIZE(prefixlen)); + pos += PSIZE(prefixlen); + consumed++; + } + + if (consumed) { + int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST) + ? MT_IPV4_REACHABILITY + : TE_IPV4_REACHABILITY, + pos - value, value, stream); + assert(rv == ISIS_OK); + } + + return consumed; } -int -tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream) +int tlv_add_ipv6_addrs(struct list *ipv6_addrs, struct stream *stream) { - struct listnode *node; - struct prefix_ipv6 *ipv6; - u_char value[255]; - u_char *pos = value; - int retval; - - for (ALL_LIST_ELEMENTS_RO (ipv6_addrs, node, ipv6)) - { - if (pos - value + IPV6_MAX_BYTELEN > 255) - { - retval = add_tlv (IPV6_ADDR, pos - value, value, stream); - if (retval != ISIS_OK) - return retval; - pos = value; + struct listnode *node; + struct prefix_ipv6 *ipv6; + u_char value[255]; + u_char *pos = value; + int retval; + + for (ALL_LIST_ELEMENTS_RO(ipv6_addrs, node, ipv6)) { + if (pos - value + IPV6_MAX_BYTELEN > 255) { + retval = add_tlv(IPV6_ADDR, pos - value, value, stream); + if (retval != ISIS_OK) + return retval; + pos = value; + } + memcpy(pos, ipv6->prefix.s6_addr, IPV6_MAX_BYTELEN); + pos += IPV6_MAX_BYTELEN; } - memcpy (pos, ipv6->prefix.s6_addr, IPV6_MAX_BYTELEN); - pos += IPV6_MAX_BYTELEN; - } - return add_tlv (IPV6_ADDR, pos - value, value, stream); + return add_tlv(IPV6_ADDR, pos - value, value, stream); } -unsigned int -tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream, void *arg) +unsigned int tlv_add_ipv6_reachs(struct list *ipv6_reachs, + struct stream *stream, void *arg) { - struct listnode *node; - struct ipv6_reachability *ip6reach; - u_char value[255]; - u_char *pos = value; - uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST; - unsigned int consumed = 0; - size_t max_size = max_tlv_size(stream); - - if (mtid != ISIS_MT_IPV4_UNICAST) - { - uint16_t mtid_conversion = ntohs(mtid); - memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); - pos += sizeof(mtid_conversion); - } - - for (ALL_LIST_ELEMENTS_RO (ipv6_reachs, node, ip6reach)) - { - if ((size_t)(pos - value) + 6 + PSIZE(ip6reach->prefix_len) > max_size) - break; - - *(uint32_t *)pos = ip6reach->metric; - pos += 4; - *pos = ip6reach->control_info; - pos++; - *pos = ip6reach->prefix_len; - pos++; - memcpy (pos, ip6reach->prefix, PSIZE(ip6reach->prefix_len)); - pos += PSIZE(ip6reach->prefix_len); - consumed++; - } - - if (consumed) - { - int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IPV6_REACHABILITY - : IPV6_REACHABILITY, - pos - value, value, stream); - assert(rv == ISIS_OK); - } - - return consumed; + struct listnode *node; + struct ipv6_reachability *ip6reach; + u_char value[255]; + u_char *pos = value; + uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST; + unsigned int consumed = 0; + size_t max_size = max_tlv_size(stream); + + if (mtid != ISIS_MT_IPV4_UNICAST) { + uint16_t mtid_conversion = ntohs(mtid); + memcpy(pos, &mtid_conversion, sizeof(mtid_conversion)); + pos += sizeof(mtid_conversion); + } + + for (ALL_LIST_ELEMENTS_RO(ipv6_reachs, node, ip6reach)) { + if ((size_t)(pos - value) + 6 + PSIZE(ip6reach->prefix_len) + > max_size) + break; + + *(uint32_t *)pos = ip6reach->metric; + pos += 4; + *pos = ip6reach->control_info; + pos++; + *pos = ip6reach->prefix_len; + pos++; + memcpy(pos, ip6reach->prefix, PSIZE(ip6reach->prefix_len)); + pos += PSIZE(ip6reach->prefix_len); + consumed++; + } + + if (consumed) { + int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST) + ? MT_IPV6_REACHABILITY + : IPV6_REACHABILITY, + pos - value, value, stream); + assert(rv == ISIS_OK); + } + + return consumed; } -int -tlv_add_padding (struct stream *stream) +int tlv_add_padding(struct stream *stream) { - int fullpads, i, left; - - /* - * How many times can we add full padding ? - */ - fullpads = (stream_get_size (stream) - stream_get_endp (stream)) / 257; - for (i = 0; i < fullpads; i++) - { - if (!stream_putc (stream, (u_char) PADDING)) /* TAG */ - goto err; - if (!stream_putc (stream, (u_char) 255)) /* LENGHT */ - goto err; - stream_put (stream, NULL, 255); /* zero padding */ - } - - left = stream_get_size (stream) - stream_get_endp (stream); - - if (left < 2) - return ISIS_OK; - - if (left == 2) - { - stream_putc (stream, PADDING); - stream_putc (stream, 0); - return ISIS_OK; - } - - stream_putc (stream, PADDING); - stream_putc (stream, left - 2); - stream_put (stream, NULL, left-2); - - return ISIS_OK; + int fullpads, i, left; + + /* + * How many times can we add full padding ? + */ + fullpads = (stream_get_size(stream) - stream_get_endp(stream)) / 257; + for (i = 0; i < fullpads; i++) { + if (!stream_putc(stream, (u_char)PADDING)) /* TAG */ + goto err; + if (!stream_putc(stream, (u_char)255)) /* LENGHT */ + goto err; + stream_put(stream, NULL, 255); /* zero padding */ + } + + left = stream_get_size(stream) - stream_get_endp(stream); + + if (left < 2) + return ISIS_OK; + + if (left == 2) { + stream_putc(stream, PADDING); + stream_putc(stream, 0); + return ISIS_OK; + } + + stream_putc(stream, PADDING); + stream_putc(stream, left - 2); + stream_put(stream, NULL, left - 2); + + return ISIS_OK; err: - zlog_warn ("tlv_add_padding(): no room for tlv"); - return ISIS_WARNING; + zlog_warn("tlv_add_padding(): no room for tlv"); + return ISIS_WARNING; } diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h index e55e81bce..d06548519 100644 --- a/isisd/isis_tlv.h +++ b/isisd/isis_tlv.h @@ -3,17 +3,17 @@ * IS-IS TLV related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -134,54 +134,49 @@ #define MAX_SUBTLV_SIZE 256 /* struct for neighbor */ -struct is_neigh -{ - struct metric metrics; - u_char neigh_id[ISIS_SYS_ID_LEN + 1]; +struct is_neigh { + struct metric metrics; + u_char neigh_id[ISIS_SYS_ID_LEN + 1]; }; /* struct for te metric */ -struct te_is_neigh -{ - u_char neigh_id[ISIS_SYS_ID_LEN + 1]; - u_char te_metric[3]; - u_char sub_tlvs_length; - /* Theorical Maximum SubTLVs is 256 because the sub_tlvs_length is 8 bits */ - /* Practically, 118 bytes are necessary to store all supported TE parameters */ - /* FIXME: A pointer will use less memory, but need to be free */ - /* which is hard to fix, especially within free_tlvs() function */ - /* and malloc() / free() as a CPU cost compared to the memory usage */ - u_char sub_tlvs[MAX_SUBTLV_SIZE]; /* SUB TLVs storage */ +struct te_is_neigh { + u_char neigh_id[ISIS_SYS_ID_LEN + 1]; + u_char te_metric[3]; + u_char sub_tlvs_length; + /* Theorical Maximum SubTLVs is 256 because the sub_tlvs_length is 8 + * bits */ + /* Practically, 118 bytes are necessary to store all supported TE + * parameters */ + /* FIXME: A pointer will use less memory, but need to be free */ + /* which is hard to fix, especially within free_tlvs() function */ + /* and malloc() / free() as a CPU cost compared to the memory usage */ + u_char sub_tlvs[MAX_SUBTLV_SIZE]; /* SUB TLVs storage */ }; /* Decode and encode three-octet metric into host byte order integer */ -#define GET_TE_METRIC(t) \ - (((unsigned)(t)->te_metric[0]<<16) | ((t)->te_metric[1]<<8) | \ - (t)->te_metric[2]) -#define SET_TE_METRIC(t, m) \ - (((t)->te_metric[0] = (m) >> 16), \ - ((t)->te_metric[1] = (m) >> 8), \ - ((t)->te_metric[2] = (m))) +#define GET_TE_METRIC(t) \ + (((unsigned)(t)->te_metric[0] << 16) | ((t)->te_metric[1] << 8) \ + | (t)->te_metric[2]) +#define SET_TE_METRIC(t, m) \ + (((t)->te_metric[0] = (m) >> 16), ((t)->te_metric[1] = (m) >> 8), \ + ((t)->te_metric[2] = (m))) /* struct for es neighbors */ -struct es_neigh -{ - struct metric metrics; - /* approximate position of first, we use the - * length ((uchar*)metric-1) to know all */ - u_char first_es_neigh[ISIS_SYS_ID_LEN]; - +struct es_neigh { + struct metric metrics; + /* approximate position of first, we use the + * length ((uchar*)metric-1) to know all */ + u_char first_es_neigh[ISIS_SYS_ID_LEN]; }; -struct partition_desig_level2_is -{ - struct list *isis_system_ids; +struct partition_desig_level2_is { + struct list *isis_system_ids; }; /* struct for lan neighbors */ -struct lan_neigh -{ - u_char LAN_addr[6]; +struct lan_neigh { + u_char LAN_addr[6]; }; #ifdef __SUNPRO_C @@ -189,60 +184,54 @@ struct lan_neigh #endif /* struct for LSP entry */ -struct lsp_entry -{ - u_int16_t rem_lifetime; - u_char lsp_id[ISIS_SYS_ID_LEN + 2]; - u_int32_t seq_num; - u_int16_t checksum; -} __attribute__ ((packed)); +struct lsp_entry { + u_int16_t rem_lifetime; + u_char lsp_id[ISIS_SYS_ID_LEN + 2]; + u_int32_t seq_num; + u_int16_t checksum; +} __attribute__((packed)); #ifdef __SUNPRO_C #pragma pack() #endif /* struct for checksum */ -struct checksum -{ - u_int16_t checksum; +struct checksum { + u_int16_t checksum; }; /* ipv4 reachability */ -struct ipv4_reachability -{ - struct metric metrics; - struct in_addr prefix; - struct in_addr mask; +struct ipv4_reachability { + struct metric metrics; + struct in_addr prefix; + struct in_addr mask; }; /* te router id */ -struct te_router_id -{ - struct in_addr id; +struct te_router_id { + struct in_addr id; }; /* te ipv4 reachability */ -struct te_ipv4_reachability -{ - u_int32_t te_metric; - u_char control; - u_char prefix_start; /* since this is variable length by nature it only */ -}; /* points to an approximate location */ +struct te_ipv4_reachability { + u_int32_t te_metric; + u_char control; + u_char prefix_start; /* since this is variable length by nature it only + */ +}; /* points to an approximate location */ #define TE_IPV4_HAS_SUBTLV (0x40) -struct idrp_info -{ - u_char len; - u_char *value; +struct idrp_info { + u_char len; + u_char *value; }; -struct ipv6_reachability -{ - u_int32_t metric; - u_char control_info; - u_char prefix_len; - u_char prefix[16]; +struct ipv6_reachability { + u_int32_t metric; + u_char control_info; + u_char prefix_len; + u_char prefix[16]; }; /* bits in control_info */ @@ -256,39 +245,37 @@ struct ipv6_reachability #define CTRL_INFO_SUBTLVS 0x20 -struct mt_router_info -{ - ISIS_MT_INFO_FIELDS - bool overload; +struct mt_router_info { + ISIS_MT_INFO_FIELDS + bool overload; }; /* * Pointer to each tlv type, filled by parse_tlvs() */ -struct tlvs -{ - struct checksum *checksum; - struct hostname *hostname; - struct nlpids *nlpids; - struct te_router_id *router_id; - struct list *area_addrs; - struct list *mt_router_info; - struct list *is_neighs; - struct list *te_is_neighs; - struct list *mt_is_neighs; - struct list *es_neighs; - struct list *lsp_entries; - struct list *prefix_neighs; - struct list *lan_neighs; - struct list *ipv4_addrs; - struct list *ipv4_int_reachs; - struct list *ipv4_ext_reachs; - struct list *te_ipv4_reachs; - struct list *mt_ipv4_reachs; - struct list *ipv6_addrs; - struct list *ipv6_reachs; - struct list *mt_ipv6_reachs; - struct isis_passwd auth_info; +struct tlvs { + struct checksum *checksum; + struct hostname *hostname; + struct nlpids *nlpids; + struct te_router_id *router_id; + struct list *area_addrs; + struct list *mt_router_info; + struct list *is_neighs; + struct list *te_is_neighs; + struct list *mt_is_neighs; + struct list *es_neighs; + struct list *lsp_entries; + struct list *prefix_neighs; + struct list *lan_neighs; + struct list *ipv4_addrs; + struct list *ipv4_int_reachs; + struct list *ipv4_ext_reachs; + struct list *te_ipv4_reachs; + struct list *mt_ipv4_reachs; + struct list *ipv6_addrs; + struct list *ipv6_reachs; + struct list *mt_ipv6_reachs; + struct isis_passwd auth_info; }; /* @@ -319,34 +306,35 @@ struct tlvs #define TLVFLAG_GRACEFUL_RESTART (1<<21) #define TLVFLAG_MT_ROUTER_INFORMATION (1<<22) -void init_tlvs (struct tlvs *tlvs, uint32_t expected); -void free_tlvs (struct tlvs *tlvs); -int parse_tlvs (char *areatag, u_char * stream, int size, - u_int32_t * expected, u_int32_t * found, struct tlvs *tlvs, - u_int32_t * auth_tlv_offset); -int add_tlv (u_char, u_char, u_char *, struct stream *); -void free_tlv (void *val); - -int tlv_add_mt_router_info (struct list *mt_router_info, struct stream *stream); -int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream); -int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream); -unsigned int tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream, void *arg); -int tlv_add_lan_neighs (struct list *lan_neighs, struct stream *stream); -int tlv_add_nlpid (struct nlpids *nlpids, struct stream *stream); -int tlv_add_checksum (struct checksum *checksum, struct stream *stream); -int tlv_add_authinfo (u_char auth_type, u_char authlen, u_char *auth_value, - struct stream *stream); -int tlv_add_ip_addrs (struct list *ip_addrs, struct stream *stream); -int tlv_add_in_addr (struct in_addr *, struct stream *stream, u_char tag); -int tlv_add_dynamic_hostname (struct hostname *hostname, - struct stream *stream); -int tlv_add_lsp_entries (struct list *lsps, struct stream *stream); -int tlv_add_ipv4_int_reachs (struct list *ipv4_reachs, struct stream *stream); -int tlv_add_ipv4_ext_reachs (struct list *ipv4_reachs, struct stream *stream); -unsigned int tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream, void *arg); -int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream); -unsigned int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream, void *arg); - -int tlv_add_padding (struct stream *stream); +void init_tlvs(struct tlvs *tlvs, uint32_t expected); +void free_tlvs(struct tlvs *tlvs); +int parse_tlvs(char *areatag, u_char *stream, int size, u_int32_t *expected, + u_int32_t *found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset); +int add_tlv(u_char, u_char, u_char *, struct stream *); +void free_tlv(void *val); + +int tlv_add_mt_router_info(struct list *mt_router_info, struct stream *stream); +int tlv_add_area_addrs(struct list *area_addrs, struct stream *stream); +int tlv_add_is_neighs(struct list *is_neighs, struct stream *stream); +unsigned int tlv_add_te_is_neighs(struct list *te_is_neighs, + struct stream *stream, void *arg); +int tlv_add_lan_neighs(struct list *lan_neighs, struct stream *stream); +int tlv_add_nlpid(struct nlpids *nlpids, struct stream *stream); +int tlv_add_checksum(struct checksum *checksum, struct stream *stream); +int tlv_add_authinfo(u_char auth_type, u_char authlen, u_char *auth_value, + struct stream *stream); +int tlv_add_ip_addrs(struct list *ip_addrs, struct stream *stream); +int tlv_add_in_addr(struct in_addr *, struct stream *stream, u_char tag); +int tlv_add_dynamic_hostname(struct hostname *hostname, struct stream *stream); +int tlv_add_lsp_entries(struct list *lsps, struct stream *stream); +int tlv_add_ipv4_int_reachs(struct list *ipv4_reachs, struct stream *stream); +int tlv_add_ipv4_ext_reachs(struct list *ipv4_reachs, struct stream *stream); +unsigned int tlv_add_te_ipv4_reachs(struct list *te_ipv4_reachs, + struct stream *stream, void *arg); +int tlv_add_ipv6_addrs(struct list *ipv6_addrs, struct stream *stream); +unsigned int tlv_add_ipv6_reachs(struct list *ipv6_reachs, + struct stream *stream, void *arg); + +int tlv_add_padding(struct stream *stream); #endif /* _ZEBRA_ISIS_TLV_H */ diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c index 157962dad..2a19465a0 100644 --- a/isisd/isis_vty.c +++ b/isisd/isis_vty.c @@ -2,18 +2,18 @@ * IS-IS Rout(e)ing protocol - isis_circuit.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -32,27 +32,23 @@ #include "isis_mt.h" #include "isisd.h" -static struct isis_circuit * -isis_circuit_lookup (struct vty *vty) +static struct isis_circuit *isis_circuit_lookup(struct vty *vty) { - struct interface *ifp = VTY_GET_CONTEXT(interface); - struct isis_circuit *circuit; + struct interface *ifp = VTY_GET_CONTEXT(interface); + struct isis_circuit *circuit; - if (!ifp) - { - vty_out (vty, "Invalid interface \n"); - return NULL; - } + if (!ifp) { + vty_out(vty, "Invalid interface \n"); + return NULL; + } - circuit = circuit_scan_by_ifp (ifp); - if (!circuit) - { - vty_out (vty, "ISIS is not enabled on circuit %s\n", - ifp->name); - return NULL; - } + circuit = circuit_scan_by_ifp(ifp); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return NULL; + } - return circuit; + return circuit; } DEFUN (ip_router_isis, @@ -63,48 +59,47 @@ DEFUN (ip_router_isis, "IS-IS Routing for IP\n" "Routing process tag\n") { - int idx_afi = 0; - int idx_word = 3; - VTY_DECLVAR_CONTEXT (interface, ifp); - struct isis_circuit *circuit; - struct isis_area *area; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - /* Prevent more than one area per circuit */ - circuit = circuit_scan_by_ifp (ifp); - if (circuit && circuit->area) - { - if (strcmp (circuit->area->area_tag, area_tag)) - { - vty_out (vty, "ISIS circuit is already defined on %s\n", - circuit->area->area_tag); - return CMD_ERR_NOTHING_TODO; - } - } - - area = isis_area_lookup (area_tag); - if (!area) - area = isis_area_create (area_tag); - - if (!circuit || !circuit->area) { - circuit = isis_circuit_create (area, ifp); - - if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP) - { - vty_out (vty, "Couldn't bring up interface, please check log.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = true; - else - ip = true; - - isis_circuit_af_set (circuit, ip, ipv6); - return CMD_SUCCESS; + int idx_afi = 0; + int idx_word = 3; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_circuit *circuit; + struct isis_area *area; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + /* Prevent more than one area per circuit */ + circuit = circuit_scan_by_ifp(ifp); + if (circuit && circuit->area) { + if (strcmp(circuit->area->area_tag, area_tag)) { + vty_out(vty, "ISIS circuit is already defined on %s\n", + circuit->area->area_tag); + return CMD_ERR_NOTHING_TODO; + } + } + + area = isis_area_lookup(area_tag); + if (!area) + area = isis_area_create(area_tag); + + if (!circuit || !circuit->area) { + circuit = isis_circuit_create(area, ifp); + + if (circuit->state != C_STATE_CONF + && circuit->state != C_STATE_UP) { + vty_out(vty, + "Couldn't bring up interface, please check log.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = true; + else + ip = true; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; } DEFUN (ip6_router_isis, @@ -115,7 +110,7 @@ DEFUN (ip6_router_isis, "IS-IS Routing for IP\n" "Routing process tag\n") { - return ip_router_isis (self, vty, argc, argv); + return ip_router_isis(self, vty, argc, argv); } DEFUN (no_ip_router_isis, @@ -128,38 +123,35 @@ DEFUN (no_ip_router_isis, "IS-IS Routing for IP\n" "Routing process tag\n") { - int idx_afi = 1; - int idx_word = 4; - VTY_DECLVAR_CONTEXT (interface, ifp); - struct isis_area *area; - struct isis_circuit *circuit; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - area = isis_area_lookup (area_tag); - if (!area) - { - vty_out (vty, "Can't find ISIS instance %s\n", - argv[idx_afi]->arg); - return CMD_ERR_NO_MATCH; - } - - circuit = circuit_lookup_by_ifp (ifp, area->circuit_list); - if (!circuit) - { - vty_out (vty, "ISIS is not enabled on circuit %s\n", - ifp->name); - return CMD_ERR_NO_MATCH; - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = false; - else - ip = false; - - isis_circuit_af_set (circuit, ip, ipv6); - return CMD_SUCCESS; + int idx_afi = 1; + int idx_word = 4; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_area *area; + struct isis_circuit *circuit; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + area = isis_area_lookup(area_tag); + if (!area) { + vty_out(vty, "Can't find ISIS instance %s\n", + argv[idx_afi]->arg); + return CMD_ERR_NO_MATCH; + } + + circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return CMD_ERR_NO_MATCH; + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = false; + else + ip = false; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; } DEFUN (isis_passive, @@ -168,12 +160,12 @@ DEFUN (isis_passive, "IS-IS commands\n" "Configure the passive mode for interface\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - isis_circuit_passive_set (circuit, 1); - return CMD_SUCCESS; + isis_circuit_passive_set(circuit, 1); + return CMD_SUCCESS; } DEFUN (no_isis_passive, @@ -183,18 +175,17 @@ DEFUN (no_isis_passive, "IS-IS commands\n" "Configure the passive mode for interface\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - if (if_is_loopback (circuit->interface)) - { - vty_out (vty,"Can't set no passive for loopback interface\n"); - return CMD_ERR_AMBIGUOUS; - } + if (if_is_loopback(circuit->interface)) { + vty_out(vty, "Can't set no passive for loopback interface\n"); + return CMD_ERR_AMBIGUOUS; + } - isis_circuit_passive_set (circuit, 0); - return CMD_SUCCESS; + isis_circuit_passive_set(circuit, 0); + return CMD_SUCCESS; } DEFUN (isis_circuit_type, @@ -206,30 +197,28 @@ DEFUN (isis_circuit_type, "Level-1-2 adjacencies are formed\n" "Level-2 only adjacencies are formed\n") { - int idx_level = 2; - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_level = 2; + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - is_type = string2circuit_t (argv[idx_level]->arg); - if (!is_type) - { - vty_out (vty, "Unknown circuit-type \n"); - return CMD_ERR_AMBIGUOUS; - } + is_type = string2circuit_t(argv[idx_level]->arg); + if (!is_type) { + vty_out(vty, "Unknown circuit-type \n"); + return CMD_ERR_AMBIGUOUS; + } - if (circuit->state == C_STATE_UP && - circuit->area->is_type != IS_LEVEL_1_AND_2 && - circuit->area->is_type != is_type) - { - vty_out (vty, "Invalid circuit level for area %s.\n", - circuit->area->area_tag); - return CMD_ERR_AMBIGUOUS; - } - isis_circuit_is_type_set (circuit, is_type); + if (circuit->state == C_STATE_UP + && circuit->area->is_type != IS_LEVEL_1_AND_2 + && circuit->area->is_type != is_type) { + vty_out(vty, "Invalid circuit level for area %s.\n", + circuit->area->area_tag); + return CMD_ERR_AMBIGUOUS; + } + isis_circuit_is_type_set(circuit, is_type); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_circuit_type, @@ -242,21 +231,21 @@ DEFUN (no_isis_circuit_type, "Level-1-2 adjacencies are formed\n" "Level-2 only adjacencies are formed\n") { - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - /* - * Set the circuits level to its default value - */ - if (circuit->state == C_STATE_UP) - is_type = circuit->area->is_type; - else - is_type = IS_LEVEL_1_AND_2; - isis_circuit_is_type_set (circuit, is_type); + /* + * Set the circuits level to its default value + */ + if (circuit->state == C_STATE_UP) + is_type = circuit->area->is_type; + else + is_type = IS_LEVEL_1_AND_2; + isis_circuit_is_type_set(circuit, is_type); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (isis_network, @@ -266,18 +255,17 @@ DEFUN (isis_network, "Set network type\n" "point-to-point network type\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) - { - vty_out (vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_ERR_AMBIGUOUS; - } + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_ERR_AMBIGUOUS; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_network, @@ -288,18 +276,17 @@ DEFUN (no_isis_network, "Set network type for circuit\n" "point-to-point network type\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) - { - vty_out (vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_ERR_AMBIGUOUS; - } + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_ERR_AMBIGUOUS; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (isis_passwd, @@ -311,24 +298,25 @@ DEFUN (isis_passwd, "Cleartext password\n" "Circuit password\n") { - int idx_encryption = 2; - int idx_word = 3; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - int rv; - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_encryption = 2; + int idx_word = 3; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int rv; + if (!circuit) + return CMD_ERR_NO_MATCH; - if (argv[idx_encryption]->arg[0] == 'm') - rv = isis_circuit_passwd_hmac_md5_set(circuit, argv[idx_word]->arg); - else - rv = isis_circuit_passwd_cleartext_set(circuit, argv[idx_word]->arg); - if (rv) - { - vty_out (vty, "Too long circuit password (>254)\n"); - return CMD_ERR_AMBIGUOUS; - } + if (argv[idx_encryption]->arg[0] == 'm') + rv = isis_circuit_passwd_hmac_md5_set(circuit, + argv[idx_word]->arg); + else + rv = isis_circuit_passwd_cleartext_set(circuit, + argv[idx_word]->arg); + if (rv) { + vty_out(vty, "Too long circuit password (>254)\n"); + return CMD_ERR_AMBIGUOUS; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_passwd, @@ -341,13 +329,13 @@ DEFUN (no_isis_passwd, "Cleartext password\n" "Circuit password\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - isis_circuit_passwd_unset(circuit); + isis_circuit_passwd_unset(circuit); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -358,24 +346,22 @@ DEFUN (isis_priority, "Set priority for Designated Router election\n" "Priority value\n") { - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int prio; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - prio = atoi (argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) - { - vty_out (vty, "Invalid priority %d - should be <0-127>\n", - prio); - return CMD_ERR_AMBIGUOUS; - } + prio = atoi(argv[idx_number]->arg); + if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { + vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); + return CMD_ERR_AMBIGUOUS; + } - circuit->priority[0] = prio; - circuit->priority[1] = prio; + circuit->priority[0] = prio; + circuit->priority[1] = prio; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_priority, @@ -386,14 +372,14 @@ DEFUN (no_isis_priority, "Set priority for Designated Router election\n" "Priority value\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->priority[0] = DEFAULT_PRIORITY; - circuit->priority[1] = DEFAULT_PRIORITY; + circuit->priority[0] = DEFAULT_PRIORITY; + circuit->priority[1] = DEFAULT_PRIORITY; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -405,23 +391,21 @@ DEFUN (isis_priority_l1, "Priority value\n" "Specify priority for level-1 routing\n") { - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int prio; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - prio = atoi (argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) - { - vty_out (vty, "Invalid priority %d - should be <0-127>\n", - prio); - return CMD_ERR_AMBIGUOUS; - } + prio = atoi(argv[idx_number]->arg); + if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { + vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); + return CMD_ERR_AMBIGUOUS; + } - circuit->priority[0] = prio; + circuit->priority[0] = prio; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_priority_l1, @@ -433,13 +417,13 @@ DEFUN (no_isis_priority_l1, "Priority value\n" "Specify priority for level-1 routing\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->priority[0] = DEFAULT_PRIORITY; + circuit->priority[0] = DEFAULT_PRIORITY; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -451,23 +435,21 @@ DEFUN (isis_priority_l2, "Priority value\n" "Specify priority for level-2 routing\n") { - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int prio; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - prio = atoi (argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) - { - vty_out (vty, "Invalid priority %d - should be <0-127>\n", - prio); - return CMD_ERR_AMBIGUOUS; - } + prio = atoi(argv[idx_number]->arg); + if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { + vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); + return CMD_ERR_AMBIGUOUS; + } - circuit->priority[1] = prio; + circuit->priority[1] = prio; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_priority_l2, @@ -479,13 +461,13 @@ DEFUN (no_isis_priority_l2, "Priority value\n" "Specify priority for level-2 routing\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->priority[1] = DEFAULT_PRIORITY; + circuit->priority[1] = DEFAULT_PRIORITY; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -497,37 +479,37 @@ DEFUN (isis_metric, "Set default metric for circuit\n" "Default metric value\n") { - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int met; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - met = atoi (argv[idx_number]->arg); + met = atoi(argv[idx_number]->arg); - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 && - met > MAX_NARROW_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC3787 section 5.1 */ + if (circuit->area && circuit->area->oldmetric == 1 + && met > MAX_NARROW_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-63> " + "when narrow metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 && - met > MAX_WIDE_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC4444 */ + if (circuit->area && circuit->area->newmetric == 1 + && met > MAX_WIDE_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-16777215> " + "when wide metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - isis_circuit_metric_set (circuit, IS_LEVEL_1, met); - isis_circuit_metric_set (circuit, IS_LEVEL_2, met); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_1, met); + isis_circuit_metric_set(circuit, IS_LEVEL_2, met); + return CMD_SUCCESS; } @@ -539,13 +521,13 @@ DEFUN (no_isis_metric, "Set default metric for circuit\n" "Default metric value\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - isis_circuit_metric_set (circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC); - isis_circuit_metric_set (circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC); + isis_circuit_metric_set(circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC); + return CMD_SUCCESS; } @@ -557,36 +539,36 @@ DEFUN (isis_metric_l1, "Default metric value\n" "Specify metric for level-1 routing\n") { - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int met; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - met = atoi (argv[idx_number]->arg); + met = atoi(argv[idx_number]->arg); - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 && - met > MAX_NARROW_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC3787 section 5.1 */ + if (circuit->area && circuit->area->oldmetric == 1 + && met > MAX_NARROW_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-63> " + "when narrow metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 && - met > MAX_WIDE_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC4444 */ + if (circuit->area && circuit->area->newmetric == 1 + && met > MAX_WIDE_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-16777215> " + "when wide metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - isis_circuit_metric_set (circuit, IS_LEVEL_1, met); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_1, met); + return CMD_SUCCESS; } @@ -599,12 +581,12 @@ DEFUN (no_isis_metric_l1, "Default metric value\n" "Specify metric for level-1 routing\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - isis_circuit_metric_set (circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC); + return CMD_SUCCESS; } @@ -616,36 +598,36 @@ DEFUN (isis_metric_l2, "Default metric value\n" "Specify metric for level-2 routing\n") { - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int met; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - met = atoi (argv[idx_number]->arg); + met = atoi(argv[idx_number]->arg); - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 && - met > MAX_NARROW_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC3787 section 5.1 */ + if (circuit->area && circuit->area->oldmetric == 1 + && met > MAX_NARROW_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-63> " + "when narrow metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 && - met > MAX_WIDE_LINK_METRIC) - { - vty_out (vty, "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_ERR_AMBIGUOUS; - } + /* RFC4444 */ + if (circuit->area && circuit->area->newmetric == 1 + && met > MAX_WIDE_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-16777215> " + "when wide metric type enabled\n", + met); + return CMD_ERR_AMBIGUOUS; + } - isis_circuit_metric_set (circuit, IS_LEVEL_2, met); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_2, met); + return CMD_SUCCESS; } @@ -658,12 +640,12 @@ DEFUN (no_isis_metric_l2, "Default metric value\n" "Specify metric for level-2 routing\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - isis_circuit_metric_set (circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC); - return CMD_SUCCESS; + isis_circuit_metric_set(circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC); + return CMD_SUCCESS; } /* end of metrics */ @@ -675,24 +657,23 @@ DEFUN (isis_hello_interval, "Set Hello interval\n" "Holdtime 1 seconds, interval depends on multiplier\n") { - int idx_number = 2; - int interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atoi (argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) - { - vty_out (vty, "Invalid hello-interval %d - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atoi(argv[idx_number]->arg); + if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { + vty_out(vty, "Invalid hello-interval %d - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_interval[0] = (u_int16_t) interval; - circuit->hello_interval[1] = (u_int16_t) interval; + circuit->hello_interval[0] = (u_int16_t)interval; + circuit->hello_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -704,14 +685,14 @@ DEFUN (no_isis_hello_interval, "Set Hello interval\n" "Holdtime 1 second, interval depends on multiplier\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -723,23 +704,22 @@ DEFUN (isis_hello_interval_l1, "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-1 IIHs\n") { - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atoi (argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) - { - vty_out (vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atoi(argv[idx_number]->arg); + if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { + vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_interval[0] = (u_int16_t) interval; + circuit->hello_interval[0] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -752,13 +732,13 @@ DEFUN (no_isis_hello_interval_l1, "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-1 IIHs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -770,23 +750,22 @@ DEFUN (isis_hello_interval_l2, "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-2 IIHs\n") { - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atoi (argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) - { - vty_out (vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atoi(argv[idx_number]->arg); + if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { + vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_interval[1] = (u_int16_t) interval; + circuit->hello_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -799,13 +778,13 @@ DEFUN (no_isis_hello_interval_l2, "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-2 IIHs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -816,24 +795,24 @@ DEFUN (isis_hello_multiplier, "Set multiplier for Hello holding time\n" "Hello multiplier value\n") { - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int mult; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - mult = atoi (argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) - { - vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_ERR_AMBIGUOUS; - } + mult = atoi(argv[idx_number]->arg); + if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { + vty_out(vty, + "Invalid hello-multiplier %d - should be <2-100>\n", + mult); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_multiplier[0] = (u_int16_t) mult; - circuit->hello_multiplier[1] = (u_int16_t) mult; + circuit->hello_multiplier[0] = (u_int16_t)mult; + circuit->hello_multiplier[1] = (u_int16_t)mult; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -845,14 +824,14 @@ DEFUN (no_isis_hello_multiplier, "Set multiplier for Hello holding time\n" "Hello multiplier value\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -864,23 +843,23 @@ DEFUN (isis_hello_multiplier_l1, "Hello multiplier value\n" "Specify hello multiplier for level-1 IIHs\n") { - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int mult; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - mult = atoi (argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) - { - vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_ERR_AMBIGUOUS; - } + mult = atoi(argv[idx_number]->arg); + if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { + vty_out(vty, + "Invalid hello-multiplier %d - should be <2-100>\n", + mult); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_multiplier[0] = (u_int16_t) mult; + circuit->hello_multiplier[0] = (u_int16_t)mult; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -893,13 +872,13 @@ DEFUN (no_isis_hello_multiplier_l1, "Hello multiplier value\n" "Specify hello multiplier for level-1 IIHs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -911,23 +890,23 @@ DEFUN (isis_hello_multiplier_l2, "Hello multiplier value\n" "Specify hello multiplier for level-2 IIHs\n") { - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + int mult; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - mult = atoi (argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) - { - vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_ERR_AMBIGUOUS; - } + mult = atoi(argv[idx_number]->arg); + if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { + vty_out(vty, + "Invalid hello-multiplier %d - should be <2-100>\n", + mult); + return CMD_ERR_AMBIGUOUS; + } - circuit->hello_multiplier[1] = (u_int16_t) mult; + circuit->hello_multiplier[1] = (u_int16_t)mult; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -940,13 +919,13 @@ DEFUN (no_isis_hello_multiplier_l2, "Hello multiplier value\n" "Specify hello multiplier for level-2 IIHs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -957,13 +936,13 @@ DEFUN (isis_hello_padding, "Add padding to IS-IS hello packets\n" "Pad hello packets\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->pad_hellos = 1; + circuit->pad_hellos = 1; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_isis_hello_padding, @@ -974,13 +953,13 @@ DEFUN (no_isis_hello_padding, "Add padding to IS-IS hello packets\n" "Pad hello packets\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->pad_hellos = 0; + circuit->pad_hellos = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (csnp_interval, @@ -990,24 +969,23 @@ DEFUN (csnp_interval, "Set CSNP interval in seconds\n" "CSNP interval value\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) - { - vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { + vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->csnp_interval[0] = (u_int16_t) interval; - circuit->csnp_interval[1] = (u_int16_t) interval; + circuit->csnp_interval[0] = (u_int16_t)interval; + circuit->csnp_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1019,14 +997,14 @@ DEFUN (no_csnp_interval, "Set CSNP interval in seconds\n" "CSNP interval value\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1038,23 +1016,22 @@ DEFUN (csnp_interval_l1, "CSNP interval value\n" "Specify interval for level-1 CSNPs\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) - { - vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { + vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->csnp_interval[0] = (u_int16_t) interval; + circuit->csnp_interval[0] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1067,13 +1044,13 @@ DEFUN (no_csnp_interval_l1, "CSNP interval value\n" "Specify interval for level-1 CSNPs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1085,23 +1062,22 @@ DEFUN (csnp_interval_l2, "CSNP interval value\n" "Specify interval for level-2 CSNPs\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) - { - vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { + vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->csnp_interval[1] = (u_int16_t) interval; + circuit->csnp_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1114,13 +1090,13 @@ DEFUN (no_csnp_interval_l2, "CSNP interval value\n" "Specify interval for level-2 CSNPs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1131,24 +1107,23 @@ DEFUN (psnp_interval, "Set PSNP interval in seconds\n" "PSNP interval value\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) - { - vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { + vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->psnp_interval[0] = (u_int16_t) interval; - circuit->psnp_interval[1] = (u_int16_t) interval; + circuit->psnp_interval[0] = (u_int16_t)interval; + circuit->psnp_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1160,14 +1135,14 @@ DEFUN (no_psnp_interval, "Set PSNP interval in seconds\n" "PSNP interval value\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1179,23 +1154,22 @@ DEFUN (psnp_interval_l1, "PSNP interval value\n" "Specify interval for level-1 PSNPs\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) - { - vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { + vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->psnp_interval[0] = (u_int16_t) interval; + circuit->psnp_interval[0] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1208,13 +1182,13 @@ DEFUN (no_psnp_interval_l1, "PSNP interval value\n" "Specify interval for level-1 PSNPs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1226,23 +1200,22 @@ DEFUN (psnp_interval_l2, "PSNP interval value\n" "Specify interval for level-2 PSNPs\n") { - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + int idx_number = 2; + unsigned long interval; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - interval = atol (argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) - { - vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_ERR_AMBIGUOUS; - } + interval = atol(argv[idx_number]->arg); + if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { + vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", + interval); + return CMD_ERR_AMBIGUOUS; + } - circuit->psnp_interval[1] = (u_int16_t) interval; + circuit->psnp_interval[1] = (u_int16_t)interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1255,13 +1228,13 @@ DEFUN (no_psnp_interval_l2, "PSNP interval value\n" "Specify interval for level-2 PSNPs\n") { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (circuit_topology, @@ -1271,26 +1244,24 @@ DEFUN (circuit_topology, "Configure interface IS-IS topologies\n" ISIS_MT_DESCRIPTIONS) { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[2]->arg; - uint16_t mtid = isis_str2mtid(arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[2]->arg; + uint16_t mtid = isis_str2mtid(arg); - if (circuit->area && circuit->area->oldmetric) - { - vty_out (vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; - } + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_ERR_AMBIGUOUS; + } - if (mtid == (uint16_t)-1) - { - vty_out (vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; - } + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_ERR_AMBIGUOUS; + } - return isis_circuit_mt_enabled_set(circuit, mtid, true); + return isis_circuit_mt_enabled_set(circuit, mtid, true); } DEFUN (no_circuit_topology, @@ -1301,64 +1272,57 @@ DEFUN (no_circuit_topology, "Configure interface IS-IS topologies\n" ISIS_MT_DESCRIPTIONS) { - struct isis_circuit *circuit = isis_circuit_lookup (vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[3]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) - { - vty_out (vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; - } - - if (mtid == (uint16_t)-1) - { - vty_out (vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, false); -} - -static int -validate_metric_style_narrow (struct vty *vty, struct isis_area *area) -{ - struct isis_circuit *circuit; - struct listnode *node; - - if (! vty) - return CMD_ERR_AMBIGUOUS; - - if (! area) - { - vty_out (vty, "ISIS area is invalid\n"); - return CMD_ERR_AMBIGUOUS; - } - - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) - { - if ((area->is_type & IS_LEVEL_1) && - (circuit->is_type & IS_LEVEL_1) && - (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) - { - vty_out (vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_ERR_AMBIGUOUS; - } - if ((area->is_type & IS_LEVEL_2) && - (circuit->is_type & IS_LEVEL_2) && - (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) - { - vty_out (vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_ERR_AMBIGUOUS; - } - } - - return CMD_SUCCESS; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[3]->arg; + uint16_t mtid = isis_str2mtid(arg); + + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_ERR_AMBIGUOUS; + } + + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_ERR_AMBIGUOUS; + } + + return isis_circuit_mt_enabled_set(circuit, mtid, false); +} + +static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) +{ + struct isis_circuit *circuit; + struct listnode *node; + + if (!vty) + return CMD_ERR_AMBIGUOUS; + + if (!area) { + vty_out(vty, "ISIS area is invalid\n"); + return CMD_ERR_AMBIGUOUS; + } + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if ((area->is_type & IS_LEVEL_1) + && (circuit->is_type & IS_LEVEL_1) + && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_ERR_AMBIGUOUS; + } + if ((area->is_type & IS_LEVEL_2) + && (circuit->is_type & IS_LEVEL_2) + && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_ERR_AMBIGUOUS; + } + } + + return CMD_SUCCESS; } DEFUN (metric_style, @@ -1369,34 +1333,32 @@ DEFUN (metric_style, "Send and accept both styles of TLVs during transition\n" "Use new style of TLVs to carry wider metric\n") { - int idx_metric_style = 1; - VTY_DECLVAR_CONTEXT (isis_area, area); - int ret; + int idx_metric_style = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; - if (strncmp (argv[idx_metric_style]->arg, "w", 1) == 0) - { - isis_area_metricstyle_set(area, false, true); - return CMD_SUCCESS; - } + if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { + isis_area_metricstyle_set(area, false, true); + return CMD_SUCCESS; + } - if (area_is_mt(area)) - { - vty_out (vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_ERR_AMBIGUOUS; - } + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_ERR_AMBIGUOUS; + } - ret = validate_metric_style_narrow (vty, area); - if (ret != CMD_SUCCESS) - return ret; + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; - if (strncmp (argv[idx_metric_style]->arg, "t", 1) == 0) - isis_area_metricstyle_set(area, true, true); - else if (strncmp (argv[idx_metric_style]->arg, "n", 1) == 0) - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; + if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) + isis_area_metricstyle_set(area, true, true); + else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_metric_style, @@ -1405,22 +1367,21 @@ DEFUN (no_metric_style, NO_STR "Use old-style (ISO 10589) or new-style packet formats\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); - int ret; + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; - if (area_is_mt(area)) - { - vty_out (vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_ERR_AMBIGUOUS; - } + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_ERR_AMBIGUOUS; + } - ret = validate_metric_style_narrow (vty, area); - if (ret != CMD_SUCCESS) - return ret; + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; } DEFUN (set_overload_bit, @@ -1428,10 +1389,10 @@ DEFUN (set_overload_bit, "set-overload-bit", "Set overload bit to avoid any transit traffic\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_overload_bit_set(area, true); - return CMD_SUCCESS; + isis_area_overload_bit_set(area, true); + return CMD_SUCCESS; } DEFUN (no_set_overload_bit, @@ -1440,10 +1401,10 @@ DEFUN (no_set_overload_bit, "Reset overload bit to accept transit traffic\n" "Reset overload bit\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_overload_bit_set(area, false); - return CMD_SUCCESS; + isis_area_overload_bit_set(area, false); + return CMD_SUCCESS; } DEFUN (set_attached_bit, @@ -1451,10 +1412,10 @@ DEFUN (set_attached_bit, "set-attached-bit", "Set attached bit to identify as L1/L2 router for inter-area traffic\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_attached_bit_set(area, true); - return CMD_SUCCESS; + isis_area_attached_bit_set(area, true); + return CMD_SUCCESS; } DEFUN (no_set_attached_bit, @@ -1463,10 +1424,10 @@ DEFUN (no_set_attached_bit, NO_STR "Reset attached bit\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_attached_bit_set(area, false); - return CMD_SUCCESS; + isis_area_attached_bit_set(area, false); + return CMD_SUCCESS; } DEFUN (dynamic_hostname, @@ -1475,10 +1436,10 @@ DEFUN (dynamic_hostname, "Dynamic hostname for IS-IS\n" "Dynamic hostname\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_dynhostname_set(area, true); - return CMD_SUCCESS; + isis_area_dynhostname_set(area, true); + return CMD_SUCCESS; } DEFUN (no_dynamic_hostname, @@ -1488,32 +1449,33 @@ DEFUN (no_dynamic_hostname, "Dynamic hostname for IS-IS\n" "Dynamic hostname\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - isis_area_dynhostname_set(area, false); - return CMD_SUCCESS; + isis_area_dynhostname_set(area, false); + return CMD_SUCCESS; } static int area_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) { - VTY_DECLVAR_CONTEXT (isis_area, area); - struct listnode *node; - struct isis_circuit *circuit; + VTY_DECLVAR_CONTEXT(isis_area, area); + struct listnode *node; + struct isis_circuit *circuit; - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) - { - if(circuit->state != C_STATE_INIT && circuit->state != C_STATE_UP) - continue; - if(lsp_mtu > isis_circuit_pdu_size(circuit)) - { - vty_out (vty, "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", - circuit->interface->name,isis_circuit_pdu_size(circuit)); - return CMD_ERR_AMBIGUOUS; - } - } + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (circuit->state != C_STATE_INIT + && circuit->state != C_STATE_UP) + continue; + if (lsp_mtu > isis_circuit_pdu_size(circuit)) { + vty_out(vty, + "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", + circuit->interface->name, + isis_circuit_pdu_size(circuit)); + return CMD_ERR_AMBIGUOUS; + } + } - isis_area_lsp_mtu_set(area, lsp_mtu); - return CMD_SUCCESS; + isis_area_lsp_mtu_set(area, lsp_mtu); + return CMD_SUCCESS; } DEFUN (area_lsp_mtu, @@ -1522,12 +1484,12 @@ DEFUN (area_lsp_mtu, "Configure the maximum size of generated LSPs\n" "Maximum size of generated LSPs\n") { - int idx_number = 1; - unsigned int lsp_mtu; + int idx_number = 1; + unsigned int lsp_mtu; - lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); + lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); - return area_lsp_mtu_set(vty, lsp_mtu); + return area_lsp_mtu_set(vty, lsp_mtu); } @@ -1538,7 +1500,7 @@ DEFUN (no_area_lsp_mtu, "Configure the maximum size of generated LSPs\n" "Maximum size of generated LSPs\n") { - return area_lsp_mtu_set(vty, DEFAULT_LSP_MTU); + return area_lsp_mtu_set(vty, DEFAULT_LSP_MTU); } @@ -1550,20 +1512,19 @@ DEFUN (is_type, "Act as both a station router and an area router\n" "Act as an area router only\n") { - int idx_level = 1; - VTY_DECLVAR_CONTEXT (isis_area, area); - int type; + int idx_level = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; - type = string2circuit_t (argv[idx_level]->arg); - if (!type) - { - vty_out (vty, "Unknown IS level \n"); - return CMD_SUCCESS; - } + type = string2circuit_t(argv[idx_level]->arg); + if (!type) { + vty_out(vty, "Unknown IS level \n"); + return CMD_SUCCESS; + } - isis_area_is_type_set(area, type); + isis_area_is_type_set(area, type); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_is_type, @@ -1575,52 +1536,49 @@ DEFUN (no_is_type, "Act as both a station router and an area router\n" "Act as an area router only\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); - int type; + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; - /* - * Put the is-type back to defaults: - * - level-1-2 on first area - * - level-1 for the rest - */ - if (listgetdata (listhead (isis->area_list)) == area) - type = IS_LEVEL_1_AND_2; - else - type = IS_LEVEL_1; + /* + * Put the is-type back to defaults: + * - level-1-2 on first area + * - level-1 for the rest + */ + if (listgetdata(listhead(isis->area_list)) == area) + type = IS_LEVEL_1_AND_2; + else + type = IS_LEVEL_1; - isis_area_is_type_set(area, type); + isis_area_is_type_set(area, type); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -set_lsp_gen_interval (struct vty *vty, struct isis_area *area, - uint16_t interval, int level) +static int set_lsp_gen_interval(struct vty *vty, struct isis_area *area, + uint16_t interval, int level) { - int lvl; + int lvl; - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) - { - if (!(lvl & level)) - continue; + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; - if (interval >= area->lsp_refresh[lvl-1]) - { - vty_out (vty, "LSP gen interval %us must be less than " - "the LSP refresh interval %us\n", - interval, area->lsp_refresh[lvl - 1]); - return CMD_ERR_AMBIGUOUS; - } - } + if (interval >= area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "LSP gen interval %us must be less than " + "the LSP refresh interval %us\n", + interval, area->lsp_refresh[lvl - 1]); + return CMD_ERR_AMBIGUOUS; + } + } - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) - { - if (!(lvl & level)) - continue; - area->lsp_gen_interval[lvl-1] = interval; - } + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + area->lsp_gen_interval[lvl - 1] = interval; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (lsp_gen_interval, @@ -1631,21 +1589,21 @@ DEFUN (lsp_gen_interval, "Set interval for level 2 only\n" "Minimum interval in seconds\n") { - int idx = 0; - VTY_DECLVAR_CONTEXT (isis_area, area); - uint16_t interval; - int level; + int idx = 0; + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval; + int level; - level = 0; - level |= argv_find (argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find (argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; + level = 0; + level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; + level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; + if (!level) + level = IS_LEVEL_1 | IS_LEVEL_2; - argv_find (argv, argc, "(1-120)", &idx); + argv_find(argv, argc, "(1-120)", &idx); - interval = atoi (argv[idx]->arg); - return set_lsp_gen_interval (vty, area, interval, level); + interval = atoi(argv[idx]->arg); + return set_lsp_gen_interval(vty, area, interval, level); } DEFUN (no_lsp_gen_interval, @@ -1657,19 +1615,19 @@ DEFUN (no_lsp_gen_interval, "Set interval for level 2 only\n" "Minimum interval in seconds\n") { - int idx = 0; - VTY_DECLVAR_CONTEXT (isis_area, area); - uint16_t interval; - int level; + int idx = 0; + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval; + int level; - level = 0; - level |= argv_find (argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find (argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; + level = 0; + level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; + level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; + if (!level) + level = IS_LEVEL_1 | IS_LEVEL_2; - interval = DEFAULT_MIN_LSP_GEN_INTERVAL; - return set_lsp_gen_interval (vty, area, interval, level); + interval = DEFAULT_MIN_LSP_GEN_INTERVAL; + return set_lsp_gen_interval(vty, area, interval, level); } DEFUN (spf_interval, @@ -1678,15 +1636,15 @@ DEFUN (spf_interval, "Minimum interval between SPF calculations\n" "Minimum interval between consecutive SPFs in seconds\n") { - int idx_number = 1; - VTY_DECLVAR_CONTEXT (isis_area, area); - u_int16_t interval; + int idx_number = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + u_int16_t interval; - interval = atoi (argv[idx_number]->arg); - area->min_spf_interval[0] = interval; - area->min_spf_interval[1] = interval; + interval = atoi(argv[idx_number]->arg); + area->min_spf_interval[0] = interval; + area->min_spf_interval[1] = interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1699,12 +1657,12 @@ DEFUN (no_spf_interval, "Set interval for level 2 only\n" "Minimum interval between consecutive SPFs in seconds\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1715,14 +1673,14 @@ DEFUN (spf_interval_l1, "Set interval for level 1 only\n" "Minimum interval between consecutive SPFs in seconds\n") { - int idx_number = 2; - VTY_DECLVAR_CONTEXT (isis_area, area); - u_int16_t interval; + int idx_number = 2; + VTY_DECLVAR_CONTEXT(isis_area, area); + u_int16_t interval; - interval = atoi (argv[idx_number]->arg); - area->min_spf_interval[0] = interval; + interval = atoi(argv[idx_number]->arg); + area->min_spf_interval[0] = interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_spf_interval_l1, @@ -1732,11 +1690,11 @@ DEFUN (no_spf_interval_l1, "Minimum interval between SPF calculations\n" "Set interval for level 1 only\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1747,14 +1705,14 @@ DEFUN (spf_interval_l2, "Set interval for level 2 only\n" "Minimum interval between consecutive SPFs in seconds\n") { - int idx_number = 2; - VTY_DECLVAR_CONTEXT (isis_area, area); - u_int16_t interval; + int idx_number = 2; + VTY_DECLVAR_CONTEXT(isis_area, area); + u_int16_t interval; - interval = atoi (argv[idx_number]->arg); - area->min_spf_interval[1] = interval; + interval = atoi(argv[idx_number]->arg); + area->min_spf_interval[1] = interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_spf_interval_l2, @@ -1764,11 +1722,11 @@ DEFUN (no_spf_interval_l2, "Minimum interval between SPF calculations\n" "Set interval for level 2 only\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_spf_delay_ietf, @@ -1777,14 +1735,14 @@ DEFUN (no_spf_delay_ietf, NO_STR "IETF SPF delay algorithm\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - spf_backoff_free(area->spf_delay_ietf[0]); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[0] = NULL; - area->spf_delay_ietf[1] = NULL; + spf_backoff_free(area->spf_delay_ietf[0]); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[0] = NULL; + area->spf_delay_ietf[1] = NULL; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (spf_delay_ietf, @@ -1802,76 +1760,77 @@ DEFUN (spf_delay_ietf, "Maximum duration needed to learn all the events related to a single failure\n" "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); - - long init_delay = atol(argv[2]->arg); - long short_delay = atol(argv[4]->arg); - long long_delay = atol(argv[6]->arg); - long holddown = atol(argv[8]->arg); - long timetolearn = atol(argv[10]->arg); - - size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); - char *buf = XCALLOC(MTYPE_TMP, bufsiz); - - snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[0]); - area->spf_delay_ietf[0] = spf_backoff_new(master, buf, init_delay, - short_delay, long_delay, - holddown, timetolearn); - - snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[1] = spf_backoff_new(master, buf, init_delay, - short_delay, long_delay, - holddown, timetolearn); - - XFREE(MTYPE_TMP, buf); - return CMD_SUCCESS; -} - -static int -area_max_lsp_lifetime_set(struct vty *vty, int level, - uint16_t interval) -{ - VTY_DECLVAR_CONTEXT (isis_area, area); - int lvl; - uint16_t refresh_interval = interval - 300; - int set_refresh_interval[ISIS_LEVELS] = {0, 0}; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) - { - if (!(lvl & level)) - continue; - - if (refresh_interval < area->lsp_refresh[lvl-1]) - { - vty_out (vty, "Level %d Max LSP lifetime %us must be 300s greater than " - "the configured LSP refresh interval %us\n", - lvl, interval, area->lsp_refresh[lvl - 1]); - vty_out (vty, "Automatically reducing level %d LSP refresh interval " - "to %us\n", lvl, refresh_interval); - set_refresh_interval[lvl-1] = 1; - - if (refresh_interval <= area->lsp_gen_interval[lvl-1]) - { - vty_out (vty, "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - refresh_interval,area->lsp_gen_interval[lvl - 1]); - return CMD_ERR_AMBIGUOUS; - } - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) - { - if (!(lvl & level)) - continue; - isis_area_max_lsp_lifetime_set(area, lvl, interval); - if (set_refresh_interval[lvl-1]) - isis_area_lsp_refresh_set(area, lvl, refresh_interval); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(isis_area, area); + + long init_delay = atol(argv[2]->arg); + long short_delay = atol(argv[4]->arg); + long long_delay = atol(argv[6]->arg); + long holddown = atol(argv[8]->arg); + long timetolearn = atol(argv[10]->arg); + + size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); + char *buf = XCALLOC(MTYPE_TMP, bufsiz); + + snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[0]); + area->spf_delay_ietf[0] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[1] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + XFREE(MTYPE_TMP, buf); + return CMD_SUCCESS; +} + +static int area_max_lsp_lifetime_set(struct vty *vty, int level, + uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + uint16_t refresh_interval = interval - 300; + int set_refresh_interval[ISIS_LEVELS] = {0, 0}; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + + if (refresh_interval < area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "Level %d Max LSP lifetime %us must be 300s greater than " + "the configured LSP refresh interval %us\n", + lvl, interval, area->lsp_refresh[lvl - 1]); + vty_out(vty, + "Automatically reducing level %d LSP refresh interval " + "to %us\n", + lvl, refresh_interval); + set_refresh_interval[lvl - 1] = 1; + + if (refresh_interval + <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + refresh_interval, + area->lsp_gen_interval[lvl - 1]); + return CMD_ERR_AMBIGUOUS; + } + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + isis_area_max_lsp_lifetime_set(area, lvl, interval); + if (set_refresh_interval[lvl - 1]) + isis_area_lsp_refresh_set(area, lvl, refresh_interval); + } + + return CMD_SUCCESS; } DEFUN (max_lsp_lifetime, @@ -1882,18 +1841,18 @@ DEFUN (max_lsp_lifetime, "Maximum LSP lifetime for Level 2 only\n" "LSP lifetime in seconds\n") { - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; + int idx = 0; + unsigned int level = IS_LEVEL_1_AND_2; - if (argv_find (argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find (argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; + if (argv_find(argv, argc, "level-1", &idx)) + level = IS_LEVEL_1; + else if (argv_find(argv, argc, "level-2", &idx)) + level = IS_LEVEL_2; - argv_find (argv, argc, "(350-65535)", &idx); - int lifetime = atoi(argv[idx]->arg); + argv_find(argv, argc, "(350-65535)", &idx); + int lifetime = atoi(argv[idx]->arg); - return area_max_lsp_lifetime_set(vty, level, lifetime); + return area_max_lsp_lifetime_set(vty, level, lifetime); } @@ -1906,51 +1865,49 @@ DEFUN (no_max_lsp_lifetime, "Maximum LSP lifetime for Level 2 only\n" "LSP lifetime in seconds\n") { - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find (argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find (argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME); -} - -static int -area_lsp_refresh_interval_set(struct vty *vty, int level, uint16_t interval) -{ - VTY_DECLVAR_CONTEXT (isis_area, area); - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) - { - if (!(lvl & level)) - continue; - if (interval <= area->lsp_gen_interval[lvl-1]) - { - vty_out (vty, "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - interval,area->lsp_gen_interval[lvl - 1]); - return CMD_ERR_AMBIGUOUS; - } - if (interval > (area->max_lsp_lifetime[lvl-1] - 300)) - { - vty_out (vty, "LSP refresh interval %us must be less than " - "the configured LSP lifetime %us less 300\n", - interval,area->max_lsp_lifetime[lvl - 1]); - return CMD_ERR_AMBIGUOUS; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) - { - if (!(lvl & level)) - continue; - isis_area_lsp_refresh_set(area, lvl, interval); - } - - return CMD_SUCCESS; + int idx = 0; + unsigned int level = IS_LEVEL_1_AND_2; + + if (argv_find(argv, argc, "level-1", &idx)) + level = IS_LEVEL_1; + else if (argv_find(argv, argc, "level-2", &idx)) + level = IS_LEVEL_2; + + return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME); +} + +static int area_lsp_refresh_interval_set(struct vty *vty, int level, + uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + if (interval <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + interval, area->lsp_gen_interval[lvl - 1]); + return CMD_ERR_AMBIGUOUS; + } + if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { + vty_out(vty, + "LSP refresh interval %us must be less than " + "the configured LSP lifetime %us less 300\n", + interval, area->max_lsp_lifetime[lvl - 1]); + return CMD_ERR_AMBIGUOUS; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + isis_area_lsp_refresh_set(area, lvl, interval); + } + + return CMD_SUCCESS; } DEFUN (lsp_refresh_interval, @@ -1961,17 +1918,17 @@ DEFUN (lsp_refresh_interval, "LSP refresh interval for Level 2 only\n" "LSP refresh interval in seconds\n") { - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - unsigned int interval = 0; + int idx = 0; + unsigned int level = IS_LEVEL_1_AND_2; + unsigned int interval = 0; - if (argv_find (argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find (argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; + if (argv_find(argv, argc, "level-1", &idx)) + level = IS_LEVEL_1; + else if (argv_find(argv, argc, "level-2", &idx)) + level = IS_LEVEL_2; - interval = atoi(argv[argc-1]->arg); - return area_lsp_refresh_interval_set(vty, level, interval); + interval = atoi(argv[argc - 1]->arg); + return area_lsp_refresh_interval_set(vty, level, interval); } DEFUN (no_lsp_refresh_interval, @@ -1983,33 +1940,32 @@ DEFUN (no_lsp_refresh_interval, "LSP refresh interval for Level 2 only\n" "LSP refresh interval in seconds\n") { - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; + int idx = 0; + unsigned int level = IS_LEVEL_1_AND_2; - if (argv_find (argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find (argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; + if (argv_find(argv, argc, "level-1", &idx)) + level = IS_LEVEL_1; + else if (argv_find(argv, argc, "level-2", &idx)) + level = IS_LEVEL_2; - return area_lsp_refresh_interval_set(vty, level, DEFAULT_MAX_LSP_GEN_INTERVAL); + return area_lsp_refresh_interval_set(vty, level, + DEFAULT_MAX_LSP_GEN_INTERVAL); } -static int -area_passwd_set(struct vty *vty, int level, - int (*type_set)(struct isis_area *area, int level, - const char *passwd, u_char snp_auth), - const char *passwd, u_char snp_auth) +static int area_passwd_set(struct vty *vty, int level, + int (*type_set)(struct isis_area *area, int level, + const char *passwd, u_char snp_auth), + const char *passwd, u_char snp_auth) { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - if (passwd && strlen(passwd) > 254) - { - vty_out (vty, "Too long area password (>254)\n"); - return CMD_ERR_AMBIGUOUS; - } + if (passwd && strlen(passwd) > 254) { + vty_out(vty, "Too long area password (>254)\n"); + return CMD_ERR_AMBIGUOUS; + } - type_set(area, level, passwd, snp_auth); - return CMD_SUCCESS; + type_set(area, level, passwd, snp_auth); + return CMD_SUCCESS; } @@ -2024,21 +1980,22 @@ DEFUN (area_passwd_md5, "Send but do not check PDUs on receiving\n" "Send and check PDUs on receiving\n") { - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - u_char snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1; + int idx_password = 0; + int idx_word = 2; + int idx_type = 5; + u_char snp_auth = 0; + int level = strmatch(argv[idx_password]->text, "domain-password") + ? IS_LEVEL_2 + : IS_LEVEL_1; - if (argc > 3) - { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } + if (argc > 3) { + snp_auth = SNP_AUTH_SEND; + if (strmatch(argv[idx_type]->text, "validate")) + snp_auth |= SNP_AUTH_RECV; + } - return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set, - argv[idx_word]->arg, snp_auth); + return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set, + argv[idx_word]->arg, snp_auth); } DEFUN (domain_passwd_md5, @@ -2052,7 +2009,7 @@ DEFUN (domain_passwd_md5, "Send but do not check PDUs on receiving\n" "Send and check PDUs on receiving\n") { - return area_passwd_md5 (self, vty, argc, argv); + return area_passwd_md5(self, vty, argc, argv); } DEFUN (area_passwd_clear, @@ -2066,21 +2023,22 @@ DEFUN (area_passwd_clear, "Send but do not check PDUs on receiving\n" "Send and check PDUs on receiving\n") { - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - u_char snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1; + int idx_password = 0; + int idx_word = 2; + int idx_type = 5; + u_char snp_auth = 0; + int level = strmatch(argv[idx_password]->text, "domain-password") + ? IS_LEVEL_2 + : IS_LEVEL_1; - if (argc > 3) - { - snp_auth = SNP_AUTH_SEND; - if (strmatch (argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } + if (argc > 3) { + snp_auth = SNP_AUTH_SEND; + if (strmatch(argv[idx_type]->text, "validate")) + snp_auth |= SNP_AUTH_RECV; + } - return area_passwd_set(vty, level, isis_area_passwd_cleartext_set, - argv[idx_word]->arg, snp_auth); + return area_passwd_set(vty, level, isis_area_passwd_cleartext_set, + argv[idx_word]->arg, snp_auth); } DEFUN (domain_passwd_clear, @@ -2094,7 +2052,7 @@ DEFUN (domain_passwd_clear, "Send but do not check PDUs on receiving\n" "Send and check PDUs on receiving\n") { - return area_passwd_clear (self, vty, argc, argv); + return area_passwd_clear(self, vty, argc, argv); } DEFUN (no_area_passwd, @@ -2104,121 +2062,121 @@ DEFUN (no_area_passwd, "Configure the authentication password for an area\n" "Set the authentication password for a routing domain\n") { - int idx_password = 1; - int level = strmatch (argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1; - VTY_DECLVAR_CONTEXT (isis_area, area); + int idx_password = 1; + int level = strmatch(argv[idx_password]->text, "domain-password") + ? IS_LEVEL_2 + : IS_LEVEL_1; + VTY_DECLVAR_CONTEXT(isis_area, area); - return isis_area_passwd_unset (area, level); + return isis_area_passwd_unset(area, level); } -void -isis_vty_init (void) +void isis_vty_init(void) { - install_element (INTERFACE_NODE, &ip_router_isis_cmd); - install_element (INTERFACE_NODE, &ip6_router_isis_cmd); - install_element (INTERFACE_NODE, &no_ip_router_isis_cmd); - - install_element (INTERFACE_NODE, &isis_passive_cmd); - install_element (INTERFACE_NODE, &no_isis_passive_cmd); + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); - install_element (INTERFACE_NODE, &isis_circuit_type_cmd); - install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &isis_passive_cmd); + install_element(INTERFACE_NODE, &no_isis_passive_cmd); - install_element (INTERFACE_NODE, &isis_network_cmd); - install_element (INTERFACE_NODE, &no_isis_network_cmd); + install_element(INTERFACE_NODE, &isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); - install_element (INTERFACE_NODE, &isis_passwd_cmd); - install_element (INTERFACE_NODE, &no_isis_passwd_cmd); + install_element(INTERFACE_NODE, &isis_network_cmd); + install_element(INTERFACE_NODE, &no_isis_network_cmd); - install_element (INTERFACE_NODE, &isis_priority_cmd); - install_element (INTERFACE_NODE, &no_isis_priority_cmd); - install_element (INTERFACE_NODE, &isis_priority_l1_cmd); - install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd); - install_element (INTERFACE_NODE, &isis_priority_l2_cmd); - install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd); + install_element(INTERFACE_NODE, &isis_passwd_cmd); + install_element(INTERFACE_NODE, &no_isis_passwd_cmd); - install_element (INTERFACE_NODE, &isis_metric_cmd); - install_element (INTERFACE_NODE, &no_isis_metric_cmd); - install_element (INTERFACE_NODE, &isis_metric_l1_cmd); - install_element (INTERFACE_NODE, &no_isis_metric_l1_cmd); - install_element (INTERFACE_NODE, &isis_metric_l2_cmd); - install_element (INTERFACE_NODE, &no_isis_metric_l2_cmd); + install_element(INTERFACE_NODE, &isis_priority_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_cmd); + install_element(INTERFACE_NODE, &isis_priority_l1_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_l1_cmd); + install_element(INTERFACE_NODE, &isis_priority_l2_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_l2_cmd); - install_element (INTERFACE_NODE, &isis_hello_interval_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_interval_cmd); - install_element (INTERFACE_NODE, &isis_hello_interval_l1_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_cmd); - install_element (INTERFACE_NODE, &isis_hello_interval_l2_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_cmd); + install_element(INTERFACE_NODE, &isis_metric_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_cmd); + install_element(INTERFACE_NODE, &isis_metric_l1_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_l1_cmd); + install_element(INTERFACE_NODE, &isis_metric_l2_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_l2_cmd); - install_element (INTERFACE_NODE, &isis_hello_multiplier_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_multiplier_cmd); - install_element (INTERFACE_NODE, &isis_hello_multiplier_l1_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd); - install_element (INTERFACE_NODE, &isis_hello_multiplier_l2_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd); + install_element(INTERFACE_NODE, &isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &isis_hello_interval_l1_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_l1_cmd); + install_element(INTERFACE_NODE, &isis_hello_interval_l2_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_l2_cmd); - install_element (INTERFACE_NODE, &isis_hello_padding_cmd); - install_element (INTERFACE_NODE, &no_isis_hello_padding_cmd); + install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &isis_hello_multiplier_l1_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd); + install_element(INTERFACE_NODE, &isis_hello_multiplier_l2_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd); - install_element (INTERFACE_NODE, &csnp_interval_cmd); - install_element (INTERFACE_NODE, &no_csnp_interval_cmd); - install_element (INTERFACE_NODE, &csnp_interval_l1_cmd); - install_element (INTERFACE_NODE, &no_csnp_interval_l1_cmd); - install_element (INTERFACE_NODE, &csnp_interval_l2_cmd); - install_element (INTERFACE_NODE, &no_csnp_interval_l2_cmd); + install_element(INTERFACE_NODE, &isis_hello_padding_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); - install_element (INTERFACE_NODE, &psnp_interval_cmd); - install_element (INTERFACE_NODE, &no_psnp_interval_cmd); - install_element (INTERFACE_NODE, &psnp_interval_l1_cmd); - install_element (INTERFACE_NODE, &no_psnp_interval_l1_cmd); - install_element (INTERFACE_NODE, &psnp_interval_l2_cmd); - install_element (INTERFACE_NODE, &no_psnp_interval_l2_cmd); + install_element(INTERFACE_NODE, &csnp_interval_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_cmd); + install_element(INTERFACE_NODE, &csnp_interval_l1_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_l1_cmd); + install_element(INTERFACE_NODE, &csnp_interval_l2_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_l2_cmd); - install_element (INTERFACE_NODE, &circuit_topology_cmd); - install_element (INTERFACE_NODE, &no_circuit_topology_cmd); + install_element(INTERFACE_NODE, &psnp_interval_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_cmd); + install_element(INTERFACE_NODE, &psnp_interval_l1_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_l1_cmd); + install_element(INTERFACE_NODE, &psnp_interval_l2_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_l2_cmd); - install_element (ISIS_NODE, &metric_style_cmd); - install_element (ISIS_NODE, &no_metric_style_cmd); + install_element(INTERFACE_NODE, &circuit_topology_cmd); + install_element(INTERFACE_NODE, &no_circuit_topology_cmd); - install_element (ISIS_NODE, &set_overload_bit_cmd); - install_element (ISIS_NODE, &no_set_overload_bit_cmd); + install_element(ISIS_NODE, &metric_style_cmd); + install_element(ISIS_NODE, &no_metric_style_cmd); - install_element (ISIS_NODE, &set_attached_bit_cmd); - install_element (ISIS_NODE, &no_set_attached_bit_cmd); + install_element(ISIS_NODE, &set_overload_bit_cmd); + install_element(ISIS_NODE, &no_set_overload_bit_cmd); - install_element (ISIS_NODE, &dynamic_hostname_cmd); - install_element (ISIS_NODE, &no_dynamic_hostname_cmd); + install_element(ISIS_NODE, &set_attached_bit_cmd); + install_element(ISIS_NODE, &no_set_attached_bit_cmd); - install_element (ISIS_NODE, &area_lsp_mtu_cmd); - install_element (ISIS_NODE, &no_area_lsp_mtu_cmd); + install_element(ISIS_NODE, &dynamic_hostname_cmd); + install_element(ISIS_NODE, &no_dynamic_hostname_cmd); - install_element (ISIS_NODE, &is_type_cmd); - install_element (ISIS_NODE, &no_is_type_cmd); + install_element(ISIS_NODE, &area_lsp_mtu_cmd); + install_element(ISIS_NODE, &no_area_lsp_mtu_cmd); - install_element (ISIS_NODE, &lsp_gen_interval_cmd); - install_element (ISIS_NODE, &no_lsp_gen_interval_cmd); + install_element(ISIS_NODE, &is_type_cmd); + install_element(ISIS_NODE, &no_is_type_cmd); - install_element (ISIS_NODE, &spf_interval_cmd); - install_element (ISIS_NODE, &no_spf_interval_cmd); - install_element (ISIS_NODE, &spf_interval_l1_cmd); - install_element (ISIS_NODE, &no_spf_interval_l1_cmd); - install_element (ISIS_NODE, &spf_interval_l2_cmd); - install_element (ISIS_NODE, &no_spf_interval_l2_cmd); + install_element(ISIS_NODE, &lsp_gen_interval_cmd); + install_element(ISIS_NODE, &no_lsp_gen_interval_cmd); - install_element (ISIS_NODE, &max_lsp_lifetime_cmd); - install_element (ISIS_NODE, &no_max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &spf_interval_cmd); + install_element(ISIS_NODE, &no_spf_interval_cmd); + install_element(ISIS_NODE, &spf_interval_l1_cmd); + install_element(ISIS_NODE, &no_spf_interval_l1_cmd); + install_element(ISIS_NODE, &spf_interval_l2_cmd); + install_element(ISIS_NODE, &no_spf_interval_l2_cmd); - install_element (ISIS_NODE, &lsp_refresh_interval_cmd); - install_element (ISIS_NODE, &no_lsp_refresh_interval_cmd); - - install_element (ISIS_NODE, &area_passwd_md5_cmd); - install_element (ISIS_NODE, &area_passwd_clear_cmd); - install_element (ISIS_NODE, &domain_passwd_md5_cmd); - install_element (ISIS_NODE, &domain_passwd_clear_cmd); - install_element (ISIS_NODE, &no_area_passwd_cmd); - - install_element (ISIS_NODE, &spf_delay_ietf_cmd); - install_element (ISIS_NODE, &no_spf_delay_ietf_cmd); + install_element(ISIS_NODE, &max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &lsp_refresh_interval_cmd); + install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd); + + install_element(ISIS_NODE, &area_passwd_md5_cmd); + install_element(ISIS_NODE, &area_passwd_clear_cmd); + install_element(ISIS_NODE, &domain_passwd_md5_cmd); + install_element(ISIS_NODE, &domain_passwd_clear_cmd); + install_element(ISIS_NODE, &no_area_passwd_cmd); + + install_element(ISIS_NODE, &spf_delay_ietf_cmd); + install_element(ISIS_NODE, &no_spf_delay_ietf_cmd); } diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index af77250a0..18a59d1fc 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1,19 +1,19 @@ /* - * IS-IS Rout(e)ing protocol - isis_zebra.c + * IS-IS Rout(e)ing protocol - isis_zebra.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -54,676 +54,655 @@ struct zclient *zclient = NULL; /* Router-id update message from zebra. */ -static int -isis_router_id_update_zebra (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_router_id_update_zebra(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct isis_area *area; - struct listnode *node; - struct prefix router_id; - - /* - * If ISIS TE is enable, TE Router ID is set through specific command. - * See mpls_te_router_addr() command in isis_te.c - */ - if (IS_MPLS_TE(isisMplsTE)) - return 0; - - zebra_router_id_update_read (zclient->ibuf, &router_id); - if (isis->router_id == router_id.u.prefix4.s_addr) - return 0; - - isis->router_id = router_id.u.prefix4.s_addr; - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - if (listcount (area->area_addrs) > 0) - lsp_regenerate_schedule (area, area->is_type, 0); - - return 0; + struct isis_area *area; + struct listnode *node; + struct prefix router_id; + + /* + * If ISIS TE is enable, TE Router ID is set through specific command. + * See mpls_te_router_addr() command in isis_te.c + */ + if (IS_MPLS_TE(isisMplsTE)) + return 0; + + zebra_router_id_update_read(zclient->ibuf, &router_id); + if (isis->router_id == router_id.u.prefix4.s_addr) + return 0; + + isis->router_id = router_id.u.prefix4.s_addr; + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + if (listcount(area->area_addrs) > 0) + lsp_regenerate_schedule(area, area->is_type, 0); + + return 0; } -static int -isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int isis_zebra_if_add(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; + struct interface *ifp; - ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); + ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); - if (isis->debugs & DEBUG_ZEBRA) - zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d", - ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu); + if (isis->debugs & DEBUG_ZEBRA) + zlog_debug( + "Zebra I/F add: %s index %d flags %ld metric %d mtu %d", + ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, + ifp->mtu); - if (if_is_operative (ifp)) - isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp); + if (if_is_operative(ifp)) + isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), + ifp); - return 0; + return 0; } -static int -isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int isis_zebra_if_del(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct stream *s; + struct interface *ifp; + struct stream *s; - s = zclient->ibuf; - ifp = zebra_interface_state_read (s, vrf_id); + s = zclient->ibuf; + ifp = zebra_interface_state_read(s, vrf_id); - if (!ifp) - return 0; + if (!ifp) + return 0; - if (if_is_operative (ifp)) - zlog_warn ("Zebra: got delete of %s, but interface is still up", - ifp->name); + if (if_is_operative(ifp)) + zlog_warn("Zebra: got delete of %s, but interface is still up", + ifp->name); - if (isis->debugs & DEBUG_ZEBRA) - zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d", - ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu); + if (isis->debugs & DEBUG_ZEBRA) + zlog_debug( + "Zebra I/F delete: %s index %d flags %ld metric %d mtu %d", + ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, + ifp->mtu); - isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp); + isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp); - /* Cannot call if_delete because we should retain the pseudo interface - in case there is configuration info attached to it. */ - if_delete_retain(ifp); + /* Cannot call if_delete because we should retain the pseudo interface + in case there is configuration info attached to it. */ + if_delete_retain(ifp); - ifp->ifindex = IFINDEX_DELETED; + ifp->ifindex = IFINDEX_DELETED; - return 0; + return 0; } -static int -isis_zebra_if_state_up (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_if_state_up(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; + struct interface *ifp; - ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); + ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); - if (ifp == NULL) - return 0; + if (ifp == NULL) + return 0; - isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp); + isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp); - return 0; + return 0; } -static int -isis_zebra_if_state_down (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_if_state_down(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct isis_circuit *circuit; + struct interface *ifp; + struct isis_circuit *circuit; - ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); + ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); - if (ifp == NULL) - return 0; + if (ifp == NULL) + return 0; - circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), - ifp); - if (circuit) - SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); + circuit = isis_csm_state_change(IF_DOWN_FROM_Z, + circuit_scan_by_ifp(ifp), ifp); + if (circuit) + SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); - return 0; + return 0; } -static int -isis_zebra_if_address_add (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_if_address_add(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct connected *c; - struct prefix *p; - char buf[PREFIX2STR_BUFFER]; + struct connected *c; + struct prefix *p; + char buf[PREFIX2STR_BUFFER]; - c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, - zclient->ibuf, vrf_id); + c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, + zclient->ibuf, vrf_id); - if (c == NULL) - return 0; + if (c == NULL) + return 0; - p = c->address; + p = c->address; - prefix2str (p, buf, sizeof (buf)); + prefix2str(p, buf, sizeof(buf)); #ifdef EXTREME_DEBUG - if (p->family == AF_INET) - zlog_debug ("connected IP address %s", buf); - if (p->family == AF_INET6) - zlog_debug ("connected IPv6 address %s", buf); + if (p->family == AF_INET) + zlog_debug("connected IP address %s", buf); + if (p->family == AF_INET6) + zlog_debug("connected IPv6 address %s", buf); #endif /* EXTREME_DEBUG */ - if (if_is_operative (c->ifp)) - isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c); + if (if_is_operative(c->ifp)) + isis_circuit_add_addr(circuit_scan_by_ifp(c->ifp), c); - return 0; + return 0; } -static int -isis_zebra_if_address_del (int command, struct zclient *client, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_if_address_del(int command, struct zclient *client, + zebra_size_t length, vrf_id_t vrf_id) { - struct connected *c; - struct interface *ifp; + struct connected *c; + struct interface *ifp; #ifdef EXTREME_DEBUG - struct prefix *p; - char buf[PREFIX2STR_BUFFER]; + struct prefix *p; + char buf[PREFIX2STR_BUFFER]; #endif /* EXTREME_DEBUG */ - c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, - zclient->ibuf, vrf_id); + c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, + zclient->ibuf, vrf_id); - if (c == NULL) - return 0; + if (c == NULL) + return 0; - ifp = c->ifp; + ifp = c->ifp; #ifdef EXTREME_DEBUG - p = c->address; - prefix2str (p, buf, sizeof (buf)); + p = c->address; + prefix2str(p, buf, sizeof(buf)); - if (p->family == AF_INET) - zlog_debug ("disconnected IP address %s", buf); - if (p->family == AF_INET6) - zlog_debug ("disconnected IPv6 address %s", buf); + if (p->family == AF_INET) + zlog_debug("disconnected IP address %s", buf); + if (p->family == AF_INET6) + zlog_debug("disconnected IPv6 address %s", buf); #endif /* EXTREME_DEBUG */ - if (if_is_operative (ifp)) - isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c); - connected_free (c); + if (if_is_operative(ifp)) + isis_circuit_del_addr(circuit_scan_by_ifp(ifp), c); + connected_free(c); - return 0; + return 0; } -static int -isis_zebra_link_params (int command, struct zclient *zclient, - zebra_size_t length) +static int isis_zebra_link_params(int command, struct zclient *zclient, + zebra_size_t length) { - struct interface *ifp; + struct interface *ifp; - ifp = zebra_interface_link_params_read (zclient->ibuf); + ifp = zebra_interface_link_params_read(zclient->ibuf); - if (ifp == NULL) - return 0; + if (ifp == NULL) + return 0; - /* Update TE TLV */ - isis_mpls_te_update(ifp); + /* Update TE TLV */ + isis_mpls_te_update(ifp); - return 0; + return 0; } -static void -isis_zebra_route_add_ipv4 (struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_add_ipv4(struct prefix *prefix, + struct isis_route_info *route_info) { - u_char message; - u_int32_t flags; - int psize; - struct stream *stream; - struct isis_nexthop *nexthop; - struct listnode *node; - - if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return; - - if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) - { - message = 0; - flags = 0; - - SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (message, ZAPI_MESSAGE_METRIC); + u_char message; + u_int32_t flags; + int psize; + struct stream *stream; + struct isis_nexthop *nexthop; + struct listnode *node; + + if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + return; + + if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT)) { + message = 0; + flags = 0; + + SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(message, ZAPI_MESSAGE_METRIC); #if 0 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); #endif - stream = zclient->obuf; - stream_reset (stream); - zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - /* type */ - stream_putc (stream, ZEBRA_ROUTE_ISIS); - /* instance */ - stream_putw (stream, 0); - /* flags */ - stream_putl (stream, flags); - /* message */ - stream_putc (stream, message); - /* SAFI */ - stream_putw (stream, SAFI_UNICAST); - /* prefix information */ - psize = PSIZE (prefix->prefixlen); - stream_putc (stream, prefix->prefixlen); - stream_write (stream, (u_char *) & prefix->u.prefix4, psize); - - stream_putc (stream, listcount (route_info->nexthops)); - - /* Nexthop, ifindex, distance and metric information */ - for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop)) - { - /* FIXME: can it be ? */ - if (nexthop->ip.s_addr != INADDR_ANY) - { - stream_putc (stream, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr (stream, &nexthop->ip); - stream_putl (stream, nexthop->ifindex); - } - else - { - stream_putc (stream, NEXTHOP_TYPE_IFINDEX); - stream_putl (stream, nexthop->ifindex); - } - } + stream = zclient->obuf; + stream_reset(stream); + zclient_create_header(stream, ZEBRA_IPV4_ROUTE_ADD, + VRF_DEFAULT); + /* type */ + stream_putc(stream, ZEBRA_ROUTE_ISIS); + /* instance */ + stream_putw(stream, 0); + /* flags */ + stream_putl(stream, flags); + /* message */ + stream_putc(stream, message); + /* SAFI */ + stream_putw(stream, SAFI_UNICAST); + /* prefix information */ + psize = PSIZE(prefix->prefixlen); + stream_putc(stream, prefix->prefixlen); + stream_write(stream, (u_char *)&prefix->u.prefix4, psize); + + stream_putc(stream, listcount(route_info->nexthops)); + + /* Nexthop, ifindex, distance and metric information */ + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, + nexthop)) { + /* FIXME: can it be ? */ + if (nexthop->ip.s_addr != INADDR_ANY) { + stream_putc(stream, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(stream, &nexthop->ip); + stream_putl(stream, nexthop->ifindex); + } else { + stream_putc(stream, NEXTHOP_TYPE_IFINDEX); + stream_putl(stream, nexthop->ifindex); + } + } #if 0 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) stream_putc (stream, route_info->depth); #endif - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - stream_putl (stream, route_info->cost); - - stream_putw_at (stream, 0, stream_get_endp (stream)); - zclient_send_message(zclient); - SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - } + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) + stream_putl(stream, route_info->cost); + + stream_putw_at(stream, 0, stream_get_endp(stream)); + zclient_send_message(zclient); + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + } } -static void -isis_zebra_route_del_ipv4 (struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_del_ipv4(struct prefix *prefix, + struct isis_route_info *route_info) { - struct zapi_ipv4 api; - struct prefix_ipv4 prefix4; - - if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) - { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - prefix4.family = AF_INET; - prefix4.prefixlen = prefix->prefixlen; - prefix4.prefix = prefix->u.prefix4; - zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api); - } - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - - return; + struct zapi_ipv4 api; + struct prefix_ipv4 prefix4; + + if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_ISIS; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + prefix4.family = AF_INET; + prefix4.prefixlen = prefix->prefixlen; + prefix4.prefix = prefix->u.prefix4; + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, + &api); + } + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + + return; } -static void -isis_zebra_route_add_ipv6 (struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_add_ipv6(struct prefix *prefix, + struct isis_route_info *route_info) { - struct zapi_ipv6 api; - struct in6_addr **nexthop_list; - ifindex_t *ifindex_list; - struct isis_nexthop6 *nexthop6; - int i, size; - struct listnode *node; - struct prefix_ipv6 prefix6; - - if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return; - - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); - SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); - api.metric = route_info->cost; + struct zapi_ipv6 api; + struct in6_addr **nexthop_list; + ifindex_t *ifindex_list; + struct isis_nexthop6 *nexthop6; + int i, size; + struct listnode *node; + struct prefix_ipv6 prefix6; + + if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + return; + + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_ISIS; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = route_info->cost; #if 0 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = route_info->depth; #endif - api.nexthop_num = listcount (route_info->nexthops6); - api.ifindex_num = listcount (route_info->nexthops6); - - /* allocate memory for nexthop_list */ - size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6); - nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size); - if (!nexthop_list) - { - zlog_err ("isis_zebra_add_route_ipv6: out of memory!"); - return; - } - - /* allocate memory for ifindex_list */ - size = sizeof (unsigned int) * listcount (route_info->nexthops6); - ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size); - if (!ifindex_list) - { - zlog_err ("isis_zebra_add_route_ipv6: out of memory!"); - XFREE (MTYPE_ISIS_TMP, nexthop_list); - return; - } - - /* for each nexthop */ - i = 0; - for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6)) - { - if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) && - !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) - { - api.nexthop_num--; - api.ifindex_num--; - continue; + api.nexthop_num = listcount(route_info->nexthops6); + api.ifindex_num = listcount(route_info->nexthops6); + + /* allocate memory for nexthop_list */ + size = sizeof(struct isis_nexthop6 *) + * listcount(route_info->nexthops6); + nexthop_list = (struct in6_addr **)XMALLOC(MTYPE_ISIS_TMP, size); + if (!nexthop_list) { + zlog_err("isis_zebra_add_route_ipv6: out of memory!"); + return; } - nexthop_list[i] = &nexthop6->ip6; - ifindex_list[i] = nexthop6->ifindex; - i++; - } + /* allocate memory for ifindex_list */ + size = sizeof(unsigned int) * listcount(route_info->nexthops6); + ifindex_list = (ifindex_t *)XMALLOC(MTYPE_ISIS_TMP, size); + if (!ifindex_list) { + zlog_err("isis_zebra_add_route_ipv6: out of memory!"); + XFREE(MTYPE_ISIS_TMP, nexthop_list); + return; + } - api.nexthop = nexthop_list; - api.ifindex = ifindex_list; + /* for each nexthop */ + i = 0; + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, nexthop6)) { + if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { + api.nexthop_num--; + api.ifindex_num--; + continue; + } + + nexthop_list[i] = &nexthop6->ip6; + ifindex_list[i] = nexthop6->ifindex; + i++; + } - if (api.nexthop_num && api.ifindex_num) - { - prefix6.family = AF_INET6; - prefix6.prefixlen = prefix->prefixlen; - memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr)); - zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, NULL, &api); - SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - } + api.nexthop = nexthop_list; + api.ifindex = ifindex_list; + + if (api.nexthop_num && api.ifindex_num) { + prefix6.family = AF_INET6; + prefix6.prefixlen = prefix->prefixlen; + memcpy(&prefix6.prefix, &prefix->u.prefix6, + sizeof(struct in6_addr)); + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, NULL, + &api); + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + } - XFREE (MTYPE_ISIS_TMP, nexthop_list); - XFREE (MTYPE_ISIS_TMP, ifindex_list); + XFREE(MTYPE_ISIS_TMP, nexthop_list); + XFREE(MTYPE_ISIS_TMP, ifindex_list); - return; + return; } -static void -isis_zebra_route_del_ipv6 (struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_del_ipv6(struct prefix *prefix, + struct isis_route_info *route_info) { - struct zapi_ipv6 api; - struct in6_addr **nexthop_list; - ifindex_t *ifindex_list; - struct isis_nexthop6 *nexthop6; - int i, size; - struct listnode *node; - struct prefix_ipv6 prefix6; - - if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return; - - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); - api.nexthop_num = listcount (route_info->nexthops6); - api.ifindex_num = listcount (route_info->nexthops6); - - /* allocate memory for nexthop_list */ - size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6); - nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size); - if (!nexthop_list) - { - zlog_err ("isis_zebra_route_del_ipv6: out of memory!"); - return; - } - - /* allocate memory for ifindex_list */ - size = sizeof (unsigned int) * listcount (route_info->nexthops6); - ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size); - if (!ifindex_list) - { - zlog_err ("isis_zebra_route_del_ipv6: out of memory!"); - XFREE (MTYPE_ISIS_TMP, nexthop_list); - return; - } - - /* for each nexthop */ - i = 0; - for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6)) - { - if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) && - !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) - { - api.nexthop_num--; - api.ifindex_num--; - continue; + struct zapi_ipv6 api; + struct in6_addr **nexthop_list; + ifindex_t *ifindex_list; + struct isis_nexthop6 *nexthop6; + int i, size; + struct listnode *node; + struct prefix_ipv6 prefix6; + + if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + return; + + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_ISIS; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.nexthop_num = listcount(route_info->nexthops6); + api.ifindex_num = listcount(route_info->nexthops6); + + /* allocate memory for nexthop_list */ + size = sizeof(struct isis_nexthop6 *) + * listcount(route_info->nexthops6); + nexthop_list = (struct in6_addr **)XMALLOC(MTYPE_ISIS_TMP, size); + if (!nexthop_list) { + zlog_err("isis_zebra_route_del_ipv6: out of memory!"); + return; + } + + /* allocate memory for ifindex_list */ + size = sizeof(unsigned int) * listcount(route_info->nexthops6); + ifindex_list = (ifindex_t *)XMALLOC(MTYPE_ISIS_TMP, size); + if (!ifindex_list) { + zlog_err("isis_zebra_route_del_ipv6: out of memory!"); + XFREE(MTYPE_ISIS_TMP, nexthop_list); + return; } - nexthop_list[i] = &nexthop6->ip6; - ifindex_list[i] = nexthop6->ifindex; - i++; - } - - api.nexthop = nexthop_list; - api.ifindex = ifindex_list; - - if (api.nexthop_num && api.ifindex_num) - { - prefix6.family = AF_INET6; - prefix6.prefixlen = prefix->prefixlen; - memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr)); - zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, NULL, &api); - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - - XFREE (MTYPE_ISIS_TMP, nexthop_list); - XFREE (MTYPE_ISIS_TMP, ifindex_list); + /* for each nexthop */ + i = 0; + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, nexthop6)) { + if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { + api.nexthop_num--; + api.ifindex_num--; + continue; + } + + nexthop_list[i] = &nexthop6->ip6; + ifindex_list[i] = nexthop6->ifindex; + i++; + } + + api.nexthop = nexthop_list; + api.ifindex = ifindex_list; + + if (api.nexthop_num && api.ifindex_num) { + prefix6.family = AF_INET6; + prefix6.prefixlen = prefix->prefixlen; + memcpy(&prefix6.prefix, &prefix->u.prefix6, + sizeof(struct in6_addr)); + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, + NULL, &api); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } + + XFREE(MTYPE_ISIS_TMP, nexthop_list); + XFREE(MTYPE_ISIS_TMP, ifindex_list); } -void -isis_zebra_route_update (struct prefix *prefix, - struct isis_route_info *route_info) +void isis_zebra_route_update(struct prefix *prefix, + struct isis_route_info *route_info) { - if (zclient->sock < 0) - return; - - if ((prefix->family == AF_INET && !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) || - (prefix->family == AF_INET6 && !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS], VRF_DEFAULT))) - return; - - if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) - { - if (prefix->family == AF_INET) - isis_zebra_route_add_ipv4 (prefix, route_info); - else if (prefix->family == AF_INET6) - isis_zebra_route_add_ipv6 (prefix, route_info); - } - else - { - if (prefix->family == AF_INET) - isis_zebra_route_del_ipv4 (prefix, route_info); - else if (prefix->family == AF_INET6) - isis_zebra_route_del_ipv6 (prefix, route_info); - } - return; + if (zclient->sock < 0) + return; + + if ((prefix->family == AF_INET + && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT)) + || (prefix->family == AF_INET6 + && !vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT))) + return; + + if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) { + if (prefix->family == AF_INET) + isis_zebra_route_add_ipv4(prefix, route_info); + else if (prefix->family == AF_INET6) + isis_zebra_route_add_ipv6(prefix, route_info); + } else { + if (prefix->family == AF_INET) + isis_zebra_route_del_ipv4(prefix, route_info); + else if (prefix->family == AF_INET6) + isis_zebra_route_del_ipv6(prefix, route_info); + } + return; } -static int -isis_zebra_read_ipv4 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_read_ipv4(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *stream; - struct zapi_ipv4 api; - struct prefix_ipv4 p; - struct prefix *p_generic = (struct prefix*)&p; - - stream = zclient->ibuf; - memset(&api, 0, sizeof(api)); - memset (&p, 0, sizeof (struct prefix_ipv4)); - - api.type = stream_getc (stream); - api.instance = stream_getw (stream); - api.flags = stream_getl (stream); - api.message = stream_getc (stream); - - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (stream)); - stream_get (&p.prefix, stream, PSIZE (p.prefixlen)); - - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (stream); - (void)stream_get_ipv4 (stream); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc (stream); - stream_getl (stream); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (stream); - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (stream); - - /* - * Avoid advertising a false default reachability. (A default - * route installed by IS-IS gets redistributed from zebra back - * into IS-IS causing us to start advertising default reachabity - * without this check) - */ - if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_IPV4_ROUTE_DELETE; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) - isis_redist_add(api.type, p_generic, api.distance, api.metric); - else - isis_redist_delete(api.type, p_generic); - - return 0; + struct stream *stream; + struct zapi_ipv4 api; + struct prefix_ipv4 p; + struct prefix *p_generic = (struct prefix *)&p; + + stream = zclient->ibuf; + memset(&api, 0, sizeof(api)); + memset(&p, 0, sizeof(struct prefix_ipv4)); + + api.type = stream_getc(stream); + api.instance = stream_getw(stream); + api.flags = stream_getl(stream); + api.message = stream_getc(stream); + + p.family = AF_INET; + p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(stream)); + stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(stream); + (void)stream_get_ipv4(stream); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(stream); + stream_getl(stream); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(stream); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(stream); + + /* + * Avoid advertising a false default reachability. (A default + * route installed by IS-IS gets redistributed from zebra back + * into IS-IS causing us to start advertising default reachabity + * without this check) + */ + if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) + command = ZEBRA_IPV4_ROUTE_DELETE; + + if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) + isis_redist_add(api.type, p_generic, api.distance, api.metric); + else + isis_redist_delete(api.type, p_generic); + + return 0; } -static int -isis_zebra_read_ipv6 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_read_ipv6(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *stream; - struct zapi_ipv6 api; - struct prefix_ipv6 p; - struct prefix src_p; - struct prefix *p_generic = (struct prefix*)&p; - struct in6_addr nexthop; - unsigned long ifindex __attribute__((unused)); - - stream = zclient->ibuf; - memset(&api, 0, sizeof(api)); - memset(&p, 0, sizeof(struct prefix_ipv6)); - memset(&nexthop, 0, sizeof(nexthop)); - ifindex = 0; - - api.type = stream_getc(stream); - api.instance = stream_getw(stream); - api.flags = stream_getl(stream); - api.message = stream_getc(stream); - - p.family = AF_INET6; - p.prefixlen = stream_getc(stream); - stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof (struct prefix)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) - { - src_p.prefixlen = stream_getc(stream); - stream_get(&src_p.u.prefix6, stream, PSIZE (src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ - return 0; - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc(stream); /* this is always 1 */ - stream_get(&nexthop, stream, sizeof(nexthop)); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc(stream); - ifindex = stream_getl(stream); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(stream); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(stream); - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(stream); - - /* - * Avoid advertising a false default reachability. (A default - * route installed by IS-IS gets redistributed from zebra back - * into IS-IS causing us to start advertising default reachabity - * without this check) - */ - if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_IPV6_ROUTE_DELETE; - - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - isis_redist_add(api.type, p_generic, api.distance, api.metric); - else - isis_redist_delete(api.type, p_generic); - - return 0; + struct stream *stream; + struct zapi_ipv6 api; + struct prefix_ipv6 p; + struct prefix src_p; + struct prefix *p_generic = (struct prefix *)&p; + struct in6_addr nexthop; + unsigned long ifindex __attribute__((unused)); + + stream = zclient->ibuf; + memset(&api, 0, sizeof(api)); + memset(&p, 0, sizeof(struct prefix_ipv6)); + memset(&nexthop, 0, sizeof(nexthop)); + ifindex = 0; + + api.type = stream_getc(stream); + api.instance = stream_getw(stream); + api.flags = stream_getl(stream); + api.message = stream_getc(stream); + + p.family = AF_INET6; + p.prefixlen = stream_getc(stream); + stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); + + memset(&src_p, 0, sizeof(struct prefix)); + src_p.family = AF_INET6; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { + src_p.prefixlen = stream_getc(stream); + stream_get(&src_p.u.prefix6, stream, PSIZE(src_p.prefixlen)); + } + + if (src_p.prefixlen) + /* we completely ignore srcdest routes for now. */ + return 0; + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(stream); /* this is always 1 */ + stream_get(&nexthop, stream, sizeof(nexthop)); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(stream); + ifindex = stream_getl(stream); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(stream); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(stream); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + api.tag = stream_getl(stream); + + /* + * Avoid advertising a false default reachability. (A default + * route installed by IS-IS gets redistributed from zebra back + * into IS-IS causing us to start advertising default reachabity + * without this check) + */ + if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) + command = ZEBRA_IPV6_ROUTE_DELETE; + + if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) + isis_redist_add(api.type, p_generic, api.distance, api.metric); + else + isis_redist_delete(api.type, p_generic); + + return 0; } -int -isis_distribute_list_update (int routetype) +int isis_distribute_list_update(int routetype) { - return 0; + return 0; } -void -isis_zebra_redistribute_set(afi_t afi, int type) +void isis_zebra_redistribute_set(afi_t afi, int type) { - if (type == DEFAULT_ROUTE) - zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT); - else - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT); + if (type == DEFAULT_ROUTE) + zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, + zclient, VRF_DEFAULT); + else + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, + 0, VRF_DEFAULT); } -void -isis_zebra_redistribute_unset(afi_t afi, int type) +void isis_zebra_redistribute_unset(afi_t afi, int type) { - if (type == DEFAULT_ROUTE) - zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT); - else - zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT); + if (type == DEFAULT_ROUTE) + zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, + zclient, VRF_DEFAULT); + else + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, + type, 0, VRF_DEFAULT); } -static void -isis_zebra_connected (struct zclient *zclient) +static void isis_zebra_connected(struct zclient *zclient) { - zclient_send_reg_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests(zclient, VRF_DEFAULT); } -void -isis_zebra_init (struct thread_master *master) +void isis_zebra_init(struct thread_master *master) { - zclient = zclient_new (master); - zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0); - zclient->zebra_connected = isis_zebra_connected; - zclient->router_id_update = isis_router_id_update_zebra; - zclient->interface_add = isis_zebra_if_add; - zclient->interface_delete = isis_zebra_if_del; - zclient->interface_up = isis_zebra_if_state_up; - zclient->interface_down = isis_zebra_if_state_down; - zclient->interface_address_add = isis_zebra_if_address_add; - zclient->interface_address_delete = isis_zebra_if_address_del; - zclient->interface_link_params = isis_zebra_link_params; - zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4; - zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6; - - return; + zclient = zclient_new(master); + zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0); + zclient->zebra_connected = isis_zebra_connected; + zclient->router_id_update = isis_router_id_update_zebra; + zclient->interface_add = isis_zebra_if_add; + zclient->interface_delete = isis_zebra_if_del; + zclient->interface_up = isis_zebra_if_state_up; + zclient->interface_down = isis_zebra_if_state_down; + zclient->interface_address_add = isis_zebra_if_address_add; + zclient->interface_address_delete = isis_zebra_if_address_del; + zclient->interface_link_params = isis_zebra_link_params; + zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4; + zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4; + zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6; + zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6; + + return; } -void -isis_zebra_stop (void) +void isis_zebra_stop(void) { - zclient_stop (zclient); - zclient_free (zclient); + zclient_stop(zclient); + zclient_free(zclient); } diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index 82d5a48d3..bd7bf2b5c 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isis_zebra.h + * IS-IS Rout(e)ing protocol - isis_zebra.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -27,9 +27,9 @@ extern struct zclient *zclient; void isis_zebra_init(struct thread_master *); void isis_zebra_stop(void); -void isis_zebra_route_update (struct prefix *prefix, - struct isis_route_info *route_info); -int isis_distribute_list_update (int routetype); +void isis_zebra_route_update(struct prefix *prefix, + struct isis_route_info *route_info); +int isis_distribute_list_update(int routetype); void isis_zebra_redistribute_set(afi_t afi, int type); void isis_zebra_redistribute_unset(afi_t afi, int type); diff --git a/isisd/isisd.c b/isisd/isisd.c index 473b6594e..8bbb5cf94 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -2,17 +2,17 @@ * IS-IS Rout(e)ing protocol - isisd.c * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -76,442 +76,412 @@ int clear_isis_neighbor_common(struct vty *, const char *id); int isis_config_write(struct vty *); +void isis_new(unsigned long process_id) +{ + isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis)); + /* + * Default values + */ + isis->max_area_addrs = 3; + isis->process_id = process_id; + isis->router_id = 0; + isis->area_list = list_new(); + isis->init_circ_list = list_new(); + isis->uptime = time(NULL); + isis->nexthops = list_new(); + isis->nexthops6 = list_new(); + dyn_cache_init(); + /* + * uncomment the next line for full debugs + */ + /* isis->debugs = 0xFFFF; */ + isisMplsTE.status = disable; /* Only support TE metric */ + QOBJ_REG(isis, isis); +} + +struct isis_area *isis_area_create(const char *area_tag) +{ + struct isis_area *area; + + area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area)); + + /* + * The first instance is level-1-2 rest are level-1, unless otherwise + * configured + */ + if (listcount(isis->area_list) > 0) + area->is_type = IS_LEVEL_1; + else + area->is_type = IS_LEVEL_1_AND_2; + + /* + * intialize the databases + */ + if (area->is_type & IS_LEVEL_1) { + area->lspdb[0] = lsp_db_init(); + area->route_table[0] = route_table_init(); + area->route_table6[0] = route_table_init(); + } + if (area->is_type & IS_LEVEL_2) { + area->lspdb[1] = lsp_db_init(); + area->route_table[1] = route_table_init(); + area->route_table6[1] = route_table_init(); + } + + spftree_area_init(area); + + area->circuit_list = list_new(); + area->area_addrs = list_new(); + thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); + flags_initialize(&area->flags); + + /* + * Default values + */ + area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */ + area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */ + area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ + area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ + area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL; + area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL; + area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; + area->dynhostname = 1; + area->oldmetric = 0; + area->newmetric = 1; + area->lsp_frag_threshold = 90; + area->lsp_mtu = DEFAULT_LSP_MTU; + + area_mt_init(area); -void -isis_new (unsigned long process_id) -{ - isis = XCALLOC (MTYPE_ISIS, sizeof (struct isis)); - /* - * Default values - */ - isis->max_area_addrs = 3; - isis->process_id = process_id; - isis->router_id = 0; - isis->area_list = list_new (); - isis->init_circ_list = list_new (); - isis->uptime = time (NULL); - isis->nexthops = list_new (); - isis->nexthops6 = list_new (); - dyn_cache_init (); - /* - * uncomment the next line for full debugs - */ - /* isis->debugs = 0xFFFF; */ - isisMplsTE.status = disable; /* Only support TE metric */ - QOBJ_REG (isis, isis); -} - -struct isis_area * -isis_area_create (const char *area_tag) -{ - struct isis_area *area; + area->area_tag = strdup(area_tag); + listnode_add(isis->area_list, area); + area->isis = isis; - area = XCALLOC (MTYPE_ISIS_AREA, sizeof (struct isis_area)); + QOBJ_REG(area, isis_area); - /* - * The first instance is level-1-2 rest are level-1, unless otherwise - * configured - */ - if (listcount (isis->area_list) > 0) - area->is_type = IS_LEVEL_1; - else - area->is_type = IS_LEVEL_1_AND_2; + return area; +} - /* - * intialize the databases - */ - if (area->is_type & IS_LEVEL_1) - { - area->lspdb[0] = lsp_db_init (); - area->route_table[0] = route_table_init (); - area->route_table6[0] = route_table_init (); - } - if (area->is_type & IS_LEVEL_2) - { - area->lspdb[1] = lsp_db_init (); - area->route_table[1] = route_table_init (); - area->route_table6[1] = route_table_init (); - } - - spftree_area_init (area); - - area->circuit_list = list_new (); - area->area_addrs = list_new (); - thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); - flags_initialize (&area->flags); - - /* - * Default values - */ - area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */ - area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */ - area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ - area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ - area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL; - area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL; - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - area->dynhostname = 1; - area->oldmetric = 0; - area->newmetric = 1; - area->lsp_frag_threshold = 90; - area->lsp_mtu = DEFAULT_LSP_MTU; - - area_mt_init(area); - - area->area_tag = strdup (area_tag); - listnode_add (isis->area_list, area); - area->isis = isis; - - QOBJ_REG (area, isis_area); - - return area; -} - -struct isis_area * -isis_area_lookup (const char *area_tag) -{ - struct isis_area *area; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - if ((area->area_tag == NULL && area_tag == NULL) || - (area->area_tag && area_tag - && strcmp (area->area_tag, area_tag) == 0)) - return area; - - return NULL; -} - -int -isis_area_get (struct vty *vty, const char *area_tag) -{ - struct isis_area *area; - - area = isis_area_lookup (area_tag); - - if (area) - { - VTY_PUSH_CONTEXT (ISIS_NODE, area); - return CMD_SUCCESS; - } - - area = isis_area_create (area_tag); - - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("New IS-IS area instance %s", area->area_tag); - - VTY_PUSH_CONTEXT (ISIS_NODE, area); - - return CMD_SUCCESS; -} - -int -isis_area_destroy (struct vty *vty, const char *area_tag) -{ - struct isis_area *area; - struct listnode *node, *nnode; - struct isis_circuit *circuit; - struct area_addr *addr; - - area = isis_area_lookup (area_tag); - - if (area == NULL) - { - vty_out (vty, "Can't find ISIS instance \n"); - return CMD_ERR_NO_MATCH; - } - - QOBJ_UNREG (area); - - if (area->circuit_list) - { - for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit)) - { - circuit->ip_router = 0; - circuit->ipv6_router = 0; - isis_csm_state_change (ISIS_DISABLE, circuit, area); - } - list_delete (area->circuit_list); - area->circuit_list = NULL; - } +struct isis_area *isis_area_lookup(const char *area_tag) +{ + struct isis_area *area; + struct listnode *node; - if (area->lspdb[0] != NULL) - { - lsp_db_destroy (area->lspdb[0]); - area->lspdb[0] = NULL; - } - if (area->lspdb[1] != NULL) - { - lsp_db_destroy (area->lspdb[1]); - area->lspdb[1] = NULL; - } + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + if ((area->area_tag == NULL && area_tag == NULL) + || (area->area_tag && area_tag + && strcmp(area->area_tag, area_tag) == 0)) + return area; - spftree_area_del (area); + return NULL; +} - THREAD_TIMER_OFF(area->spf_timer[0]); - THREAD_TIMER_OFF(area->spf_timer[1]); +int isis_area_get(struct vty *vty, const char *area_tag) +{ + struct isis_area *area; - spf_backoff_free(area->spf_delay_ietf[0]); - spf_backoff_free(area->spf_delay_ietf[1]); + area = isis_area_lookup(area_tag); - /* invalidate and validate would delete all routes from zebra */ - isis_route_invalidate (area); - isis_route_validate (area); + if (area) { + VTY_PUSH_CONTEXT(ISIS_NODE, area); + return CMD_SUCCESS; + } + + area = isis_area_create(area_tag); - if (area->route_table[0]) - { - route_table_finish (area->route_table[0]); - area->route_table[0] = NULL; - } - if (area->route_table[1]) - { - route_table_finish (area->route_table[1]); - area->route_table[1] = NULL; - } - if (area->route_table6[0]) - { - route_table_finish (area->route_table6[0]); - area->route_table6[0] = NULL; - } - if (area->route_table6[1]) - { - route_table_finish (area->route_table6[1]); - area->route_table6[1] = NULL; - } + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("New IS-IS area instance %s", area->area_tag); - isis_redist_area_finish(area); + VTY_PUSH_CONTEXT(ISIS_NODE, area); - for (ALL_LIST_ELEMENTS (area->area_addrs, node, nnode, addr)) - { - list_delete_node (area->area_addrs, node); - XFREE (MTYPE_ISIS_AREA_ADDR, addr); - } - area->area_addrs = NULL; - - THREAD_TIMER_OFF (area->t_tick); - THREAD_TIMER_OFF (area->t_lsp_refresh[0]); - THREAD_TIMER_OFF (area->t_lsp_refresh[1]); - - thread_cancel_event (master, area); + return CMD_SUCCESS; +} - listnode_delete (isis->area_list, area); - - free (area->area_tag); - - area_mt_finish(area); - - XFREE (MTYPE_ISIS_AREA, area); - - if (listcount (isis->area_list) == 0) - { - memset (isis->sysid, 0, ISIS_SYS_ID_LEN); - isis->sysid_set = 0; - } - - return CMD_SUCCESS; -} - -static void -area_set_mt_enabled(struct isis_area *area, uint16_t mtid, bool enabled) -{ - struct isis_area_mt_setting *setting; - - setting = area_get_mt_setting(area, mtid); - if (setting->enabled != enabled) - { - setting->enabled = enabled; - lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); - } -} - -static void -area_set_mt_overload(struct isis_area *area, uint16_t mtid, bool overload) -{ - struct isis_area_mt_setting *setting; - - setting = area_get_mt_setting(area, mtid); - if (setting->overload != overload) - { - setting->overload = overload; - if (setting->enabled) - lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); - } -} - -int -area_net_title (struct vty *vty, const char *net_title) +int isis_area_destroy(struct vty *vty, const char *area_tag) { - VTY_DECLVAR_CONTEXT (isis_area, area); - struct area_addr *addr; - struct area_addr *addrp; - struct listnode *node; + struct isis_area *area; + struct listnode *node, *nnode; + struct isis_circuit *circuit; + struct area_addr *addr; - u_char buff[255]; + area = isis_area_lookup(area_tag); + + if (area == NULL) { + vty_out(vty, "Can't find ISIS instance \n"); + return CMD_ERR_NO_MATCH; + } + + QOBJ_UNREG(area); + + if (area->circuit_list) { + for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode, + circuit)) { + circuit->ip_router = 0; + circuit->ipv6_router = 0; + isis_csm_state_change(ISIS_DISABLE, circuit, area); + } + list_delete(area->circuit_list); + area->circuit_list = NULL; + } + + if (area->lspdb[0] != NULL) { + lsp_db_destroy(area->lspdb[0]); + area->lspdb[0] = NULL; + } + if (area->lspdb[1] != NULL) { + lsp_db_destroy(area->lspdb[1]); + area->lspdb[1] = NULL; + } + + spftree_area_del(area); + + THREAD_TIMER_OFF(area->spf_timer[0]); + THREAD_TIMER_OFF(area->spf_timer[1]); + + spf_backoff_free(area->spf_delay_ietf[0]); + spf_backoff_free(area->spf_delay_ietf[1]); + + /* invalidate and validate would delete all routes from zebra */ + isis_route_invalidate(area); + isis_route_validate(area); + + if (area->route_table[0]) { + route_table_finish(area->route_table[0]); + area->route_table[0] = NULL; + } + if (area->route_table[1]) { + route_table_finish(area->route_table[1]); + area->route_table[1] = NULL; + } + if (area->route_table6[0]) { + route_table_finish(area->route_table6[0]); + area->route_table6[0] = NULL; + } + if (area->route_table6[1]) { + route_table_finish(area->route_table6[1]); + area->route_table6[1] = NULL; + } + + isis_redist_area_finish(area); + + for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) { + list_delete_node(area->area_addrs, node); + XFREE(MTYPE_ISIS_AREA_ADDR, addr); + } + area->area_addrs = NULL; + + THREAD_TIMER_OFF(area->t_tick); + THREAD_TIMER_OFF(area->t_lsp_refresh[0]); + THREAD_TIMER_OFF(area->t_lsp_refresh[1]); + + thread_cancel_event(master, area); + + listnode_delete(isis->area_list, area); + + free(area->area_tag); + + area_mt_finish(area); + + XFREE(MTYPE_ISIS_AREA, area); + + if (listcount(isis->area_list) == 0) { + memset(isis->sysid, 0, ISIS_SYS_ID_LEN); + isis->sysid_set = 0; + } + + return CMD_SUCCESS; +} + +static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid, + bool enabled) +{ + struct isis_area_mt_setting *setting; + + setting = area_get_mt_setting(area, mtid); + if (setting->enabled != enabled) { + setting->enabled = enabled; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0); + } +} + +static void area_set_mt_overload(struct isis_area *area, uint16_t mtid, + bool overload) +{ + struct isis_area_mt_setting *setting; + + setting = area_get_mt_setting(area, mtid); + if (setting->overload != overload) { + setting->overload = overload; + if (setting->enabled) + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, + 0); + } +} + +int area_net_title(struct vty *vty, const char *net_title) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + struct area_addr *addr; + struct area_addr *addrp; + struct listnode *node; - /* We check that we are not over the maximal number of addresses */ - if (listcount (area->area_addrs) >= isis->max_area_addrs) - { - vty_out (vty, "Maximum of area addresses (%d) already reached \n", - isis->max_area_addrs); - return CMD_ERR_NOTHING_TODO; - } - - addr = XMALLOC (MTYPE_ISIS_AREA_ADDR, sizeof (struct area_addr)); - addr->addr_len = dotformat2buff (buff, net_title); - memcpy (addr->area_addr, buff, addr->addr_len); + u_char buff[255]; + + /* We check that we are not over the maximal number of addresses */ + if (listcount(area->area_addrs) >= isis->max_area_addrs) { + vty_out(vty, + "Maximum of area addresses (%d) already reached \n", + isis->max_area_addrs); + return CMD_ERR_NOTHING_TODO; + } + + addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr)); + addr->addr_len = dotformat2buff(buff, net_title); + memcpy(addr->area_addr, buff, addr->addr_len); #ifdef EXTREME_DEBUG - zlog_debug ("added area address %s for area %s (address length %d)", - net_title, area->area_tag, addr->addr_len); + zlog_debug("added area address %s for area %s (address length %d)", + net_title, area->area_tag, addr->addr_len); #endif /* EXTREME_DEBUG */ - if (addr->addr_len < 8 || addr->addr_len > 20) - { - vty_out (vty, "area address must be at least 8..20 octets long (%d)\n", - addr->addr_len); - XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; - } - - if (addr->area_addr[addr->addr_len-1] != 0) - { - vty_out (vty,"nsel byte (last byte) in area address must be 0\n"); - XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; - } - - if (isis->sysid_set == 0) - { - /* - * First area address - get the SystemID for this router - */ - memcpy (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN); - isis->sysid_set = 1; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("Router has SystemID %s", sysid_print (isis->sysid)); - } - else - { - /* - * Check that the SystemID portions match - */ - if (memcmp (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN)) - { - vty_out (vty, - "System ID must not change when defining additional area addresses\n"); - XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; - } - - /* now we see that we don't already have this address */ - for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp)) - { - if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN) != (addr->addr_len)) - continue; - if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len)) - { - XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_SUCCESS; /* silent fail */ - } - } - } - - /* - * Forget the systemID part of the address - */ - addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN); - listnode_add (area->area_addrs, addr); - - /* only now we can safely generate our LSPs for this area */ - if (listcount (area->area_addrs) > 0) - { - if (area->is_type & IS_LEVEL_1) - lsp_generate (area, IS_LEVEL_1); - if (area->is_type & IS_LEVEL_2) - lsp_generate (area, IS_LEVEL_2); - } - - return CMD_SUCCESS; -} - -int -area_clear_net_title (struct vty *vty, const char *net_title) -{ - VTY_DECLVAR_CONTEXT (isis_area, area); - struct area_addr addr, *addrp = NULL; - struct listnode *node; - u_char buff[255]; - - addr.addr_len = dotformat2buff (buff, net_title); - if (addr.addr_len < 8 || addr.addr_len > 20) - { - vty_out (vty, "Unsupported area address length %d, should be 8...20 \n", - addr.addr_len); - return CMD_ERR_AMBIGUOUS; - } - - memcpy (addr.area_addr, buff, (int) addr.addr_len); - - for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp)) - if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len && - !memcmp (addrp->area_addr, addr.area_addr, addr.addr_len)) - break; - - if (!addrp) - { - vty_out (vty, "No area address %s for area %s \n", net_title, - area->area_tag); - return CMD_ERR_NO_MATCH; - } - - listnode_delete (area->area_addrs, addrp); - XFREE (MTYPE_ISIS_AREA_ADDR, addrp); - - /* - * Last area address - reset the SystemID for this router - */ - if (listcount (area->area_addrs) == 0) - { - memset (isis->sysid, 0, ISIS_SYS_ID_LEN); - isis->sysid_set = 0; - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("Router has no SystemID"); - } - - return CMD_SUCCESS; + if (addr->addr_len < 8 || addr->addr_len > 20) { + vty_out(vty, + "area address must be at least 8..20 octets long (%d)\n", + addr->addr_len); + XFREE(MTYPE_ISIS_AREA_ADDR, addr); + return CMD_ERR_AMBIGUOUS; + } + + if (addr->area_addr[addr->addr_len - 1] != 0) { + vty_out(vty, + "nsel byte (last byte) in area address must be 0\n"); + XFREE(MTYPE_ISIS_AREA_ADDR, addr); + return CMD_ERR_AMBIGUOUS; + } + + if (isis->sysid_set == 0) { + /* + * First area address - get the SystemID for this router + */ + memcpy(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN); + isis->sysid_set = 1; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("Router has SystemID %s", + sysid_print(isis->sysid)); + } else { + /* + * Check that the SystemID portions match + */ + if (memcmp(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN)) { + vty_out(vty, + "System ID must not change when defining additional area addresses\n"); + XFREE(MTYPE_ISIS_AREA_ADDR, addr); + return CMD_ERR_AMBIGUOUS; + } + + /* now we see that we don't already have this address */ + for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) { + if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN) + != (addr->addr_len)) + continue; + if (!memcmp(addrp->area_addr, addr->area_addr, + addr->addr_len)) { + XFREE(MTYPE_ISIS_AREA_ADDR, addr); + return CMD_SUCCESS; /* silent fail */ + } + } + } + + /* + * Forget the systemID part of the address + */ + addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN); + listnode_add(area->area_addrs, addr); + + /* only now we can safely generate our LSPs for this area */ + if (listcount(area->area_addrs) > 0) { + if (area->is_type & IS_LEVEL_1) + lsp_generate(area, IS_LEVEL_1); + if (area->is_type & IS_LEVEL_2) + lsp_generate(area, IS_LEVEL_2); + } + + return CMD_SUCCESS; +} + +int area_clear_net_title(struct vty *vty, const char *net_title) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + struct area_addr addr, *addrp = NULL; + struct listnode *node; + u_char buff[255]; + + addr.addr_len = dotformat2buff(buff, net_title); + if (addr.addr_len < 8 || addr.addr_len > 20) { + vty_out(vty, + "Unsupported area address length %d, should be 8...20 \n", + addr.addr_len); + return CMD_ERR_AMBIGUOUS; + } + + memcpy(addr.area_addr, buff, (int)addr.addr_len); + + for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) + if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len + && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len)) + break; + + if (!addrp) { + vty_out(vty, "No area address %s for area %s \n", net_title, + area->area_tag); + return CMD_ERR_NO_MATCH; + } + + listnode_delete(area->area_addrs, addrp); + XFREE(MTYPE_ISIS_AREA_ADDR, addrp); + + /* + * Last area address - reset the SystemID for this router + */ + if (listcount(area->area_addrs) == 0) { + memset(isis->sysid, 0, ISIS_SYS_ID_LEN); + isis->sysid_set = 0; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("Router has no SystemID"); + } + + return CMD_SUCCESS; } /* * 'show isis interface' command */ -int -show_isis_interface_common (struct vty *vty, const char *ifname, char detail) +int show_isis_interface_common(struct vty *vty, const char *ifname, char detail) { - struct listnode *anode, *cnode; - struct isis_area *area; - struct isis_circuit *circuit; + struct listnode *anode, *cnode; + struct isis_area *area; + struct isis_circuit *circuit; - if (!isis) - { - vty_out (vty, "IS-IS Routing Process not enabled\n"); - return CMD_SUCCESS; - } + if (!isis) { + vty_out(vty, "IS-IS Routing Process not enabled\n"); + return CMD_SUCCESS; + } - for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area)) - { - vty_out (vty, "Area %s:\n", area->area_tag); + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + vty_out(vty, "Area %s:\n", area->area_tag); - if (detail == ISIS_UI_LEVEL_BRIEF) - vty_out (vty," Interface CircId State Type Level\n"); + if (detail == ISIS_UI_LEVEL_BRIEF) + vty_out(vty, + " Interface CircId State Type Level\n"); - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) - if (!ifname) - isis_circuit_print_vty (circuit, vty, detail); - else if (strcmp(circuit->interface->name, ifname) == 0) - isis_circuit_print_vty (circuit, vty, detail); - } + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) + if (!ifname) + isis_circuit_print_vty(circuit, vty, detail); + else if (strcmp(circuit->interface->name, ifname) == 0) + isis_circuit_print_vty(circuit, vty, detail); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_isis_interface, @@ -521,7 +491,7 @@ DEFUN (show_isis_interface, "ISIS network information\n" "ISIS interface\n") { - return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_BRIEF); + return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); } DEFUN (show_isis_interface_detail, @@ -532,7 +502,7 @@ DEFUN (show_isis_interface_detail, "ISIS interface\n" "show detailed information\n") { - return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_DETAIL); + return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL); } DEFUN (show_isis_interface_arg, @@ -543,150 +513,146 @@ DEFUN (show_isis_interface_arg, "ISIS interface\n" "ISIS interface name\n") { - int idx_word = 3; - return show_isis_interface_common (vty, argv[idx_word]->arg, ISIS_UI_LEVEL_DETAIL); + int idx_word = 3; + return show_isis_interface_common(vty, argv[idx_word]->arg, + ISIS_UI_LEVEL_DETAIL); } /* * 'show isis neighbor' command */ -int -show_isis_neighbor_common (struct vty *vty, const char *id, char detail) -{ - struct listnode *anode, *cnode, *node; - struct isis_area *area; - struct isis_circuit *circuit; - struct list *adjdb; - struct isis_adjacency *adj; - struct isis_dynhn *dynhn; - u_char sysid[ISIS_SYS_ID_LEN]; - int i; - - if (!isis) - { - vty_out (vty, "IS-IS Routing Process not enabled\n"); - return CMD_SUCCESS; - } - - memset (sysid, 0, ISIS_SYS_ID_LEN); - if (id) - { - if (sysid2buff (sysid, id) == 0) - { - dynhn = dynhn_find_by_name (id); - if (dynhn == NULL) - { - vty_out (vty, "Invalid system id %s\n", id); - return CMD_SUCCESS; - } - memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN); - } - } - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area)) - { - vty_out (vty, "Area %s:\n", area->area_tag); - - if (detail == ISIS_UI_LEVEL_BRIEF) - vty_out (vty, - " System Id Interface L State Holdtime SNPA\n"); - - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) - { - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - for (i = 0; i < 2; i++) - { - adjdb = circuit->u.bc.adjdb[i]; - if (adjdb && adjdb->count) - { - for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) - if (!id || !memcmp (adj->sysid, sysid, - ISIS_SYS_ID_LEN)) - isis_adj_print_vty (adj, vty, detail); - } - } - } - else if (circuit->circ_type == CIRCUIT_T_P2P && - circuit->u.p2p.neighbor) - { - adj = circuit->u.p2p.neighbor; - if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) - isis_adj_print_vty (adj, vty, detail); - } - } - } - - return CMD_SUCCESS; +int show_isis_neighbor_common(struct vty *vty, const char *id, char detail) +{ + struct listnode *anode, *cnode, *node; + struct isis_area *area; + struct isis_circuit *circuit; + struct list *adjdb; + struct isis_adjacency *adj; + struct isis_dynhn *dynhn; + u_char sysid[ISIS_SYS_ID_LEN]; + int i; + + if (!isis) { + vty_out(vty, "IS-IS Routing Process not enabled\n"); + return CMD_SUCCESS; + } + + memset(sysid, 0, ISIS_SYS_ID_LEN); + if (id) { + if (sysid2buff(sysid, id) == 0) { + dynhn = dynhn_find_by_name(id); + if (dynhn == NULL) { + vty_out(vty, "Invalid system id %s\n", id); + return CMD_SUCCESS; + } + memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN); + } + } + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + vty_out(vty, "Area %s:\n", area->area_tag); + + if (detail == ISIS_UI_LEVEL_BRIEF) + vty_out(vty, + " System Id Interface L State Holdtime SNPA\n"); + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + for (i = 0; i < 2; i++) { + adjdb = circuit->u.bc.adjdb[i]; + if (adjdb && adjdb->count) { + for (ALL_LIST_ELEMENTS_RO( + adjdb, node, adj)) + if (!id + || !memcmp(adj->sysid, + sysid, + ISIS_SYS_ID_LEN)) + isis_adj_print_vty( + adj, + vty, + detail); + } + } + } else if (circuit->circ_type == CIRCUIT_T_P2P + && circuit->u.p2p.neighbor) { + adj = circuit->u.p2p.neighbor; + if (!id + || !memcmp(adj->sysid, sysid, + ISIS_SYS_ID_LEN)) + isis_adj_print_vty(adj, vty, detail); + } + } + } + + return CMD_SUCCESS; } /* * 'clear isis neighbor' command */ -int -clear_isis_neighbor_common (struct vty *vty, const char *id) -{ - struct listnode *anode, *cnode, *cnextnode, *node, *nnode; - struct isis_area *area; - struct isis_circuit *circuit; - struct list *adjdb; - struct isis_adjacency *adj; - struct isis_dynhn *dynhn; - u_char sysid[ISIS_SYS_ID_LEN]; - int i; - - if (!isis) - { - vty_out (vty, "IS-IS Routing Process not enabled\n"); - return CMD_SUCCESS; - } - - memset (sysid, 0, ISIS_SYS_ID_LEN); - if (id) - { - if (sysid2buff (sysid, id) == 0) - { - dynhn = dynhn_find_by_name (id); - if (dynhn == NULL) - { - vty_out (vty, "Invalid system id %s\n", id); - return CMD_SUCCESS; - } - memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN); - } - } - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area)) - { - for (ALL_LIST_ELEMENTS (area->circuit_list, cnode, cnextnode, circuit)) - { - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - for (i = 0; i < 2; i++) - { - adjdb = circuit->u.bc.adjdb[i]; - if (adjdb && adjdb->count) - { - for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj)) - if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) - isis_adj_state_change (adj, ISIS_ADJ_DOWN, - "clear user request"); - } - } - } - else if (circuit->circ_type == CIRCUIT_T_P2P && - circuit->u.p2p.neighbor) - { - adj = circuit->u.p2p.neighbor; - if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) - isis_adj_state_change (adj, ISIS_ADJ_DOWN, - "clear user request"); - } - } - } - - return CMD_SUCCESS; +int clear_isis_neighbor_common(struct vty *vty, const char *id) +{ + struct listnode *anode, *cnode, *cnextnode, *node, *nnode; + struct isis_area *area; + struct isis_circuit *circuit; + struct list *adjdb; + struct isis_adjacency *adj; + struct isis_dynhn *dynhn; + u_char sysid[ISIS_SYS_ID_LEN]; + int i; + + if (!isis) { + vty_out(vty, "IS-IS Routing Process not enabled\n"); + return CMD_SUCCESS; + } + + memset(sysid, 0, ISIS_SYS_ID_LEN); + if (id) { + if (sysid2buff(sysid, id) == 0) { + dynhn = dynhn_find_by_name(id); + if (dynhn == NULL) { + vty_out(vty, "Invalid system id %s\n", id); + return CMD_SUCCESS; + } + memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN); + } + } + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode, + circuit)) { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + for (i = 0; i < 2; i++) { + adjdb = circuit->u.bc.adjdb[i]; + if (adjdb && adjdb->count) { + for (ALL_LIST_ELEMENTS( + adjdb, node, nnode, + adj)) + if (!id + || !memcmp(adj->sysid, + sysid, + ISIS_SYS_ID_LEN)) + isis_adj_state_change( + adj, + ISIS_ADJ_DOWN, + "clear user request"); + } + } + } else if (circuit->circ_type == CIRCUIT_T_P2P + && circuit->u.p2p.neighbor) { + adj = circuit->u.p2p.neighbor; + if (!id + || !memcmp(adj->sysid, sysid, + ISIS_SYS_ID_LEN)) + isis_adj_state_change( + adj, ISIS_ADJ_DOWN, + "clear user request"); + } + } + } + + return CMD_SUCCESS; } DEFUN (show_isis_neighbor, @@ -696,7 +662,7 @@ DEFUN (show_isis_neighbor, "ISIS network information\n" "ISIS neighbor adjacencies\n") { - return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_BRIEF); + return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); } DEFUN (show_isis_neighbor_detail, @@ -707,7 +673,7 @@ DEFUN (show_isis_neighbor_detail, "ISIS neighbor adjacencies\n" "show detailed information\n") { - return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_DETAIL); + return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL); } DEFUN (show_isis_neighbor_arg, @@ -718,8 +684,9 @@ DEFUN (show_isis_neighbor_arg, "ISIS neighbor adjacencies\n" "System id\n") { - int idx_word = 3; - return show_isis_neighbor_common (vty, argv[idx_word]->arg, ISIS_UI_LEVEL_DETAIL); + int idx_word = 3; + return show_isis_neighbor_common(vty, argv[idx_word]->arg, + ISIS_UI_LEVEL_DETAIL); } DEFUN (clear_isis_neighbor, @@ -729,7 +696,7 @@ DEFUN (clear_isis_neighbor, "Reset ISIS network information\n" "Reset ISIS neighbor adjacencies\n") { - return clear_isis_neighbor_common (vty, NULL); + return clear_isis_neighbor_common(vty, NULL); } DEFUN (clear_isis_neighbor_arg, @@ -740,52 +707,56 @@ DEFUN (clear_isis_neighbor_arg, "ISIS neighbor adjacencies\n" "System id\n") { - int idx_word = 3; - return clear_isis_neighbor_common (vty, argv[idx_word]->arg); + int idx_word = 3; + return clear_isis_neighbor_common(vty, argv[idx_word]->arg); } /* * 'isis debug', 'show debugging' */ -void -print_debug (struct vty *vty, int flags, int onoff) -{ - char onoffs[4]; - if (onoff) - strcpy (onoffs, "on"); - else - strcpy (onoffs, "off"); - - if (flags & DEBUG_ADJ_PACKETS) - vty_out (vty, "IS-IS Adjacency related packets debugging is %s\n", - onoffs); - if (flags & DEBUG_CHECKSUM_ERRORS) - vty_out (vty, "IS-IS checksum errors debugging is %s\n",onoffs); - if (flags & DEBUG_LOCAL_UPDATES) - vty_out (vty, "IS-IS local updates debugging is %s\n",onoffs); - if (flags & DEBUG_PROTOCOL_ERRORS) - vty_out (vty, "IS-IS protocol errors debugging is %s\n",onoffs); - if (flags & DEBUG_SNP_PACKETS) - vty_out (vty, "IS-IS CSNP/PSNP packets debugging is %s\n",onoffs); - if (flags & DEBUG_SPF_EVENTS) - vty_out (vty, "IS-IS SPF events debugging is %s\n", onoffs); - if (flags & DEBUG_SPF_STATS) - vty_out (vty, "IS-IS SPF Timing and Statistics Data debugging is %s\n", - onoffs); - if (flags & DEBUG_SPF_TRIGGERS) - vty_out (vty, "IS-IS SPF triggering events debugging is %s\n",onoffs); - if (flags & DEBUG_UPDATE_PACKETS) - vty_out (vty, "IS-IS Update related packet debugging is %s\n",onoffs); - if (flags & DEBUG_RTE_EVENTS) - vty_out (vty, "IS-IS Route related debuggin is %s\n",onoffs); - if (flags & DEBUG_EVENTS) - vty_out (vty, "IS-IS Event debugging is %s\n", onoffs); - if (flags & DEBUG_PACKET_DUMP) - vty_out (vty, "IS-IS Packet dump debugging is %s\n", onoffs); - if (flags & DEBUG_LSP_GEN) - vty_out (vty, "IS-IS LSP generation debugging is %s\n", onoffs); - if (flags & DEBUG_LSP_SCHED) - vty_out (vty, "IS-IS LSP scheduling debugging is %s\n", onoffs); +void print_debug(struct vty *vty, int flags, int onoff) +{ + char onoffs[4]; + if (onoff) + strcpy(onoffs, "on"); + else + strcpy(onoffs, "off"); + + if (flags & DEBUG_ADJ_PACKETS) + vty_out(vty, + "IS-IS Adjacency related packets debugging is %s\n", + onoffs); + if (flags & DEBUG_CHECKSUM_ERRORS) + vty_out(vty, "IS-IS checksum errors debugging is %s\n", onoffs); + if (flags & DEBUG_LOCAL_UPDATES) + vty_out(vty, "IS-IS local updates debugging is %s\n", onoffs); + if (flags & DEBUG_PROTOCOL_ERRORS) + vty_out(vty, "IS-IS protocol errors debugging is %s\n", onoffs); + if (flags & DEBUG_SNP_PACKETS) + vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n", + onoffs); + if (flags & DEBUG_SPF_EVENTS) + vty_out(vty, "IS-IS SPF events debugging is %s\n", onoffs); + if (flags & DEBUG_SPF_STATS) + vty_out(vty, + "IS-IS SPF Timing and Statistics Data debugging is %s\n", + onoffs); + if (flags & DEBUG_SPF_TRIGGERS) + vty_out(vty, "IS-IS SPF triggering events debugging is %s\n", + onoffs); + if (flags & DEBUG_UPDATE_PACKETS) + vty_out(vty, "IS-IS Update related packet debugging is %s\n", + onoffs); + if (flags & DEBUG_RTE_EVENTS) + vty_out(vty, "IS-IS Route related debuggin is %s\n", onoffs); + if (flags & DEBUG_EVENTS) + vty_out(vty, "IS-IS Event debugging is %s\n", onoffs); + if (flags & DEBUG_PACKET_DUMP) + vty_out(vty, "IS-IS Packet dump debugging is %s\n", onoffs); + if (flags & DEBUG_LSP_GEN) + vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs); + if (flags & DEBUG_LSP_SCHED) + vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs); } DEFUN (show_debugging, @@ -795,99 +766,80 @@ DEFUN (show_debugging, "State of each debugging option\n" ISIS_STR) { - if (isis->debugs) { - vty_out (vty, "IS-IS:\n"); - print_debug (vty, isis->debugs, 1); - } - return CMD_SUCCESS; + if (isis->debugs) { + vty_out(vty, "IS-IS:\n"); + print_debug(vty, isis->debugs, 1); + } + return CMD_SUCCESS; } /* Debug node. */ -static struct cmd_node debug_node = { - DEBUG_NODE, - "", - 1 -}; - -static int -config_write_debug (struct vty *vty) -{ - int write = 0; - int flags = isis->debugs; - - if (flags & DEBUG_ADJ_PACKETS) - { - vty_out (vty, "debug isis adj-packets\n"); - write++; - } - if (flags & DEBUG_CHECKSUM_ERRORS) - { - vty_out (vty, "debug isis checksum-errors\n"); - write++; - } - if (flags & DEBUG_LOCAL_UPDATES) - { - vty_out (vty, "debug isis local-updates\n"); - write++; - } - if (flags & DEBUG_PROTOCOL_ERRORS) - { - vty_out (vty, "debug isis protocol-errors\n"); - write++; - } - if (flags & DEBUG_SNP_PACKETS) - { - vty_out (vty, "debug isis snp-packets\n"); - write++; - } - if (flags & DEBUG_SPF_EVENTS) - { - vty_out (vty, "debug isis spf-events\n"); - write++; - } - if (flags & DEBUG_SPF_STATS) - { - vty_out (vty, "debug isis spf-statistics\n"); - write++; - } - if (flags & DEBUG_SPF_TRIGGERS) - { - vty_out (vty, "debug isis spf-triggers\n"); - write++; - } - if (flags & DEBUG_UPDATE_PACKETS) - { - vty_out (vty, "debug isis update-packets\n"); - write++; - } - if (flags & DEBUG_RTE_EVENTS) - { - vty_out (vty, "debug isis route-events\n"); - write++; - } - if (flags & DEBUG_EVENTS) - { - vty_out (vty, "debug isis events\n"); - write++; - } - if (flags & DEBUG_PACKET_DUMP) - { - vty_out (vty, "debug isis packet-dump\n"); - write++; - } - if (flags & DEBUG_LSP_GEN) - { - vty_out (vty, "debug isis lsp-gen\n"); - write++; - } - if (flags & DEBUG_LSP_SCHED) - { - vty_out (vty, "debug isis lsp-sched\n"); - write++; - } - write += spf_backoff_write_config(vty); - - return write; +static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; + +static int config_write_debug(struct vty *vty) +{ + int write = 0; + int flags = isis->debugs; + + if (flags & DEBUG_ADJ_PACKETS) { + vty_out(vty, "debug isis adj-packets\n"); + write++; + } + if (flags & DEBUG_CHECKSUM_ERRORS) { + vty_out(vty, "debug isis checksum-errors\n"); + write++; + } + if (flags & DEBUG_LOCAL_UPDATES) { + vty_out(vty, "debug isis local-updates\n"); + write++; + } + if (flags & DEBUG_PROTOCOL_ERRORS) { + vty_out(vty, "debug isis protocol-errors\n"); + write++; + } + if (flags & DEBUG_SNP_PACKETS) { + vty_out(vty, "debug isis snp-packets\n"); + write++; + } + if (flags & DEBUG_SPF_EVENTS) { + vty_out(vty, "debug isis spf-events\n"); + write++; + } + if (flags & DEBUG_SPF_STATS) { + vty_out(vty, "debug isis spf-statistics\n"); + write++; + } + if (flags & DEBUG_SPF_TRIGGERS) { + vty_out(vty, "debug isis spf-triggers\n"); + write++; + } + if (flags & DEBUG_UPDATE_PACKETS) { + vty_out(vty, "debug isis update-packets\n"); + write++; + } + if (flags & DEBUG_RTE_EVENTS) { + vty_out(vty, "debug isis route-events\n"); + write++; + } + if (flags & DEBUG_EVENTS) { + vty_out(vty, "debug isis events\n"); + write++; + } + if (flags & DEBUG_PACKET_DUMP) { + vty_out(vty, "debug isis packet-dump\n"); + write++; + } + if (flags & DEBUG_LSP_GEN) { + vty_out(vty, "debug isis lsp-gen\n"); + write++; + } + if (flags & DEBUG_LSP_SCHED) { + vty_out(vty, "debug isis lsp-sched\n"); + write++; + } + write += spf_backoff_write_config(vty); + + return write; } DEFUN (debug_isis_adj, @@ -897,10 +849,10 @@ DEFUN (debug_isis_adj, "IS-IS information\n" "IS-IS Adjacency related packets\n") { - isis->debugs |= DEBUG_ADJ_PACKETS; - print_debug (vty, DEBUG_ADJ_PACKETS, 1); + isis->debugs |= DEBUG_ADJ_PACKETS; + print_debug(vty, DEBUG_ADJ_PACKETS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_adj, @@ -911,10 +863,10 @@ DEFUN (no_debug_isis_adj, "IS-IS information\n" "IS-IS Adjacency related packets\n") { - isis->debugs &= ~DEBUG_ADJ_PACKETS; - print_debug (vty, DEBUG_ADJ_PACKETS, 0); + isis->debugs &= ~DEBUG_ADJ_PACKETS; + print_debug(vty, DEBUG_ADJ_PACKETS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_csum, @@ -924,10 +876,10 @@ DEFUN (debug_isis_csum, "IS-IS information\n" "IS-IS LSP checksum errors\n") { - isis->debugs |= DEBUG_CHECKSUM_ERRORS; - print_debug (vty, DEBUG_CHECKSUM_ERRORS, 1); + isis->debugs |= DEBUG_CHECKSUM_ERRORS; + print_debug(vty, DEBUG_CHECKSUM_ERRORS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_csum, @@ -938,10 +890,10 @@ DEFUN (no_debug_isis_csum, "IS-IS information\n" "IS-IS LSP checksum errors\n") { - isis->debugs &= ~DEBUG_CHECKSUM_ERRORS; - print_debug (vty, DEBUG_CHECKSUM_ERRORS, 0); + isis->debugs &= ~DEBUG_CHECKSUM_ERRORS; + print_debug(vty, DEBUG_CHECKSUM_ERRORS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_lupd, @@ -951,10 +903,10 @@ DEFUN (debug_isis_lupd, "IS-IS information\n" "IS-IS local update packets\n") { - isis->debugs |= DEBUG_LOCAL_UPDATES; - print_debug (vty, DEBUG_LOCAL_UPDATES, 1); + isis->debugs |= DEBUG_LOCAL_UPDATES; + print_debug(vty, DEBUG_LOCAL_UPDATES, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_lupd, @@ -965,10 +917,10 @@ DEFUN (no_debug_isis_lupd, "IS-IS information\n" "IS-IS local update packets\n") { - isis->debugs &= ~DEBUG_LOCAL_UPDATES; - print_debug (vty, DEBUG_LOCAL_UPDATES, 0); + isis->debugs &= ~DEBUG_LOCAL_UPDATES; + print_debug(vty, DEBUG_LOCAL_UPDATES, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_err, @@ -978,10 +930,10 @@ DEFUN (debug_isis_err, "IS-IS information\n" "IS-IS LSP protocol errors\n") { - isis->debugs |= DEBUG_PROTOCOL_ERRORS; - print_debug (vty, DEBUG_PROTOCOL_ERRORS, 1); + isis->debugs |= DEBUG_PROTOCOL_ERRORS; + print_debug(vty, DEBUG_PROTOCOL_ERRORS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_err, @@ -992,10 +944,10 @@ DEFUN (no_debug_isis_err, "IS-IS information\n" "IS-IS LSP protocol errors\n") { - isis->debugs &= ~DEBUG_PROTOCOL_ERRORS; - print_debug (vty, DEBUG_PROTOCOL_ERRORS, 0); + isis->debugs &= ~DEBUG_PROTOCOL_ERRORS; + print_debug(vty, DEBUG_PROTOCOL_ERRORS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_snp, @@ -1005,10 +957,10 @@ DEFUN (debug_isis_snp, "IS-IS information\n" "IS-IS CSNP/PSNP packets\n") { - isis->debugs |= DEBUG_SNP_PACKETS; - print_debug (vty, DEBUG_SNP_PACKETS, 1); + isis->debugs |= DEBUG_SNP_PACKETS; + print_debug(vty, DEBUG_SNP_PACKETS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_snp, @@ -1019,10 +971,10 @@ DEFUN (no_debug_isis_snp, "IS-IS information\n" "IS-IS CSNP/PSNP packets\n") { - isis->debugs &= ~DEBUG_SNP_PACKETS; - print_debug (vty, DEBUG_SNP_PACKETS, 0); + isis->debugs &= ~DEBUG_SNP_PACKETS; + print_debug(vty, DEBUG_SNP_PACKETS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_upd, @@ -1032,10 +984,10 @@ DEFUN (debug_isis_upd, "IS-IS information\n" "IS-IS Update related packets\n") { - isis->debugs |= DEBUG_UPDATE_PACKETS; - print_debug (vty, DEBUG_UPDATE_PACKETS, 1); + isis->debugs |= DEBUG_UPDATE_PACKETS; + print_debug(vty, DEBUG_UPDATE_PACKETS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_upd, @@ -1046,10 +998,10 @@ DEFUN (no_debug_isis_upd, "IS-IS information\n" "IS-IS Update related packets\n") { - isis->debugs &= ~DEBUG_UPDATE_PACKETS; - print_debug (vty, DEBUG_UPDATE_PACKETS, 0); + isis->debugs &= ~DEBUG_UPDATE_PACKETS; + print_debug(vty, DEBUG_UPDATE_PACKETS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_spfevents, @@ -1059,10 +1011,10 @@ DEFUN (debug_isis_spfevents, "IS-IS information\n" "IS-IS Shortest Path First Events\n") { - isis->debugs |= DEBUG_SPF_EVENTS; - print_debug (vty, DEBUG_SPF_EVENTS, 1); + isis->debugs |= DEBUG_SPF_EVENTS; + print_debug(vty, DEBUG_SPF_EVENTS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_spfevents, @@ -1073,10 +1025,10 @@ DEFUN (no_debug_isis_spfevents, "IS-IS information\n" "IS-IS Shortest Path First Events\n") { - isis->debugs &= ~DEBUG_SPF_EVENTS; - print_debug (vty, DEBUG_SPF_EVENTS, 0); + isis->debugs &= ~DEBUG_SPF_EVENTS; + print_debug(vty, DEBUG_SPF_EVENTS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_spfstats, @@ -1086,10 +1038,10 @@ DEFUN (debug_isis_spfstats, "IS-IS information\n" "IS-IS SPF Timing and Statistic Data\n") { - isis->debugs |= DEBUG_SPF_STATS; - print_debug (vty, DEBUG_SPF_STATS, 1); + isis->debugs |= DEBUG_SPF_STATS; + print_debug(vty, DEBUG_SPF_STATS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_spfstats, @@ -1100,10 +1052,10 @@ DEFUN (no_debug_isis_spfstats, "IS-IS information\n" "IS-IS SPF Timing and Statistic Data\n") { - isis->debugs &= ~DEBUG_SPF_STATS; - print_debug (vty, DEBUG_SPF_STATS, 0); + isis->debugs &= ~DEBUG_SPF_STATS; + print_debug(vty, DEBUG_SPF_STATS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_spftrigg, @@ -1113,10 +1065,10 @@ DEFUN (debug_isis_spftrigg, "IS-IS information\n" "IS-IS SPF triggering events\n") { - isis->debugs |= DEBUG_SPF_TRIGGERS; - print_debug (vty, DEBUG_SPF_TRIGGERS, 1); + isis->debugs |= DEBUG_SPF_TRIGGERS; + print_debug(vty, DEBUG_SPF_TRIGGERS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_spftrigg, @@ -1127,10 +1079,10 @@ DEFUN (no_debug_isis_spftrigg, "IS-IS information\n" "IS-IS SPF triggering events\n") { - isis->debugs &= ~DEBUG_SPF_TRIGGERS; - print_debug (vty, DEBUG_SPF_TRIGGERS, 0); + isis->debugs &= ~DEBUG_SPF_TRIGGERS; + print_debug(vty, DEBUG_SPF_TRIGGERS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_rtevents, @@ -1140,10 +1092,10 @@ DEFUN (debug_isis_rtevents, "IS-IS information\n" "IS-IS Route related events\n") { - isis->debugs |= DEBUG_RTE_EVENTS; - print_debug (vty, DEBUG_RTE_EVENTS, 1); + isis->debugs |= DEBUG_RTE_EVENTS; + print_debug(vty, DEBUG_RTE_EVENTS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_rtevents, @@ -1154,10 +1106,10 @@ DEFUN (no_debug_isis_rtevents, "IS-IS information\n" "IS-IS Route related events\n") { - isis->debugs &= ~DEBUG_RTE_EVENTS; - print_debug (vty, DEBUG_RTE_EVENTS, 0); + isis->debugs &= ~DEBUG_RTE_EVENTS; + print_debug(vty, DEBUG_RTE_EVENTS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_events, @@ -1167,10 +1119,10 @@ DEFUN (debug_isis_events, "IS-IS information\n" "IS-IS Events\n") { - isis->debugs |= DEBUG_EVENTS; - print_debug (vty, DEBUG_EVENTS, 1); + isis->debugs |= DEBUG_EVENTS; + print_debug(vty, DEBUG_EVENTS, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_events, @@ -1181,10 +1133,10 @@ DEFUN (no_debug_isis_events, "IS-IS information\n" "IS-IS Events\n") { - isis->debugs &= ~DEBUG_EVENTS; - print_debug (vty, DEBUG_EVENTS, 0); + isis->debugs &= ~DEBUG_EVENTS; + print_debug(vty, DEBUG_EVENTS, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_packet_dump, @@ -1194,10 +1146,10 @@ DEFUN (debug_isis_packet_dump, "IS-IS information\n" "IS-IS packet dump\n") { - isis->debugs |= DEBUG_PACKET_DUMP; - print_debug (vty, DEBUG_PACKET_DUMP, 1); + isis->debugs |= DEBUG_PACKET_DUMP; + print_debug(vty, DEBUG_PACKET_DUMP, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_packet_dump, @@ -1208,10 +1160,10 @@ DEFUN (no_debug_isis_packet_dump, "IS-IS information\n" "IS-IS packet dump\n") { - isis->debugs &= ~DEBUG_PACKET_DUMP; - print_debug (vty, DEBUG_PACKET_DUMP, 0); + isis->debugs &= ~DEBUG_PACKET_DUMP; + print_debug(vty, DEBUG_PACKET_DUMP, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_lsp_gen, @@ -1221,10 +1173,10 @@ DEFUN (debug_isis_lsp_gen, "IS-IS information\n" "IS-IS generation of own LSPs\n") { - isis->debugs |= DEBUG_LSP_GEN; - print_debug (vty, DEBUG_LSP_GEN, 1); + isis->debugs |= DEBUG_LSP_GEN; + print_debug(vty, DEBUG_LSP_GEN, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_lsp_gen, @@ -1235,10 +1187,10 @@ DEFUN (no_debug_isis_lsp_gen, "IS-IS information\n" "IS-IS generation of own LSPs\n") { - isis->debugs &= ~DEBUG_LSP_GEN; - print_debug (vty, DEBUG_LSP_GEN, 0); + isis->debugs &= ~DEBUG_LSP_GEN; + print_debug(vty, DEBUG_LSP_GEN, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_isis_lsp_sched, @@ -1248,10 +1200,10 @@ DEFUN (debug_isis_lsp_sched, "IS-IS information\n" "IS-IS scheduling of LSP generation\n") { - isis->debugs |= DEBUG_LSP_SCHED; - print_debug (vty, DEBUG_LSP_SCHED, 1); + isis->debugs |= DEBUG_LSP_SCHED; + print_debug(vty, DEBUG_LSP_SCHED, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_isis_lsp_sched, @@ -1262,10 +1214,10 @@ DEFUN (no_debug_isis_lsp_sched, "IS-IS information\n" "IS-IS scheduling of LSP generation\n") { - isis->debugs &= ~DEBUG_LSP_SCHED; - print_debug (vty, DEBUG_LSP_SCHED, 0); + isis->debugs &= ~DEBUG_LSP_SCHED; + print_debug(vty, DEBUG_LSP_SCHED, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_hostname, @@ -1275,32 +1227,30 @@ DEFUN (show_hostname, "IS-IS information\n" "IS-IS Dynamic hostname mapping\n") { - dynhn_print_all (vty); + dynhn_print_all(vty); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static void -vty_out_timestr(struct vty *vty, time_t uptime) +static void vty_out_timestr(struct vty *vty, time_t uptime) { - struct tm *tm; - time_t difftime = time (NULL); - difftime -= uptime; - tm = gmtime (&difftime); + struct tm *tm; + time_t difftime = time(NULL); + difftime -= uptime; + tm = gmtime(&difftime); #define ONE_DAY_SECOND 60*60*24 #define ONE_WEEK_SECOND 60*60*24*7 - if (difftime < ONE_DAY_SECOND) - vty_out (vty, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (difftime < ONE_WEEK_SECOND) - vty_out (vty, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); - else - vty_out (vty, "%02dw%dd%02dh", - tm->tm_yday/7, - tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - vty_out (vty, " ago"); + if (difftime < ONE_DAY_SECOND) + vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, + tm->tm_sec); + else if (difftime < ONE_WEEK_SECOND) + vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, + tm->tm_min); + else + vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour); + vty_out(vty, " ago"); } DEFUN (show_isis_spf_ietf, @@ -1310,46 +1260,46 @@ DEFUN (show_isis_spf_ietf, "IS-IS information\n" "IS-IS SPF delay IETF information\n") { - if (!isis) - { - vty_out (vty, "ISIS is not running\n"); - return CMD_SUCCESS; - } - - struct listnode *node; - struct isis_area *area; - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - vty_out (vty, "Area %s:\n",area->area_tag ? area->area_tag : "null"); - - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) - { - if ((area->is_type & level) == 0) - continue; - - vty_out (vty, " Level-%d:\n", level); - vty_out (vty, " SPF delay status: "); - if (area->spf_timer[level -1]) - { - struct timeval remain = thread_timer_remain(area->spf_timer[level - 1]); - vty_out (vty, "Pending, due in %ld msec\n", - remain.tv_sec * 1000 + remain.tv_usec / 1000); - } - else - { - vty_out (vty, "Not scheduled\n"); - } - - if (area->spf_delay_ietf[level - 1]) { - vty_out (vty, " Using draft-ietf-rtgwg-backoff-algo-04\n"); - spf_backoff_show(area->spf_delay_ietf[level - 1], vty, " "); - } else { - vty_out (vty, " Using legacy backoff algo\n"); - } - } - } - return CMD_SUCCESS; + if (!isis) { + vty_out(vty, "ISIS is not running\n"); + return CMD_SUCCESS; + } + + struct listnode *node; + struct isis_area *area; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + vty_out(vty, "Area %s:\n", + area->area_tag ? area->area_tag : "null"); + + for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { + if ((area->is_type & level) == 0) + continue; + + vty_out(vty, " Level-%d:\n", level); + vty_out(vty, " SPF delay status: "); + if (area->spf_timer[level - 1]) { + struct timeval remain = thread_timer_remain( + area->spf_timer[level - 1]); + vty_out(vty, "Pending, due in %ld msec\n", + remain.tv_sec * 1000 + + remain.tv_usec / 1000); + } else { + vty_out(vty, "Not scheduled\n"); + } + + if (area->spf_delay_ietf[level - 1]) { + vty_out(vty, + " Using draft-ietf-rtgwg-backoff-algo-04\n"); + spf_backoff_show( + area->spf_delay_ietf[level - 1], vty, + " "); + } else { + vty_out(vty, " Using legacy backoff algo\n"); + } + } + } + return CMD_SUCCESS; } DEFUN (show_isis_summary, @@ -1357,88 +1307,90 @@ DEFUN (show_isis_summary, "show isis summary", SHOW_STR "IS-IS information\n" "IS-IS summary\n") { - struct listnode *node, *node2; - struct isis_area *area; - struct isis_spftree *spftree; - int level; - - if (isis == NULL) - { - vty_out (vty, "ISIS is not running\n"); - return CMD_SUCCESS; - } - - vty_out (vty, "Process Id : %ld\n",isis->process_id); - if (isis->sysid_set) - vty_out (vty, "System Id : %s\n",sysid_print(isis->sysid)); - - vty_out (vty, "Up time : "); - vty_out_timestr(vty, isis->uptime); - vty_out (vty, "\n"); - - if (isis->area_list) - vty_out (vty, "Number of areas : %d\n",isis->area_list->count); - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - vty_out (vty, "Area %s:\n",area->area_tag ? area->area_tag : "null"); - - if (listcount (area->area_addrs) > 0) - { - struct area_addr *area_addr; - for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr)) - { - vty_out (vty, " Net: %s\n", - isonet_print(area_addr->area_addr, area_addr->addr_len + ISIS_SYS_ID_LEN + 1)); - } - } - - for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) - { - if ((area->is_type & level) == 0) - continue; - - vty_out (vty, " Level-%d:\n", level); - spftree = area->spftree[level - 1]; - if (area->spf_timer[level - 1]) - vty_out (vty, " SPF: (pending)\n"); - else - vty_out (vty, " SPF:\n"); - - vty_out (vty, " minimum interval : %d", - area->min_spf_interval[level - 1]); - if (area->spf_delay_ietf[level - 1]) - vty_out (vty, " (not used, IETF SPF delay activated)"); - vty_out (vty, "\n"); - - vty_out (vty, " IPv4 route computation:\n"); - vty_out (vty, " last run elapsed : "); - vty_out_timestr(vty, spftree->last_run_timestamp); - vty_out (vty, "\n"); - - vty_out (vty, " last run duration : %u usec\n", - (u_int32_t)spftree->last_run_duration); - - vty_out (vty, " run count : %d\n", - spftree->runcount); - - spftree = area->spftree6[level - 1]; - vty_out (vty, " IPv6 route computation:\n"); - - vty_out (vty, " last run elapsed : "); - vty_out_timestr(vty, spftree->last_run_timestamp); - vty_out (vty, "\n"); - - vty_out (vty, " last run duration : %llu msec\n", - (unsigned long long)spftree->last_run_duration); - - vty_out (vty, " run count : %d\n", - spftree->runcount); - } - } - vty_out (vty, "\n"); - - return CMD_SUCCESS; + struct listnode *node, *node2; + struct isis_area *area; + struct isis_spftree *spftree; + int level; + + if (isis == NULL) { + vty_out(vty, "ISIS is not running\n"); + return CMD_SUCCESS; + } + + vty_out(vty, "Process Id : %ld\n", isis->process_id); + if (isis->sysid_set) + vty_out(vty, "System Id : %s\n", + sysid_print(isis->sysid)); + + vty_out(vty, "Up time : "); + vty_out_timestr(vty, isis->uptime); + vty_out(vty, "\n"); + + if (isis->area_list) + vty_out(vty, "Number of areas : %d\n", isis->area_list->count); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + vty_out(vty, "Area %s:\n", + area->area_tag ? area->area_tag : "null"); + + if (listcount(area->area_addrs) > 0) { + struct area_addr *area_addr; + for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2, + area_addr)) { + vty_out(vty, " Net: %s\n", + isonet_print(area_addr->area_addr, + area_addr->addr_len + + ISIS_SYS_ID_LEN + + 1)); + } + } + + for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { + if ((area->is_type & level) == 0) + continue; + + vty_out(vty, " Level-%d:\n", level); + spftree = area->spftree[level - 1]; + if (area->spf_timer[level - 1]) + vty_out(vty, " SPF: (pending)\n"); + else + vty_out(vty, " SPF:\n"); + + vty_out(vty, " minimum interval : %d", + area->min_spf_interval[level - 1]); + if (area->spf_delay_ietf[level - 1]) + vty_out(vty, + " (not used, IETF SPF delay activated)"); + vty_out(vty, "\n"); + + vty_out(vty, " IPv4 route computation:\n"); + vty_out(vty, " last run elapsed : "); + vty_out_timestr(vty, spftree->last_run_timestamp); + vty_out(vty, "\n"); + + vty_out(vty, " last run duration : %u usec\n", + (u_int32_t)spftree->last_run_duration); + + vty_out(vty, " run count : %d\n", + spftree->runcount); + + spftree = area->spftree6[level - 1]; + vty_out(vty, " IPv6 route computation:\n"); + + vty_out(vty, " last run elapsed : "); + vty_out_timestr(vty, spftree->last_run_timestamp); + vty_out(vty, "\n"); + + vty_out(vty, " last run duration : %llu msec\n", + (unsigned long long)spftree->last_run_duration); + + vty_out(vty, " run count : %d\n", + spftree->runcount); + } + } + vty_out(vty, "\n"); + + return CMD_SUCCESS; } /* @@ -1457,117 +1409,121 @@ DEFUN (show_isis_summary, * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ] * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ] */ -static int -show_isis_database (struct vty *vty, const char *argv, int ui_level) -{ - struct listnode *node; - struct isis_area *area; - struct isis_lsp *lsp; - struct isis_dynhn *dynhn; - const char *pos = argv; - u_char lspid[ISIS_SYS_ID_LEN+2]; - char sysid[255]; - u_char number[3]; - int level, lsp_count; - - if (isis->area_list->count == 0) - return CMD_SUCCESS; - - memset (&lspid, 0, ISIS_SYS_ID_LEN); - memset (&sysid, 0, 255); - - /* - * extract fragment and pseudo id from the string argv - * in the forms: - * (a) <systemid/hostname>.<pseudo-id>-<framenent> or - * (b) <systemid/hostname>.<pseudo-id> or - * (c) <systemid/hostname> or - * Where systemid is in the form: - * xxxx.xxxx.xxxx - */ - if (argv) - strncpy (sysid, argv, 254); - if (argv && strlen (argv) > 3) - { - pos = argv + strlen (argv) - 3; - if (strncmp (pos, "-", 1) == 0) - { - memcpy (number, ++pos, 2); - lspid[ISIS_SYS_ID_LEN+1] = (u_char) strtol ((char *)number, NULL, 16); - pos -= 4; - if (strncmp (pos, ".", 1) != 0) - return CMD_ERR_AMBIGUOUS; - } - if (strncmp (pos, ".", 1) == 0) - { - memcpy (number, ++pos, 2); - lspid[ISIS_SYS_ID_LEN] = (u_char) strtol ((char *)number, NULL, 16); - sysid[pos - argv - 1] = '\0'; - } - } - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - vty_out (vty, "Area %s:\n",area->area_tag ? area->area_tag : "null"); - - for (level = 0; level < ISIS_LEVELS; level++) - { - if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0) - { - lsp = NULL; - if (argv != NULL) - { - /* - * Try to find the lsp-id if the argv string is in - * the form hostname.<pseudo-id>-<fragment> - */ - if (sysid2buff (lspid, sysid)) - { - lsp = lsp_search (lspid, area->lspdb[level]); - } - else if ((dynhn = dynhn_find_by_name (sysid))) - { - memcpy (lspid, dynhn->id, ISIS_SYS_ID_LEN); - lsp = lsp_search (lspid, area->lspdb[level]); - } - else if (strncmp(unix_hostname (), sysid, 15) == 0) - { - memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN); - lsp = lsp_search (lspid, area->lspdb[level]); - } - } - - if (lsp != NULL || argv == NULL) - { - vty_out (vty, "IS-IS Level-%d link-state database:\n", - level + 1); - - /* print the title in all cases */ - vty_out (vty, - "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n"); - } - - if (lsp) - { - if (ui_level == ISIS_UI_LEVEL_DETAIL) - lsp_print_detail (lsp, vty, area->dynhostname); - else - lsp_print (lsp, vty, area->dynhostname); - } - else if (argv == NULL) - { - lsp_count = lsp_print_all (vty, area->lspdb[level], - ui_level, - area->dynhostname); - - vty_out (vty, " %u LSPs\n\n", - lsp_count); - } - } - } - } - - return CMD_SUCCESS; +static int show_isis_database(struct vty *vty, const char *argv, int ui_level) +{ + struct listnode *node; + struct isis_area *area; + struct isis_lsp *lsp; + struct isis_dynhn *dynhn; + const char *pos = argv; + u_char lspid[ISIS_SYS_ID_LEN + 2]; + char sysid[255]; + u_char number[3]; + int level, lsp_count; + + if (isis->area_list->count == 0) + return CMD_SUCCESS; + + memset(&lspid, 0, ISIS_SYS_ID_LEN); + memset(&sysid, 0, 255); + + /* + * extract fragment and pseudo id from the string argv + * in the forms: + * (a) <systemid/hostname>.<pseudo-id>-<framenent> or + * (b) <systemid/hostname>.<pseudo-id> or + * (c) <systemid/hostname> or + * Where systemid is in the form: + * xxxx.xxxx.xxxx + */ + if (argv) + strncpy(sysid, argv, 254); + if (argv && strlen(argv) > 3) { + pos = argv + strlen(argv) - 3; + if (strncmp(pos, "-", 1) == 0) { + memcpy(number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN + 1] = + (u_char)strtol((char *)number, NULL, 16); + pos -= 4; + if (strncmp(pos, ".", 1) != 0) + return CMD_ERR_AMBIGUOUS; + } + if (strncmp(pos, ".", 1) == 0) { + memcpy(number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN] = + (u_char)strtol((char *)number, NULL, 16); + sysid[pos - argv - 1] = '\0'; + } + } + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + vty_out(vty, "Area %s:\n", + area->area_tag ? area->area_tag : "null"); + + for (level = 0; level < ISIS_LEVELS; level++) { + if (area->lspdb[level] + && dict_count(area->lspdb[level]) > 0) { + lsp = NULL; + if (argv != NULL) { + /* + * Try to find the lsp-id if the argv + * string is in + * the form + * hostname.<pseudo-id>-<fragment> + */ + if (sysid2buff(lspid, sysid)) { + lsp = lsp_search( + lspid, + area->lspdb[level]); + } else if ((dynhn = dynhn_find_by_name( + sysid))) { + memcpy(lspid, dynhn->id, + ISIS_SYS_ID_LEN); + lsp = lsp_search( + lspid, + area->lspdb[level]); + } else if (strncmp(unix_hostname(), + sysid, 15) + == 0) { + memcpy(lspid, isis->sysid, + ISIS_SYS_ID_LEN); + lsp = lsp_search( + lspid, + area->lspdb[level]); + } + } + + if (lsp != NULL || argv == NULL) { + vty_out(vty, + "IS-IS Level-%d link-state database:\n", + level + 1); + + /* print the title in all cases */ + vty_out(vty, + "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n"); + } + + if (lsp) { + if (ui_level == ISIS_UI_LEVEL_DETAIL) + lsp_print_detail( + lsp, vty, + area->dynhostname); + else + lsp_print(lsp, vty, + area->dynhostname); + } else if (argv == NULL) { + lsp_count = lsp_print_all( + vty, area->lspdb[level], + ui_level, area->dynhostname); + + vty_out(vty, " %u LSPs\n\n", + lsp_count); + } + } + } + } + + return CMD_SUCCESS; } DEFUN (show_database, @@ -1579,14 +1535,16 @@ DEFUN (show_database, "Detailed information\n" "LSP ID\n") { - int idx = 0; - int uilevel = argv_find (argv, argc, "detail", &idx) ? ISIS_UI_LEVEL_DETAIL : ISIS_UI_LEVEL_BRIEF; - char *id = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL; - return show_isis_database (vty, id, uilevel); + int idx = 0; + int uilevel = argv_find(argv, argc, "detail", &idx) + ? ISIS_UI_LEVEL_DETAIL + : ISIS_UI_LEVEL_BRIEF; + char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL; + return show_isis_database(vty, id, uilevel); } -/* - * 'router isis' command +/* + * 'router isis' command */ DEFUN_NOSH (router_isis, router_isis_cmd, @@ -1595,20 +1553,20 @@ DEFUN_NOSH (router_isis, "ISO IS-IS\n" "ISO Routing area tag") { - int idx_word = 2; - return isis_area_get (vty, argv[idx_word]->arg); + int idx_word = 2; + return isis_area_get(vty, argv[idx_word]->arg); } -/* - *'no router isis' command +/* + *'no router isis' command */ DEFUN (no_router_isis, no_router_isis_cmd, "no router isis WORD", "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag") { - int idx_word = 3; - return isis_area_destroy (vty, argv[idx_word]->arg); + int idx_word = 3; + return isis_area_destroy(vty, argv[idx_word]->arg); } /* @@ -1620,8 +1578,8 @@ DEFUN (net, "A Network Entity Title for this process (OSI only)\n" "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") { - int idx_word = 1; - return area_net_title (vty, argv[idx_word]->arg); + int idx_word = 1; + return area_net_title(vty, argv[idx_word]->arg); } /* @@ -1634,8 +1592,8 @@ DEFUN (no_net, "A Network Entity Title for this process (OSI only)\n" "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") { - int idx_word = 2; - return area_clear_net_title (vty, argv[idx_word]->arg); + int idx_word = 2; + return area_clear_net_title(vty, argv[idx_word]->arg); } DEFUN (isis_topology, @@ -1645,32 +1603,29 @@ DEFUN (isis_topology, ISIS_MT_DESCRIPTIONS "Set overload bit for topology\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - const char *arg = argv[1]->arg; - uint16_t mtid = isis_str2mtid(arg); + const char *arg = argv[1]->arg; + uint16_t mtid = isis_str2mtid(arg); - if (area->oldmetric) - { - vty_out (vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; - } + if (area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_ERR_AMBIGUOUS; + } - if (mtid == (uint16_t)-1) - { - vty_out (vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; - } - if (mtid == ISIS_MT_IPV4_UNICAST) - { - vty_out (vty, "Cannot configure IPv4 unicast topology\n"); - return CMD_ERR_AMBIGUOUS; - } + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_ERR_AMBIGUOUS; + } + if (mtid == ISIS_MT_IPV4_UNICAST) { + vty_out(vty, "Cannot configure IPv4 unicast topology\n"); + return CMD_ERR_AMBIGUOUS; + } - area_set_mt_enabled(area, mtid, true); - area_set_mt_overload(area, mtid, (argc == 3)); - return CMD_SUCCESS; + area_set_mt_enabled(area, mtid, true); + area_set_mt_overload(area, mtid, (argc == 3)); + return CMD_SUCCESS; } DEFUN (no_isis_topology, @@ -1681,274 +1636,253 @@ DEFUN (no_isis_topology, ISIS_MT_DESCRIPTIONS "Set overload bit for topology\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - const char *arg = argv[2]->arg; - uint16_t mtid = isis_str2mtid(arg); + const char *arg = argv[2]->arg; + uint16_t mtid = isis_str2mtid(arg); - if (area->oldmetric) - { - vty_out (vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; - } + if (area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_ERR_AMBIGUOUS; + } - if (mtid == (uint16_t)-1) - { - vty_out (vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; - } - if (mtid == ISIS_MT_IPV4_UNICAST) - { - vty_out (vty, "Cannot configure IPv4 unicast topology\n"); - return CMD_ERR_AMBIGUOUS; - } + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_ERR_AMBIGUOUS; + } + if (mtid == ISIS_MT_IPV4_UNICAST) { + vty_out(vty, "Cannot configure IPv4 unicast topology\n"); + return CMD_ERR_AMBIGUOUS; + } - area_set_mt_enabled(area, mtid, false); - area_set_mt_overload(area, mtid, false); - return CMD_SUCCESS; + area_set_mt_enabled(area, mtid, false); + area_set_mt_overload(area, mtid, false); + return CMD_SUCCESS; } void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu) { - area->lsp_mtu = lsp_mtu; - lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1); + area->lsp_mtu = lsp_mtu; + lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1); +} + +static int isis_area_passwd_set(struct isis_area *area, int level, + u_char passwd_type, const char *passwd, + u_char snp_auth) +{ + struct isis_passwd *dest; + struct isis_passwd modified; + int len; + + assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); + dest = (level == IS_LEVEL_1) ? &area->area_passwd + : &area->domain_passwd; + memset(&modified, 0, sizeof(modified)); + + if (passwd_type != ISIS_PASSWD_TYPE_UNUSED) { + if (!passwd) + return -1; + + len = strlen(passwd); + if (len > 254) + return -1; + + modified.len = len; + strncpy((char *)modified.passwd, passwd, 255); + modified.type = passwd_type; + modified.snp_auth = snp_auth; + } + + if (memcmp(&modified, dest, sizeof(modified))) { + memcpy(dest, &modified, sizeof(modified)); + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); + } + + return 0; +} + +int isis_area_passwd_unset(struct isis_area *area, int level) +{ + return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_UNUSED, NULL, + 0); +} + +int isis_area_passwd_cleartext_set(struct isis_area *area, int level, + const char *passwd, u_char snp_auth) +{ + return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_CLEARTXT, + passwd, snp_auth); +} + +int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, + const char *passwd, u_char snp_auth) +{ + return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_HMAC_MD5, + passwd, snp_auth); } -static int -isis_area_passwd_set(struct isis_area *area, int level, u_char passwd_type, - const char *passwd, u_char snp_auth) +static void area_resign_level(struct isis_area *area, int level) { - struct isis_passwd *dest; - struct isis_passwd modified; - int len; + if (area->lspdb[level - 1]) { + lsp_db_destroy(area->lspdb[level - 1]); + area->lspdb[level - 1] = NULL; + } + if (area->spftree[level - 1]) { + isis_spftree_del(area->spftree[level - 1]); + area->spftree[level - 1] = NULL; + } + if (area->spftree6[level - 1]) { + isis_spftree_del(area->spftree6[level - 1]); + area->spftree6[level - 1] = NULL; + } + THREAD_TIMER_OFF(area->spf_timer[level - 1]); + if (area->route_table[level - 1]) { + route_table_finish(area->route_table[level - 1]); + area->route_table[level - 1] = NULL; + } + if (area->route_table6[level - 1]) { + route_table_finish(area->route_table6[level - 1]); + area->route_table6[level - 1] = NULL; + } - assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); - dest = (level == IS_LEVEL_1) ? &area->area_passwd : &area->domain_passwd; - memset(&modified, 0, sizeof(modified)); + sched_debug( + "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.", + area->area_tag, level); + THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]); + area->lsp_regenerate_pending[level - 1] = 0; +} - if (passwd_type != ISIS_PASSWD_TYPE_UNUSED) - { - if (!passwd) - return -1; +void isis_area_is_type_set(struct isis_area *area, int is_type) +{ + struct listnode *node; + struct isis_circuit *circuit; - len = strlen(passwd); - if (len > 254) - return -1; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug("ISIS-Evt (%s) system type change %s -> %s", + area->area_tag, circuit_t2string(area->is_type), + circuit_t2string(is_type)); - modified.len = len; - strncpy((char*)modified.passwd, passwd, 255); - modified.type = passwd_type; - modified.snp_auth = snp_auth; - } - - if (memcmp(&modified, dest, sizeof(modified))) - { - memcpy(dest, &modified, sizeof(modified)); - lsp_regenerate_schedule(area, IS_LEVEL_1|IS_LEVEL_2, 1); - } - - return 0; -} - -int -isis_area_passwd_unset (struct isis_area *area, int level) -{ - return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_UNUSED, NULL, 0); -} - -int -isis_area_passwd_cleartext_set (struct isis_area *area, int level, - const char *passwd, u_char snp_auth) -{ - return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_CLEARTXT, - passwd, snp_auth); -} - -int -isis_area_passwd_hmac_md5_set (struct isis_area *area, int level, - const char *passwd, u_char snp_auth) -{ - return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_HMAC_MD5, - passwd, snp_auth); -} - -static void -area_resign_level (struct isis_area *area, int level) -{ - if (area->lspdb[level - 1]) - { - lsp_db_destroy (area->lspdb[level - 1]); - area->lspdb[level - 1] = NULL; - } - if (area->spftree[level - 1]) - { - isis_spftree_del (area->spftree[level - 1]); - area->spftree[level - 1] = NULL; - } - if (area->spftree6[level - 1]) - { - isis_spftree_del (area->spftree6[level - 1]); - area->spftree6[level - 1] = NULL; - } - THREAD_TIMER_OFF(area->spf_timer[level - 1]); - if (area->route_table[level - 1]) - { - route_table_finish (area->route_table[level - 1]); - area->route_table[level - 1] = NULL; - } - if (area->route_table6[level - 1]) - { - route_table_finish (area->route_table6[level - 1]); - area->route_table6[level - 1] = NULL; - } - - sched_debug("ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.", - area->area_tag, level); - THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]); - area->lsp_regenerate_pending[level - 1] = 0; -} - -void -isis_area_is_type_set(struct isis_area *area, int is_type) -{ - struct listnode *node; - struct isis_circuit *circuit; - - if (isis->debugs & DEBUG_EVENTS) - zlog_debug ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag, - circuit_t2string (area->is_type), circuit_t2string (is_type)); - - if (area->is_type == is_type) - return; /* No change */ - - switch (area->is_type) - { - case IS_LEVEL_1: - if (is_type == IS_LEVEL_2) - area_resign_level (area, IS_LEVEL_1); - - if (area->lspdb[1] == NULL) - area->lspdb[1] = lsp_db_init (); - if (area->route_table[1] == NULL) - area->route_table[1] = route_table_init (); - if (area->route_table6[1] == NULL) - area->route_table6[1] = route_table_init (); - break; - - case IS_LEVEL_1_AND_2: - if (is_type == IS_LEVEL_1) - area_resign_level (area, IS_LEVEL_2); - else - area_resign_level (area, IS_LEVEL_1); - break; - - case IS_LEVEL_2: - if (is_type == IS_LEVEL_1) - area_resign_level (area, IS_LEVEL_2); - - if (area->lspdb[0] == NULL) - area->lspdb[0] = lsp_db_init (); - if (area->route_table[0] == NULL) - area->route_table[0] = route_table_init (); - if (area->route_table6[0] == NULL) - area->route_table6[0] = route_table_init (); - break; - - default: - break; - } - - area->is_type = is_type; - - /* override circuit's is_type */ - if (area->is_type != IS_LEVEL_1_AND_2) - { - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) - isis_circuit_is_type_set (circuit, is_type); - } - - spftree_area_init (area); - - if (listcount (area->area_addrs) > 0) - { - if (is_type & IS_LEVEL_1) - lsp_generate (area, IS_LEVEL_1); - if (is_type & IS_LEVEL_2) - lsp_generate (area, IS_LEVEL_2); - } - lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); - - return; + if (area->is_type == is_type) + return; /* No change */ + + switch (area->is_type) { + case IS_LEVEL_1: + if (is_type == IS_LEVEL_2) + area_resign_level(area, IS_LEVEL_1); + + if (area->lspdb[1] == NULL) + area->lspdb[1] = lsp_db_init(); + if (area->route_table[1] == NULL) + area->route_table[1] = route_table_init(); + if (area->route_table6[1] == NULL) + area->route_table6[1] = route_table_init(); + break; + + case IS_LEVEL_1_AND_2: + if (is_type == IS_LEVEL_1) + area_resign_level(area, IS_LEVEL_2); + else + area_resign_level(area, IS_LEVEL_1); + break; + + case IS_LEVEL_2: + if (is_type == IS_LEVEL_1) + area_resign_level(area, IS_LEVEL_2); + + if (area->lspdb[0] == NULL) + area->lspdb[0] = lsp_db_init(); + if (area->route_table[0] == NULL) + area->route_table[0] = route_table_init(); + if (area->route_table6[0] == NULL) + area->route_table6[0] = route_table_init(); + break; + + default: + break; + } + + area->is_type = is_type; + + /* override circuit's is_type */ + if (area->is_type != IS_LEVEL_1_AND_2) { + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) + isis_circuit_is_type_set(circuit, is_type); + } + + spftree_area_init(area); + + if (listcount(area->area_addrs) > 0) { + if (is_type & IS_LEVEL_1) + lsp_generate(area, IS_LEVEL_1); + if (is_type & IS_LEVEL_2) + lsp_generate(area, IS_LEVEL_2); + } + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); + + return; } void isis_area_metricstyle_set(struct isis_area *area, bool old_metric, bool new_metric) { - if (area->oldmetric != old_metric - || area->newmetric != new_metric) - { - area->oldmetric = old_metric; - area->newmetric = new_metric; - lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); - } + if (area->oldmetric != old_metric || area->newmetric != new_metric) { + area->oldmetric = old_metric; + area->newmetric = new_metric; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); + } } void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit) { - char new_overload_bit = overload_bit ? LSPBIT_OL : 0; + char new_overload_bit = overload_bit ? LSPBIT_OL : 0; - if (new_overload_bit != area->overload_bit) - { - area->overload_bit = new_overload_bit; - lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); - } + if (new_overload_bit != area->overload_bit) { + area->overload_bit = new_overload_bit; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); + } } void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit) { - char new_attached_bit = attached_bit ? LSPBIT_ATT : 0; + char new_attached_bit = attached_bit ? LSPBIT_ATT : 0; - if (new_attached_bit != area->attached_bit) - { - area->attached_bit = new_attached_bit; - lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); - } + if (new_attached_bit != area->attached_bit) { + area->attached_bit = new_attached_bit; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); + } } void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname) { - if (area->dynhostname != dynhostname) - { - area->dynhostname = dynhostname; - lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0); - } + if (area->dynhostname != dynhostname) { + area->dynhostname = dynhostname; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0); + } } -void -isis_area_max_lsp_lifetime_set(struct isis_area *area, int level, - uint16_t max_lsp_lifetime) +void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level, + uint16_t max_lsp_lifetime) { - assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); + assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); - if (area->max_lsp_lifetime[level-1] == max_lsp_lifetime) - return; + if (area->max_lsp_lifetime[level - 1] == max_lsp_lifetime) + return; - area->max_lsp_lifetime[level-1] = max_lsp_lifetime; - lsp_regenerate_schedule(area, level, 1); + area->max_lsp_lifetime[level - 1] = max_lsp_lifetime; + lsp_regenerate_schedule(area, level, 1); } -void -isis_area_lsp_refresh_set(struct isis_area *area, int level, - uint16_t lsp_refresh) +void isis_area_lsp_refresh_set(struct isis_area *area, int level, + uint16_t lsp_refresh) { - assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); + assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2)); - if (area->lsp_refresh[level-1] == lsp_refresh) - return; + if (area->lsp_refresh[level - 1] == lsp_refresh) + return; - area->lsp_refresh[level-1] = lsp_refresh; - lsp_regenerate_schedule(area, level, 1); + area->lsp_refresh[level - 1] = lsp_refresh; + lsp_regenerate_schedule(area, level, 1); } DEFUN (log_adj_changes, @@ -1956,11 +1890,11 @@ DEFUN (log_adj_changes, "log-adjacency-changes", "Log changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - area->log_adj_changes = 1; + area->log_adj_changes = 1; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_log_adj_changes, @@ -1969,377 +1903,377 @@ DEFUN (no_log_adj_changes, NO_STR "Stop logging changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT (isis_area, area); + VTY_DECLVAR_CONTEXT(isis_area, area); - area->log_adj_changes = 0; + area->log_adj_changes = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } /* IS-IS configuration write function */ -int -isis_config_write (struct vty *vty) -{ - int write = 0; - - if (isis != NULL) - { - struct isis_area *area; - struct listnode *node, *node2; - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - /* ISIS - Area name */ - vty_out (vty, "router isis %s\n", area->area_tag); - write++; - /* ISIS - Net */ - if (listcount (area->area_addrs) > 0) - { - struct area_addr *area_addr; - for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr)) - { - vty_out (vty, " net %s\n", - isonet_print(area_addr->area_addr, area_addr->addr_len + ISIS_SYS_ID_LEN + 1)); - write++; - } - } - /* ISIS - Dynamic hostname - Defaults to true so only display if - * false. */ - if (!area->dynhostname) - { - vty_out (vty, " no hostname dynamic\n"); - write++; - } - /* ISIS - Metric-Style - when true displays wide */ - if (area->newmetric) - { - if (!area->oldmetric) - vty_out (vty, " metric-style wide\n"); - else - vty_out (vty, " metric-style transition\n"); - write++; - } - else - { - vty_out (vty, " metric-style narrow\n"); - write++; - } - /* ISIS - overload-bit */ - if (area->overload_bit) - { - vty_out (vty, " set-overload-bit\n"); - write++; - } - /* ISIS - Area is-type (level-1-2 is default) */ - if (area->is_type == IS_LEVEL_1) - { - vty_out (vty, " is-type level-1\n"); - write++; - } - else if (area->is_type == IS_LEVEL_2) - { - vty_out (vty, " is-type level-2-only\n"); - write++; - } - write += isis_redist_config_write(vty, area, AF_INET); - write += isis_redist_config_write(vty, area, AF_INET6); - /* ISIS - Lsp generation interval */ - if (area->lsp_gen_interval[0] == area->lsp_gen_interval[1]) - { - if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-gen-interval %d\n", - area->lsp_gen_interval[0]); - write++; - } - } - else - { - if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-gen-interval level-1 %d\n", - area->lsp_gen_interval[0]); - write++; - } - if (area->lsp_gen_interval[1] != DEFAULT_MIN_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-gen-interval level-2 %d\n", - area->lsp_gen_interval[1]); - write++; - } - } - /* ISIS - LSP lifetime */ - if (area->max_lsp_lifetime[0] == area->max_lsp_lifetime[1]) - { - if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME) - { - vty_out (vty, " max-lsp-lifetime %u\n", - area->max_lsp_lifetime[0]); - write++; - } - } - else - { - if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME) - { - vty_out (vty, " max-lsp-lifetime level-1 %u\n", - area->max_lsp_lifetime[0]); - write++; - } - if (area->max_lsp_lifetime[1] != DEFAULT_LSP_LIFETIME) - { - vty_out (vty, " max-lsp-lifetime level-2 %u\n", - area->max_lsp_lifetime[1]); - write++; - } - } - /* ISIS - LSP refresh interval */ - if (area->lsp_refresh[0] == area->lsp_refresh[1]) - { - if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-refresh-interval %u\n", - area->lsp_refresh[0]); - write++; - } - } - else - { - if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-refresh-interval level-1 %u\n", - area->lsp_refresh[0]); - write++; - } - if (area->lsp_refresh[1] != DEFAULT_MAX_LSP_GEN_INTERVAL) - { - vty_out (vty, " lsp-refresh-interval level-2 %u\n", - area->lsp_refresh[1]); - write++; - } - } - if (area->lsp_mtu != DEFAULT_LSP_MTU) - { - vty_out (vty, " lsp-mtu %u\n", area->lsp_mtu); - write++; - } - - /* Minimum SPF interval. */ - if (area->min_spf_interval[0] == area->min_spf_interval[1]) - { - if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL) - { - vty_out (vty, " spf-interval %d\n", - area->min_spf_interval[0]); - write++; - } - } - else - { - if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL) - { - vty_out (vty, " spf-interval level-1 %d\n", - area->min_spf_interval[0]); - write++; - } - if (area->min_spf_interval[1] != MINIMUM_SPF_INTERVAL) - { - vty_out (vty, " spf-interval level-2 %d\n", - area->min_spf_interval[1]); - write++; - } - } - - /* IETF SPF interval */ - if (area->spf_delay_ietf[0]) - { - vty_out (vty, " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n", - spf_backoff_init_delay(area->spf_delay_ietf[0]), - spf_backoff_short_delay(area->spf_delay_ietf[0]), - spf_backoff_long_delay(area->spf_delay_ietf[0]), - spf_backoff_holddown(area->spf_delay_ietf[0]), - spf_backoff_timetolearn(area->spf_delay_ietf[0])); - write++; - } - - /* Authentication passwords. */ - if (area->area_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - vty_out(vty, " area-password md5 %s", area->area_passwd.passwd); - if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND)) - { - vty_out(vty, " authenticate snp "); - if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV)) - vty_out(vty, "validate"); - else - vty_out(vty, "send-only"); - } - vty_out (vty, "\n"); - write++; - } - else if (area->area_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) - { - vty_out(vty, " area-password clear %s", area->area_passwd.passwd); - if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND)) - { - vty_out(vty, " authenticate snp "); - if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV)) - vty_out(vty, "validate"); - else - vty_out(vty, "send-only"); - } - vty_out (vty, "\n"); - write++; - } - if (area->domain_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) - { - vty_out(vty, " domain-password md5 %s", - area->domain_passwd.passwd); - if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND)) - { - vty_out(vty, " authenticate snp "); - if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV)) - vty_out(vty, "validate"); - else - vty_out(vty, "send-only"); - } - vty_out (vty, "\n"); - write++; - } - else if (area->domain_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) - { - vty_out(vty, " domain-password clear %s", - area->domain_passwd.passwd); - if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND)) - { - vty_out(vty, " authenticate snp "); - if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV)) - vty_out(vty, "validate"); - else - vty_out(vty, "send-only"); - } - vty_out (vty, "\n"); - write++; - } - - if (area->log_adj_changes) - { - vty_out (vty, " log-adjacency-changes\n"); - write++; - } - - write += area_write_mt_settings(area, vty); - } - isis_mpls_te_config_write_router(vty); - } - - return write; -} - -struct cmd_node isis_node = { - ISIS_NODE, - "%s(config-router)# ", - 1 -}; - -void -isis_init () -{ - /* Install IS-IS top node */ - install_node (&isis_node, isis_config_write); - - install_element (VIEW_NODE, &show_isis_summary_cmd); - - install_element (VIEW_NODE, &show_isis_spf_ietf_cmd); - - install_element (VIEW_NODE, &show_isis_interface_cmd); - install_element (VIEW_NODE, &show_isis_interface_detail_cmd); - install_element (VIEW_NODE, &show_isis_interface_arg_cmd); - - install_element (VIEW_NODE, &show_isis_neighbor_cmd); - install_element (VIEW_NODE, &show_isis_neighbor_detail_cmd); - install_element (VIEW_NODE, &show_isis_neighbor_arg_cmd); - install_element (VIEW_NODE, &clear_isis_neighbor_cmd); - install_element (VIEW_NODE, &clear_isis_neighbor_arg_cmd); - - install_element (VIEW_NODE, &show_hostname_cmd); - install_element (VIEW_NODE, &show_database_cmd); - - install_element (ENABLE_NODE, &show_debugging_isis_cmd); - - install_node (&debug_node, config_write_debug); - - install_element (ENABLE_NODE, &debug_isis_adj_cmd); - install_element (ENABLE_NODE, &no_debug_isis_adj_cmd); - install_element (ENABLE_NODE, &debug_isis_csum_cmd); - install_element (ENABLE_NODE, &no_debug_isis_csum_cmd); - install_element (ENABLE_NODE, &debug_isis_lupd_cmd); - install_element (ENABLE_NODE, &no_debug_isis_lupd_cmd); - install_element (ENABLE_NODE, &debug_isis_err_cmd); - install_element (ENABLE_NODE, &no_debug_isis_err_cmd); - install_element (ENABLE_NODE, &debug_isis_snp_cmd); - install_element (ENABLE_NODE, &no_debug_isis_snp_cmd); - install_element (ENABLE_NODE, &debug_isis_upd_cmd); - install_element (ENABLE_NODE, &no_debug_isis_upd_cmd); - install_element (ENABLE_NODE, &debug_isis_spfevents_cmd); - install_element (ENABLE_NODE, &no_debug_isis_spfevents_cmd); - install_element (ENABLE_NODE, &debug_isis_spfstats_cmd); - install_element (ENABLE_NODE, &no_debug_isis_spfstats_cmd); - install_element (ENABLE_NODE, &debug_isis_spftrigg_cmd); - install_element (ENABLE_NODE, &no_debug_isis_spftrigg_cmd); - install_element (ENABLE_NODE, &debug_isis_rtevents_cmd); - install_element (ENABLE_NODE, &no_debug_isis_rtevents_cmd); - install_element (ENABLE_NODE, &debug_isis_events_cmd); - install_element (ENABLE_NODE, &no_debug_isis_events_cmd); - install_element (ENABLE_NODE, &debug_isis_packet_dump_cmd); - install_element (ENABLE_NODE, &no_debug_isis_packet_dump_cmd); - install_element (ENABLE_NODE, &debug_isis_lsp_gen_cmd); - install_element (ENABLE_NODE, &no_debug_isis_lsp_gen_cmd); - install_element (ENABLE_NODE, &debug_isis_lsp_sched_cmd); - install_element (ENABLE_NODE, &no_debug_isis_lsp_sched_cmd); - - install_element (CONFIG_NODE, &debug_isis_adj_cmd); - install_element (CONFIG_NODE, &no_debug_isis_adj_cmd); - install_element (CONFIG_NODE, &debug_isis_csum_cmd); - install_element (CONFIG_NODE, &no_debug_isis_csum_cmd); - install_element (CONFIG_NODE, &debug_isis_lupd_cmd); - install_element (CONFIG_NODE, &no_debug_isis_lupd_cmd); - install_element (CONFIG_NODE, &debug_isis_err_cmd); - install_element (CONFIG_NODE, &no_debug_isis_err_cmd); - install_element (CONFIG_NODE, &debug_isis_snp_cmd); - install_element (CONFIG_NODE, &no_debug_isis_snp_cmd); - install_element (CONFIG_NODE, &debug_isis_upd_cmd); - install_element (CONFIG_NODE, &no_debug_isis_upd_cmd); - install_element (CONFIG_NODE, &debug_isis_spfevents_cmd); - install_element (CONFIG_NODE, &no_debug_isis_spfevents_cmd); - install_element (CONFIG_NODE, &debug_isis_spfstats_cmd); - install_element (CONFIG_NODE, &no_debug_isis_spfstats_cmd); - install_element (CONFIG_NODE, &debug_isis_spftrigg_cmd); - install_element (CONFIG_NODE, &no_debug_isis_spftrigg_cmd); - install_element (CONFIG_NODE, &debug_isis_rtevents_cmd); - install_element (CONFIG_NODE, &no_debug_isis_rtevents_cmd); - install_element (CONFIG_NODE, &debug_isis_events_cmd); - install_element (CONFIG_NODE, &no_debug_isis_events_cmd); - install_element (CONFIG_NODE, &debug_isis_packet_dump_cmd); - install_element (CONFIG_NODE, &no_debug_isis_packet_dump_cmd); - install_element (CONFIG_NODE, &debug_isis_lsp_gen_cmd); - install_element (CONFIG_NODE, &no_debug_isis_lsp_gen_cmd); - install_element (CONFIG_NODE, &debug_isis_lsp_sched_cmd); - install_element (CONFIG_NODE, &no_debug_isis_lsp_sched_cmd); - - install_element (CONFIG_NODE, &router_isis_cmd); - install_element (CONFIG_NODE, &no_router_isis_cmd); - - install_default (ISIS_NODE); - - install_element (ISIS_NODE, &net_cmd); - install_element (ISIS_NODE, &no_net_cmd); - - install_element (ISIS_NODE, &isis_topology_cmd); - install_element (ISIS_NODE, &no_isis_topology_cmd); - - install_element (ISIS_NODE, &log_adj_changes_cmd); - install_element (ISIS_NODE, &no_log_adj_changes_cmd); - - spf_backoff_cmd_init(); +int isis_config_write(struct vty *vty) +{ + int write = 0; + + if (isis != NULL) { + struct isis_area *area; + struct listnode *node, *node2; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + /* ISIS - Area name */ + vty_out(vty, "router isis %s\n", area->area_tag); + write++; + /* ISIS - Net */ + if (listcount(area->area_addrs) > 0) { + struct area_addr *area_addr; + for (ALL_LIST_ELEMENTS_RO(area->area_addrs, + node2, area_addr)) { + vty_out(vty, " net %s\n", + isonet_print( + area_addr->area_addr, + area_addr->addr_len + + ISIS_SYS_ID_LEN + + 1)); + write++; + } + } + /* ISIS - Dynamic hostname - Defaults to true so only + * display if + * false. */ + if (!area->dynhostname) { + vty_out(vty, " no hostname dynamic\n"); + write++; + } + /* ISIS - Metric-Style - when true displays wide */ + if (area->newmetric) { + if (!area->oldmetric) + vty_out(vty, " metric-style wide\n"); + else + vty_out(vty, + " metric-style transition\n"); + write++; + } else { + vty_out(vty, " metric-style narrow\n"); + write++; + } + /* ISIS - overload-bit */ + if (area->overload_bit) { + vty_out(vty, " set-overload-bit\n"); + write++; + } + /* ISIS - Area is-type (level-1-2 is default) */ + if (area->is_type == IS_LEVEL_1) { + vty_out(vty, " is-type level-1\n"); + write++; + } else if (area->is_type == IS_LEVEL_2) { + vty_out(vty, " is-type level-2-only\n"); + write++; + } + write += isis_redist_config_write(vty, area, AF_INET); + write += isis_redist_config_write(vty, area, AF_INET6); + /* ISIS - Lsp generation interval */ + if (area->lsp_gen_interval[0] + == area->lsp_gen_interval[1]) { + if (area->lsp_gen_interval[0] + != DEFAULT_MIN_LSP_GEN_INTERVAL) { + vty_out(vty, " lsp-gen-interval %d\n", + area->lsp_gen_interval[0]); + write++; + } + } else { + if (area->lsp_gen_interval[0] + != DEFAULT_MIN_LSP_GEN_INTERVAL) { + vty_out(vty, + " lsp-gen-interval level-1 %d\n", + area->lsp_gen_interval[0]); + write++; + } + if (area->lsp_gen_interval[1] + != DEFAULT_MIN_LSP_GEN_INTERVAL) { + vty_out(vty, + " lsp-gen-interval level-2 %d\n", + area->lsp_gen_interval[1]); + write++; + } + } + /* ISIS - LSP lifetime */ + if (area->max_lsp_lifetime[0] + == area->max_lsp_lifetime[1]) { + if (area->max_lsp_lifetime[0] + != DEFAULT_LSP_LIFETIME) { + vty_out(vty, " max-lsp-lifetime %u\n", + area->max_lsp_lifetime[0]); + write++; + } + } else { + if (area->max_lsp_lifetime[0] + != DEFAULT_LSP_LIFETIME) { + vty_out(vty, + " max-lsp-lifetime level-1 %u\n", + area->max_lsp_lifetime[0]); + write++; + } + if (area->max_lsp_lifetime[1] + != DEFAULT_LSP_LIFETIME) { + vty_out(vty, + " max-lsp-lifetime level-2 %u\n", + area->max_lsp_lifetime[1]); + write++; + } + } + /* ISIS - LSP refresh interval */ + if (area->lsp_refresh[0] == area->lsp_refresh[1]) { + if (area->lsp_refresh[0] + != DEFAULT_MAX_LSP_GEN_INTERVAL) { + vty_out(vty, + " lsp-refresh-interval %u\n", + area->lsp_refresh[0]); + write++; + } + } else { + if (area->lsp_refresh[0] + != DEFAULT_MAX_LSP_GEN_INTERVAL) { + vty_out(vty, + " lsp-refresh-interval level-1 %u\n", + area->lsp_refresh[0]); + write++; + } + if (area->lsp_refresh[1] + != DEFAULT_MAX_LSP_GEN_INTERVAL) { + vty_out(vty, + " lsp-refresh-interval level-2 %u\n", + area->lsp_refresh[1]); + write++; + } + } + if (area->lsp_mtu != DEFAULT_LSP_MTU) { + vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu); + write++; + } + + /* Minimum SPF interval. */ + if (area->min_spf_interval[0] + == area->min_spf_interval[1]) { + if (area->min_spf_interval[0] + != MINIMUM_SPF_INTERVAL) { + vty_out(vty, " spf-interval %d\n", + area->min_spf_interval[0]); + write++; + } + } else { + if (area->min_spf_interval[0] + != MINIMUM_SPF_INTERVAL) { + vty_out(vty, + " spf-interval level-1 %d\n", + area->min_spf_interval[0]); + write++; + } + if (area->min_spf_interval[1] + != MINIMUM_SPF_INTERVAL) { + vty_out(vty, + " spf-interval level-2 %d\n", + area->min_spf_interval[1]); + write++; + } + } + + /* IETF SPF interval */ + if (area->spf_delay_ietf[0]) { + vty_out(vty, + " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n", + spf_backoff_init_delay( + area->spf_delay_ietf[0]), + spf_backoff_short_delay( + area->spf_delay_ietf[0]), + spf_backoff_long_delay( + area->spf_delay_ietf[0]), + spf_backoff_holddown( + area->spf_delay_ietf[0]), + spf_backoff_timetolearn( + area->spf_delay_ietf[0])); + write++; + } + + /* Authentication passwords. */ + if (area->area_passwd.type + == ISIS_PASSWD_TYPE_HMAC_MD5) { + vty_out(vty, " area-password md5 %s", + area->area_passwd.passwd); + if (CHECK_FLAG(area->area_passwd.snp_auth, + SNP_AUTH_SEND)) { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG( + area->area_passwd.snp_auth, + SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "\n"); + write++; + } else if (area->area_passwd.type + == ISIS_PASSWD_TYPE_CLEARTXT) { + vty_out(vty, " area-password clear %s", + area->area_passwd.passwd); + if (CHECK_FLAG(area->area_passwd.snp_auth, + SNP_AUTH_SEND)) { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG( + area->area_passwd.snp_auth, + SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "\n"); + write++; + } + if (area->domain_passwd.type + == ISIS_PASSWD_TYPE_HMAC_MD5) { + vty_out(vty, " domain-password md5 %s", + area->domain_passwd.passwd); + if (CHECK_FLAG(area->domain_passwd.snp_auth, + SNP_AUTH_SEND)) { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG(area->domain_passwd + .snp_auth, + SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "\n"); + write++; + } else if (area->domain_passwd.type + == ISIS_PASSWD_TYPE_CLEARTXT) { + vty_out(vty, " domain-password clear %s", + area->domain_passwd.passwd); + if (CHECK_FLAG(area->domain_passwd.snp_auth, + SNP_AUTH_SEND)) { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG(area->domain_passwd + .snp_auth, + SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "\n"); + write++; + } + + if (area->log_adj_changes) { + vty_out(vty, " log-adjacency-changes\n"); + write++; + } + + write += area_write_mt_settings(area, vty); + } + isis_mpls_te_config_write_router(vty); + } + + return write; +} + +struct cmd_node isis_node = {ISIS_NODE, "%s(config-router)# ", 1}; + +void isis_init() +{ + /* Install IS-IS top node */ + install_node(&isis_node, isis_config_write); + + install_element(VIEW_NODE, &show_isis_summary_cmd); + + install_element(VIEW_NODE, &show_isis_spf_ietf_cmd); + + install_element(VIEW_NODE, &show_isis_interface_cmd); + install_element(VIEW_NODE, &show_isis_interface_detail_cmd); + install_element(VIEW_NODE, &show_isis_interface_arg_cmd); + + install_element(VIEW_NODE, &show_isis_neighbor_cmd); + install_element(VIEW_NODE, &show_isis_neighbor_detail_cmd); + install_element(VIEW_NODE, &show_isis_neighbor_arg_cmd); + install_element(VIEW_NODE, &clear_isis_neighbor_cmd); + install_element(VIEW_NODE, &clear_isis_neighbor_arg_cmd); + + install_element(VIEW_NODE, &show_hostname_cmd); + install_element(VIEW_NODE, &show_database_cmd); + + install_element(ENABLE_NODE, &show_debugging_isis_cmd); + + install_node(&debug_node, config_write_debug); + + install_element(ENABLE_NODE, &debug_isis_adj_cmd); + install_element(ENABLE_NODE, &no_debug_isis_adj_cmd); + install_element(ENABLE_NODE, &debug_isis_csum_cmd); + install_element(ENABLE_NODE, &no_debug_isis_csum_cmd); + install_element(ENABLE_NODE, &debug_isis_lupd_cmd); + install_element(ENABLE_NODE, &no_debug_isis_lupd_cmd); + install_element(ENABLE_NODE, &debug_isis_err_cmd); + install_element(ENABLE_NODE, &no_debug_isis_err_cmd); + install_element(ENABLE_NODE, &debug_isis_snp_cmd); + install_element(ENABLE_NODE, &no_debug_isis_snp_cmd); + install_element(ENABLE_NODE, &debug_isis_upd_cmd); + install_element(ENABLE_NODE, &no_debug_isis_upd_cmd); + install_element(ENABLE_NODE, &debug_isis_spfevents_cmd); + install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd); + install_element(ENABLE_NODE, &debug_isis_spfstats_cmd); + install_element(ENABLE_NODE, &no_debug_isis_spfstats_cmd); + install_element(ENABLE_NODE, &debug_isis_spftrigg_cmd); + install_element(ENABLE_NODE, &no_debug_isis_spftrigg_cmd); + install_element(ENABLE_NODE, &debug_isis_rtevents_cmd); + install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd); + install_element(ENABLE_NODE, &debug_isis_events_cmd); + install_element(ENABLE_NODE, &no_debug_isis_events_cmd); + install_element(ENABLE_NODE, &debug_isis_packet_dump_cmd); + install_element(ENABLE_NODE, &no_debug_isis_packet_dump_cmd); + install_element(ENABLE_NODE, &debug_isis_lsp_gen_cmd); + install_element(ENABLE_NODE, &no_debug_isis_lsp_gen_cmd); + install_element(ENABLE_NODE, &debug_isis_lsp_sched_cmd); + install_element(ENABLE_NODE, &no_debug_isis_lsp_sched_cmd); + + install_element(CONFIG_NODE, &debug_isis_adj_cmd); + install_element(CONFIG_NODE, &no_debug_isis_adj_cmd); + install_element(CONFIG_NODE, &debug_isis_csum_cmd); + install_element(CONFIG_NODE, &no_debug_isis_csum_cmd); + install_element(CONFIG_NODE, &debug_isis_lupd_cmd); + install_element(CONFIG_NODE, &no_debug_isis_lupd_cmd); + install_element(CONFIG_NODE, &debug_isis_err_cmd); + install_element(CONFIG_NODE, &no_debug_isis_err_cmd); + install_element(CONFIG_NODE, &debug_isis_snp_cmd); + install_element(CONFIG_NODE, &no_debug_isis_snp_cmd); + install_element(CONFIG_NODE, &debug_isis_upd_cmd); + install_element(CONFIG_NODE, &no_debug_isis_upd_cmd); + install_element(CONFIG_NODE, &debug_isis_spfevents_cmd); + install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd); + install_element(CONFIG_NODE, &debug_isis_spfstats_cmd); + install_element(CONFIG_NODE, &no_debug_isis_spfstats_cmd); + install_element(CONFIG_NODE, &debug_isis_spftrigg_cmd); + install_element(CONFIG_NODE, &no_debug_isis_spftrigg_cmd); + install_element(CONFIG_NODE, &debug_isis_rtevents_cmd); + install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd); + install_element(CONFIG_NODE, &debug_isis_events_cmd); + install_element(CONFIG_NODE, &no_debug_isis_events_cmd); + install_element(CONFIG_NODE, &debug_isis_packet_dump_cmd); + install_element(CONFIG_NODE, &no_debug_isis_packet_dump_cmd); + install_element(CONFIG_NODE, &debug_isis_lsp_gen_cmd); + install_element(CONFIG_NODE, &no_debug_isis_lsp_gen_cmd); + install_element(CONFIG_NODE, &debug_isis_lsp_sched_cmd); + install_element(CONFIG_NODE, &no_debug_isis_lsp_sched_cmd); + + install_element(CONFIG_NODE, &router_isis_cmd); + install_element(CONFIG_NODE, &no_router_isis_cmd); + + install_default(ISIS_NODE); + + install_element(ISIS_NODE, &net_cmd); + install_element(ISIS_NODE, &no_net_cmd); + + install_element(ISIS_NODE, &isis_topology_cmd); + install_element(ISIS_NODE, &no_isis_topology_cmd); + + install_element(ISIS_NODE, &log_adj_changes_cmd); + install_element(ISIS_NODE, &no_log_adj_changes_cmd); + + spf_backoff_cmd_init(); } diff --git a/isisd/isisd.h b/isisd/isisd.h index 9b6281866..1aacea881 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -1,18 +1,18 @@ /* - * IS-IS Rout(e)ing protocol - isisd.h + * IS-IS Rout(e)ing protocol - isisd.h * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -39,108 +39,110 @@ /* #define EXTREME_DEBUG */ /* #define EXTREME_TLV_DEBUG */ -struct isis -{ - u_long process_id; - int sysid_set; - u_char sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */ - u_int32_t router_id; /* Router ID from zebra */ - struct list *area_list; /* list of IS-IS areas */ - struct list *init_circ_list; - struct list *nexthops; /* IPv4 next hops from this IS */ - struct list *nexthops6; /* IPv6 next hops from this IS */ - u_char max_area_addrs; /* maximumAreaAdresses */ - struct area_addr *man_area_addrs; /* manualAreaAddresses */ - u_int32_t debugs; /* bitmap for debug */ - time_t uptime; /* when did we start */ - struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */ - - struct route_table *ext_info[REDIST_PROTOCOL_COUNT]; - - QOBJ_FIELDS +struct isis { + u_long process_id; + int sysid_set; + u_char sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */ + u_int32_t router_id; /* Router ID from zebra */ + struct list *area_list; /* list of IS-IS areas */ + struct list *init_circ_list; + struct list *nexthops; /* IPv4 next hops from this IS */ + struct list *nexthops6; /* IPv6 next hops from this IS */ + u_char max_area_addrs; /* maximumAreaAdresses */ + struct area_addr *man_area_addrs; /* manualAreaAddresses */ + u_int32_t debugs; /* bitmap for debug */ + time_t uptime; /* when did we start */ + struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */ + + struct route_table *ext_info[REDIST_PROTOCOL_COUNT]; + + QOBJ_FIELDS }; extern struct isis *isis; DECLARE_QOBJ_TYPE(isis_area) -struct isis_area -{ - struct isis *isis; /* back pointer */ - dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */ - struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */ - struct route_table *route_table[ISIS_LEVELS]; /* IPv4 routes */ - struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */ - struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */ +struct isis_area { + struct isis *isis; /* back pointer */ + dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */ + struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */ + struct route_table *route_table[ISIS_LEVELS]; /* IPv4 routes */ + struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */ + struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */ + /* $FRR indent$ */ +/* clang-format off */ #define DEFAULT_LSP_MTU 1497 - unsigned int lsp_mtu; /* Size of LSPs to generate */ - struct list *circuit_list; /* IS-IS circuits */ - struct flags flags; - struct thread *t_tick; /* LSP walker */ - struct thread *t_lsp_refresh[ISIS_LEVELS]; - /* t_lsp_refresh is used in two ways: - * a) regular refresh of LSPs - * b) (possibly throttled) updates to LSPs - * - * The lsp_regenerate_pending flag tracks whether the timer is active - * for the a) or the b) case. - * - * It is of utmost importance to clear this flag when the timer is - * rescheduled for normal refresh, because otherwise, updates will - * be delayed until the next regular refresh. - */ - int lsp_regenerate_pending[ISIS_LEVELS]; - - /* - * Configurables - */ - struct isis_passwd area_passwd; - struct isis_passwd domain_passwd; - /* do we support dynamic hostnames? */ - char dynhostname; - /* do we support new style metrics? */ - char newmetric; - char oldmetric; - /* identifies the routing instance */ - char *area_tag; - /* area addresses for this area */ - struct list *area_addrs; - u_int16_t max_lsp_lifetime[ISIS_LEVELS]; - char is_type; /* level-1 level-1-2 or level-2-only */ - /* are we overloaded? */ - char overload_bit; - /* L1/L2 router identifier for inter-area traffic */ - char attached_bit; - u_int16_t lsp_refresh[ISIS_LEVELS]; - /* minimum time allowed before lsp retransmission */ - u_int16_t lsp_gen_interval[ISIS_LEVELS]; - /* min interval between between consequtive SPFs */ - u_int16_t min_spf_interval[ISIS_LEVELS]; - /* the percentage of LSP mtu size used, before generating a new frag */ - int lsp_frag_threshold; - int ip_circuits; - /* logging adjacency changes? */ - u_char log_adj_changes; - /* multi topology settings */ - struct list *mt_settings; - int ipv6_circuits; - /* Counters */ - u_int32_t circuit_state_changes; - struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT] - [ZEBRA_ROUTE_MAX + 1][ISIS_LEVELS]; - struct route_table *ext_reach[REDIST_PROTOCOL_COUNT][ISIS_LEVELS]; - - struct spf_backoff *spf_delay_ietf[ISIS_LEVELS]; /*Structure with IETF SPF algo parameters*/ - struct thread *spf_timer[ISIS_LEVELS]; - - QOBJ_FIELDS + unsigned int lsp_mtu; /* Size of LSPs to generate */ + struct list *circuit_list; /* IS-IS circuits */ + struct flags flags; + struct thread *t_tick; /* LSP walker */ + struct thread *t_lsp_refresh[ISIS_LEVELS]; + /* t_lsp_refresh is used in two ways: + * a) regular refresh of LSPs + * b) (possibly throttled) updates to LSPs + * + * The lsp_regenerate_pending flag tracks whether the timer is active + * for the a) or the b) case. + * + * It is of utmost importance to clear this flag when the timer is + * rescheduled for normal refresh, because otherwise, updates will + * be delayed until the next regular refresh. + */ + int lsp_regenerate_pending[ISIS_LEVELS]; + + /* + * Configurables + */ + struct isis_passwd area_passwd; + struct isis_passwd domain_passwd; + /* do we support dynamic hostnames? */ + char dynhostname; + /* do we support new style metrics? */ + char newmetric; + char oldmetric; + /* identifies the routing instance */ + char *area_tag; + /* area addresses for this area */ + struct list *area_addrs; + u_int16_t max_lsp_lifetime[ISIS_LEVELS]; + char is_type; /* level-1 level-1-2 or level-2-only */ + /* are we overloaded? */ + char overload_bit; + /* L1/L2 router identifier for inter-area traffic */ + char attached_bit; + u_int16_t lsp_refresh[ISIS_LEVELS]; + /* minimum time allowed before lsp retransmission */ + u_int16_t lsp_gen_interval[ISIS_LEVELS]; + /* min interval between between consequtive SPFs */ + u_int16_t min_spf_interval[ISIS_LEVELS]; + /* the percentage of LSP mtu size used, before generating a new frag */ + int lsp_frag_threshold; + int ip_circuits; + /* logging adjacency changes? */ + u_char log_adj_changes; + /* multi topology settings */ + struct list *mt_settings; + int ipv6_circuits; + /* Counters */ + u_int32_t circuit_state_changes; + struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT] + [ZEBRA_ROUTE_MAX + 1][ISIS_LEVELS]; + struct route_table *ext_reach[REDIST_PROTOCOL_COUNT][ISIS_LEVELS]; + + struct spf_backoff *spf_delay_ietf[ISIS_LEVELS]; /*Structure with IETF + SPF algo + parameters*/ + struct thread *spf_timer[ISIS_LEVELS]; + + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(isis_area) -void isis_init (void); +void isis_init(void); void isis_new(unsigned long); struct isis_area *isis_area_create(const char *); -struct isis_area *isis_area_lookup (const char *); -int isis_area_get (struct vty *vty, const char *area_tag); +struct isis_area *isis_area_lookup(const char *); +int isis_area_get(struct vty *vty, const char *area_tag); void print_debug(struct vty *, int, int); void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit); @@ -151,16 +153,16 @@ void isis_area_metricstyle_set(struct isis_area *area, bool old_metric, void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu); void isis_area_is_type_set(struct isis_area *area, int is_type); void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level, - uint16_t max_lsp_lifetime); + uint16_t max_lsp_lifetime); void isis_area_lsp_refresh_set(struct isis_area *area, int level, uint16_t lsp_refresh); /* IS_LEVEL_1 sets area_passwd, IS_LEVEL_2 domain_passwd */ -int isis_area_passwd_unset (struct isis_area *area, int level); -int isis_area_passwd_cleartext_set (struct isis_area *area, int level, - const char *passwd, u_char snp_auth); -int isis_area_passwd_hmac_md5_set (struct isis_area *area, int level, - const char *passwd, u_char snp_auth); -void isis_vty_init (void); +int isis_area_passwd_unset(struct isis_area *area, int level); +int isis_area_passwd_cleartext_set(struct isis_area *area, int level, + const char *passwd, u_char snp_auth); +int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, + const char *passwd, u_char snp_auth); +void isis_vty_init(void); /* Master of threads. */ extern struct thread_master *master; @@ -181,21 +183,17 @@ extern struct thread_master *master; #define DEBUG_LSP_GEN (1<<13) #define DEBUG_LSP_SCHED (1<<14) -#define lsp_debug(...) \ - do \ - { \ - if (isis->debugs & DEBUG_LSP_GEN) \ - zlog_debug(__VA_ARGS__); \ - } \ - while (0) - -#define sched_debug(...) \ - do \ - { \ - if (isis->debugs & DEBUG_LSP_SCHED) \ - zlog_debug(__VA_ARGS__); \ - } \ - while (0) +#define lsp_debug(...) \ + do { \ + if (isis->debugs & DEBUG_LSP_GEN) \ + zlog_debug(__VA_ARGS__); \ + } while (0) + +#define sched_debug(...) \ + do { \ + if (isis->debugs & DEBUG_LSP_SCHED) \ + zlog_debug(__VA_ARGS__); \ + } while (0) #define DEBUG_TE (1<<13) diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c index 70b6b91ed..e0a4ba370 100644 --- a/isisd/iso_checksum.c +++ b/isisd/iso_checksum.c @@ -3,17 +3,17 @@ * ISO checksum related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -33,7 +33,7 @@ * sum a (mod 255) = 0 * 1 i * - * L + * L * sum (L-i+1)a (mod 255) = 0 * 1 i * @@ -45,30 +45,29 @@ * Based on Annex C.4 of ISO/IEC 8473 */ -int -iso_csum_verify (u_char * buffer, int len, uint16_t csum, int offset) +int iso_csum_verify(u_char *buffer, int len, uint16_t csum, int offset) { - u_int16_t checksum; - u_int32_t c0; - u_int32_t c1; + u_int16_t checksum; + u_int32_t c0; + u_int32_t c1; - c0 = csum & 0xff00; - c1 = csum & 0x00ff; + c0 = csum & 0xff00; + c1 = csum & 0x00ff; - /* - * If both are zero return correct - */ - if (c0 == 0 && c1 == 0) - return 0; + /* + * If both are zero return correct + */ + if (c0 == 0 && c1 == 0) + return 0; - /* - * If either, but not both are zero return incorrect - */ - if (c0 == 0 || c1 == 0) - return 1; + /* + * If either, but not both are zero return incorrect + */ + if (c0 == 0 || c1 == 0) + return 1; - checksum = fletcher_checksum(buffer, len, offset); - if (checksum == csum) - return 0; - return 1; + checksum = fletcher_checksum(buffer, len, offset); + if (checksum == csum) + return 0; + return 1; } diff --git a/isisd/iso_checksum.h b/isisd/iso_checksum.h index 50f6a7d56..5ba371fb4 100644 --- a/isisd/iso_checksum.h +++ b/isisd/iso_checksum.h @@ -3,17 +3,17 @@ * ISO checksum related routines * * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program 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 + * This program 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 @@ -23,6 +23,6 @@ #ifndef _ZEBRA_ISO_CSUM_H #define _ZEBRA_ISO_CSUM_H -int iso_csum_verify (u_char * buffer, int len, uint16_t csum, int offset); +int iso_csum_verify(u_char *buffer, int len, uint16_t csum, int offset); #endif /* _ZEBRA_ISO_CSUM_H */ |