]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_routemap.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / eigrpd / eigrp_routemap.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
7f57883e
DS
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 *
7f57883e
DS
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"
d62a17ae 33#include "sockunion.h" /* for inet_aton () */
7f57883e
DS
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
d62a17ae 42void eigrp_if_rmap_update(struct if_rmap *if_rmap)
7f57883e 43{
d62a17ae 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
a36898e7 50 ifp = if_lookup_by_name(if_rmap->ifname);
d62a17ae 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;
7f57883e
DS
80}
81
d62a17ae 82void eigrp_if_rmap_update_interface(struct interface *ifp)
7f57883e 83{
d62a17ae 84 struct if_rmap *if_rmap;
7f57883e 85
d62a17ae 86 if_rmap = if_rmap_lookup(ifp->name);
87 if (if_rmap)
88 eigrp_if_rmap_update(if_rmap);
7f57883e
DS
89}
90
d62a17ae 91void eigrp_routemap_update_redistribute(void)
7f57883e 92{
d62a17ae 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 }
7f57883e
DS
105}
106
107/* ARGSUSED */
d62a17ae 108void eigrp_rmap_update(const char *notused)
7f57883e 109{
d62a17ae 110 struct interface *ifp;
111 struct listnode *node, *nnode;
7f57883e 112
d62a17ae 113 for (ALL_LIST_ELEMENTS(iflist, node, nnode, ifp))
114 eigrp_if_rmap_update_interface(ifp);
7f57883e 115
d62a17ae 116 eigrp_routemap_update_redistribute();
7f57883e
DS
117}
118
119/* Add eigrp route map rule. */
d62a17ae 120static int eigrp_route_match_add(struct vty *vty, struct route_map_index *index,
121 const char *command, const char *arg)
7f57883e 122{
cda7187d
DS
123 enum rmap_compile_rets ret;
124
e2c8d6ce 125 ret = route_map_add_match(index, command, arg, type);
9ca25fed
DS
126 switch (ret) {
127 case RMAP_RULE_MISSING:
128 vty_out(vty, "%% Can't find rule.\n");
129 return CMD_WARNING_CONFIG_FAILED;
9ca25fed
DS
130 case RMAP_COMPILE_ERROR:
131 vty_out(vty, "%% Argument is malformed.\n");
132 return CMD_WARNING_CONFIG_FAILED;
9ca25fed 133 case RMAP_COMPILE_SUCCESS:
cda7187d
DS
134 /*
135 * Intentionally not handling these cases
136 */
9ca25fed 137 break;
d62a17ae 138 }
9ca25fed 139
d62a17ae 140 return CMD_SUCCESS;
7f57883e
DS
141}
142
143/* Delete rip route map rule. */
d62a17ae 144static int eigrp_route_match_delete(struct vty *vty,
145 struct route_map_index *index,
146 const char *command, const char *arg)
7f57883e 147{
cda7187d
DS
148 enum rmap_compile_rets ret;
149
909f3d56 150 ret = route_map_delete_match(index, command, arg, type);
9ca25fed
DS
151 switch (ret) {
152 case RMAP_RULE_MISSING:
153 vty_out(vty, "%% Can't find rule.\n");
154 return CMD_WARNING_CONFIG_FAILED;
9ca25fed
DS
155 case RMAP_COMPILE_ERROR:
156 vty_out(vty, "%% Argument is malformed.\n");
157 return CMD_WARNING_CONFIG_FAILED;
9ca25fed 158 case RMAP_COMPILE_SUCCESS:
cda7187d
DS
159 /*
160 * These cases intentionally ignored
161 */
9ca25fed 162 break;
d62a17ae 163 }
9ca25fed 164
d62a17ae 165 return CMD_SUCCESS;
7f57883e
DS
166}
167
168/* Add eigrp route map rule. */
d62a17ae 169static int eigrp_route_set_add(struct vty *vty, struct route_map_index *index,
170 const char *command, const char *arg)
7f57883e 171{
cda7187d 172 enum rmap_compile_rets ret;
d62a17ae 173
174 ret = route_map_add_set(index, command, arg);
9ca25fed
DS
175 switch (ret) {
176 case RMAP_RULE_MISSING:
177 vty_out(vty, "%% Can't find rule.\n");
178 return CMD_WARNING_CONFIG_FAILED;
9ca25fed
DS
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");
d62a17ae 188 return CMD_WARNING_CONFIG_FAILED;
d62a17ae 189 }
9ca25fed
DS
190 break;
191 case RMAP_COMPILE_SUCCESS:
cda7187d
DS
192 /*
193 * These cases intentionally left blank here
194 */
9ca25fed 195 break;
d62a17ae 196 }
9ca25fed 197
d62a17ae 198 return CMD_SUCCESS;
7f57883e
DS
199}
200
201/* Delete eigrp route map rule. */
d62a17ae 202static int eigrp_route_set_delete(struct vty *vty,
203 struct route_map_index *index,
204 const char *command, const char *arg)
7f57883e 205{
cda7187d 206 enum rmap_compile_rets ret;
d62a17ae 207
208 ret = route_map_delete_set(index, command, arg);
9ca25fed
DS
209 switch (ret) {
210 case RMAP_RULE_MISSING:
211 vty_out(vty, "%% Can't find rule.\n");
212 return CMD_WARNING_CONFIG_FAILED;
9ca25fed
DS
213 case RMAP_COMPILE_ERROR:
214 vty_out(vty, "%% Argument is malformed.\n");
215 return CMD_WARNING_CONFIG_FAILED;
9ca25fed 216 case RMAP_COMPILE_SUCCESS:
cda7187d
DS
217 /*
218 * These cases intentionally not handled
219 */
9ca25fed 220 break;
d62a17ae 221 }
9ca25fed 222
d62a17ae 223 return CMD_SUCCESS;
7f57883e
DS
224}
225
226/* Hook function for updating route_map assignment. */
227/* ARGSUSED */
d62a17ae 228void eigrp_route_map_update(const char *notused)
7f57883e 229{
d62a17ae 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 }
7f57883e
DS
241}
242
243
7f57883e
DS
244/* `match metric METRIC' */
245/* Match function return 1 if match is success else return zero. */
b68885f9
LK
246static enum route_map_cmd_result_t
247route_match_metric(void *rule, struct prefix *prefix, route_map_object_t type,
248 void *object)
f9e5c9ca 249{
d7c0a89a
QY
250 // uint32_t *metric;
251 // uint32_t check;
d62a17ae 252 // struct rip_info *rinfo;
dc4accdd
DS
253 // struct eigrp_route_descriptor *te;
254 // struct eigrp_prefix_descriptor *pe;
d62a17ae 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;
7f57883e
DS
276}
277
278/* Route map `match metric' match statement. `arg' is METRIC value */
d62a17ae 279static void *route_match_metric_compile(const char *arg)
7f57883e 280{
d7c0a89a 281 // uint32_t *metric;
d62a17ae 282 //
0d6f7fd6 283 // metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
d62a17ae 284 // *metric = atoi (arg);
285 //
286 // if(*metric > 0)
287 // return metric;
288 //
289 // XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
290 return NULL;
7f57883e
DS
291}
292
293/* Free route map's compiled `match metric' value. */
d62a17ae 294static void route_match_metric_free(void *rule)
7f57883e 295{
d62a17ae 296 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
297}
298
299/* Route map commands for metric matching. */
364deb04
DL
300static 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};
7f57883e
DS
306
307/* `match interface IFNAME' */
308/* Match function return 1 if match is success else return zero. */
b68885f9
LK
309static enum route_map_cmd_result_t
310route_match_interface(void *rule, struct prefix *prefix,
311 route_map_object_t type, void *object)
f9e5c9ca 312{
d62a17ae 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;
7f57883e
DS
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? */
d62a17ae 338static void *route_match_interface_compile(const char *arg)
7f57883e 339{
d62a17ae 340 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
7f57883e
DS
341}
342
343/* Free route map's compiled `match interface' value. */
d62a17ae 344static void route_match_interface_free(void *rule)
7f57883e 345{
d62a17ae 346 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
347}
348
349/* Route map commands for interface matching. */
364deb04
DL
350static 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};
7f57883e
DS
356
357/* `match ip next-hop IP_ACCESS_LIST' */
358
359/* Match function return 1 if match is success else return zero. */
b68885f9
LK
360static enum route_map_cmd_result_t
361route_match_ip_next_hop(void *rule, struct prefix *prefix,
362 route_map_object_t type, void *object)
f9e5c9ca 363{
d62a17ae 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;
7f57883e
DS
384}
385
386/* Route map `ip next-hop' match statement. `arg' should be
387 access-list name. */
d62a17ae 388static void *route_match_ip_next_hop_compile(const char *arg)
7f57883e 389{
d62a17ae 390 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
7f57883e
DS
391}
392
393/* Free route map's compiled `. */
d62a17ae 394static void route_match_ip_next_hop_free(void *rule)
7f57883e 395{
d62a17ae 396 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
397}
398
399/* Route map commands for ip next-hop matching. */
364deb04
DL
400static 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};
7f57883e
DS
406
407/* `match ip next-hop prefix-list PREFIX_LIST' */
408
b68885f9 409static enum route_map_cmd_result_t
d62a17ae 410route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
411 route_map_object_t type, void *object)
f9e5c9ca 412{
d62a17ae 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;
7f57883e
DS
433}
434
d62a17ae 435static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
7f57883e 436{
d62a17ae 437 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
7f57883e
DS
438}
439
d62a17ae 440static void route_match_ip_next_hop_prefix_list_free(void *rule)
7f57883e 441{
d62a17ae 442 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
443}
444
364deb04
DL
445static 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,
d62a17ae 449 route_match_ip_next_hop_prefix_list_compile,
364deb04
DL
450 route_match_ip_next_hop_prefix_list_free
451};
7f57883e
DS
452
453/* `match ip address IP_ACCESS_LIST' */
454
455/* Match function should return 1 if match is success else return
456 zero. */
b68885f9
LK
457static enum route_map_cmd_result_t
458route_match_ip_address(void *rule, struct prefix *prefix,
459 route_map_object_t type, void *object)
7f57883e 460{
d62a17ae 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;
7f57883e
DS
473}
474
475/* Route map `ip address' match statement. `arg' should be
476 access-list name. */
d62a17ae 477static void *route_match_ip_address_compile(const char *arg)
7f57883e 478{
d62a17ae 479 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
7f57883e
DS
480}
481
482/* Free route map's compiled `ip address' value. */
d62a17ae 483static void route_match_ip_address_free(void *rule)
7f57883e 484{
d62a17ae 485 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
486}
487
488/* Route map commands for ip address matching. */
364deb04
DL
489static 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};
7f57883e
DS
495
496/* `match ip address prefix-list PREFIX_LIST' */
497
b68885f9 498static enum route_map_cmd_result_t
d62a17ae 499route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
500 route_map_object_t type, void *object)
7f57883e 501{
d62a17ae 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;
7f57883e
DS
514}
515
d62a17ae 516static void *route_match_ip_address_prefix_list_compile(const char *arg)
7f57883e 517{
d62a17ae 518 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
7f57883e
DS
519}
520
d62a17ae 521static void route_match_ip_address_prefix_list_free(void *rule)
7f57883e 522{
d62a17ae 523 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
524}
525
364deb04
DL
526static 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,
d62a17ae 530 route_match_ip_address_prefix_list_compile,
364deb04
DL
531 route_match_ip_address_prefix_list_free
532};
7f57883e
DS
533
534/* `match tag TAG' */
535/* Match function return 1 if match is success else return zero. */
b68885f9
LK
536static enum route_map_cmd_result_t
537route_match_tag(void *rule, struct prefix *prefix, route_map_object_t type,
538 void *object)
f9e5c9ca 539{
d7c0a89a 540 // unsigned short *tag;
d62a17ae 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;
7f57883e
DS
555}
556
557/* Route map `match tag' match statement. `arg' is TAG value */
d62a17ae 558static void *route_match_tag_compile(const char *arg)
7f57883e 559{
d7c0a89a 560 // unsigned short *tag;
d62a17ae 561 //
0d6f7fd6 562 // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(unsigned short));
d62a17ae 563 // *tag = atoi (arg);
564 //
565 // return tag;
7f57883e
DS
566}
567
568/* Free route map's compiled `match tag' value. */
d62a17ae 569static void route_match_tag_free(void *rule)
7f57883e 570{
d62a17ae 571 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
572}
573
574/* Route map commands for tag matching. */
364deb04
DL
575static 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};
7f57883e
DS
581
582/* Set metric to attribute. */
b68885f9
LK
583static enum route_map_cmd_result_t
584route_set_metric(void *rule, struct prefix *prefix,
585 route_map_object_t type, void *object)
f9e5c9ca 586{
d62a17ae 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;
7f57883e
DS
610}
611
612/* set metric compilation. */
d62a17ae 613static void *route_set_metric_compile(const char *arg)
7f57883e 614{
d62a17ae 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,
0d6f7fd6 655 // sizeof(struct rip_metric_modifier));
d62a17ae 656 // mod->type = type;
657 // mod->metric = metric;
658
659 // return mod;
7f57883e
DS
660}
661
662/* Free route map's compiled `set metric' value. */
d62a17ae 663static void route_set_metric_free(void *rule)
7f57883e 664{
d62a17ae 665 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
666}
667
668/* Set metric rule structure. */
364deb04
DL
669static const struct route_map_rule_cmd route_set_metric_cmd = {
670 "metric",
671 route_set_metric,
672 route_set_metric_compile,
d62a17ae 673 route_set_metric_free,
674};
7f57883e
DS
675
676/* `set ip next-hop IP_ADDRESS' */
677
581776fa 678/* Set nexthop to object. object must be pointer to struct attr. */
b68885f9
LK
679static enum route_map_cmd_result_t
680route_set_ip_nexthop(void *rule, struct prefix *prefix,
681 route_map_object_t type, void *object)
f9e5c9ca 682{
d62a17ae 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;
7f57883e
DS
697}
698
699/* Route map `ip nexthop' compile function. Given string is converted
700 to struct in_addr structure. */
d62a17ae 701static void *route_set_ip_nexthop_compile(const char *arg)
7f57883e 702{
d62a17ae 703 // int ret;
704 // struct in_addr *address;
705 //
0d6f7fd6 706 // address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct
d62a17ae 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;
7f57883e
DS
718}
719
720/* Free route map's compiled `ip nexthop' value. */
d62a17ae 721static void route_set_ip_nexthop_free(void *rule)
7f57883e 722{
d62a17ae 723 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
724}
725
726/* Route map commands for ip nexthop set. */
364deb04
DL
727static 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};
7f57883e
DS
733
734/* `set tag TAG' */
735
581776fa 736/* Set tag to object. object must be pointer to struct attr. */
b68885f9
LK
737static enum route_map_cmd_result_t
738route_set_tag(void *rule, struct prefix *prefix,
739 route_map_object_t type, void *object)
f9e5c9ca 740{
d7c0a89a 741 // unsigned short *tag;
d62a17ae 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;
7f57883e
DS
755}
756
757/* Route map `tag' compile function. Given string is converted
d7c0a89a 758 to unsigned short. */
d62a17ae 759static void *route_set_tag_compile(const char *arg)
7f57883e 760{
d7c0a89a 761 // unsigned short *tag;
d62a17ae 762 //
0d6f7fd6 763 // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(unsigned short));
d62a17ae 764 // *tag = atoi (arg);
765 //
766 // return tag;
7f57883e
DS
767}
768
769/* Free route map's compiled `ip nexthop' value. */
d62a17ae 770static void route_set_tag_free(void *rule)
7f57883e 771{
d62a17ae 772 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
7f57883e
DS
773}
774
775/* Route map commands for tag set. */
364deb04
DL
776static 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};
7f57883e
DS
782
783#define MATCH_STR "Match values from routing table\n"
784#define SET_STR "Set values in destination routing protocol\n"
785
786DEFUN (match_metric,
787 match_metric_cmd,
db684383 788 "match metric (0-4294967295)",
7f57883e
DS
789 MATCH_STR
790 "Match metric of route\n"
791 "Metric value\n")
792{
d62a17ae 793 return eigrp_route_match_add(vty, vty->index, "metric", argv[0]);
7f57883e
DS
794}
795
796DEFUN (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{
d62a17ae 803 if (argc == 0)
804 return eigrp_route_match_delete(vty, vty->index, "metric",
805 NULL);
7f57883e 806
d62a17ae 807 return eigrp_route_match_delete(vty, vty->index, "metric", argv[0]);
7f57883e
DS
808}
809
d62a17ae 810ALIAS(no_match_metric, no_match_metric_val_cmd,
db684383 811 "no match metric (0-4294967295)", NO_STR MATCH_STR
d62a17ae 812 "Match metric of route\n"
813 "Metric value\n")
7f57883e
DS
814
815DEFUN (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{
d62a17ae 822 return eigrp_route_match_add(vty, vty->index, "interface", argv[0]);
7f57883e
DS
823}
824
825DEFUN (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{
d62a17ae 832 if (argc == 0)
833 return eigrp_route_match_delete(vty, vty->index, "interface",
834 NULL);
7f57883e 835
d62a17ae 836 return eigrp_route_match_delete(vty, vty->index, "interface", argv[0]);
7f57883e
DS
837}
838
d62a17ae 839ALIAS(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")
7f57883e
DS
843
844DEFUN (match_ip_next_hop,
845 match_ip_next_hop_cmd,
c60dec36 846 "match ip next-hop ACCESSLIST4_NAME",
7f57883e
DS
847 MATCH_STR
848 IP_STR
849 "Match next-hop address of route\n"
7f57883e
DS
850 "IP Access-list name\n")
851{
d62a17ae 852 return eigrp_route_match_add(vty, vty->index, "ip next-hop", argv[0]);
7f57883e
DS
853}
854
855DEFUN (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{
d62a17ae 863 if (argc == 0)
864 return eigrp_route_match_delete(vty, vty->index, "ip next-hop",
865 NULL);
7f57883e 866
d62a17ae 867 return eigrp_route_match_delete(vty, vty->index, "ip next-hop",
868 argv[0]);
7f57883e
DS
869}
870
d62a17ae 871ALIAS(no_match_ip_next_hop, no_match_ip_next_hop_val_cmd,
c60dec36 872 "no match ip next-hop ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
d62a17ae 873 "Match next-hop address of route\n"
d62a17ae 874 "IP Access-list name\n")
7f57883e
DS
875
876DEFUN (match_ip_next_hop_prefix_list,
877 match_ip_next_hop_prefix_list_cmd,
943224a1 878 "match ip next-hop prefix-list PREFIXLIST_NAME",
7f57883e
DS
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{
d62a17ae 885 return eigrp_route_match_add(vty, vty->index, "ip next-hop prefix-list",
886 argv[0]);
7f57883e
DS
887}
888
889DEFUN (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{
d62a17ae 898 if (argc == 0)
899 return eigrp_route_match_delete(
900 vty, vty->index, "ip next-hop prefix-list", NULL);
7f57883e 901
d62a17ae 902 return eigrp_route_match_delete(vty, vty->index,
903 "ip next-hop prefix-list", argv[0]);
7f57883e
DS
904}
905
d62a17ae 906ALIAS(no_match_ip_next_hop_prefix_list,
907 no_match_ip_next_hop_prefix_list_val_cmd,
943224a1 908 "no match ip next-hop prefix-list PREFIXLIST_NAME", NO_STR MATCH_STR IP_STR
d62a17ae 909 "Match next-hop address of route\n"
910 "Match entries of prefix-lists\n"
911 "IP prefix-list name\n")
7f57883e
DS
912
913DEFUN (match_ip_address,
914 match_ip_address_cmd,
c60dec36 915 "match ip address ACCESSLIST4_NAME",
7f57883e
DS
916 MATCH_STR
917 IP_STR
918 "Match address of route\n"
7f57883e 919 "IP Access-list name\n")
7f57883e 920{
d62a17ae 921 return eigrp_route_match_add(vty, vty->index, "ip address", argv[0]);
7f57883e
DS
922}
923
924DEFUN (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{
d62a17ae 932 if (argc == 0)
933 return eigrp_route_match_delete(vty, vty->index, "ip address",
934 NULL);
7f57883e 935
d62a17ae 936 return eigrp_route_match_delete(vty, vty->index, "ip address", argv[0]);
7f57883e
DS
937}
938
d62a17ae 939ALIAS(no_match_ip_address, no_match_ip_address_val_cmd,
c60dec36 940 "no match ip address ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
d62a17ae 941 "Match address of route\n"
d62a17ae 942 "IP Access-list name\n")
7f57883e
DS
943
944DEFUN (match_ip_address_prefix_list,
945 match_ip_address_prefix_list_cmd,
943224a1 946 "match ip address prefix-list PREFIXLIST_NAME",
7f57883e
DS
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{
d62a17ae 953 return eigrp_route_match_add(vty, vty->index, "ip address prefix-list",
954 argv[0]);
7f57883e
DS
955}
956
957DEFUN (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{
d62a17ae 966 if (argc == 0)
967 return eigrp_route_match_delete(vty, vty->index,
968 "ip address prefix-list", NULL);
7f57883e 969
d62a17ae 970 return eigrp_route_match_delete(vty, vty->index,
971 "ip address prefix-list", argv[0]);
7f57883e
DS
972}
973
d62a17ae 974ALIAS(no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_val_cmd,
943224a1 975 "no match ip address prefix-list PREFIXLIST_NAME", NO_STR MATCH_STR IP_STR
d62a17ae 976 "Match address of route\n"
977 "Match entries of prefix-lists\n"
978 "IP prefix-list name\n")
7f57883e
DS
979
980DEFUN (match_tag,
981 match_tag_cmd,
db684383 982 "match tag (0-65535)",
7f57883e
DS
983 MATCH_STR
984 "Match tag of route\n"
985 "Metric value\n")
986{
d62a17ae 987 return eigrp_route_match_add(vty, vty->index, "tag", argv[0]);
7f57883e
DS
988}
989
990DEFUN (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{
d62a17ae 997 if (argc == 0)
998 return eigrp_route_match_delete(vty, vty->index, "tag", NULL);
7f57883e 999
d62a17ae 1000 return eigrp_route_match_delete(vty, vty->index, "tag", argv[0]);
7f57883e
DS
1001}
1002
db684383 1003ALIAS(no_match_tag, no_match_tag_val_cmd, "no match tag (0-65535)",
d62a17ae 1004 NO_STR MATCH_STR
1005 "Match tag of route\n"
1006 "Metric value\n")
7f57883e
DS
1007
1008/* set functions */
1009
1010DEFUN (set_metric,
1011 set_metric_cmd,
db684383 1012 "set metric (0-4294967295)",
7f57883e
DS
1013 SET_STR
1014 "Metric value for destination routing protocol\n"
1015 "Metric value\n")
1016{
d62a17ae 1017 return eigrp_route_set_add(vty, vty->index, "metric", argv[0]);
7f57883e
DS
1018}
1019
9d303b37 1020ALIAS(set_metric, set_metric_addsub_cmd, "set metric <+/-metric>", SET_STR
d62a17ae 1021 "Metric value for destination routing protocol\n"
1022 "Add or subtract metric\n")
7f57883e
DS
1023
1024DEFUN (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{
d62a17ae 1031 if (argc == 0)
1032 return eigrp_route_set_delete(vty, vty->index, "metric", NULL);
7f57883e 1033
d62a17ae 1034 return eigrp_route_set_delete(vty, vty->index, "metric", argv[0]);
7f57883e
DS
1035}
1036
d62a17ae 1037ALIAS(no_set_metric, no_set_metric_val_cmd,
db684383 1038 "no set metric ((0-4294967295)|<+/-metric>)", NO_STR SET_STR
d62a17ae 1039 "Metric value for destination routing protocol\n"
1040 "Metric value\n"
1041 "Add or subtract metric\n")
7f57883e
DS
1042
1043DEFUN (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{
d62a17ae 1051 union sockunion su;
1052 int ret;
7f57883e 1053
d62a17ae 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 }
7f57883e 1059
d62a17ae 1060 return eigrp_route_set_add(vty, vty->index, "ip next-hop", argv[0]);
7f57883e
DS
1061}
1062
1063DEFUN (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{
d62a17ae 1071 if (argc == 0)
1072 return eigrp_route_set_delete(vty, vty->index, "ip next-hop",
1073 NULL);
7f57883e 1074
d62a17ae 1075 return eigrp_route_set_delete(vty, vty->index, "ip next-hop", argv[0]);
7f57883e
DS
1076}
1077
d62a17ae 1078ALIAS(no_set_ip_nexthop, no_set_ip_nexthop_val_cmd,
9d303b37 1079 "no set ip next-hop A.B.C.D", NO_STR SET_STR IP_STR
d62a17ae 1080 "Next hop address\n"
1081 "IP address of next hop\n")
7f57883e
DS
1082
1083DEFUN (set_tag,
1084 set_tag_cmd,
db684383 1085 "set tag (0-65535)",
7f57883e
DS
1086 SET_STR
1087 "Tag value for routing protocol\n"
1088 "Tag value\n")
1089{
d62a17ae 1090 return eigrp_route_set_add(vty, vty->index, "tag", argv[0]);
7f57883e
DS
1091}
1092
1093DEFUN (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{
d62a17ae 1100 if (argc == 0)
1101 return eigrp_route_set_delete(vty, vty->index, "tag", NULL);
7f57883e 1102
d62a17ae 1103 return eigrp_route_set_delete(vty, vty->index, "tag", argv[0]);
7f57883e
DS
1104}
1105
db684383 1106ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR
d62a17ae 1107 "Tag value for routing protocol\n"
1108 "Tag value\n")
7f57883e 1109
5463d7c3
DS
1110DEFUN (eigrp_distribute_list,
1111 eigrp_distribute_list_cmd,
c60dec36 1112 "distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
5463d7c3
DS
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
1130DEFUN (eigrp_no_distribute_list,
1131 eigrp_no_distribute_list_cmd,
c60dec36 1132 "no distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
5463d7c3
DS
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
7f57883e
DS
1152
1153/* Route-map init */
d62a17ae 1154void eigrp_route_map_init()
7f57883e 1155{
d62a17ae 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
5463d7c3
DS
1161 install_element(EIGRP_NODE, &eigrp_distribute_list_cmd);
1162 install_element(EIGRP_NODE, &eigrp_no_distribute_list_cmd);
1163
d62a17ae 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);*/
7f57883e 1210}