summaryrefslogtreecommitdiffstats
path: root/isisd/isis_pdu.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2014-06-29 13:48:18 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2014-08-18 01:49:32 +0200
commit28a8cfcbc3a5cc74bb3b87981b878f8b4edc2dd6 (patch)
tree55316289799b819a7170f908d4cf8c2f24350c99 /isisd/isis_pdu.c
parenttests/bgpd: don't hardcode error number (fix f57000c) (diff)
downloadfrr-28a8cfcbc3a5cc74bb3b87981b878f8b4edc2dd6.tar.xz
frr-28a8cfcbc3a5cc74bb3b87981b878f8b4edc2dd6.zip
isisd: don't require IPv4 for adjacency
This was precluding isisd from IPv6-only operation; no adjacency would come up unless there was IPv4 in parallel. Reported-by: Martin Winter <mwinter@netdef.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to '')
-rw-r--r--isisd/isis_pdu.c89
1 files changed, 79 insertions, 10 deletions
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 8a92789ff..5f18135e8 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -402,6 +402,7 @@ process_p2p_hello (struct isis_circuit *circuit)
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)
{
@@ -518,11 +519,44 @@ process_p2p_hello (struct isis_circuit *circuit)
/*
* check if it's own interface ip match iih ip addrs
*/
- if ((found & TLVFLAG_IPV4_ADDR) == 0 ||
- ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0)
+ if (found & TLVFLAG_IPV4_ADDR)
+ {
+ 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);
+ }
+#ifndef HAVE_IPV6
+ else /* !(found & TLVFLAG_IPV4_ADDR) */
+ zlog_warn ("ISIS-Adj: no IPv4 in P2P IIH from %s "
+ "(this isisd has no IPv6)\n", circuit->interface->name);
+
+#else
+ if (found & TLVFLAG_IPV6_ADDR)
+ {
+ /* TBA: check that we have a linklocal ourselves? */
+ struct listnode *node;
+ struct prefix_ipv6 *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);
+ }
+
+ 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);
+#endif
+
+ if (!v6_usable && !v4_usable)
{
- zlog_warn ("ISIS-Adj: No usable IP interface addresses "
- "in LAN IIH from %s\n", circuit->interface->name);
free_tlvs (&tlvs);
return ISIS_WARNING;
}
@@ -859,6 +893,7 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa)
struct tlvs tlvs;
u_char *snpa;
struct listnode *node;
+ int v4_usable = 0, v6_usable = 0;
if (isis->debugs & DEBUG_ADJ_PACKETS)
{
@@ -1045,15 +1080,49 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa)
/*
* check if it's own interface ip match iih ip addrs
*/
- if ((found & TLVFLAG_IPV4_ADDR) == 0 ||
- ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0)
+ if (found & TLVFLAG_IPV4_ADDR)
{
- zlog_debug ("ISIS-Adj: No usable IP interface addresses "
- "in LAN IIH from %s\n", circuit->interface->name);
- retval = ISIS_WARNING;
- goto out;
+ 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);
+ }
+#ifndef HAVE_IPV6
+ else /* !(found & TLVFLAG_IPV4_ADDR) */
+ zlog_warn ("ISIS-Adj: no IPv4 in LAN IIH from %s "
+ "(this isisd has no IPv6)\n", circuit->interface->name);
+
+#else
+ if (found & TLVFLAG_IPV6_ADDR)
+ {
+ /* TBA: check that we have a linklocal ourselves? */
+ struct listnode *node;
+ struct prefix_ipv6 *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 (!(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);
+#endif
+
+ 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))