mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 11:01:48 +00:00
Merge pull request #474 from opensourcerouting/isis-mt-additions
IS-IS additions
This commit is contained in:
commit
69bc62ba90
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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? */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user