]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_routemap.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / isisd / isis_routemap.c
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 "thread.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 }