]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_reply.c
*: add indent control files
[mirror_frr.git] / eigrpd / eigrp_reply.c
CommitLineData
7f57883e
DS
1/*
2 * EIGRP Sending and Receiving EIGRP Reply Packets.
3 * Copyright (C) 2013-2016
4 * Authors:
5 * Donnie Savage
6 * Jan Janovic
7 * Matej Perina
8 * Peter Orsag
9 * Peter Paluch
10 * Frantisek Gazo
11 * Tomas Hvorkovy
12 * Martin Kontsek
13 * Lukas Koribsky
14 *
15 * This file is part of GNU Zebra.
16 *
17 * GNU Zebra is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2, or (at your option) any
20 * later version.
21 *
22 * GNU Zebra is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
896014f4
DL
27 * You should have received a copy of the GNU General Public License along
28 * with this program; see the file COPYING; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7f57883e
DS
30 */
31
32#include <zebra.h>
33
34#include "thread.h"
35#include "memory.h"
36#include "linklist.h"
37#include "prefix.h"
38#include "if.h"
39#include "table.h"
40#include "sockunion.h"
41#include "stream.h"
42#include "log.h"
43#include "sockopt.h"
44#include "checksum.h"
45#include "md5.h"
46#include "vty.h"
47#include "keychain.h"
48#include "plist.h"
49
50#include "eigrpd/eigrp_structs.h"
51#include "eigrpd/eigrpd.h"
52#include "eigrpd/eigrp_interface.h"
53#include "eigrpd/eigrp_neighbor.h"
54#include "eigrpd/eigrp_packet.h"
55#include "eigrpd/eigrp_zebra.h"
56#include "eigrpd/eigrp_vty.h"
57#include "eigrpd/eigrp_dump.h"
58#include "eigrpd/eigrp_macros.h"
59#include "eigrpd/eigrp_topology.h"
60#include "eigrpd/eigrp_fsm.h"
61#include "eigrpd/eigrp_memory.h"
62
63void
64eigrp_send_reply (struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
65{
66 struct eigrp_packet *ep;
67 u_int16_t length = EIGRP_HEADER_LEN;
68
69 struct access_list *alist;
70 struct prefix_list *plist;
71 struct access_list *alist_i;
72 struct prefix_list *plist_i;
73 struct eigrp *e;
74 struct eigrp_prefix_entry *pe2;
75
76 //TODO: Work in progress
77 /* Filtering */
78 /* get list from eigrp process */
79 e = eigrp_lookup();
80 pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, sizeof(struct eigrp_prefix_entry));
81 memcpy(pe2,pe,sizeof(struct eigrp_prefix_entry));
82 /* Get access-lists and prefix-lists from process and interface */
83 alist = e->list[EIGRP_FILTER_OUT];
84 plist = e->prefix[EIGRP_FILTER_OUT];
85 alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
86 plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
87 zlog_info("REPLY Send: Filtering");
88
89 zlog_info("REPLY SEND Prefix: %s", inet_ntoa(nbr->src));
90 /* Check if any list fits */
f9e5c9ca
DS
91 if ((alist &&
92 access_list_apply (alist, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY) ||
93 (plist && prefix_list_apply (plist, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY)||
94 (alist_i && access_list_apply (alist_i, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY)||
95 (plist_i && prefix_list_apply (plist_i, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY))
96 {
97 zlog_info("REPLY SEND: Setting Metric to max");
98 pe2->reported_metric.delay = EIGRP_MAX_METRIC;
7f57883e 99
f9e5c9ca
DS
100 }
101 else
102 {
103 zlog_info("REPLY SEND: Not setting metric");
104 }
7f57883e
DS
105
106 /*
107 * End of filtering
108 */
109
110 ep = eigrp_packet_new(nbr->ei->ifp->mtu);
111
112 /* Prepare EIGRP INIT UPDATE header */
113 eigrp_packet_header_init(EIGRP_OPC_REPLY, nbr->ei, ep->s, 0,
114 nbr->ei->eigrp->sequence_number, 0);
115
116 // encode Authentication TLV, if needed
f9e5c9ca
DS
117 if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
118 (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
7f57883e
DS
119 {
120 length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
121 }
122
123
124 length += eigrp_add_internalTLV_to_stream(ep->s, pe2);
125
f9e5c9ca
DS
126 if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
127 (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
7f57883e
DS
128 {
129 eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
130 }
131
132 /* EIGRP Checksum */
133 eigrp_packet_checksum(nbr->ei, ep->s, length);
134
135 ep->length = length;
136 ep->dst.s_addr = nbr->src.s_addr;
137
138 /*This ack number we await from neighbor*/
139 ep->sequence_number = nbr->ei->eigrp->sequence_number;
140
141 /*Put packet to retransmission queue*/
142 eigrp_fifo_push_head(nbr->retrans_queue, ep);
143
144 if (nbr->retrans_queue->count == 1)
145 {
146 eigrp_send_packet_reliably(nbr);
147 }
057fad8d
DS
148
149 XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe2);
7f57883e
DS
150}
151
152/*EIGRP REPLY read function*/
153void
154eigrp_reply_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
155 struct stream * s, struct eigrp_interface *ei, int size)
156{
157 struct eigrp_neighbor *nbr;
158 struct TLV_IPv4_Internal_type *tlv;
159
160 struct access_list *alist;
161 struct prefix_list *plist;
162 struct access_list *alist_i;
163 struct prefix_list *plist_i;
164 struct eigrp *e;
165
166 u_int16_t type;
167
168 /* increment statistics. */
169 ei->reply_in++;
170
171 /* get neighbor struct */
172 nbr = eigrp_nbr_get(ei, eigrph, iph);
173
174 /* neighbor must be valid, eigrp_nbr_get creates if none existed */
175 assert(nbr);
176
177 nbr->recv_sequence_number = ntohl(eigrph->sequence);
178
179 while (s->endp > s->getp)
180 {
181 type = stream_getw(s);
182 if (type == EIGRP_TLV_IPv4_INT)
183 {
057fad8d
DS
184 struct prefix_ipv4 dest_addr;
185
7f57883e
DS
186 stream_set_getp(s, s->getp - sizeof(u_int16_t));
187
188 tlv = eigrp_read_ipv4_tlv(s);
189
d286e5f5 190 dest_addr.family = AF_INET;
057fad8d
DS
191 dest_addr.prefix = tlv->destination;
192 dest_addr.prefixlen = tlv->prefix_length;
f9e5c9ca 193 struct eigrp_prefix_entry *dest =
057fad8d 194 eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, &dest_addr);
7f57883e
DS
195 /*
196 * Destination must exists
197 */
198 assert(dest);
199
200 struct eigrp_fsm_action_message *msg;
201 msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
f9e5c9ca
DS
202 sizeof(struct eigrp_fsm_action_message));
203 struct eigrp_neighbor_entry *entry =
204 eigrp_prefix_entry_lookup(dest->entries, nbr);
7f57883e
DS
205
206 /*
207 * Filtering
208 */
209 //TODO: Work in progress
210 /* get list from eigrp process */
211 e = eigrp_lookup();
212 /* Get access-lists and prefix-lists from process and interface */
213 alist = e->list[EIGRP_FILTER_IN];
214 plist = e->prefix[EIGRP_FILTER_IN];
215 alist_i = ei->list[EIGRP_FILTER_IN];
216 plist_i = ei->prefix[EIGRP_FILTER_IN];
f9e5c9ca 217 /* Check if any list fits */
057fad8d
DS
218 if ((alist &&
219 access_list_apply (alist, (struct prefix *)&dest_addr) == FILTER_DENY) ||
220 (plist &&
221 prefix_list_apply (plist, (struct prefix *)&dest_addr) == PREFIX_DENY) ||
222 (alist_i &&
223 access_list_apply (alist_i, (struct prefix *)&dest_addr) == FILTER_DENY) ||
224 (plist_i &&
225 prefix_list_apply (plist_i, (struct prefix *)&dest_addr) == PREFIX_DENY))
f9e5c9ca 226 {
f9e5c9ca 227 tlv->metric.delay = EIGRP_MAX_METRIC;
057fad8d 228 }
f9e5c9ca
DS
229 /*
230 * End of filtering
231 */
232
233 msg->packet_type = EIGRP_OPC_REPLY;
234 msg->eigrp = eigrp;
235 msg->data_type = EIGRP_TLV_IPv4_INT;
236 msg->adv_router = nbr;
237 msg->data.ipv4_int_type = tlv;
238 msg->entry = entry;
239 msg->prefix = dest;
240 int event = eigrp_get_fsm_event(msg);
241 eigrp_fsm_event(msg, event);
7f57883e
DS
242
243
244 eigrp_IPv4_InternalTLV_free (tlv);
245 }
246 }
247 eigrp_hello_send_ack(nbr);
248}
249