]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_routemap.c
Update the log message when we receive a non-link-local nexthop for better
[mirror_frr.git] / bgpd / bgp_routemap.c
CommitLineData
718e3744 1/* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "prefix.h"
24#include "filter.h"
25#include "routemap.h"
26#include "command.h"
27#include "linklist.h"
28#include "plist.h"
29#include "memory.h"
30#include "log.h"
25f45887
JJ
31#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
718e3744 33#else
25f45887
JJ
34# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
718e3744 40#include "buffer.h"
41#include "sockunion.h"
518f0eb1 42#include "hash.h"
3f9c7369 43#include "queue.h"
718e3744 44
45#include "bgpd/bgpd.h"
46#include "bgpd/bgp_table.h"
47#include "bgpd/bgp_attr.h"
48#include "bgpd/bgp_aspath.h"
518f0eb1 49#include "bgpd/bgp_packet.h"
718e3744 50#include "bgpd/bgp_route.h"
73ac8160 51#include "bgpd/bgp_zebra.h"
718e3744 52#include "bgpd/bgp_regex.h"
53#include "bgpd/bgp_community.h"
54#include "bgpd/bgp_clist.h"
55#include "bgpd/bgp_filter.h"
56#include "bgpd/bgp_mplsvpn.h"
57#include "bgpd/bgp_ecommunity.h"
320da874 58#include "bgpd/bgp_vty.h"
73ac8160 59#include "bgpd/bgp_debug.h"
718e3744 60
518f0eb1 61
718e3744 62/* Memo of route-map commands.
63
64o Cisco route-map
65
66 match as-path : Done
67 community : Done
bc413143 68 interface : Done
718e3744 69 ip address : Done
70 ip next-hop : Done
c1643bb7 71 ip route-source : Done
718e3744 72 ip prefix-list : Done
73 ipv6 address : Done
74 ipv6 next-hop : Done
75 ipv6 route-source: (This will not be implemented by bgpd)
76 ipv6 prefix-list : Done
77 length : (This will not be implemented by bgpd)
78 metric : Done
79 route-type : (This will not be implemented by bgpd)
0d9551dc 80 tag : Done
af291c15 81 local-preference : Done
718e3744 82
83 set as-path prepend : Done
84 as-path tag : Not yet
85 automatic-tag : (This will not be implemented by bgpd)
86 community : Done
87 comm-list : Not yet
88 dampning : Not yet
89 default : (This will not be implemented by bgpd)
90 interface : (This will not be implemented by bgpd)
91 ip default : (This will not be implemented by bgpd)
92 ip next-hop : Done
93 ip precedence : (This will not be implemented by bgpd)
94 ip tos : (This will not be implemented by bgpd)
95 level : (This will not be implemented by bgpd)
96 local-preference : Done
97 metric : Done
98 metric-type : Not yet
99 origin : Done
0d9551dc 100 tag : Done
718e3744 101 weight : Done
102
2aa640bd 103o Local extensions
718e3744 104
105 set ipv6 next-hop global: Done
106 set ipv6 next-hop local : Done
841f7a57 107 set as-path exclude : Done
718e3744 108
109*/
6b0655a2 110
b304dcb8
TT
111 /* generic as path object to be shared in multiple rules */
112
113static void *
114route_aspath_compile (const char *arg)
115{
116 struct aspath *aspath;
117
118 aspath = aspath_str2aspath (arg);
119 if (! aspath)
120 return NULL;
121 return aspath;
122}
123
124static void
125route_aspath_free (void *rule)
126{
127 struct aspath *aspath = rule;
128 aspath_free (aspath);
129}
130
fee0f4c6 131 /* 'match peer (A.B.C.D|X:X::X:X)' */
132
133/* Compares the peer specified in the 'match peer' clause with the peer
134 received in bgp_info->peer. If it is the same, or if the peer structure
135 received is a peer_group containing it, returns RMAP_MATCH. */
94f2b392 136static route_map_result_t
fee0f4c6 137route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
138 void *object)
139{
140 union sockunion *su;
c63b83fe
JBD
141 union sockunion su_def = { .sa.sa_family = AF_INET,
142 .sin.sin_addr.s_addr = INADDR_ANY };
fee0f4c6 143 struct peer_group *group;
144 struct peer *peer;
1eb8ef25 145 struct listnode *node, *nnode;
fee0f4c6 146
147 if (type == RMAP_BGP)
148 {
149 su = rule;
150 peer = ((struct bgp_info *) object)->peer;
151
152 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
153 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
154 return RMAP_NOMATCH;
155
156 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
157 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
c63b83fe 158 if (sockunion_same (su, &su_def))
fee0f4c6 159 {
22db9dec 160 int ret;
fee0f4c6 161 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
162 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
163 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
22db9dec 164 ret = RMAP_MATCH;
fee0f4c6 165 else
22db9dec 166 ret = RMAP_NOMATCH;
22db9dec 167 return ret;
fee0f4c6 168 }
c63b83fe 169
fee0f4c6 170 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
171 {
172 if (sockunion_same (su, &peer->su))
173 return RMAP_MATCH;
174
175 return RMAP_NOMATCH;
176 }
177 else
178 {
179 group = peer->group;
1eb8ef25 180 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
fee0f4c6 181 {
182 if (sockunion_same (su, &peer->su))
183 return RMAP_MATCH;
fee0f4c6 184 }
30a2231a 185 return RMAP_NOMATCH;
fee0f4c6 186 }
187 }
188 return RMAP_NOMATCH;
189}
190
94f2b392 191static void *
fd79ac91 192route_match_peer_compile (const char *arg)
fee0f4c6 193{
194 union sockunion *su;
195 int ret;
196
197 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
198
4fe080d7 199 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
fee0f4c6 200 if (ret < 0) {
201 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
202 return NULL;
203 }
204
205 return su;
206}
207
208/* Free route map's compiled `ip address' value. */
94f2b392 209static void
fee0f4c6 210route_match_peer_free (void *rule)
211{
212 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
213}
214
215/* Route map commands for ip address matching. */
216struct route_map_rule_cmd route_match_peer_cmd =
217{
218 "peer",
219 route_match_peer,
220 route_match_peer_compile,
221 route_match_peer_free
222};
223
718e3744 224/* `match ip address IP_ACCESS_LIST' */
225
226/* Match function should return 1 if match is success else return
227 zero. */
94f2b392 228static route_map_result_t
718e3744 229route_match_ip_address (void *rule, struct prefix *prefix,
230 route_map_object_t type, void *object)
231{
232 struct access_list *alist;
233 /* struct prefix_ipv4 match; */
234
235 if (type == RMAP_BGP)
236 {
237 alist = access_list_lookup (AFI_IP, (char *) rule);
238 if (alist == NULL)
239 return RMAP_NOMATCH;
240
241 return (access_list_apply (alist, prefix) == FILTER_DENY ?
242 RMAP_NOMATCH : RMAP_MATCH);
243 }
244 return RMAP_NOMATCH;
245}
246
247/* Route map `ip address' match statement. `arg' should be
248 access-list name. */
94f2b392 249static void *
fd79ac91 250route_match_ip_address_compile (const char *arg)
718e3744 251{
252 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
253}
254
255/* Free route map's compiled `ip address' value. */
94f2b392 256static void
718e3744 257route_match_ip_address_free (void *rule)
258{
259 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
260}
261
262/* Route map commands for ip address matching. */
263struct route_map_rule_cmd route_match_ip_address_cmd =
264{
265 "ip address",
266 route_match_ip_address,
267 route_match_ip_address_compile,
268 route_match_ip_address_free
269};
6b0655a2 270
718e3744 271/* `match ip next-hop IP_ADDRESS' */
272
273/* Match function return 1 if match is success else return zero. */
94f2b392 274static route_map_result_t
718e3744 275route_match_ip_next_hop (void *rule, struct prefix *prefix,
276 route_map_object_t type, void *object)
277{
278 struct access_list *alist;
279 struct bgp_info *bgp_info;
280 struct prefix_ipv4 p;
281
282 if (type == RMAP_BGP)
283 {
284 bgp_info = object;
285 p.family = AF_INET;
286 p.prefix = bgp_info->attr->nexthop;
287 p.prefixlen = IPV4_MAX_BITLEN;
288
289 alist = access_list_lookup (AFI_IP, (char *) rule);
290 if (alist == NULL)
291 return RMAP_NOMATCH;
292
293 return (access_list_apply (alist, &p) == FILTER_DENY ?
294 RMAP_NOMATCH : RMAP_MATCH);
295 }
296 return RMAP_NOMATCH;
297}
298
299/* Route map `ip next-hop' match statement. `arg' is
300 access-list name. */
94f2b392 301static void *
fd79ac91 302route_match_ip_next_hop_compile (const char *arg)
718e3744 303{
304 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
305}
306
307/* Free route map's compiled `ip address' value. */
94f2b392 308static void
718e3744 309route_match_ip_next_hop_free (void *rule)
310{
311 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
312}
313
314/* Route map commands for ip next-hop matching. */
315struct route_map_rule_cmd route_match_ip_next_hop_cmd =
316{
317 "ip next-hop",
318 route_match_ip_next_hop,
319 route_match_ip_next_hop_compile,
320 route_match_ip_next_hop_free
321};
6b0655a2 322
c1643bb7 323/* `match ip route-source ACCESS-LIST' */
324
325/* Match function return 1 if match is success else return zero. */
94f2b392 326static route_map_result_t
c1643bb7 327route_match_ip_route_source (void *rule, struct prefix *prefix,
328 route_map_object_t type, void *object)
329{
330 struct access_list *alist;
331 struct bgp_info *bgp_info;
332 struct peer *peer;
333 struct prefix_ipv4 p;
334
335 if (type == RMAP_BGP)
336 {
337 bgp_info = object;
338 peer = bgp_info->peer;
339
340 if (! peer || sockunion_family (&peer->su) != AF_INET)
341 return RMAP_NOMATCH;
342
343 p.family = AF_INET;
344 p.prefix = peer->su.sin.sin_addr;
345 p.prefixlen = IPV4_MAX_BITLEN;
346
347 alist = access_list_lookup (AFI_IP, (char *) rule);
348 if (alist == NULL)
349 return RMAP_NOMATCH;
350
351 return (access_list_apply (alist, &p) == FILTER_DENY ?
352 RMAP_NOMATCH : RMAP_MATCH);
353 }
354 return RMAP_NOMATCH;
355}
356
357/* Route map `ip route-source' match statement. `arg' is
358 access-list name. */
94f2b392 359static void *
c1643bb7 360route_match_ip_route_source_compile (const char *arg)
361{
362 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
363}
364
365/* Free route map's compiled `ip address' value. */
94f2b392 366static void
c1643bb7 367route_match_ip_route_source_free (void *rule)
368{
369 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
370}
371
372/* Route map commands for ip route-source matching. */
373struct route_map_rule_cmd route_match_ip_route_source_cmd =
374{
375 "ip route-source",
376 route_match_ip_route_source,
377 route_match_ip_route_source_compile,
378 route_match_ip_route_source_free
379};
6b0655a2 380
718e3744 381/* `match ip address prefix-list PREFIX_LIST' */
382
94f2b392 383static route_map_result_t
718e3744 384route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
385 route_map_object_t type, void *object)
386{
387 struct prefix_list *plist;
388
389 if (type == RMAP_BGP)
390 {
391 plist = prefix_list_lookup (AFI_IP, (char *) rule);
392 if (plist == NULL)
393 return RMAP_NOMATCH;
394
395 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
396 RMAP_NOMATCH : RMAP_MATCH);
397 }
398 return RMAP_NOMATCH;
399}
400
94f2b392 401static void *
fd79ac91 402route_match_ip_address_prefix_list_compile (const char *arg)
718e3744 403{
404 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
405}
406
94f2b392 407static void
718e3744 408route_match_ip_address_prefix_list_free (void *rule)
409{
410 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
411}
412
413struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
414{
415 "ip address prefix-list",
416 route_match_ip_address_prefix_list,
417 route_match_ip_address_prefix_list_compile,
418 route_match_ip_address_prefix_list_free
419};
6b0655a2 420
718e3744 421/* `match ip next-hop prefix-list PREFIX_LIST' */
422
94f2b392 423static route_map_result_t
718e3744 424route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
425 route_map_object_t type, void *object)
426{
427 struct prefix_list *plist;
428 struct bgp_info *bgp_info;
429 struct prefix_ipv4 p;
430
431 if (type == RMAP_BGP)
432 {
433 bgp_info = object;
434 p.family = AF_INET;
435 p.prefix = bgp_info->attr->nexthop;
436 p.prefixlen = IPV4_MAX_BITLEN;
437
438 plist = prefix_list_lookup (AFI_IP, (char *) rule);
439 if (plist == NULL)
440 return RMAP_NOMATCH;
441
442 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
443 RMAP_NOMATCH : RMAP_MATCH);
444 }
445 return RMAP_NOMATCH;
446}
447
94f2b392 448static void *
fd79ac91 449route_match_ip_next_hop_prefix_list_compile (const char *arg)
718e3744 450{
451 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
452}
453
94f2b392 454static void
718e3744 455route_match_ip_next_hop_prefix_list_free (void *rule)
456{
457 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
458}
459
460struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
461{
462 "ip next-hop prefix-list",
463 route_match_ip_next_hop_prefix_list,
464 route_match_ip_next_hop_prefix_list_compile,
465 route_match_ip_next_hop_prefix_list_free
466};
6b0655a2 467
c1643bb7 468/* `match ip route-source prefix-list PREFIX_LIST' */
469
94f2b392 470static route_map_result_t
c1643bb7 471route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
472 route_map_object_t type, void *object)
473{
474 struct prefix_list *plist;
475 struct bgp_info *bgp_info;
476 struct peer *peer;
477 struct prefix_ipv4 p;
478
479 if (type == RMAP_BGP)
480 {
481 bgp_info = object;
482 peer = bgp_info->peer;
483
484 if (! peer || sockunion_family (&peer->su) != AF_INET)
485 return RMAP_NOMATCH;
486
487 p.family = AF_INET;
488 p.prefix = peer->su.sin.sin_addr;
489 p.prefixlen = IPV4_MAX_BITLEN;
490
491 plist = prefix_list_lookup (AFI_IP, (char *) rule);
492 if (plist == NULL)
493 return RMAP_NOMATCH;
494
495 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
496 RMAP_NOMATCH : RMAP_MATCH);
497 }
498 return RMAP_NOMATCH;
499}
500
94f2b392 501static void *
c1643bb7 502route_match_ip_route_source_prefix_list_compile (const char *arg)
503{
504 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
505}
506
94f2b392 507static void
c1643bb7 508route_match_ip_route_source_prefix_list_free (void *rule)
509{
510 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
511}
512
513struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
514{
515 "ip route-source prefix-list",
516 route_match_ip_route_source_prefix_list,
517 route_match_ip_route_source_prefix_list_compile,
518 route_match_ip_route_source_prefix_list_free
519};
6b0655a2 520
af291c15
DS
521/* `match local-preference LOCAL-PREF' */
522
523/* Match function return 1 if match is success else return zero. */
524static route_map_result_t
525route_match_local_pref (void *rule, struct prefix *prefix,
526 route_map_object_t type, void *object)
527{
528 u_int32_t *local_pref;
529 struct bgp_info *bgp_info;
530
531 if (type == RMAP_BGP)
532 {
533 local_pref = rule;
534 bgp_info = object;
535
536 if (bgp_info->attr->local_pref == *local_pref)
537 return RMAP_MATCH;
538 else
539 return RMAP_NOMATCH;
540 }
541 return RMAP_NOMATCH;
542}
543
544/* Route map `match local-preference' match statement.
545 `arg' is local-pref value */
546static void *
547route_match_local_pref_compile (const char *arg)
548{
549 u_int32_t *local_pref;
550 char *endptr = NULL;
551 unsigned long tmpval;
552
553 /* Locpref value shoud be integer. */
554 if (! all_digit (arg))
555 return NULL;
556
557 errno = 0;
558 tmpval = strtoul (arg, &endptr, 10);
559 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
560 return NULL;
561
562 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
563
564 if (!local_pref)
565 return local_pref;
566
567 *local_pref = tmpval;
568 return local_pref;
569}
570
571/* Free route map's compiled `match local-preference' value. */
572static void
573route_match_local_pref_free (void *rule)
574{
575 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
576}
577
578/* Route map commands for metric matching. */
579struct route_map_rule_cmd route_match_local_pref_cmd =
580{
581 "local-preference",
582 route_match_local_pref,
583 route_match_local_pref_compile,
584 route_match_local_pref_free
585};
586
718e3744 587/* `match metric METRIC' */
588
589/* Match function return 1 if match is success else return zero. */
94f2b392 590static route_map_result_t
718e3744 591route_match_metric (void *rule, struct prefix *prefix,
592 route_map_object_t type, void *object)
593{
594 u_int32_t *med;
595 struct bgp_info *bgp_info;
596
597 if (type == RMAP_BGP)
598 {
599 med = rule;
600 bgp_info = object;
601
602 if (bgp_info->attr->med == *med)
603 return RMAP_MATCH;
604 else
605 return RMAP_NOMATCH;
606 }
607 return RMAP_NOMATCH;
608}
609
610/* Route map `match metric' match statement. `arg' is MED value */
94f2b392 611static void *
fd79ac91 612route_match_metric_compile (const char *arg)
718e3744 613{
614 u_int32_t *med;
615 char *endptr = NULL;
3b424979 616 unsigned long tmpval;
718e3744 617
664711c1
UW
618 /* Metric value shoud be integer. */
619 if (! all_digit (arg))
620 return NULL;
621
622 errno = 0;
3b424979 623 tmpval = strtoul (arg, &endptr, 10);
664711c1 624 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
3b424979 625 return NULL;
fd79ac91 626
718e3744 627 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
fd79ac91 628
629 if (!med)
630 return med;
631
3b424979 632 *med = tmpval;
718e3744 633 return med;
634}
635
636/* Free route map's compiled `match metric' value. */
94f2b392 637static void
718e3744 638route_match_metric_free (void *rule)
639{
640 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
641}
642
643/* Route map commands for metric matching. */
644struct route_map_rule_cmd route_match_metric_cmd =
645{
646 "metric",
647 route_match_metric,
648 route_match_metric_compile,
649 route_match_metric_free
650};
6b0655a2 651
718e3744 652/* `match as-path ASPATH' */
653
654/* Match function for as-path match. I assume given object is */
94f2b392 655static route_map_result_t
718e3744 656route_match_aspath (void *rule, struct prefix *prefix,
657 route_map_object_t type, void *object)
658{
659
660 struct as_list *as_list;
661 struct bgp_info *bgp_info;
662
663 if (type == RMAP_BGP)
664 {
665 as_list = as_list_lookup ((char *) rule);
666 if (as_list == NULL)
667 return RMAP_NOMATCH;
518f0eb1 668
718e3744 669 bgp_info = object;
518f0eb1 670
718e3744 671 /* Perform match. */
672 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
673 }
674 return RMAP_NOMATCH;
675}
676
677/* Compile function for as-path match. */
94f2b392 678static void *
fd79ac91 679route_match_aspath_compile (const char *arg)
718e3744 680{
681 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
682}
683
684/* Compile function for as-path match. */
94f2b392 685static void
718e3744 686route_match_aspath_free (void *rule)
687{
688 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
689}
690
691/* Route map commands for aspath matching. */
692struct route_map_rule_cmd route_match_aspath_cmd =
693{
694 "as-path",
695 route_match_aspath,
696 route_match_aspath_compile,
697 route_match_aspath_free
698};
6b0655a2 699
718e3744 700/* `match community COMMUNIY' */
701struct rmap_community
702{
703 char *name;
704 int exact;
705};
706
707/* Match function for community match. */
94f2b392 708static route_map_result_t
718e3744 709route_match_community (void *rule, struct prefix *prefix,
710 route_map_object_t type, void *object)
711{
712 struct community_list *list;
713 struct bgp_info *bgp_info;
714 struct rmap_community *rcom;
715
716 if (type == RMAP_BGP)
717 {
718 bgp_info = object;
719 rcom = rule;
720
fee6e4e4 721 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
718e3744 722 if (! list)
723 return RMAP_NOMATCH;
724
725 if (rcom->exact)
726 {
727 if (community_list_exact_match (bgp_info->attr->community, list))
728 return RMAP_MATCH;
729 }
730 else
731 {
732 if (community_list_match (bgp_info->attr->community, list))
733 return RMAP_MATCH;
734 }
735 }
736 return RMAP_NOMATCH;
737}
738
739/* Compile function for community match. */
94f2b392 740static void *
fd79ac91 741route_match_community_compile (const char *arg)
718e3744 742{
743 struct rmap_community *rcom;
744 int len;
745 char *p;
746
747 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
748
749 p = strchr (arg, ' ');
750 if (p)
751 {
752 len = p - arg;
753 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
754 memcpy (rcom->name, arg, len);
755 rcom->exact = 1;
756 }
757 else
758 {
759 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
760 rcom->exact = 0;
761 }
762 return rcom;
763}
764
765/* Compile function for community match. */
94f2b392 766static void
718e3744 767route_match_community_free (void *rule)
768{
769 struct rmap_community *rcom = rule;
770
771 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
772 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
773}
774
775/* Route map commands for community matching. */
776struct route_map_rule_cmd route_match_community_cmd =
777{
778 "community",
779 route_match_community,
780 route_match_community_compile,
781 route_match_community_free
782};
6b0655a2 783
73ffb25b 784/* Match function for extcommunity match. */
94f2b392 785static route_map_result_t
73ffb25b 786route_match_ecommunity (void *rule, struct prefix *prefix,
787 route_map_object_t type, void *object)
788{
789 struct community_list *list;
790 struct bgp_info *bgp_info;
791
792 if (type == RMAP_BGP)
793 {
794 bgp_info = object;
fb982c25
PJ
795
796 if (!bgp_info->attr->extra)
797 return RMAP_NOMATCH;
798
73ffb25b 799 list = community_list_lookup (bgp_clist, (char *) rule,
fee6e4e4 800 EXTCOMMUNITY_LIST_MASTER);
73ffb25b 801 if (! list)
802 return RMAP_NOMATCH;
803
fb982c25 804 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
73ffb25b 805 return RMAP_MATCH;
806 }
807 return RMAP_NOMATCH;
808}
809
810/* Compile function for extcommunity match. */
94f2b392 811static void *
fd79ac91 812route_match_ecommunity_compile (const char *arg)
73ffb25b 813{
814 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
815}
816
817/* Compile function for extcommunity match. */
94f2b392 818static void
73ffb25b 819route_match_ecommunity_free (void *rule)
820{
821 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
822}
823
824/* Route map commands for community matching. */
825struct route_map_rule_cmd route_match_ecommunity_cmd =
826{
827 "extcommunity",
828 route_match_ecommunity,
829 route_match_ecommunity_compile,
830 route_match_ecommunity_free
831};
6b0655a2 832
718e3744 833/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
834 and `address-family vpnv4'. */
6b0655a2 835
718e3744 836/* `match origin' */
94f2b392 837static route_map_result_t
718e3744 838route_match_origin (void *rule, struct prefix *prefix,
839 route_map_object_t type, void *object)
840{
841 u_char *origin;
842 struct bgp_info *bgp_info;
843
844 if (type == RMAP_BGP)
845 {
846 origin = rule;
847 bgp_info = object;
848
849 if (bgp_info->attr->origin == *origin)
850 return RMAP_MATCH;
851 }
852
853 return RMAP_NOMATCH;
854}
855
94f2b392 856static void *
fd79ac91 857route_match_origin_compile (const char *arg)
718e3744 858{
859 u_char *origin;
860
861 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
862
863 if (strcmp (arg, "igp") == 0)
864 *origin = 0;
865 else if (strcmp (arg, "egp") == 0)
866 *origin = 1;
867 else
868 *origin = 2;
869
870 return origin;
871}
872
873/* Free route map's compiled `ip address' value. */
94f2b392 874static void
718e3744 875route_match_origin_free (void *rule)
876{
877 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
878}
879
880/* Route map commands for origin matching. */
881struct route_map_rule_cmd route_match_origin_cmd =
882{
883 "origin",
884 route_match_origin,
885 route_match_origin_compile,
886 route_match_origin_free
887};
1add115a
VT
888
889/* match probability { */
890
891static route_map_result_t
892route_match_probability (void *rule, struct prefix *prefix,
893 route_map_object_t type, void *object)
894{
895 long r;
896#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
897 r = random();
898#else
899 r = (long) rand();
900#endif
901
902 switch (*(unsigned *) rule)
903 {
904 case 0: break;
905 case RAND_MAX: return RMAP_MATCH;
906 default:
907 if (r < *(unsigned *) rule)
908 {
909 return RMAP_MATCH;
910 }
911 }
912
913 return RMAP_NOMATCH;
914}
915
916static void *
917route_match_probability_compile (const char *arg)
918{
919 unsigned *lobule;
920 unsigned perc;
921
922#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
923 srandom (time (NULL));
924#else
925 srand (time (NULL));
926#endif
927
928 perc = atoi (arg);
929 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
930
931 switch (perc)
932 {
933 case 0: *lobule = 0; break;
934 case 100: *lobule = RAND_MAX; break;
935 default: *lobule = RAND_MAX / 100 * perc;
936 }
937
938 return lobule;
939}
940
941static void
942route_match_probability_free (void *rule)
943{
944 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
945}
946
947struct route_map_rule_cmd route_match_probability_cmd =
948{
949 "probability",
950 route_match_probability,
951 route_match_probability_compile,
952 route_match_probability_free
953};
954
bc413143
DS
955/* `match interface IFNAME' */
956/* Match function should return 1 if match is success else return
957 zero. */
958static route_map_result_t
959route_match_interface (void *rule, struct prefix *prefix,
960 route_map_object_t type, void *object)
961{
962 struct interface *ifp;
bc413143
DS
963 struct bgp_info *info;
964
965 if (type == RMAP_BGP)
966 {
967 info = object;
968
969 if (!info || !info->attr)
970 return RMAP_NOMATCH;
971
972 ifp = if_lookup_by_name ((char *)rule);
973
974 if (ifp == NULL || ifp->ifindex != info->attr->nh_ifindex)
975 return RMAP_NOMATCH;
976
977 return RMAP_MATCH;
978 }
979 return RMAP_NOMATCH;
980}
981
982/* Route map `interface' match statement. `arg' should be
983 interface name. */
984static void *
985route_match_interface_compile (const char *arg)
986{
987 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
988}
989
990/* Free route map's compiled `interface' value. */
991static void
992route_match_interface_free (void *rule)
993{
994 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
995}
996
997/* Route map commands for ip address matching. */
998struct route_map_rule_cmd route_match_interface_cmd =
999{
1000 "interface",
1001 route_match_interface,
1002 route_match_interface_compile,
1003 route_match_interface_free
1004};
1005
1add115a
VT
1006/* } */
1007
718e3744 1008/* `set ip next-hop IP_ADDRESS' */
1009
0d9551dc
DS
1010/* Match function return 1 if match is success else return zero. */
1011static route_map_result_t
1012route_match_tag (void *rule, struct prefix *prefix,
1013 route_map_object_t type, void *object)
1014{
1015 u_short *tag;
1016 struct bgp_info *bgp_info;
1017
1018 if (type == RMAP_BGP)
1019 {
1020 tag = rule;
1021 bgp_info = object;
1022
1023 if (!bgp_info->attr->extra)
1024 return RMAP_NOMATCH;
1025
1026 return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
1027 }
1028
1029 return RMAP_NOMATCH;
1030}
1031
1032
1033/* Route map `match tag' match statement. `arg' is TAG value */
1034static void *
1035route_match_tag_compile (const char *arg)
1036{
1037 u_short *tag;
1038 u_short tmp;
1039
1040 /* tag value shoud be integer. */
1041 if (! all_digit (arg))
1042 return NULL;
1043
1044 tmp = atoi(arg);
1045 if (tmp < 1)
1046 return NULL;
1047
1048 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
1049
1050 if (!tag)
1051 return tag;
1052
1053 *tag = tmp;
1054
1055 return tag;
1056}
1057
1058
1059/* Free route map's compiled 'match tag' value. */
1060static void
1061route_match_tag_free (void *rule)
1062{
1063 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1064}
1065
1066/* Route map commands for tag matching. */
1067struct route_map_rule_cmd route_match_tag_cmd =
1068{
1069 "tag",
1070 route_match_tag,
1071 route_match_tag_compile,
1072 route_match_tag_free,
1073};
1074
1075
718e3744 1076/* Set nexthop to object. ojbect must be pointer to struct attr. */
ac41b2a2 1077struct rmap_ip_nexthop_set
1078{
1079 struct in_addr *address;
1080 int peer_address;
316e074d 1081 int unchanged;
ac41b2a2 1082};
1083
94f2b392 1084static route_map_result_t
718e3744 1085route_set_ip_nexthop (void *rule, struct prefix *prefix,
1086 route_map_object_t type, void *object)
1087{
ac41b2a2 1088 struct rmap_ip_nexthop_set *rins = rule;
718e3744 1089 struct bgp_info *bgp_info;
ac41b2a2 1090 struct peer *peer;
718e3744 1091
1092 if (type == RMAP_BGP)
1093 {
718e3744 1094 bgp_info = object;
ac41b2a2 1095 peer = bgp_info->peer;
1096
316e074d
DS
1097 if (rins->unchanged)
1098 {
1099 SET_FLAG(bgp_info->attr->rmap_change_flags,
1100 BATTR_RMAP_NEXTHOP_UNCHANGED);
1101 }
1102 else if (rins->peer_address)
ac41b2a2 1103 {
fee0f4c6 1104 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1105 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
ac41b2a2 1106 && peer->su_remote
1107 && sockunion_family (peer->su_remote) == AF_INET)
1108 {
0c5ed3ed 1109 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
ac41b2a2 1110 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1111 }
3f9c7369 1112 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT))
ac41b2a2 1113 {
3f9c7369
DS
1114 /* The next hop value will be set as part of packet rewrite.
1115 * Set the flags here to indicate that rewrite needs to be done.
1116 * Also, clear the value.
1117 */
1118 SET_FLAG(bgp_info->attr->rmap_change_flags,
1119 BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
1120 SET_FLAG(bgp_info->attr->rmap_change_flags,
1121 BATTR_RMAP_NEXTHOP_CHANGED);
1122 bgp_info->attr->nexthop.s_addr = 0;
ac41b2a2 1123 }
1124 }
1125 else
1126 {
3f9c7369 1127 /* Set next hop value. */
ac41b2a2 1128 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1129 bgp_info->attr->nexthop = *rins->address;
3f9c7369
DS
1130 SET_FLAG(bgp_info->attr->rmap_change_flags,
1131 BATTR_RMAP_NEXTHOP_CHANGED);
ac41b2a2 1132 }
718e3744 1133 }
1134
1135 return RMAP_OKAY;
1136}
1137
1138/* Route map `ip nexthop' compile function. Given string is converted
1139 to struct in_addr structure. */
94f2b392 1140static void *
fd79ac91 1141route_set_ip_nexthop_compile (const char *arg)
718e3744 1142{
ac41b2a2 1143 struct rmap_ip_nexthop_set *rins;
1144 struct in_addr *address = NULL;
1145 int peer_address = 0;
316e074d 1146 int unchanged = 0;
718e3744 1147 int ret;
718e3744 1148
ac41b2a2 1149 if (strcmp (arg, "peer-address") == 0)
1150 peer_address = 1;
316e074d
DS
1151 else if (strcmp (arg, "unchanged") == 0)
1152 unchanged = 1;
ac41b2a2 1153 else
718e3744 1154 {
ac41b2a2 1155 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1156 ret = inet_aton (arg, address);
1157
1158 if (ret == 0)
1159 {
1160 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1161 return NULL;
1162 }
718e3744 1163 }
1164
393deb9b 1165 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
ac41b2a2 1166
1167 rins->address = address;
1168 rins->peer_address = peer_address;
316e074d 1169 rins->unchanged = unchanged;
ac41b2a2 1170
1171 return rins;
718e3744 1172}
1173
1174/* Free route map's compiled `ip nexthop' value. */
94f2b392 1175static void
718e3744 1176route_set_ip_nexthop_free (void *rule)
1177{
ac41b2a2 1178 struct rmap_ip_nexthop_set *rins = rule;
1179
1180 if (rins->address)
1181 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1182
1183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
718e3744 1184}
1185
1186/* Route map commands for ip nexthop set. */
1187struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1188{
1189 "ip next-hop",
1190 route_set_ip_nexthop,
1191 route_set_ip_nexthop_compile,
1192 route_set_ip_nexthop_free
1193};
6b0655a2 1194
718e3744 1195/* `set local-preference LOCAL_PREF' */
1196
1197/* Set local preference. */
94f2b392 1198static route_map_result_t
718e3744 1199route_set_local_pref (void *rule, struct prefix *prefix,
1200 route_map_object_t type, void *object)
1201{
1202 u_int32_t *local_pref;
1203 struct bgp_info *bgp_info;
1204
1205 if (type == RMAP_BGP)
1206 {
1207 /* Fetch routemap's rule information. */
1208 local_pref = rule;
1209 bgp_info = object;
1210
1211 /* Set local preference value. */
1212 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1213 bgp_info->attr->local_pref = *local_pref;
1214 }
1215
1216 return RMAP_OKAY;
1217}
1218
1219/* set local preference compilation. */
94f2b392 1220static void *
fd79ac91 1221route_set_local_pref_compile (const char *arg)
718e3744 1222{
fd79ac91 1223 unsigned long tmp;
718e3744 1224 u_int32_t *local_pref;
1225 char *endptr = NULL;
1226
1227 /* Local preference value shoud be integer. */
1228 if (! all_digit (arg))
1229 return NULL;
fd79ac91 1230
664711c1 1231 errno = 0;
fd79ac91 1232 tmp = strtoul (arg, &endptr, 10);
664711c1 1233 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
fd79ac91 1234 return NULL;
1235
1236 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1237
1238 if (!local_pref)
1239 return local_pref;
1240
1241 *local_pref = tmp;
1242
718e3744 1243 return local_pref;
1244}
1245
1246/* Free route map's local preference value. */
94f2b392 1247static void
718e3744 1248route_set_local_pref_free (void *rule)
1249{
1250 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1251}
1252
1253/* Set local preference rule structure. */
1254struct route_map_rule_cmd route_set_local_pref_cmd =
1255{
1256 "local-preference",
1257 route_set_local_pref,
1258 route_set_local_pref_compile,
1259 route_set_local_pref_free,
1260};
6b0655a2 1261
718e3744 1262/* `set weight WEIGHT' */
1263
1264/* Set weight. */
94f2b392 1265static route_map_result_t
718e3744 1266route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1267 void *object)
1268{
1269 u_int32_t *weight;
1270 struct bgp_info *bgp_info;
1271
1272 if (type == RMAP_BGP)
1273 {
1274 /* Fetch routemap's rule information. */
1275 weight = rule;
1276 bgp_info = object;
1277
1278 /* Set weight value. */
fb982c25
PJ
1279 if (*weight)
1280 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1281 else if (bgp_info->attr->extra)
1282 bgp_info->attr->extra->weight = 0;
718e3744 1283 }
1284
1285 return RMAP_OKAY;
1286}
1287
1288/* set local preference compilation. */
94f2b392 1289static void *
fd79ac91 1290route_set_weight_compile (const char *arg)
718e3744 1291{
fd79ac91 1292 unsigned long tmp;
718e3744 1293 u_int32_t *weight;
1294 char *endptr = NULL;
1295
1296 /* Local preference value shoud be integer. */
1297 if (! all_digit (arg))
1298 return NULL;
1299
664711c1 1300 errno = 0;
fd79ac91 1301 tmp = strtoul (arg, &endptr, 10);
664711c1 1302 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
fd79ac91 1303 return NULL;
1304
718e3744 1305 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
fd79ac91 1306
1307 if (weight == NULL)
1308 return weight;
1309
1310 *weight = tmp;
1311
718e3744 1312 return weight;
1313}
1314
1315/* Free route map's local preference value. */
94f2b392 1316static void
718e3744 1317route_set_weight_free (void *rule)
1318{
1319 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1320}
1321
1322/* Set local preference rule structure. */
1323struct route_map_rule_cmd route_set_weight_cmd =
1324{
1325 "weight",
1326 route_set_weight,
1327 route_set_weight_compile,
1328 route_set_weight_free,
1329};
6b0655a2 1330
718e3744 1331/* `set metric METRIC' */
1332
1333/* Set metric to attribute. */
94f2b392 1334static route_map_result_t
718e3744 1335route_set_metric (void *rule, struct prefix *prefix,
1336 route_map_object_t type, void *object)
1337{
1338 char *metric;
1339 u_int32_t metric_val;
1340 struct bgp_info *bgp_info;
1341
1342 if (type == RMAP_BGP)
1343 {
1344 /* Fetch routemap's rule information. */
1345 metric = rule;
1346 bgp_info = object;
1347
1348 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1349 bgp_info->attr->med = 0;
1350 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1351
1352 if (all_digit (metric))
1353 {
1354 metric_val = strtoul (metric, (char **)NULL, 10);
1355 bgp_info->attr->med = metric_val;
1356 }
1357 else
1358 {
1359 metric_val = strtoul (metric+1, (char **)NULL, 10);
1360
1361 if (strncmp (metric, "+", 1) == 0)
1362 {
3b424979 1363 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1364 bgp_info->attr->med = BGP_MED_MAX - 1;
718e3744 1365 else
537d8ea9 1366 bgp_info->attr->med += metric_val;
718e3744 1367 }
1368 else if (strncmp (metric, "-", 1) == 0)
1369 {
537d8ea9 1370 if (bgp_info->attr->med <= metric_val)
1371 bgp_info->attr->med = 0;
718e3744 1372 else
537d8ea9 1373 bgp_info->attr->med -= metric_val;
718e3744 1374 }
1375 }
1376 }
1377 return RMAP_OKAY;
1378}
1379
1380/* set metric compilation. */
94f2b392 1381static void *
fd79ac91 1382route_set_metric_compile (const char *arg)
718e3744 1383{
94f2b392 1384 unsigned long larg;
718e3744 1385 char *endptr = NULL;
1386
1387 if (all_digit (arg))
1388 {
1389 /* set metric value check*/
664711c1 1390 errno = 0;
94f2b392 1391 larg = strtoul (arg, &endptr, 10);
664711c1 1392 if (*endptr != '\0' || errno || larg > UINT32_MAX)
718e3744 1393 return NULL;
1394 }
1395 else
1396 {
5e3edbf5 1397 /* set metric <+/-metric> check */
718e3744 1398 if ((strncmp (arg, "+", 1) != 0
1399 && strncmp (arg, "-", 1) != 0)
1400 || (! all_digit (arg+1)))
1401 return NULL;
1402
664711c1 1403 errno = 0;
94f2b392 1404 larg = strtoul (arg+1, &endptr, 10);
664711c1 1405 if (*endptr != '\0' || errno || larg > UINT32_MAX)
718e3744 1406 return NULL;
1407 }
1408
1409 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1410}
1411
1412/* Free route map's compiled `set metric' value. */
94f2b392 1413static void
718e3744 1414route_set_metric_free (void *rule)
1415{
1416 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1417}
1418
1419/* Set metric rule structure. */
1420struct route_map_rule_cmd route_set_metric_cmd =
1421{
1422 "metric",
1423 route_set_metric,
1424 route_set_metric_compile,
1425 route_set_metric_free,
1426};
6b0655a2 1427
718e3744 1428/* `set as-path prepend ASPATH' */
1429
1430/* For AS path prepend mechanism. */
94f2b392 1431static route_map_result_t
718e3744 1432route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1433{
1434 struct aspath *aspath;
1435 struct aspath *new;
1436 struct bgp_info *binfo;
1437
1438 if (type == RMAP_BGP)
1439 {
1440 aspath = rule;
1441 binfo = object;
1442
1443 if (binfo->attr->aspath->refcnt)
1444 new = aspath_dup (binfo->attr->aspath);
1445 else
1446 new = binfo->attr->aspath;
1447
1448 aspath_prepend (aspath, new);
1449 binfo->attr->aspath = new;
1450 }
1451
1452 return RMAP_OKAY;
1453}
1454
2aa640bd 1455/* Set as-path prepend rule structure. */
718e3744 1456struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1457{
1458 "as-path prepend",
1459 route_set_aspath_prepend,
b304dcb8
TT
1460 route_aspath_compile,
1461 route_aspath_free,
718e3744 1462};
6b0655a2 1463
841f7a57
DO
1464/* `set as-path exclude ASn' */
1465
1466/* For ASN exclude mechanism.
1467 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1468 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1469 */
1470static route_map_result_t
1471route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1472{
1473 struct aspath * new_path, * exclude_path;
1474 struct bgp_info *binfo;
1475
1476 if (type == RMAP_BGP)
1477 {
1478 exclude_path = rule;
1479 binfo = object;
1480 if (binfo->attr->aspath->refcnt)
1481 new_path = aspath_dup (binfo->attr->aspath);
1482 else
1483 new_path = binfo->attr->aspath;
1484 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1485 }
1486 return RMAP_OKAY;
1487}
1488
841f7a57
DO
1489/* Set ASn exlude rule structure. */
1490struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1491{
1492 "as-path exclude",
1493 route_set_aspath_exclude,
b304dcb8
TT
1494 route_aspath_compile,
1495 route_aspath_free,
841f7a57 1496};
6b0655a2 1497
718e3744 1498/* `set community COMMUNITY' */
1499struct rmap_com_set
1500{
1501 struct community *com;
1502 int additive;
1503 int none;
1504};
1505
1506/* For community set mechanism. */
94f2b392 1507static route_map_result_t
718e3744 1508route_set_community (void *rule, struct prefix *prefix,
1509 route_map_object_t type, void *object)
1510{
1511 struct rmap_com_set *rcs;
1512 struct bgp_info *binfo;
1513 struct attr *attr;
1514 struct community *new = NULL;
1515 struct community *old;
1516 struct community *merge;
aa94ca86 1517
718e3744 1518 if (type == RMAP_BGP)
1519 {
1520 rcs = rule;
1521 binfo = object;
1522 attr = binfo->attr;
1523 old = attr->community;
1524
1525 /* "none" case. */
1526 if (rcs->none)
1527 {
1528 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1529 attr->community = NULL;
b06b35f0
CF
1530 /* See the longer comment down below. */
1531 if (old && old->refcnt == 0)
1532 community_free(old);
718e3744 1533 return RMAP_OKAY;
1534 }
1535
1536 /* "additive" case. */
1537 if (rcs->additive && old)
1538 {
1539 merge = community_merge (community_dup (old), rcs->com);
aa94ca86
PJ
1540
1541 /* HACK: if the old community is not intern'd,
1542 * we should free it here, or all reference to it may be lost.
1543 * Really need to cleanup attribute caching sometime.
1544 */
1545 if (old->refcnt == 0)
1546 community_free (old);
718e3744 1547 new = community_uniq_sort (merge);
1548 community_free (merge);
1549 }
1550 else
1551 new = community_dup (rcs->com);
aa94ca86
PJ
1552
1553 /* will be interned by caller if required */
4a2035fd 1554 attr->community = new;
70601e06 1555
718e3744 1556 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1557 }
1558
1559 return RMAP_OKAY;
1560}
1561
1562/* Compile function for set community. */
94f2b392 1563static void *
fd79ac91 1564route_set_community_compile (const char *arg)
718e3744 1565{
1566 struct rmap_com_set *rcs;
1567 struct community *com = NULL;
1568 char *sp;
1569 int additive = 0;
1570 int none = 0;
1571
1572 if (strcmp (arg, "none") == 0)
1573 none = 1;
1574 else
1575 {
1576 sp = strstr (arg, "additive");
1577
1578 if (sp && sp > arg)
1579 {
1580 /* "additive" keyworkd is included. */
1581 additive = 1;
1582 *(sp - 1) = '\0';
1583 }
1584
1585 com = community_str2com (arg);
1586
1587 if (additive)
1588 *(sp - 1) = ' ';
1589
1590 if (! com)
1591 return NULL;
1592 }
1593
393deb9b 1594 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
4a2035fd 1595 rcs->com = com;
718e3744 1596 rcs->additive = additive;
1597 rcs->none = none;
1598
1599 return rcs;
1600}
1601
1602/* Free function for set community. */
94f2b392 1603static void
718e3744 1604route_set_community_free (void *rule)
1605{
1606 struct rmap_com_set *rcs = rule;
1607
1608 if (rcs->com)
1609 community_free (rcs->com);
1610 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1611}
1612
1613/* Set community rule structure. */
1614struct route_map_rule_cmd route_set_community_cmd =
1615{
1616 "community",
1617 route_set_community,
1618 route_set_community_compile,
1619 route_set_community_free,
1620};
6b0655a2 1621
fee6e4e4 1622/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
718e3744 1623
1624/* For community set mechanism. */
94f2b392 1625static route_map_result_t
718e3744 1626route_set_community_delete (void *rule, struct prefix *prefix,
1627 route_map_object_t type, void *object)
1628{
1629 struct community_list *list;
1630 struct community *merge;
1631 struct community *new;
1632 struct community *old;
1633 struct bgp_info *binfo;
1634
1635 if (type == RMAP_BGP)
1636 {
1637 if (! rule)
1638 return RMAP_OKAY;
1639
1640 binfo = object;
fee6e4e4 1641 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
718e3744 1642 old = binfo->attr->community;
1643
1644 if (list && old)
1645 {
1646 merge = community_list_match_delete (community_dup (old), list);
1647 new = community_uniq_sort (merge);
1648 community_free (merge);
1649
604a9b43
ML
1650 /* HACK: if the old community is not intern'd,
1651 * we should free it here, or all reference to it may be lost.
1652 * Really need to cleanup attribute caching sometime.
1653 */
1654 if (old->refcnt == 0)
1655 community_free (old);
1656
718e3744 1657 if (new->size == 0)
1658 {
1659 binfo->attr->community = NULL;
1660 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1661 community_free (new);
1662 }
1663 else
1664 {
4a2035fd 1665 binfo->attr->community = new;
718e3744 1666 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1667 }
1668 }
1669 }
1670
1671 return RMAP_OKAY;
1672}
1673
1674/* Compile function for set community. */
94f2b392 1675static void *
fd79ac91 1676route_set_community_delete_compile (const char *arg)
718e3744 1677{
1678 char *p;
1679 char *str;
1680 int len;
1681
1682 p = strchr (arg, ' ');
1683 if (p)
1684 {
1685 len = p - arg;
1686 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1687 memcpy (str, arg, len);
1688 }
1689 else
1690 str = NULL;
1691
1692 return str;
1693}
1694
1695/* Free function for set community. */
94f2b392 1696static void
718e3744 1697route_set_community_delete_free (void *rule)
1698{
1699 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1700}
1701
1702/* Set community rule structure. */
1703struct route_map_rule_cmd route_set_community_delete_cmd =
1704{
1705 "comm-list",
1706 route_set_community_delete,
1707 route_set_community_delete_compile,
1708 route_set_community_delete_free,
1709};
6b0655a2 1710
718e3744 1711/* `set extcommunity rt COMMUNITY' */
1712
73d78ea0 1713/* For community set mechanism. Used by _rt and _soo. */
94f2b392 1714static route_map_result_t
73d78ea0
DL
1715route_set_ecommunity (void *rule, struct prefix *prefix,
1716 route_map_object_t type, void *object)
718e3744 1717{
1718 struct ecommunity *ecom;
1719 struct ecommunity *new_ecom;
1720 struct ecommunity *old_ecom;
1721 struct bgp_info *bgp_info;
1722
1723 if (type == RMAP_BGP)
1724 {
1725 ecom = rule;
1726 bgp_info = object;
1727
1728 if (! ecom)
1729 return RMAP_OKAY;
1730
1731 /* We assume additive for Extended Community. */
fb982c25 1732 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
718e3744 1733
1734 if (old_ecom)
27bf90a1
DL
1735 {
1736 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1737
1738 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1739 * ->refcnt = 0 => set by a previous route-map statement */
1740 if (!old_ecom->refcnt)
1741 ecommunity_free (&old_ecom);
1742 }
718e3744 1743 else
1744 new_ecom = ecommunity_dup (ecom);
1745
27bf90a1
DL
1746 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1747 bgp_info->attr->extra->ecommunity = new_ecom;
70601e06 1748
718e3744 1749 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1750 }
1751 return RMAP_OKAY;
1752}
1753
1754/* Compile function for set community. */
94f2b392 1755static void *
fd79ac91 1756route_set_ecommunity_rt_compile (const char *arg)
718e3744 1757{
1758 struct ecommunity *ecom;
1759
1760 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1761 if (! ecom)
1762 return NULL;
f6f434b2 1763 return ecommunity_intern (ecom);
718e3744 1764}
1765
73d78ea0 1766/* Free function for set community. Used by _rt and _soo */
94f2b392 1767static void
73d78ea0 1768route_set_ecommunity_free (void *rule)
718e3744 1769{
1770 struct ecommunity *ecom = rule;
f6f434b2 1771 ecommunity_unintern (&ecom);
718e3744 1772}
1773
1774/* Set community rule structure. */
1775struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1776{
1777 "extcommunity rt",
73d78ea0 1778 route_set_ecommunity,
718e3744 1779 route_set_ecommunity_rt_compile,
73d78ea0 1780 route_set_ecommunity_free,
718e3744 1781};
1782
1783/* `set extcommunity soo COMMUNITY' */
1784
718e3744 1785/* Compile function for set community. */
94f2b392 1786static void *
fd79ac91 1787route_set_ecommunity_soo_compile (const char *arg)
718e3744 1788{
1789 struct ecommunity *ecom;
1790
1791 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1792 if (! ecom)
1793 return NULL;
1794
f6f434b2 1795 return ecommunity_intern (ecom);
718e3744 1796}
1797
718e3744 1798/* Set community rule structure. */
1799struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1800{
1801 "extcommunity soo",
73d78ea0 1802 route_set_ecommunity,
718e3744 1803 route_set_ecommunity_soo_compile,
73d78ea0 1804 route_set_ecommunity_free,
718e3744 1805};
6b0655a2 1806
718e3744 1807/* `set origin ORIGIN' */
1808
1809/* For origin set. */
94f2b392 1810static route_map_result_t
718e3744 1811route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1812{
1813 u_char *origin;
1814 struct bgp_info *bgp_info;
1815
1816 if (type == RMAP_BGP)
1817 {
1818 origin = rule;
1819 bgp_info = object;
1820
1821 bgp_info->attr->origin = *origin;
1822 }
1823
1824 return RMAP_OKAY;
1825}
1826
1827/* Compile function for origin set. */
94f2b392 1828static void *
fd79ac91 1829route_set_origin_compile (const char *arg)
718e3744 1830{
1831 u_char *origin;
1832
1833 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1834
1835 if (strcmp (arg, "igp") == 0)
1836 *origin = 0;
1837 else if (strcmp (arg, "egp") == 0)
1838 *origin = 1;
1839 else
1840 *origin = 2;
1841
1842 return origin;
1843}
1844
1845/* Compile function for origin set. */
94f2b392 1846static void
718e3744 1847route_set_origin_free (void *rule)
1848{
1849 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1850}
1851
2aa640bd 1852/* Set origin rule structure. */
718e3744 1853struct route_map_rule_cmd route_set_origin_cmd =
1854{
1855 "origin",
1856 route_set_origin,
1857 route_set_origin_compile,
1858 route_set_origin_free,
1859};
6b0655a2 1860
718e3744 1861/* `set atomic-aggregate' */
1862
1863/* For atomic aggregate set. */
94f2b392 1864static route_map_result_t
718e3744 1865route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1866 route_map_object_t type, void *object)
1867{
1868 struct bgp_info *bgp_info;
1869
1870 if (type == RMAP_BGP)
1871 {
1872 bgp_info = object;
1873 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1874 }
1875
1876 return RMAP_OKAY;
1877}
1878
1879/* Compile function for atomic aggregate. */
94f2b392 1880static void *
fd79ac91 1881route_set_atomic_aggregate_compile (const char *arg)
718e3744 1882{
1883 return (void *)1;
1884}
1885
1886/* Compile function for atomic aggregate. */
94f2b392 1887static void
718e3744 1888route_set_atomic_aggregate_free (void *rule)
1889{
1890 return;
1891}
1892
1893/* Set atomic aggregate rule structure. */
1894struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1895{
1896 "atomic-aggregate",
1897 route_set_atomic_aggregate,
1898 route_set_atomic_aggregate_compile,
1899 route_set_atomic_aggregate_free,
1900};
6b0655a2 1901
718e3744 1902/* `set aggregator as AS A.B.C.D' */
1903struct aggregator
1904{
1905 as_t as;
1906 struct in_addr address;
1907};
1908
94f2b392 1909static route_map_result_t
718e3744 1910route_set_aggregator_as (void *rule, struct prefix *prefix,
1911 route_map_object_t type, void *object)
1912{
1913 struct bgp_info *bgp_info;
1914 struct aggregator *aggregator;
fb982c25 1915 struct attr_extra *ae;
718e3744 1916
1917 if (type == RMAP_BGP)
1918 {
1919 bgp_info = object;
1920 aggregator = rule;
fb982c25
PJ
1921 ae = bgp_attr_extra_get (bgp_info->attr);
1922
1923 ae->aggregator_as = aggregator->as;
1924 ae->aggregator_addr = aggregator->address;
718e3744 1925 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1926 }
1927
1928 return RMAP_OKAY;
1929}
1930
94f2b392 1931static void *
fd79ac91 1932route_set_aggregator_as_compile (const char *arg)
718e3744 1933{
1934 struct aggregator *aggregator;
1935 char as[10];
1936 char address[20];
1937
393deb9b 1938 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
718e3744 1939 sscanf (arg, "%s %s", as, address);
1940
1941 aggregator->as = strtoul (as, NULL, 10);
1942 inet_aton (address, &aggregator->address);
1943
1944 return aggregator;
1945}
1946
94f2b392 1947static void
718e3744 1948route_set_aggregator_as_free (void *rule)
1949{
1950 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1951}
1952
1953struct route_map_rule_cmd route_set_aggregator_as_cmd =
1954{
1955 "aggregator as",
1956 route_set_aggregator_as,
1957 route_set_aggregator_as_compile,
1958 route_set_aggregator_as_free,
1959};
6b0655a2 1960
0d9551dc
DS
1961/* Set tag to object. object must be pointer to struct bgp_info */
1962static route_map_result_t
1963route_set_tag (void *rule, struct prefix *prefix,
1964 route_map_object_t type, void *object)
1965{
1966 u_short *tag;
1967 struct bgp_info *bgp_info;
1968 struct attr_extra *ae;
1969
1970 if (type == RMAP_BGP)
1971 {
1972 tag = rule;
1973 bgp_info = object;
1974 ae = bgp_attr_extra_get (bgp_info->attr);
1975
1976 /* Set tag value */
1977 ae->tag=*tag;
1978
1979 }
1980
1981 return RMAP_OKAY;
1982}
1983
1984/* Route map `tag' compile function. Given string is converted to u_short. */
1985static void *
1986route_set_tag_compile (const char *arg)
1987{
1988 u_short *tag;
1989 u_short tmp;
1990
1991 /* tag value shoud be integer. */
1992 if (! all_digit (arg))
1993 return NULL;
1994
1995 tmp = atoi(arg);
1996
1997 if (tmp < 1)
1998 return NULL;
1999
2000 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
2001
2002 if (!tag)
2003 return tag;
2004
2005 *tag = tmp;
2006
2007 return tag;
2008}
2009
2010/* Free route map's tag value. */
2011static void
2012route_set_tag_free (void *rule)
2013{
2014 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2015}
2016
2017
2018/* Route map commands for tag set. */
2019struct route_map_rule_cmd route_set_tag_cmd =
2020{
2021 "tag",
2022 route_set_tag,
2023 route_set_tag_compile,
2024 route_set_tag_free,
2025};
2026
2027
718e3744 2028#ifdef HAVE_IPV6
2029/* `match ipv6 address IP_ACCESS_LIST' */
2030
94f2b392 2031static route_map_result_t
718e3744 2032route_match_ipv6_address (void *rule, struct prefix *prefix,
2033 route_map_object_t type, void *object)
2034{
2035 struct access_list *alist;
2036
2037 if (type == RMAP_BGP)
2038 {
2039 alist = access_list_lookup (AFI_IP6, (char *) rule);
2040 if (alist == NULL)
2041 return RMAP_NOMATCH;
2042
2043 return (access_list_apply (alist, prefix) == FILTER_DENY ?
2044 RMAP_NOMATCH : RMAP_MATCH);
2045 }
2046 return RMAP_NOMATCH;
2047}
2048
94f2b392 2049static void *
fd79ac91 2050route_match_ipv6_address_compile (const char *arg)
718e3744 2051{
2052 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
2053}
2054
94f2b392 2055static void
718e3744 2056route_match_ipv6_address_free (void *rule)
2057{
2058 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2059}
2060
2061/* Route map commands for ip address matching. */
2062struct route_map_rule_cmd route_match_ipv6_address_cmd =
2063{
2064 "ipv6 address",
2065 route_match_ipv6_address,
2066 route_match_ipv6_address_compile,
2067 route_match_ipv6_address_free
2068};
6b0655a2 2069
718e3744 2070/* `match ipv6 next-hop IP_ADDRESS' */
2071
94f2b392 2072static route_map_result_t
718e3744 2073route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
2074 route_map_object_t type, void *object)
2075{
718e3744 2076 struct bgp_info *bgp_info;
2077
2078 if (type == RMAP_BGP)
2079 {
718e3744 2080 bgp_info = object;
fb982c25
PJ
2081
2082 if (!bgp_info->attr->extra)
2083 return RMAP_NOMATCH;
2084
2085 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
718e3744 2086 return RMAP_MATCH;
2087
801a9bcc 2088 if (bgp_info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
fb982c25 2089 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
718e3744 2090 return RMAP_MATCH;
2091
2092 return RMAP_NOMATCH;
2093 }
2094
2095 return RMAP_NOMATCH;
2096}
2097
94f2b392 2098static void *
fd79ac91 2099route_match_ipv6_next_hop_compile (const char *arg)
718e3744 2100{
2101 struct in6_addr *address;
2102 int ret;
2103
2104 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2105
2106 ret = inet_pton (AF_INET6, arg, address);
2107 if (!ret)
2108 {
2109 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2110 return NULL;
2111 }
2112
2113 return address;
2114}
2115
94f2b392 2116static void
718e3744 2117route_match_ipv6_next_hop_free (void *rule)
2118{
2119 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2120}
2121
2122struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
2123{
2124 "ipv6 next-hop",
2125 route_match_ipv6_next_hop,
2126 route_match_ipv6_next_hop_compile,
2127 route_match_ipv6_next_hop_free
2128};
6b0655a2 2129
718e3744 2130/* `match ipv6 address prefix-list PREFIX_LIST' */
2131
94f2b392 2132static route_map_result_t
718e3744 2133route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
2134 route_map_object_t type, void *object)
2135{
2136 struct prefix_list *plist;
2137
2138 if (type == RMAP_BGP)
2139 {
2140 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
2141 if (plist == NULL)
2142 return RMAP_NOMATCH;
2143
2144 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
2145 RMAP_NOMATCH : RMAP_MATCH);
2146 }
2147 return RMAP_NOMATCH;
2148}
2149
94f2b392 2150static void *
fd79ac91 2151route_match_ipv6_address_prefix_list_compile (const char *arg)
718e3744 2152{
2153 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
2154}
2155
94f2b392 2156static void
718e3744 2157route_match_ipv6_address_prefix_list_free (void *rule)
2158{
2159 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2160}
2161
2162struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
2163{
2164 "ipv6 address prefix-list",
2165 route_match_ipv6_address_prefix_list,
2166 route_match_ipv6_address_prefix_list_compile,
2167 route_match_ipv6_address_prefix_list_free
2168};
6b0655a2 2169
718e3744 2170/* `set ipv6 nexthop global IP_ADDRESS' */
2171
2172/* Set nexthop to object. ojbect must be pointer to struct attr. */
94f2b392 2173static route_map_result_t
718e3744 2174route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
2175 route_map_object_t type, void *object)
2176{
2177 struct in6_addr *address;
2178 struct bgp_info *bgp_info;
2179
2180 if (type == RMAP_BGP)
2181 {
2182 /* Fetch routemap's rule information. */
2183 address = rule;
2184 bgp_info = object;
2185
2186 /* Set next hop value. */
fb982c25 2187 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
3f9c7369 2188
718e3744 2189 /* Set nexthop length. */
fb982c25 2190 if (bgp_info->attr->extra->mp_nexthop_len == 0)
801a9bcc 2191 bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
3f9c7369
DS
2192
2193 SET_FLAG(bgp_info->attr->rmap_change_flags,
2194 BATTR_RMAP_NEXTHOP_CHANGED);
718e3744 2195 }
2196
2197 return RMAP_OKAY;
2198}
2199
2200/* Route map `ip next-hop' compile function. Given string is converted
2201 to struct in_addr structure. */
94f2b392 2202static void *
fd79ac91 2203route_set_ipv6_nexthop_global_compile (const char *arg)
718e3744 2204{
2205 int ret;
2206 struct in6_addr *address;
2207
2208 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2209
2210 ret = inet_pton (AF_INET6, arg, address);
2211
2212 if (ret == 0)
2213 {
2214 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2215 return NULL;
2216 }
2217
2218 return address;
2219}
2220
2221/* Free route map's compiled `ip next-hop' value. */
94f2b392 2222static void
718e3744 2223route_set_ipv6_nexthop_global_free (void *rule)
2224{
2225 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2226}
2227
2228/* Route map commands for ip nexthop set. */
2229struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2230{
2231 "ipv6 next-hop global",
2232 route_set_ipv6_nexthop_global,
2233 route_set_ipv6_nexthop_global_compile,
2234 route_set_ipv6_nexthop_global_free
2235};
6b0655a2 2236
718e3744 2237/* `set ipv6 nexthop local IP_ADDRESS' */
2238
2239/* Set nexthop to object. ojbect must be pointer to struct attr. */
94f2b392 2240static route_map_result_t
718e3744 2241route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2242 route_map_object_t type, void *object)
2243{
2244 struct in6_addr *address;
2245 struct bgp_info *bgp_info;
2246
2247 if (type == RMAP_BGP)
2248 {
2249 /* Fetch routemap's rule information. */
2250 address = rule;
2251 bgp_info = object;
2252
2253 /* Set next hop value. */
fb982c25 2254 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
718e3744 2255
2256 /* Set nexthop length. */
801a9bcc
DS
2257 if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
2258 bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
3f9c7369
DS
2259
2260 SET_FLAG(bgp_info->attr->rmap_change_flags,
2261 BATTR_RMAP_NEXTHOP_CHANGED);
718e3744 2262 }
2263
2264 return RMAP_OKAY;
2265}
2266
2267/* Route map `ip nexthop' compile function. Given string is converted
2268 to struct in_addr structure. */
94f2b392 2269static void *
fd79ac91 2270route_set_ipv6_nexthop_local_compile (const char *arg)
718e3744 2271{
2272 int ret;
2273 struct in6_addr *address;
2274
2275 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2276
2277 ret = inet_pton (AF_INET6, arg, address);
2278
2279 if (ret == 0)
2280 {
2281 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2282 return NULL;
2283 }
2284
2285 return address;
2286}
2287
2288/* Free route map's compiled `ip nexthop' value. */
94f2b392 2289static void
718e3744 2290route_set_ipv6_nexthop_local_free (void *rule)
2291{
2292 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2293}
2294
2295/* Route map commands for ip nexthop set. */
2296struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2297{
2298 "ipv6 next-hop local",
2299 route_set_ipv6_nexthop_local,
2300 route_set_ipv6_nexthop_local_compile,
2301 route_set_ipv6_nexthop_local_free
2302};
90916ac2
DS
2303
2304/* `set ipv6 nexthop peer-address' */
2305
2306/* Set nexthop to object. ojbect must be pointer to struct attr. */
2307static route_map_result_t
2308route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2309 route_map_object_t type, void *object)
2310{
90916ac2
DS
2311 struct in6_addr peer_address;
2312 struct bgp_info *bgp_info;
2313 struct peer *peer;
2314 char peer_addr_buf[INET6_ADDRSTRLEN];
2315
2316 if (type == RMAP_BGP)
2317 {
2318 /* Fetch routemap's rule information. */
90916ac2
DS
2319 bgp_info = object;
2320 peer = bgp_info->peer;
2321
2322 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2323 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2324 && peer->su_remote
2325 && sockunion_family (peer->su_remote) == AF_INET6)
2326 {
2327 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2328 peer_addr_buf,
2329 INET6_ADDRSTRLEN),
2330 &peer_address);
2331 }
3f9c7369 2332 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT))
90916ac2 2333 {
3f9c7369
DS
2334 SET_FLAG(bgp_info->attr->rmap_change_flags,
2335 BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
2336 SET_FLAG(bgp_info->attr->rmap_change_flags,
2337 BATTR_RMAP_NEXTHOP_CHANGED);
2338 /* clear next hop value. */
2339 memset (&((bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global),
2340 0, sizeof (struct in6_addr));
90916ac2
DS
2341 }
2342
2343 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2344 {
3f9c7369 2345 /* The next hop value will be set as part of packet rewrite. */
90916ac2
DS
2346
2347 /* Set nexthop length. */
801a9bcc
DS
2348 if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
2349 bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
90916ac2
DS
2350 }
2351 else
2352 {
3f9c7369 2353 /* The next hop value will be set as part of packet rewrite. */
90916ac2
DS
2354
2355 /* Set nexthop length. */
2356 if (bgp_info->attr->extra->mp_nexthop_len == 0)
801a9bcc 2357 bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
90916ac2
DS
2358 }
2359 }
2360
2361 return RMAP_OKAY;
2362}
2363
2364/* Route map `ip next-hop' compile function. Given string is converted
2365 to struct in_addr structure. */
2366static void *
2367route_set_ipv6_nexthop_peer_compile (const char *arg)
2368{
90916ac2
DS
2369 int *rins = NULL;
2370
2371 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2372 *rins = 1;
2373
2374 return rins;
2375}
2376
2377/* Free route map's compiled `ip next-hop' value. */
2378static void
2379route_set_ipv6_nexthop_peer_free (void *rule)
2380{
2381 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2382}
2383
2384/* Route map commands for ip nexthop set. */
2385struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2386{
2387 "ipv6 next-hop peer-address",
2388 route_set_ipv6_nexthop_peer,
2389 route_set_ipv6_nexthop_peer_compile,
2390 route_set_ipv6_nexthop_peer_free
2391};
2392
718e3744 2393#endif /* HAVE_IPV6 */
6b0655a2 2394
718e3744 2395/* `set vpnv4 nexthop A.B.C.D' */
2396
94f2b392 2397static route_map_result_t
718e3744 2398route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2399 route_map_object_t type, void *object)
2400{
2401 struct in_addr *address;
2402 struct bgp_info *bgp_info;
2403
2404 if (type == RMAP_BGP)
2405 {
2406 /* Fetch routemap's rule information. */
2407 address = rule;
2408 bgp_info = object;
2409
2410 /* Set next hop value. */
fb982c25 2411 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
718e3744 2412 }
2413
2414 return RMAP_OKAY;
2415}
2416
94f2b392 2417static void *
fd79ac91 2418route_set_vpnv4_nexthop_compile (const char *arg)
718e3744 2419{
2420 int ret;
2421 struct in_addr *address;
2422
2423 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2424
2425 ret = inet_aton (arg, address);
2426
2427 if (ret == 0)
2428 {
2429 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2430 return NULL;
2431 }
2432
2433 return address;
2434}
2435
94f2b392 2436static void
718e3744 2437route_set_vpnv4_nexthop_free (void *rule)
2438{
2439 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2440}
2441
2442/* Route map commands for ip nexthop set. */
2443struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2444{
2445 "vpnv4 next-hop",
2446 route_set_vpnv4_nexthop,
2447 route_set_vpnv4_nexthop_compile,
2448 route_set_vpnv4_nexthop_free
2449};
6b0655a2 2450
718e3744 2451/* `set originator-id' */
2452
2453/* For origin set. */
94f2b392 2454static route_map_result_t
718e3744 2455route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2456{
2457 struct in_addr *address;
2458 struct bgp_info *bgp_info;
2459
2460 if (type == RMAP_BGP)
2461 {
2462 address = rule;
2463 bgp_info = object;
2464
2465 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
fb982c25 2466 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
718e3744 2467 }
2468
2469 return RMAP_OKAY;
2470}
2471
2472/* Compile function for originator-id set. */
94f2b392 2473static void *
fd79ac91 2474route_set_originator_id_compile (const char *arg)
718e3744 2475{
2476 int ret;
2477 struct in_addr *address;
2478
2479 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2480
2481 ret = inet_aton (arg, address);
2482
2483 if (ret == 0)
2484 {
2485 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2486 return NULL;
2487 }
2488
2489 return address;
2490}
2491
2492/* Compile function for originator_id set. */
94f2b392 2493static void
718e3744 2494route_set_originator_id_free (void *rule)
2495{
2496 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2497}
2498
2aa640bd 2499/* Set originator-id rule structure. */
718e3744 2500struct route_map_rule_cmd route_set_originator_id_cmd =
2501{
2502 "originator-id",
2503 route_set_originator_id,
2504 route_set_originator_id_compile,
2505 route_set_originator_id_free,
2506};
6b0655a2 2507
718e3744 2508/* Add bgp route map rule. */
94f2b392 2509static int
718e3744 2510bgp_route_match_add (struct vty *vty, struct route_map_index *index,
518f0eb1
DS
2511 const char *command, const char *arg,
2512 route_map_event_t type)
718e3744 2513{
2514 int ret;
2515
2516 ret = route_map_add_match (index, command, arg);
2517 if (ret)
2518 {
2519 switch (ret)
2520 {
2521 case RMAP_RULE_MISSING:
5e3edbf5 2522 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
718e3744 2523 return CMD_WARNING;
718e3744 2524 case RMAP_COMPILE_ERROR:
5e3edbf5 2525 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
718e3744 2526 return CMD_WARNING;
718e3744 2527 }
2528 }
518f0eb1
DS
2529
2530 if (type != RMAP_EVENT_MATCH_ADDED)
2531 {
2532 route_map_upd8_dependency (type, arg, index->map->name);
2533 }
2534
718e3744 2535 return CMD_SUCCESS;
2536}
2537
2538/* Delete bgp route map rule. */
94f2b392 2539static int
718e3744 2540bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
518f0eb1
DS
2541 const char *command, const char *arg,
2542 route_map_event_t type)
718e3744 2543{
2544 int ret;
ffd0c037 2545 char *dep_name = NULL;
518f0eb1
DS
2546 const char *tmpstr;
2547 char *rmap_name = NULL;
718e3744 2548
518f0eb1
DS
2549 if (type != RMAP_EVENT_MATCH_DELETED)
2550 {
2551 /* ignore the mundane, the types without any dependency */
2552 if (arg == NULL)
2553 {
2554 if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
2555 dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
2556 }
ffd0c037
DS
2557 else
2558 {
2559 dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
2560 }
518f0eb1
DS
2561 rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
2562 }
2563
2564 ret = route_map_delete_match (index, command, dep_name);
718e3744 2565 if (ret)
2566 {
2567 switch (ret)
2568 {
2569 case RMAP_RULE_MISSING:
5e3edbf5 2570 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
518f0eb1 2571 break;
718e3744 2572 case RMAP_COMPILE_ERROR:
5e3edbf5 2573 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
518f0eb1 2574 break;
718e3744 2575 }
ffd0c037 2576 if (dep_name)
518f0eb1
DS
2577 XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
2578 if (rmap_name)
2579 XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
2580 return CMD_WARNING;
718e3744 2581 }
518f0eb1
DS
2582
2583 if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
2584 route_map_upd8_dependency(type, dep_name, rmap_name);
2585
ffd0c037 2586 if (dep_name)
518f0eb1
DS
2587 XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
2588 if (rmap_name)
2589 XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
2590
718e3744 2591 return CMD_SUCCESS;
2592}
2593
2594/* Add bgp route map rule. */
94f2b392 2595static int
718e3744 2596bgp_route_set_add (struct vty *vty, struct route_map_index *index,
fd79ac91 2597 const char *command, const char *arg)
718e3744 2598{
2599 int ret;
2600
2601 ret = route_map_add_set (index, command, arg);
2602 if (ret)
2603 {
2604 switch (ret)
2605 {
2606 case RMAP_RULE_MISSING:
5e3edbf5 2607 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
718e3744 2608 return CMD_WARNING;
718e3744 2609 case RMAP_COMPILE_ERROR:
5e3edbf5 2610 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
718e3744 2611 return CMD_WARNING;
718e3744 2612 }
2613 }
2614 return CMD_SUCCESS;
2615}
2616
2617/* Delete bgp route map rule. */
94f2b392 2618static int
718e3744 2619bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
fd79ac91 2620 const char *command, const char *arg)
718e3744 2621{
2622 int ret;
2623
2624 ret = route_map_delete_set (index, command, arg);
2625 if (ret)
2626 {
2627 switch (ret)
2628 {
2629 case RMAP_RULE_MISSING:
5e3edbf5 2630 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
718e3744 2631 return CMD_WARNING;
718e3744 2632 case RMAP_COMPILE_ERROR:
5e3edbf5 2633 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
718e3744 2634 return CMD_WARNING;
718e3744 2635 }
2636 }
2637 return CMD_SUCCESS;
2638}
2639
518f0eb1
DS
2640/*
2641 * This is the workhorse routine for processing in/out/import/export routemap
2642 * modifications.
2643 */
94f2b392 2644static void
ffd0c037 2645bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
518f0eb1 2646 int afi, int safi, int route_update)
718e3744 2647{
518f0eb1
DS
2648
2649 int update;
718e3744 2650 struct bgp_filter *filter;
718e3744 2651
518f0eb1
DS
2652 if (!peer || !rmap_name)
2653 return;
2654
2655 filter = &peer->filter[afi][safi];
2656 /*
2657 * in is for non-route-server clients,
2658 * import/export is for route-server clients,
2659 * out is for all peers
2660 */
2661 if (!CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
718e3744 2662 {
518f0eb1
DS
2663 if (filter->map[RMAP_IN].name &&
2664 (strcmp(rmap_name, filter->map[RMAP_IN].name) == 0))
718e3744 2665 {
518f0eb1
DS
2666 filter->map[RMAP_IN].map =
2667 route_map_lookup_by_name (filter->map[RMAP_IN].name);
2668
fa5f7ad5 2669 if (route_update && peer->status == Established)
518f0eb1
DS
2670 {
2671 if (CHECK_FLAG (peer->af_flags[afi][safi],
2672 PEER_FLAG_SOFT_RECONFIG))
2673 {
3f9c7369 2674 if (bgp_debug_update(peer, NULL, NULL, 1))
518f0eb1
DS
2675 zlog_debug("Processing route_map %s update on "
2676 "peer %s (inbound, soft-reconfig)",
2677 rmap_name, peer->host);
2678
2679 bgp_soft_reconfig_in (peer, afi, safi);
2680 }
2681 else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
2682 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
2683 {
2684
3f9c7369 2685 if (bgp_debug_update(peer, NULL, NULL, 1))
518f0eb1
DS
2686 zlog_debug("Processing route_map %s update on "
2687 "peer %s (inbound, route-refresh)",
2688 rmap_name, peer->host);
2689 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
2690 }
2691 }
718e3744 2692 }
2693 }
2694
518f0eb1 2695 if (CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
718e3744 2696 {
518f0eb1
DS
2697 update = 0;
2698
2699 if (filter->map[RMAP_IMPORT].name &&
2700 (strcmp(rmap_name, filter->map[RMAP_IMPORT].name) == 0))
718e3744 2701 {
518f0eb1
DS
2702 filter->map[RMAP_IMPORT].map =
2703 route_map_lookup_by_name (filter->map[RMAP_IMPORT].name);
2704 update = 1;
2705 }
2706
2707 if (filter->map[RMAP_EXPORT].name &&
2708 (strcmp(rmap_name, filter->map[RMAP_EXPORT].name) == 0))
2709 {
2710 filter->map[RMAP_EXPORT].map =
2711 route_map_lookup_by_name (filter->map[RMAP_EXPORT].name);
2712
2713 update = 1;
2714 }
2715
fa5f7ad5 2716 if (update && route_update && peer->status == Established)
518f0eb1
DS
2717 {
2718 if (CHECK_FLAG (peer->af_flags[afi][safi],
2719 PEER_FLAG_SOFT_RECONFIG))
2720 {
3f9c7369 2721 if (bgp_debug_update(peer, NULL, NULL, 1))
518f0eb1
DS
2722 zlog_debug("Processing route_map %s update on "
2723 "peer %s (import, soft-reconfig)",
2724 rmap_name, peer->host);
2725
2726 bgp_soft_reconfig_in (peer, afi, safi);
2727 }
2728 else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
2729 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
2730 {
3f9c7369 2731 if (bgp_debug_update(peer, NULL, NULL, 1))
518f0eb1
DS
2732 zlog_debug("Processing route_map %s update on "
2733 "peer %s (import, route-refresh)",
2734 rmap_name, peer->host);
2735 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
2736 }
2737 /* DD: Else, what else do we do ? Reset peer ? */
718e3744 2738 }
2739 }
2740
3f9c7369
DS
2741 /*
2742 * For outbound, unsuppress and default-originate map change (content or
2743 * map created), merely update the "config" here, the actual route
2744 * announcement happens at the group level.
2745 */
518f0eb1 2746 if (filter->map[RMAP_OUT].name &&
3f9c7369
DS
2747 (strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
2748 filter->map[RMAP_OUT].map =
2749 route_map_lookup_by_name (filter->map[RMAP_OUT].name);
518f0eb1
DS
2750
2751 if (filter->usmap.name &&
2752 (strcmp(rmap_name, filter->usmap.name) == 0))
3f9c7369
DS
2753 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2754
2755 if (peer->default_rmap[afi][safi].name &&
2756 (strcmp (rmap_name, peer->default_rmap[afi][safi].name) == 0))
2757 peer->default_rmap[afi][safi].map =
2758 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
518f0eb1 2759}
73ac8160 2760
518f0eb1 2761static void
ffd0c037 2762bgp_route_map_update_peer_group(const char *rmap_name, struct bgp *bgp)
518f0eb1
DS
2763{
2764 struct peer_group *group;
2765 struct listnode *node, *nnode;
2766 struct bgp_filter *filter;
2767 int afi, safi;
2768 int direct;
2769
2770 if (!bgp)
2771 return;
2772
2773 /* All the peers have been updated correctly already. This is
2774 * just updating the placeholder data. No real update required.
2775 */
2776 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2777 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2778 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2779 {
2780 filter = &group->conf->filter[afi][safi];
2781
2782 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
2783 {
2784 if ((filter->map[direct].name) &&
2785 (strcmp(rmap_name, filter->map[direct].name) == 0))
2786 filter->map[direct].map =
2787 route_map_lookup_by_name (filter->map[direct].name);
2788 }
2789
2790 if (filter->usmap.name &&
2791 (strcmp(rmap_name, filter->usmap.name) == 0))
2792 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2793 }
2794}
2795
2796static int
ffd0c037 2797bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update)
518f0eb1
DS
2798{
2799 int i;
2800 afi_t afi;
2801 safi_t safi;
2802 struct peer *peer;
2803 struct bgp_node *bn;
2804 struct bgp_static *bgp_static;
2805 struct bgp *bgp = (struct bgp *)arg;
2806 struct listnode *node, *nnode;
2807 char buf[INET6_ADDRSTRLEN];
2808
2809 if (!bgp)
7c8ff89e 2810 return (-1);
518f0eb1
DS
2811
2812 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2813 {
518f0eb1
DS
2814
2815 /* Ignore dummy peer-group structure */
2816 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
2817 continue;
2818
718e3744 2819 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2820 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
518f0eb1
DS
2821 {
2822 /* Ignore inactive AFI/SAFI */
2823 if (! peer->afc[afi][safi])
2824 continue;
2825
3f9c7369 2826 /* process in/out/import/export/default-orig route-maps */
518f0eb1 2827 bgp_route_map_process_peer(rmap_name, peer, afi, safi, route_update);
518f0eb1 2828 }
718e3744 2829 }
2830
3f9c7369
DS
2831 /* for outbound/default-orig route-maps, process for groups */
2832 update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP, rmap_name,
2833 route_update, 0);
2834
2835 /* update peer-group config (template) */
518f0eb1
DS
2836 bgp_route_map_update_peer_group(rmap_name, bgp);
2837
2838 /* For table route-map updates. */
2839 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2840 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2841 {
2842 if (bgp->table_map[afi][safi].name &&
2843 (strcmp(rmap_name, bgp->table_map[afi][safi].name) == 0))
2844 {
2845 bgp->table_map[afi][safi].map =
2846 route_map_lookup_by_name (bgp->table_map[afi][safi].name);
16286195 2847 if (BGP_DEBUG (zebra, ZEBRA))
518f0eb1
DS
2848 zlog_debug("Processing route_map %s update on "
2849 "table map", rmap_name);
2850 if (route_update)
2851 bgp_zebra_announce_table(bgp, afi, safi);
2852 }
2853 }
2854
2855 /* For network route-map updates. */
2856 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2857 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2858 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2859 bn = bgp_route_next (bn))
2860 if ((bgp_static = bn->info) != NULL)
2861 {
2862 if (bgp_static->rmap.name &&
2863 (strcmp(rmap_name, bgp_static->rmap.name) == 0))
2864 {
2865 bgp_static->rmap.map =
2866 route_map_lookup_by_name (bgp_static->rmap.name);
2867 if (route_update)
2868 if (!bgp_static->backdoor)
2869 {
16286195 2870 if (bgp_debug_zebra(&bn->p))
518f0eb1
DS
2871 zlog_debug("Processing route_map %s update on "
2872 "static route %s", rmap_name,
2873 inet_ntop (bn->p.family, &bn->p.u.prefix,
2874 buf, INET6_ADDRSTRLEN));
2875 bgp_static_update (bgp, &bn->p, bgp_static, afi, safi);
2876 }
2877 }
2878 }
2879
718e3744 2880 /* For redistribute route-map updates. */
518f0eb1
DS
2881 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2882 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2883 {
7c8ff89e
DS
2884 struct list *red_list;
2885 struct listnode *node;
2886 struct bgp_redist *red;
2887
2888 red_list = bgp->redist[afi][i];
2889 if (!red_list)
2890 continue;
2891
2892 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
2893 {
2894 if (red->rmap.name &&
2895 (strcmp(rmap_name, red->rmap.name) == 0))
2896 {
2897 red->rmap.map =
2898 route_map_lookup_by_name (red->rmap.name);
2899
2900 if (route_update)
2901 {
3f9c7369 2902 if (BGP_DEBUG (zebra, ZEBRA))
7c8ff89e
DS
2903 zlog_debug("Processing route_map %s update on "
2904 "redistributed routes", rmap_name);
2905
2906 bgp_redistribute_resend (bgp, afi, i, red->instance);
2907 }
2908 }
518f0eb1
DS
2909 }
2910 }
2911
2912 return (0);
2913}
2914
2915static int
2916bgp_route_map_process_update_cb (void *arg, char *rmap_name)
2917{
2918 return bgp_route_map_process_update (arg, rmap_name, 1);
2919}
2920
2921int
2922bgp_route_map_update_timer(struct thread *thread)
2923{
2924 struct bgp *bgp = THREAD_ARG(thread);
2925
2926 bgp->t_rmap_update = NULL;
2927
518f0eb1
DS
2928 route_map_walk_update_list((void *)bgp, bgp_route_map_process_update_cb);
2929
518f0eb1
DS
2930 return (0);
2931}
2932
2933static void
ffd0c037 2934bgp_route_map_mark_update (const char *rmap_name)
518f0eb1
DS
2935{
2936 struct listnode *node, *nnode;
2937 struct bgp *bgp;
2938
2939 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
718e3744 2940 {
3f9c7369 2941
518f0eb1 2942 if (bgp->t_rmap_update == NULL)
718e3744 2943 {
518f0eb1
DS
2944 /* rmap_update_timer of 0 means don't do route updates */
2945 if (bgp->rmap_update_timer)
3f9c7369
DS
2946 {
2947 bgp->t_rmap_update =
2948 thread_add_timer(master, bgp_route_map_update_timer, bgp,
2949 bgp->rmap_update_timer);
2950 /* Signal the groups that a route-map update event has started */
2951 update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP, rmap_name, 1, 1);
2952 }
518f0eb1
DS
2953 else
2954 bgp_route_map_process_update((void *)bgp, rmap_name, 0);
718e3744 2955 }
2956 }
2957}
6b0655a2 2958
73ac8160 2959static void
518f0eb1 2960bgp_route_map_add (const char *rmap_name)
73ac8160 2961{
518f0eb1
DS
2962 if (route_map_mark_updated(rmap_name, 0) == 0)
2963 bgp_route_map_mark_update(rmap_name);
73ac8160 2964
518f0eb1 2965 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
73ac8160 2966}
518f0eb1 2967
73ac8160 2968static void
518f0eb1 2969bgp_route_map_delete (const char *rmap_name)
73ac8160 2970{
518f0eb1
DS
2971 if (route_map_mark_updated(rmap_name, 1) == 0)
2972 bgp_route_map_mark_update(rmap_name);
73ac8160 2973
518f0eb1 2974 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
73ac8160 2975}
518f0eb1 2976
73ac8160 2977static void
518f0eb1 2978bgp_route_map_event (route_map_event_t event, const char *rmap_name)
73ac8160 2979{
518f0eb1
DS
2980 if (route_map_mark_updated(rmap_name, 0) == 0)
2981 bgp_route_map_mark_update(rmap_name);
2982
2983 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
73ac8160
DS
2984}
2985
2986
fee0f4c6 2987DEFUN (match_peer,
2988 match_peer_cmd,
2989 "match peer (A.B.C.D|X:X::X:X)",
2990 MATCH_STR
2991 "Match peer address\n"
2992 "IPv6 address of peer\n"
2993 "IP address of peer\n")
2994{
518f0eb1
DS
2995 return bgp_route_match_add (vty, vty->index, "peer", argv[0],
2996 RMAP_EVENT_MATCH_ADDED);
fee0f4c6 2997}
2998
2999DEFUN (match_peer_local,
3000 match_peer_local_cmd,
3001 "match peer local",
3002 MATCH_STR
3003 "Match peer address\n"
3004 "Static or Redistributed routes\n")
3005{
518f0eb1
DS
3006 return bgp_route_match_add (vty, vty->index, "peer", "local",
3007 RMAP_EVENT_MATCH_DELETED);
fee0f4c6 3008}
3009
3010DEFUN (no_match_peer,
3011 no_match_peer_cmd,
3012 "no match peer",
3013 NO_STR
3014 MATCH_STR
3015 "Match peer address\n")
3016{
3017 if (argc == 0)
518f0eb1
DS
3018 return bgp_route_match_delete (vty, vty->index, "peer", NULL,
3019 RMAP_EVENT_MATCH_DELETED);
fee0f4c6 3020
518f0eb1
DS
3021 return bgp_route_match_delete (vty, vty->index, "peer", argv[0],
3022 RMAP_EVENT_MATCH_DELETED);
fee0f4c6 3023}
3024
3025ALIAS (no_match_peer,
3026 no_match_peer_val_cmd,
3027 "no match peer (A.B.C.D|X:X::X:X)",
3028 NO_STR
3029 MATCH_STR
3030 "Match peer address\n"
3031 "IPv6 address of peer\n"
3032 "IP address of peer\n")
3033
3034ALIAS (no_match_peer,
3035 no_match_peer_local_cmd,
3036 "no match peer local",
3037 NO_STR
3038 MATCH_STR
3039 "Match peer address\n"
3040 "Static or Redistributed routes\n")
3041
718e3744 3042DEFUN (match_ip_address,
3043 match_ip_address_cmd,
3044 "match ip address (<1-199>|<1300-2699>|WORD)",
3045 MATCH_STR
3046 IP_STR
3047 "Match address of route\n"
3048 "IP access-list number\n"
3049 "IP access-list number (expanded range)\n"
3050 "IP Access-list name\n")
3051{
518f0eb1
DS
3052 return bgp_route_match_add (vty, vty->index, "ip address", argv[0],
3053 RMAP_EVENT_FILTER_ADDED);
718e3744 3054}
3055
3056DEFUN (no_match_ip_address,
3057 no_match_ip_address_cmd,
3058 "no match ip address",
3059 NO_STR
3060 MATCH_STR
3061 IP_STR
3062 "Match address of route\n")
3063{
3064 if (argc == 0)
518f0eb1
DS
3065 return bgp_route_match_delete (vty, vty->index, "ip address", NULL,
3066 RMAP_EVENT_FILTER_DELETED);
718e3744 3067
518f0eb1
DS
3068 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0],
3069 RMAP_EVENT_FILTER_DELETED);
718e3744 3070}
3071
3072ALIAS (no_match_ip_address,
3073 no_match_ip_address_val_cmd,
3074 "no match ip address (<1-199>|<1300-2699>|WORD)",
3075 NO_STR
3076 MATCH_STR
3077 IP_STR
3078 "Match address of route\n"
3079 "IP access-list number\n"
3080 "IP access-list number (expanded range)\n"
3081 "IP Access-list name\n")
3082
3083DEFUN (match_ip_next_hop,
3084 match_ip_next_hop_cmd,
3085 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
3086 MATCH_STR
3087 IP_STR
3088 "Match next-hop address of route\n"
3089 "IP access-list number\n"
3090 "IP access-list number (expanded range)\n"
3091 "IP Access-list name\n")
3092{
518f0eb1
DS
3093 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0],
3094 RMAP_EVENT_FILTER_ADDED);
718e3744 3095}
3096
3097DEFUN (no_match_ip_next_hop,
3098 no_match_ip_next_hop_cmd,
3099 "no match ip next-hop",
3100 NO_STR
3101 MATCH_STR
3102 IP_STR
3103 "Match next-hop address of route\n")
3104{
3105 if (argc == 0)
518f0eb1
DS
3106 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL,
3107 RMAP_EVENT_FILTER_DELETED);
718e3744 3108
518f0eb1
DS
3109 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0],
3110 RMAP_EVENT_FILTER_DELETED);
718e3744 3111}
3112
3113ALIAS (no_match_ip_next_hop,
3114 no_match_ip_next_hop_val_cmd,
3115 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
3116 NO_STR
3117 MATCH_STR
3118 IP_STR
3119 "Match next-hop address of route\n"
3120 "IP access-list number\n"
3121 "IP access-list number (expanded range)\n"
3122 "IP Access-list name\n")
3123
1add115a
VT
3124/* match probability { */
3125
3126DEFUN (match_probability,
3127 match_probability_cmd,
3128 "match probability <0-100>",
3129 MATCH_STR
3130 "Match portion of routes defined by percentage value\n"
3131 "Percentage of routes\n")
3132{
518f0eb1
DS
3133 return bgp_route_match_add (vty, vty->index, "probability", argv[0],
3134 RMAP_EVENT_MATCH_ADDED);
1add115a
VT
3135}
3136
3137DEFUN (no_match_probability,
3138 no_match_probability_cmd,
3139 "no match probability",
3140 NO_STR
3141 MATCH_STR
3142 "Match portion of routes defined by percentage value\n")
3143{
518f0eb1
DS
3144 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL,
3145 RMAP_EVENT_MATCH_DELETED);
1add115a
VT
3146}
3147
3148ALIAS (no_match_probability,
3149 no_match_probability_val_cmd,
3150 "no match probability <1-99>",
3151 NO_STR
3152 MATCH_STR
3153 "Match portion of routes defined by percentage value\n"
3154 "Percentage of routes\n")
3155
3156/* } */
3157
c1643bb7 3158DEFUN (match_ip_route_source,
3159 match_ip_route_source_cmd,
3160 "match ip route-source (<1-199>|<1300-2699>|WORD)",
3161 MATCH_STR
3162 IP_STR
3163 "Match advertising source address of route\n"
3164 "IP access-list number\n"
3165 "IP access-list number (expanded range)\n"
3166 "IP standard access-list name\n")
3167{
518f0eb1
DS
3168 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0],
3169 RMAP_EVENT_FILTER_ADDED);
c1643bb7 3170}
3171
3172DEFUN (no_match_ip_route_source,
3173 no_match_ip_route_source_cmd,
3174 "no match ip route-source",
3175 NO_STR
3176 MATCH_STR
3177 IP_STR
3178 "Match advertising source address of route\n")
3179{
3180 if (argc == 0)
518f0eb1
DS
3181 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL,
3182 RMAP_EVENT_FILTER_DELETED);
c1643bb7 3183
518f0eb1
DS
3184 return bgp_route_match_delete (vty, vty->index, "ip route-source",
3185 argv[0], RMAP_EVENT_FILTER_DELETED);
c1643bb7 3186}
3187
3188ALIAS (no_match_ip_route_source,
3189 no_match_ip_route_source_val_cmd,
3190 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
3191 NO_STR
3192 MATCH_STR
3193 IP_STR
3194 "Match advertising source address of route\n"
3195 "IP access-list number\n"
3196 "IP access-list number (expanded range)\n"
30a2231a 3197 "IP standard access-list name\n")
c1643bb7 3198
718e3744 3199DEFUN (match_ip_address_prefix_list,
3200 match_ip_address_prefix_list_cmd,
3201 "match ip address prefix-list WORD",
3202 MATCH_STR
3203 IP_STR
3204 "Match address of route\n"
3205 "Match entries of prefix-lists\n"
3206 "IP prefix-list name\n")
3207{
518f0eb1
DS
3208 return bgp_route_match_add (vty, vty->index, "ip address prefix-list",
3209 argv[0], RMAP_EVENT_PLIST_ADDED);
718e3744 3210}
3211
3212DEFUN (no_match_ip_address_prefix_list,
3213 no_match_ip_address_prefix_list_cmd,
3214 "no match ip address prefix-list",
3215 NO_STR
3216 MATCH_STR
3217 IP_STR
3218 "Match address of route\n"
3219 "Match entries of prefix-lists\n")
3220{
518f0eb1
DS
3221 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list",
3222 argc == 0 ? NULL : argv[0],
3223 RMAP_EVENT_PLIST_DELETED);
718e3744 3224}
3225
3226ALIAS (no_match_ip_address_prefix_list,
3227 no_match_ip_address_prefix_list_val_cmd,
3228 "no match ip address prefix-list WORD",
3229 NO_STR
3230 MATCH_STR
3231 IP_STR
3232 "Match address of route\n"
3233 "Match entries of prefix-lists\n"
3234 "IP prefix-list name\n")
3235
3236DEFUN (match_ip_next_hop_prefix_list,
3237 match_ip_next_hop_prefix_list_cmd,
3238 "match ip next-hop prefix-list WORD",
3239 MATCH_STR
3240 IP_STR
3241 "Match next-hop address of route\n"
3242 "Match entries of prefix-lists\n"
3243 "IP prefix-list name\n")
3244{
518f0eb1
DS
3245 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list",
3246 argv[0], RMAP_EVENT_PLIST_ADDED);
718e3744 3247}
3248
3249DEFUN (no_match_ip_next_hop_prefix_list,
3250 no_match_ip_next_hop_prefix_list_cmd,
3251 "no match ip next-hop prefix-list",
3252 NO_STR
3253 MATCH_STR
3254 IP_STR
3255 "Match next-hop address of route\n"
3256 "Match entries of prefix-lists\n")
3257{
518f0eb1
DS
3258 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
3259 argc == 0 ? NULL : argv[0],
3260 RMAP_EVENT_PLIST_DELETED);
718e3744 3261}
3262
3263ALIAS (no_match_ip_next_hop_prefix_list,
3264 no_match_ip_next_hop_prefix_list_val_cmd,
3265 "no match ip next-hop prefix-list WORD",
3266 NO_STR
3267 MATCH_STR
3268 IP_STR
3269 "Match next-hop address of route\n"
3270 "Match entries of prefix-lists\n"
3271 "IP prefix-list name\n")
3272
c1643bb7 3273DEFUN (match_ip_route_source_prefix_list,
3274 match_ip_route_source_prefix_list_cmd,
3275 "match ip route-source prefix-list WORD",
3276 MATCH_STR
3277 IP_STR
3278 "Match advertising source address of route\n"
3279 "Match entries of prefix-lists\n"
3280 "IP prefix-list name\n")
3281{
518f0eb1
DS
3282 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list",
3283 argv[0], RMAP_EVENT_PLIST_ADDED);
c1643bb7 3284}
3285
3286DEFUN (no_match_ip_route_source_prefix_list,
3287 no_match_ip_route_source_prefix_list_cmd,
3288 "no match ip route-source prefix-list",
3289 NO_STR
3290 MATCH_STR
3291 IP_STR
3292 "Match advertising source address of route\n"
3293 "Match entries of prefix-lists\n")
3294{
518f0eb1
DS
3295 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list",
3296 argc == 0 ? NULL : argv[0],
3297 RMAP_EVENT_PLIST_DELETED);
c1643bb7 3298}
3299
3300ALIAS (no_match_ip_route_source_prefix_list,
3301 no_match_ip_route_source_prefix_list_val_cmd,
3302 "no match ip route-source prefix-list WORD",
3303 NO_STR
3304 MATCH_STR
3305 IP_STR
3306 "Match advertising source address of route\n"
3307 "Match entries of prefix-lists\n"
30a2231a 3308 "IP prefix-list name\n")
c1643bb7 3309
718e3744 3310DEFUN (match_metric,
3311 match_metric_cmd,
3312 "match metric <0-4294967295>",
3313 MATCH_STR
3314 "Match metric of route\n"
3315 "Metric value\n")
3316{
518f0eb1
DS
3317 return bgp_route_match_add (vty, vty->index, "metric", argv[0],
3318 RMAP_EVENT_MATCH_ADDED);
718e3744 3319}
3320
3321DEFUN (no_match_metric,
3322 no_match_metric_cmd,
3323 "no match metric",
3324 NO_STR
3325 MATCH_STR
3326 "Match metric of route\n")
3327{
518f0eb1
DS
3328 return bgp_route_match_delete (vty, vty->index, "metric",
3329 argc == 0 ? NULL : argv[0],
3330 RMAP_EVENT_MATCH_DELETED);
718e3744 3331}
3332
3333ALIAS (no_match_metric,
3334 no_match_metric_val_cmd,
3335 "no match metric <0-4294967295>",
3336 NO_STR
3337 MATCH_STR
3338 "Match metric of route\n"
3339 "Metric value\n")
3340
af291c15
DS
3341DEFUN (match_local_pref,
3342 match_local_pref_cmd,
3343 "match local-preference <0-4294967295>",
3344 MATCH_STR
3345 "Match local-preference of route\n"
3346 "Metric value\n")
3347{
518f0eb1
DS
3348 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0],
3349 RMAP_EVENT_MATCH_ADDED);
af291c15
DS
3350}
3351
3352DEFUN (no_match_local_pref,
3353 no_match_local_pref_cmd,
3354 "no match local-preference",
3355 NO_STR
3356 MATCH_STR
3357 "Match local preference of route\n")
3358{
518f0eb1
DS
3359 return bgp_route_match_delete (vty, vty->index, "local-preference",
3360 argc == 0 ? NULL : argv[0],
3361 RMAP_EVENT_MATCH_DELETED);
af291c15 3362
518f0eb1
DS
3363 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0],
3364 RMAP_EVENT_MATCH_DELETED);
af291c15
DS
3365}
3366
3367ALIAS (no_match_local_pref,
3368 no_match_local_pref_val_cmd,
3369 "no match local-preference <0-4294967295>",
3370 NO_STR
3371 MATCH_STR
3372 "Match local preference of route\n"
3373 "Local preference value\n")
3374
718e3744 3375DEFUN (match_community,
3376 match_community_cmd,
fee6e4e4 3377 "match community (<1-99>|<100-500>|WORD)",
718e3744 3378 MATCH_STR
3379 "Match BGP community list\n"
3380 "Community-list number (standard)\n"
3381 "Community-list number (expanded)\n"
3382 "Community-list name\n")
3383{
518f0eb1
DS
3384 return bgp_route_match_add (vty, vty->index, "community", argv[0],
3385 RMAP_EVENT_CLIST_ADDED);
718e3744 3386}
3387
3388DEFUN (match_community_exact,
3389 match_community_exact_cmd,
fee6e4e4 3390 "match community (<1-99>|<100-500>|WORD) exact-match",
718e3744 3391 MATCH_STR
3392 "Match BGP community list\n"
3393 "Community-list number (standard)\n"
3394 "Community-list number (expanded)\n"
3395 "Community-list name\n"
3396 "Do exact matching of communities\n")
3397{
3398 int ret;
3399 char *argstr;
3400
3401 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3402 strlen (argv[0]) + strlen ("exact-match") + 2);
3403
3404 sprintf (argstr, "%s exact-match", argv[0]);
3405
518f0eb1
DS
3406 ret = bgp_route_match_add (vty, vty->index, "community", argstr,
3407 RMAP_EVENT_CLIST_ADDED);
718e3744 3408
3409 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3410
3411 return ret;
3412}
3413
3414DEFUN (no_match_community,
3415 no_match_community_cmd,
3416 "no match community",
3417 NO_STR
3418 MATCH_STR
3419 "Match BGP community list\n")
3420{
518f0eb1
DS
3421 return bgp_route_match_delete (vty, vty->index, "community", NULL,
3422 RMAP_EVENT_CLIST_DELETED);
718e3744 3423}
3424
3425ALIAS (no_match_community,
3426 no_match_community_val_cmd,
fee6e4e4 3427 "no match community (<1-99>|<100-500>|WORD)",
718e3744 3428 NO_STR
3429 MATCH_STR
3430 "Match BGP community list\n"
3431 "Community-list number (standard)\n"
3432 "Community-list number (expanded)\n"
3433 "Community-list name\n")
3434
3435ALIAS (no_match_community,
3436 no_match_community_exact_cmd,
fee6e4e4 3437 "no match community (<1-99>|<100-500>|WORD) exact-match",
718e3744 3438 NO_STR
3439 MATCH_STR
3440 "Match BGP community list\n"
3441 "Community-list number (standard)\n"
3442 "Community-list number (expanded)\n"
3443 "Community-list name\n"
3444 "Do exact matching of communities\n")
3445
73ffb25b 3446DEFUN (match_ecommunity,
3447 match_ecommunity_cmd,
fee6e4e4 3448 "match extcommunity (<1-99>|<100-500>|WORD)",
73ffb25b 3449 MATCH_STR
3450 "Match BGP/VPN extended community list\n"
3451 "Extended community-list number (standard)\n"
3452 "Extended community-list number (expanded)\n"
3453 "Extended community-list name\n")
3454{
518f0eb1
DS
3455 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0],
3456 RMAP_EVENT_ECLIST_ADDED);
73ffb25b 3457}
3458
3459DEFUN (no_match_ecommunity,
3460 no_match_ecommunity_cmd,
3461 "no match extcommunity",
3462 NO_STR
3463 MATCH_STR
3464 "Match BGP/VPN extended community list\n")
3465{
518f0eb1
DS
3466 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL,
3467 RMAP_EVENT_ECLIST_DELETED);
73ffb25b 3468}
3469
3470ALIAS (no_match_ecommunity,
3471 no_match_ecommunity_val_cmd,
fee6e4e4 3472 "no match extcommunity (<1-99>|<100-500>|WORD)",
73ffb25b 3473 NO_STR
3474 MATCH_STR
3475 "Match BGP/VPN extended community list\n"
3476 "Extended community-list number (standard)\n"
3477 "Extended community-list number (expanded)\n"
3478 "Extended community-list name\n")
3479
718e3744 3480DEFUN (match_aspath,
3481 match_aspath_cmd,
3482 "match as-path WORD",
3483 MATCH_STR
3484 "Match BGP AS path list\n"
3485 "AS path access-list name\n")
3486{
518f0eb1
DS
3487 return bgp_route_match_add (vty, vty->index, "as-path", argv[0],
3488 RMAP_EVENT_ASLIST_ADDED);
718e3744 3489}
3490
3491DEFUN (no_match_aspath,
3492 no_match_aspath_cmd,
3493 "no match as-path",
3494 NO_STR
3495 MATCH_STR
3496 "Match BGP AS path list\n")
3497{
518f0eb1
DS
3498 return bgp_route_match_delete (vty, vty->index, "as-path", NULL,
3499 RMAP_EVENT_ASLIST_DELETED);
718e3744 3500}
3501
3502ALIAS (no_match_aspath,
3503 no_match_aspath_val_cmd,
3504 "no match as-path WORD",
3505 NO_STR
3506 MATCH_STR
3507 "Match BGP AS path list\n"
3508 "AS path access-list name\n")
3509
3510DEFUN (match_origin,
3511 match_origin_cmd,
3512 "match origin (egp|igp|incomplete)",
3513 MATCH_STR
3514 "BGP origin code\n"
3515 "remote EGP\n"
3516 "local IGP\n"
3517 "unknown heritage\n")
3518{
3519 if (strncmp (argv[0], "igp", 2) == 0)
518f0eb1
DS
3520 return bgp_route_match_add (vty, vty->index, "origin", "igp",
3521 RMAP_EVENT_MATCH_ADDED);
718e3744 3522 if (strncmp (argv[0], "egp", 1) == 0)
518f0eb1
DS
3523 return bgp_route_match_add (vty, vty->index, "origin", "egp",
3524 RMAP_EVENT_MATCH_ADDED);
718e3744 3525 if (strncmp (argv[0], "incomplete", 2) == 0)
518f0eb1
DS
3526 return bgp_route_match_add (vty, vty->index, "origin", "incomplete",
3527 RMAP_EVENT_MATCH_ADDED);
718e3744 3528
3529 return CMD_WARNING;
3530}
3531
3532DEFUN (no_match_origin,
3533 no_match_origin_cmd,
3534 "no match origin",
3535 NO_STR
3536 MATCH_STR
3537 "BGP origin code\n")
3538{
518f0eb1
DS
3539 return bgp_route_match_delete (vty, vty->index, "origin", NULL,
3540 RMAP_EVENT_MATCH_DELETED);
718e3744 3541}
3542
3543ALIAS (no_match_origin,
3544 no_match_origin_val_cmd,
3545 "no match origin (egp|igp|incomplete)",
3546 NO_STR
3547 MATCH_STR
3548 "BGP origin code\n"
3549 "remote EGP\n"
3550 "local IGP\n"
3551 "unknown heritage\n")
3552
bc413143
DS
3553DEFUN (match_interface,
3554 match_interface_cmd,
3555 "match interface WORD",
3556 MATCH_STR
3557 "Match first hop interface of route\n"
3558 "Interface name\n")
3559{
3560 return bgp_route_match_add (vty, vty->index, "interface", argv[0],
3561 RMAP_EVENT_MATCH_ADDED);
3562}
3563
3564DEFUN (no_match_interface,
3565 no_match_interface_cmd,
3566 "no match interface",
3567 NO_STR
3568 MATCH_STR
3569 "Match first hop interface of route\n")
3570{
3571 if (argc == 0)
3572 return bgp_route_match_delete (vty, vty->index, "interface", NULL,
3573 RMAP_EVENT_MATCH_DELETED);
3574
3575 return bgp_route_match_delete (vty, vty->index, "interface", argv[0],
3576 RMAP_EVENT_MATCH_DELETED);
3577}
3578
3579ALIAS (no_match_interface,
3580 no_match_interface_val_cmd,
3581 "no match interface WORD",
3582 NO_STR
3583 MATCH_STR
3584 "Match first hop interface of route\n"
3585 "Interface name\n")
3586
0d9551dc
DS
3587DEFUN (match_tag,
3588 match_tag_cmd,
3589 "match tag <1-65535>",
3590 MATCH_STR
3591 "Match tag of route\n"
3592 "Tag value\n")
3593{
3594 return bgp_route_match_add (vty, vty->index, "tag", argv[0],
3595 RMAP_EVENT_MATCH_ADDED);
3596}
3597
3598DEFUN (no_match_tag,
3599 no_match_tag_cmd,
3600 "no match tag",
3601 NO_STR
3602 MATCH_STR
3603 "Match tag of route\n")
3604{
3605 if (argc == 0)
3606 return bgp_route_match_delete (vty, vty->index, "tag", NULL,
3607 RMAP_EVENT_MATCH_DELETED);
3608
3609 return bgp_route_match_delete (vty, vty->index, "tag", argv[0],
3610 RMAP_EVENT_MATCH_DELETED);
3611}
3612
3613ALIAS (no_match_tag,
3614 no_match_tag_val_cmd,
3615 "no match tag <1-65535>",
3616 NO_STR
3617 MATCH_STR
3618 "Match tag of route\n"
3619 "Tag value\n")
3620
3621
718e3744 3622DEFUN (set_ip_nexthop,
3623 set_ip_nexthop_cmd,
af5cd0a5 3624 "set ip next-hop A.B.C.D",
718e3744 3625 SET_STR
3626 IP_STR
3627 "Next hop address\n"
af5cd0a5 3628 "IP address of next hop\n")
718e3744 3629{
3630 union sockunion su;
3631 int ret;
3632
3633 ret = str2sockunion (argv[0], &su);
3634 if (ret < 0)
3635 {
3636 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3637 return CMD_WARNING;
3638 }
3639
3640 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3641}
3642
af5cd0a5 3643DEFUN (set_ip_nexthop_peer,
3644 set_ip_nexthop_peer_cmd,
3645 "set ip next-hop peer-address",
3646 SET_STR
3647 IP_STR
3648 "Next hop address\n"
3649 "Use peer address (for BGP only)\n")
3650{
3651 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3652}
3653
316e074d
DS
3654DEFUN (set_ip_nexthop_unchanged,
3655 set_ip_nexthop_unchanged_cmd,
3656 "set ip next-hop unchanged",
3657 SET_STR
3658 IP_STR
3659 "Next hop address\n"
3660 "Don't modify existing Next hop address\n")
3661{
3662 return bgp_route_set_add (vty, vty->index, "ip next-hop", "unchanged");
3663}
3664
94f2b392 3665DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
af5cd0a5 3666 no_set_ip_nexthop_peer_cmd,
3667 "no set ip next-hop peer-address",
3668 NO_STR
3669 SET_STR
3670 IP_STR
3671 "Next hop address\n"
3672 "Use peer address (for BGP only)\n")
3673{
3674 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3675}
3676
3677
718e3744 3678DEFUN (no_set_ip_nexthop,
3679 no_set_ip_nexthop_cmd,
3680 "no set ip next-hop",
3681 NO_STR
3682 SET_STR
718e3744 3683 "Next hop address\n")
3684{
af5cd0a5 3685 if (argc == 0)
718e3744 3686 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3687
3688 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3689}
3690
3691ALIAS (no_set_ip_nexthop,
3692 no_set_ip_nexthop_val_cmd,
af5cd0a5 3693 "no set ip next-hop A.B.C.D",
718e3744 3694 NO_STR
3695 SET_STR
3696 IP_STR
3697 "Next hop address\n"
af5cd0a5 3698 "IP address of next hop\n")
718e3744 3699
3700DEFUN (set_metric,
3701 set_metric_cmd,
73ffb25b 3702 "set metric <0-4294967295>",
718e3744 3703 SET_STR
3704 "Metric value for destination routing protocol\n"
73ffb25b 3705 "Metric value\n")
718e3744 3706{
3707 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3708}
3709
73ffb25b 3710ALIAS (set_metric,
3711 set_metric_addsub_cmd,
3712 "set metric <+/-metric>",
3713 SET_STR
3714 "Metric value for destination routing protocol\n"
033e8612 3715 "Add or subtract metric\n")
73ffb25b 3716
718e3744 3717DEFUN (no_set_metric,
3718 no_set_metric_cmd,
3719 "no set metric",
3720 NO_STR
3721 SET_STR
3722 "Metric value for destination routing protocol\n")
3723{
3724 if (argc == 0)
3725 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3726
3727 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3728}
3729
3730ALIAS (no_set_metric,
3731 no_set_metric_val_cmd,
3732 "no set metric <0-4294967295>",
3733 NO_STR
3734 SET_STR
3735 "Metric value for destination routing protocol\n"
3736 "Metric value\n")
3737
3738DEFUN (set_local_pref,
3739 set_local_pref_cmd,
3740 "set local-preference <0-4294967295>",
3741 SET_STR
3742 "BGP local preference path attribute\n"
3743 "Preference value\n")
3744{
3745 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3746}
3747
3748DEFUN (no_set_local_pref,
3749 no_set_local_pref_cmd,
3750 "no set local-preference",
3751 NO_STR
3752 SET_STR
3753 "BGP local preference path attribute\n")
3754{
3755 if (argc == 0)
3756 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3757
3758 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3759}
3760
3761ALIAS (no_set_local_pref,
3762 no_set_local_pref_val_cmd,
3763 "no set local-preference <0-4294967295>",
3764 NO_STR
3765 SET_STR
3766 "BGP local preference path attribute\n"
3767 "Preference value\n")
3768
3769DEFUN (set_weight,
3770 set_weight_cmd,
3771 "set weight <0-4294967295>",
3772 SET_STR
3773 "BGP weight for routing table\n"
3774 "Weight value\n")
3775{
3776 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3777}
3778
3779DEFUN (no_set_weight,
3780 no_set_weight_cmd,
3781 "no set weight",
3782 NO_STR
3783 SET_STR
3784 "BGP weight for routing table\n")
3785{
3786 if (argc == 0)
3787 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3788
3789 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3790}
3791
3792ALIAS (no_set_weight,
3793 no_set_weight_val_cmd,
3794 "no set weight <0-4294967295>",
3795 NO_STR
3796 SET_STR
3797 "BGP weight for routing table\n"
3798 "Weight value\n")
3799
3800DEFUN (set_aspath_prepend,
3801 set_aspath_prepend_cmd,
10819ece 3802 "set as-path prepend ." CMD_AS_RANGE,
718e3744 3803 SET_STR
841f7a57 3804 "Transform BGP AS_PATH attribute\n"
718e3744 3805 "Prepend to the as-path\n"
3806 "AS number\n")
3807{
3808 int ret;
3809 char *str;
3810
3811 str = argv_concat (argv, argc, 0);
3812 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3813 XFREE (MTYPE_TMP, str);
3814
3815 return ret;
3816}
3817
3818DEFUN (no_set_aspath_prepend,
3819 no_set_aspath_prepend_cmd,
3820 "no set as-path prepend",
3821 NO_STR
3822 SET_STR
841f7a57 3823 "Transform BGP AS_PATH attribute\n"
718e3744 3824 "Prepend to the as-path\n")
3825{
a7f93f3e
DO
3826 int ret;
3827 char *str;
3828
3829 if (argc == 0)
3830 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3831
3832 str = argv_concat (argv, argc, 0);
3833 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3834 XFREE (MTYPE_TMP, str);
3835 return ret;
718e3744 3836}
3837
3838ALIAS (no_set_aspath_prepend,
3839 no_set_aspath_prepend_val_cmd,
10819ece 3840 "no set as-path prepend ." CMD_AS_RANGE,
718e3744 3841 NO_STR
3842 SET_STR
841f7a57 3843 "Transform BGP AS_PATH attribute\n"
718e3744 3844 "Prepend to the as-path\n"
3845 "AS number\n")
3846
841f7a57
DO
3847DEFUN (set_aspath_exclude,
3848 set_aspath_exclude_cmd,
10819ece 3849 "set as-path exclude ." CMD_AS_RANGE,
841f7a57
DO
3850 SET_STR
3851 "Transform BGP AS-path attribute\n"
3852 "Exclude from the as-path\n"
3853 "AS number\n")
3854{
3855 int ret;
3856 char *str;
3857
3858 str = argv_concat (argv, argc, 0);
3859 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3860 XFREE (MTYPE_TMP, str);
3861 return ret;
3862}
3863
3864DEFUN (no_set_aspath_exclude,
3865 no_set_aspath_exclude_cmd,
3866 "no set as-path exclude",
3867 NO_STR
3868 SET_STR
3869 "Transform BGP AS_PATH attribute\n"
3870 "Exclude from the as-path\n")
3871{
3872 int ret;
3873 char *str;
3874
3875 if (argc == 0)
3876 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3877
3878 str = argv_concat (argv, argc, 0);
3879 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3880 XFREE (MTYPE_TMP, str);
3881 return ret;
3882}
3883
3884ALIAS (no_set_aspath_exclude,
3885 no_set_aspath_exclude_val_cmd,
10819ece 3886 "no set as-path exclude ." CMD_AS_RANGE,
841f7a57
DO
3887 NO_STR
3888 SET_STR
3889 "Transform BGP AS_PATH attribute\n"
3890 "Exclude from the as-path\n"
3891 "AS number\n")
3892
718e3744 3893DEFUN (set_community,
3894 set_community_cmd,
3895 "set community .AA:NN",
3896 SET_STR
3897 "BGP community attribute\n"
3898 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3899{
3900 int i;
3901 int first = 0;
3902 int additive = 0;
3903 struct buffer *b;
3904 struct community *com = NULL;
3905 char *str;
3906 char *argstr;
3907 int ret;
3908
3909 b = buffer_new (1024);
3910
3911 for (i = 0; i < argc; i++)
3912 {
3913 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3914 {
3915 additive = 1;
3916 continue;
3917 }
3918
3919 if (first)
3920 buffer_putc (b, ' ');
3921 else
3922 first = 1;
3923
3924 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3925 {
3926 buffer_putstr (b, "internet");
3927 continue;
3928 }
3929 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3930 {
3931 buffer_putstr (b, "local-AS");
3932 continue;
3933 }
3934 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3935 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3936 {
3937 buffer_putstr (b, "no-advertise");
3938 continue;
3939 }
3940 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3941 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3942 {
3943 buffer_putstr (b, "no-export");
3944 continue;
3945 }
3946 buffer_putstr (b, argv[i]);
3947 }
3948 buffer_putc (b, '\0');
3949
3950 /* Fetch result string then compile it to communities attribute. */
3951 str = buffer_getstr (b);
3952 buffer_free (b);
3953
3954 if (str)
3955 {
3956 com = community_str2com (str);
3b8b1855 3957 XFREE (MTYPE_TMP, str);
718e3744 3958 }
3959
3960 /* Can't compile user input into communities attribute. */
3961 if (! com)
3962 {
3963 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3964 return CMD_WARNING;
3965 }
3966
3967 /* Set communites attribute string. */
3968 str = community_str (com);
3969
3970 if (additive)
3971 {
3972 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3973 strcpy (argstr, str);
3974 strcpy (argstr + strlen (str), " additive");
3975 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3976 XFREE (MTYPE_TMP, argstr);
3977 }
3978 else
3979 ret = bgp_route_set_add (vty, vty->index, "community", str);
3980
3981 community_free (com);
3982
3983 return ret;
3984}
3985
3986DEFUN (set_community_none,
3987 set_community_none_cmd,
3988 "set community none",
3989 SET_STR
3990 "BGP community attribute\n"
3991 "No community attribute\n")
3992{
3993 return bgp_route_set_add (vty, vty->index, "community", "none");
3994}
3995
3996DEFUN (no_set_community,
3997 no_set_community_cmd,
3998 "no set community",
3999 NO_STR
4000 SET_STR
4001 "BGP community attribute\n")
4002{
4003 return bgp_route_set_delete (vty, vty->index, "community", NULL);
4004}
4005
4006ALIAS (no_set_community,
4007 no_set_community_val_cmd,
4008 "no set community .AA:NN",
4009 NO_STR
4010 SET_STR
4011 "BGP community attribute\n"
4012 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
4013
4014ALIAS (no_set_community,
4015 no_set_community_none_cmd,
4016 "no set community none",
4017 NO_STR
4018 SET_STR
4019 "BGP community attribute\n"
4020 "No community attribute\n")
4021
4022DEFUN (set_community_delete,
4023 set_community_delete_cmd,
fee6e4e4 4024 "set comm-list (<1-99>|<100-500>|WORD) delete",
718e3744 4025 SET_STR
4026 "set BGP community list (for deletion)\n"
4027 "Community-list number (standard)\n"
5e3edbf5 4028 "Community-list number (expanded)\n"
718e3744 4029 "Community-list name\n"
4030 "Delete matching communities\n")
4031{
4032 char *str;
4033
4034 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
4035 strcpy (str, argv[0]);
4036 strcpy (str + strlen (argv[0]), " delete");
4037
4038 bgp_route_set_add (vty, vty->index, "comm-list", str);
4039
4040 XFREE (MTYPE_TMP, str);
4041 return CMD_SUCCESS;
4042}
4043
4044DEFUN (no_set_community_delete,
4045 no_set_community_delete_cmd,
4046 "no set comm-list",
4047 NO_STR
4048 SET_STR
4049 "set BGP community list (for deletion)\n")
4050{
4051 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
4052}
4053
4054ALIAS (no_set_community_delete,
4055 no_set_community_delete_val_cmd,
fee6e4e4 4056 "no set comm-list (<1-99>|<100-500>|WORD) delete",
718e3744 4057 NO_STR
4058 SET_STR
4059 "set BGP community list (for deletion)\n"
4060 "Community-list number (standard)\n"
5e3edbf5 4061 "Community-list number (expanded)\n"
718e3744 4062 "Community-list name\n"
4063 "Delete matching communities\n")
4064
4065DEFUN (set_ecommunity_rt,
4066 set_ecommunity_rt_cmd,
4067 "set extcommunity rt .ASN:nn_or_IP-address:nn",
4068 SET_STR
4069 "BGP extended community attribute\n"
e6b6a564 4070 "Route Target extended community\n"
718e3744 4071 "VPN extended community\n")
4072{
4073 int ret;
4074 char *str;
4075
4076 str = argv_concat (argv, argc, 0);
4077 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
4078 XFREE (MTYPE_TMP, str);
4079
4080 return ret;
4081}
4082
4083DEFUN (no_set_ecommunity_rt,
4084 no_set_ecommunity_rt_cmd,
4085 "no set extcommunity rt",
4086 NO_STR
4087 SET_STR
4088 "BGP extended community attribute\n"
e6b6a564 4089 "Route Target extended community\n")
718e3744 4090{
4091 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
4092}
4093
4094ALIAS (no_set_ecommunity_rt,
4095 no_set_ecommunity_rt_val_cmd,
4096 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
4097 NO_STR
4098 SET_STR
4099 "BGP extended community attribute\n"
e6b6a564 4100 "Route Target extended community\n"
718e3744 4101 "VPN extended community\n")
4102
4103DEFUN (set_ecommunity_soo,
4104 set_ecommunity_soo_cmd,
4105 "set extcommunity soo .ASN:nn_or_IP-address:nn",
4106 SET_STR
4107 "BGP extended community attribute\n"
4108 "Site-of-Origin extended community\n"
4109 "VPN extended community\n")
4110{
4111 int ret;
4112 char *str;
4113
4114 str = argv_concat (argv, argc, 0);
4115 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
4116 XFREE (MTYPE_TMP, str);
4117 return ret;
4118}
4119
4120DEFUN (no_set_ecommunity_soo,
4121 no_set_ecommunity_soo_cmd,
4122 "no set extcommunity soo",
4123 NO_STR
4124 SET_STR
4125 "BGP extended community attribute\n"
4126 "Site-of-Origin extended community\n")
4127{
4128 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
4129}
4130
4131ALIAS (no_set_ecommunity_soo,
4132 no_set_ecommunity_soo_val_cmd,
4133 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
4134 NO_STR
4135 SET_STR
4136 "BGP extended community attribute\n"
4137 "Site-of-Origin extended community\n"
4138 "VPN extended community\n")
4139
4140DEFUN (set_origin,
4141 set_origin_cmd,
4142 "set origin (egp|igp|incomplete)",
4143 SET_STR
4144 "BGP origin code\n"
4145 "remote EGP\n"
4146 "local IGP\n"
4147 "unknown heritage\n")
4148{
4149 if (strncmp (argv[0], "igp", 2) == 0)
4150 return bgp_route_set_add (vty, vty->index, "origin", "igp");
4151 if (strncmp (argv[0], "egp", 1) == 0)
4152 return bgp_route_set_add (vty, vty->index, "origin", "egp");
4153 if (strncmp (argv[0], "incomplete", 2) == 0)
4154 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
4155
4156 return CMD_WARNING;
4157}
4158
4159DEFUN (no_set_origin,
4160 no_set_origin_cmd,
4161 "no set origin",
4162 NO_STR
4163 SET_STR
4164 "BGP origin code\n")
4165{
4166 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
4167}
4168
4169ALIAS (no_set_origin,
4170 no_set_origin_val_cmd,
4171 "no set origin (egp|igp|incomplete)",
4172 NO_STR
4173 SET_STR
4174 "BGP origin code\n"
4175 "remote EGP\n"
4176 "local IGP\n"
4177 "unknown heritage\n")
4178
4179DEFUN (set_atomic_aggregate,
4180 set_atomic_aggregate_cmd,
4181 "set atomic-aggregate",
4182 SET_STR
4183 "BGP atomic aggregate attribute\n" )
4184{
4185 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
4186}
4187
4188DEFUN (no_set_atomic_aggregate,
4189 no_set_atomic_aggregate_cmd,
4190 "no set atomic-aggregate",
4191 NO_STR
4192 SET_STR
4193 "BGP atomic aggregate attribute\n" )
4194{
4195 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
4196}
4197
4198DEFUN (set_aggregator_as,
4199 set_aggregator_as_cmd,
320da874 4200 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
718e3744 4201 SET_STR
4202 "BGP aggregator attribute\n"
4203 "AS number of aggregator\n"
4204 "AS number\n"
4205 "IP address of aggregator\n")
4206{
4207 int ret;
718e3744 4208 struct in_addr address;
718e3744 4209 char *argstr;
fd79ac91 4210
718e3744 4211 ret = inet_aton (argv[1], &address);
4212 if (ret == 0)
4213 {
4214 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
4215 return CMD_WARNING;
4216 }
4217
4218 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
4219 strlen (argv[0]) + strlen (argv[1]) + 2);
4220
4221 sprintf (argstr, "%s %s", argv[0], argv[1]);
4222
4223 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
4224
4225 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
4226
4227 return ret;
4228}
4229
4230DEFUN (no_set_aggregator_as,
4231 no_set_aggregator_as_cmd,
4232 "no set aggregator as",
4233 NO_STR
4234 SET_STR
4235 "BGP aggregator attribute\n"
4236 "AS number of aggregator\n")
4237{
4238 int ret;
718e3744 4239 struct in_addr address;
718e3744 4240 char *argstr;
4241
4242 if (argv == 0)
4243 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
4244
718e3744 4245 ret = inet_aton (argv[1], &address);
4246 if (ret == 0)
4247 {
4248 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
4249 return CMD_WARNING;
4250 }
4251
4252 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
4253 strlen (argv[0]) + strlen (argv[1]) + 2);
4254
4255 sprintf (argstr, "%s %s", argv[0], argv[1]);
4256
4257 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
4258
4259 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
4260
4261 return ret;
4262}
4263
4264ALIAS (no_set_aggregator_as,
4265 no_set_aggregator_as_val_cmd,
320da874 4266 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
718e3744 4267 NO_STR
4268 SET_STR
4269 "BGP aggregator attribute\n"
4270 "AS number of aggregator\n"
4271 "AS number\n"
4272 "IP address of aggregator\n")
4273
0d9551dc
DS
4274DEFUN (set_tag,
4275 set_tag_cmd,
4276 "set tag <1-65535>",
4277 SET_STR
4278 "Tag value for routing protocol\n"
4279 "Tag value\n")
4280{
4281 return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
4282}
4283
4284DEFUN (no_set_tag,
4285 no_set_tag_cmd,
4286 "no set tag",
4287 NO_STR
4288 SET_STR
4289 "Tag value for routing protocol\n")
4290{
4291 if (argc == 0)
4292 bgp_route_set_delete(vty, vty->index, "tag", NULL);
4293
4294 return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
4295}
4296
4297ALIAS (no_set_tag,
4298 no_set_tag_val_cmd,
4299 "no set tag <1-65535>",
4300 NO_STR
4301 SET_STR
4302 "Tag value for routing protocol\n"
4303 "Tag value\n")
4304
6b0655a2 4305
718e3744 4306#ifdef HAVE_IPV6
4307DEFUN (match_ipv6_address,
4308 match_ipv6_address_cmd,
4309 "match ipv6 address WORD",
4310 MATCH_STR
4311 IPV6_STR
4312 "Match IPv6 address of route\n"
4313 "IPv6 access-list name\n")
4314{
518f0eb1
DS
4315 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0],
4316 RMAP_EVENT_FILTER_ADDED);
718e3744 4317}
4318
4319DEFUN (no_match_ipv6_address,
4320 no_match_ipv6_address_cmd,
4321 "no match ipv6 address WORD",
4322 NO_STR
4323 MATCH_STR
4324 IPV6_STR
4325 "Match IPv6 address of route\n"
4326 "IPv6 access-list name\n")
4327{
518f0eb1
DS
4328 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0],
4329 RMAP_EVENT_FILTER_DELETED);
718e3744 4330}
4331
4332DEFUN (match_ipv6_next_hop,
4333 match_ipv6_next_hop_cmd,
4334 "match ipv6 next-hop X:X::X:X",
4335 MATCH_STR
4336 IPV6_STR
4337 "Match IPv6 next-hop address of route\n"
4338 "IPv6 address of next hop\n")
4339{
518f0eb1
DS
4340 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0],
4341 RMAP_EVENT_MATCH_ADDED);
718e3744 4342}
4343
4344DEFUN (no_match_ipv6_next_hop,
4345 no_match_ipv6_next_hop_cmd,
4346 "no match ipv6 next-hop X:X::X:X",
4347 NO_STR
4348 MATCH_STR
4349 IPV6_STR
4350 "Match IPv6 next-hop address of route\n"
4351 "IPv6 address of next hop\n")
4352{
518f0eb1
DS
4353 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0],
4354 RMAP_EVENT_MATCH_DELETED);
718e3744 4355}
4356
4357DEFUN (match_ipv6_address_prefix_list,
4358 match_ipv6_address_prefix_list_cmd,
4359 "match ipv6 address prefix-list WORD",
4360 MATCH_STR
4361 IPV6_STR
4362 "Match address of route\n"
4363 "Match entries of prefix-lists\n"
4364 "IP prefix-list name\n")
4365{
518f0eb1
DS
4366 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list",
4367 argv[0], RMAP_EVENT_PLIST_ADDED);
718e3744 4368}
4369
4370DEFUN (no_match_ipv6_address_prefix_list,
4371 no_match_ipv6_address_prefix_list_cmd,
4372 "no match ipv6 address prefix-list WORD",
4373 NO_STR
4374 MATCH_STR
4375 IPV6_STR
4376 "Match address of route\n"
4377 "Match entries of prefix-lists\n"
4378 "IP prefix-list name\n")
4379{
518f0eb1
DS
4380 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list",
4381 argv[0], RMAP_EVENT_PLIST_DELETED);
718e3744 4382}
4383
90916ac2
DS
4384DEFUN (set_ipv6_nexthop_peer,
4385 set_ipv6_nexthop_peer_cmd,
4386 "set ipv6 next-hop peer-address",
4387 SET_STR
4388 IPV6_STR
4389 "Next hop address\n"
4390 "Use peer address (for BGP only)\n")
4391{
4392 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
4393}
4394
4395DEFUN (no_set_ipv6_nexthop_peer,
4396 no_set_ipv6_nexthop_peer_cmd,
4397 "no set ipv6 next-hop peer-address",
4398 NO_STR
4399 SET_STR
4400 IPV6_STR
4401 "IPv6 next-hop address\n"
4402 )
4403{
4404 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
4405}
4406
718e3744 4407DEFUN (set_ipv6_nexthop_global,
4408 set_ipv6_nexthop_global_cmd,
4409 "set ipv6 next-hop global X:X::X:X",
4410 SET_STR
4411 IPV6_STR
4412 "IPv6 next-hop address\n"
4413 "IPv6 global address\n"
4414 "IPv6 address of next hop\n")
4415{
4416 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
4417}
4418
4419DEFUN (no_set_ipv6_nexthop_global,
4420 no_set_ipv6_nexthop_global_cmd,
4421 "no set ipv6 next-hop global",
4422 NO_STR
4423 SET_STR
4424 IPV6_STR
4425 "IPv6 next-hop address\n"
4426 "IPv6 global address\n")
4427{
4428 if (argc == 0)
4429 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
4430
4431 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
4432}
4433
4434ALIAS (no_set_ipv6_nexthop_global,
4435 no_set_ipv6_nexthop_global_val_cmd,
4436 "no set ipv6 next-hop global X:X::X:X",
4437 NO_STR
4438 SET_STR
4439 IPV6_STR
4440 "IPv6 next-hop address\n"
4441 "IPv6 global address\n"
4442 "IPv6 address of next hop\n")
4443
4444DEFUN (set_ipv6_nexthop_local,
4445 set_ipv6_nexthop_local_cmd,
4446 "set ipv6 next-hop local X:X::X:X",
4447 SET_STR
4448 IPV6_STR
4449 "IPv6 next-hop address\n"
4450 "IPv6 local address\n"
4451 "IPv6 address of next hop\n")
4452{
4453 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
4454}
4455
4456DEFUN (no_set_ipv6_nexthop_local,
4457 no_set_ipv6_nexthop_local_cmd,
4458 "no set ipv6 next-hop local",
4459 NO_STR
4460 SET_STR
4461 IPV6_STR
4462 "IPv6 next-hop address\n"
4463 "IPv6 local address\n")
4464{
4465 if (argc == 0)
4466 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
4467
4468 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
4469}
4470
4471ALIAS (no_set_ipv6_nexthop_local,
4472 no_set_ipv6_nexthop_local_val_cmd,
4473 "no set ipv6 next-hop local X:X::X:X",
4474 NO_STR
4475 SET_STR
4476 IPV6_STR
4477 "IPv6 next-hop address\n"
4478 "IPv6 local address\n"
4479 "IPv6 address of next hop\n")
4480#endif /* HAVE_IPV6 */
4481
4482DEFUN (set_vpnv4_nexthop,
4483 set_vpnv4_nexthop_cmd,
4484 "set vpnv4 next-hop A.B.C.D",
4485 SET_STR
4486 "VPNv4 information\n"
4487 "VPNv4 next-hop address\n"
4488 "IP address of next hop\n")
4489{
4490 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
4491}
4492
4493DEFUN (no_set_vpnv4_nexthop,
4494 no_set_vpnv4_nexthop_cmd,
4495 "no set vpnv4 next-hop",
4496 NO_STR
4497 SET_STR
4498 "VPNv4 information\n"
4499 "VPNv4 next-hop address\n")
4500{
4501 if (argc == 0)
4502 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
4503
4504 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
4505}
4506
4507ALIAS (no_set_vpnv4_nexthop,
4508 no_set_vpnv4_nexthop_val_cmd,
4509 "no set vpnv4 next-hop A.B.C.D",
4510 NO_STR
4511 SET_STR
4512 "VPNv4 information\n"
4513 "VPNv4 next-hop address\n"
4514 "IP address of next hop\n")
4515
4516DEFUN (set_originator_id,
4517 set_originator_id_cmd,
4518 "set originator-id A.B.C.D",
4519 SET_STR
4520 "BGP originator ID attribute\n"
4521 "IP address of originator\n")
4522{
4523 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
4524}
4525
4526DEFUN (no_set_originator_id,
4527 no_set_originator_id_cmd,
4528 "no set originator-id",
4529 NO_STR
4530 SET_STR
4531 "BGP originator ID attribute\n")
4532{
4533 if (argc == 0)
4534 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
4535
4536 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
4537}
4538
4539ALIAS (no_set_originator_id,
4540 no_set_originator_id_val_cmd,
4541 "no set originator-id A.B.C.D",
4542 NO_STR
4543 SET_STR
4544 "BGP originator ID attribute\n"
4545 "IP address of originator\n")
4546
c8f3fe30 4547DEFUN_DEPRECATED (set_pathlimit_ttl,
41367172
PJ
4548 set_pathlimit_ttl_cmd,
4549 "set pathlimit ttl <1-255>",
4550 SET_STR
4551 "BGP AS-Pathlimit attribute\n"
4552 "Set AS-Path Hop-count TTL\n")
4553{
c8f3fe30 4554 return CMD_SUCCESS;
41367172
PJ
4555}
4556
c8f3fe30 4557DEFUN_DEPRECATED (no_set_pathlimit_ttl,
41367172
PJ
4558 no_set_pathlimit_ttl_cmd,
4559 "no set pathlimit ttl",
4560 NO_STR
4561 SET_STR
4562 "BGP AS-Pathlimit attribute\n"
4563 "Set AS-Path Hop-count TTL\n")
4564{
c8f3fe30 4565 return CMD_SUCCESS;
41367172
PJ
4566}
4567
4568ALIAS (no_set_pathlimit_ttl,
4569 no_set_pathlimit_ttl_val_cmd,
4570 "no set pathlimit ttl <1-255>",
4571 NO_STR
4572 MATCH_STR
4573 "BGP AS-Pathlimit attribute\n"
4574 "Set AS-Path Hop-count TTL\n")
4575
c8f3fe30 4576DEFUN_DEPRECATED (match_pathlimit_as,
41367172
PJ
4577 match_pathlimit_as_cmd,
4578 "match pathlimit as <1-65535>",
4579 MATCH_STR
4580 "BGP AS-Pathlimit attribute\n"
4581 "Match Pathlimit AS number\n")
4582{
c8f3fe30 4583 return CMD_SUCCESS;
41367172
PJ
4584}
4585
c8f3fe30 4586DEFUN_DEPRECATED (no_match_pathlimit_as,
41367172
PJ
4587 no_match_pathlimit_as_cmd,
4588 "no match pathlimit as",
4589 NO_STR
4590 MATCH_STR
4591 "BGP AS-Pathlimit attribute\n"
4592 "Match Pathlimit AS number\n")
4593{
c8f3fe30 4594 return CMD_SUCCESS;
41367172
PJ
4595}
4596
4597ALIAS (no_match_pathlimit_as,
4598 no_match_pathlimit_as_val_cmd,
4599 "no match pathlimit as <1-65535>",
4600 NO_STR
4601 MATCH_STR
4602 "BGP AS-Pathlimit attribute\n"
4603 "Match Pathlimit ASN\n")
4604
6b0655a2 4605
718e3744 4606/* Initialization of route map. */
4607void
94f2b392 4608bgp_route_map_init (void)
718e3744 4609{
4610 route_map_init ();
4611 route_map_init_vty ();
73ac8160
DS
4612 route_map_add_hook (bgp_route_map_add);
4613 route_map_delete_hook (bgp_route_map_delete);
4614 route_map_event_hook (bgp_route_map_event);
718e3744 4615
fee0f4c6 4616 route_map_install_match (&route_match_peer_cmd);
af291c15 4617 route_map_install_match (&route_match_local_pref_cmd);
718e3744 4618 route_map_install_match (&route_match_ip_address_cmd);
4619 route_map_install_match (&route_match_ip_next_hop_cmd);
c1643bb7 4620 route_map_install_match (&route_match_ip_route_source_cmd);
718e3744 4621 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
4622 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
c1643bb7 4623 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
718e3744 4624 route_map_install_match (&route_match_aspath_cmd);
4625 route_map_install_match (&route_match_community_cmd);
73ffb25b 4626 route_map_install_match (&route_match_ecommunity_cmd);
af291c15 4627 route_map_install_match (&route_match_local_pref_cmd);
718e3744 4628 route_map_install_match (&route_match_metric_cmd);
4629 route_map_install_match (&route_match_origin_cmd);
1add115a 4630 route_map_install_match (&route_match_probability_cmd);
bc413143 4631 route_map_install_match (&route_match_interface_cmd);
0d9551dc 4632 route_map_install_match (&route_match_tag_cmd);
718e3744 4633
4634 route_map_install_set (&route_set_ip_nexthop_cmd);
4635 route_map_install_set (&route_set_local_pref_cmd);
4636 route_map_install_set (&route_set_weight_cmd);
4637 route_map_install_set (&route_set_metric_cmd);
4638 route_map_install_set (&route_set_aspath_prepend_cmd);
841f7a57 4639 route_map_install_set (&route_set_aspath_exclude_cmd);
718e3744 4640 route_map_install_set (&route_set_origin_cmd);
4641 route_map_install_set (&route_set_atomic_aggregate_cmd);
4642 route_map_install_set (&route_set_aggregator_as_cmd);
4643 route_map_install_set (&route_set_community_cmd);
4644 route_map_install_set (&route_set_community_delete_cmd);
4645 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
4646 route_map_install_set (&route_set_originator_id_cmd);
4647 route_map_install_set (&route_set_ecommunity_rt_cmd);
4648 route_map_install_set (&route_set_ecommunity_soo_cmd);
0d9551dc 4649 route_map_install_set (&route_set_tag_cmd);
718e3744 4650
fee0f4c6 4651 install_element (RMAP_NODE, &match_peer_cmd);
4652 install_element (RMAP_NODE, &match_peer_local_cmd);
4653 install_element (RMAP_NODE, &no_match_peer_cmd);
4654 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4655 install_element (RMAP_NODE, &no_match_peer_local_cmd);
718e3744 4656 install_element (RMAP_NODE, &match_ip_address_cmd);
4657 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4658 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4659 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4660 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4661 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
c1643bb7 4662 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4663 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4664 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
718e3744 4665 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4666 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4667 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4668 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4669 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4670 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
c1643bb7 4671 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4672 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4673 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
718e3744 4674
4675 install_element (RMAP_NODE, &match_aspath_cmd);
4676 install_element (RMAP_NODE, &no_match_aspath_cmd);
4677 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4678 install_element (RMAP_NODE, &match_metric_cmd);
4679 install_element (RMAP_NODE, &no_match_metric_cmd);
4680 install_element (RMAP_NODE, &no_match_metric_val_cmd);
af291c15
DS
4681 install_element (RMAP_NODE, &match_local_pref_cmd);
4682 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4683 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
718e3744 4684 install_element (RMAP_NODE, &match_community_cmd);
4685 install_element (RMAP_NODE, &match_community_exact_cmd);
4686 install_element (RMAP_NODE, &no_match_community_cmd);
4687 install_element (RMAP_NODE, &no_match_community_val_cmd);
4688 install_element (RMAP_NODE, &no_match_community_exact_cmd);
73ffb25b 4689 install_element (RMAP_NODE, &match_ecommunity_cmd);
4690 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4691 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
718e3744 4692 install_element (RMAP_NODE, &match_origin_cmd);
4693 install_element (RMAP_NODE, &no_match_origin_cmd);
4694 install_element (RMAP_NODE, &no_match_origin_val_cmd);
1add115a
VT
4695 install_element (RMAP_NODE, &match_probability_cmd);
4696 install_element (RMAP_NODE, &no_match_probability_cmd);
4697 install_element (RMAP_NODE, &no_match_probability_val_cmd);
bc413143
DS
4698 install_element (RMAP_NODE, &match_interface_cmd);
4699 install_element (RMAP_NODE, &no_match_interface_cmd);
4700 install_element (RMAP_NODE, &no_match_interface_val_cmd);
0d9551dc
DS
4701 install_element (RMAP_NODE, &match_tag_cmd);
4702 install_element (RMAP_NODE, &no_match_tag_cmd);
4703 install_element (RMAP_NODE, &no_match_tag_val_cmd);
718e3744 4704
4705 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
af5cd0a5 4706 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
316e074d 4707 install_element (RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
718e3744 4708 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4709 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4710 install_element (RMAP_NODE, &set_local_pref_cmd);
4711 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4712 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4713 install_element (RMAP_NODE, &set_weight_cmd);
4714 install_element (RMAP_NODE, &no_set_weight_cmd);
4715 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4716 install_element (RMAP_NODE, &set_metric_cmd);
73ffb25b 4717 install_element (RMAP_NODE, &set_metric_addsub_cmd);
718e3744 4718 install_element (RMAP_NODE, &no_set_metric_cmd);
4719 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4720 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
841f7a57 4721 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
718e3744 4722 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4723 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
841f7a57
DO
4724 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4725 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
718e3744 4726 install_element (RMAP_NODE, &set_origin_cmd);
4727 install_element (RMAP_NODE, &no_set_origin_cmd);
4728 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4729 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4730 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4731 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4732 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4733 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4734 install_element (RMAP_NODE, &set_community_cmd);
4735 install_element (RMAP_NODE, &set_community_none_cmd);
4736 install_element (RMAP_NODE, &no_set_community_cmd);
4737 install_element (RMAP_NODE, &no_set_community_val_cmd);
4738 install_element (RMAP_NODE, &no_set_community_none_cmd);
4739 install_element (RMAP_NODE, &set_community_delete_cmd);
4740 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4741 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4742 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4743 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4744 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4745 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4746 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4747 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4748 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4749 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4750 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4751 install_element (RMAP_NODE, &set_originator_id_cmd);
4752 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4753 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
0d9551dc
DS
4754 install_element (RMAP_NODE, &set_tag_cmd);
4755 install_element (RMAP_NODE, &no_set_tag_cmd);
4756 install_element (RMAP_NODE, &no_set_tag_val_cmd);
718e3744 4757
4758#ifdef HAVE_IPV6
4759 route_map_install_match (&route_match_ipv6_address_cmd);
4760 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4761 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4762 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4763 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
90916ac2
DS
4764 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4765
718e3744 4766 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4767 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4768 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4769 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4770 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4771 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4772 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4773 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4774 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4775 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4776 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4777 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
90916ac2
DS
4778 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4779 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
718e3744 4780#endif /* HAVE_IPV6 */
41367172 4781
c8f3fe30
PJ
4782 /* AS-Pathlimit: functionality removed, commands kept for
4783 * compatibility.
4784 */
41367172
PJ
4785 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4786 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4787 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4788 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4789 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4790 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
718e3744 4791}
518f0eb1
DS
4792
4793void
4794bgp_route_map_terminate (void)
4795{
4796 /* ToDo: Cleanup all the used memory */
4797
4798 route_map_add_hook (NULL);
4799 route_map_delete_hook (NULL);
4800 route_map_event_hook (NULL);
4801 route_map_finish();
4802
4803}