diff options
| author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
|---|---|---|
| committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
| commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
| tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /eigrpd/eigrp_hello.c | |
| parent | 888ac268a0077fc9ebd1218cec6ae472af0bfc40 (diff) | |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'eigrpd/eigrp_hello.c')
| -rw-r--r-- | eigrpd/eigrp_hello.c | 944 |
1 files changed, 469 insertions, 475 deletions
diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index 8750cf2dcd..b7c2f7f18d 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -56,25 +56,23 @@ #include "eigrpd/eigrp_macros.h" /* Packet Type String. */ -static const struct message eigrp_general_tlv_type_str[] = -{ - { EIGRP_TLV_PARAMETER, "PARAMETER" }, - { EIGRP_TLV_AUTH, "AUTH" }, - { EIGRP_TLV_SEQ, "SEQ" }, - { EIGRP_TLV_SW_VERSION, "SW_VERSION" }, - { EIGRP_TLV_NEXT_MCAST_SEQ, "NEXT_MCAST_SEQ" }, - { EIGRP_TLV_PEER_TERMINATION, "PEER_TERMINATION" }, - { EIGRP_TLV_PEER_MTRLIST, "PEER_MTRLIST" }, - { EIGRP_TLV_PEER_TIDLIST, "PEER_TIDLIST" }, - { 0 } -}; +static const struct message eigrp_general_tlv_type_str[] = { + {EIGRP_TLV_PARAMETER, "PARAMETER"}, + {EIGRP_TLV_AUTH, "AUTH"}, + {EIGRP_TLV_SEQ, "SEQ"}, + {EIGRP_TLV_SW_VERSION, "SW_VERSION"}, + {EIGRP_TLV_NEXT_MCAST_SEQ, "NEXT_MCAST_SEQ"}, + {EIGRP_TLV_PEER_TERMINATION, "PEER_TERMINATION"}, + {EIGRP_TLV_PEER_MTRLIST, "PEER_MTRLIST"}, + {EIGRP_TLV_PEER_TIDLIST, "PEER_TIDLIST"}, + {0}}; /* * @fn eigrp_hello_timer * * @param[in] thread current execution thread timer is associated with - * + * * @return int always returns 0 * * @par @@ -82,27 +80,26 @@ static const struct message eigrp_general_tlv_type_str[] = * Sends hello packet via multicast for all interfaces eigrp * is configured for */ -int -eigrp_hello_timer (struct thread *thread) +int eigrp_hello_timer(struct thread *thread) { - struct eigrp_interface *ei; + struct eigrp_interface *ei; - ei = THREAD_ARG(thread); - ei->t_hello = NULL; + ei = THREAD_ARG(thread); + ei->t_hello = NULL; - if (IS_DEBUG_EIGRP(0, TIMERS)) - zlog_debug ("Start Hello Timer (%s) Expire [%u]", - IF_NAME(ei), EIGRP_IF_PARAM(ei, v_hello)); + if (IS_DEBUG_EIGRP(0, TIMERS)) + zlog_debug("Start Hello Timer (%s) Expire [%u]", IF_NAME(ei), + EIGRP_IF_PARAM(ei, v_hello)); - /* Sending hello packet. */ - eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL); + /* Sending hello packet. */ + eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL); - /* Hello timer set. */ - ei->t_hello = NULL; - thread_add_timer(master, eigrp_hello_timer, ei, EIGRP_IF_PARAM(ei, v_hello), - &ei->t_hello); + /* Hello timer set. */ + ei->t_hello = NULL; + thread_add_timer(master, eigrp_hello_timer, ei, + EIGRP_IF_PARAM(ei, v_hello), &ei->t_hello); - return 0; + return 0; } /** @@ -121,84 +118,89 @@ eigrp_hello_timer (struct thread *thread) * older TLV packet formats. */ static struct eigrp_neighbor * -eigrp_hello_parameter_decode (struct eigrp_neighbor *nbr, - struct eigrp_tlv_hdr_type *tlv) +eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr, + struct eigrp_tlv_hdr_type *tlv) { - struct eigrp *eigrp = nbr->ei->eigrp; - struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv; - - /* copy over the values passed in by the neighbor */ - nbr->K1 = param->K1; - nbr->K2 = param->K2; - nbr->K3 = param->K3; - nbr->K4 = param->K4; - nbr->K5 = param->K5; - nbr->K6 = param->K6; - nbr->v_holddown = ntohs(param->hold_time); - - /* - * Check K1-K5 have the correct values to be able to become neighbors - * K6 does not have to match - */ - if ((eigrp->k_values[0] == nbr->K1) && - (eigrp->k_values[1] == nbr->K2) && - (eigrp->k_values[2] == nbr->K3) && - (eigrp->k_values[3] == nbr->K4) && - (eigrp->k_values[4] == nbr->K5)) - { - - if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN) - { - zlog_info("Neighbor %s (%s) is pending: new adjacency", - inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT)); - - /* Expedited hello sent */ - eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL); - - // if(ntohl(nbr->ei->address->u.prefix4.s_addr) > ntohl(nbr->src.s_addr)) - eigrp_update_send_init(nbr); - - eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING); - } - } - else - { - if (eigrp_nbr_state_get(nbr) != EIGRP_NEIGHBOR_DOWN) - { - if ((param->K1 & param->K2 & param->K3 & param->K4 & param->K5) == 255) - { - zlog_info ("Neighbor %s (%s) is down: Interface PEER-TERMINATION received", - inet_ntoa (nbr->src),ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT)); - eigrp_nbr_delete (nbr); - return NULL; - } - else - { - zlog_info ("Neighbor %s (%s) going down: Kvalue mismatch", - inet_ntoa (nbr->src),ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT)); - eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); - } - } - } - - return nbr; + struct eigrp *eigrp = nbr->ei->eigrp; + struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv; + + /* copy over the values passed in by the neighbor */ + nbr->K1 = param->K1; + nbr->K2 = param->K2; + nbr->K3 = param->K3; + nbr->K4 = param->K4; + nbr->K5 = param->K5; + nbr->K6 = param->K6; + nbr->v_holddown = ntohs(param->hold_time); + + /* + * Check K1-K5 have the correct values to be able to become neighbors + * K6 does not have to match + */ + if ((eigrp->k_values[0] == nbr->K1) && (eigrp->k_values[1] == nbr->K2) + && (eigrp->k_values[2] == nbr->K3) + && (eigrp->k_values[3] == nbr->K4) + && (eigrp->k_values[4] == nbr->K5)) { + + if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN) { + zlog_info("Neighbor %s (%s) is pending: new adjacency", + inet_ntoa(nbr->src), + ifindex2ifname(nbr->ei->ifp->ifindex, + VRF_DEFAULT)); + + /* Expedited hello sent */ + eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL); + + // if(ntohl(nbr->ei->address->u.prefix4.s_addr) > + // ntohl(nbr->src.s_addr)) + eigrp_update_send_init(nbr); + + eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING); + } + } else { + if (eigrp_nbr_state_get(nbr) != EIGRP_NEIGHBOR_DOWN) { + if ((param->K1 & param->K2 & param->K3 & param->K4 + & param->K5) + == 255) { + zlog_info( + "Neighbor %s (%s) is down: Interface PEER-TERMINATION received", + inet_ntoa(nbr->src), + ifindex2ifname(nbr->ei->ifp->ifindex, + VRF_DEFAULT)); + eigrp_nbr_delete(nbr); + return NULL; + } else { + zlog_info( + "Neighbor %s (%s) going down: Kvalue mismatch", + inet_ntoa(nbr->src), + ifindex2ifname(nbr->ei->ifp->ifindex, + VRF_DEFAULT)); + eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); + } + } + } + + return nbr; } static u_char -eigrp_hello_authentication_decode(struct stream *s, struct eigrp_tlv_hdr_type *tlv_header, - struct eigrp_neighbor *nbr) +eigrp_hello_authentication_decode(struct stream *s, + struct eigrp_tlv_hdr_type *tlv_header, + struct eigrp_neighbor *nbr) { - struct TLV_MD5_Authentication_Type *md5; + struct TLV_MD5_Authentication_Type *md5; - md5 = (struct TLV_MD5_Authentication_Type *) tlv_header; + md5 = (struct TLV_MD5_Authentication_Type *)tlv_header; - if(md5->auth_type == EIGRP_AUTH_TYPE_MD5) - return eigrp_check_md5_digest(s, md5, nbr, EIGRP_AUTH_BASIC_HELLO_FLAG); - else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256) - return eigrp_check_sha256_digest(s, (struct TLV_SHA256_Authentication_Type *)tlv_header, - nbr, EIGRP_AUTH_BASIC_HELLO_FLAG); + if (md5->auth_type == EIGRP_AUTH_TYPE_MD5) + return eigrp_check_md5_digest(s, md5, nbr, + EIGRP_AUTH_BASIC_HELLO_FLAG); + else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256) + return eigrp_check_sha256_digest( + s, (struct TLV_SHA256_Authentication_Type *)tlv_header, + nbr, EIGRP_AUTH_BASIC_HELLO_FLAG); - return 0; + return 0; } /** @@ -214,17 +216,16 @@ eigrp_hello_authentication_decode(struct stream *s, struct eigrp_tlv_hdr_type *t * This consists of two bytes of OS version, and two bytes of EIGRP * revision number. */ -static void -eigrp_sw_version_decode (struct eigrp_neighbor *nbr, - struct eigrp_tlv_hdr_type *tlv) +static void eigrp_sw_version_decode(struct eigrp_neighbor *nbr, + struct eigrp_tlv_hdr_type *tlv) { - struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv; + struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv; - nbr->os_rel_major = version->vender_major; - nbr->os_rel_minor = version->vender_minor; - nbr->tlv_rel_major = version->eigrp_major; - nbr->tlv_rel_minor = version->eigrp_minor; - return; + nbr->os_rel_major = version->vender_major; + nbr->os_rel_minor = version->vender_minor; + nbr->tlv_rel_major = version->eigrp_major; + nbr->tlv_rel_minor = version->eigrp_minor; + return; } /** @@ -240,54 +241,54 @@ eigrp_sw_version_decode (struct eigrp_neighbor *nbr, * a match is found, move the sending neighbor to the down state. If * out address is not in the TLV, then ignore the peer termination */ -static void -eigrp_peer_termination_decode (struct eigrp_neighbor *nbr, - struct eigrp_tlv_hdr_type *tlv) +static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr, + struct eigrp_tlv_hdr_type *tlv) { - struct TLV_Peer_Termination_type *param = (struct TLV_Peer_Termination_type *)tlv; - - uint32_t my_ip = nbr->ei->address->u.prefix4.s_addr; - uint32_t received_ip = param->neighbor_ip; - - if(my_ip == received_ip) - { - zlog_info ("Neighbor %s (%s) is down: Peer Termination received", - inet_ntoa (nbr->src), - ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT)); - /* set neighbor to DOWN */ - nbr->state = EIGRP_NEIGHBOR_DOWN; - /* delete neighbor */ - eigrp_nbr_delete (nbr); - } + struct TLV_Peer_Termination_type *param = + (struct TLV_Peer_Termination_type *)tlv; + + uint32_t my_ip = nbr->ei->address->u.prefix4.s_addr; + uint32_t received_ip = param->neighbor_ip; + + if (my_ip == received_ip) { + zlog_info("Neighbor %s (%s) is down: Peer Termination received", + inet_ntoa(nbr->src), + ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT)); + /* set neighbor to DOWN */ + nbr->state = EIGRP_NEIGHBOR_DOWN; + /* delete neighbor */ + eigrp_nbr_delete(nbr); + } } /** * @fn eigrp_peer_termination_encode * * @param[in,out] s packet stream TLV is stored to - * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV + * @param[in] nbr_addr pointer to neighbor address for Peer + * Termination TLV * * @return u_int16_t number of bytes added to packet stream * * @par * Function used to encode Peer Termination TLV to Hello packet. */ -static u_int16_t -eigrp_peer_termination_encode (struct stream *s, struct in_addr *nbr_addr) +static u_int16_t eigrp_peer_termination_encode(struct stream *s, + struct in_addr *nbr_addr) { - u_int16_t length = EIGRP_TLV_PEER_TERMINATION_LEN; + u_int16_t length = EIGRP_TLV_PEER_TERMINATION_LEN; - /* fill in type and length */ - stream_putw(s, EIGRP_TLV_PEER_TERMINATION); - stream_putw(s, length); + /* fill in type and length */ + stream_putw(s, EIGRP_TLV_PEER_TERMINATION); + stream_putw(s, length); - /* fill in unknown field 0x04 */ - stream_putc(s, 0x04); + /* fill in unknown field 0x04 */ + stream_putc(s, 0x04); - /* finally neighbor IP address */ - stream_put_ipv4(s, nbr_addr->s_addr); + /* finally neighbor IP address */ + stream_put_ipv4(s, nbr_addr->s_addr); - return(length); + return (length); } /* @@ -307,98 +308,101 @@ eigrp_peer_termination_encode (struct stream *s, struct in_addr *nbr_addr) * will validate the peer associated with the src ip address of the ip * header, and then decode each of the general TLVs which the packet * may contain. - * + * * @usage * Not all TLVs are current decoder. This is a work in progress.. */ -void -eigrp_hello_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph, - struct stream *s, struct eigrp_interface *ei, int size) +void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, struct stream *s, + struct eigrp_interface *ei, int size) { - struct eigrp_tlv_hdr_type *tlv_header; - struct eigrp_neighbor *nbr; - uint16_t type; - uint16_t length; - - /* get neighbor struct */ - nbr = eigrp_nbr_get(ei, eigrph, iph); - - /* neighbor must be valid, eigrp_nbr_get creates if none existed */ - assert(nbr); - - if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV)) - zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)", - size, ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT), - inet_ntoa(nbr->src)); - - size -= EIGRP_HEADER_LEN; - if (size < 0) - return; - - tlv_header = (struct eigrp_tlv_hdr_type *)eigrph->tlv; - - do { - type = ntohs(tlv_header->type); - length = ntohs(tlv_header->length); - - if ((length > 0) && (length <= size)) - { - if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug(" General TLV(%s)", lookup_msg(eigrp_general_tlv_type_str, type, NULL)); - - // determine what General TLV is being processed - switch (type) - { - case EIGRP_TLV_PARAMETER: - nbr = eigrp_hello_parameter_decode(nbr, tlv_header); - if (!nbr) - return; - break; - case EIGRP_TLV_AUTH: - { - if(eigrp_hello_authentication_decode(s,tlv_header,nbr) == 0) - return; - else - break; - break; - } - case EIGRP_TLV_SEQ: - break; - case EIGRP_TLV_SW_VERSION: - eigrp_sw_version_decode(nbr, tlv_header); - break; - case EIGRP_TLV_NEXT_MCAST_SEQ: - break; - case EIGRP_TLV_PEER_TERMINATION: - eigrp_peer_termination_decode(nbr, tlv_header); - return; - break; - case EIGRP_TLV_PEER_MTRLIST: - case EIGRP_TLV_PEER_TIDLIST: - break; - default: - break; - } - } - - tlv_header = (struct eigrp_tlv_hdr_type *)(((char *)tlv_header) + length); - size -= length; - - } while (size > 0); - - - /*If received packet is hello with Parameter TLV*/ - if (ntohl(eigrph->ack) == 0) - { - /* increment statistics. */ - ei->hello_in++; - if (nbr) - eigrp_nbr_state_update(nbr); - - } - - if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug("Hello Packet received from %s", inet_ntoa(nbr->src)); + struct eigrp_tlv_hdr_type *tlv_header; + struct eigrp_neighbor *nbr; + uint16_t type; + uint16_t length; + + /* get neighbor struct */ + nbr = eigrp_nbr_get(ei, eigrph, iph); + + /* neighbor must be valid, eigrp_nbr_get creates if none existed */ + assert(nbr); + + if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV)) + zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)", size, + ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT), + inet_ntoa(nbr->src)); + + size -= EIGRP_HEADER_LEN; + if (size < 0) + return; + + tlv_header = (struct eigrp_tlv_hdr_type *)eigrph->tlv; + + do { + type = ntohs(tlv_header->type); + length = ntohs(tlv_header->length); + + if ((length > 0) && (length <= size)) { + if (IS_DEBUG_EIGRP_PACKET(0, RECV)) + zlog_debug( + " General TLV(%s)", + lookup_msg(eigrp_general_tlv_type_str, + type, NULL)); + + // determine what General TLV is being processed + switch (type) { + case EIGRP_TLV_PARAMETER: + nbr = eigrp_hello_parameter_decode(nbr, + tlv_header); + if (!nbr) + return; + break; + case EIGRP_TLV_AUTH: { + if (eigrp_hello_authentication_decode( + s, tlv_header, nbr) + == 0) + return; + else + break; + break; + } + case EIGRP_TLV_SEQ: + break; + case EIGRP_TLV_SW_VERSION: + eigrp_sw_version_decode(nbr, tlv_header); + break; + case EIGRP_TLV_NEXT_MCAST_SEQ: + break; + case EIGRP_TLV_PEER_TERMINATION: + eigrp_peer_termination_decode(nbr, tlv_header); + return; + break; + case EIGRP_TLV_PEER_MTRLIST: + case EIGRP_TLV_PEER_TIDLIST: + break; + default: + break; + } + } + + tlv_header = (struct eigrp_tlv_hdr_type *)(((char *)tlv_header) + + length); + size -= length; + + } while (size > 0); + + + /*If received packet is hello with Parameter TLV*/ + if (ntohl(eigrph->ack) == 0) { + /* increment statistics. */ + ei->hello_in++; + if (nbr) + eigrp_nbr_state_update(nbr); + } + + if (IS_DEBUG_EIGRP_PACKET(0, RECV)) + zlog_debug("Hello Packet received from %s", + inet_ntoa(nbr->src)); } /** @@ -413,25 +417,24 @@ eigrp_hello_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *e * This consists of two bytes of OS version, and two bytes of EIGRP * revision number. */ -static u_int16_t -eigrp_sw_version_encode (struct stream *s) +static u_int16_t eigrp_sw_version_encode(struct stream *s) { - u_int16_t length = EIGRP_TLV_SW_VERSION_LEN; + u_int16_t length = EIGRP_TLV_SW_VERSION_LEN; - // setup the tlv fields - stream_putw(s, EIGRP_TLV_SW_VERSION); - stream_putw(s, length); + // setup the tlv fields + stream_putw(s, EIGRP_TLV_SW_VERSION); + stream_putw(s, length); - // encode the version of quagga we're running - // DVS: need to figure out a cleaner way to do this - stream_putc(s, 0); //!< major os version - stream_putc(s, 99); //!< minor os version + // encode the version of quagga we're running + // DVS: need to figure out a cleaner way to do this + stream_putc(s, 0); //!< major os version + stream_putc(s, 99); //!< minor os version - /* and the core eigrp version */ - stream_putc(s, EIGRP_MAJOR_VERSION); - stream_putc(s, EIGRP_MINOR_VERSION); + /* and the core eigrp version */ + stream_putc(s, EIGRP_MAJOR_VERSION); + stream_putc(s, EIGRP_MINOR_VERSION); - return(length); + return (length); } /** @@ -445,11 +448,10 @@ eigrp_sw_version_encode (struct stream *s) * If doing mutli-topology, then store the supported TID list. * This is currently a place holder function */ -static u_int16_t -eigrp_tidlist_encode (struct stream *s) +static u_int16_t eigrp_tidlist_encode(struct stream *s) { - //u_int16_t length = EIGRP_TLV_SW_VERSION_LEN; - return 0; + // u_int16_t length = EIGRP_TLV_SW_VERSION_LEN; + return 0; } /** @@ -463,55 +465,50 @@ eigrp_tidlist_encode (struct stream *s) * Part of conditional receive process * */ -static u_int16_t -eigrp_sequence_encode (struct stream *s) +static u_int16_t eigrp_sequence_encode(struct stream *s) { - u_int16_t length = EIGRP_TLV_SEQ_BASE_LEN; - struct eigrp *eigrp; - struct eigrp_interface *ei; - struct listnode *node, *node2, *nnode2; - struct eigrp_neighbor *nbr; - size_t backup_end, size_end; - int found; - - eigrp = eigrp_lookup (); - if (eigrp == NULL) - { - return 0; - } - - // add in the parameters TLV - backup_end = stream_get_endp(s); - stream_putw(s, EIGRP_TLV_SEQ); - size_end = s->endp; - stream_putw(s, 0x0000); - stream_putc(s, IPV4_MAX_BYTELEN); - - found = 0; - for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei)) - { - for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr)) - { - if(nbr->multicast_queue->count > 0) - { - length += (u_int16_t) stream_put_ipv4(s,nbr->src.s_addr); - found = 1; - } - } - } - - if(found == 0) - { - stream_set_endp(s,backup_end); - return 0; - } - - backup_end = stream_get_endp (s); - stream_set_endp (s,size_end); - stream_putw (s, length); - stream_set_endp (s, backup_end); - - return length; + u_int16_t length = EIGRP_TLV_SEQ_BASE_LEN; + struct eigrp *eigrp; + struct eigrp_interface *ei; + struct listnode *node, *node2, *nnode2; + struct eigrp_neighbor *nbr; + size_t backup_end, size_end; + int found; + + eigrp = eigrp_lookup(); + if (eigrp == NULL) { + return 0; + } + + // add in the parameters TLV + backup_end = stream_get_endp(s); + stream_putw(s, EIGRP_TLV_SEQ); + size_end = s->endp; + stream_putw(s, 0x0000); + stream_putc(s, IPV4_MAX_BYTELEN); + + found = 0; + for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + if (nbr->multicast_queue->count > 0) { + length += (u_int16_t)stream_put_ipv4( + s, nbr->src.s_addr); + found = 1; + } + } + } + + if (found == 0) { + stream_set_endp(s, backup_end); + return 0; + } + + backup_end = stream_get_endp(s); + stream_set_endp(s, size_end); + stream_putw(s, length); + stream_set_endp(s, backup_end); + + return length; } /** @@ -525,24 +522,22 @@ eigrp_sequence_encode (struct stream *s) * Part of conditional receive process * */ -static u_int16_t -eigrp_next_sequence_encode (struct stream *s) +static u_int16_t eigrp_next_sequence_encode(struct stream *s) { - u_int16_t length = EIGRP_NEXT_SEQUENCE_TLV_SIZE; - struct eigrp *eigrp; + u_int16_t length = EIGRP_NEXT_SEQUENCE_TLV_SIZE; + struct eigrp *eigrp; - eigrp = eigrp_lookup (); - if (eigrp == NULL) - { - return 0; - } + eigrp = eigrp_lookup(); + if (eigrp == NULL) { + return 0; + } - // add in the parameters TLV - stream_putw(s, EIGRP_TLV_NEXT_MCAST_SEQ); - stream_putw(s, EIGRP_NEXT_SEQUENCE_TLV_SIZE); - stream_putl(s,eigrp->sequence_number+1); + // add in the parameters TLV + stream_putw(s, EIGRP_TLV_NEXT_MCAST_SEQ); + stream_putw(s, EIGRP_NEXT_SEQUENCE_TLV_SIZE); + stream_putl(s, eigrp->sequence_number + 1); - return length; + return length; } /** @@ -560,39 +555,38 @@ eigrp_next_sequence_encode (struct stream *s) * Note the addition of K6 for the new extended metrics, and does not apply to * older TLV packet formats. */ -static u_int16_t -eigrp_hello_parameter_encode (struct eigrp_interface *ei, struct stream *s, u_char flags) +static u_int16_t eigrp_hello_parameter_encode(struct eigrp_interface *ei, + struct stream *s, u_char flags) { - u_int16_t length = EIGRP_TLV_PARAMETER_LEN; - - // add in the parameters TLV - stream_putw(s, EIGRP_TLV_PARAMETER); - stream_putw(s, EIGRP_TLV_PARAMETER_LEN); - - //if graceful shutdown is needed to be announced, send all 255 in K values - if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) - { - stream_putc(s, 0xff); /* K1 */ - stream_putc(s, 0xff); /* K2 */ - stream_putc(s, 0xff); /* K3 */ - stream_putc(s, 0xff); /* K4 */ - stream_putc(s, 0xff); /* K5 */ - stream_putc(s, 0xff); /* K6 */ - } - else // set k values - { - stream_putc(s, ei->eigrp->k_values[0]); /* K1 */ - stream_putc(s, ei->eigrp->k_values[1]); /* K2 */ - stream_putc(s, ei->eigrp->k_values[2]); /* K3 */ - stream_putc(s, ei->eigrp->k_values[3]); /* K4 */ - stream_putc(s, ei->eigrp->k_values[4]); /* K5 */ - stream_putc(s, ei->eigrp->k_values[5]); /* K6 */ - } - - // and set hold time value.. - stream_putw(s, IF_DEF_PARAMS(ei->ifp)->v_wait); - - return length; + u_int16_t length = EIGRP_TLV_PARAMETER_LEN; + + // add in the parameters TLV + stream_putw(s, EIGRP_TLV_PARAMETER); + stream_putw(s, EIGRP_TLV_PARAMETER_LEN); + + // if graceful shutdown is needed to be announced, send all 255 in K + // values + if (flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) { + stream_putc(s, 0xff); /* K1 */ + stream_putc(s, 0xff); /* K2 */ + stream_putc(s, 0xff); /* K3 */ + stream_putc(s, 0xff); /* K4 */ + stream_putc(s, 0xff); /* K5 */ + stream_putc(s, 0xff); /* K6 */ + } else // set k values + { + stream_putc(s, ei->eigrp->k_values[0]); /* K1 */ + stream_putc(s, ei->eigrp->k_values[1]); /* K2 */ + stream_putc(s, ei->eigrp->k_values[2]); /* K3 */ + stream_putc(s, ei->eigrp->k_values[3]); /* K4 */ + stream_putc(s, ei->eigrp->k_values[4]); /* K5 */ + stream_putc(s, ei->eigrp->k_values[5]); /* K6 */ + } + + // and set hold time value.. + stream_putw(s, IF_DEF_PARAMS(ei->ifp)->v_wait); + + return length; } /** @@ -602,7 +596,8 @@ eigrp_hello_parameter_encode (struct eigrp_interface *ei, struct stream *s, u_ch * @param[in] s packet stream TLV is stored to * @param[in] ack if non-zero, neigbors sequence packet to ack * @param[in] flags type of hello packet - * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV + * @param[in] nbr_addr pointer to neighbor address for Peer + * Termination TLV * * @return eigrp_packet pointer initialize hello packet * @@ -610,77 +605,77 @@ eigrp_hello_parameter_encode (struct eigrp_interface *ei, struct stream *s, u_ch * Allocate an EIGRP hello packet, and add in the the approperate TLVs * */ -static struct eigrp_packet * -eigrp_hello_encode (struct eigrp_interface *ei, in_addr_t addr, u_int32_t ack, - u_char flags, struct in_addr *nbr_addr) +static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei, + in_addr_t addr, u_int32_t ack, + u_char flags, + struct in_addr *nbr_addr) { - struct eigrp_packet *ep; - u_int16_t length = EIGRP_HEADER_LEN; - - // allocate a new packet to be sent - ep = eigrp_packet_new(ei->ifp->mtu); - - if (ep) - { - // encode common header feilds - eigrp_packet_header_init(EIGRP_OPC_HELLO, ei, ep->s, 0, 0, ack); - - // encode Authentication TLV - if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) - { - length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei); - } - else if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_SHA256) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) - { - length += eigrp_add_authTLV_SHA256_to_stream(ep->s,ei); - } - - /* encode appropriate parameters to Hello packet */ - if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) - length += eigrp_hello_parameter_encode(ei, ep->s, EIGRP_HELLO_GRACEFUL_SHUTDOWN); - else - length += eigrp_hello_parameter_encode(ei, ep->s, EIGRP_HELLO_NORMAL); - - // figure out the version of code we're running - length += eigrp_sw_version_encode(ep->s); - - if(flags & EIGRP_HELLO_ADD_SEQUENCE) - { - length += eigrp_sequence_encode(ep->s); - length += eigrp_next_sequence_encode(ep->s); - } - - // add in the TID list if doing multi-topology - length += eigrp_tidlist_encode(ep->s); - - /* encode Peer Termination TLV if needed */ - if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN_NBR) - length += eigrp_peer_termination_encode(ep->s, nbr_addr); - - // Set packet length - ep->length = length; - - // set soruce address for the hello packet - ep->dst.s_addr = addr; - - if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) - { - eigrp_make_md5_digest(ei,ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG); - } - else if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_SHA256) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) - { - eigrp_make_sha256_digest(ei,ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG); - } - - // EIGRP Checksum - eigrp_packet_checksum(ei, ep->s, length); - } - - return(ep); + struct eigrp_packet *ep; + u_int16_t length = EIGRP_HEADER_LEN; + + // allocate a new packet to be sent + ep = eigrp_packet_new(ei->ifp->mtu); + + if (ep) { + // encode common header feilds + eigrp_packet_header_init(EIGRP_OPC_HELLO, ei, ep->s, 0, 0, ack); + + // encode Authentication TLV + if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) + && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); + } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type + == EIGRP_AUTH_TYPE_SHA256) + && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + length += eigrp_add_authTLV_SHA256_to_stream(ep->s, ei); + } + + /* encode appropriate parameters to Hello packet */ + if (flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) + length += eigrp_hello_parameter_encode( + ei, ep->s, EIGRP_HELLO_GRACEFUL_SHUTDOWN); + else + length += eigrp_hello_parameter_encode( + ei, ep->s, EIGRP_HELLO_NORMAL); + + // figure out the version of code we're running + length += eigrp_sw_version_encode(ep->s); + + if (flags & EIGRP_HELLO_ADD_SEQUENCE) { + length += eigrp_sequence_encode(ep->s); + length += eigrp_next_sequence_encode(ep->s); + } + + // add in the TID list if doing multi-topology + length += eigrp_tidlist_encode(ep->s); + + /* encode Peer Termination TLV if needed */ + if (flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN_NBR) + length += + eigrp_peer_termination_encode(ep->s, nbr_addr); + + // Set packet length + ep->length = length; + + // set soruce address for the hello packet + ep->dst.s_addr = addr; + + if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) + && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + eigrp_make_md5_digest(ei, ep->s, + EIGRP_AUTH_BASIC_HELLO_FLAG); + } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type + == EIGRP_AUTH_TYPE_SHA256) + && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + eigrp_make_sha256_digest(ei, ep->s, + EIGRP_AUTH_BASIC_HELLO_FLAG); + } + + // EIGRP Checksum + eigrp_packet_checksum(ei, ep->s, length); + } + + return (ep); } /** @@ -696,32 +691,32 @@ eigrp_hello_encode (struct eigrp_interface *ei, in_addr_t addr, u_int32_t ack, * updated to the neighbor's sequence number to acknolodge any * outstanding packets */ -void -eigrp_hello_send_ack (struct eigrp_neighbor *nbr) +void eigrp_hello_send_ack(struct eigrp_neighbor *nbr) { - struct eigrp_packet *ep; - - /* if packet succesfully created, add it to the interface queue */ - ep = eigrp_hello_encode(nbr->ei, nbr->src.s_addr, nbr->recv_sequence_number, EIGRP_HELLO_NORMAL, NULL); - - if (ep) - { - if (IS_DEBUG_EIGRP_PACKET(0, SEND)) - zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%s]", - nbr->recv_sequence_number, inet_ntoa(nbr->src)); - - /* Add packet to the top of the interface output queue*/ - eigrp_fifo_push_head(nbr->ei->obuf, ep); - - /* Hook thread to write packet. */ - if (nbr->ei->on_write_q == 0) - { - listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei); - nbr->ei->on_write_q = 1; - } - thread_add_write(master, eigrp_write, nbr->ei->eigrp, nbr->ei->eigrp->fd, - &nbr->ei->eigrp->t_write); - } + struct eigrp_packet *ep; + + /* if packet succesfully created, add it to the interface queue */ + ep = eigrp_hello_encode(nbr->ei, nbr->src.s_addr, + nbr->recv_sequence_number, EIGRP_HELLO_NORMAL, + NULL); + + if (ep) { + if (IS_DEBUG_EIGRP_PACKET(0, SEND)) + zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%s]", + nbr->recv_sequence_number, + inet_ntoa(nbr->src)); + + /* Add packet to the top of the interface output queue*/ + eigrp_fifo_push_head(nbr->ei->obuf, ep); + + /* Hook thread to write packet. */ + if (nbr->ei->on_write_q == 0) { + listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei); + nbr->ei->on_write_q = 1; + } + thread_add_write(master, eigrp_write, nbr->ei->eigrp, + nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write); + } } /** @@ -729,7 +724,8 @@ eigrp_hello_send_ack (struct eigrp_neighbor *nbr) * * @param[in] ei pointer to interface hello should be sent * @param[in] flags type of hello packet - * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV + * @param[in] nbr_addr pointer to neighbor address for Peer + * Termination TLV * * @return void * @@ -738,46 +734,44 @@ eigrp_hello_send_ack (struct eigrp_neighbor *nbr) * sending. If no packets are currently queues, the packet will be * sent immadiatly */ -void -eigrp_hello_send (struct eigrp_interface *ei, u_char flags, struct in_addr *nbr_addr) +void eigrp_hello_send(struct eigrp_interface *ei, u_char flags, + struct in_addr *nbr_addr) { - struct eigrp_packet *ep = NULL; - - /* If this is passive interface, do not send EIGRP Hello. - if ((EIGRP_IF_PASSIVE_STATUS (ei) == EIGRP_IF_PASSIVE) || - (ei->type != EIGRP_IFTYPE_NBMA)) - return; - */ - - if (IS_DEBUG_EIGRP_PACKET(0, SEND)) - zlog_debug("Queueing [Hello] Interface(%s)", IF_NAME(ei)); - - /* if packet was succesfully created, then add it to the interface queue */ - ep = eigrp_hello_encode(ei, htonl(EIGRP_MULTICAST_ADDRESS), 0, flags, nbr_addr); - - if (ep) - { - // Add packet to the top of the interface output queue - eigrp_fifo_push_head(ei->obuf, ep); - - /* Hook thread to write packet. */ - if (ei->on_write_q == 0) - { - listnode_add(ei->eigrp->oi_write_q, ei); - ei->on_write_q = 1; - } - - if (ei->eigrp->t_write == NULL) - { - if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) - { - thread_execute(master, eigrp_write, ei->eigrp, ei->eigrp->fd); - } - else - { - thread_add_write(master, eigrp_write, ei->eigrp, ei->eigrp->fd, - &ei->eigrp->t_write); - } - } - } + struct eigrp_packet *ep = NULL; + + /* If this is passive interface, do not send EIGRP Hello. + if ((EIGRP_IF_PASSIVE_STATUS (ei) == EIGRP_IF_PASSIVE) || + (ei->type != EIGRP_IFTYPE_NBMA)) + return; + */ + + if (IS_DEBUG_EIGRP_PACKET(0, SEND)) + zlog_debug("Queueing [Hello] Interface(%s)", IF_NAME(ei)); + + /* if packet was succesfully created, then add it to the interface queue + */ + ep = eigrp_hello_encode(ei, htonl(EIGRP_MULTICAST_ADDRESS), 0, flags, + nbr_addr); + + if (ep) { + // Add packet to the top of the interface output queue + eigrp_fifo_push_head(ei->obuf, ep); + + /* Hook thread to write packet. */ + if (ei->on_write_q == 0) { + listnode_add(ei->eigrp->oi_write_q, ei); + ei->on_write_q = 1; + } + + if (ei->eigrp->t_write == NULL) { + if (flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) { + thread_execute(master, eigrp_write, ei->eigrp, + ei->eigrp->fd); + } else { + thread_add_write(master, eigrp_write, ei->eigrp, + ei->eigrp->fd, + &ei->eigrp->t_write); + } + } + } } |
