]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_routemap.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / eigrpd / eigrp_routemap.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * EIGRP Filter Functions.
4 * Copyright (C) 2013-2015
5 * Authors:
6 * Donnie Savage
7 * Jan Janovic
8 * Matej Perina
9 * Peter Orsag
10 * Peter Paluch
11 * Frantisek Gazo
12 * Tomas Hvorkovy
13 * Martin Kontsek
14 * Lukas Koribsky
15 *
16 * Note: This file contains skeleton for all possible matches and sets,
17 * but they are hidden in comment block and not properly implemented.
18 * At this time, the only function we consider useful for our use
19 * in distribute command in EIGRP is matching destination IP (with both
20 * access and prefix list).
21 *
22 */
23
24 #include <zebra.h>
25
26 #include "memory.h"
27 #include "prefix.h"
28 #include "if_rmap.h"
29 #include "routemap.h"
30 #include "command.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "sockunion.h" /* for inet_aton () */
34 #include "plist.h"
35
36 #include "eigrpd/eigrpd.h"
37 #include "eigrpd/eigrp_structs.h"
38 #include "eigrpd/eigrp_const.h"
39 #include "eigrpd/eigrp_macros.h"
40 #include "eigrpd/eigrp_routemap.h"
41
42 void eigrp_if_rmap_update(struct if_rmap *if_rmap)
43 {
44 struct interface *ifp;
45 struct eigrp_interface *ei, *ei2;
46 struct listnode *node, *nnode;
47 struct route_map *rmap;
48 struct eigrp *e;
49
50 ifp = if_lookup_by_name(if_rmap->ifname);
51 if (ifp == NULL)
52 return;
53
54 ei = NULL;
55 e = eigrp_lookup();
56 for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) {
57 if (strcmp(ei2->ifp->name, ifp->name) == 0) {
58 ei = ei2;
59 break;
60 }
61 }
62
63 if (if_rmap->routemap[IF_RMAP_IN]) {
64 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
65 if (rmap)
66 ei->routemap[IF_RMAP_IN] = rmap;
67 else
68 ei->routemap[IF_RMAP_IN] = NULL;
69 } else
70 ei->routemap[EIGRP_FILTER_IN] = NULL;
71
72 if (if_rmap->routemap[IF_RMAP_OUT]) {
73 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_OUT]);
74 if (rmap)
75 ei->routemap[IF_RMAP_OUT] = rmap;
76 else
77 ei->routemap[IF_RMAP_OUT] = NULL;
78 } else
79 ei->routemap[EIGRP_FILTER_OUT] = NULL;
80 }
81
82 void eigrp_if_rmap_update_interface(struct interface *ifp)
83 {
84 struct if_rmap *if_rmap;
85
86 if_rmap = if_rmap_lookup(ifp->name);
87 if (if_rmap)
88 eigrp_if_rmap_update(if_rmap);
89 }
90
91 void eigrp_routemap_update_redistribute(void)
92 {
93 int i;
94 struct eigrp *e;
95
96 e = eigrp_lookup();
97
98 if (e) {
99 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
100 if (e->route_map[i].name)
101 e->route_map[i].map = route_map_lookup_by_name(
102 e->route_map[i].name);
103 }
104 }
105 }
106
107 /* ARGSUSED */
108 void eigrp_rmap_update(const char *notused)
109 {
110 struct interface *ifp;
111 struct listnode *node, *nnode;
112
113 for (ALL_LIST_ELEMENTS(iflist, node, nnode, ifp))
114 eigrp_if_rmap_update_interface(ifp);
115
116 eigrp_routemap_update_redistribute();
117 }
118
119 /* Add eigrp route map rule. */
120 static int eigrp_route_match_add(struct vty *vty, struct route_map_index *index,
121 const char *command, const char *arg)
122 {
123 enum rmap_compile_rets ret;
124
125 ret = route_map_add_match(index, command, arg, type);
126 switch (ret) {
127 case RMAP_RULE_MISSING:
128 vty_out(vty, "%% Can't find rule.\n");
129 return CMD_WARNING_CONFIG_FAILED;
130 case RMAP_COMPILE_ERROR:
131 vty_out(vty, "%% Argument is malformed.\n");
132 return CMD_WARNING_CONFIG_FAILED;
133 case RMAP_COMPILE_SUCCESS:
134 /*
135 * Intentionally not handling these cases
136 */
137 break;
138 }
139
140 return CMD_SUCCESS;
141 }
142
143 /* Delete rip route map rule. */
144 static int eigrp_route_match_delete(struct vty *vty,
145 struct route_map_index *index,
146 const char *command, const char *arg)
147 {
148 enum rmap_compile_rets ret;
149
150 ret = route_map_delete_match(index, command, arg, type);
151 switch (ret) {
152 case RMAP_RULE_MISSING:
153 vty_out(vty, "%% Can't find rule.\n");
154 return CMD_WARNING_CONFIG_FAILED;
155 case RMAP_COMPILE_ERROR:
156 vty_out(vty, "%% Argument is malformed.\n");
157 return CMD_WARNING_CONFIG_FAILED;
158 case RMAP_COMPILE_SUCCESS:
159 /*
160 * These cases intentionally ignored
161 */
162 break;
163 }
164
165 return CMD_SUCCESS;
166 }
167
168 /* Add eigrp route map rule. */
169 static int eigrp_route_set_add(struct vty *vty, struct route_map_index *index,
170 const char *command, const char *arg)
171 {
172 enum rmap_compile_rets ret;
173
174 ret = route_map_add_set(index, command, arg);
175 switch (ret) {
176 case RMAP_RULE_MISSING:
177 vty_out(vty, "%% Can't find rule.\n");
178 return CMD_WARNING_CONFIG_FAILED;
179 case RMAP_COMPILE_ERROR:
180 /*
181 * rip, ripng and other protocols share the set metric command
182 * but only values from 0 to 16 are valid for rip and ripng
183 * if metric is out of range for rip and ripng, it is
184 * not for other protocols. Do not return an error
185 */
186 if (strcmp(command, "metric")) {
187 vty_out(vty, "%% Argument is malformed.\n");
188 return CMD_WARNING_CONFIG_FAILED;
189 }
190 break;
191 case RMAP_COMPILE_SUCCESS:
192 /*
193 * These cases intentionally left blank here
194 */
195 break;
196 }
197
198 return CMD_SUCCESS;
199 }
200
201 /* Delete eigrp route map rule. */
202 static int eigrp_route_set_delete(struct vty *vty,
203 struct route_map_index *index,
204 const char *command, const char *arg)
205 {
206 enum rmap_compile_rets ret;
207
208 ret = route_map_delete_set(index, command, arg);
209 switch (ret) {
210 case RMAP_RULE_MISSING:
211 vty_out(vty, "%% Can't find rule.\n");
212 return CMD_WARNING_CONFIG_FAILED;
213 case RMAP_COMPILE_ERROR:
214 vty_out(vty, "%% Argument is malformed.\n");
215 return CMD_WARNING_CONFIG_FAILED;
216 case RMAP_COMPILE_SUCCESS:
217 /*
218 * These cases intentionally not handled
219 */
220 break;
221 }
222
223 return CMD_SUCCESS;
224 }
225
226 /* Hook function for updating route_map assignment. */
227 /* ARGSUSED */
228 void eigrp_route_map_update(const char *notused)
229 {
230 int i;
231 struct eigrp *e;
232 e = eigrp_lookup();
233
234 if (e) {
235 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
236 if (e->route_map[i].name)
237 e->route_map[i].map = route_map_lookup_by_name(
238 e->route_map[i].name);
239 }
240 }
241 }
242
243
244 /* `match metric METRIC' */
245 /* Match function return 1 if match is success else return zero. */
246 static enum route_map_cmd_result_t
247 route_match_metric(void *rule, struct prefix *prefix, route_map_object_t type,
248 void *object)
249 {
250 // uint32_t *metric;
251 // uint32_t check;
252 // struct rip_info *rinfo;
253 // struct eigrp_route_descriptor *te;
254 // struct eigrp_prefix_descriptor *pe;
255 // struct listnode *node, *node2, *nnode, *nnode2;
256 // struct eigrp *e;
257 //
258 // e = eigrp_lookup();
259 //
260 // if (type == RMAP_EIGRP)
261 // {
262 // metric = rule;
263 // rinfo = object;
264 //
265 // /* If external metric is available, the route-map should
266 // work on this one (for redistribute purpose) */
267 // /*check = (rinfo->external_metric) ? rinfo->external_metric :
268 // rinfo->metric;*/
269 //
270 // if (check == *metric)
271 // return RMAP_MATCH;
272 // else
273 // return RMAP_NOMATCH;
274 // }
275 return RMAP_NOMATCH;
276 }
277
278 /* Route map `match metric' match statement. `arg' is METRIC value */
279 static void *route_match_metric_compile(const char *arg)
280 {
281 // uint32_t *metric;
282 //
283 // metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
284 // *metric = atoi (arg);
285 //
286 // if(*metric > 0)
287 // return metric;
288 //
289 // XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
290 return NULL;
291 }
292
293 /* Free route map's compiled `match metric' value. */
294 static void route_match_metric_free(void *rule)
295 {
296 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
297 }
298
299 /* Route map commands for metric matching. */
300 static const struct route_map_rule_cmd route_match_metric_cmd = {
301 "metric",
302 route_match_metric,
303 route_match_metric_compile,
304 route_match_metric_free
305 };
306
307 /* `match interface IFNAME' */
308 /* Match function return 1 if match is success else return zero. */
309 static enum route_map_cmd_result_t
310 route_match_interface(void *rule, struct prefix *prefix,
311 route_map_object_t type, void *object)
312 {
313 // struct rip_info *rinfo;
314 // struct interface *ifp;
315 // char *ifname;
316 //
317 // if (type == RMAP_EIGRP)
318 // {
319 // ifname = rule;
320 // ifp = if_lookup_by_name(ifname);
321 //
322 // if (!ifp)
323 // return RMAP_NOMATCH;
324 //
325 // rinfo = object;
326 //
327 // /*if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex ==
328 // ifp->ifindex)
329 // return RMAP_MATCH;
330 // else
331 // return RMAP_NOMATCH;*/
332 // }
333 return RMAP_NOMATCH;
334 }
335
336 /* Route map `match interface' match statement. `arg' is IFNAME value */
337 /* XXX I don`t know if I need to check does interface exist? */
338 static void *route_match_interface_compile(const char *arg)
339 {
340 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
341 }
342
343 /* Free route map's compiled `match interface' value. */
344 static void route_match_interface_free(void *rule)
345 {
346 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
347 }
348
349 /* Route map commands for interface matching. */
350 static const struct route_map_rule_cmd route_match_interface_cmd = {
351 "interface",
352 route_match_interface,
353 route_match_interface_compile,
354 route_match_interface_free
355 };
356
357 /* `match ip next-hop IP_ACCESS_LIST' */
358
359 /* Match function return 1 if match is success else return zero. */
360 static enum route_map_cmd_result_t
361 route_match_ip_next_hop(void *rule, struct prefix *prefix,
362 route_map_object_t type, void *object)
363 {
364 // struct access_list *alist;
365 // struct rip_info *rinfo;
366 // struct prefix_ipv4 p;
367 //
368 // if (type == RMAP_EIGRP)
369 // {
370 // rinfo = object;
371 // p.family = AF_INET;
372 // /*p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop :
373 // rinfo->from;*/
374 // p.prefixlen = IPV4_MAX_BITLEN;
375 //
376 // alist = access_list_lookup (AFI_IP, (char *) rule);
377 // if (alist == NULL)
378 // return RMAP_NOMATCH;
379 //
380 // return (access_list_apply (alist, &p) == FILTER_DENY ?
381 // RMAP_NOMATCH : RMAP_MATCH);
382 // }
383 return RMAP_NOMATCH;
384 }
385
386 /* Route map `ip next-hop' match statement. `arg' should be
387 access-list name. */
388 static void *route_match_ip_next_hop_compile(const char *arg)
389 {
390 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
391 }
392
393 /* Free route map's compiled `. */
394 static void route_match_ip_next_hop_free(void *rule)
395 {
396 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
397 }
398
399 /* Route map commands for ip next-hop matching. */
400 static const struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
401 "ip next-hop",
402 route_match_ip_next_hop,
403 route_match_ip_next_hop_compile,
404 route_match_ip_next_hop_free
405 };
406
407 /* `match ip next-hop prefix-list PREFIX_LIST' */
408
409 static enum route_map_cmd_result_t
410 route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
411 route_map_object_t type, void *object)
412 {
413 // struct prefix_list *plist;
414 // struct rip_info *rinfo;
415 // struct prefix_ipv4 p;
416 //
417 // if (type == RMAP_EIGRP)
418 // {
419 // rinfo = object;
420 // p.family = AF_INET;
421 // /*p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop :
422 // rinfo->from;*/
423 // p.prefixlen = IPV4_MAX_BITLEN;
424 //
425 // plist = prefix_list_lookup (AFI_IP, (char *) rule);
426 // if (plist == NULL)
427 // return RMAP_NOMATCH;
428 //
429 // return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
430 // RMAP_NOMATCH : RMAP_MATCH);
431 // }
432 return RMAP_NOMATCH;
433 }
434
435 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
436 {
437 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
438 }
439
440 static void route_match_ip_next_hop_prefix_list_free(void *rule)
441 {
442 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
443 }
444
445 static const struct route_map_rule_cmd
446 route_match_ip_next_hop_prefix_list_cmd = {
447 "ip next-hop prefix-list",
448 route_match_ip_next_hop_prefix_list,
449 route_match_ip_next_hop_prefix_list_compile,
450 route_match_ip_next_hop_prefix_list_free
451 };
452
453 /* `match ip address IP_ACCESS_LIST' */
454
455 /* Match function should return 1 if match is success else return
456 zero. */
457 static enum route_map_cmd_result_t
458 route_match_ip_address(void *rule, struct prefix *prefix,
459 route_map_object_t type, void *object)
460 {
461 struct access_list *alist;
462
463 if (type == RMAP_EIGRP) {
464 alist = access_list_lookup(AFI_IP, (char *)rule);
465 if (alist == NULL)
466 return RMAP_NOMATCH;
467
468 return (access_list_apply(alist, prefix) == FILTER_DENY
469 ? RMAP_NOMATCH
470 : RMAP_MATCH);
471 }
472 return RMAP_NOMATCH;
473 }
474
475 /* Route map `ip address' match statement. `arg' should be
476 access-list name. */
477 static void *route_match_ip_address_compile(const char *arg)
478 {
479 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
480 }
481
482 /* Free route map's compiled `ip address' value. */
483 static void route_match_ip_address_free(void *rule)
484 {
485 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
486 }
487
488 /* Route map commands for ip address matching. */
489 static const struct route_map_rule_cmd route_match_ip_address_cmd = {
490 "ip address",
491 route_match_ip_address,
492 route_match_ip_address_compile,
493 route_match_ip_address_free
494 };
495
496 /* `match ip address prefix-list PREFIX_LIST' */
497
498 static enum route_map_cmd_result_t
499 route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
500 route_map_object_t type, void *object)
501 {
502 struct prefix_list *plist;
503
504 if (type == RMAP_EIGRP) {
505 plist = prefix_list_lookup(AFI_IP, (char *)rule);
506 if (plist == NULL)
507 return RMAP_NOMATCH;
508
509 return (prefix_list_apply(plist, prefix) == PREFIX_DENY
510 ? RMAP_NOMATCH
511 : RMAP_MATCH);
512 }
513 return RMAP_NOMATCH;
514 }
515
516 static void *route_match_ip_address_prefix_list_compile(const char *arg)
517 {
518 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
519 }
520
521 static void route_match_ip_address_prefix_list_free(void *rule)
522 {
523 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
524 }
525
526 static const struct route_map_rule_cmd
527 route_match_ip_address_prefix_list_cmd = {
528 "ip address prefix-list",
529 route_match_ip_address_prefix_list,
530 route_match_ip_address_prefix_list_compile,
531 route_match_ip_address_prefix_list_free
532 };
533
534 /* `match tag TAG' */
535 /* Match function return 1 if match is success else return zero. */
536 static enum route_map_cmd_result_t
537 route_match_tag(void *rule, struct prefix *prefix, route_map_object_t type,
538 void *object)
539 {
540 // unsigned short *tag;
541 // struct rip_info *rinfo;
542 //
543 // if (type == RMAP_EIGRP)
544 // {
545 // tag = rule;
546 // rinfo = object;
547 //
548 // /* The information stored by rinfo is host ordered. */
549 // /*if (rinfo->tag == *tag)
550 // return RMAP_MATCH;
551 // else
552 // return RMAP_NOMATCH;*/
553 // }
554 return RMAP_NOMATCH;
555 }
556
557 /* Route map `match tag' match statement. `arg' is TAG value */
558 static void *route_match_tag_compile(const char *arg)
559 {
560 // unsigned short *tag;
561 //
562 // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(unsigned short));
563 // *tag = atoi (arg);
564 //
565 // return tag;
566 }
567
568 /* Free route map's compiled `match tag' value. */
569 static void route_match_tag_free(void *rule)
570 {
571 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
572 }
573
574 /* Route map commands for tag matching. */
575 static const struct route_map_rule_cmd route_match_tag_cmd = {
576 "tag",
577 route_match_tag,
578 route_match_tag_compile,
579 route_match_tag_free
580 };
581
582 /* Set metric to attribute. */
583 static enum route_map_cmd_result_t
584 route_set_metric(void *rule, struct prefix *prefix,
585 route_map_object_t type, void *object)
586 {
587 // if (type == RMAP_RIP)
588 // {
589 // struct rip_metric_modifier *mod;
590 // struct rip_info *rinfo;
591 //
592 // mod = rule;
593 // rinfo = object;
594 //
595 // /*if (mod->type == metric_increment)
596 // rinfo->metric_out += mod->metric;
597 // else if (mod->type == metric_decrement)
598 // rinfo->metric_out -= mod->metric;
599 // else if (mod->type == metric_absolute)
600 // rinfo->metric_out = mod->metric;
601 //
602 // if ((signed int)rinfo->metric_out < 1)
603 // rinfo->metric_out = 1;
604 // if (rinfo->metric_out > RIP_METRIC_INFINITY)
605 // rinfo->metric_out = RIP_METRIC_INFINITY;*/
606 //
607 // rinfo->metric_set = 1;
608 // }
609 return RMAP_OKAY;
610 }
611
612 /* set metric compilation. */
613 static void *route_set_metric_compile(const char *arg)
614 {
615 // int len;
616 // const char *pnt;
617 // int type;
618 // long metric;
619 // char *endptr = NULL;
620 // struct rip_metric_modifier *mod;
621 //
622 // len = strlen (arg);
623 // pnt = arg;
624 //
625 // if (len == 0)
626 // return NULL;
627 //
628 // /* Examine first character. */
629 // if (arg[0] == '+')
630 // {
631 // //type = metric_increment;
632 // pnt++;
633 // }
634 // else if (arg[0] == '-')
635 // {
636 // //type = metric_decrement;
637 // pnt++;
638 // }
639 // /*else
640 // type = metric_absolute;*/
641 //
642 // /* Check beginning with digit string. */
643 // if (*pnt < '0' || *pnt > '9')
644 // return NULL;
645 //
646 // /* Convert string to integer. */
647 // metric = strtol (pnt, &endptr, 10);
648 //
649 // if (metric == LONG_MAX || *endptr != '\0')
650 // return NULL;
651 // /*if (metric < 0 || metric > RIP_METRIC_INFINITY)
652 // return NULL;*/
653 //
654 // mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
655 // sizeof(struct rip_metric_modifier));
656 // mod->type = type;
657 // mod->metric = metric;
658
659 // return mod;
660 }
661
662 /* Free route map's compiled `set metric' value. */
663 static void route_set_metric_free(void *rule)
664 {
665 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
666 }
667
668 /* Set metric rule structure. */
669 static const struct route_map_rule_cmd route_set_metric_cmd = {
670 "metric",
671 route_set_metric,
672 route_set_metric_compile,
673 route_set_metric_free,
674 };
675
676 /* `set ip next-hop IP_ADDRESS' */
677
678 /* Set nexthop to object. object must be pointer to struct attr. */
679 static enum route_map_cmd_result_t
680 route_set_ip_nexthop(void *rule, struct prefix *prefix,
681 route_map_object_t type, void *object)
682 {
683 // struct in_addr *address;
684 // struct rip_info *rinfo;
685 //
686 // if(type == RMAP_RIP)
687 // {
688 // /* Fetch routemap's rule information. */
689 // address = rule;
690 // rinfo = object;
691 //
692 // /* Set next hop value. */
693 // rinfo->nexthop_out = *address;
694 // }
695
696 return RMAP_OKAY;
697 }
698
699 /* Route map `ip nexthop' compile function. Given string is converted
700 to struct in_addr structure. */
701 static void *route_set_ip_nexthop_compile(const char *arg)
702 {
703 // int ret;
704 // struct in_addr *address;
705 //
706 // address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct
707 // in_addr));
708 //
709 // ret = inet_aton (arg, address);
710 //
711 // if (ret == 0)
712 // {
713 // XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
714 // return NULL;
715 // }
716 //
717 // return address;
718 }
719
720 /* Free route map's compiled `ip nexthop' value. */
721 static void route_set_ip_nexthop_free(void *rule)
722 {
723 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
724 }
725
726 /* Route map commands for ip nexthop set. */
727 static const struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
728 "ip next-hop",
729 route_set_ip_nexthop,
730 route_set_ip_nexthop_compile,
731 route_set_ip_nexthop_free
732 };
733
734 /* `set tag TAG' */
735
736 /* Set tag to object. object must be pointer to struct attr. */
737 static enum route_map_cmd_result_t
738 route_set_tag(void *rule, struct prefix *prefix,
739 route_map_object_t type, void *object)
740 {
741 // unsigned short *tag;
742 // struct rip_info *rinfo;
743 //
744 // if(type == RMAP_RIP)
745 // {
746 // /* Fetch routemap's rule information. */
747 // tag = rule;
748 // rinfo = object;
749 //
750 // /* Set next hop value. */
751 // rinfo->tag_out = *tag;
752 // }
753
754 return RMAP_OKAY;
755 }
756
757 /* Route map `tag' compile function. Given string is converted
758 to unsigned short. */
759 static void *route_set_tag_compile(const char *arg)
760 {
761 // unsigned short *tag;
762 //
763 // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(unsigned short));
764 // *tag = atoi (arg);
765 //
766 // return tag;
767 }
768
769 /* Free route map's compiled `ip nexthop' value. */
770 static void route_set_tag_free(void *rule)
771 {
772 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
773 }
774
775 /* Route map commands for tag set. */
776 static const struct route_map_rule_cmd route_set_tag_cmd = {
777 "tag",
778 route_set_tag,
779 route_set_tag_compile,
780 route_set_tag_free
781 };
782
783 #define MATCH_STR "Match values from routing table\n"
784 #define SET_STR "Set values in destination routing protocol\n"
785
786 DEFUN (match_metric,
787 match_metric_cmd,
788 "match metric (0-4294967295)",
789 MATCH_STR
790 "Match metric of route\n"
791 "Metric value\n")
792 {
793 return eigrp_route_match_add(vty, vty->index, "metric", argv[0]);
794 }
795
796 DEFUN (no_match_metric,
797 no_match_metric_cmd,
798 "no match metric",
799 NO_STR
800 MATCH_STR
801 "Match metric of route\n")
802 {
803 if (argc == 0)
804 return eigrp_route_match_delete(vty, vty->index, "metric",
805 NULL);
806
807 return eigrp_route_match_delete(vty, vty->index, "metric", argv[0]);
808 }
809
810 ALIAS(no_match_metric, no_match_metric_val_cmd,
811 "no match metric (0-4294967295)", NO_STR MATCH_STR
812 "Match metric of route\n"
813 "Metric value\n")
814
815 DEFUN (match_interface,
816 match_interface_cmd,
817 "match interface WORD",
818 MATCH_STR
819 "Match first hop interface of route\n"
820 "Interface name\n")
821 {
822 return eigrp_route_match_add(vty, vty->index, "interface", argv[0]);
823 }
824
825 DEFUN (no_match_interface,
826 no_match_interface_cmd,
827 "no match interface",
828 NO_STR
829 MATCH_STR
830 "Match first hop interface of route\n")
831 {
832 if (argc == 0)
833 return eigrp_route_match_delete(vty, vty->index, "interface",
834 NULL);
835
836 return eigrp_route_match_delete(vty, vty->index, "interface", argv[0]);
837 }
838
839 ALIAS(no_match_interface, no_match_interface_val_cmd, "no match interface WORD",
840 NO_STR MATCH_STR
841 "Match first hop interface of route\n"
842 "Interface name\n")
843
844 DEFUN (match_ip_next_hop,
845 match_ip_next_hop_cmd,
846 "match ip next-hop ACCESSLIST4_NAME",
847 MATCH_STR
848 IP_STR
849 "Match next-hop address of route\n"
850 "IP Access-list name\n")
851 {
852 return eigrp_route_match_add(vty, vty->index, "ip next-hop", argv[0]);
853 }
854
855 DEFUN (no_match_ip_next_hop,
856 no_match_ip_next_hop_cmd,
857 "no match ip next-hop",
858 NO_STR
859 MATCH_STR
860 IP_STR
861 "Match next-hop address of route\n")
862 {
863 if (argc == 0)
864 return eigrp_route_match_delete(vty, vty->index, "ip next-hop",
865 NULL);
866
867 return eigrp_route_match_delete(vty, vty->index, "ip next-hop",
868 argv[0]);
869 }
870
871 ALIAS(no_match_ip_next_hop, no_match_ip_next_hop_val_cmd,
872 "no match ip next-hop ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
873 "Match next-hop address of route\n"
874 "IP Access-list name\n")
875
876 DEFUN (match_ip_next_hop_prefix_list,
877 match_ip_next_hop_prefix_list_cmd,
878 "match ip next-hop prefix-list PREFIXLIST_NAME",
879 MATCH_STR
880 IP_STR
881 "Match next-hop address of route\n"
882 "Match entries of prefix-lists\n"
883 "IP prefix-list name\n")
884 {
885 return eigrp_route_match_add(vty, vty->index, "ip next-hop prefix-list",
886 argv[0]);
887 }
888
889 DEFUN (no_match_ip_next_hop_prefix_list,
890 no_match_ip_next_hop_prefix_list_cmd,
891 "no match ip next-hop prefix-list",
892 NO_STR
893 MATCH_STR
894 IP_STR
895 "Match next-hop address of route\n"
896 "Match entries of prefix-lists\n")
897 {
898 if (argc == 0)
899 return eigrp_route_match_delete(
900 vty, vty->index, "ip next-hop prefix-list", NULL);
901
902 return eigrp_route_match_delete(vty, vty->index,
903 "ip next-hop prefix-list", argv[0]);
904 }
905
906 ALIAS(no_match_ip_next_hop_prefix_list,
907 no_match_ip_next_hop_prefix_list_val_cmd,
908 "no match ip next-hop prefix-list PREFIXLIST_NAME", NO_STR MATCH_STR IP_STR
909 "Match next-hop address of route\n"
910 "Match entries of prefix-lists\n"
911 "IP prefix-list name\n")
912
913 DEFUN (match_ip_address,
914 match_ip_address_cmd,
915 "match ip address ACCESSLIST4_NAME",
916 MATCH_STR
917 IP_STR
918 "Match address of route\n"
919 "IP Access-list name\n")
920 {
921 return eigrp_route_match_add(vty, vty->index, "ip address", argv[0]);
922 }
923
924 DEFUN (no_match_ip_address,
925 no_match_ip_address_cmd,
926 "no match ip address",
927 NO_STR
928 MATCH_STR
929 IP_STR
930 "Match address of route\n")
931 {
932 if (argc == 0)
933 return eigrp_route_match_delete(vty, vty->index, "ip address",
934 NULL);
935
936 return eigrp_route_match_delete(vty, vty->index, "ip address", argv[0]);
937 }
938
939 ALIAS(no_match_ip_address, no_match_ip_address_val_cmd,
940 "no match ip address ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
941 "Match address of route\n"
942 "IP Access-list name\n")
943
944 DEFUN (match_ip_address_prefix_list,
945 match_ip_address_prefix_list_cmd,
946 "match ip address prefix-list PREFIXLIST_NAME",
947 MATCH_STR
948 IP_STR
949 "Match address of route\n"
950 "Match entries of prefix-lists\n"
951 "IP prefix-list name\n")
952 {
953 return eigrp_route_match_add(vty, vty->index, "ip address prefix-list",
954 argv[0]);
955 }
956
957 DEFUN (no_match_ip_address_prefix_list,
958 no_match_ip_address_prefix_list_cmd,
959 "no match ip address prefix-list",
960 NO_STR
961 MATCH_STR
962 IP_STR
963 "Match address of route\n"
964 "Match entries of prefix-lists\n")
965 {
966 if (argc == 0)
967 return eigrp_route_match_delete(vty, vty->index,
968 "ip address prefix-list", NULL);
969
970 return eigrp_route_match_delete(vty, vty->index,
971 "ip address prefix-list", argv[0]);
972 }
973
974 ALIAS(no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_val_cmd,
975 "no match ip address prefix-list PREFIXLIST_NAME", NO_STR MATCH_STR IP_STR
976 "Match address of route\n"
977 "Match entries of prefix-lists\n"
978 "IP prefix-list name\n")
979
980 DEFUN (match_tag,
981 match_tag_cmd,
982 "match tag (0-65535)",
983 MATCH_STR
984 "Match tag of route\n"
985 "Metric value\n")
986 {
987 return eigrp_route_match_add(vty, vty->index, "tag", argv[0]);
988 }
989
990 DEFUN (no_match_tag,
991 no_match_tag_cmd,
992 "no match tag",
993 NO_STR
994 MATCH_STR
995 "Match tag of route\n")
996 {
997 if (argc == 0)
998 return eigrp_route_match_delete(vty, vty->index, "tag", NULL);
999
1000 return eigrp_route_match_delete(vty, vty->index, "tag", argv[0]);
1001 }
1002
1003 ALIAS(no_match_tag, no_match_tag_val_cmd, "no match tag (0-65535)",
1004 NO_STR MATCH_STR
1005 "Match tag of route\n"
1006 "Metric value\n")
1007
1008 /* set functions */
1009
1010 DEFUN (set_metric,
1011 set_metric_cmd,
1012 "set metric (0-4294967295)",
1013 SET_STR
1014 "Metric value for destination routing protocol\n"
1015 "Metric value\n")
1016 {
1017 return eigrp_route_set_add(vty, vty->index, "metric", argv[0]);
1018 }
1019
1020 ALIAS(set_metric, set_metric_addsub_cmd, "set metric <+/-metric>", SET_STR
1021 "Metric value for destination routing protocol\n"
1022 "Add or subtract metric\n")
1023
1024 DEFUN (no_set_metric,
1025 no_set_metric_cmd,
1026 "no set metric",
1027 NO_STR
1028 SET_STR
1029 "Metric value for destination routing protocol\n")
1030 {
1031 if (argc == 0)
1032 return eigrp_route_set_delete(vty, vty->index, "metric", NULL);
1033
1034 return eigrp_route_set_delete(vty, vty->index, "metric", argv[0]);
1035 }
1036
1037 ALIAS(no_set_metric, no_set_metric_val_cmd,
1038 "no set metric ((0-4294967295)|<+/-metric>)", NO_STR SET_STR
1039 "Metric value for destination routing protocol\n"
1040 "Metric value\n"
1041 "Add or subtract metric\n")
1042
1043 DEFUN (set_ip_nexthop,
1044 set_ip_nexthop_cmd,
1045 "set ip next-hop A.B.C.D",
1046 SET_STR
1047 IP_STR
1048 "Next hop address\n"
1049 "IP address of next hop\n")
1050 {
1051 union sockunion su;
1052 int ret;
1053
1054 ret = str2sockunion(argv[0], &su);
1055 if (ret < 0) {
1056 vty_out(vty, "%% Malformed next-hop address\n");
1057 return CMD_WARNING_CONFIG_FAILED;
1058 }
1059
1060 return eigrp_route_set_add(vty, vty->index, "ip next-hop", argv[0]);
1061 }
1062
1063 DEFUN (no_set_ip_nexthop,
1064 no_set_ip_nexthop_cmd,
1065 "no set ip next-hop",
1066 NO_STR
1067 SET_STR
1068 IP_STR
1069 "Next hop address\n")
1070 {
1071 if (argc == 0)
1072 return eigrp_route_set_delete(vty, vty->index, "ip next-hop",
1073 NULL);
1074
1075 return eigrp_route_set_delete(vty, vty->index, "ip next-hop", argv[0]);
1076 }
1077
1078 ALIAS(no_set_ip_nexthop, no_set_ip_nexthop_val_cmd,
1079 "no set ip next-hop A.B.C.D", NO_STR SET_STR IP_STR
1080 "Next hop address\n"
1081 "IP address of next hop\n")
1082
1083 DEFUN (set_tag,
1084 set_tag_cmd,
1085 "set tag (0-65535)",
1086 SET_STR
1087 "Tag value for routing protocol\n"
1088 "Tag value\n")
1089 {
1090 return eigrp_route_set_add(vty, vty->index, "tag", argv[0]);
1091 }
1092
1093 DEFUN (no_set_tag,
1094 no_set_tag_cmd,
1095 "no set tag",
1096 NO_STR
1097 SET_STR
1098 "Tag value for routing protocol\n")
1099 {
1100 if (argc == 0)
1101 return eigrp_route_set_delete(vty, vty->index, "tag", NULL);
1102
1103 return eigrp_route_set_delete(vty, vty->index, "tag", argv[0]);
1104 }
1105
1106 ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR
1107 "Tag value for routing protocol\n"
1108 "Tag value\n")
1109
1110 DEFUN (eigrp_distribute_list,
1111 eigrp_distribute_list_cmd,
1112 "distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
1113 "Filter networks in routing updates\n"
1114 "Specify a prefix\n"
1115 "Access-list name\n"
1116 "Filter incoming routing updates\n"
1117 "Filter outgoing routing updates\n"
1118 "Interface name\n")
1119 {
1120 const char *ifname = NULL;
1121 int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
1122
1123 if (argv[argc - 1]->type == VARIABLE_TKN)
1124 ifname = argv[argc - 1]->arg;
1125
1126 return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
1127 argv[1 + prefix]->arg, ifname);
1128 }
1129
1130 DEFUN (eigrp_no_distribute_list,
1131 eigrp_no_distribute_list_cmd,
1132 "no distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
1133 NO_STR
1134 "Filter networks in routing updates\n"
1135 "Specify a prefix\n"
1136 "Access-list name\n"
1137 "Filter incoming routing updates\n"
1138 "Filter outgoing routing updates\n"
1139 "Interface name\n")
1140 {
1141 const char *ifname = NULL;
1142 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
1143
1144 if (argv[argc - 1]->type == VARIABLE_TKN)
1145 ifname = argv[argc - 1]->arg;
1146
1147 return distribute_list_no_parser(vty, prefix, true,
1148 argv[3 + prefix]->text,
1149 argv[2 + prefix]->arg, ifname);
1150 }
1151
1152
1153 /* Route-map init */
1154 void eigrp_route_map_init()
1155 {
1156 route_map_init();
1157 route_map_init_vty();
1158 route_map_add_hook(eigrp_route_map_update);
1159 route_map_delete_hook(eigrp_route_map_update);
1160
1161 install_element(EIGRP_NODE, &eigrp_distribute_list_cmd);
1162 install_element(EIGRP_NODE, &eigrp_no_distribute_list_cmd);
1163
1164 /*route_map_install_match (&route_match_metric_cmd);
1165 route_map_install_match (&route_match_interface_cmd);*/
1166 /*route_map_install_match (&route_match_ip_next_hop_cmd);
1167 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
1168 route_map_install_match (&route_match_ip_address_cmd);
1169 route_map_install_match (&route_match_ip_address_prefix_list_cmd);*/
1170 /*route_map_install_match (&route_match_tag_cmd);*/
1171
1172 /*route_map_install_set (&route_set_metric_cmd);
1173 route_map_install_set (&route_set_ip_nexthop_cmd);
1174 route_map_install_set (&route_set_tag_cmd);*/
1175
1176 /*install_element (RMAP_NODE, &route_match_metric_cmd);
1177 install_element (RMAP_NODE, &no_match_metric_cmd);
1178 install_element (RMAP_NODE, &no_match_metric_val_cmd);
1179 install_element (RMAP_NODE, &route_match_interface_cmd);
1180 install_element (RMAP_NODE, &no_match_interface_cmd);
1181 install_element (RMAP_NODE, &no_match_interface_val_cmd);
1182 install_element (RMAP_NODE, &route_match_ip_next_hop_cmd);
1183 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
1184 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
1185 install_element (RMAP_NODE, &route_match_ip_next_hop_prefix_list_cmd);
1186 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
1187 install_element (RMAP_NODE,
1188 &no_match_ip_next_hop_prefix_list_val_cmd);*/
1189 /*install_element (RMAP_NODE, &route_match_ip_address_cmd);
1190 install_element (RMAP_NODE, &no_match_ip_address_cmd);
1191 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
1192 install_element (RMAP_NODE, &route_match_ip_address_prefix_list_cmd);
1193 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
1194 install_element (RMAP_NODE,
1195 &no_match_ip_address_prefix_list_val_cmd);*/
1196 /*install_element (RMAP_NODE, &route_match_tag_cmd);
1197 install_element (RMAP_NODE, &no_match_tag_cmd);
1198 install_element (RMAP_NODE, &no_match_tag_val_cmd);*/
1199
1200 /*install_element (RMAP_NODE, &set_metric_cmd);
1201 install_element (RMAP_NODE, &set_metric_addsub_cmd);
1202 install_element (RMAP_NODE, &no_set_metric_cmd);
1203 install_element (RMAP_NODE, &no_set_metric_val_cmd);
1204 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
1205 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
1206 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
1207 install_element (RMAP_NODE, &set_tag_cmd);
1208 install_element (RMAP_NODE, &no_set_tag_cmd);
1209 install_element (RMAP_NODE, &no_set_tag_val_cmd);*/
1210 }