]>
Commit | Line | Data |
---|---|---|
5921ef9a PJ |
1 | /* zebra routemap. |
2 | * Copyright (C) 2006 IBM Corporation | |
3 | * | |
4 | * This file is part of GNU Zebra. | |
5 | * | |
6 | * GNU Zebra 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 | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * GNU Zebra is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
18 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 | * 02111-1307, USA. | |
20 | */ | |
21 | ||
22 | #include <zebra.h> | |
23 | ||
24 | #include "memory.h" | |
25 | #include "prefix.h" | |
26 | #include "rib.h" | |
27 | #include "routemap.h" | |
28 | #include "command.h" | |
29 | #include "filter.h" | |
30 | #include "plist.h" | |
31 | ||
32 | #include "zebra/zserv.h" | |
33 | ||
34 | /* Add zebra route map rule */ | |
35 | static int | |
36 | zebra_route_match_add(struct vty *vty, struct route_map_index *index, | |
37 | const char *command, const char *arg) | |
38 | { | |
39 | int ret; | |
40 | ||
41 | ret = route_map_add_match (index, command, arg); | |
42 | if (ret) | |
43 | { | |
44 | switch (ret) | |
45 | { | |
46 | case RMAP_RULE_MISSING: | |
47 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
48 | return CMD_WARNING; | |
49 | case RMAP_COMPILE_ERROR: | |
50 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
51 | return CMD_WARNING; | |
52 | } | |
53 | } | |
54 | return CMD_SUCCESS; | |
55 | } | |
56 | ||
57 | /* Delete zebra route map rule. */ | |
58 | static int | |
59 | zebra_route_match_delete (struct vty *vty, struct route_map_index *index, | |
60 | const char *command, const char *arg) | |
61 | { | |
62 | int ret; | |
63 | ||
64 | ret = route_map_delete_match (index, command, arg); | |
65 | if (ret) | |
66 | { | |
67 | switch (ret) | |
68 | { | |
69 | case RMAP_RULE_MISSING: | |
70 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
71 | return CMD_WARNING; | |
72 | case RMAP_COMPILE_ERROR: | |
73 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
74 | return CMD_WARNING; | |
75 | } | |
76 | } | |
77 | return CMD_SUCCESS; | |
78 | } | |
79 | ||
80 | /* Add zebra route map rule. */ | |
81 | static int | |
82 | zebra_route_set_add (struct vty *vty, struct route_map_index *index, | |
83 | const char *command, const char *arg) | |
84 | { | |
85 | int ret; | |
86 | ||
87 | ret = route_map_add_set (index, command, arg); | |
88 | if (ret) | |
89 | { | |
90 | switch (ret) | |
91 | { | |
92 | case RMAP_RULE_MISSING: | |
93 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
94 | return CMD_WARNING; | |
95 | case RMAP_COMPILE_ERROR: | |
96 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
97 | return CMD_WARNING; | |
98 | } | |
99 | } | |
100 | return CMD_SUCCESS; | |
101 | } | |
102 | ||
103 | /* Delete zebra route map rule. */ | |
104 | static int | |
105 | zebra_route_set_delete (struct vty *vty, struct route_map_index *index, | |
106 | const char *command, const char *arg) | |
107 | { | |
108 | int ret; | |
109 | ||
110 | ret = route_map_delete_set (index, command, arg); | |
111 | if (ret) | |
112 | { | |
113 | switch (ret) | |
114 | { | |
115 | case RMAP_RULE_MISSING: | |
116 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
117 | return CMD_WARNING; | |
118 | case RMAP_COMPILE_ERROR: | |
119 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
120 | return CMD_WARNING; | |
121 | } | |
122 | } | |
123 | return CMD_SUCCESS; | |
124 | } | |
125 | ||
126 | \f | |
127 | /* `match interface IFNAME' */ | |
128 | /* Match function return 1 if match is success else return zero. */ | |
129 | static route_map_result_t | |
130 | route_match_interface (void *rule, struct prefix *prefix, | |
131 | route_map_object_t type, void *object) | |
132 | { | |
133 | struct nexthop *nexthop; | |
134 | char *ifname = rule; | |
135 | unsigned int ifindex; | |
136 | ||
137 | if (type == RMAP_ZEBRA) | |
138 | { | |
139 | if (strcasecmp(ifname, "any") == 0) | |
140 | return RMAP_MATCH; | |
141 | ifindex = ifname2ifindex(ifname); | |
142 | if (ifindex == 0) | |
143 | return RMAP_NOMATCH; | |
144 | nexthop = object; | |
145 | if (!nexthop) | |
146 | return RMAP_NOMATCH; | |
147 | if (nexthop->ifindex == ifindex) | |
148 | return RMAP_MATCH; | |
149 | } | |
150 | return RMAP_NOMATCH; | |
151 | } | |
152 | ||
153 | /* Route map `match interface' match statement. `arg' is IFNAME value */ | |
154 | static void * | |
155 | route_match_interface_compile (const char *arg) | |
156 | { | |
157 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
158 | } | |
159 | ||
160 | /* Free route map's compiled `match interface' value. */ | |
161 | static void | |
162 | route_match_interface_free (void *rule) | |
163 | { | |
164 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
165 | } | |
166 | ||
167 | /* Route map commands for interface matching */ | |
168 | struct route_map_rule_cmd route_match_interface_cmd = | |
169 | { | |
170 | "interface", | |
171 | route_match_interface, | |
172 | route_match_interface_compile, | |
173 | route_match_interface_free | |
174 | }; | |
175 | ||
176 | DEFUN (match_interface, | |
177 | match_interface_cmd, | |
178 | "match interface WORD", | |
179 | MATCH_STR | |
180 | "match first hop interface of route\n" | |
181 | "Interface name\n") | |
182 | { | |
183 | return zebra_route_match_add (vty, vty->index, "interface", argv[0]); | |
184 | } | |
185 | ||
186 | DEFUN (no_match_interface, | |
187 | no_match_interface_cmd, | |
188 | "no match interface", | |
189 | NO_STR | |
190 | MATCH_STR | |
191 | "Match first hop interface of route\n") | |
192 | { | |
193 | if (argc == 0) | |
194 | return zebra_route_match_delete (vty, vty->index, "interface", NULL); | |
195 | ||
196 | return zebra_route_match_delete (vty, vty->index, "interface", argv[0]); | |
197 | } | |
198 | ||
199 | ALIAS (no_match_interface, | |
200 | no_match_interface_val_cmd, | |
201 | "no match interface WORD", | |
202 | NO_STR | |
203 | MATCH_STR | |
204 | "Match first hop interface of route\n" | |
205 | "Interface name\n") | |
206 | ||
207 | DEFUN (match_ip_next_hop, | |
208 | match_ip_next_hop_cmd, | |
209 | "match ip next-hop (<1-199>|<1300-2699>|WORD)", | |
210 | MATCH_STR | |
211 | IP_STR | |
212 | "Match next-hop address of route\n" | |
213 | "IP access-list number\n" | |
214 | "IP access-list number (expanded range)\n" | |
215 | "IP Access-list name\n") | |
216 | { | |
217 | return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]); | |
218 | } | |
219 | ||
220 | DEFUN (no_match_ip_next_hop, | |
221 | no_match_ip_next_hop_cmd, | |
222 | "no match ip next-hop", | |
223 | NO_STR | |
224 | MATCH_STR | |
225 | IP_STR | |
226 | "Match next-hop address of route\n") | |
227 | { | |
228 | if (argc == 0) | |
229 | return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL); | |
230 | ||
231 | return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]); | |
232 | } | |
233 | ||
234 | ALIAS (no_match_ip_next_hop, | |
235 | no_match_ip_next_hop_val_cmd, | |
236 | "no match ip next-hop (<1-199>|<1300-2699>|WORD)", | |
237 | NO_STR | |
238 | MATCH_STR | |
239 | IP_STR | |
240 | "Match next-hop address of route\n" | |
241 | "IP access-list number\n" | |
242 | "IP access-list number (expanded range)\n" | |
243 | "IP Access-list name\n") | |
244 | ||
245 | DEFUN (match_ip_next_hop_prefix_list, | |
246 | match_ip_next_hop_prefix_list_cmd, | |
247 | "match ip next-hop prefix-list WORD", | |
248 | MATCH_STR | |
249 | IP_STR | |
250 | "Match next-hop address of route\n" | |
251 | "Match entries of prefix-lists\n" | |
252 | "IP prefix-list name\n") | |
253 | { | |
254 | return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]); | |
255 | } | |
256 | ||
257 | DEFUN (no_match_ip_next_hop_prefix_list, | |
258 | no_match_ip_next_hop_prefix_list_cmd, | |
259 | "no match ip next-hop prefix-list", | |
260 | NO_STR | |
261 | MATCH_STR | |
262 | IP_STR | |
263 | "Match next-hop address of route\n" | |
264 | "Match entries of prefix-lists\n") | |
265 | { | |
266 | if (argc == 0) | |
267 | return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL); | |
268 | ||
269 | return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]); | |
270 | } | |
271 | ||
272 | ALIAS (no_match_ip_next_hop_prefix_list, | |
273 | no_match_ip_next_hop_prefix_list_val_cmd, | |
274 | "no match ip next-hop prefix-list WORD", | |
275 | NO_STR | |
276 | MATCH_STR | |
277 | IP_STR | |
278 | "Match next-hop address of route\n" | |
279 | "Match entries of prefix-lists\n" | |
280 | "IP prefix-list name\n") | |
281 | ||
282 | DEFUN (match_ip_address, | |
283 | match_ip_address_cmd, | |
284 | "match ip address (<1-199>|<1300-2699>|WORD)", | |
285 | MATCH_STR | |
286 | IP_STR | |
287 | "Match address of route\n" | |
288 | "IP access-list number\n" | |
289 | "IP access-list number (expanded range)\n" | |
290 | "IP Access-list name\n") | |
291 | ||
292 | { | |
293 | return zebra_route_match_add (vty, vty->index, "ip address", argv[0]); | |
294 | } | |
295 | ||
296 | DEFUN (no_match_ip_address, | |
297 | no_match_ip_address_cmd, | |
298 | "no match ip address", | |
299 | NO_STR | |
300 | MATCH_STR | |
301 | IP_STR | |
302 | "Match address of route\n") | |
303 | { | |
304 | if (argc == 0) | |
305 | return zebra_route_match_delete (vty, vty->index, "ip address", NULL); | |
306 | ||
307 | return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]); | |
308 | } | |
309 | ||
310 | ALIAS (no_match_ip_address, | |
311 | no_match_ip_address_val_cmd, | |
312 | "no match ip address (<1-199>|<1300-2699>|WORD)", | |
313 | NO_STR | |
314 | MATCH_STR | |
315 | IP_STR | |
316 | "Match address of route\n" | |
317 | "IP access-list number\n" | |
318 | "IP access-list number (expanded range)\n" | |
319 | "IP Access-list name\n") | |
320 | ||
321 | DEFUN (match_ip_address_prefix_list, | |
322 | match_ip_address_prefix_list_cmd, | |
323 | "match ip address prefix-list WORD", | |
324 | MATCH_STR | |
325 | IP_STR | |
326 | "Match address of route\n" | |
327 | "Match entries of prefix-lists\n" | |
328 | "IP prefix-list name\n") | |
329 | { | |
330 | return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]); | |
331 | } | |
332 | ||
333 | DEFUN (no_match_ip_address_prefix_list, | |
334 | no_match_ip_address_prefix_list_cmd, | |
335 | "no match ip address prefix-list", | |
336 | NO_STR | |
337 | MATCH_STR | |
338 | IP_STR | |
339 | "Match address of route\n" | |
340 | "Match entries of prefix-lists\n") | |
341 | { | |
342 | if (argc == 0) | |
343 | return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL); | |
344 | ||
345 | return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]); | |
346 | } | |
347 | ||
348 | ALIAS (no_match_ip_address_prefix_list, | |
349 | no_match_ip_address_prefix_list_val_cmd, | |
350 | "no match ip address prefix-list WORD", | |
351 | NO_STR | |
352 | MATCH_STR | |
353 | IP_STR | |
354 | "Match address of route\n" | |
355 | "Match entries of prefix-lists\n" | |
356 | "IP prefix-list name\n") | |
357 | ||
358 | /* set functions */ | |
359 | ||
360 | DEFUN (set_src, | |
361 | set_src_cmd, | |
362 | "set src A.B.C.D", | |
363 | SET_STR | |
364 | "src address for route\n" | |
365 | "src address\n") | |
366 | { | |
367 | struct in_addr src; | |
368 | struct interface *pif; | |
369 | ||
370 | if (inet_pton(AF_INET, argv[0], &src) <= 0) | |
371 | { | |
372 | vty_out (vty, "%% not a local address%s", VTY_NEWLINE); | |
373 | return CMD_WARNING; | |
374 | } | |
375 | ||
376 | pif = if_lookup_exact_address (src); | |
377 | if (!pif) | |
378 | { | |
379 | vty_out (vty, "%% not a local address%s", VTY_NEWLINE); | |
380 | return CMD_WARNING; | |
381 | } | |
382 | return zebra_route_set_add (vty, vty->index, "src", argv[0]); | |
383 | } | |
384 | ||
385 | DEFUN (no_set_src, | |
386 | no_set_src_cmd, | |
387 | "no set src", | |
388 | NO_STR | |
389 | SET_STR | |
390 | "Source address for route\n") | |
391 | { | |
392 | if (argc == 0) | |
393 | return zebra_route_set_delete (vty, vty->index, "src", NULL); | |
394 | ||
395 | return zebra_route_set_delete (vty, vty->index, "src", argv[0]); | |
396 | } | |
397 | ||
398 | ALIAS (no_set_src, | |
399 | no_set_src_val_cmd, | |
400 | "no set src (A.B.C.D)", | |
401 | NO_STR | |
402 | SET_STR | |
403 | "src address for route\n" | |
404 | "src address\n") | |
405 | ||
406 | /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ | |
407 | ||
408 | /* `match ip next-hop IP_ACCESS_LIST' */ | |
409 | ||
410 | /* Match function return 1 if match is success else return zero. */ | |
411 | static route_map_result_t | |
412 | route_match_ip_next_hop (void *rule, struct prefix *prefix, | |
413 | route_map_object_t type, void *object) | |
414 | { | |
415 | struct access_list *alist; | |
416 | struct nexthop *nexthop; | |
417 | struct prefix_ipv4 p; | |
418 | ||
419 | if (type == RMAP_ZEBRA) | |
420 | { | |
421 | nexthop = object; | |
422 | switch (nexthop->type) { | |
423 | case NEXTHOP_TYPE_IFINDEX: | |
424 | case NEXTHOP_TYPE_IFNAME: | |
fa713d9e CF |
425 | /* Interface routes can't match ip next-hop */ |
426 | return RMAP_NOMATCH; | |
5921ef9a PJ |
427 | case NEXTHOP_TYPE_IPV4_IFINDEX: |
428 | case NEXTHOP_TYPE_IPV4_IFNAME: | |
5921ef9a PJ |
429 | case NEXTHOP_TYPE_IPV4: |
430 | p.family = AF_INET; | |
431 | p.prefix = nexthop->gate.ipv4; | |
432 | p.prefixlen = IPV4_MAX_BITLEN; | |
433 | break; | |
434 | default: | |
435 | return RMAP_NOMATCH; | |
436 | } | |
437 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
438 | if (alist == NULL) | |
439 | return RMAP_NOMATCH; | |
440 | ||
441 | return (access_list_apply (alist, &p) == FILTER_DENY ? | |
442 | RMAP_NOMATCH : RMAP_MATCH); | |
443 | } | |
444 | return RMAP_NOMATCH; | |
445 | } | |
446 | ||
447 | /* Route map `ip next-hop' match statement. `arg' should be | |
448 | access-list name. */ | |
449 | static void * | |
450 | route_match_ip_next_hop_compile (const char *arg) | |
451 | { | |
452 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
453 | } | |
454 | ||
455 | /* Free route map's compiled `. */ | |
456 | static void | |
457 | route_match_ip_next_hop_free (void *rule) | |
458 | { | |
459 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
460 | } | |
461 | ||
462 | /* Route map commands for ip next-hop matching. */ | |
463 | static struct route_map_rule_cmd route_match_ip_next_hop_cmd = | |
464 | { | |
465 | "ip next-hop", | |
466 | route_match_ip_next_hop, | |
467 | route_match_ip_next_hop_compile, | |
468 | route_match_ip_next_hop_free | |
469 | }; | |
470 | \f | |
471 | /* `match ip next-hop prefix-list PREFIX_LIST' */ | |
472 | ||
473 | static route_map_result_t | |
474 | route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, | |
475 | route_map_object_t type, void *object) | |
476 | { | |
477 | struct prefix_list *plist; | |
478 | struct nexthop *nexthop; | |
479 | struct prefix_ipv4 p; | |
480 | ||
481 | if (type == RMAP_ZEBRA) | |
482 | { | |
483 | nexthop = object; | |
484 | switch (nexthop->type) { | |
485 | case NEXTHOP_TYPE_IFINDEX: | |
486 | case NEXTHOP_TYPE_IFNAME: | |
fa713d9e CF |
487 | /* Interface routes can't match ip next-hop */ |
488 | return RMAP_NOMATCH; | |
5921ef9a PJ |
489 | case NEXTHOP_TYPE_IPV4_IFINDEX: |
490 | case NEXTHOP_TYPE_IPV4_IFNAME: | |
5921ef9a PJ |
491 | case NEXTHOP_TYPE_IPV4: |
492 | p.family = AF_INET; | |
493 | p.prefix = nexthop->gate.ipv4; | |
494 | p.prefixlen = IPV4_MAX_BITLEN; | |
495 | break; | |
496 | default: | |
497 | return RMAP_NOMATCH; | |
498 | } | |
499 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
500 | if (plist == NULL) | |
501 | return RMAP_NOMATCH; | |
502 | ||
503 | return (prefix_list_apply (plist, &p) == PREFIX_DENY ? | |
504 | RMAP_NOMATCH : RMAP_MATCH); | |
505 | } | |
506 | return RMAP_NOMATCH; | |
507 | } | |
508 | ||
509 | static void * | |
510 | route_match_ip_next_hop_prefix_list_compile (const char *arg) | |
511 | { | |
512 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
513 | } | |
514 | ||
515 | static void | |
516 | route_match_ip_next_hop_prefix_list_free (void *rule) | |
517 | { | |
518 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
519 | } | |
520 | ||
521 | static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = | |
522 | { | |
523 | "ip next-hop prefix-list", | |
524 | route_match_ip_next_hop_prefix_list, | |
525 | route_match_ip_next_hop_prefix_list_compile, | |
526 | route_match_ip_next_hop_prefix_list_free | |
527 | }; | |
528 | \f | |
529 | /* `match ip address IP_ACCESS_LIST' */ | |
530 | ||
531 | /* Match function should return 1 if match is success else return | |
532 | zero. */ | |
533 | static route_map_result_t | |
534 | route_match_ip_address (void *rule, struct prefix *prefix, | |
535 | route_map_object_t type, void *object) | |
536 | { | |
537 | struct access_list *alist; | |
538 | ||
539 | if (type == RMAP_ZEBRA) | |
540 | { | |
541 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
542 | if (alist == NULL) | |
543 | return RMAP_NOMATCH; | |
544 | ||
545 | return (access_list_apply (alist, prefix) == FILTER_DENY ? | |
546 | RMAP_NOMATCH : RMAP_MATCH); | |
547 | } | |
548 | return RMAP_NOMATCH; | |
549 | } | |
550 | ||
551 | /* Route map `ip address' match statement. `arg' should be | |
552 | access-list name. */ | |
553 | static void * | |
554 | route_match_ip_address_compile (const char *arg) | |
555 | { | |
556 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
557 | } | |
558 | ||
559 | /* Free route map's compiled `ip address' value. */ | |
560 | static void | |
561 | route_match_ip_address_free (void *rule) | |
562 | { | |
563 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
564 | } | |
565 | ||
566 | /* Route map commands for ip address matching. */ | |
567 | static struct route_map_rule_cmd route_match_ip_address_cmd = | |
568 | { | |
569 | "ip address", | |
570 | route_match_ip_address, | |
571 | route_match_ip_address_compile, | |
572 | route_match_ip_address_free | |
573 | }; | |
574 | \f | |
575 | /* `match ip address prefix-list PREFIX_LIST' */ | |
576 | ||
577 | static route_map_result_t | |
578 | route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, | |
579 | route_map_object_t type, void *object) | |
580 | { | |
581 | struct prefix_list *plist; | |
582 | ||
583 | if (type == RMAP_ZEBRA) | |
584 | { | |
585 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
586 | if (plist == NULL) | |
587 | return RMAP_NOMATCH; | |
588 | ||
589 | return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? | |
590 | RMAP_NOMATCH : RMAP_MATCH); | |
591 | } | |
592 | return RMAP_NOMATCH; | |
593 | } | |
594 | ||
595 | static void * | |
596 | route_match_ip_address_prefix_list_compile (const char *arg) | |
597 | { | |
598 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
599 | } | |
600 | ||
601 | static void | |
602 | route_match_ip_address_prefix_list_free (void *rule) | |
603 | { | |
604 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
605 | } | |
606 | ||
607 | static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = | |
608 | { | |
609 | "ip address prefix-list", | |
610 | route_match_ip_address_prefix_list, | |
611 | route_match_ip_address_prefix_list_compile, | |
612 | route_match_ip_address_prefix_list_free | |
613 | }; | |
614 | ||
615 | \f | |
616 | /* `set src A.B.C.D' */ | |
617 | ||
618 | /* Set src. */ | |
619 | static route_map_result_t | |
620 | route_set_src (void *rule, struct prefix *prefix, | |
621 | route_map_object_t type, void *object) | |
622 | { | |
623 | if (type == RMAP_ZEBRA) | |
624 | { | |
625 | struct nexthop *nexthop; | |
626 | ||
627 | nexthop = object; | |
628 | nexthop->src = *(union g_addr *)rule; | |
629 | } | |
630 | return RMAP_OKAY; | |
631 | } | |
632 | ||
633 | /* set src compilation. */ | |
634 | static void * | |
635 | route_set_src_compile (const char *arg) | |
636 | { | |
5921ef9a PJ |
637 | union g_addr src, *psrc; |
638 | ||
8dd1a8da | 639 | if (inet_pton(AF_INET, arg, &src.ipv4) != 1 |
09303314 | 640 | #ifdef HAVE_IPV6 |
8dd1a8da | 641 | && inet_pton(AF_INET6, arg, &src.ipv6) != 1 |
09303314 | 642 | #endif /* HAVE_IPV6 */ |
8dd1a8da PJ |
643 | ) |
644 | return NULL; | |
5921ef9a PJ |
645 | |
646 | psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr)); | |
647 | *psrc = src; | |
648 | ||
649 | return psrc; | |
650 | } | |
651 | ||
652 | /* Free route map's compiled `set src' value. */ | |
653 | static void | |
654 | route_set_src_free (void *rule) | |
655 | { | |
656 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
657 | } | |
658 | ||
659 | /* Set src rule structure. */ | |
660 | static struct route_map_rule_cmd route_set_src_cmd = | |
661 | { | |
662 | "src", | |
663 | route_set_src, | |
664 | route_set_src_compile, | |
665 | route_set_src_free, | |
666 | }; | |
667 | ||
668 | void | |
669 | zebra_route_map_init () | |
670 | { | |
671 | route_map_init (); | |
672 | route_map_init_vty (); | |
673 | ||
674 | route_map_install_match (&route_match_interface_cmd); | |
675 | route_map_install_match (&route_match_ip_next_hop_cmd); | |
676 | route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); | |
677 | route_map_install_match (&route_match_ip_address_cmd); | |
678 | route_map_install_match (&route_match_ip_address_prefix_list_cmd); | |
679 | /* */ | |
680 | route_map_install_set (&route_set_src_cmd); | |
681 | /* */ | |
682 | install_element (RMAP_NODE, &match_interface_cmd); | |
683 | install_element (RMAP_NODE, &no_match_interface_cmd); | |
684 | install_element (RMAP_NODE, &no_match_interface_val_cmd); | |
685 | install_element (RMAP_NODE, &match_ip_next_hop_cmd); | |
686 | install_element (RMAP_NODE, &no_match_ip_next_hop_cmd); | |
687 | install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd); | |
688 | install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd); | |
689 | install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd); | |
690 | install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd); | |
691 | install_element (RMAP_NODE, &match_ip_address_cmd); | |
692 | install_element (RMAP_NODE, &no_match_ip_address_cmd); | |
693 | install_element (RMAP_NODE, &no_match_ip_address_val_cmd); | |
694 | install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd); | |
695 | install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd); | |
696 | install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd); | |
697 | /* */ | |
698 | install_element (RMAP_NODE, &set_src_cmd); | |
699 | install_element (RMAP_NODE, &no_set_src_cmd); | |
700 | } |