From f390d2c7839c04100e4de8246215ce10ea96b653 Mon Sep 17 00:00:00 2001 From: hasso Date: Fri, 10 Sep 2004 20:48:21 +0000 Subject: Indentation only. No any functional changes. --- isisd/isis_pdu.c | 2910 +++++++++++++++++++++++++++++------------------------- 1 file changed, 1575 insertions(+), 1335 deletions(-) (limited to 'isisd/isis_pdu.c') diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index f93025db..cae34610 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -58,15 +58,14 @@ extern struct thread_master *master; extern struct isis *isis; #define ISIS_MINIMUM_FIXED_HDR_LEN 15 -#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */ +#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */ #ifndef PNBBY #define PNBBY 8 #endif /* PNBBY */ /* Utility mask array. */ -static u_char maskbit[] = -{ +static u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; @@ -77,21 +76,23 @@ static u_char maskbit[] = /* * Compares two sets of area addresses */ -static int +static int area_match (struct list *left, struct list *right) { struct area_addr *addr1, *addr2; struct listnode *node1, *node2; - LIST_LOOP (left, addr1, node1) { - LIST_LOOP (right, addr2, node2) { - if (addr1->addr_len == addr2->addr_len && - !memcmp (addr1->area_addr, addr2->area_addr, (int)addr1->addr_len)) - return 1; /* match */ + LIST_LOOP (left, addr1, node1) + { + LIST_LOOP (right, addr2, node2) + { + 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 */ } /* @@ -102,34 +103,37 @@ area_match (struct list *left, struct list *right) * 1 the IIH's IP is in the IS's subnetwork */ int -ip_same_subnet (struct prefix_ipv4 *ip1, struct in_addr *ip2) +ip_same_subnet (struct prefix_ipv4 *ip1, struct in_addr *ip2) { u_char *addr1, *addr2; int shift, offset; int len; - - addr1 = (u_char *) &ip1->prefix.s_addr; - addr2 = (u_char *) &ip2->s_addr; + + addr1 = (u_char *) & ip1->prefix.s_addr; + addr2 = (u_char *) & ip2->s_addr; len = ip1->prefixlen; shift = len % PNBBY; offset = len / PNBBY; - while (offset--) { - if (addr1[offset] != addr2[offset]) { - return 0; + while (offset--) + { + if (addr1[offset] != addr2[offset]) + { + return 0; + } } - } - if (shift) { - if (maskbit[shift] & (addr1[offset] ^ addr2[offset])) { - return 0; + if (shift) + { + if (maskbit[shift] & (addr1[offset] ^ addr2[offset])) + { + return 0; + } } - } - - return 1; /* match */ -} + return 1; /* match */ +} /* * Compares two set of ip addresses @@ -138,20 +142,23 @@ ip_same_subnet (struct prefix_ipv4 *ip1, struct in_addr *ip2) * return 0 no match; * 1 match; */ -static int +static int ip_match (struct list *left, struct list *right) { struct prefix_ipv4 *ip1; struct in_addr *ip2; struct listnode *node1, *node2; - LIST_LOOP (left, ip1, node1) { - LIST_LOOP (right, ip2, node2) { - if (ip_same_subnet(ip1, ip2)) { - return 1; /* match */ - } + LIST_LOOP (left, ip1, node1) + { + LIST_LOOP (right, ip2, node2) + { + if (ip_same_subnet (ip1, ip2)) + { + return 1; /* match */ + } } - + } return 0; } @@ -162,103 +169,111 @@ ip_match (struct list *left, struct list *right) 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; } -int +int authentication_check (struct isis_passwd *one, struct isis_passwd *theother) { - if (one->type != theother->type) { - zlog_warn ("Unsupported authentication type %d", theother->type ); - return 1; /* Auth fail (different authentication types)*/ - } - switch (one->type) { - case ISIS_PASSWD_TYPE_CLEARTXT: - if (one->len != theother->len) - return 1; /* Auth fail () - passwd len mismatch */ - return memcmp (one->passwd, theother->passwd, one->len); - break; - default: - zlog_warn ("Unsupported authentication type"); - break; - } - return 0; /* Auth pass */ + if (one->type != theother->type) + { + zlog_warn ("Unsupported authentication type %d", theother->type); + return 1; /* Auth fail (different authentication types) */ + } + switch (one->type) + { + case ISIS_PASSWD_TYPE_CLEARTXT: + if (one->len != theother->len) + return 1; /* Auth fail () - passwd len mismatch */ + return memcmp (one->passwd, theother->passwd, one->len); + break; + default: + zlog_warn ("Unsupported authentication type"); + break; + } + return 0; /* Auth pass */ } /* * Processing helper functions */ void -tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) +tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) { int i; struct nlpids *tlv_nlpids; - if (tlvs->nlpids) { + if (tlvs->nlpids) + { - tlv_nlpids = tlvs->nlpids; + tlv_nlpids = tlvs->nlpids; - adj->nlpids.count = tlv_nlpids->count; + adj->nlpids.count = tlv_nlpids->count; - for (i=0;icount;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]; + } } - } } -void +void del_ip_addr (void *val) { XFREE (MTYPE_ISIS_TMP, val); } void -tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) +tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) { struct listnode *node; struct in_addr *ipv4_addr, *malloced; - if (adj->ipv4_addrs) { - adj->ipv4_addrs->del = del_ip_addr; - list_delete (adj->ipv4_addrs); - } + if (adj->ipv4_addrs) + { + adj->ipv4_addrs->del = del_ip_addr; + list_delete (adj->ipv4_addrs); + } adj->ipv4_addrs = list_new (); - if (tlvs->ipv4_addrs) { - LIST_LOOP (tlvs->ipv4_addrs, ipv4_addr, node) { - malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in_addr)); - memcpy (malloced, ipv4_addr, sizeof (struct in_addr)); - listnode_add (adj->ipv4_addrs, malloced); + if (tlvs->ipv4_addrs) + { + LIST_LOOP (tlvs->ipv4_addrs, ipv4_addr, node) + { + malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in_addr)); + memcpy (malloced, ipv4_addr, sizeof (struct in_addr)); + listnode_add (adj->ipv4_addrs, malloced); + } } - } } #ifdef HAVE_IPV6 void -tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) +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_ip_addr; - list_delete (adj->ipv6_addrs); - } + if (adj->ipv6_addrs) + { + adj->ipv6_addrs->del = del_ip_addr; + list_delete (adj->ipv6_addrs); + } adj->ipv6_addrs = list_new (); - if (tlvs->ipv6_addrs) { - LIST_LOOP (tlvs->ipv6_addrs, ipv6_addr, node) { - malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in6_addr)); - memcpy (malloced, ipv6_addr, sizeof (struct in6_addr)); - listnode_add (adj->ipv6_addrs, malloced); + if (tlvs->ipv6_addrs) + { + LIST_LOOP (tlvs->ipv6_addrs, ipv6_addr, node) + { + malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in6_addr)); + memcpy (malloced, ipv6_addr, sizeof (struct in6_addr)); + listnode_add (adj->ipv6_addrs, malloced); + } } - } } #endif /* HAVE_IPV6 */ - - /* * RECEIVE SIDE */ @@ -278,12 +293,12 @@ process_p2p_hello (struct isis_circuit *circuit) u_int32_t expected = 0, found; struct tlvs tlvs; - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < - ISIS_P2PHELLO_HDRLEN) { - zlog_warn ("Packet too short"); - 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 */ @@ -301,41 +316,43 @@ process_p2p_hello (struct isis_circuit *circuit) /* * Get the header */ - hdr = (struct isis_p2p_hello_hdr*) STREAM_PNT(circuit->rcv_stream); + hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream); circuit->rcv_stream->getp += ISIS_P2PHELLO_HDRLEN; /* hdr.circuit_t = stream_getc (stream); - stream_get (hdr.source_id, stream, ISIS_SYS_ID_LEN); - hdr.hold_time = stream_getw (stream); - hdr.pdu_len = stream_getw (stream); - hdr.local_id = stream_getc (stream); */ + stream_get (hdr.source_id, stream, ISIS_SYS_ID_LEN); + hdr.hold_time = stream_getw (stream); + hdr.pdu_len = stream_getw (stream); + hdr.local_id = stream_getc (stream); */ /* * My interpertation of the ISO, if no adj exists we will create one for * the circuit */ - if (isis->debugs & DEBUG_ADJ_PACKETS) { - zlog_info("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->circuit_is_type), - circuit->circuit_id,ntohs(hdr->pdu_len)); - } + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + zlog_info ("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->circuit_is_type), + circuit->circuit_id, ntohs (hdr->pdu_len)); + } adj = circuit->u.p2p.neighbor; - if ( !adj ) { - adj = isis_new_adj (hdr->source_id," ", 0, circuit); - if (adj == NULL) - return ISIS_ERROR; - circuit->u.p2p.neighbor = adj; - isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - } + if (!adj) + { + adj = isis_new_adj (hdr->source_id, " ", 0, circuit); + if (adj == NULL) + return ISIS_ERROR; + circuit->u.p2p.neighbor = adj; + isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; + } /* 8.2.6 Monitoring point-to-point adjacencies */ adj->hold_time = ntohs (hdr->hold_time); - adj->last_upd = time (NULL); + adj->last_upd = time (NULL); /* * Lets get the TLVS now @@ -348,214 +365,273 @@ process_p2p_hello (struct isis_circuit *circuit) retval = parse_tlvs (circuit->area->area_tag, STREAM_PNT (circuit->rcv_stream), - ntohs (hdr->pdu_len) - ISIS_P2PHELLO_HDRLEN - - ISIS_FIXED_HDR_LEN, - &expected, - &found, - &tlvs); - - if (retval > ISIS_WARNING) { - free_tlvs (&tlvs); - return retval; - }; + ntohs (hdr->pdu_len) - ISIS_P2PHELLO_HDRLEN + - ISIS_FIXED_HDR_LEN, &expected, &found, &tlvs); + + if (retval > ISIS_WARNING) + { + free_tlvs (&tlvs); + return retval; + }; /* 8.2.5.1 c) Authentication */ - if (circuit->passwd.type) { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (&circuit->passwd, &tlvs.auth_info)) { - isis_event_auth_failure (circuit->area->area_tag, - "P2P hello authentication failure", - hdr->source_id); - return ISIS_OK; + if (circuit->passwd.type) + { + if (!(found & TLVFLAG_AUTH_INFO) || + authentication_check (&circuit->passwd, &tlvs.auth_info)) + { + isis_event_auth_failure (circuit->area->area_tag, + "P2P hello authentication failure", + hdr->source_id); + return ISIS_OK; + } } - } /* we do this now because the adj may not survive till the end... */ /* we need to copy addresses to the adj */ - tlvs_to_adj_ipv4_addrs (&tlvs,adj); + tlvs_to_adj_ipv4_addrs (&tlvs, adj); #ifdef HAVE_IPV6 - tlvs_to_adj_ipv6_addrs (&tlvs,adj); + tlvs_to_adj_ipv6_addrs (&tlvs, adj); #endif /* HAVE_IPV6 */ /* lets take care of the expiry */ - THREAD_TIMER_OFF(adj->t_expire); - THREAD_TIMER_ON(master, adj->t_expire, isis_adj_expire, adj, - (long)adj->hold_time); + THREAD_TIMER_OFF (adj->t_expire); + THREAD_TIMER_ON (master, adj->t_expire, isis_adj_expire, adj, + (long) adj->hold_time); /* 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"); - 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; - } - } + 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"); + 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; + } + } - /* 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; - } - } + /* 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; + } + } - /* 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"); - 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.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"); + 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.5.2 b) if no match was detected */ else - { - 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"); - 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; - } + 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"); + 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; + } + } } - } /* 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) { + switch (adj->adj_usage) + { case ISIS_ADJ_LEVEL1: adj->sys_type = ISIS_SYSTYPE_L1_IS; break; @@ -568,7 +644,7 @@ process_p2p_hello (struct isis_circuit *circuit) case ISIS_ADJ_NONE: adj->sys_type = ISIS_SYSTYPE_UNKNOWN; break; - } + } adj->circuit_t = hdr->circuit_t; adj->level = hdr->circuit_t; @@ -578,12 +654,11 @@ process_p2p_hello (struct isis_circuit *circuit) return retval; } - /* * Process IS-IS LAN Level 1/2 Hello PDU */ -static int -process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa) +static int +process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa) { int retval = ISIS_OK; struct isis_lan_hello_hdr hdr; @@ -593,35 +668,41 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa) u_char *snpa; struct listnode *node; - 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_info ("level %d LAN Hello received over circuit with " - "externalDomain = true", level); - return ISIS_WARNING; - } + if (circuit->ext_domain) + { + zlog_info ("level %d LAN Hello received over circuit with " + "externalDomain = true", level); + return ISIS_WARNING; + } - if (!accept_level (level, circuit->circuit_is_type)) { - if (isis->debugs & DEBUG_ADJ_PACKETS) { - zlog_info ("ISIS-Adj (%s): Interface level mismatch, %s", - circuit->area->area_tag, circuit->interface->name); + if (!accept_level (level, circuit->circuit_is_type)) + { + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + zlog_info ("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 */ - if (!accept_level (level, circuit->area->is_type)) { - if (isis->debugs & DEBUG_ADJ_PACKETS) { - zlog_info ("ISIS-Adj (%s): is type mismatch", - circuit->area->area_tag); + if (!accept_level (level, circuit->area->is_type)) + { + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + zlog_info ("ISIS-Adj (%s): is type mismatch", + circuit->area->area_tag); + } + return ISIS_WARNING; } - return ISIS_WARNING; - } #endif /* * Fill the header @@ -629,16 +710,17 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa) 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); + 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.circuit_t != IS_LEVEL_1 && hdr.circuit_t != IS_LEVEL_2 && - hdr.circuit_t != IS_LEVEL_1_AND_2 ) { - zlog_warn ("Level %d LAN Hello with Circuit Type %d", level, - hdr.circuit_t); - return ISIS_ERROR; - } + hdr.circuit_t != IS_LEVEL_1_AND_2) + { + zlog_warn ("Level %d LAN Hello with Circuit Type %d", level, + hdr.circuit_t); + return ISIS_ERROR; + } /* * Then get the tlvs */ @@ -650,171 +732,194 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa) expected |= TLVFLAG_IPV6_ADDR; 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); - - if (retval > ISIS_WARNING) { - zlog_warn ("parse_tlvs() failed"); - goto out; - } + STREAM_PNT (circuit->rcv_stream), + hdr.pdu_len - ISIS_LANHELLO_HDRLEN - + ISIS_FIXED_HDR_LEN, &expected, &found, &tlvs); - 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; - } + if (retval > ISIS_WARNING) + { + zlog_warn ("parse_tlvs() failed"); + goto out; + } - if (circuit->passwd.type) { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (&circuit->passwd, &tlvs.auth_info)) { - isis_event_auth_failure (circuit->area->area_tag, - "LAN hello authentication failure", - hdr.source_id); + 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; } - } + + if (circuit->passwd.type) + { + if (!(found & TLVFLAG_AUTH_INFO) || + authentication_check (&circuit->passwd, &tlvs.auth_info)) + { + 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 (level == 1 && !area_match (circuit->area->area_addrs, tlvs.area_addrs)) { - if (isis->debugs & DEBUG_ADJ_PACKETS) { - zlog_info ("ISIS-Adj (%s): Area mismatch, level %d IIH on %s", - circuit->area->area_tag, level,circuit->interface->name); + if (level == 1 && !area_match (circuit->area->area_addrs, tlvs.area_addrs)) + { + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + zlog_info ("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_info ("ISIS-Adj (%s): it's own IIH PDU - discarded", - circuit->area->area_tag); + */ + if (!memcmp (circuit->u.bc.snpa, ssnpa, ETH_ALEN)) + { + zlog_info ("ISIS-Adj (%s): it's own IIH PDU - discarded", + circuit->area->area_tag); - retval = ISIS_OK; - goto out; - } + retval = ISIS_OK; + goto out; + } /* * check if it's own interface ip match iih ip addrs */ - if (!(found & TLVFLAG_IPV4_ADDR) || !ip_match(circuit->ip_addrs, tlvs.ipv4_addrs)) { - zlog_info("ISIS-Adj: No usable IP interface addresses in LAN IIH from %s\n", - circuit->interface->name); - retval = ISIS_WARNING; - goto out; - } - + if (!(found & TLVFLAG_IPV4_ADDR) + || !ip_match (circuit->ip_addrs, tlvs.ipv4_addrs)) + { + zlog_info + ("ISIS-Adj: No usable IP interface addresses in LAN IIH from %s\n", + circuit->interface->name); + retval = ISIS_WARNING; + goto out; + } adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]); - 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; + 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; - adj->level = level; - isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); + adj->level = level; + isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); - if (level == 1) { - adj->sys_type = ISIS_SYSTYPE_L1_IS; - } else { - adj->sys_type = ISIS_SYSTYPE_L2_IS; + if (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]); } - 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]); - } - 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); - 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); - memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1); + 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); + 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); + memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id, + ISIS_SYS_ID_LEN + 1); + } + break; } - break; - } #if 0 - /* Old solution: believe the lan-header always - */ - if (level == 1) { - memcpy(circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1); - } else if (level == 2) { - memcpy(circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1); - } + /* Old solution: believe the lan-header always + */ + if (level == 1) + { + memcpy (circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1); + } + else if (level == 2) + { + memcpy (circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1); + } #endif adj->hold_time = hdr.hold_time; - adj->last_upd = time (NULL); - adj->prio[level-1] = hdr.prio; + adj->last_upd = time (NULL); + adj->prio[level - 1] = hdr.prio; memcpy (adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1); /* which protocol are spoken ??? */ - if (found & TLVFLAG_NLPID) + if (found & TLVFLAG_NLPID) tlvs_to_adj_nlpids (&tlvs, adj); /* we need to copy addresses to the adj */ - if (found & TLVFLAG_IPV4_ADDR) + if (found & TLVFLAG_IPV4_ADDR) tlvs_to_adj_ipv4_addrs (&tlvs, adj); #ifdef HAVE_IPV6 - if (found & TLVFLAG_IPV6_ADDR) + if (found & TLVFLAG_IPV6_ADDR) tlvs_to_adj_ipv6_addrs (&tlvs, adj); #endif /* HAVE_IPV6 */ adj->circuit_t = hdr.circuit_t; /* lets take care of the expiry */ - THREAD_TIMER_OFF(adj->t_expire); - THREAD_TIMER_ON(master, adj->t_expire, isis_adj_expire, adj, - (long)adj->hold_time); + THREAD_TIMER_OFF (adj->t_expire); + THREAD_TIMER_ON (master, adj->t_expire, isis_adj_expire, adj, + (long) adj->hold_time); /* * 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) { - LIST_LOOP (tlvs.lan_neighs, snpa, node) - if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN)) { - isis_adj_state_change (adj, ISIS_ADJ_UP, - "own SNPA found in LAN Neighbours TLV"); - } + if (found & TLVFLAG_LAN_NEIGHS) + { + if (adj->adj_state != ISIS_ADJ_UP) + { + LIST_LOOP (tlvs.lan_neighs, snpa, node) + if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN)) + { + isis_adj_state_change (adj, ISIS_ADJ_UP, + "own SNPA found in LAN Neighbours TLV"); + } + } } - } - out: +out: /* DEBUG_ADJ_PACKETS */ - if (isis->debugs & DEBUG_ADJ_PACKETS) { - /* FIXME: is this place right? fix missing info */ - zlog_info ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " - "cirID %u, length %ld", - circuit->area->area_tag, - level,snpa_print(ssnpa), circuit->interface->name, - circuit_t2string(circuit->circuit_is_type), - circuit->circuit_id, - stream_get_endp (circuit->rcv_stream)); - } - + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + /* FIXME: is this place right? fix missing info */ + zlog_info ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " + "cirID %u, length %ld", + circuit->area->area_tag, + level, snpa_print (ssnpa), circuit->interface->name, + circuit_t2string (circuit->circuit_is_type), + circuit->circuit_id, stream_get_endp (circuit->rcv_stream)); + } free_tlvs (&tlvs); @@ -825,9 +930,9 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa) * Process Level 1/2 Link State * 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, u_char *ssnpa) + */ +static int +process_lsp (int level, struct isis_circuit *circuit, u_char * ssnpa) { struct isis_link_state_hdr *hdr; struct isis_adjacency *adj = NULL; @@ -837,64 +942,65 @@ process_lsp (int level, struct isis_circuit *circuit, u_char *ssnpa) struct isis_passwd *passwd; /* Sanity check - FIXME: move to correct place */ - 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; - } + 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); - - if (isis->debugs & DEBUG_UPDATE_PACKETS) { - zlog_info ("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, " - "lifetime %us, len %lu, on %s", - circuit->area->area_tag, - level, - rawlspid_print(hdr->lsp_id), - ntohl(hdr->seq_num), - ntohs(hdr->checksum), - ntohs(hdr->rem_lifetime), - circuit->rcv_stream->endp, - circuit->interface->name); - } + hdr = (struct isis_link_state_hdr *) STREAM_PNT (circuit->rcv_stream); + + if (isis->debugs & DEBUG_UPDATE_PACKETS) + { + zlog_info ("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, " + "lifetime %us, len %lu, on %s", + circuit->area->area_tag, + level, + rawlspid_print (hdr->lsp_id), + ntohl (hdr->seq_num), + ntohs (hdr->checksum), + ntohs (hdr->rem_lifetime), + circuit->rcv_stream->endp, circuit->interface->name); + } assert (ntohs (hdr->pdu_len) > ISIS_LSP_HDR_LEN); /* Checksum sanity check - FIXME: move to correct place */ /* 12 = sysid+pdu+remtime */ - if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4, - ntohs (hdr->pdu_len) - 12, &hdr->checksum)) { - zlog_info ("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; - } + if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4, + ntohs (hdr->pdu_len) - 12, &hdr->checksum)) + { + zlog_info ("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; + } /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */ - if (circuit->ext_domain) { - zlog_info ("ISIS-Upd (%s): LSP %s received at level %d over circuit with " - "externalDomain = true", - circuit->area->area_tag, - rawlspid_print (hdr->lsp_id), - level); - - return ISIS_WARNING; - } + if (circuit->ext_domain) + { + zlog_info + ("ISIS-Upd (%s): LSP %s received at level %d over circuit with " + "externalDomain = true", circuit->area->area_tag, + rawlspid_print (hdr->lsp_id), level); + + return ISIS_WARNING; + } /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */ - if (!accept_level (level, circuit->circuit_is_type)) { - zlog_info ("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->circuit_is_type)); - - return ISIS_WARNING; - } + if (!accept_level (level, circuit->circuit_is_type)) + { + zlog_info ("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->circuit_is_type)); + + return ISIS_WARNING; + } /* 7.3.15.1 a) 4 - need to make sure IDLength matches */ @@ -903,221 +1009,254 @@ process_lsp (int level, struct isis_circuit *circuit, u_char *ssnpa) /* 7.3.15.1 a) 7 - password check */ (level == ISIS_LEVEL1) ? (passwd = &circuit->area->area_passwd) : (passwd = &circuit->area->domain_passwd); - if (passwd->type) { - if (isis_lsp_authinfo_check (circuit->rcv_stream, circuit->area, - ntohs (hdr->pdu_len), passwd)) { - isis_event_auth_failure (circuit->area->area_tag, - "LSP authentication failure", - hdr->lsp_id); - return ISIS_WARNING; + if (passwd->type) + { + if (isis_lsp_authinfo_check (circuit->rcv_stream, circuit->area, + ntohs (hdr->pdu_len), passwd)) + { + isis_event_auth_failure (circuit->area->area_tag, + "LSP authentication failure", hdr->lsp_id); + 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 + comp = lsp_compare (circuit->area->area_tag, lsp, hdr->seq_num, + hdr->checksum, hdr->rem_lifetime); + if (lsp && (lsp->own_lsp #ifdef TOPOLOGY_GENERATE - || lsp->from_topology + || lsp->from_topology #endif /* TOPOLOGY_GENERATE */ - )) + )) 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 */ /* FIXME : Point To Point */ - if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - adj = isis_adj_lookup_snpa (ssnpa, circuit->u.bc.adjdb[level - 1]); - if (!adj) { - zlog_info ("(%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 */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + { + adj = isis_adj_lookup_snpa (ssnpa, circuit->u.bc.adjdb[level - 1]); + if (!adj) + { + zlog_info ("(%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 */ + } } - } /* 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 == 1) && - (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL2)) || - ((level == 2) && - (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL1))) - return ISIS_WARNING; /* Silently discard */ + else + { + /* If no adj, or no sharing of level */ + if (!circuit->u.p2p.neighbor) + { + return ISIS_OK; /* Silently discard */ + } + else + { + if (((level == 1) && + (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL2)) || + ((level == 2) && + (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL1))) + return ISIS_WARNING; /* Silently discard */ + } } - } - dontcheckadj: +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.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, hdr, circuit->rcv_stream, circuit->area); - /* ii */ - ISIS_FLAGS_SET_ALL (lsp->SRMflags); - /* iii */ - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); - /* v */ - ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); /* FIXME: OTHER than c */ - /* 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 { - /* our own LSP -> 7.3.16.4 c) */ - if (LSP_PSEUDO_ID(lsp->lsp_header->lsp_id) != circuit->circuit_id || - (LSP_PSEUDO_ID(lsp->lsp_header->lsp_id) == circuit->circuit_id && - circuit->u.bc.is_dr[level - 1] == 1) ) { - lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1); - zlog_info ("LSP LEN: %d", ntohs (lsp->lsp_header->pdu_len)); - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, - ntohs (lsp->lsp_header->pdu_len) - 12, 12); - ISIS_FLAGS_SET_ALL (lsp->SRMflags); - zlog_info ("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)); - lsp->lsp_header->rem_lifetime = htons (isis_jitter - (circuit->area-> - max_lsp_lifetime[level-1], - MAX_AGE_JITTER)); - - } else { - /* Got purge for own pseudo-lsp, and we are not DR */ - lsp_purge_dr (lsp->lsp_header->lsp_id, circuit, level); - } - } + /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do it */ + + /* 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, hdr, circuit->rcv_stream, circuit->area); + /* ii */ + ISIS_FLAGS_SET_ALL (lsp->SRMflags); + /* iii */ + ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); + /* v */ + ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c */ + /* 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 + { + /* our own LSP -> 7.3.16.4 c) */ + if (LSP_PSEUDO_ID (lsp->lsp_header->lsp_id) != + circuit->circuit_id + || (LSP_PSEUDO_ID (lsp->lsp_header->lsp_id) == + circuit->circuit_id + && circuit->u.bc.is_dr[level - 1] == 1)) + { + lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1); + zlog_info ("LSP LEN: %d", ntohs (lsp->lsp_header->pdu_len)); + iso_csum_create (STREAM_DATA (lsp->pdu) + 12, + ntohs (lsp->lsp_header->pdu_len) - 12, 12); + ISIS_FLAGS_SET_ALL (lsp->SRMflags); + zlog_info + ("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)); + lsp->lsp_header->rem_lifetime = + htons (isis_jitter + (circuit->area->max_lsp_lifetime[level - 1], + MAX_AGE_JITTER)); + } + else + { + /* Got purge for own pseudo-lsp, and we are not DR */ + lsp_purge_dr (lsp->lsp_header->lsp_id, circuit, level); + } + } + } + return retval; } - 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 (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, ... */ - - else if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num)) { - /* 7.3.16.1 */ - lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1); - - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, - ntohs(lsp->lsp_header->pdu_len) - 12, 12); - - ISIS_FLAGS_SET_ALL (lsp->SRMflags); - zlog_info ("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)); - lsp->lsp_header->rem_lifetime = htons (isis_jitter - (circuit-> - area->max_lsp_lifetime[level-1], - MAX_AGE_JITTER)); - + 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 (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, ... */ + + else if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num)) + { + /* 7.3.16.1 */ + lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1); + + iso_csum_create (STREAM_DATA (lsp->pdu) + 12, + ntohs (lsp->lsp_header->pdu_len) - 12, 12); + + ISIS_FLAGS_SET_ALL (lsp->SRMflags); + zlog_info + ("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)); + lsp->lsp_header->rem_lifetime = + htons (isis_jitter + (circuit->area->max_lsp_lifetime[level - 1], + MAX_AGE_JITTER)); + } } - } 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)){ - /* i */ - if (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)) + { + /* i */ + if (lsp) + { #ifdef EXTREME_DEBUG - zlog_info ("level %d number is - %ld", level, - circuit->area->lspdb[level-1]->dict_nodecount); + zlog_info ("level %d number is - %ld", level, + circuit->area->lspdb[level - 1]->dict_nodecount); #endif /* EXTREME DEBUG */ - lsp_search_and_destroy (hdr->lsp_id, circuit->area->lspdb[level-1]); - /* exists, so we overwrite */ + lsp_search_and_destroy (hdr->lsp_id, + circuit->area->lspdb[level - 1]); + /* exists, so we overwrite */ #ifdef EXTREME_DEBUG - zlog_info ("level %d number is - %ld",level, - circuit->area->lspdb[level-1]->dict_nodecount); + zlog_info ("level %d number is - %ld", level, + circuit->area->lspdb[level - 1]->dict_nodecount); #endif /* EXTREME DEBUG */ - } - /* - * 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_info ("Got lsp frag, while zero lsp not database"); - return ISIS_OK; - } - } - lsp = lsp_new_from_stream_ptr (circuit->rcv_stream, ntohs (hdr->pdu_len), - lsp0, circuit->area); - lsp->level = level; - lsp->adj = adj; - lsp_insert (lsp, circuit->area->lspdb[level-1]); - /* ii */ - ISIS_FLAGS_SET_ALL (lsp->SRMflags); - /* 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, hdr, circuit->rcv_stream, circuit->area); - 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); + } + /* + * 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_info ("Got lsp frag, while zero lsp not database"); + return ISIS_OK; + } + } + lsp = + lsp_new_from_stream_ptr (circuit->rcv_stream, + ntohs (hdr->pdu_len), lsp0, + circuit->area); + lsp->level = level; + lsp->adj = adj; + lsp_insert (lsp, circuit->area->lspdb[level - 1]); + /* ii */ + ISIS_FLAGS_SET_ALL (lsp->SRMflags); + /* 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, hdr, circuit->rcv_stream, circuit->area); + 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); + } } - } if (lsp) lsp->adj = adj; return retval; @@ -1130,8 +1269,8 @@ process_lsp (int level, struct isis_circuit *circuit, u_char *ssnpa) */ int -process_snp (int snp_type, int level, struct isis_circuit *circuit, - u_char *ssnpa) +process_snp (int snp_type, int level, struct isis_circuit *circuit, + u_char * ssnpa) { int retval = ISIS_OK; int cmp, own_lsp; @@ -1143,76 +1282,82 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit, uint32_t found = 0, expected = 0; struct isis_lsp *lsp; struct lsp_entry *entry; - struct listnode *node,*node2; + struct listnode *node, *node2; 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); - circuit->rcv_stream->getp += ISIS_CSNP_HDRLEN; - len = ntohs(chdr->pdu_len); - if (len < ISIS_CSNP_HDRLEN) { - zlog_warn ("Received a CSNP with bogus length!"); - return ISIS_OK; + if (snp_type == ISIS_SNP_CSNP_FLAG) + { + /* getting the header info */ + typechar = 'C'; + chdr = + (struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); + circuit->rcv_stream->getp += ISIS_CSNP_HDRLEN; + len = ntohs (chdr->pdu_len); + if (len < ISIS_CSNP_HDRLEN) + { + zlog_warn ("Received a CSNP with bogus length!"); + return ISIS_OK; + } } - } else { - typechar = 'P'; - phdr = (struct isis_partial_seqnum_hdr*)STREAM_PNT(circuit->rcv_stream); - circuit->rcv_stream->getp += ISIS_PSNP_HDRLEN; - len = ntohs(phdr->pdu_len); - if (len < ISIS_PSNP_HDRLEN) { - zlog_warn ("Received a CSNP with bogus length!"); - return ISIS_OK; + else + { + typechar = 'P'; + phdr = + (struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); + circuit->rcv_stream->getp += ISIS_PSNP_HDRLEN; + len = ntohs (phdr->pdu_len); + if (len < ISIS_PSNP_HDRLEN) + { + zlog_warn ("Received a CSNP with bogus length!"); + return ISIS_OK; + } } - } /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */ - if (circuit->ext_domain) { + if (circuit->ext_domain) + { - zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " - "skipping: circuit externalDomain = true", - circuit->area->area_tag, - level, - typechar, - circuit->interface->name); + zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " + "skipping: circuit externalDomain = true", + circuit->area->area_tag, + level, typechar, circuit->interface->name); - return ISIS_OK; - } + return ISIS_OK; + } /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */ - if (!accept_level (level, circuit->circuit_is_type)) { - - zlog_info ("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->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)) { - if (!circuit->u.bc.is_dr[level-1]) { + if (!accept_level (level, circuit->circuit_is_type)) + { - zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, " - "skipping: we are not the DIS", + zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " + "skipping: circuit type %s does not match level %d", circuit->area->area_tag, - level, + level, typechar, - snpa_print(ssnpa), - circuit->interface->name); + circuit->interface->name, + circuit_t2string (circuit->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)) + { + if (!circuit->u.bc.is_dr[level - 1]) + { + + zlog_info ("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; + } + } /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked */ @@ -1222,19 +1367,27 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit, /* 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) - return ISIS_OK; /* Silently discard */ - } + 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) + return ISIS_OK; /* Silently discard */ + } /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented */ @@ -1246,163 +1399,183 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit, expected |= TLVFLAG_LSP_ENTRIES; expected |= TLVFLAG_AUTH_INFO; retval = parse_tlvs (circuit->area->area_tag, - STREAM_PNT(circuit->rcv_stream), + STREAM_PNT (circuit->rcv_stream), len - circuit->rcv_stream->getp, - &expected, - &found, - &tlvs); + &expected, &found, &tlvs); - if (retval > ISIS_WARNING) { - zlog_warn ("something went very wrong processing SNP"); - free_tlvs (&tlvs); - return retval; - } + if (retval > ISIS_WARNING) + { + zlog_warn ("something went very wrong processing SNP"); + free_tlvs (&tlvs); + return retval; + } (level == 1) ? (passwd = &circuit->area->area_passwd) : - (passwd = &circuit->area->domain_passwd); - if (passwd->type) { - if (!(found & TLVFLAG_AUTH_INFO) || - authentication_check (passwd, &tlvs.auth_info)) { - isis_event_auth_failure (circuit->area->area_tag, "SNP authentication" - " failure", phdr ? - phdr->source_id : chdr->source_id); - return ISIS_OK; - } - } + (passwd = &circuit->area->domain_passwd); + if (passwd->type) + { + if (!(found & TLVFLAG_AUTH_INFO) || + authentication_check (passwd, &tlvs.auth_info)) + { + isis_event_auth_failure (circuit->area->area_tag, + "SNP authentication" " failure", + phdr ? phdr->source_id : chdr->source_id); + return ISIS_OK; + } + } /* debug isis snp-packets */ - if (isis->debugs & DEBUG_SNP_PACKETS) { - zlog_info ("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) { - LIST_LOOP (tlvs.lsp_entries,entry,node) { - zlog_info("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 (isis->debugs & DEBUG_SNP_PACKETS) + { + zlog_info ("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) + { + LIST_LOOP (tlvs.lsp_entries, entry, node) + { + zlog_info ("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)); + } + } } - } /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */ - if (tlvs.lsp_entries) { - LIST_LOOP (tlvs.lsp_entries, entry, node) { - 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); - } else { - /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p*/ - 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 (entry->lsp_id, ntohs (entry->rem_lifetime), - 0, 0, entry->checksum, level); - lsp_insert (lsp, circuit->area->lspdb[level - 1]); - ISIS_SET_FLAG (lsp->SSNflags, circuit); - } + if (tlvs.lsp_entries) + { + LIST_LOOP (tlvs.lsp_entries, entry, node) + { + 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); + } + else + { + /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM + * on p2p */ + 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 (entry->lsp_id, ntohs (entry->rem_lifetime), + 0, 0, entry->checksum, level); + lsp_insert (lsp, circuit->area->lspdb[level - 1]); + ISIS_SET_FLAG (lsp->SSNflags, circuit); + } + } } } - } /* 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_ 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) { - LIST_LOOP (tlvs.lsp_entries, entry, node) { - LIST_LOOP (lsp_list, lsp, node2) { - if (lsp_id_cmp (lsp->lsp_header->lsp_id, entry->lsp_id) == 0) { - list_delete_node (lsp_list, node2); - break; - } - } + if (snp_type == ISIS_SNP_CSNP_FLAG) + { + /* + * Build a list from our own LSP db bounded with start_ 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) + { + LIST_LOOP (tlvs.lsp_entries, entry, node) + { + LIST_LOOP (lsp_list, lsp, node2) + { + 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) */ + LIST_LOOP (lsp_list, lsp, node2) + { + ISIS_SET_FLAG (lsp->SRMflags, circuit); } + /* lets free it */ + list_free (lsp_list); } - /* on remaining LSPs we set SRM (neighbor knew not of) */ - LIST_LOOP (lsp_list, lsp, node2) { - ISIS_SET_FLAG (lsp->SRMflags, circuit); - } - /* lets free it */ - list_free (lsp_list); - } free_tlvs (&tlvs); return retval; } int -process_csnp (int level, struct isis_circuit *circuit, u_char *ssnpa) +process_csnp (int level, struct isis_circuit *circuit, u_char * ssnpa) { - /* 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; - } + 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); } -int -process_psnp (int level, struct isis_circuit *circuit, u_char *ssnpa) +int +process_psnp (int level, struct isis_circuit *circuit, u_char * ssnpa) { - - if ((stream_get_endp (circuit->rcv_stream) - - stream_get_getp (circuit->rcv_stream)) < ISIS_PSNP_HDRLEN) { - zlog_warn ("Packet too short"); - return ISIS_WARNING; - } + if ((stream_get_endp (circuit->rcv_stream) - + stream_get_getp (circuit->rcv_stream)) < ISIS_PSNP_HDRLEN) + { + zlog_warn ("Packet too short"); + return ISIS_WARNING; + } return process_snp (ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa); } - - /* * Process ISH * ISO - 10589 * Section 8.2.2 - Receiving ISH PDUs by an intermediate system * FIXME: sample packet dump, need to figure 0x81 - looks like NLPid - 0x82 0x15 0x01 0x00 0x04 0x01 0x2c 0x59 - 0x38 0x08 0x47 0x00 0x01 0x00 0x02 0x00 - 0x03 0x00 0x81 0x01 0xcc + * 0x82 0x15 0x01 0x00 0x04 0x01 0x2c 0x59 + * 0x38 0x08 0x47 0x00 0x01 0x00 0x02 0x00 + * 0x03 0x00 0x81 0x01 0xcc */ int process_is_hello (struct isis_circuit *circuit) @@ -1419,172 +1592,185 @@ process_is_hello (struct isis_circuit *circuit) return retval; neigh_len = stream_getc (circuit->rcv_stream); - sysid = STREAM_PNT(circuit->rcv_stream) + neigh_len - 1 - ISIS_SYS_ID_LEN; + sysid = STREAM_PNT (circuit->rcv_stream) + neigh_len - 1 - ISIS_SYS_ID_LEN; adj = circuit->u.p2p.neighbor; - if (!adj) { - /* 8.2.2 */ - adj = isis_new_adj (sysid, " ", 0, circuit); - if (adj == NULL) - return ISIS_ERROR; - - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - circuit->u.p2p.neighbor = adj; - } - /* 8.2.2 a)*/ - if ((adj->adj_state == ISIS_ADJ_UP) && memcmp (adj->sysid,sysid, - ISIS_SYS_ID_LEN)) { - /* 8.2.2 a) 1) FIXME: adjStateChange(down) event */ - /* 8.2.2 a) 2) delete the adj */ - XFREE (MTYPE_ISIS_ADJACENCY, adj); - /* 8.2.2 a) 3) create a new adj */ - adj = isis_new_adj (sysid, " ", 0, circuit); - if (adj == NULL) - return ISIS_ERROR; + if (!adj) + { + /* 8.2.2 */ + adj = isis_new_adj (sysid, " ", 0, circuit); + if (adj == NULL) + return ISIS_ERROR; - /* 8.2.2 a) 3) i */ - isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); - /* 8.2.2 a) 3) ii */ - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - /* 8.2.2 a) 4) quite meaningless */ - } + isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; + circuit->u.p2p.neighbor = adj; + } + /* 8.2.2 a) */ + if ((adj->adj_state == ISIS_ADJ_UP) && memcmp (adj->sysid, sysid, + ISIS_SYS_ID_LEN)) + { + /* 8.2.2 a) 1) FIXME: adjStateChange(down) event */ + /* 8.2.2 a) 2) delete the adj */ + XFREE (MTYPE_ISIS_ADJACENCY, adj); + /* 8.2.2 a) 3) create a new adj */ + adj = isis_new_adj (sysid, " ", 0, circuit); + if (adj == NULL) + return ISIS_ERROR; + + /* 8.2.2 a) 3) i */ + isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); + /* 8.2.2 a) 3) ii */ + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; + /* 8.2.2 a) 4) quite meaningless */ + } /* 8.2.2 b) ignore on condition */ - if ((adj->adj_state == ISIS_ADJ_INITIALIZING) && - (adj->sys_type == ISIS_SYSTYPE_IS)) { - /* do nothing */ - } else { - /* 8.2.2 c) respond with a p2p IIH */ - send_hello (circuit, 1); - } + if ((adj->adj_state == ISIS_ADJ_INITIALIZING) && + (adj->sys_type == ISIS_SYSTYPE_IS)) + { + /* do nothing */ + } + else + { + /* 8.2.2 c) respond with a p2p IIH */ + send_hello (circuit, 1); + } /* 8.2.2 d) type is IS */ - adj->sys_type = ISIS_SYSTYPE_IS; + adj->sys_type = ISIS_SYSTYPE_IS; /* 8.2.2 e) FIXME: Circuit type of? */ - return retval; } - /* * PDU Dispatcher */ -int -isis_handle_pdu (struct isis_circuit *circuit, u_char *ssnpa) +int +isis_handle_pdu (struct isis_circuit *circuit, u_char * ssnpa) { - struct isis_fixed_hdr *hdr; struct esis_fixed_hdr *esis_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); + hdr = (struct isis_fixed_hdr *) STREAM_DATA (circuit->rcv_stream); - if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS)){ - zlog_warn ("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_warn ("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){ - esis_hdr = (struct esis_fixed_hdr*)STREAM_DATA(circuit->rcv_stream); - stream_set_getp (circuit->rcv_stream, ESIS_FIXED_HDR_LEN); - /* FIXME: Need to do some acceptence tests */ - /* example length... */ - switch (esis_hdr->pdu_type) { - case ESH_PDU: - /* FIXME */ - break; - case ISH_PDU: - zlog_info ("AN ISH PDU!!"); - retval = process_is_hello (circuit); - break; - default: - return ISIS_ERROR; - } - return retval; - } else { - stream_set_getp (circuit->rcv_stream, ISIS_FIXED_HDR_LEN); - } + if (hdr->idrp == ISO9542_ESIS) + { + esis_hdr = (struct esis_fixed_hdr *) STREAM_DATA (circuit->rcv_stream); + stream_set_getp (circuit->rcv_stream, ESIS_FIXED_HDR_LEN); + /* FIXME: Need to do some acceptence tests */ + /* example length... */ + switch (esis_hdr->pdu_type) + { + case ESH_PDU: + /* FIXME */ + break; + case ISH_PDU: + zlog_info ("AN ISH PDU!!"); + retval = process_is_hello (circuit); + break; + default: + return ISIS_ERROR; + } + return retval; + } + else + { + stream_set_getp (circuit->rcv_stream, ISIS_FIXED_HDR_LEN); + } /* * 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; - } + 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->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; + } /* 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; - } + 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; } - #ifdef GNU_LINUX int isis_receive (struct thread *thread) { - struct isis_circuit *circuit; u_char ssnpa[ETH_ALEN]; int retval; @@ -1596,12 +1782,12 @@ isis_receive (struct thread *thread) assert (circuit); if (circuit->rcv_stream == NULL) - circuit->rcv_stream = stream_new (ISO_MTU(circuit)); + circuit->rcv_stream = stream_new (ISO_MTU (circuit)); else stream_reset (circuit->rcv_stream); retval = circuit->rx (circuit, ssnpa); - circuit->t_read = NULL; + circuit->t_read = NULL; if (retval == ISIS_OK) retval = isis_handle_pdu (circuit, ssnpa); @@ -1609,7 +1795,8 @@ isis_receive (struct thread *thread) /* * prepare for next packet. */ - THREAD_READ_ON(master, circuit->t_read, isis_receive, circuit, circuit->fd); + THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit, + circuit->fd); return retval; } @@ -1618,7 +1805,6 @@ isis_receive (struct thread *thread) int isis_receive (struct thread *thread) { - struct isis_circuit *circuit; u_char ssnpa[ETH_ALEN]; int retval; @@ -1629,10 +1815,10 @@ isis_receive (struct thread *thread) circuit = THREAD_ARG (thread); assert (circuit); - circuit->t_read = NULL; + circuit->t_read = NULL; if (circuit->rcv_stream == NULL) - circuit->rcv_stream = stream_new (ISO_MTU(circuit)); + circuit->rcv_stream = stream_new (ISO_MTU (circuit)); else stream_reset (circuit->rcv_stream); @@ -1644,10 +1830,10 @@ isis_receive (struct thread *thread) /* * prepare for next packet. */ - circuit->t_read = 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); return retval; } @@ -1662,47 +1848,47 @@ fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type) 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; - } + 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->id_len = 0; /* ISIS_SYS_ID_LEN - 0==6 */ hdr->version2 = 1; - hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */ + hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */ } - /* * SEND SIDE */ void fill_fixed_hdr_andstream (struct isis_fixed_hdr *hdr, u_char pdu_type, - struct stream *stream) + struct stream *stream) { - fill_fixed_hdr (hdr,pdu_type); + fill_fixed_hdr (hdr, pdu_type); stream_putc (stream, hdr->idrp); stream_putc (stream, hdr->length); @@ -1716,7 +1902,6 @@ fill_fixed_hdr_andstream (struct isis_fixed_hdr *hdr, u_char pdu_type, return; } - int send_hello (struct isis_circuit *circuit, int level) { @@ -1728,55 +1913,65 @@ send_hello (struct isis_circuit *circuit, int level) unsigned long len_pointer, length; int retval; - if (circuit->interface->mtu == 0) { - zlog_warn ("circuit has zero MTU"); - return ISIS_WARNING; - } + if (circuit->interface->mtu == 0) + { + zlog_warn ("circuit has zero MTU"); + return ISIS_WARNING; + } if (!circuit->snd_stream) - circuit->snd_stream = stream_new (ISO_MTU(circuit)); + circuit->snd_stream = stream_new (ISO_MTU (circuit)); else stream_reset (circuit->snd_stream); if (circuit->circ_type == CIRCUIT_T_BROADCAST) if (level == 1) - fill_fixed_hdr_andstream(&fixed_hdr, L1_LAN_HELLO, circuit->snd_stream); + 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); + 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_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] * + interval = circuit->hello_multiplier[level - 1] * circuit->hello_interval[level - 1]; if (interval > USHRT_MAX) interval = USHRT_MAX; hello_hdr.circuit_t = circuit->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_putp (circuit->snd_stream) + 3 + 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_putp (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->u.bc.priority[level - 1]; - if(level == 1 && circuit->u.bc.l1_desig_is) { - memcpy(hello_hdr.lan_id, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1); - } else if (level == 2 && circuit->u.bc.l2_desig_is){ - 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->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->u.bc.priority[level - 1]; + if (level == 1 && circuit->u.bc.l1_desig_is) + { + memcpy (hello_hdr.lan_id, circuit->u.bc.l1_desig_is, + ISIS_SYS_ID_LEN + 1); + } + else if (level == 2 && circuit->u.bc.l2_desig_is) + { + 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); + } /* * Then the variable length part @@ -1793,19 +1988,20 @@ send_hello (struct isis_circuit *circuit, int level) return ISIS_WARNING; /* LAN Neighbors TLV */ - if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - if (level == 1 && circuit->u.bc.lan_neighs[0]->count > 0) - if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0], - circuit->snd_stream)) - return ISIS_WARNING; - if (level == 2 && circuit->u.bc.lan_neighs[1]->count > 0) - if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1], - circuit->snd_stream)) - return ISIS_WARNING; - } + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + { + if (level == 1 && circuit->u.bc.lan_neighs[0]->count > 0) + if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0], + circuit->snd_stream)) + return ISIS_WARNING; + if (level == 2 && circuit->u.bc.lan_neighs[1]->count > 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 (circuit->nlpids.count > 0) if (tlv_add_nlpid (&circuit->nlpids, circuit->snd_stream)) return ISIS_WARNING; /* IP interface Address TLV */ @@ -1813,9 +2009,9 @@ send_hello (struct isis_circuit *circuit, int level) if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream)) return ISIS_WARNING; -#ifdef HAVE_IPV6 +#ifdef HAVE_IPV6 /* IPv6 Interface Address TLV */ - if (circuit->ipv6_router && circuit->ipv6_link && + if (circuit->ipv6_router && circuit->ipv6_link && circuit->ipv6_link->count > 0) if (tlv_add_ipv6_addrs (circuit->ipv6_link, circuit->snd_stream)) return ISIS_WARNING; @@ -1827,25 +2023,28 @@ send_hello (struct isis_circuit *circuit, int level) length = stream_get_putp (circuit->snd_stream); /* Update PDU length */ - stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t)length); + stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t) length); retval = circuit->tx (circuit, level); if (retval) zlog_warn ("sending of LAN Level %d Hello failed", level); /* DEBUG_ADJ_PACKETS */ - if (isis->debugs & DEBUG_ADJ_PACKETS) { - if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - zlog_info ("ISIS-Adj (%s): Sent L%d LAN IIH on %s, length %ld", - circuit->area->area_tag, level, circuit->interface->name, - STREAM_SIZE(circuit->snd_stream)); - } else { - zlog_info ("ISIS-Adj (%s): Sent P2P IIH on %s, length %ld", - circuit->area->area_tag, circuit->interface->name, - STREAM_SIZE(circuit->snd_stream)); + if (isis->debugs & DEBUG_ADJ_PACKETS) + { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + { + zlog_info ("ISIS-Adj (%s): Sent L%d LAN IIH on %s, length %ld", + circuit->area->area_tag, level, circuit->interface->name, + STREAM_SIZE (circuit->snd_stream)); + } + else + { + zlog_info ("ISIS-Adj (%s): Sent P2P IIH on %s, length %ld", + circuit->area->area_tag, circuit->interface->name, + STREAM_SIZE (circuit->snd_stream)); + } } - } - return retval; } @@ -1853,13 +2052,12 @@ send_hello (struct isis_circuit *circuit, int level) int send_lan_hello (struct isis_circuit *circuit, int level) { - return send_hello (circuit,level); + return send_hello (circuit, level); } int send_lan_l1_hello (struct thread *thread) { - struct isis_circuit *circuit; int retval; @@ -1868,13 +2066,14 @@ send_lan_l1_hello (struct thread *thread) circuit->u.bc.t_send_lan_hello[0] = NULL; if (circuit->u.bc.run_dr_elect[0]) - retval = isis_dr_elect (circuit, 1); + retval = isis_dr_elect (circuit, 1); retval = send_lan_hello (circuit, 1); /* set next timer thread */ - THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[0], send_lan_l1_hello, - circuit, isis_jitter (circuit->hello_interval[0], IIH_JITTER)); + THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0], + send_lan_l1_hello, circuit, + isis_jitter (circuit->hello_interval[0], IIH_JITTER)); return retval; } @@ -1894,9 +2093,10 @@ send_lan_l2_hello (struct thread *thread) retval = send_lan_hello (circuit, 2); - /* set next timer thread*/ - THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[1], send_lan_l2_hello, - circuit, isis_jitter (circuit->hello_interval[1], IIH_JITTER)); + /* set next timer thread */ + THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1], + send_lan_l2_hello, circuit, + isis_jitter (circuit->hello_interval[1], IIH_JITTER)); return retval; } @@ -1910,18 +2110,19 @@ send_p2p_hello (struct thread *thread) assert (circuit); circuit->u.p2p.t_send_p2p_hello = NULL; - send_hello(circuit,1); + send_hello (circuit, 1); - /* set next timer thread*/ - THREAD_TIMER_ON(master, circuit->u.p2p.t_send_p2p_hello, send_p2p_hello, - circuit, isis_jitter (circuit->hello_interval[1], IIH_JITTER)); + /* set next timer thread */ + THREAD_TIMER_ON (master, circuit->u.p2p.t_send_p2p_hello, send_p2p_hello, + circuit, isis_jitter (circuit->hello_interval[1], + IIH_JITTER)); return ISIS_OK; } int -build_csnp (int level, u_char *start, u_char *stop, struct list *lsps, - struct isis_circuit *circuit) +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; @@ -1929,19 +2130,19 @@ build_csnp (int level, u_char *start, u_char *stop, struct list *lsps, unsigned long lenp; u_int16_t length; - if (level ==1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM, - circuit->snd_stream); + if (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_fixed_hdr_andstream (&fixed_hdr, L2_COMPLETE_SEQ_NUM, + circuit->snd_stream); /* * Fill Level 1 or 2 Complete Sequence Numbers header */ lenp = stream_get_putp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */ + 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 */ @@ -1962,10 +2163,11 @@ build_csnp (int level, u_char *start, u_char *stop, struct list *lsps, retval = tlv_add_authinfo (passwd->type, passwd->len, passwd->passwd, circuit->snd_stream); - if (!retval && lsps) { - retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); - } - length = (u_int16_t)stream_get_putp (circuit->snd_stream); + if (!retval && lsps) + { + retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); + } + length = (u_int16_t) stream_get_putp (circuit->snd_stream); assert (length >= ISIS_CSNP_HDRLEN); /* Update PU length */ stream_putw_at (circuit->snd_stream, lenp, length); @@ -1987,41 +2189,44 @@ send_csnp (struct isis_circuit *circuit, int level) struct listnode *node; struct isis_lsp *lsp; - memset (start,0x00, ISIS_SYS_ID_LEN + 2); + memset (start, 0x00, ISIS_SYS_ID_LEN + 2); memset (stop, 0xff, ISIS_SYS_ID_LEN + 2); - if (circuit->area->lspdb[level-1] && - dict_count (circuit->area->lspdb[level-1]) > 0) { - list = list_new (); - lsp_build_list (start, stop, list, circuit->area->lspdb[level-1]); - - if (circuit->snd_stream == NULL) - circuit->snd_stream = stream_new (ISO_MTU(circuit)); - else - stream_reset (circuit->snd_stream); - - retval = build_csnp (level, start, stop, list, circuit); - - if (isis->debugs & DEBUG_SNP_PACKETS) { - zlog_info ("ISIS-Snp (%s): Sent L%d CSNP on %s, length %ld", - circuit->area->area_tag, level, circuit->interface->name, - STREAM_SIZE(circuit->snd_stream)); - LIST_LOOP (list, lsp, node) { - zlog_info("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 (circuit->area->lspdb[level - 1] && + dict_count (circuit->area->lspdb[level - 1]) > 0) + { + list = list_new (); + lsp_build_list (start, stop, list, circuit->area->lspdb[level - 1]); + + if (circuit->snd_stream == NULL) + circuit->snd_stream = stream_new (ISO_MTU (circuit)); + else + stream_reset (circuit->snd_stream); + + retval = build_csnp (level, start, stop, list, circuit); + + if (isis->debugs & DEBUG_SNP_PACKETS) + { + zlog_info ("ISIS-Snp (%s): Sent L%d CSNP on %s, length %ld", + circuit->area->area_tag, level, circuit->interface->name, + STREAM_SIZE (circuit->snd_stream)); + LIST_LOOP (list, lsp, node) + { + zlog_info ("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)); + } + } - list_delete (list); + list_delete (list); - if (retval == ISIS_OK) - retval = circuit->tx (circuit, level); - } + if (retval == ISIS_OK) + retval = circuit->tx (circuit, level); + } return retval; } @@ -2036,12 +2241,13 @@ send_l1_csnp (struct thread *thread) circuit->t_send_csnp[0] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[0]) { - send_csnp(circuit,1); - } + if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[0]) + { + send_csnp (circuit, 1); + } /* set next timer thread */ - THREAD_TIMER_ON(master, circuit->t_send_csnp[0], send_l1_csnp, circuit, - isis_jitter(circuit->csnp_interval[0], CSNP_JITTER)); + THREAD_TIMER_ON (master, circuit->t_send_csnp[0], send_l1_csnp, circuit, + isis_jitter (circuit->csnp_interval[0], CSNP_JITTER)); return retval; } @@ -2057,12 +2263,13 @@ send_l2_csnp (struct thread *thread) circuit->t_send_csnp[1] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[1]) { - send_csnp(circuit,2); - } + if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[1]) + { + send_csnp (circuit, 2); + } /* set next timer thread */ - THREAD_TIMER_ON(master, circuit->t_send_csnp[1], send_l2_csnp, circuit, - isis_jitter(circuit->csnp_interval[1], CSNP_JITTER)); + THREAD_TIMER_ON (master, circuit->t_send_csnp[1], send_l2_csnp, circuit, + isis_jitter (circuit->csnp_interval[1], CSNP_JITTER)); return retval; } @@ -2079,17 +2286,17 @@ build_psnp (int level, struct isis_circuit *circuit, struct list *lsps) struct listnode *node; if (level == 1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, - circuit->snd_stream); + 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); + circuit->snd_stream); /* * Fill Level 1 or 2 Partial Sequence Numbers header */ lenp = stream_get_putp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */ + 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); @@ -2106,23 +2313,26 @@ build_psnp (int level, struct isis_circuit *circuit, struct list *lsps) retval = tlv_add_authinfo (passwd->type, passwd->len, passwd->passwd, circuit->snd_stream); - if (!retval && lsps) { - retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); - } + if (!retval && lsps) + { + retval = tlv_add_lsp_entries (lsps, circuit->snd_stream); + } - if (isis->debugs & DEBUG_SNP_PACKETS) { - LIST_LOOP (lsps, lsp, node) { - zlog_info("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)); + if (isis->debugs & DEBUG_SNP_PACKETS) + { + LIST_LOOP (lsps, lsp, node) + { + zlog_info ("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)); + } } - } - length = (u_int16_t)stream_get_putp (circuit->snd_stream); + length = (u_int16_t) stream_get_putp (circuit->snd_stream); assert (length >= ISIS_PSNP_HDRLEN); /* Update PDU length */ stream_putw_at (circuit->snd_stream, lenp, length); @@ -2142,45 +2352,51 @@ send_psnp (int level, struct isis_circuit *circuit) struct list *list = NULL; struct listnode *node; - if ((circuit->circ_type == CIRCUIT_T_BROADCAST && + if ((circuit->circ_type == CIRCUIT_T_BROADCAST && !circuit->u.bc.is_dr[level - 1]) || - circuit->circ_type != CIRCUIT_T_BROADCAST) { + circuit->circ_type != CIRCUIT_T_BROADCAST) + { - if (circuit->area->lspdb[level-1] && - dict_count (circuit->area->lspdb[level-1]) > 0) { - list = list_new (); - lsp_build_list_ssn (circuit, list, circuit->area->lspdb[level-1]); - - if (listcount(list) > 0) { - if (circuit->snd_stream == NULL) - circuit->snd_stream = stream_new (ISO_MTU(circuit)); - else - stream_reset (circuit->snd_stream); - - - if (isis->debugs & DEBUG_SNP_PACKETS) - zlog_info ("ISIS-Snp (%s): Sent L%d PSNP on %s, length %ld", - circuit->area->area_tag, level, circuit->interface->name, - STREAM_SIZE(circuit->snd_stream)); - - retval = build_psnp (level, circuit, list); - if (retval == ISIS_OK) - retval = circuit->tx (circuit, level); - - if (retval == ISIS_OK) { - /* - * sending succeeded, we can clear SSN flags of this circuit - * for the LSPs in list - */ - for (node = listhead (list); node; nextnode(node)) { - lsp = getdata (node); - ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); - } - } - } - list_delete (list); + if (circuit->area->lspdb[level - 1] && + dict_count (circuit->area->lspdb[level - 1]) > 0) + { + list = list_new (); + lsp_build_list_ssn (circuit, list, circuit->area->lspdb[level - 1]); + + if (listcount (list) > 0) + { + if (circuit->snd_stream == NULL) + circuit->snd_stream = stream_new (ISO_MTU (circuit)); + else + stream_reset (circuit->snd_stream); + + + if (isis->debugs & DEBUG_SNP_PACKETS) + zlog_info ("ISIS-Snp (%s): Sent L%d PSNP on %s, length %ld", + circuit->area->area_tag, level, + circuit->interface->name, + STREAM_SIZE (circuit->snd_stream)); + + retval = build_psnp (level, circuit, list); + if (retval == ISIS_OK) + retval = circuit->tx (circuit, level); + + if (retval == ISIS_OK) + { + /* + * sending succeeded, we can clear SSN flags of this circuit + * for the LSPs in list + */ + for (node = listhead (list); node; nextnode (node)) + { + lsp = getdata (node); + ISIS_CLEAR_FLAG (lsp->SSNflags, circuit); + } + } + } + list_delete (list); + } } - } return retval; } @@ -2199,8 +2415,8 @@ send_l1_psnp (struct thread *thread) send_psnp (1, circuit); /* set next timer thread */ - THREAD_TIMER_ON(master, circuit->t_send_psnp[0], send_l1_psnp, circuit, - isis_jitter(circuit->psnp_interval[0], PSNP_JITTER)); + THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit, + isis_jitter (circuit->psnp_interval[0], PSNP_JITTER)); return retval; } @@ -2212,7 +2428,6 @@ send_l1_psnp (struct thread *thread) int send_l2_psnp (struct thread *thread) { - struct isis_circuit *circuit; int retval = ISIS_OK; @@ -2224,26 +2439,24 @@ send_l2_psnp (struct thread *thread) send_psnp (2, circuit); /* set next timer thread */ - THREAD_TIMER_ON(master, circuit->t_send_psnp[1], send_l2_psnp, circuit, - isis_jitter(circuit->psnp_interval[1], PSNP_JITTER)); + THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit, + isis_jitter (circuit->psnp_interval[1], PSNP_JITTER)); return retval; } - void build_link_state (struct isis_lsp *lsp, struct isis_circuit *circuit, - struct stream *stream) + struct stream *stream) { unsigned long length; - stream_put (stream, lsp->pdu, ntohs(lsp->lsp_header->pdu_len)); - length = stream_get_putp (stream); + stream_put (stream, lsp->pdu, ntohs (lsp->lsp_header->pdu_len)); + length = stream_get_putp (stream); return; } - /* * ISO 10589 - 7.3.14.3 */ @@ -2258,90 +2471,98 @@ send_lsp (struct thread *thread) circuit = THREAD_ARG (thread); assert (circuit); - if (circuit->state == C_STATE_UP) { - node = listhead (circuit->lsp_queue); - assert (node); - - lsp = getdata (node); - - /* - * Do not send if levels do not match - */ - if (!(lsp->level & circuit->circuit_is_type)) - goto dontsend; - - /* - * Do not send if we do not have adjacencies in state up on the circuit - */ - if (circuit->upadjcount[lsp->level - 1] == 0) - goto dontsend; - /* only send if it needs sending */ - if ((time(NULL) - lsp->last_sent) >= - circuit->area->lsp_gen_interval[lsp->level-1]) { - - if (isis->debugs & DEBUG_UPDATE_PACKETS) { - zlog_info ("ISIS-Upd (%s): Sent 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); - } - /* copy our lsp to the send buffer */ - circuit->snd_stream->getp = lsp->pdu->getp; - circuit->snd_stream->putp = lsp->pdu->putp; - circuit->snd_stream->endp = lsp->pdu->endp; - memcpy (circuit->snd_stream->data, lsp->pdu->data, lsp->pdu->endp); + if (circuit->state == C_STATE_UP) + { + node = listhead (circuit->lsp_queue); + assert (node); - retval = circuit->tx (circuit, lsp->level); + lsp = getdata (node); /* - * If the sending succeeded, we can del the lsp from circuits lsp_queue + * Do not send if levels do not match */ - if (retval == ISIS_OK) { - list_delete_node (circuit->lsp_queue, node); + if (!(lsp->level & circuit->circuit_is_type)) + goto dontsend; - /* - * On broadcast circuits also the SRMflag can be cleared - */ - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); + /* + * Do not send if we do not have adjacencies in state up on the circuit + */ + if (circuit->upadjcount[lsp->level - 1] == 0) + goto dontsend; + /* only send if it needs sending */ + if ((time (NULL) - lsp->last_sent) >= + circuit->area->lsp_gen_interval[lsp->level - 1]) + { + + if (isis->debugs & DEBUG_UPDATE_PACKETS) + { + zlog_info + ("ISIS-Upd (%s): Sent 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); + } + /* copy our lsp to the send buffer */ + circuit->snd_stream->getp = lsp->pdu->getp; + circuit->snd_stream->putp = lsp->pdu->putp; + circuit->snd_stream->endp = lsp->pdu->endp; + memcpy (circuit->snd_stream->data, lsp->pdu->data, lsp->pdu->endp); + + retval = circuit->tx (circuit, lsp->level); - if (flags_any_set (lsp->SRMflags) == 0) { /* - * need to remember when we were last sent + * If the sending succeeded, we can del the lsp from circuits + * lsp_queue */ - lsp->last_sent = time (NULL); + if (retval == ISIS_OK) + { + list_delete_node (circuit->lsp_queue, node); + + /* + * On broadcast circuits also the SRMflag can be cleared + */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); + + if (flags_any_set (lsp->SRMflags) == 0) + { + /* + * need to remember when we were last sent + */ + lsp->last_sent = time (NULL); + } + } + else + { + zlog_info ("sending of level %d link state failed", lsp->level); + } + } + else + { + /* my belief is that if it wasn't his time, the lsp can be removed + * from the queue + */ + dontsend: + list_delete_node (circuit->lsp_queue, node); } - } else { - zlog_info ("sending of level %d link state failed", lsp->level); - } - } else { - /* my belief is that if it wasn't his time, the lsp can be removed - * from the queue - */ - dontsend: - list_delete_node (circuit->lsp_queue, node); - } #if 0 - /* - * If there are still LSPs send next one after lsp-interval (33 msecs) - */ - if (listcount (circuit->lsp_queue) > 0) - thread_add_timer (master, send_lsp, circuit, - 1); + /* + * If there are still LSPs send next one after lsp-interval (33 msecs) + */ + if (listcount (circuit->lsp_queue) > 0) + thread_add_timer (master, send_lsp, circuit, 1); #endif - } + } return retval; -} +} int -ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, - int level) +ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, + int level) { unsigned long lenp; int retval; @@ -2349,32 +2570,32 @@ ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, struct isis_fixed_hdr fixed_hdr; if (!circuit->snd_stream) - circuit->snd_stream = stream_new (ISO_MTU(circuit)); + circuit->snd_stream = stream_new (ISO_MTU (circuit)); else stream_reset (circuit->snd_stream); // fill_llc_hdr (stream); if (level == 1) - fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, - circuit->snd_stream); + 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_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM, + circuit->snd_stream); lenp = stream_get_putp (circuit->snd_stream); - stream_putw (circuit->snd_stream, 0); /* PDU length */ - stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN); + 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_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)); + 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_putp (circuit->snd_stream); + length = (u_int16_t) stream_get_putp (circuit->snd_stream); /* Update PDU length */ stream_putw_at (circuit->snd_stream, lenp, length); @@ -2388,67 +2609,86 @@ ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, * ISH PDU Processing */ - /* * Let's first check if the local and remote system have any common area * addresses */ - if (area_match(tlvs.area_addrs, isis->man_area_addrs) == 0) { - if (circuit->circuit_t == IS_LEVEL_2) { - /* do as in table 8 (p. 40) */ - switch (circuit_type) { - case IS_LEVEL_1: - if (adj->adj_state != ISIS_ADJ_UP) { - /* Reject */ - zlog_warn("areaMismatch"); - retval = ISIS_WARNING; - } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch", - circuit->adjdb); - } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2 || - adj->adj_usage == ISIS_ADJ_LEVEL2) { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", - circuit->adjdb); - } - break; - case IS_LEVEL_2: - if (adj->adj_state != ISIS_ADJ_UP) { - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, circuit->adjdb); - adj->adj_usage = ISIS_ADJ_LEVEL2; - } else if (adj->adj_usage == ISIS_ADJ_LEVEL1 || - adj->adj_usage == ISIS_ADJ_LEVEL1AND2) { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", - circuit->adjdb); - } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) { - ; /* Accept */ - } - break; - case IS_LEVEL_1_AND_2: - if (adj->adj_state != ISIS_ADJ_UP) { - isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, circuit->adjdb); - adj->adj_usage = ISIS_ADJ_LEVEL2; - } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", - circuit->adjdb); - } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) { - isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch", - circuit->adjdb); - } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) { - ; /* Accept */ - } - break; +if (area_match (tlvs.area_addrs, isis->man_area_addrs) == 0) + { + if (circuit->circuit_t == IS_LEVEL_2) + { + /* do as in table 8 (p. 40) */ + switch (circuit_type) + { + case IS_LEVEL_1: + if (adj->adj_state != ISIS_ADJ_UP) + { + /* Reject */ + zlog_warn ("areaMismatch"); + retval = ISIS_WARNING; + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL1) + { + isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch", + circuit->adjdb); + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2 || + adj->adj_usage == ISIS_ADJ_LEVEL2) + { + isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", + circuit->adjdb); + } + break; + case IS_LEVEL_2: + if (adj->adj_state != ISIS_ADJ_UP) + { + isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, + circuit->adjdb); + adj->adj_usage = ISIS_ADJ_LEVEL2; + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL1 || + adj->adj_usage == ISIS_ADJ_LEVEL1AND2) + { + isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", + circuit->adjdb); + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL2) + { + ; /* Accept */ + } + break; + case IS_LEVEL_1_AND_2: + if (adj->adj_state != ISIS_ADJ_UP) + { + isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, + circuit->adjdb); + adj->adj_usage = ISIS_ADJ_LEVEL2; + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL1) + { + isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System", + circuit->adjdb); + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) + { + isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch", + circuit->adjdb); + } + else if (adj->adj_usage == ISIS_ADJ_LEVEL2) + { + ; /* Accept */ + } + break; + } + goto mismatch; + } + else + { + isis_delete_adj (adj, circuit->adjdb); + zlog_warn ("areaMismatch"); + return ISIS_WARNING; } - goto mismatch; - } else { - isis_delete_adj (adj, circuit->adjdb); - zlog_warn("areaMismatch"); - return ISIS_WARNING; - } } mismatch: #endif - - - - -- cgit v1.2.1