diff options
Diffstat (limited to 'isisd')
51 files changed, 19543 insertions, 20184 deletions
diff --git a/isisd/dict.c b/isisd/dict.c index 56676edaf1..f09a8152a8 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 93edb7d603..a5ee922318 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 e4a4e0c426..d8cb32375b 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 a81797bb1e..9f4af1b45d 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 4ebaa4a1ee..69c2f941f0 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 d07ea27c44..72810532b0 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 82ca7ca0d9..5e523cd68b 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 6c827115b3..ba6c5f876d 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 b59d77bf3f..4b5ff888ba 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 90272d68b2..b0ccdee769 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 a1e0f234f6..53a5f9d5d0 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 afd8a14f94..7ac8b54fa4 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 96cf8488da..3f532ecf84 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 801cd0e472..ed26558b08 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 35d573d30a..9249ad6290 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 c36d9a0093..f3ca94d40f 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 8011d2db9c..9af256ba38 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 e9aa05db77..0ed2059c65 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 6c88cfeda5..e28d90d3db 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 ba11cf42b5..c57f778807 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 ed376058b1..40c6141ab8 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 0d1dd6740f..7bec162719 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 674592f46b..463e3abcf3 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 101fdcc69c..4ad26cf91f 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 3869159a02..16c789ff59 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 a71edd8e69..12ab0fac1c 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 26e02498ba..46b57510ac 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 e90f1756ff..eec089228e 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 41788e69fa..4b25316062 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 d62682b10f..a3706179a6 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 e512b6b1b9..fa8006cda0 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 c5985dcd8d..e24901b0de 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 b3f29fd203..8e329494dd 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 11b3c31e24..2bd40e849c 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 bceb70ce03..afc4f65128 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 24bd786fa7..6c7d9aea95 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 cf4562dbcd..44d7fa0403 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 b0ff559ac1..f1577666b0 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 4b5592c159..615c2eeaa2 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 8c72f45c52..c7a505489f 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 271545744a..5296d99480 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 3c99c90855..0bd076af19 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 7ffa7509c3..a295f4dd3f 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 e55e81bce1..d06548519f 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 157962dad3..2a19465a01 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 af77250a01..18a59d1fc5 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 82d5a48d3e..bd7bf2b5c5 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 473b6594e1..8bbb5cf949 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 9b6281866c..1aacea881f 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 70b6b91edb..e0a4ba3700 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 50f6a7d560..5ba371fb40 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 */  | 
