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