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