Merge pull request #474 from opensourcerouting/isis-mt-additions

IS-IS additions
This commit is contained in:
Donald Sharp 2017-05-06 20:55:15 -04:00 committed by GitHub
commit 69bc62ba90
7 changed files with 86 additions and 87 deletions

View File

@ -415,6 +415,12 @@ isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
vty_out (vty, " Circuit type: %s", circuit_t2string (adj->circuit_t));
vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
vty_out (vty, "%s", VTY_NEWLINE);
if (adj->mt_count != 1 || adj->mt_set[0] != ISIS_MT_IPV4_UNICAST)
{
vty_out (vty, " Topologies:%s", VTY_NEWLINE);
for (unsigned int i = 0; i < adj->mt_count; i++)
vty_out (vty, " %s%s", isis_mtid2str(adj->mt_set[i]), VTY_NEWLINE);
}
vty_out (vty, " SNPA: %s", snpa_print (adj->snpa));
if (adj->circuit && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST))
{

View File

@ -415,7 +415,7 @@ tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
if (!tlvs->mt_router_info)
{
/* Other end does not have MT enabled */
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST)
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST && v4_usable)
adj_mt_set(adj, intersect_count++, ISIS_MT_IPV4_UNICAST);
}
else
@ -425,7 +425,27 @@ tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
for (ALL_LIST_ELEMENTS_RO(tlvs->mt_router_info, node, info))
{
if (mt_settings[i]->mtid == info->mtid)
adj_mt_set(adj, intersect_count++, 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);
}
}
}
}

View File

@ -62,11 +62,6 @@
#define PNBBY 8
#endif /* PNBBY */
/* Utility mask array. */
static const u_char maskbit[] = {
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
};
/*
* HELPER FUNCS
*/
@ -93,69 +88,6 @@ area_match (struct list *left, struct list *right)
return 0; /* mismatch */
}
/*
* Check if ip2 is in the ip1's network (function like Prefix.h:prefix_match() )
* param ip1 the IS interface ip address structure
* param ip2 the IIH's ip address
* return 0 the IIH's IP is not in the IS's subnetwork
* 1 the IIH's IP is in the IS's subnetwork
*/
static int
ip_same_subnet (struct prefix_ipv4 *ip1, struct in_addr *ip2)
{
u_char *addr1, *addr2;
int shift, offset, offsetloop;
int len;
addr1 = (u_char *) & ip1->prefix.s_addr;
addr2 = (u_char *) & ip2->s_addr;
len = ip1->prefixlen;
shift = len % PNBBY;
offsetloop = offset = len / PNBBY;
while (offsetloop--)
if (addr1[offsetloop] != addr2[offsetloop])
return 0;
if (shift)
if (maskbit[shift] & (addr1[offset] ^ addr2[offset]))
return 0;
return 1; /* match */
}
/*
* Compares two set of ip addresses
* param left the local interface's ip addresses
* param right the iih interface's ip address
* return 0 no match;
* 1 match;
*/
static int
ip_match (struct list *left, struct list *right)
{
struct prefix_ipv4 *ip1;
struct in_addr *ip2;
struct listnode *node1, *node2;
if ((left == NULL) || (right == NULL))
return 0;
for (ALL_LIST_ELEMENTS_RO (left, node1, ip1))
{
for (ALL_LIST_ELEMENTS_RO (right, node2, ip2))
{
if (ip_same_subnet (ip1, ip2))
{
return 1; /* match */
}
}
}
return 0;
}
/*
* Checks whether we should accept a PDU of given level
*/
@ -517,16 +449,14 @@ process_p2p_hello (struct isis_circuit *circuit)
}
/*
* check if it's own interface ip match iih ip addrs
* check if both ends have an IPv4 address
*/
if (found & TLVFLAG_IPV4_ADDR)
if (circuit->ip_addrs && listcount(circuit->ip_addrs)
&& tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
{
if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
v4_usable = 1;
else
zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
"in P2P IIH from %s\n", circuit->interface->name);
v4_usable = 1;
}
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */
@ -1116,16 +1046,14 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
}
/*
* check if it's own interface ip match iih ip addrs
* check if both ends have an IPv4 address
*/
if (found & TLVFLAG_IPV4_ADDR)
if (circuit->ip_addrs && listcount(circuit->ip_addrs)
&& tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
{
if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
v4_usable = 1;
else
zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
"in LAN IIH from %s\n", circuit->interface->name);
v4_usable = 1;
}
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */

View File

@ -940,7 +940,9 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
switch (adj->sys_type)
{
case ISIS_SYSTYPE_ES:
isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
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;
@ -1017,7 +1019,9 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
switch (adj->sys_type)
{
case ISIS_SYSTYPE_ES:
isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
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;

View File

@ -1284,6 +1284,13 @@ DEFUN (circuit_topology,
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%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
if (mtid == (uint16_t)-1)
{
vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
@ -1306,6 +1313,13 @@ DEFUN (no_circuit_topology,
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%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
if (mtid == (uint16_t)-1)
{
vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
@ -1371,6 +1385,12 @@ DEFUN (metric_style,
return CMD_SUCCESS;
}
if (area_is_mt(area))
{
vty_out (vty, "Narrow metrics cannot be used while multi topology IS-IS is active%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
ret = validate_metric_style_narrow (vty, area);
if (ret != CMD_SUCCESS)
return ret;
@ -1393,6 +1413,12 @@ DEFUN (no_metric_style,
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%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
ret = validate_metric_style_narrow (vty, area);
if (ret != CMD_SUCCESS)
return ret;

View File

@ -300,8 +300,9 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
/* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY)
{
stream_putc (stream, NEXTHOP_TYPE_IPV4);
stream_putc (stream, NEXTHOP_TYPE_IPV4_IFINDEX);
stream_put_in_addr (stream, &nexthop->ip);
stream_putl (stream, nexthop->ifindex);
}
else
{

View File

@ -1669,6 +1669,13 @@ DEFUN (isis_topology,
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%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
if (mtid == (uint16_t)-1)
{
vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
@ -1697,6 +1704,13 @@ DEFUN (no_isis_topology,
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%s", VTY_NEWLINE);
return CMD_ERR_AMBIGUOUS;
}
if (mtid == (uint16_t)-1)
{
vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);