]>
Commit | Line | Data |
---|---|---|
eb5d44eb | 1 | /* |
f3ccedaa | 2 | * IS-IS Rout(e)ing protocol - isis_routemap.c |
eb5d44eb | 3 | * |
f3ccedaa | 4 | * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> |
eb5d44eb | 5 | * |
d62a17ae | 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) | |
eb5d44eb | 9 | * any later version. |
10 | * | |
d62a17ae | 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 | |
eb5d44eb | 14 | * more details. |
896014f4 DL |
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 | |
eb5d44eb | 19 | */ |
f3ccedaa | 20 | |
eb5d44eb | 21 | #include <zebra.h> |
eb5d44eb | 22 | |
f3ccedaa CF |
23 | #include "command.h" |
24 | #include "filter.h" | |
25 | #include "hash.h" | |
26 | #include "if.h" | |
eb5d44eb | 27 | #include "linklist.h" |
eb5d44eb | 28 | #include "log.h" |
29 | #include "memory.h" | |
30 | #include "prefix.h" | |
f3ccedaa | 31 | #include "plist.h" |
eb5d44eb | 32 | #include "routemap.h" |
f3ccedaa CF |
33 | #include "table.h" |
34 | #include "thread.h" | |
35 | #include "vty.h" | |
eb5d44eb | 36 | |
37 | #include "isis_constants.h" | |
38 | #include "isis_common.h" | |
3f045a08 | 39 | #include "isis_flags.h" |
eb5d44eb | 40 | #include "isisd.h" |
41 | #include "isis_misc.h" | |
42 | #include "isis_adjacency.h" | |
43 | #include "isis_circuit.h" | |
eb5d44eb | 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" | |
f3ccedaa | 49 | #include "isis_routemap.h" |
eb5d44eb | 50 | |
b68885f9 LK |
51 | static enum route_map_cmd_result_t |
52 | route_match_ip_address(void *rule, const struct prefix *prefix, | |
53 | route_map_object_t type, void *object) | |
f3ccedaa | 54 | { |
d62a17ae | 55 | struct access_list *alist; |
eb5d44eb | 56 | |
d62a17ae | 57 | if (type != RMAP_ISIS) |
58 | return RMAP_NOMATCH; | |
41b36e90 | 59 | |
d62a17ae | 60 | alist = access_list_lookup(AFI_IP, (char *)rule); |
61 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
62 | return RMAP_MATCH; | |
41b36e90 | 63 | |
d62a17ae | 64 | return RMAP_NOMATCH; |
f3ccedaa CF |
65 | } |
66 | ||
d62a17ae | 67 | static void *route_match_ip_address_compile(const char *arg) |
f3ccedaa | 68 | { |
d62a17ae | 69 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
70 | } |
71 | ||
d62a17ae | 72 | static void route_match_ip_address_free(void *rule) |
f3ccedaa | 73 | { |
d62a17ae | 74 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
75 | } |
76 | ||
364deb04 DL |
77 | static const struct route_map_rule_cmd route_match_ip_address_cmd = { |
78 | "ip address", | |
79 | route_match_ip_address, | |
80 | route_match_ip_address_compile, | |
81 | route_match_ip_address_free | |
82 | }; | |
f3ccedaa CF |
83 | |
84 | /* ------------------------------------------------------------*/ | |
85 | ||
b68885f9 | 86 | static enum route_map_cmd_result_t |
123214ef | 87 | route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, |
d62a17ae | 88 | route_map_object_t type, void *object) |
f3ccedaa | 89 | { |
d62a17ae | 90 | struct prefix_list *plist; |
f3ccedaa | 91 | |
d62a17ae | 92 | if (type != RMAP_ISIS) |
93 | return RMAP_NOMATCH; | |
f3ccedaa | 94 | |
d62a17ae | 95 | plist = prefix_list_lookup(AFI_IP, (char *)rule); |
96 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
97 | return RMAP_MATCH; | |
f3ccedaa | 98 | |
d62a17ae | 99 | return RMAP_NOMATCH; |
f3ccedaa CF |
100 | } |
101 | ||
d62a17ae | 102 | static void *route_match_ip_address_prefix_list_compile(const char *arg) |
f3ccedaa | 103 | { |
d62a17ae | 104 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
105 | } |
106 | ||
d62a17ae | 107 | static void route_match_ip_address_prefix_list_free(void *rule) |
f3ccedaa | 108 | { |
d62a17ae | 109 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
110 | } |
111 | ||
364deb04 DL |
112 | static const struct route_map_rule_cmd |
113 | route_match_ip_address_prefix_list_cmd = { | |
114 | "ip address prefix-list", | |
115 | route_match_ip_address_prefix_list, | |
d62a17ae | 116 | route_match_ip_address_prefix_list_compile, |
364deb04 DL |
117 | route_match_ip_address_prefix_list_free |
118 | }; | |
f3ccedaa CF |
119 | |
120 | /* ------------------------------------------------------------*/ | |
121 | ||
b68885f9 LK |
122 | static enum route_map_cmd_result_t |
123 | route_match_ipv6_address(void *rule, const struct prefix *prefix, | |
124 | route_map_object_t type, void *object) | |
eb5d44eb | 125 | { |
d62a17ae | 126 | struct access_list *alist; |
f390d2c7 | 127 | |
d62a17ae | 128 | if (type != RMAP_ISIS) |
129 | return RMAP_NOMATCH; | |
f3ccedaa | 130 | |
d62a17ae | 131 | alist = access_list_lookup(AFI_IP6, (char *)rule); |
132 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
133 | return RMAP_MATCH; | |
f3ccedaa | 134 | |
d62a17ae | 135 | return RMAP_NOMATCH; |
f3ccedaa CF |
136 | } |
137 | ||
d62a17ae | 138 | static void *route_match_ipv6_address_compile(const char *arg) |
f3ccedaa | 139 | { |
d62a17ae | 140 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
141 | } |
142 | ||
d62a17ae | 143 | static void route_match_ipv6_address_free(void *rule) |
f3ccedaa | 144 | { |
d62a17ae | 145 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
146 | } |
147 | ||
364deb04 DL |
148 | static const struct route_map_rule_cmd route_match_ipv6_address_cmd = { |
149 | "ipv6 address", | |
150 | route_match_ipv6_address, | |
151 | route_match_ipv6_address_compile, | |
152 | route_match_ipv6_address_free | |
153 | }; | |
f3ccedaa CF |
154 | |
155 | /* ------------------------------------------------------------*/ | |
156 | ||
b68885f9 | 157 | static enum route_map_cmd_result_t |
123214ef | 158 | route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, |
d62a17ae | 159 | route_map_object_t type, void *object) |
f3ccedaa | 160 | { |
d62a17ae | 161 | struct prefix_list *plist; |
f390d2c7 | 162 | |
d62a17ae | 163 | if (type != RMAP_ISIS) |
164 | return RMAP_NOMATCH; | |
f3ccedaa | 165 | |
d62a17ae | 166 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); |
167 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
168 | return RMAP_MATCH; | |
f3ccedaa | 169 | |
d62a17ae | 170 | return RMAP_NOMATCH; |
f3ccedaa CF |
171 | } |
172 | ||
d62a17ae | 173 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) |
f3ccedaa | 174 | { |
d62a17ae | 175 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
176 | } |
177 | ||
d62a17ae | 178 | static void route_match_ipv6_address_prefix_list_free(void *rule) |
f3ccedaa | 179 | { |
d62a17ae | 180 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
181 | } |
182 | ||
364deb04 DL |
183 | static const struct route_map_rule_cmd |
184 | route_match_ipv6_address_prefix_list_cmd = { | |
185 | "ipv6 address prefix-list", | |
186 | route_match_ipv6_address_prefix_list, | |
d62a17ae | 187 | route_match_ipv6_address_prefix_list_compile, |
364deb04 DL |
188 | route_match_ipv6_address_prefix_list_free |
189 | }; | |
f3ccedaa CF |
190 | |
191 | /* ------------------------------------------------------------*/ | |
192 | ||
b68885f9 LK |
193 | static enum route_map_cmd_result_t |
194 | route_set_metric(void *rule, const struct prefix *prefix, | |
195 | route_map_object_t type, void *object) | |
f3ccedaa | 196 | { |
d62a17ae | 197 | uint32_t *metric; |
198 | struct isis_ext_info *info; | |
f3ccedaa | 199 | |
d62a17ae | 200 | if (type == RMAP_ISIS) { |
201 | metric = rule; | |
202 | info = object; | |
f3ccedaa | 203 | |
d62a17ae | 204 | info->metric = *metric; |
205 | } | |
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 | |
d62a17ae | 253 | route_map_set_metric_hook(generic_set_add); |
254 | route_map_no_set_metric_hook(generic_set_delete); | |
f3ccedaa | 255 | |
d62a17ae | 256 | route_map_install_match(&route_match_ip_address_cmd); |
257 | route_map_install_match(&route_match_ip_address_prefix_list_cmd); | |
258 | route_map_install_match(&route_match_ipv6_address_cmd); | |
259 | route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); | |
260 | route_map_install_set(&route_set_metric_cmd); | |
eb5d44eb | 261 | } |