]>
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 | * |
ac4d0be5 | 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 | * | |
ac4d0be5 | 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. |
15 | ||
ac4d0be5 | 16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; if not, write to the Free Software Foundation, Inc., | |
eb5d44eb | 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
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 "dict.h" |
41 | #include "isisd.h" | |
42 | #include "isis_misc.h" | |
43 | #include "isis_adjacency.h" | |
44 | #include "isis_circuit.h" | |
45 | #include "isis_tlv.h" | |
46 | #include "isis_pdu.h" | |
47 | #include "isis_lsp.h" | |
48 | #include "isis_spf.h" | |
49 | #include "isis_route.h" | |
50 | #include "isis_zebra.h" | |
f3ccedaa | 51 | #include "isis_routemap.h" |
eb5d44eb | 52 | |
ac4d0be5 | 53 | static route_map_result_t route_match_ip_address(void *rule, |
54 | struct prefix *prefix, | |
55 | route_map_object_t type, | |
56 | void *object) | |
f3ccedaa | 57 | { |
ac4d0be5 | 58 | struct access_list *alist; |
eb5d44eb | 59 | |
ac4d0be5 | 60 | if (type != RMAP_ISIS) |
61 | return RMAP_NOMATCH; | |
41b36e90 | 62 | |
ac4d0be5 | 63 | alist = access_list_lookup(AFI_IP, (char *)rule); |
64 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
65 | return RMAP_MATCH; | |
41b36e90 | 66 | |
ac4d0be5 | 67 | return RMAP_NOMATCH; |
f3ccedaa CF |
68 | } |
69 | ||
ac4d0be5 | 70 | static void *route_match_ip_address_compile(const char *arg) |
f3ccedaa | 71 | { |
ac4d0be5 | 72 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
73 | } |
74 | ||
ac4d0be5 | 75 | static void route_match_ip_address_free(void *rule) |
f3ccedaa | 76 | { |
ac4d0be5 | 77 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
78 | } |
79 | ||
ac4d0be5 | 80 | static struct route_map_rule_cmd route_match_ip_address_cmd = { |
81 | "ip address", route_match_ip_address, route_match_ip_address_compile, | |
82 | route_match_ip_address_free}; | |
f3ccedaa CF |
83 | |
84 | /* ------------------------------------------------------------*/ | |
85 | ||
86 | static route_map_result_t | |
87 | route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, | |
ac4d0be5 | 88 | route_map_object_t type, void *object) |
f3ccedaa | 89 | { |
ac4d0be5 | 90 | struct prefix_list *plist; |
f3ccedaa | 91 | |
ac4d0be5 | 92 | if (type != RMAP_ISIS) |
93 | return RMAP_NOMATCH; | |
f3ccedaa | 94 | |
ac4d0be5 | 95 | plist = prefix_list_lookup(AFI_IP, (char *)rule); |
96 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
97 | return RMAP_MATCH; | |
f3ccedaa | 98 | |
ac4d0be5 | 99 | return RMAP_NOMATCH; |
f3ccedaa CF |
100 | } |
101 | ||
ac4d0be5 | 102 | static void *route_match_ip_address_prefix_list_compile(const char *arg) |
f3ccedaa | 103 | { |
ac4d0be5 | 104 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
105 | } |
106 | ||
ac4d0be5 | 107 | static void route_match_ip_address_prefix_list_free(void *rule) |
f3ccedaa | 108 | { |
ac4d0be5 | 109 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
110 | } |
111 | ||
ac4d0be5 | 112 | struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { |
113 | "ip address prefix-list", route_match_ip_address_prefix_list, | |
114 | route_match_ip_address_prefix_list_compile, | |
115 | route_match_ip_address_prefix_list_free}; | |
f3ccedaa CF |
116 | |
117 | /* ------------------------------------------------------------*/ | |
118 | ||
ac4d0be5 | 119 | static route_map_result_t route_match_ipv6_address(void *rule, |
120 | struct prefix *prefix, | |
121 | route_map_object_t type, | |
122 | void *object) | |
eb5d44eb | 123 | { |
ac4d0be5 | 124 | struct access_list *alist; |
f390d2c7 | 125 | |
ac4d0be5 | 126 | if (type != RMAP_ISIS) |
127 | return RMAP_NOMATCH; | |
f3ccedaa | 128 | |
ac4d0be5 | 129 | alist = access_list_lookup(AFI_IP6, (char *)rule); |
130 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
131 | return RMAP_MATCH; | |
f3ccedaa | 132 | |
ac4d0be5 | 133 | return RMAP_NOMATCH; |
f3ccedaa CF |
134 | } |
135 | ||
ac4d0be5 | 136 | static void *route_match_ipv6_address_compile(const char *arg) |
f3ccedaa | 137 | { |
ac4d0be5 | 138 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
139 | } |
140 | ||
ac4d0be5 | 141 | static void route_match_ipv6_address_free(void *rule) |
f3ccedaa | 142 | { |
ac4d0be5 | 143 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
144 | } |
145 | ||
ac4d0be5 | 146 | static struct route_map_rule_cmd route_match_ipv6_address_cmd = { |
147 | "ipv6 address", route_match_ipv6_address, | |
148 | route_match_ipv6_address_compile, route_match_ipv6_address_free}; | |
f3ccedaa CF |
149 | |
150 | /* ------------------------------------------------------------*/ | |
151 | ||
152 | static route_map_result_t | |
153 | route_match_ipv6_address_prefix_list(void *rule, struct prefix *prefix, | |
ac4d0be5 | 154 | route_map_object_t type, void *object) |
f3ccedaa | 155 | { |
ac4d0be5 | 156 | struct prefix_list *plist; |
f390d2c7 | 157 | |
ac4d0be5 | 158 | if (type != RMAP_ISIS) |
159 | return RMAP_NOMATCH; | |
f3ccedaa | 160 | |
ac4d0be5 | 161 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); |
162 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
163 | return RMAP_MATCH; | |
f3ccedaa | 164 | |
ac4d0be5 | 165 | return RMAP_NOMATCH; |
f3ccedaa CF |
166 | } |
167 | ||
ac4d0be5 | 168 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) |
f3ccedaa | 169 | { |
ac4d0be5 | 170 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
171 | } |
172 | ||
ac4d0be5 | 173 | static void route_match_ipv6_address_prefix_list_free(void *rule) |
f3ccedaa | 174 | { |
ac4d0be5 | 175 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
176 | } |
177 | ||
ac4d0be5 | 178 | struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { |
179 | "ipv6 address prefix-list", route_match_ipv6_address_prefix_list, | |
180 | route_match_ipv6_address_prefix_list_compile, | |
181 | route_match_ipv6_address_prefix_list_free}; | |
f3ccedaa CF |
182 | |
183 | /* ------------------------------------------------------------*/ | |
184 | ||
ac4d0be5 | 185 | static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, |
186 | route_map_object_t type, | |
187 | void *object) | |
f3ccedaa | 188 | { |
ac4d0be5 | 189 | uint32_t *metric; |
190 | struct isis_ext_info *info; | |
f3ccedaa | 191 | |
ac4d0be5 | 192 | if (type == RMAP_ISIS) { |
193 | metric = rule; | |
194 | info = object; | |
f3ccedaa | 195 | |
ac4d0be5 | 196 | info->metric = *metric; |
197 | } | |
198 | return RMAP_OKAY; | |
eb5d44eb | 199 | } |
200 | ||
ac4d0be5 | 201 | static void *route_set_metric_compile(const char *arg) |
f3ccedaa | 202 | { |
ac4d0be5 | 203 | unsigned long metric; |
204 | char *endp; | |
205 | uint32_t *ret; | |
f3ccedaa | 206 | |
ac4d0be5 | 207 | metric = strtoul(arg, &endp, 10); |
208 | if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) | |
209 | return NULL; | |
f3ccedaa | 210 | |
ac4d0be5 | 211 | ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); |
212 | *ret = metric; | |
f3ccedaa | 213 | |
ac4d0be5 | 214 | return ret; |
f3ccedaa CF |
215 | } |
216 | ||
ac4d0be5 | 217 | static void route_set_metric_free(void *rule) |
eb5d44eb | 218 | { |
ac4d0be5 | 219 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
220 | } |
221 | ||
ac4d0be5 | 222 | static struct route_map_rule_cmd route_set_metric_cmd = { |
223 | "metric", route_set_metric, route_set_metric_compile, | |
224 | route_set_metric_free}; | |
225 | ||
226 | void isis_route_map_init(void) | |
f3ccedaa | 227 | { |
ac4d0be5 | 228 | route_map_init(); |
f3ccedaa | 229 | |
ac4d0be5 | 230 | route_map_match_ip_address_hook(generic_match_add); |
231 | route_map_no_match_ip_address_hook(generic_match_delete); | |
f3ccedaa | 232 | |
ac4d0be5 | 233 | route_map_match_ip_address_prefix_list_hook(generic_match_add); |
234 | route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 235 | |
ac4d0be5 | 236 | route_map_match_ipv6_address_hook(generic_match_add); |
237 | route_map_no_match_ipv6_address_hook(generic_match_delete); | |
f3ccedaa | 238 | |
ac4d0be5 | 239 | route_map_match_ipv6_address_prefix_list_hook(generic_match_add); |
240 | route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 241 | |
ac4d0be5 | 242 | route_map_set_metric_hook(generic_set_add); |
243 | route_map_no_set_metric_hook(generic_set_delete); | |
f3ccedaa | 244 | |
ac4d0be5 | 245 | route_map_install_match(&route_match_ip_address_cmd); |
246 | route_map_install_match(&route_match_ip_address_prefix_list_cmd); | |
247 | route_map_install_match(&route_match_ipv6_address_cmd); | |
248 | route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); | |
249 | route_map_install_set(&route_set_metric_cmd); | |
eb5d44eb | 250 | } |