mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-27 13:06:51 +00:00
commit
e919cf55bd
@ -297,6 +297,12 @@ enum eigrp_fsm_events {
|
|||||||
#define EIGRP_TLV_IPv4_EXT (EIGRP_TLV_IPv4 | EIGRP_TLV_EXTERNAL)
|
#define EIGRP_TLV_IPv4_EXT (EIGRP_TLV_IPv4 | EIGRP_TLV_EXTERNAL)
|
||||||
#define EIGRP_TLV_IPv4_COM (EIGRP_TLV_IPv4 | EIGRP_TLV_COMMUNITY)
|
#define EIGRP_TLV_IPv4_COM (EIGRP_TLV_IPv4 | EIGRP_TLV_COMMUNITY)
|
||||||
|
|
||||||
|
#define EIGRP_TLV_IPV4_SIZE_GRT_24_BIT 0x001D
|
||||||
|
#define EIGRP_TLV_IPV4_SIZE_GRT_16_BIT 0x001C
|
||||||
|
#define EIGRP_TLV_IPV4_SIZE_GRT_8_BIT 0x001B
|
||||||
|
#define EIGRP_TLV_IPV4_SIZE_GRT_0_BIT 0x001A
|
||||||
|
#define EIGRP_TLV_MAX_IPV4_BYTE EIGRP_TLV_IPV4_SIZE_GRT_24_BIT
|
||||||
|
|
||||||
/* max number of TLV IPv4 prefixes in packet */
|
/* max number of TLV IPv4 prefixes in packet */
|
||||||
#define EIGRP_TLV_MAX_IPv4 25
|
#define EIGRP_TLV_MAX_IPv4 25
|
||||||
|
|
||||||
|
@ -1165,25 +1165,57 @@ u_int16_t eigrp_add_internalTLV_to_stream(struct stream *s,
|
|||||||
u_int16_t length;
|
u_int16_t length;
|
||||||
|
|
||||||
stream_putw(s, EIGRP_TLV_IPv4_INT);
|
stream_putw(s, EIGRP_TLV_IPv4_INT);
|
||||||
if (pe->destination->prefixlen <= 8) {
|
switch (pe->destination->prefixlen) {
|
||||||
stream_putw(s, 0x001A);
|
case 0:
|
||||||
length = 0x001A;
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
length = EIGRP_TLV_IPV4_SIZE_GRT_0_BIT;
|
||||||
|
stream_putw(s, length);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
length = EIGRP_TLV_IPV4_SIZE_GRT_8_BIT;
|
||||||
|
stream_putw(s, length);
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
case 18:
|
||||||
|
case 19:
|
||||||
|
case 20:
|
||||||
|
case 21:
|
||||||
|
case 22:
|
||||||
|
case 23:
|
||||||
|
case 24:
|
||||||
|
length = EIGRP_TLV_IPV4_SIZE_GRT_16_BIT;
|
||||||
|
stream_putw(s, length);
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
case 26:
|
||||||
|
case 27:
|
||||||
|
case 28:
|
||||||
|
case 29:
|
||||||
|
case 30:
|
||||||
|
case 31:
|
||||||
|
case 32:
|
||||||
|
length = EIGRP_TLV_IPV4_SIZE_GRT_24_BIT;
|
||||||
|
stream_putw(s, length);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
zlog_err("%s: Unexpected prefix length: %d",
|
||||||
|
__PRETTY_FUNCTION__, pe->destination->prefixlen);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if ((pe->destination->prefixlen > 8)
|
|
||||||
&& (pe->destination->prefixlen <= 16)) {
|
|
||||||
stream_putw(s, 0x001B);
|
|
||||||
length = 0x001B;
|
|
||||||
}
|
|
||||||
if ((pe->destination->prefixlen > 16)
|
|
||||||
&& (pe->destination->prefixlen <= 24)) {
|
|
||||||
stream_putw(s, 0x001C);
|
|
||||||
length = 0x001C;
|
|
||||||
}
|
|
||||||
if (pe->destination->prefixlen > 24) {
|
|
||||||
stream_putw(s, 0x001D);
|
|
||||||
length = 0x001D;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream_putl(s, 0x00000000);
|
stream_putl(s, 0x00000000);
|
||||||
|
|
||||||
/*Metric*/
|
/*Metric*/
|
||||||
|
@ -160,49 +160,91 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph,
|
|||||||
|
|
||||||
void eigrp_send_query(struct eigrp_interface *ei)
|
void eigrp_send_query(struct eigrp_interface *ei)
|
||||||
{
|
{
|
||||||
struct eigrp_packet *ep;
|
struct eigrp_packet *ep = NULL;
|
||||||
u_int16_t length = EIGRP_HEADER_LEN;
|
u_int16_t length = EIGRP_HEADER_LEN;
|
||||||
struct listnode *node, *nnode, *node2, *nnode2;
|
struct listnode *node, *nnode, *node2, *nnode2;
|
||||||
struct eigrp_neighbor *nbr;
|
struct eigrp_neighbor *nbr;
|
||||||
struct eigrp_prefix_entry *pe;
|
struct eigrp_prefix_entry *pe;
|
||||||
bool has_tlv = false;
|
bool has_tlv = false;
|
||||||
bool ep_saved = false;
|
bool new_packet = true;
|
||||||
|
|
||||||
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
|
|
||||||
|
|
||||||
/* Prepare EIGRP INIT UPDATE header */
|
|
||||||
eigrp_packet_header_init(EIGRP_OPC_QUERY, ei->eigrp, ep->s, 0,
|
|
||||||
ei->eigrp->sequence_number, 0);
|
|
||||||
|
|
||||||
// encode Authentication TLV, if needed
|
|
||||||
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
|
||||||
&& (ei->params.auth_keychain != NULL)) {
|
|
||||||
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
|
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
|
||||||
nnode, pe)) {
|
nnode, pe)) {
|
||||||
if (!(pe->req_action & EIGRP_FSM_NEED_QUERY))
|
if (!(pe->req_action & EIGRP_FSM_NEED_QUERY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
if (new_packet) {
|
||||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
|
||||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
|
||||||
listnode_add(pe->rij, nbr);
|
/* Prepare EIGRP INIT UPDATE header */
|
||||||
has_tlv = true;;
|
eigrp_packet_header_init(EIGRP_OPC_QUERY,
|
||||||
|
ei->eigrp, ep->s, 0,
|
||||||
|
ei->eigrp->sequence_number, 0);
|
||||||
|
|
||||||
|
// encode Authentication TLV, if needed
|
||||||
|
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
||||||
|
&& (ei->params.auth_keychain != NULL)) {
|
||||||
|
length +=
|
||||||
|
eigrp_add_authTLV_MD5_to_stream(ep->s,
|
||||||
|
ei);
|
||||||
}
|
}
|
||||||
|
new_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
||||||
|
has_tlv = true;
|
||||||
|
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||||
|
if (nbr->state == EIGRP_NEIGHBOR_UP)
|
||||||
|
listnode_add(pe->rij, nbr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length + EIGRP_TLV_MAX_IPV4_BYTE > (uint16_t)ei->ifp->mtu) {
|
||||||
|
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
||||||
|
&& ei->params.auth_keychain != NULL) {
|
||||||
|
eigrp_make_md5_digest(ei, ep->s,
|
||||||
|
EIGRP_AUTH_UPDATE_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
eigrp_packet_checksum(ei, ep->s, length);
|
||||||
|
ep->length = length;
|
||||||
|
|
||||||
|
ep->dst.s_addr = htonl(EIGRP_MULTICAST_ADDRESS);
|
||||||
|
|
||||||
|
ep->sequence_number = ei->eigrp->sequence_number;
|
||||||
|
ei->eigrp->sequence_number++;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||||
|
struct eigrp_packet *dup;
|
||||||
|
|
||||||
|
if (nbr->state != EIGRP_NEIGHBOR_UP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dup = eigrp_packet_duplicate(ep, nbr);
|
||||||
|
/*Put packet to retransmission queue*/
|
||||||
|
eigrp_fifo_push(nbr->retrans_queue, dup);
|
||||||
|
|
||||||
|
if (nbr->retrans_queue->count == 1)
|
||||||
|
eigrp_send_packet_reliably(nbr);
|
||||||
|
}
|
||||||
|
|
||||||
|
has_tlv = false;
|
||||||
|
length = 0;
|
||||||
|
eigrp_packet_free(ep);
|
||||||
|
ep = NULL;
|
||||||
|
new_packet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_tlv) {
|
if (!has_tlv) {
|
||||||
eigrp_packet_free(ep);
|
if (ep)
|
||||||
|
eigrp_packet_free(ep);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
||||||
&& ei->params.auth_keychain != NULL) {
|
&& ei->params.auth_keychain != NULL)
|
||||||
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
|
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
|
||||||
}
|
|
||||||
|
|
||||||
/* EIGRP Checksum */
|
/* EIGRP Checksum */
|
||||||
eigrp_packet_checksum(ei, ep->s, length);
|
eigrp_packet_checksum(ei, ep->s, length);
|
||||||
@ -215,17 +257,18 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||||||
ei->eigrp->sequence_number++;
|
ei->eigrp->sequence_number++;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
struct eigrp_packet *dup;
|
||||||
/*Put packet to retransmission queue*/
|
|
||||||
eigrp_fifo_push(nbr->retrans_queue, ep);
|
|
||||||
ep_saved = true;
|
|
||||||
|
|
||||||
if (nbr->retrans_queue->count == 1) {
|
if (nbr->state != EIGRP_NEIGHBOR_UP)
|
||||||
eigrp_send_packet_reliably(nbr);
|
continue;
|
||||||
}
|
|
||||||
}
|
dup = eigrp_packet_duplicate(ep, nbr);
|
||||||
|
/*Put packet to retransmission queue*/
|
||||||
|
eigrp_fifo_push(nbr->retrans_queue, dup);
|
||||||
|
|
||||||
|
if (nbr->retrans_queue->count == 1)
|
||||||
|
eigrp_send_packet_reliably(nbr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ep_saved)
|
eigrp_packet_free(ep);
|
||||||
eigrp_packet_free(ep);
|
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
|
|||||||
if (eigrp_nbr_split_horizon_check(te, ei))
|
if (eigrp_nbr_split_horizon_check(te, ei))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((length + 0x001D) > mtu) {
|
if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > mtu) {
|
||||||
eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length);
|
eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length);
|
||||||
seq_no++;
|
seq_no++;
|
||||||
|
|
||||||
@ -635,7 +635,8 @@ void eigrp_update_send(struct eigrp_interface *ei)
|
|||||||
if (eigrp_nbr_split_horizon_check(ne, ei))
|
if (eigrp_nbr_split_horizon_check(ne, ei))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) {
|
if ((length + EIGRP_TLV_MAX_IPV4_BYTE) >
|
||||||
|
(u_int16_t)ei->ifp->mtu) {
|
||||||
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
|
||||||
&& (ei->params.auth_keychain != NULL)) {
|
&& (ei->params.auth_keychain != NULL)) {
|
||||||
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
|
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
|
||||||
|
Loading…
Reference in New Issue
Block a user