]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_reply.c
eigrpd: Cleanup tab/spacing of the *.c files
[mirror_frr.git] / eigrpd / eigrp_reply.c
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 *
27 * You should have received a copy of the GNU General Public License
28 * along with GNU Zebra; see the file COPYING. If not, write to the Free
29 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
30 * 02111-1307, USA.
31 */
32
33 #include <zebra.h>
34
35 #include "thread.h"
36 #include "memory.h"
37 #include "linklist.h"
38 #include "prefix.h"
39 #include "if.h"
40 #include "table.h"
41 #include "sockunion.h"
42 #include "stream.h"
43 #include "log.h"
44 #include "sockopt.h"
45 #include "checksum.h"
46 #include "md5.h"
47 #include "vty.h"
48 #include "keychain.h"
49 #include "plist.h"
50
51 #include "eigrpd/eigrp_structs.h"
52 #include "eigrpd/eigrpd.h"
53 #include "eigrpd/eigrp_interface.h"
54 #include "eigrpd/eigrp_neighbor.h"
55 #include "eigrpd/eigrp_packet.h"
56 #include "eigrpd/eigrp_zebra.h"
57 #include "eigrpd/eigrp_vty.h"
58 #include "eigrpd/eigrp_dump.h"
59 #include "eigrpd/eigrp_macros.h"
60 #include "eigrpd/eigrp_topology.h"
61 #include "eigrpd/eigrp_fsm.h"
62 #include "eigrpd/eigrp_memory.h"
63
64 void
65 eigrp_send_reply (struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
66 {
67 struct eigrp_packet *ep;
68 u_int16_t length = EIGRP_HEADER_LEN;
69
70 struct access_list *alist;
71 struct prefix_list *plist;
72 struct access_list *alist_i;
73 struct prefix_list *plist_i;
74 struct eigrp *e;
75 struct eigrp_prefix_entry *pe2;
76
77 //TODO: Work in progress
78 /* Filtering */
79 /* get list from eigrp process */
80 e = eigrp_lookup();
81 pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, sizeof(struct eigrp_prefix_entry));
82 memcpy(pe2,pe,sizeof(struct eigrp_prefix_entry));
83 /* Get access-lists and prefix-lists from process and interface */
84 alist = e->list[EIGRP_FILTER_OUT];
85 plist = e->prefix[EIGRP_FILTER_OUT];
86 alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
87 plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
88 zlog_info("REPLY Send: Filtering");
89
90 zlog_info("REPLY SEND Prefix: %s", inet_ntoa(nbr->src));
91 /* Check if any list fits */
92 if ((alist &&
93 access_list_apply (alist, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY) ||
94 (plist && prefix_list_apply (plist, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY)||
95 (alist_i && access_list_apply (alist_i, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY)||
96 (plist_i && prefix_list_apply (plist_i, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY))
97 {
98 zlog_info("REPLY SEND: Setting Metric to max");
99 pe2->reported_metric.delay = EIGRP_MAX_METRIC;
100
101 }
102 else
103 {
104 zlog_info("REPLY SEND: Not setting metric");
105 }
106
107 /*
108 * End of filtering
109 */
110
111 ep = eigrp_packet_new(nbr->ei->ifp->mtu);
112
113 /* Prepare EIGRP INIT UPDATE header */
114 eigrp_packet_header_init(EIGRP_OPC_REPLY, nbr->ei, ep->s, 0,
115 nbr->ei->eigrp->sequence_number, 0);
116
117 // encode Authentication TLV, if needed
118 if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
119 (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
120 {
121 length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
122 }
123
124
125 length += eigrp_add_internalTLV_to_stream(ep->s, pe2);
126
127 if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
128 (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
129 {
130 eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
131 }
132
133 /* EIGRP Checksum */
134 eigrp_packet_checksum(nbr->ei, ep->s, length);
135
136 ep->length = length;
137 ep->dst.s_addr = nbr->src.s_addr;
138
139 /*This ack number we await from neighbor*/
140 ep->sequence_number = nbr->ei->eigrp->sequence_number;
141
142 /*Put packet to retransmission queue*/
143 eigrp_fifo_push_head(nbr->retrans_queue, ep);
144
145 if (nbr->retrans_queue->count == 1)
146 {
147 eigrp_send_packet_reliably(nbr);
148 }
149 }
150
151 /*EIGRP REPLY read function*/
152 void
153 eigrp_reply_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
154 struct stream * s, struct eigrp_interface *ei, int size)
155 {
156 struct eigrp_neighbor *nbr;
157 struct TLV_IPv4_Internal_type *tlv;
158
159 struct access_list *alist;
160 struct prefix_list *plist;
161 struct access_list *alist_i;
162 struct prefix_list *plist_i;
163 struct eigrp *e;
164
165 u_int16_t type;
166
167 /* increment statistics. */
168 ei->reply_in++;
169
170 /* get neighbor struct */
171 nbr = eigrp_nbr_get(ei, eigrph, iph);
172
173 /* neighbor must be valid, eigrp_nbr_get creates if none existed */
174 assert(nbr);
175
176 nbr->recv_sequence_number = ntohl(eigrph->sequence);
177
178 while (s->endp > s->getp)
179 {
180 type = stream_getw(s);
181 if (type == EIGRP_TLV_IPv4_INT)
182 {
183 stream_set_getp(s, s->getp - sizeof(u_int16_t));
184
185 tlv = eigrp_read_ipv4_tlv(s);
186
187 struct prefix_ipv4 *dest_addr;
188 dest_addr = prefix_ipv4_new();
189 dest_addr->prefix = tlv->destination;
190 dest_addr->prefixlen = tlv->prefix_length;
191 struct eigrp_prefix_entry *dest =
192 eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, dest_addr);
193 /*
194 * Destination must exists
195 */
196 assert(dest);
197
198 struct eigrp_fsm_action_message *msg;
199 msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
200 sizeof(struct eigrp_fsm_action_message));
201 struct eigrp_neighbor_entry *entry =
202 eigrp_prefix_entry_lookup(dest->entries, nbr);
203
204 /*
205 * Filtering
206 */
207 //TODO: Work in progress
208 /* get list from eigrp process */
209 e = eigrp_lookup();
210 /* Get access-lists and prefix-lists from process and interface */
211 alist = e->list[EIGRP_FILTER_IN];
212 plist = e->prefix[EIGRP_FILTER_IN];
213 alist_i = ei->list[EIGRP_FILTER_IN];
214 plist_i = ei->prefix[EIGRP_FILTER_IN];
215 zlog_info("REPLY Receive: Filtering");
216 zlog_info("REPLY RECEIVE Prefix: %s", inet_ntoa(dest_addr->prefix));
217 /* Check if any list fits */
218 if ((alist && access_list_apply (alist,
219 (struct prefix *) dest_addr) == FILTER_DENY)||
220 (plist && prefix_list_apply (plist,
221 (struct prefix *) dest_addr) == PREFIX_DENY)||
222 (alist_i && access_list_apply (alist_i,
223 (struct prefix *) dest_addr) == FILTER_DENY)||
224 (plist_i && prefix_list_apply (plist_i,
225 (struct prefix *) dest_addr) == PREFIX_DENY))
226 {
227 zlog_info("REPLY RECEIVE: Setting metric to max");
228 tlv->metric.delay = EIGRP_MAX_METRIC;
229 zlog_info("REPLY RECEIVE Prefix: %s", inet_ntoa(dest_addr->prefix));
230 } else {
231 zlog_info("REPLY RECEIVE: Not setting metric");
232 }
233 /*
234 * End of filtering
235 */
236
237 msg->packet_type = EIGRP_OPC_REPLY;
238 msg->eigrp = eigrp;
239 msg->data_type = EIGRP_TLV_IPv4_INT;
240 msg->adv_router = nbr;
241 msg->data.ipv4_int_type = tlv;
242 msg->entry = entry;
243 msg->prefix = dest;
244 int event = eigrp_get_fsm_event(msg);
245 eigrp_fsm_event(msg, event);
246
247
248 eigrp_IPv4_InternalTLV_free (tlv);
249 }
250 }
251 eigrp_hello_send_ack(nbr);
252 }
253