]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
7f57883e DS |
2 | /* |
3 | * EIGRP Filter Functions. | |
4 | * Copyright (C) 2013-2015 | |
5 | * Authors: | |
6 | * Donnie Savage | |
7 | * Jan Janovic | |
8 | * Matej Perina | |
9 | * Peter Orsag | |
10 | * Peter Paluch | |
11 | * Frantisek Gazo | |
12 | * Tomas Hvorkovy | |
13 | * Martin Kontsek | |
14 | * Lukas Koribsky | |
15 | * | |
7f57883e DS |
16 | */ |
17 | ||
18 | #include <zebra.h> | |
19 | ||
20 | #include "if.h" | |
21 | #include "command.h" | |
22 | #include "prefix.h" | |
23 | #include "table.h" | |
24 | #include "thread.h" | |
25 | #include "memory.h" | |
26 | #include "log.h" | |
27 | #include "stream.h" | |
28 | #include "filter.h" | |
29 | #include "sockunion.h" | |
30 | #include "sockopt.h" | |
31 | #include "routemap.h" | |
32 | #include "if_rmap.h" | |
33 | #include "plist.h" | |
34 | #include "distribute.h" | |
35 | #include "md5.h" | |
36 | #include "keychain.h" | |
37 | #include "privs.h" | |
38 | #include "vrf.h" | |
39 | ||
40 | #include "eigrpd/eigrp_structs.h" | |
41 | #include "eigrpd/eigrpd.h" | |
42 | #include "eigrpd/eigrp_const.h" | |
43 | #include "eigrpd/eigrp_filter.h" | |
44 | #include "eigrpd/eigrp_packet.h" | |
7f57883e DS |
45 | |
46 | /* | |
47 | * Distribute-list update functions. | |
48 | */ | |
03a38493 PG |
49 | void eigrp_distribute_update(struct distribute_ctx *ctx, |
50 | struct distribute *dist) | |
7f57883e | 51 | { |
4cfff48a | 52 | struct eigrp *e = eigrp_lookup(ctx->vrf->vrf_id); |
d62a17ae | 53 | struct interface *ifp; |
54 | struct eigrp_interface *ei = NULL; | |
55 | struct access_list *alist; | |
56 | struct prefix_list *plist; | |
57 | // struct route_map *routemap; | |
d62a17ae | 58 | |
59 | /* if no interface address is present, set list to eigrp process struct | |
60 | */ | |
d62a17ae | 61 | |
62 | /* Check if distribute-list was set for process or interface */ | |
63 | if (!dist->ifname) { | |
64 | /* access list IN for whole process */ | |
65 | if (dist->list[DISTRIBUTE_V4_IN]) { | |
66 | alist = access_list_lookup( | |
67 | AFI_IP, dist->list[DISTRIBUTE_V4_IN]); | |
68 | if (alist) | |
69 | e->list[EIGRP_FILTER_IN] = alist; | |
70 | else | |
71 | e->list[EIGRP_FILTER_IN] = NULL; | |
72 | } else { | |
73 | e->list[EIGRP_FILTER_IN] = NULL; | |
74 | } | |
75 | ||
76 | /* access list OUT for whole process */ | |
77 | if (dist->list[DISTRIBUTE_V4_OUT]) { | |
78 | alist = access_list_lookup( | |
79 | AFI_IP, dist->list[DISTRIBUTE_V4_OUT]); | |
80 | if (alist) | |
81 | e->list[EIGRP_FILTER_OUT] = alist; | |
82 | else | |
83 | e->list[EIGRP_FILTER_OUT] = NULL; | |
84 | } else { | |
85 | e->list[EIGRP_FILTER_OUT] = NULL; | |
86 | } | |
87 | ||
88 | /* PREFIX_LIST IN for process */ | |
89 | if (dist->prefix[DISTRIBUTE_V4_IN]) { | |
90 | plist = prefix_list_lookup( | |
91 | AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]); | |
92 | if (plist) { | |
93 | e->prefix[EIGRP_FILTER_IN] = plist; | |
94 | } else | |
95 | e->prefix[EIGRP_FILTER_IN] = NULL; | |
96 | } else | |
97 | e->prefix[EIGRP_FILTER_IN] = NULL; | |
98 | ||
99 | /* PREFIX_LIST OUT for process */ | |
100 | if (dist->prefix[DISTRIBUTE_V4_OUT]) { | |
101 | plist = prefix_list_lookup( | |
102 | AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]); | |
103 | if (plist) { | |
104 | e->prefix[EIGRP_FILTER_OUT] = plist; | |
105 | ||
106 | } else | |
107 | e->prefix[EIGRP_FILTER_OUT] = NULL; | |
108 | } else | |
109 | e->prefix[EIGRP_FILTER_OUT] = NULL; | |
110 | ||
d62a17ae | 111 | // TODO: check Graceful restart after 10sec |
112 | ||
50478845 MS |
113 | /* cancel GR scheduled */ |
114 | thread_cancel(&(e->t_distribute)); | |
b3d6bc6e | 115 | |
d62a17ae | 116 | /* schedule Graceful restart for whole process in 10sec */ |
d62a17ae | 117 | thread_add_timer(master, eigrp_distribute_timer_process, e, |
118 | (10), &e->t_distribute); | |
119 | ||
120 | return; | |
121 | } | |
122 | ||
daa64bdf | 123 | ifp = if_lookup_by_name(dist->ifname, e->vrf_id); |
d62a17ae | 124 | if (ifp == NULL) |
125 | return; | |
126 | ||
127 | /*struct eigrp_if_info * info = ifp->info; | |
128 | ei = info->eigrp_interface;*/ | |
129 | struct listnode *node, *nnode; | |
130 | struct eigrp_interface *ei2; | |
131 | /* Find proper interface */ | |
132 | for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) { | |
133 | if (strcmp(ei2->ifp->name, ifp->name) == 0) { | |
134 | ei = ei2; | |
135 | break; | |
136 | } | |
137 | } | |
85bbc95d | 138 | assert(ei != NULL); |
d62a17ae | 139 | |
140 | /* Access-list for interface in */ | |
141 | if (dist->list[DISTRIBUTE_V4_IN]) { | |
142 | alist = access_list_lookup(AFI_IP, | |
143 | dist->list[DISTRIBUTE_V4_IN]); | |
144 | if (alist) { | |
145 | ei->list[EIGRP_FILTER_IN] = alist; | |
146 | } else | |
147 | ei->list[EIGRP_FILTER_IN] = NULL; | |
148 | } else { | |
149 | ei->list[EIGRP_FILTER_IN] = NULL; | |
150 | } | |
151 | ||
152 | /* Access-list for interface in */ | |
153 | if (dist->list[DISTRIBUTE_V4_OUT]) { | |
154 | alist = access_list_lookup(AFI_IP, | |
155 | dist->list[DISTRIBUTE_V4_OUT]); | |
156 | if (alist) | |
157 | ei->list[EIGRP_FILTER_OUT] = alist; | |
158 | else | |
159 | ei->list[EIGRP_FILTER_OUT] = NULL; | |
160 | ||
161 | } else | |
162 | ei->list[EIGRP_FILTER_OUT] = NULL; | |
163 | ||
164 | /* Prefix-list for interface in */ | |
165 | if (dist->prefix[DISTRIBUTE_V4_IN]) { | |
166 | plist = prefix_list_lookup(AFI_IP, | |
167 | dist->prefix[DISTRIBUTE_V4_IN]); | |
168 | if (plist) | |
169 | ei->prefix[EIGRP_FILTER_IN] = plist; | |
170 | else | |
171 | ei->prefix[EIGRP_FILTER_IN] = NULL; | |
172 | } else | |
173 | ei->prefix[EIGRP_FILTER_IN] = NULL; | |
174 | ||
175 | /* Prefix-list for interface out */ | |
176 | if (dist->prefix[DISTRIBUTE_V4_OUT]) { | |
177 | plist = prefix_list_lookup(AFI_IP, | |
178 | dist->prefix[DISTRIBUTE_V4_OUT]); | |
179 | if (plist) | |
180 | ei->prefix[EIGRP_FILTER_OUT] = plist; | |
181 | else | |
182 | ei->prefix[EIGRP_FILTER_OUT] = NULL; | |
183 | } else | |
184 | ei->prefix[EIGRP_FILTER_OUT] = NULL; | |
7f57883e | 185 | |
d62a17ae | 186 | // TODO: check Graceful restart after 10sec |
187 | ||
50478845 | 188 | /* Cancel GR scheduled */ |
b3d6bc6e | 189 | thread_cancel(&(ei->t_distribute)); |
d62a17ae | 190 | /* schedule Graceful restart for interface in 10sec */ |
d62a17ae | 191 | thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10, |
eb946ef5 | 192 | &ei->t_distribute); |
7f57883e DS |
193 | } |
194 | ||
195 | /* | |
196 | * Function called by prefix-list and access-list update | |
197 | */ | |
d62a17ae | 198 | void eigrp_distribute_update_interface(struct interface *ifp) |
7f57883e | 199 | { |
d62a17ae | 200 | struct distribute *dist; |
03a38493 | 201 | struct eigrp *eigrp; |
7f57883e | 202 | |
096f7609 | 203 | eigrp = eigrp_lookup(ifp->vrf->vrf_id); |
03a38493 PG |
204 | if (!eigrp) |
205 | return; | |
206 | dist = distribute_lookup(eigrp->distribute_ctx, ifp->name); | |
d62a17ae | 207 | if (dist) |
03a38493 PG |
208 | eigrp_distribute_update(eigrp->distribute_ctx, |
209 | dist); | |
7f57883e DS |
210 | } |
211 | ||
212 | /* Update all interface's distribute list. | |
213 | * Function used in hook for prefix-list | |
214 | */ | |
d62a17ae | 215 | void eigrp_distribute_update_all(struct prefix_list *notused) |
7f57883e | 216 | { |
4cfff48a | 217 | struct vrf *vrf; |
d62a17ae | 218 | struct interface *ifp; |
7f57883e | 219 | |
4cfff48a DS |
220 | RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { |
221 | FOR_ALL_INTERFACES (vrf, ifp) | |
222 | eigrp_distribute_update_interface(ifp); | |
223 | } | |
7f57883e DS |
224 | } |
225 | ||
226 | /* | |
227 | * Function used in hook for acces-list | |
228 | */ | |
d62a17ae | 229 | void eigrp_distribute_update_all_wrapper(struct access_list *notused) |
7f57883e | 230 | { |
d62a17ae | 231 | eigrp_distribute_update_all(NULL); |
7f57883e DS |
232 | } |
233 | ||
234 | /* | |
235 | * @fn eigrp_distribute_timer_process | |
236 | * | |
f9e5c9ca | 237 | * @param[in] thread current execution thread timer is associated with |
7f57883e | 238 | * |
cc9f21da | 239 | * @return void |
7f57883e DS |
240 | * |
241 | * @par | |
242 | * Called when 10sec waiting time expire and | |
243 | * executes Graceful restart for whole process | |
244 | */ | |
cc9f21da | 245 | void eigrp_distribute_timer_process(struct thread *thread) |
7f57883e | 246 | { |
d62a17ae | 247 | struct eigrp *eigrp; |
7f57883e | 248 | |
d62a17ae | 249 | eigrp = THREAD_ARG(thread); |
7f57883e | 250 | |
d62a17ae | 251 | /* execute GR for whole process */ |
252 | eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL); | |
7f57883e DS |
253 | } |
254 | ||
255 | /* | |
256 | * @fn eigrp_distribute_timer_interface | |
257 | * | |
f9e5c9ca | 258 | * @param[in] thread current execution thread timer is associated with |
7f57883e | 259 | * |
cc9f21da | 260 | * @return void |
7f57883e DS |
261 | * |
262 | * @par | |
263 | * Called when 10sec waiting time expire and | |
264 | * executes Graceful restart for interface | |
265 | */ | |
cc9f21da | 266 | void eigrp_distribute_timer_interface(struct thread *thread) |
7f57883e | 267 | { |
d62a17ae | 268 | struct eigrp_interface *ei; |
7f57883e | 269 | |
d62a17ae | 270 | ei = THREAD_ARG(thread); |
271 | ei->t_distribute = NULL; | |
7f57883e | 272 | |
d62a17ae | 273 | /* execute GR for interface */ |
274 | eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL); | |
7f57883e | 275 | } |