2 * EIGRP Filter Functions.
3 * Copyright (C) 2013-2015
16 * This file is part of GNU Zebra.
18 * GNU Zebra is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2, or (at your option) any
23 * GNU Zebra is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
28 * You should have received a copy of the GNU General Public License along
29 * with this program; see the file COPYING; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
44 #include "sockunion.h"
49 #include "distribute.h"
55 #include "eigrpd/eigrp_structs.h"
56 #include "eigrpd/eigrpd.h"
57 #include "eigrpd/eigrp_const.h"
58 #include "eigrpd/eigrp_filter.h"
59 #include "eigrpd/eigrp_packet.h"
62 * Distribute-list update functions.
64 void eigrp_distribute_update(struct distribute_ctx
*ctx
,
65 struct distribute
*dist
)
67 struct eigrp
*e
= eigrp_lookup(ctx
->vrf
->vrf_id
);
68 struct interface
*ifp
;
69 struct eigrp_interface
*ei
= NULL
;
70 struct access_list
*alist
;
71 struct prefix_list
*plist
;
72 // struct route_map *routemap;
74 /* if no interface address is present, set list to eigrp process struct
77 /* Check if distribute-list was set for process or interface */
79 /* access list IN for whole process */
80 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
81 alist
= access_list_lookup(
82 AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
84 e
->list
[EIGRP_FILTER_IN
] = alist
;
86 e
->list
[EIGRP_FILTER_IN
] = NULL
;
88 e
->list
[EIGRP_FILTER_IN
] = NULL
;
91 /* access list OUT for whole process */
92 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
93 alist
= access_list_lookup(
94 AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
96 e
->list
[EIGRP_FILTER_OUT
] = alist
;
98 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
100 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
103 /* PREFIX_LIST IN for process */
104 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
105 plist
= prefix_list_lookup(
106 AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
108 e
->prefix
[EIGRP_FILTER_IN
] = plist
;
110 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
112 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
114 /* PREFIX_LIST OUT for process */
115 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
116 plist
= prefix_list_lookup(
117 AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
119 e
->prefix
[EIGRP_FILTER_OUT
] = plist
;
122 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
124 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
126 // TODO: check Graceful restart after 10sec
128 /* cancel GR scheduled */
129 thread_cancel(&(e
->t_distribute
));
131 /* schedule Graceful restart for whole process in 10sec */
132 thread_add_timer(master
, eigrp_distribute_timer_process
, e
,
133 (10), &e
->t_distribute
);
138 ifp
= if_lookup_by_name(dist
->ifname
, e
->vrf_id
);
142 /*struct eigrp_if_info * info = ifp->info;
143 ei = info->eigrp_interface;*/
144 struct listnode
*node
, *nnode
;
145 struct eigrp_interface
*ei2
;
146 /* Find proper interface */
147 for (ALL_LIST_ELEMENTS(e
->eiflist
, node
, nnode
, ei2
)) {
148 if (strcmp(ei2
->ifp
->name
, ifp
->name
) == 0) {
155 /* Access-list for interface in */
156 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
157 alist
= access_list_lookup(AFI_IP
,
158 dist
->list
[DISTRIBUTE_V4_IN
]);
160 ei
->list
[EIGRP_FILTER_IN
] = alist
;
162 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
164 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
167 /* Access-list for interface in */
168 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
169 alist
= access_list_lookup(AFI_IP
,
170 dist
->list
[DISTRIBUTE_V4_OUT
]);
172 ei
->list
[EIGRP_FILTER_OUT
] = alist
;
174 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
177 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
179 /* Prefix-list for interface in */
180 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
181 plist
= prefix_list_lookup(AFI_IP
,
182 dist
->prefix
[DISTRIBUTE_V4_IN
]);
184 ei
->prefix
[EIGRP_FILTER_IN
] = plist
;
186 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
188 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
190 /* Prefix-list for interface out */
191 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
192 plist
= prefix_list_lookup(AFI_IP
,
193 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
195 ei
->prefix
[EIGRP_FILTER_OUT
] = plist
;
197 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
199 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
201 // TODO: check Graceful restart after 10sec
203 /* Cancel GR scheduled */
204 thread_cancel(&(ei
->t_distribute
));
205 /* schedule Graceful restart for interface in 10sec */
206 thread_add_timer(master
, eigrp_distribute_timer_interface
, ei
, 10,
211 * Function called by prefix-list and access-list update
213 void eigrp_distribute_update_interface(struct interface
*ifp
)
215 struct distribute
*dist
;
218 eigrp
= eigrp_lookup(ifp
->vrf
->vrf_id
);
221 dist
= distribute_lookup(eigrp
->distribute_ctx
, ifp
->name
);
223 eigrp_distribute_update(eigrp
->distribute_ctx
,
227 /* Update all interface's distribute list.
228 * Function used in hook for prefix-list
230 void eigrp_distribute_update_all(struct prefix_list
*notused
)
233 struct interface
*ifp
;
235 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
236 FOR_ALL_INTERFACES (vrf
, ifp
)
237 eigrp_distribute_update_interface(ifp
);
242 * Function used in hook for acces-list
244 void eigrp_distribute_update_all_wrapper(struct access_list
*notused
)
246 eigrp_distribute_update_all(NULL
);
250 * @fn eigrp_distribute_timer_process
252 * @param[in] thread current execution thread timer is associated with
254 * @return int always returns 0
257 * Called when 10sec waiting time expire and
258 * executes Graceful restart for whole process
260 int eigrp_distribute_timer_process(struct thread
*thread
)
264 eigrp
= THREAD_ARG(thread
);
266 /* execute GR for whole process */
267 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_FILTER
, NULL
);
273 * @fn eigrp_distribute_timer_interface
275 * @param[in] thread current execution thread timer is associated with
277 * @return int always returns 0
280 * Called when 10sec waiting time expire and
281 * executes Graceful restart for interface
283 int eigrp_distribute_timer_interface(struct thread
*thread
)
285 struct eigrp_interface
*ei
;
287 ei
= THREAD_ARG(thread
);
288 ei
->t_distribute
= NULL
;
290 /* execute GR for interface */
291 eigrp_update_send_interface_GR(ei
, EIGRP_GR_FILTER
, NULL
);