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