]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
eb5d44eb | 2 | /* |
f3ccedaa | 3 | * IS-IS Rout(e)ing protocol - isis_routemap.c |
eb5d44eb | 4 | * |
f3ccedaa | 5 | * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> |
eb5d44eb | 6 | */ |
f3ccedaa | 7 | |
eb5d44eb | 8 | #include <zebra.h> |
eb5d44eb | 9 | |
f3ccedaa CF |
10 | #include "command.h" |
11 | #include "filter.h" | |
12 | #include "hash.h" | |
13 | #include "if.h" | |
eb5d44eb | 14 | #include "linklist.h" |
eb5d44eb | 15 | #include "log.h" |
16 | #include "memory.h" | |
17 | #include "prefix.h" | |
f3ccedaa | 18 | #include "plist.h" |
eb5d44eb | 19 | #include "routemap.h" |
f3ccedaa CF |
20 | #include "table.h" |
21 | #include "thread.h" | |
22 | #include "vty.h" | |
eb5d44eb | 23 | |
24 | #include "isis_constants.h" | |
25 | #include "isis_common.h" | |
3f045a08 | 26 | #include "isis_flags.h" |
eb5d44eb | 27 | #include "isisd.h" |
28 | #include "isis_misc.h" | |
29 | #include "isis_adjacency.h" | |
30 | #include "isis_circuit.h" | |
eb5d44eb | 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" | |
f3ccedaa | 36 | #include "isis_routemap.h" |
eb5d44eb | 37 | |
b68885f9 | 38 | static enum route_map_cmd_result_t |
1782514f | 39 | route_match_ip_address(void *rule, const struct prefix *prefix, void *object) |
f3ccedaa | 40 | { |
d62a17ae | 41 | struct access_list *alist; |
eb5d44eb | 42 | |
d62a17ae | 43 | alist = access_list_lookup(AFI_IP, (char *)rule); |
44 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
45 | return RMAP_MATCH; | |
41b36e90 | 46 | |
d62a17ae | 47 | return RMAP_NOMATCH; |
f3ccedaa CF |
48 | } |
49 | ||
d62a17ae | 50 | static void *route_match_ip_address_compile(const char *arg) |
f3ccedaa | 51 | { |
d62a17ae | 52 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
53 | } |
54 | ||
d62a17ae | 55 | static void route_match_ip_address_free(void *rule) |
f3ccedaa | 56 | { |
d62a17ae | 57 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
58 | } |
59 | ||
364deb04 DL |
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 | }; | |
f3ccedaa CF |
66 | |
67 | /* ------------------------------------------------------------*/ | |
68 | ||
b68885f9 | 69 | static enum route_map_cmd_result_t |
123214ef | 70 | route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, |
1782514f | 71 | void *object) |
f3ccedaa | 72 | { |
d62a17ae | 73 | struct prefix_list *plist; |
f3ccedaa | 74 | |
d62a17ae | 75 | plist = prefix_list_lookup(AFI_IP, (char *)rule); |
76 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
77 | return RMAP_MATCH; | |
f3ccedaa | 78 | |
d62a17ae | 79 | return RMAP_NOMATCH; |
f3ccedaa CF |
80 | } |
81 | ||
d62a17ae | 82 | static void *route_match_ip_address_prefix_list_compile(const char *arg) |
f3ccedaa | 83 | { |
d62a17ae | 84 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
85 | } |
86 | ||
d62a17ae | 87 | static void route_match_ip_address_prefix_list_free(void *rule) |
f3ccedaa | 88 | { |
d62a17ae | 89 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
90 | } |
91 | ||
364deb04 DL |
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, | |
d62a17ae | 96 | route_match_ip_address_prefix_list_compile, |
364deb04 DL |
97 | route_match_ip_address_prefix_list_free |
98 | }; | |
f3ccedaa CF |
99 | |
100 | /* ------------------------------------------------------------*/ | |
101 | ||
3b1e3aab EA |
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 | ||
b68885f9 | 131 | static enum route_map_cmd_result_t |
1782514f | 132 | route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object) |
eb5d44eb | 133 | { |
d62a17ae | 134 | struct access_list *alist; |
f390d2c7 | 135 | |
d62a17ae | 136 | alist = access_list_lookup(AFI_IP6, (char *)rule); |
137 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
138 | return RMAP_MATCH; | |
f3ccedaa | 139 | |
d62a17ae | 140 | return RMAP_NOMATCH; |
f3ccedaa CF |
141 | } |
142 | ||
d62a17ae | 143 | static void *route_match_ipv6_address_compile(const char *arg) |
f3ccedaa | 144 | { |
d62a17ae | 145 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
146 | } |
147 | ||
d62a17ae | 148 | static void route_match_ipv6_address_free(void *rule) |
f3ccedaa | 149 | { |
d62a17ae | 150 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
151 | } |
152 | ||
364deb04 DL |
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 | }; | |
f3ccedaa CF |
159 | |
160 | /* ------------------------------------------------------------*/ | |
161 | ||
b68885f9 | 162 | static enum route_map_cmd_result_t |
123214ef | 163 | route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, |
1782514f | 164 | void *object) |
f3ccedaa | 165 | { |
d62a17ae | 166 | struct prefix_list *plist; |
f390d2c7 | 167 | |
d62a17ae | 168 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); |
169 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
170 | return RMAP_MATCH; | |
f3ccedaa | 171 | |
d62a17ae | 172 | return RMAP_NOMATCH; |
f3ccedaa CF |
173 | } |
174 | ||
d62a17ae | 175 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) |
f3ccedaa | 176 | { |
d62a17ae | 177 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
178 | } |
179 | ||
d62a17ae | 180 | static void route_match_ipv6_address_prefix_list_free(void *rule) |
f3ccedaa | 181 | { |
d62a17ae | 182 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
183 | } |
184 | ||
364deb04 DL |
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, | |
d62a17ae | 189 | route_match_ipv6_address_prefix_list_compile, |
364deb04 DL |
190 | route_match_ipv6_address_prefix_list_free |
191 | }; | |
f3ccedaa CF |
192 | |
193 | /* ------------------------------------------------------------*/ | |
194 | ||
b68885f9 | 195 | static enum route_map_cmd_result_t |
1782514f | 196 | route_set_metric(void *rule, const struct prefix *prefix, void *object) |
f3ccedaa | 197 | { |
d62a17ae | 198 | uint32_t *metric; |
199 | struct isis_ext_info *info; | |
f3ccedaa | 200 | |
1782514f DS |
201 | metric = rule; |
202 | info = object; | |
203 | ||
204 | info->metric = *metric; | |
f3ccedaa | 205 | |
d62a17ae | 206 | return RMAP_OKAY; |
eb5d44eb | 207 | } |
208 | ||
d62a17ae | 209 | static void *route_set_metric_compile(const char *arg) |
f3ccedaa | 210 | { |
d62a17ae | 211 | unsigned long metric; |
212 | char *endp; | |
213 | uint32_t *ret; | |
f3ccedaa | 214 | |
d62a17ae | 215 | metric = strtoul(arg, &endp, 10); |
216 | if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) | |
217 | return NULL; | |
f3ccedaa | 218 | |
d62a17ae | 219 | ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); |
220 | *ret = metric; | |
f3ccedaa | 221 | |
d62a17ae | 222 | return ret; |
f3ccedaa CF |
223 | } |
224 | ||
d62a17ae | 225 | static void route_set_metric_free(void *rule) |
eb5d44eb | 226 | { |
d62a17ae | 227 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
228 | } |
229 | ||
364deb04 DL |
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 | }; | |
d62a17ae | 236 | |
237 | void isis_route_map_init(void) | |
f3ccedaa | 238 | { |
d62a17ae | 239 | route_map_init(); |
f3ccedaa | 240 | |
d62a17ae | 241 | route_map_match_ip_address_hook(generic_match_add); |
242 | route_map_no_match_ip_address_hook(generic_match_delete); | |
f3ccedaa | 243 | |
d62a17ae | 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); | |
f3ccedaa | 246 | |
d62a17ae | 247 | route_map_match_ipv6_address_hook(generic_match_add); |
248 | route_map_no_match_ipv6_address_hook(generic_match_delete); | |
f3ccedaa | 249 | |
d62a17ae | 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); | |
f3ccedaa | 252 | |
3b1e3aab EA |
253 | route_map_match_tag_hook(generic_match_add); |
254 | route_map_no_match_tag_hook(generic_match_delete); | |
255 | ||
d62a17ae | 256 | route_map_set_metric_hook(generic_set_add); |
257 | route_map_no_set_metric_hook(generic_set_delete); | |
f3ccedaa | 258 | |
d62a17ae | 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); | |
3b1e3aab | 263 | route_map_install_match(&route_match_tag_cmd); |
d62a17ae | 264 | route_map_install_set(&route_set_metric_cmd); |
eb5d44eb | 265 | } |