]>
Commit | Line | Data |
---|---|---|
1 | // SPDX-License-Identifier: GPL-2.0-or-later | |
2 | /* | |
3 | * IS-IS Rout(e)ing protocol - isis_routemap.c | |
4 | * | |
5 | * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> | |
6 | */ | |
7 | ||
8 | #include <zebra.h> | |
9 | ||
10 | #include "command.h" | |
11 | #include "filter.h" | |
12 | #include "hash.h" | |
13 | #include "if.h" | |
14 | #include "linklist.h" | |
15 | #include "log.h" | |
16 | #include "memory.h" | |
17 | #include "prefix.h" | |
18 | #include "plist.h" | |
19 | #include "routemap.h" | |
20 | #include "table.h" | |
21 | #include "frrevent.h" | |
22 | #include "vty.h" | |
23 | ||
24 | #include "isis_constants.h" | |
25 | #include "isis_common.h" | |
26 | #include "isis_flags.h" | |
27 | #include "isisd.h" | |
28 | #include "isis_misc.h" | |
29 | #include "isis_adjacency.h" | |
30 | #include "isis_circuit.h" | |
31 | #include "isis_pdu.h" | |
32 | #include "isis_lsp.h" | |
33 | #include "isis_spf.h" | |
34 | #include "isis_route.h" | |
35 | #include "isis_zebra.h" | |
36 | #include "isis_routemap.h" | |
37 | ||
38 | static enum route_map_cmd_result_t | |
39 | route_match_ip_address(void *rule, const struct prefix *prefix, void *object) | |
40 | { | |
41 | struct access_list *alist; | |
42 | ||
43 | alist = access_list_lookup(AFI_IP, (char *)rule); | |
44 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
45 | return RMAP_MATCH; | |
46 | ||
47 | return RMAP_NOMATCH; | |
48 | } | |
49 | ||
50 | static void *route_match_ip_address_compile(const char *arg) | |
51 | { | |
52 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); | |
53 | } | |
54 | ||
55 | static void route_match_ip_address_free(void *rule) | |
56 | { | |
57 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); | |
58 | } | |
59 | ||
60 | static const struct route_map_rule_cmd route_match_ip_address_cmd = { | |
61 | "ip address", | |
62 | route_match_ip_address, | |
63 | route_match_ip_address_compile, | |
64 | route_match_ip_address_free | |
65 | }; | |
66 | ||
67 | /* ------------------------------------------------------------*/ | |
68 | ||
69 | static enum route_map_cmd_result_t | |
70 | route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, | |
71 | void *object) | |
72 | { | |
73 | struct prefix_list *plist; | |
74 | ||
75 | plist = prefix_list_lookup(AFI_IP, (char *)rule); | |
76 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
77 | return RMAP_MATCH; | |
78 | ||
79 | return RMAP_NOMATCH; | |
80 | } | |
81 | ||
82 | static void *route_match_ip_address_prefix_list_compile(const char *arg) | |
83 | { | |
84 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); | |
85 | } | |
86 | ||
87 | static void route_match_ip_address_prefix_list_free(void *rule) | |
88 | { | |
89 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); | |
90 | } | |
91 | ||
92 | static const struct route_map_rule_cmd | |
93 | route_match_ip_address_prefix_list_cmd = { | |
94 | "ip address prefix-list", | |
95 | route_match_ip_address_prefix_list, | |
96 | route_match_ip_address_prefix_list_compile, | |
97 | route_match_ip_address_prefix_list_free | |
98 | }; | |
99 | ||
100 | /* ------------------------------------------------------------*/ | |
101 | ||
102 | /* `match tag TAG' */ | |
103 | /* Match function return 1 if match is success else return zero. */ | |
104 | static enum route_map_cmd_result_t | |
105 | route_match_tag(void *rule, const struct prefix *p, void *object) | |
106 | { | |
107 | route_tag_t *tag; | |
108 | struct isis_ext_info *info; | |
109 | route_tag_t info_tag; | |
110 | ||
111 | tag = rule; | |
112 | info = object; | |
113 | ||
114 | info_tag = info->tag; | |
115 | if (info_tag == *tag) | |
116 | return RMAP_MATCH; | |
117 | else | |
118 | return RMAP_NOMATCH; | |
119 | } | |
120 | ||
121 | /* Route map commands for tag matching. */ | |
122 | static const struct route_map_rule_cmd route_match_tag_cmd = { | |
123 | "tag", | |
124 | route_match_tag, | |
125 | route_map_rule_tag_compile, | |
126 | route_map_rule_tag_free, | |
127 | }; | |
128 | ||
129 | /* ------------------------------------------------------------*/ | |
130 | ||
131 | static enum route_map_cmd_result_t | |
132 | route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object) | |
133 | { | |
134 | struct access_list *alist; | |
135 | ||
136 | alist = access_list_lookup(AFI_IP6, (char *)rule); | |
137 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
138 | return RMAP_MATCH; | |
139 | ||
140 | return RMAP_NOMATCH; | |
141 | } | |
142 | ||
143 | static void *route_match_ipv6_address_compile(const char *arg) | |
144 | { | |
145 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); | |
146 | } | |
147 | ||
148 | static void route_match_ipv6_address_free(void *rule) | |
149 | { | |
150 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); | |
151 | } | |
152 | ||
153 | static const struct route_map_rule_cmd route_match_ipv6_address_cmd = { | |
154 | "ipv6 address", | |
155 | route_match_ipv6_address, | |
156 | route_match_ipv6_address_compile, | |
157 | route_match_ipv6_address_free | |
158 | }; | |
159 | ||
160 | /* ------------------------------------------------------------*/ | |
161 | ||
162 | static enum route_map_cmd_result_t | |
163 | route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, | |
164 | void *object) | |
165 | { | |
166 | struct prefix_list *plist; | |
167 | ||
168 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); | |
169 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
170 | return RMAP_MATCH; | |
171 | ||
172 | return RMAP_NOMATCH; | |
173 | } | |
174 | ||
175 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) | |
176 | { | |
177 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); | |
178 | } | |
179 | ||
180 | static void route_match_ipv6_address_prefix_list_free(void *rule) | |
181 | { | |
182 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); | |
183 | } | |
184 | ||
185 | static const struct route_map_rule_cmd | |
186 | route_match_ipv6_address_prefix_list_cmd = { | |
187 | "ipv6 address prefix-list", | |
188 | route_match_ipv6_address_prefix_list, | |
189 | route_match_ipv6_address_prefix_list_compile, | |
190 | route_match_ipv6_address_prefix_list_free | |
191 | }; | |
192 | ||
193 | /* ------------------------------------------------------------*/ | |
194 | ||
195 | static enum route_map_cmd_result_t | |
196 | route_set_metric(void *rule, const struct prefix *prefix, void *object) | |
197 | { | |
198 | uint32_t *metric; | |
199 | struct isis_ext_info *info; | |
200 | ||
201 | metric = rule; | |
202 | info = object; | |
203 | ||
204 | info->metric = *metric; | |
205 | ||
206 | return RMAP_OKAY; | |
207 | } | |
208 | ||
209 | static void *route_set_metric_compile(const char *arg) | |
210 | { | |
211 | unsigned long metric; | |
212 | char *endp; | |
213 | uint32_t *ret; | |
214 | ||
215 | metric = strtoul(arg, &endp, 10); | |
216 | if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) | |
217 | return NULL; | |
218 | ||
219 | ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); | |
220 | *ret = metric; | |
221 | ||
222 | return ret; | |
223 | } | |
224 | ||
225 | static void route_set_metric_free(void *rule) | |
226 | { | |
227 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); | |
228 | } | |
229 | ||
230 | static const struct route_map_rule_cmd route_set_metric_cmd = { | |
231 | "metric", | |
232 | route_set_metric, | |
233 | route_set_metric_compile, | |
234 | route_set_metric_free | |
235 | }; | |
236 | ||
237 | void isis_route_map_init(void) | |
238 | { | |
239 | route_map_init(); | |
240 | ||
241 | route_map_match_ip_address_hook(generic_match_add); | |
242 | route_map_no_match_ip_address_hook(generic_match_delete); | |
243 | ||
244 | route_map_match_ip_address_prefix_list_hook(generic_match_add); | |
245 | route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); | |
246 | ||
247 | route_map_match_ipv6_address_hook(generic_match_add); | |
248 | route_map_no_match_ipv6_address_hook(generic_match_delete); | |
249 | ||
250 | route_map_match_ipv6_address_prefix_list_hook(generic_match_add); | |
251 | route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); | |
252 | ||
253 | route_map_match_tag_hook(generic_match_add); | |
254 | route_map_no_match_tag_hook(generic_match_delete); | |
255 | ||
256 | route_map_set_metric_hook(generic_set_add); | |
257 | route_map_no_set_metric_hook(generic_set_delete); | |
258 | ||
259 | route_map_install_match(&route_match_ip_address_cmd); | |
260 | route_map_install_match(&route_match_ip_address_prefix_list_cmd); | |
261 | route_map_install_match(&route_match_ipv6_address_cmd); | |
262 | route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); | |
263 | route_map_install_match(&route_match_tag_cmd); | |
264 | route_map_install_set(&route_set_metric_cmd); | |
265 | } |