]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_routemap.c
Merge pull request #4027 from pguibert6WIND/fix_interface_rtadv
[mirror_frr.git] / isisd / isis_routemap.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_routemap.c
3 *
4 * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "filter.h"
25 #include "hash.h"
26 #include "if.h"
27 #include "linklist.h"
28 #include "log.h"
29 #include "memory.h"
30 #include "prefix.h"
31 #include "plist.h"
32 #include "routemap.h"
33 #include "table.h"
34 #include "thread.h"
35 #include "vty.h"
36
37 #include "isis_constants.h"
38 #include "isis_common.h"
39 #include "isis_flags.h"
40 #include "isisd.h"
41 #include "isis_misc.h"
42 #include "isis_adjacency.h"
43 #include "isis_circuit.h"
44 #include "isis_pdu.h"
45 #include "isis_lsp.h"
46 #include "isis_spf.h"
47 #include "isis_route.h"
48 #include "isis_zebra.h"
49 #include "isis_routemap.h"
50
51 static route_map_result_t route_match_ip_address(void *rule,
52 const struct prefix *prefix,
53 route_map_object_t type,
54 void *object)
55 {
56 struct access_list *alist;
57
58 if (type != RMAP_ISIS)
59 return RMAP_NOMATCH;
60
61 alist = access_list_lookup(AFI_IP, (char *)rule);
62 if (access_list_apply(alist, prefix) != FILTER_DENY)
63 return RMAP_MATCH;
64
65 return RMAP_NOMATCH;
66 }
67
68 static void *route_match_ip_address_compile(const char *arg)
69 {
70 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
71 }
72
73 static void route_match_ip_address_free(void *rule)
74 {
75 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
76 }
77
78 static struct route_map_rule_cmd route_match_ip_address_cmd = {
79 "ip address", route_match_ip_address, route_match_ip_address_compile,
80 route_match_ip_address_free};
81
82 /* ------------------------------------------------------------*/
83
84 static route_map_result_t
85 route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
86 route_map_object_t type, void *object)
87 {
88 struct prefix_list *plist;
89
90 if (type != RMAP_ISIS)
91 return RMAP_NOMATCH;
92
93 plist = prefix_list_lookup(AFI_IP, (char *)rule);
94 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
95 return RMAP_MATCH;
96
97 return RMAP_NOMATCH;
98 }
99
100 static void *route_match_ip_address_prefix_list_compile(const char *arg)
101 {
102 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
103 }
104
105 static void route_match_ip_address_prefix_list_free(void *rule)
106 {
107 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
108 }
109
110 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
111 "ip address prefix-list", route_match_ip_address_prefix_list,
112 route_match_ip_address_prefix_list_compile,
113 route_match_ip_address_prefix_list_free};
114
115 /* ------------------------------------------------------------*/
116
117 static route_map_result_t route_match_ipv6_address(void *rule,
118 const struct prefix *prefix,
119 route_map_object_t type,
120 void *object)
121 {
122 struct access_list *alist;
123
124 if (type != RMAP_ISIS)
125 return RMAP_NOMATCH;
126
127 alist = access_list_lookup(AFI_IP6, (char *)rule);
128 if (access_list_apply(alist, prefix) != FILTER_DENY)
129 return RMAP_MATCH;
130
131 return RMAP_NOMATCH;
132 }
133
134 static void *route_match_ipv6_address_compile(const char *arg)
135 {
136 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
137 }
138
139 static void route_match_ipv6_address_free(void *rule)
140 {
141 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
142 }
143
144 static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
145 "ipv6 address", route_match_ipv6_address,
146 route_match_ipv6_address_compile, route_match_ipv6_address_free};
147
148 /* ------------------------------------------------------------*/
149
150 static route_map_result_t
151 route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
152 route_map_object_t type, void *object)
153 {
154 struct prefix_list *plist;
155
156 if (type != RMAP_ISIS)
157 return RMAP_NOMATCH;
158
159 plist = prefix_list_lookup(AFI_IP6, (char *)rule);
160 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
161 return RMAP_MATCH;
162
163 return RMAP_NOMATCH;
164 }
165
166 static void *route_match_ipv6_address_prefix_list_compile(const char *arg)
167 {
168 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
169 }
170
171 static void route_match_ipv6_address_prefix_list_free(void *rule)
172 {
173 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
174 }
175
176 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
177 "ipv6 address prefix-list", route_match_ipv6_address_prefix_list,
178 route_match_ipv6_address_prefix_list_compile,
179 route_match_ipv6_address_prefix_list_free};
180
181 /* ------------------------------------------------------------*/
182
183 static route_map_result_t route_set_metric(void *rule,
184 const struct prefix *prefix,
185 route_map_object_t type,
186 void *object)
187 {
188 uint32_t *metric;
189 struct isis_ext_info *info;
190
191 if (type == RMAP_ISIS) {
192 metric = rule;
193 info = object;
194
195 info->metric = *metric;
196 }
197 return RMAP_OKAY;
198 }
199
200 static void *route_set_metric_compile(const char *arg)
201 {
202 unsigned long metric;
203 char *endp;
204 uint32_t *ret;
205
206 metric = strtoul(arg, &endp, 10);
207 if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC)
208 return NULL;
209
210 ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret));
211 *ret = metric;
212
213 return ret;
214 }
215
216 static void route_set_metric_free(void *rule)
217 {
218 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
219 }
220
221 static struct route_map_rule_cmd route_set_metric_cmd = {
222 "metric", route_set_metric, route_set_metric_compile,
223 route_set_metric_free};
224
225 void isis_route_map_init(void)
226 {
227 route_map_init();
228
229 route_map_match_ip_address_hook(generic_match_add);
230 route_map_no_match_ip_address_hook(generic_match_delete);
231
232 route_map_match_ip_address_prefix_list_hook(generic_match_add);
233 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
234
235 route_map_match_ipv6_address_hook(generic_match_add);
236 route_map_no_match_ipv6_address_hook(generic_match_delete);
237
238 route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
239 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
240
241 route_map_set_metric_hook(generic_set_add);
242 route_map_no_set_metric_hook(generic_set_delete);
243
244 route_map_install_match(&route_match_ip_address_cmd);
245 route_map_install_match(&route_match_ip_address_prefix_list_cmd);
246 route_map_install_match(&route_match_ipv6_address_cmd);
247 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
248 route_map_install_set(&route_set_metric_cmd);
249 }