blob: 060c68c0d590e8b8281fa6e8ecb77b333afb7451 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
31#ifdef HAVE_GNU_REGEX
32#include <regex.h>
33#else
34#include "regex-gnu.h"
35#endif /* HAVE_GNU_REGEX */
36#include "buffer.h"
37#include "sockunion.h"
38
39#include "bgpd/bgpd.h"
40#include "bgpd/bgp_table.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_aspath.h"
43#include "bgpd/bgp_route.h"
44#include "bgpd/bgp_regex.h"
45#include "bgpd/bgp_community.h"
46#include "bgpd/bgp_clist.h"
47#include "bgpd/bgp_filter.h"
48#include "bgpd/bgp_mplsvpn.h"
49#include "bgpd/bgp_ecommunity.h"
50
51/* Memo of route-map commands.
52
53o Cisco route-map
54
55 match as-path : Done
56 community : Done
57 interface : Not yet
58 ip address : Done
59 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000060 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000061 ip prefix-list : Done
62 ipv6 address : Done
63 ipv6 next-hop : Done
64 ipv6 route-source: (This will not be implemented by bgpd)
65 ipv6 prefix-list : Done
66 length : (This will not be implemented by bgpd)
67 metric : Done
68 route-type : (This will not be implemented by bgpd)
69 tag : (This will not be implemented by bgpd)
70
71 set as-path prepend : Done
72 as-path tag : Not yet
73 automatic-tag : (This will not be implemented by bgpd)
74 community : Done
75 comm-list : Not yet
76 dampning : Not yet
77 default : (This will not be implemented by bgpd)
78 interface : (This will not be implemented by bgpd)
79 ip default : (This will not be implemented by bgpd)
80 ip next-hop : Done
81 ip precedence : (This will not be implemented by bgpd)
82 ip tos : (This will not be implemented by bgpd)
83 level : (This will not be implemented by bgpd)
84 local-preference : Done
85 metric : Done
86 metric-type : Not yet
87 origin : Done
88 tag : (This will not be implemented by bgpd)
89 weight : Done
90
91o Local extention
92
93 set ipv6 next-hop global: Done
94 set ipv6 next-hop local : Done
95
96*/
97
paulfee0f4c2004-09-13 05:12:46 +000098 /* 'match peer (A.B.C.D|X:X::X:X)' */
99
100/* Compares the peer specified in the 'match peer' clause with the peer
101 received in bgp_info->peer. If it is the same, or if the peer structure
102 received is a peer_group containing it, returns RMAP_MATCH. */
103route_map_result_t
104route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
105 void *object)
106{
107 union sockunion *su;
108 union sockunion *su2;
109 struct peer_group *group;
110 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000111 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000112
113 if (type == RMAP_BGP)
114 {
115 su = rule;
116 peer = ((struct bgp_info *) object)->peer;
117
118 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
119 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
120 return RMAP_NOMATCH;
121
122 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
123 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
124 su2 = sockunion_str2su ("0.0.0.0");
125 if ( sockunion_same (su, su2) )
126 {
127 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
128 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
129 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
130 {
131 XFREE (MTYPE_SOCKUNION, su2);
132
133 return RMAP_MATCH;
134 }
135 else
136 return RMAP_NOMATCH;
137 }
138 XFREE (MTYPE_SOCKUNION, su2);
139
140 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
141 {
142 if (sockunion_same (su, &peer->su))
143 return RMAP_MATCH;
144
145 return RMAP_NOMATCH;
146 }
147 else
148 {
149 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000150 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000151 {
152 if (sockunion_same (su, &peer->su))
153 return RMAP_MATCH;
154
155 return RMAP_NOMATCH;
156 }
157 }
158 }
159 return RMAP_NOMATCH;
160}
161
162void *
paulfd79ac92004-10-13 05:06:08 +0000163route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000164{
165 union sockunion *su;
166 int ret;
167
168 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
169
170 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
171 if (ret < 0) {
172 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
173 return NULL;
174 }
175
176 return su;
177}
178
179/* Free route map's compiled `ip address' value. */
180void
181route_match_peer_free (void *rule)
182{
183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
184}
185
186/* Route map commands for ip address matching. */
187struct route_map_rule_cmd route_match_peer_cmd =
188{
189 "peer",
190 route_match_peer,
191 route_match_peer_compile,
192 route_match_peer_free
193};
194
paul718e3742002-12-13 20:15:29 +0000195/* `match ip address IP_ACCESS_LIST' */
196
197/* Match function should return 1 if match is success else return
198 zero. */
199route_map_result_t
200route_match_ip_address (void *rule, struct prefix *prefix,
201 route_map_object_t type, void *object)
202{
203 struct access_list *alist;
204 /* struct prefix_ipv4 match; */
205
206 if (type == RMAP_BGP)
207 {
208 alist = access_list_lookup (AFI_IP, (char *) rule);
209 if (alist == NULL)
210 return RMAP_NOMATCH;
211
212 return (access_list_apply (alist, prefix) == FILTER_DENY ?
213 RMAP_NOMATCH : RMAP_MATCH);
214 }
215 return RMAP_NOMATCH;
216}
217
218/* Route map `ip address' match statement. `arg' should be
219 access-list name. */
220void *
paulfd79ac92004-10-13 05:06:08 +0000221route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000222{
223 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
224}
225
226/* Free route map's compiled `ip address' value. */
227void
228route_match_ip_address_free (void *rule)
229{
230 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
231}
232
233/* Route map commands for ip address matching. */
234struct route_map_rule_cmd route_match_ip_address_cmd =
235{
236 "ip address",
237 route_match_ip_address,
238 route_match_ip_address_compile,
239 route_match_ip_address_free
240};
241
242/* `match ip next-hop IP_ADDRESS' */
243
244/* Match function return 1 if match is success else return zero. */
245route_map_result_t
246route_match_ip_next_hop (void *rule, struct prefix *prefix,
247 route_map_object_t type, void *object)
248{
249 struct access_list *alist;
250 struct bgp_info *bgp_info;
251 struct prefix_ipv4 p;
252
253 if (type == RMAP_BGP)
254 {
255 bgp_info = object;
256 p.family = AF_INET;
257 p.prefix = bgp_info->attr->nexthop;
258 p.prefixlen = IPV4_MAX_BITLEN;
259
260 alist = access_list_lookup (AFI_IP, (char *) rule);
261 if (alist == NULL)
262 return RMAP_NOMATCH;
263
264 return (access_list_apply (alist, &p) == FILTER_DENY ?
265 RMAP_NOMATCH : RMAP_MATCH);
266 }
267 return RMAP_NOMATCH;
268}
269
270/* Route map `ip next-hop' match statement. `arg' is
271 access-list name. */
272void *
paulfd79ac92004-10-13 05:06:08 +0000273route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000274{
275 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
276}
277
278/* Free route map's compiled `ip address' value. */
279void
280route_match_ip_next_hop_free (void *rule)
281{
282 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
283}
284
285/* Route map commands for ip next-hop matching. */
286struct route_map_rule_cmd route_match_ip_next_hop_cmd =
287{
288 "ip next-hop",
289 route_match_ip_next_hop,
290 route_match_ip_next_hop_compile,
291 route_match_ip_next_hop_free
292};
293
hassoc1643bb2005-02-02 16:43:17 +0000294/* `match ip route-source ACCESS-LIST' */
295
296/* Match function return 1 if match is success else return zero. */
297route_map_result_t
298route_match_ip_route_source (void *rule, struct prefix *prefix,
299 route_map_object_t type, void *object)
300{
301 struct access_list *alist;
302 struct bgp_info *bgp_info;
303 struct peer *peer;
304 struct prefix_ipv4 p;
305
306 if (type == RMAP_BGP)
307 {
308 bgp_info = object;
309 peer = bgp_info->peer;
310
311 if (! peer || sockunion_family (&peer->su) != AF_INET)
312 return RMAP_NOMATCH;
313
314 p.family = AF_INET;
315 p.prefix = peer->su.sin.sin_addr;
316 p.prefixlen = IPV4_MAX_BITLEN;
317
318 alist = access_list_lookup (AFI_IP, (char *) rule);
319 if (alist == NULL)
320 return RMAP_NOMATCH;
321
322 return (access_list_apply (alist, &p) == FILTER_DENY ?
323 RMAP_NOMATCH : RMAP_MATCH);
324 }
325 return RMAP_NOMATCH;
326}
327
328/* Route map `ip route-source' match statement. `arg' is
329 access-list name. */
330void *
331route_match_ip_route_source_compile (const char *arg)
332{
333 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
334}
335
336/* Free route map's compiled `ip address' value. */
337void
338route_match_ip_route_source_free (void *rule)
339{
340 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
341}
342
343/* Route map commands for ip route-source matching. */
344struct route_map_rule_cmd route_match_ip_route_source_cmd =
345{
346 "ip route-source",
347 route_match_ip_route_source,
348 route_match_ip_route_source_compile,
349 route_match_ip_route_source_free
350};
351
paul718e3742002-12-13 20:15:29 +0000352/* `match ip address prefix-list PREFIX_LIST' */
353
354route_map_result_t
355route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
356 route_map_object_t type, void *object)
357{
358 struct prefix_list *plist;
359
360 if (type == RMAP_BGP)
361 {
362 plist = prefix_list_lookup (AFI_IP, (char *) rule);
363 if (plist == NULL)
364 return RMAP_NOMATCH;
365
366 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
367 RMAP_NOMATCH : RMAP_MATCH);
368 }
369 return RMAP_NOMATCH;
370}
371
372void *
paulfd79ac92004-10-13 05:06:08 +0000373route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000374{
375 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
376}
377
378void
379route_match_ip_address_prefix_list_free (void *rule)
380{
381 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
382}
383
384struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
385{
386 "ip address prefix-list",
387 route_match_ip_address_prefix_list,
388 route_match_ip_address_prefix_list_compile,
389 route_match_ip_address_prefix_list_free
390};
391
392/* `match ip next-hop prefix-list PREFIX_LIST' */
393
394route_map_result_t
395route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
396 route_map_object_t type, void *object)
397{
398 struct prefix_list *plist;
399 struct bgp_info *bgp_info;
400 struct prefix_ipv4 p;
401
402 if (type == RMAP_BGP)
403 {
404 bgp_info = object;
405 p.family = AF_INET;
406 p.prefix = bgp_info->attr->nexthop;
407 p.prefixlen = IPV4_MAX_BITLEN;
408
409 plist = prefix_list_lookup (AFI_IP, (char *) rule);
410 if (plist == NULL)
411 return RMAP_NOMATCH;
412
413 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
414 RMAP_NOMATCH : RMAP_MATCH);
415 }
416 return RMAP_NOMATCH;
417}
418
419void *
paulfd79ac92004-10-13 05:06:08 +0000420route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000421{
422 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
423}
424
425void
426route_match_ip_next_hop_prefix_list_free (void *rule)
427{
428 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
429}
430
431struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
432{
433 "ip next-hop prefix-list",
434 route_match_ip_next_hop_prefix_list,
435 route_match_ip_next_hop_prefix_list_compile,
436 route_match_ip_next_hop_prefix_list_free
437};
438
hassoc1643bb2005-02-02 16:43:17 +0000439/* `match ip route-source prefix-list PREFIX_LIST' */
440
441route_map_result_t
442route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
443 route_map_object_t type, void *object)
444{
445 struct prefix_list *plist;
446 struct bgp_info *bgp_info;
447 struct peer *peer;
448 struct prefix_ipv4 p;
449
450 if (type == RMAP_BGP)
451 {
452 bgp_info = object;
453 peer = bgp_info->peer;
454
455 if (! peer || sockunion_family (&peer->su) != AF_INET)
456 return RMAP_NOMATCH;
457
458 p.family = AF_INET;
459 p.prefix = peer->su.sin.sin_addr;
460 p.prefixlen = IPV4_MAX_BITLEN;
461
462 plist = prefix_list_lookup (AFI_IP, (char *) rule);
463 if (plist == NULL)
464 return RMAP_NOMATCH;
465
466 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
467 RMAP_NOMATCH : RMAP_MATCH);
468 }
469 return RMAP_NOMATCH;
470}
471
472void *
473route_match_ip_route_source_prefix_list_compile (const char *arg)
474{
475 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
476}
477
478void
479route_match_ip_route_source_prefix_list_free (void *rule)
480{
481 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
482}
483
484struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
485{
486 "ip route-source prefix-list",
487 route_match_ip_route_source_prefix_list,
488 route_match_ip_route_source_prefix_list_compile,
489 route_match_ip_route_source_prefix_list_free
490};
491
paul718e3742002-12-13 20:15:29 +0000492/* `match metric METRIC' */
493
494/* Match function return 1 if match is success else return zero. */
495route_map_result_t
496route_match_metric (void *rule, struct prefix *prefix,
497 route_map_object_t type, void *object)
498{
499 u_int32_t *med;
500 struct bgp_info *bgp_info;
501
502 if (type == RMAP_BGP)
503 {
504 med = rule;
505 bgp_info = object;
506
507 if (bgp_info->attr->med == *med)
508 return RMAP_MATCH;
509 else
510 return RMAP_NOMATCH;
511 }
512 return RMAP_NOMATCH;
513}
514
515/* Route map `match metric' match statement. `arg' is MED value */
516void *
paulfd79ac92004-10-13 05:06:08 +0000517route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000518{
519 u_int32_t *med;
520 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000521 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000522
paul3b424972003-10-13 09:47:32 +0000523 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000524 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000525 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000526
paul718e3742002-12-13 20:15:29 +0000527 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000528
529 if (!med)
530 return med;
531
paul3b424972003-10-13 09:47:32 +0000532 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000533 return med;
534}
535
536/* Free route map's compiled `match metric' value. */
537void
538route_match_metric_free (void *rule)
539{
540 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
541}
542
543/* Route map commands for metric matching. */
544struct route_map_rule_cmd route_match_metric_cmd =
545{
546 "metric",
547 route_match_metric,
548 route_match_metric_compile,
549 route_match_metric_free
550};
551
552/* `match as-path ASPATH' */
553
554/* Match function for as-path match. I assume given object is */
555route_map_result_t
556route_match_aspath (void *rule, struct prefix *prefix,
557 route_map_object_t type, void *object)
558{
559
560 struct as_list *as_list;
561 struct bgp_info *bgp_info;
562
563 if (type == RMAP_BGP)
564 {
565 as_list = as_list_lookup ((char *) rule);
566 if (as_list == NULL)
567 return RMAP_NOMATCH;
568
569 bgp_info = object;
570
571 /* Perform match. */
572 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
573 }
574 return RMAP_NOMATCH;
575}
576
577/* Compile function for as-path match. */
578void *
paulfd79ac92004-10-13 05:06:08 +0000579route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000580{
581 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
582}
583
584/* Compile function for as-path match. */
585void
586route_match_aspath_free (void *rule)
587{
588 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
589}
590
591/* Route map commands for aspath matching. */
592struct route_map_rule_cmd route_match_aspath_cmd =
593{
594 "as-path",
595 route_match_aspath,
596 route_match_aspath_compile,
597 route_match_aspath_free
598};
599
600#if ROUTE_MATCH_ASPATH_OLD
601/* `match as-path ASPATH' */
602
603/* Match function for as-path match. I assume given object is */
604int
605route_match_aspath (void *rule, struct prefix *prefix, void *object)
606{
607 regex_t *regex;
608 struct bgp_info *bgp_info;
609
610 regex = rule;
611 bgp_info = object;
612
613 /* Perform match. */
614 return bgp_regexec (regex, bgp_info->attr->aspath);
615}
616
617/* Compile function for as-path match. */
618void *
paulfd79ac92004-10-13 05:06:08 +0000619route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000620{
621 regex_t *regex;
622
623 regex = bgp_regcomp (arg);
624 if (! regex)
625 return NULL;
626
627 return regex;
628}
629
630/* Compile function for as-path match. */
631void
632route_match_aspath_free (void *rule)
633{
634 regex_t *regex = rule;
635
636 bgp_regex_free (regex);
637}
638
639/* Route map commands for aspath matching. */
640struct route_map_rule_cmd route_match_aspath_cmd =
641{
642 "as-path",
643 route_match_aspath,
644 route_match_aspath_compile,
645 route_match_aspath_free
646};
647#endif /* ROUTE_MATCH_ASPATH_OLD */
648
649/* `match community COMMUNIY' */
650struct rmap_community
651{
652 char *name;
653 int exact;
654};
655
656/* Match function for community match. */
657route_map_result_t
658route_match_community (void *rule, struct prefix *prefix,
659 route_map_object_t type, void *object)
660{
661 struct community_list *list;
662 struct bgp_info *bgp_info;
663 struct rmap_community *rcom;
664
665 if (type == RMAP_BGP)
666 {
667 bgp_info = object;
668 rcom = rule;
669
hassofee6e4e2005-02-02 16:29:31 +0000670 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000671 if (! list)
672 return RMAP_NOMATCH;
673
674 if (rcom->exact)
675 {
676 if (community_list_exact_match (bgp_info->attr->community, list))
677 return RMAP_MATCH;
678 }
679 else
680 {
681 if (community_list_match (bgp_info->attr->community, list))
682 return RMAP_MATCH;
683 }
684 }
685 return RMAP_NOMATCH;
686}
687
688/* Compile function for community match. */
689void *
paulfd79ac92004-10-13 05:06:08 +0000690route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000691{
692 struct rmap_community *rcom;
693 int len;
694 char *p;
695
696 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
697
698 p = strchr (arg, ' ');
699 if (p)
700 {
701 len = p - arg;
702 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
703 memcpy (rcom->name, arg, len);
704 rcom->exact = 1;
705 }
706 else
707 {
708 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
709 rcom->exact = 0;
710 }
711 return rcom;
712}
713
714/* Compile function for community match. */
715void
716route_match_community_free (void *rule)
717{
718 struct rmap_community *rcom = rule;
719
720 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
721 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
722}
723
724/* Route map commands for community matching. */
725struct route_map_rule_cmd route_match_community_cmd =
726{
727 "community",
728 route_match_community,
729 route_match_community_compile,
730 route_match_community_free
731};
732
paul73ffb252003-04-19 15:49:49 +0000733/* Match function for extcommunity match. */
734route_map_result_t
735route_match_ecommunity (void *rule, struct prefix *prefix,
736 route_map_object_t type, void *object)
737{
738 struct community_list *list;
739 struct bgp_info *bgp_info;
740
741 if (type == RMAP_BGP)
742 {
743 bgp_info = object;
744
745 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000746 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000747 if (! list)
748 return RMAP_NOMATCH;
749
750 if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
751 return RMAP_MATCH;
752 }
753 return RMAP_NOMATCH;
754}
755
756/* Compile function for extcommunity match. */
757void *
paulfd79ac92004-10-13 05:06:08 +0000758route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000759{
760 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
761}
762
763/* Compile function for extcommunity match. */
764void
765route_match_ecommunity_free (void *rule)
766{
767 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
768}
769
770/* Route map commands for community matching. */
771struct route_map_rule_cmd route_match_ecommunity_cmd =
772{
773 "extcommunity",
774 route_match_ecommunity,
775 route_match_ecommunity_compile,
776 route_match_ecommunity_free
777};
778
paul718e3742002-12-13 20:15:29 +0000779/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
780 and `address-family vpnv4'. */
781
782/* `match origin' */
783route_map_result_t
784route_match_origin (void *rule, struct prefix *prefix,
785 route_map_object_t type, void *object)
786{
787 u_char *origin;
788 struct bgp_info *bgp_info;
789
790 if (type == RMAP_BGP)
791 {
792 origin = rule;
793 bgp_info = object;
794
795 if (bgp_info->attr->origin == *origin)
796 return RMAP_MATCH;
797 }
798
799 return RMAP_NOMATCH;
800}
801
802void *
paulfd79ac92004-10-13 05:06:08 +0000803route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000804{
805 u_char *origin;
806
807 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
808
809 if (strcmp (arg, "igp") == 0)
810 *origin = 0;
811 else if (strcmp (arg, "egp") == 0)
812 *origin = 1;
813 else
814 *origin = 2;
815
816 return origin;
817}
818
819/* Free route map's compiled `ip address' value. */
820void
821route_match_origin_free (void *rule)
822{
823 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
824}
825
826/* Route map commands for origin matching. */
827struct route_map_rule_cmd route_match_origin_cmd =
828{
829 "origin",
830 route_match_origin,
831 route_match_origin_compile,
832 route_match_origin_free
833};
834/* `set ip next-hop IP_ADDRESS' */
835
836/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000837struct rmap_ip_nexthop_set
838{
839 struct in_addr *address;
840 int peer_address;
841};
842
paul718e3742002-12-13 20:15:29 +0000843route_map_result_t
844route_set_ip_nexthop (void *rule, struct prefix *prefix,
845 route_map_object_t type, void *object)
846{
paulac41b2a2003-08-12 05:32:27 +0000847 struct rmap_ip_nexthop_set *rins = rule;
848 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000849 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000850 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000851
852 if (type == RMAP_BGP)
853 {
paul718e3742002-12-13 20:15:29 +0000854 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000855 peer = bgp_info->peer;
856
857 if (rins->peer_address)
858 {
paulfee0f4c2004-09-13 05:12:46 +0000859 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
860 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000861 && peer->su_remote
862 && sockunion_family (peer->su_remote) == AF_INET)
863 {
864 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
865 bgp_info->attr->nexthop = peer_address;
866 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
867 }
868 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
869 && peer->su_local
870 && sockunion_family (peer->su_local) == AF_INET)
871 {
872 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
873 bgp_info->attr->nexthop = peer_address;
874 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
875 }
876 }
877 else
878 {
879 /* Set next hop value. */
880 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
881 bgp_info->attr->nexthop = *rins->address;
882 }
paul718e3742002-12-13 20:15:29 +0000883 }
884
885 return RMAP_OKAY;
886}
887
888/* Route map `ip nexthop' compile function. Given string is converted
889 to struct in_addr structure. */
890void *
paulfd79ac92004-10-13 05:06:08 +0000891route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000892{
paulac41b2a2003-08-12 05:32:27 +0000893 struct rmap_ip_nexthop_set *rins;
894 struct in_addr *address = NULL;
895 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000896 int ret;
paul718e3742002-12-13 20:15:29 +0000897
paulac41b2a2003-08-12 05:32:27 +0000898 if (strcmp (arg, "peer-address") == 0)
899 peer_address = 1;
900 else
paul718e3742002-12-13 20:15:29 +0000901 {
paulac41b2a2003-08-12 05:32:27 +0000902 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
903 ret = inet_aton (arg, address);
904
905 if (ret == 0)
906 {
907 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
908 return NULL;
909 }
paul718e3742002-12-13 20:15:29 +0000910 }
911
paulac41b2a2003-08-12 05:32:27 +0000912 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
913 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
914
915 rins->address = address;
916 rins->peer_address = peer_address;
917
918 return rins;
paul718e3742002-12-13 20:15:29 +0000919}
920
921/* Free route map's compiled `ip nexthop' value. */
922void
923route_set_ip_nexthop_free (void *rule)
924{
paulac41b2a2003-08-12 05:32:27 +0000925 struct rmap_ip_nexthop_set *rins = rule;
926
927 if (rins->address)
928 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
929
930 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000931}
932
933/* Route map commands for ip nexthop set. */
934struct route_map_rule_cmd route_set_ip_nexthop_cmd =
935{
936 "ip next-hop",
937 route_set_ip_nexthop,
938 route_set_ip_nexthop_compile,
939 route_set_ip_nexthop_free
940};
941
942/* `set local-preference LOCAL_PREF' */
943
944/* Set local preference. */
945route_map_result_t
946route_set_local_pref (void *rule, struct prefix *prefix,
947 route_map_object_t type, void *object)
948{
949 u_int32_t *local_pref;
950 struct bgp_info *bgp_info;
951
952 if (type == RMAP_BGP)
953 {
954 /* Fetch routemap's rule information. */
955 local_pref = rule;
956 bgp_info = object;
957
958 /* Set local preference value. */
959 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
960 bgp_info->attr->local_pref = *local_pref;
961 }
962
963 return RMAP_OKAY;
964}
965
966/* set local preference compilation. */
967void *
paulfd79ac92004-10-13 05:06:08 +0000968route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000969{
paulfd79ac92004-10-13 05:06:08 +0000970 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000971 u_int32_t *local_pref;
972 char *endptr = NULL;
973
974 /* Local preference value shoud be integer. */
975 if (! all_digit (arg))
976 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000977
978 tmp = strtoul (arg, &endptr, 10);
979 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
980 return NULL;
981
982 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
983
984 if (!local_pref)
985 return local_pref;
986
987 *local_pref = tmp;
988
paul718e3742002-12-13 20:15:29 +0000989 return local_pref;
990}
991
992/* Free route map's local preference value. */
993void
994route_set_local_pref_free (void *rule)
995{
996 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
997}
998
999/* Set local preference rule structure. */
1000struct route_map_rule_cmd route_set_local_pref_cmd =
1001{
1002 "local-preference",
1003 route_set_local_pref,
1004 route_set_local_pref_compile,
1005 route_set_local_pref_free,
1006};
1007
1008/* `set weight WEIGHT' */
1009
1010/* Set weight. */
1011route_map_result_t
1012route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1013 void *object)
1014{
1015 u_int32_t *weight;
1016 struct bgp_info *bgp_info;
1017
1018 if (type == RMAP_BGP)
1019 {
1020 /* Fetch routemap's rule information. */
1021 weight = rule;
1022 bgp_info = object;
1023
1024 /* Set weight value. */
1025 bgp_info->attr->weight = *weight;
1026 }
1027
1028 return RMAP_OKAY;
1029}
1030
1031/* set local preference compilation. */
1032void *
paulfd79ac92004-10-13 05:06:08 +00001033route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001034{
paulfd79ac92004-10-13 05:06:08 +00001035 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001036 u_int32_t *weight;
1037 char *endptr = NULL;
1038
1039 /* Local preference value shoud be integer. */
1040 if (! all_digit (arg))
1041 return NULL;
1042
paulfd79ac92004-10-13 05:06:08 +00001043
1044 tmp = strtoul (arg, &endptr, 10);
1045 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1046 return NULL;
1047
paul718e3742002-12-13 20:15:29 +00001048 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001049
1050 if (weight == NULL)
1051 return weight;
1052
1053 *weight = tmp;
1054
paul718e3742002-12-13 20:15:29 +00001055 return weight;
1056}
1057
1058/* Free route map's local preference value. */
1059void
1060route_set_weight_free (void *rule)
1061{
1062 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1063}
1064
1065/* Set local preference rule structure. */
1066struct route_map_rule_cmd route_set_weight_cmd =
1067{
1068 "weight",
1069 route_set_weight,
1070 route_set_weight_compile,
1071 route_set_weight_free,
1072};
1073
1074/* `set metric METRIC' */
1075
1076/* Set metric to attribute. */
1077route_map_result_t
1078route_set_metric (void *rule, struct prefix *prefix,
1079 route_map_object_t type, void *object)
1080{
1081 char *metric;
1082 u_int32_t metric_val;
1083 struct bgp_info *bgp_info;
1084
1085 if (type == RMAP_BGP)
1086 {
1087 /* Fetch routemap's rule information. */
1088 metric = rule;
1089 bgp_info = object;
1090
1091 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1092 bgp_info->attr->med = 0;
1093 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1094
1095 if (all_digit (metric))
1096 {
1097 metric_val = strtoul (metric, (char **)NULL, 10);
1098 bgp_info->attr->med = metric_val;
1099 }
1100 else
1101 {
1102 metric_val = strtoul (metric+1, (char **)NULL, 10);
1103
1104 if (strncmp (metric, "+", 1) == 0)
1105 {
paul3b424972003-10-13 09:47:32 +00001106 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1107 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001108 else
paul537d8ea2003-08-27 06:45:32 +00001109 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001110 }
1111 else if (strncmp (metric, "-", 1) == 0)
1112 {
paul537d8ea2003-08-27 06:45:32 +00001113 if (bgp_info->attr->med <= metric_val)
1114 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001115 else
paul537d8ea2003-08-27 06:45:32 +00001116 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001117 }
1118 }
1119 }
1120 return RMAP_OKAY;
1121}
1122
1123/* set metric compilation. */
1124void *
paulfd79ac92004-10-13 05:06:08 +00001125route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001126{
1127 u_int32_t metric;
1128 char *endptr = NULL;
1129
1130 if (all_digit (arg))
1131 {
1132 /* set metric value check*/
1133 metric = strtoul (arg, &endptr, 10);
1134 if (*endptr != '\0' || metric == ULONG_MAX)
1135 return NULL;
1136 }
1137 else
1138 {
1139 /* set metric +/-value check */
1140 if ((strncmp (arg, "+", 1) != 0
1141 && strncmp (arg, "-", 1) != 0)
1142 || (! all_digit (arg+1)))
1143 return NULL;
1144
1145 metric = strtoul (arg+1, &endptr, 10);
1146 if (*endptr != '\0' || metric == ULONG_MAX)
1147 return NULL;
1148 }
1149
1150 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1151}
1152
1153/* Free route map's compiled `set metric' value. */
1154void
1155route_set_metric_free (void *rule)
1156{
1157 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1158}
1159
1160/* Set metric rule structure. */
1161struct route_map_rule_cmd route_set_metric_cmd =
1162{
1163 "metric",
1164 route_set_metric,
1165 route_set_metric_compile,
1166 route_set_metric_free,
1167};
1168
1169/* `set as-path prepend ASPATH' */
1170
1171/* For AS path prepend mechanism. */
1172route_map_result_t
1173route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1174{
1175 struct aspath *aspath;
1176 struct aspath *new;
1177 struct bgp_info *binfo;
1178
1179 if (type == RMAP_BGP)
1180 {
1181 aspath = rule;
1182 binfo = object;
1183
1184 if (binfo->attr->aspath->refcnt)
1185 new = aspath_dup (binfo->attr->aspath);
1186 else
1187 new = binfo->attr->aspath;
1188
1189 aspath_prepend (aspath, new);
1190 binfo->attr->aspath = new;
1191 }
1192
1193 return RMAP_OKAY;
1194}
1195
1196/* Compile function for as-path prepend. */
1197void *
paulfd79ac92004-10-13 05:06:08 +00001198route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001199{
1200 struct aspath *aspath;
1201
1202 aspath = aspath_str2aspath (arg);
1203 if (! aspath)
1204 return NULL;
1205 return aspath;
1206}
1207
1208/* Compile function for as-path prepend. */
1209void
1210route_set_aspath_prepend_free (void *rule)
1211{
1212 struct aspath *aspath = rule;
1213 aspath_free (aspath);
1214}
1215
1216/* Set metric rule structure. */
1217struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1218{
1219 "as-path prepend",
1220 route_set_aspath_prepend,
1221 route_set_aspath_prepend_compile,
1222 route_set_aspath_prepend_free,
1223};
1224
1225/* `set community COMMUNITY' */
1226struct rmap_com_set
1227{
1228 struct community *com;
1229 int additive;
1230 int none;
1231};
1232
1233/* For community set mechanism. */
1234route_map_result_t
1235route_set_community (void *rule, struct prefix *prefix,
1236 route_map_object_t type, void *object)
1237{
1238 struct rmap_com_set *rcs;
1239 struct bgp_info *binfo;
1240 struct attr *attr;
1241 struct community *new = NULL;
1242 struct community *old;
1243 struct community *merge;
1244
1245 if (type == RMAP_BGP)
1246 {
1247 rcs = rule;
1248 binfo = object;
1249 attr = binfo->attr;
1250 old = attr->community;
1251
1252 /* "none" case. */
1253 if (rcs->none)
1254 {
1255 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1256 attr->community = NULL;
1257 return RMAP_OKAY;
1258 }
1259
1260 /* "additive" case. */
1261 if (rcs->additive && old)
1262 {
1263 merge = community_merge (community_dup (old), rcs->com);
1264 new = community_uniq_sort (merge);
1265 community_free (merge);
1266 }
1267 else
1268 new = community_dup (rcs->com);
1269
1270 attr->community = new;
1271 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1272 }
1273
1274 return RMAP_OKAY;
1275}
1276
1277/* Compile function for set community. */
1278void *
paulfd79ac92004-10-13 05:06:08 +00001279route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001280{
1281 struct rmap_com_set *rcs;
1282 struct community *com = NULL;
1283 char *sp;
1284 int additive = 0;
1285 int none = 0;
1286
1287 if (strcmp (arg, "none") == 0)
1288 none = 1;
1289 else
1290 {
1291 sp = strstr (arg, "additive");
1292
1293 if (sp && sp > arg)
1294 {
1295 /* "additive" keyworkd is included. */
1296 additive = 1;
1297 *(sp - 1) = '\0';
1298 }
1299
1300 com = community_str2com (arg);
1301
1302 if (additive)
1303 *(sp - 1) = ' ';
1304
1305 if (! com)
1306 return NULL;
1307 }
1308
1309 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1310 memset (rcs, 0, sizeof (struct rmap_com_set));
1311
1312 rcs->com = com;
1313 rcs->additive = additive;
1314 rcs->none = none;
1315
1316 return rcs;
1317}
1318
1319/* Free function for set community. */
1320void
1321route_set_community_free (void *rule)
1322{
1323 struct rmap_com_set *rcs = rule;
1324
1325 if (rcs->com)
1326 community_free (rcs->com);
1327 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1328}
1329
1330/* Set community rule structure. */
1331struct route_map_rule_cmd route_set_community_cmd =
1332{
1333 "community",
1334 route_set_community,
1335 route_set_community_compile,
1336 route_set_community_free,
1337};
1338
hassofee6e4e2005-02-02 16:29:31 +00001339/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001340
1341/* For community set mechanism. */
1342route_map_result_t
1343route_set_community_delete (void *rule, struct prefix *prefix,
1344 route_map_object_t type, void *object)
1345{
1346 struct community_list *list;
1347 struct community *merge;
1348 struct community *new;
1349 struct community *old;
1350 struct bgp_info *binfo;
1351
1352 if (type == RMAP_BGP)
1353 {
1354 if (! rule)
1355 return RMAP_OKAY;
1356
1357 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001358 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001359 old = binfo->attr->community;
1360
1361 if (list && old)
1362 {
1363 merge = community_list_match_delete (community_dup (old), list);
1364 new = community_uniq_sort (merge);
1365 community_free (merge);
1366
1367 if (new->size == 0)
1368 {
1369 binfo->attr->community = NULL;
1370 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1371 community_free (new);
1372 }
1373 else
1374 {
1375 binfo->attr->community = new;
1376 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1377 }
1378 }
1379 }
1380
1381 return RMAP_OKAY;
1382}
1383
1384/* Compile function for set community. */
1385void *
paulfd79ac92004-10-13 05:06:08 +00001386route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001387{
1388 char *p;
1389 char *str;
1390 int len;
1391
1392 p = strchr (arg, ' ');
1393 if (p)
1394 {
1395 len = p - arg;
1396 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1397 memcpy (str, arg, len);
1398 }
1399 else
1400 str = NULL;
1401
1402 return str;
1403}
1404
1405/* Free function for set community. */
1406void
1407route_set_community_delete_free (void *rule)
1408{
1409 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1410}
1411
1412/* Set community rule structure. */
1413struct route_map_rule_cmd route_set_community_delete_cmd =
1414{
1415 "comm-list",
1416 route_set_community_delete,
1417 route_set_community_delete_compile,
1418 route_set_community_delete_free,
1419};
1420
1421/* `set extcommunity rt COMMUNITY' */
1422
1423/* For community set mechanism. */
1424route_map_result_t
1425route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1426 route_map_object_t type, void *object)
1427{
1428 struct ecommunity *ecom;
1429 struct ecommunity *new_ecom;
1430 struct ecommunity *old_ecom;
1431 struct bgp_info *bgp_info;
1432
1433 if (type == RMAP_BGP)
1434 {
1435 ecom = rule;
1436 bgp_info = object;
1437
1438 if (! ecom)
1439 return RMAP_OKAY;
1440
1441 /* We assume additive for Extended Community. */
1442 old_ecom = bgp_info->attr->ecommunity;
1443
1444 if (old_ecom)
1445 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1446 else
1447 new_ecom = ecommunity_dup (ecom);
1448
1449 bgp_info->attr->ecommunity = new_ecom;
1450
1451 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1452 }
1453 return RMAP_OKAY;
1454}
1455
1456/* Compile function for set community. */
1457void *
paulfd79ac92004-10-13 05:06:08 +00001458route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001459{
1460 struct ecommunity *ecom;
1461
1462 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1463 if (! ecom)
1464 return NULL;
1465 return ecom;
1466}
1467
1468/* Free function for set community. */
1469void
1470route_set_ecommunity_rt_free (void *rule)
1471{
1472 struct ecommunity *ecom = rule;
1473 ecommunity_free (ecom);
1474}
1475
1476/* Set community rule structure. */
1477struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1478{
1479 "extcommunity rt",
1480 route_set_ecommunity_rt,
1481 route_set_ecommunity_rt_compile,
1482 route_set_ecommunity_rt_free,
1483};
1484
1485/* `set extcommunity soo COMMUNITY' */
1486
1487/* For community set mechanism. */
1488route_map_result_t
1489route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1490 route_map_object_t type, void *object)
1491{
1492 struct ecommunity *ecom;
1493 struct bgp_info *bgp_info;
1494
1495 if (type == RMAP_BGP)
1496 {
1497 ecom = rule;
1498 bgp_info = object;
1499
1500 if (! ecom)
1501 return RMAP_OKAY;
1502
1503 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1504 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1505 }
1506 return RMAP_OKAY;
1507}
1508
1509/* Compile function for set community. */
1510void *
paulfd79ac92004-10-13 05:06:08 +00001511route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001512{
1513 struct ecommunity *ecom;
1514
1515 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1516 if (! ecom)
1517 return NULL;
1518
1519 return ecom;
1520}
1521
1522/* Free function for set community. */
1523void
1524route_set_ecommunity_soo_free (void *rule)
1525{
1526 struct ecommunity *ecom = rule;
1527 ecommunity_free (ecom);
1528}
1529
1530/* Set community rule structure. */
1531struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1532{
1533 "extcommunity soo",
1534 route_set_ecommunity_soo,
1535 route_set_ecommunity_soo_compile,
1536 route_set_ecommunity_soo_free,
1537};
1538
1539/* `set origin ORIGIN' */
1540
1541/* For origin set. */
1542route_map_result_t
1543route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1544{
1545 u_char *origin;
1546 struct bgp_info *bgp_info;
1547
1548 if (type == RMAP_BGP)
1549 {
1550 origin = rule;
1551 bgp_info = object;
1552
1553 bgp_info->attr->origin = *origin;
1554 }
1555
1556 return RMAP_OKAY;
1557}
1558
1559/* Compile function for origin set. */
1560void *
paulfd79ac92004-10-13 05:06:08 +00001561route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001562{
1563 u_char *origin;
1564
1565 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1566
1567 if (strcmp (arg, "igp") == 0)
1568 *origin = 0;
1569 else if (strcmp (arg, "egp") == 0)
1570 *origin = 1;
1571 else
1572 *origin = 2;
1573
1574 return origin;
1575}
1576
1577/* Compile function for origin set. */
1578void
1579route_set_origin_free (void *rule)
1580{
1581 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1582}
1583
1584/* Set metric rule structure. */
1585struct route_map_rule_cmd route_set_origin_cmd =
1586{
1587 "origin",
1588 route_set_origin,
1589 route_set_origin_compile,
1590 route_set_origin_free,
1591};
1592
1593/* `set atomic-aggregate' */
1594
1595/* For atomic aggregate set. */
1596route_map_result_t
1597route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1598 route_map_object_t type, void *object)
1599{
1600 struct bgp_info *bgp_info;
1601
1602 if (type == RMAP_BGP)
1603 {
1604 bgp_info = object;
1605 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1606 }
1607
1608 return RMAP_OKAY;
1609}
1610
1611/* Compile function for atomic aggregate. */
1612void *
paulfd79ac92004-10-13 05:06:08 +00001613route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001614{
1615 return (void *)1;
1616}
1617
1618/* Compile function for atomic aggregate. */
1619void
1620route_set_atomic_aggregate_free (void *rule)
1621{
1622 return;
1623}
1624
1625/* Set atomic aggregate rule structure. */
1626struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1627{
1628 "atomic-aggregate",
1629 route_set_atomic_aggregate,
1630 route_set_atomic_aggregate_compile,
1631 route_set_atomic_aggregate_free,
1632};
1633
1634/* `set aggregator as AS A.B.C.D' */
1635struct aggregator
1636{
1637 as_t as;
1638 struct in_addr address;
1639};
1640
1641route_map_result_t
1642route_set_aggregator_as (void *rule, struct prefix *prefix,
1643 route_map_object_t type, void *object)
1644{
1645 struct bgp_info *bgp_info;
1646 struct aggregator *aggregator;
1647
1648 if (type == RMAP_BGP)
1649 {
1650 bgp_info = object;
1651 aggregator = rule;
1652
1653 bgp_info->attr->aggregator_as = aggregator->as;
1654 bgp_info->attr->aggregator_addr = aggregator->address;
1655 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1656 }
1657
1658 return RMAP_OKAY;
1659}
1660
1661void *
paulfd79ac92004-10-13 05:06:08 +00001662route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001663{
1664 struct aggregator *aggregator;
1665 char as[10];
1666 char address[20];
1667
1668 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1669 memset (aggregator, 0, sizeof (struct aggregator));
1670
1671 sscanf (arg, "%s %s", as, address);
1672
1673 aggregator->as = strtoul (as, NULL, 10);
1674 inet_aton (address, &aggregator->address);
1675
1676 return aggregator;
1677}
1678
1679void
1680route_set_aggregator_as_free (void *rule)
1681{
1682 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1683}
1684
1685struct route_map_rule_cmd route_set_aggregator_as_cmd =
1686{
1687 "aggregator as",
1688 route_set_aggregator_as,
1689 route_set_aggregator_as_compile,
1690 route_set_aggregator_as_free,
1691};
1692
1693#ifdef HAVE_IPV6
1694/* `match ipv6 address IP_ACCESS_LIST' */
1695
1696route_map_result_t
1697route_match_ipv6_address (void *rule, struct prefix *prefix,
1698 route_map_object_t type, void *object)
1699{
1700 struct access_list *alist;
1701
1702 if (type == RMAP_BGP)
1703 {
1704 alist = access_list_lookup (AFI_IP6, (char *) rule);
1705 if (alist == NULL)
1706 return RMAP_NOMATCH;
1707
1708 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1709 RMAP_NOMATCH : RMAP_MATCH);
1710 }
1711 return RMAP_NOMATCH;
1712}
1713
1714void *
paulfd79ac92004-10-13 05:06:08 +00001715route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001716{
1717 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1718}
1719
1720void
1721route_match_ipv6_address_free (void *rule)
1722{
1723 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1724}
1725
1726/* Route map commands for ip address matching. */
1727struct route_map_rule_cmd route_match_ipv6_address_cmd =
1728{
1729 "ipv6 address",
1730 route_match_ipv6_address,
1731 route_match_ipv6_address_compile,
1732 route_match_ipv6_address_free
1733};
1734
1735/* `match ipv6 next-hop IP_ADDRESS' */
1736
1737route_map_result_t
1738route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1739 route_map_object_t type, void *object)
1740{
1741 struct in6_addr *addr;
1742 struct bgp_info *bgp_info;
1743
1744 if (type == RMAP_BGP)
1745 {
1746 addr = rule;
1747 bgp_info = object;
1748
1749 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1750 return RMAP_MATCH;
1751
1752 if (bgp_info->attr->mp_nexthop_len == 32 &&
1753 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1754 return RMAP_MATCH;
1755
1756 return RMAP_NOMATCH;
1757 }
1758
1759 return RMAP_NOMATCH;
1760}
1761
1762void *
paulfd79ac92004-10-13 05:06:08 +00001763route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001764{
1765 struct in6_addr *address;
1766 int ret;
1767
1768 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1769
1770 ret = inet_pton (AF_INET6, arg, address);
1771 if (!ret)
1772 {
1773 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1774 return NULL;
1775 }
1776
1777 return address;
1778}
1779
1780void
1781route_match_ipv6_next_hop_free (void *rule)
1782{
1783 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1784}
1785
1786struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1787{
1788 "ipv6 next-hop",
1789 route_match_ipv6_next_hop,
1790 route_match_ipv6_next_hop_compile,
1791 route_match_ipv6_next_hop_free
1792};
1793
1794/* `match ipv6 address prefix-list PREFIX_LIST' */
1795
1796route_map_result_t
1797route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1798 route_map_object_t type, void *object)
1799{
1800 struct prefix_list *plist;
1801
1802 if (type == RMAP_BGP)
1803 {
1804 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1805 if (plist == NULL)
1806 return RMAP_NOMATCH;
1807
1808 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1809 RMAP_NOMATCH : RMAP_MATCH);
1810 }
1811 return RMAP_NOMATCH;
1812}
1813
1814void *
paulfd79ac92004-10-13 05:06:08 +00001815route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001816{
1817 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1818}
1819
1820void
1821route_match_ipv6_address_prefix_list_free (void *rule)
1822{
1823 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1824}
1825
1826struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1827{
1828 "ipv6 address prefix-list",
1829 route_match_ipv6_address_prefix_list,
1830 route_match_ipv6_address_prefix_list_compile,
1831 route_match_ipv6_address_prefix_list_free
1832};
1833
1834/* `set ipv6 nexthop global IP_ADDRESS' */
1835
1836/* Set nexthop to object. ojbect must be pointer to struct attr. */
1837route_map_result_t
1838route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1839 route_map_object_t type, void *object)
1840{
1841 struct in6_addr *address;
1842 struct bgp_info *bgp_info;
1843
1844 if (type == RMAP_BGP)
1845 {
1846 /* Fetch routemap's rule information. */
1847 address = rule;
1848 bgp_info = object;
1849
1850 /* Set next hop value. */
1851 bgp_info->attr->mp_nexthop_global = *address;
1852
1853 /* Set nexthop length. */
1854 if (bgp_info->attr->mp_nexthop_len == 0)
1855 bgp_info->attr->mp_nexthop_len = 16;
1856 }
1857
1858 return RMAP_OKAY;
1859}
1860
1861/* Route map `ip next-hop' compile function. Given string is converted
1862 to struct in_addr structure. */
1863void *
paulfd79ac92004-10-13 05:06:08 +00001864route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001865{
1866 int ret;
1867 struct in6_addr *address;
1868
1869 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1870
1871 ret = inet_pton (AF_INET6, arg, address);
1872
1873 if (ret == 0)
1874 {
1875 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1876 return NULL;
1877 }
1878
1879 return address;
1880}
1881
1882/* Free route map's compiled `ip next-hop' value. */
1883void
1884route_set_ipv6_nexthop_global_free (void *rule)
1885{
1886 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1887}
1888
1889/* Route map commands for ip nexthop set. */
1890struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1891{
1892 "ipv6 next-hop global",
1893 route_set_ipv6_nexthop_global,
1894 route_set_ipv6_nexthop_global_compile,
1895 route_set_ipv6_nexthop_global_free
1896};
1897
1898/* `set ipv6 nexthop local IP_ADDRESS' */
1899
1900/* Set nexthop to object. ojbect must be pointer to struct attr. */
1901route_map_result_t
1902route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1903 route_map_object_t type, void *object)
1904{
1905 struct in6_addr *address;
1906 struct bgp_info *bgp_info;
1907
1908 if (type == RMAP_BGP)
1909 {
1910 /* Fetch routemap's rule information. */
1911 address = rule;
1912 bgp_info = object;
1913
1914 /* Set next hop value. */
1915 bgp_info->attr->mp_nexthop_local = *address;
1916
1917 /* Set nexthop length. */
1918 if (bgp_info->attr->mp_nexthop_len != 32)
1919 bgp_info->attr->mp_nexthop_len = 32;
1920 }
1921
1922 return RMAP_OKAY;
1923}
1924
1925/* Route map `ip nexthop' compile function. Given string is converted
1926 to struct in_addr structure. */
1927void *
paulfd79ac92004-10-13 05:06:08 +00001928route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001929{
1930 int ret;
1931 struct in6_addr *address;
1932
1933 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1934
1935 ret = inet_pton (AF_INET6, arg, address);
1936
1937 if (ret == 0)
1938 {
1939 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1940 return NULL;
1941 }
1942
1943 return address;
1944}
1945
1946/* Free route map's compiled `ip nexthop' value. */
1947void
1948route_set_ipv6_nexthop_local_free (void *rule)
1949{
1950 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1951}
1952
1953/* Route map commands for ip nexthop set. */
1954struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1955{
1956 "ipv6 next-hop local",
1957 route_set_ipv6_nexthop_local,
1958 route_set_ipv6_nexthop_local_compile,
1959 route_set_ipv6_nexthop_local_free
1960};
1961#endif /* HAVE_IPV6 */
1962
1963/* `set vpnv4 nexthop A.B.C.D' */
1964
1965route_map_result_t
1966route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1967 route_map_object_t type, void *object)
1968{
1969 struct in_addr *address;
1970 struct bgp_info *bgp_info;
1971
1972 if (type == RMAP_BGP)
1973 {
1974 /* Fetch routemap's rule information. */
1975 address = rule;
1976 bgp_info = object;
1977
1978 /* Set next hop value. */
1979 bgp_info->attr->mp_nexthop_global_in = *address;
1980 }
1981
1982 return RMAP_OKAY;
1983}
1984
1985void *
paulfd79ac92004-10-13 05:06:08 +00001986route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001987{
1988 int ret;
1989 struct in_addr *address;
1990
1991 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1992
1993 ret = inet_aton (arg, address);
1994
1995 if (ret == 0)
1996 {
1997 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1998 return NULL;
1999 }
2000
2001 return address;
2002}
2003
2004void
2005route_set_vpnv4_nexthop_free (void *rule)
2006{
2007 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2008}
2009
2010/* Route map commands for ip nexthop set. */
2011struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2012{
2013 "vpnv4 next-hop",
2014 route_set_vpnv4_nexthop,
2015 route_set_vpnv4_nexthop_compile,
2016 route_set_vpnv4_nexthop_free
2017};
2018
2019/* `set originator-id' */
2020
2021/* For origin set. */
2022route_map_result_t
2023route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2024{
2025 struct in_addr *address;
2026 struct bgp_info *bgp_info;
2027
2028 if (type == RMAP_BGP)
2029 {
2030 address = rule;
2031 bgp_info = object;
2032
2033 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
2034 bgp_info->attr->originator_id = *address;
2035 }
2036
2037 return RMAP_OKAY;
2038}
2039
2040/* Compile function for originator-id set. */
2041void *
paulfd79ac92004-10-13 05:06:08 +00002042route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002043{
2044 int ret;
2045 struct in_addr *address;
2046
2047 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2048
2049 ret = inet_aton (arg, address);
2050
2051 if (ret == 0)
2052 {
2053 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2054 return NULL;
2055 }
2056
2057 return address;
2058}
2059
2060/* Compile function for originator_id set. */
2061void
2062route_set_originator_id_free (void *rule)
2063{
2064 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2065}
2066
2067/* Set metric rule structure. */
2068struct route_map_rule_cmd route_set_originator_id_cmd =
2069{
2070 "originator-id",
2071 route_set_originator_id,
2072 route_set_originator_id_compile,
2073 route_set_originator_id_free,
2074};
2075
2076/* Add bgp route map rule. */
2077int
2078bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002079 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002080{
2081 int ret;
2082
2083 ret = route_map_add_match (index, command, arg);
2084 if (ret)
2085 {
2086 switch (ret)
2087 {
2088 case RMAP_RULE_MISSING:
2089 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2090 return CMD_WARNING;
2091 break;
2092 case RMAP_COMPILE_ERROR:
2093 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2094 return CMD_WARNING;
2095 break;
2096 }
2097 }
2098 return CMD_SUCCESS;
2099}
2100
2101/* Delete bgp route map rule. */
2102int
2103bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002104 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002105{
2106 int ret;
2107
2108 ret = route_map_delete_match (index, command, arg);
2109 if (ret)
2110 {
2111 switch (ret)
2112 {
2113 case RMAP_RULE_MISSING:
2114 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2115 return CMD_WARNING;
2116 break;
2117 case RMAP_COMPILE_ERROR:
2118 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2119 return CMD_WARNING;
2120 break;
2121 }
2122 }
2123 return CMD_SUCCESS;
2124}
2125
2126/* Add bgp route map rule. */
2127int
2128bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002129 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002130{
2131 int ret;
2132
2133 ret = route_map_add_set (index, command, arg);
2134 if (ret)
2135 {
2136 switch (ret)
2137 {
2138 case RMAP_RULE_MISSING:
2139 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2140 return CMD_WARNING;
2141 break;
2142 case RMAP_COMPILE_ERROR:
2143 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2144 return CMD_WARNING;
2145 break;
2146 }
2147 }
2148 return CMD_SUCCESS;
2149}
2150
2151/* Delete bgp route map rule. */
2152int
2153bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002154 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002155{
2156 int ret;
2157
2158 ret = route_map_delete_set (index, command, arg);
2159 if (ret)
2160 {
2161 switch (ret)
2162 {
2163 case RMAP_RULE_MISSING:
2164 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2165 return CMD_WARNING;
2166 break;
2167 case RMAP_COMPILE_ERROR:
2168 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2169 return CMD_WARNING;
2170 break;
2171 }
2172 }
2173 return CMD_SUCCESS;
2174}
2175
2176/* Hook function for updating route_map assignment. */
2177void
paulfd79ac92004-10-13 05:06:08 +00002178bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002179{
2180 int i;
2181 afi_t afi;
2182 safi_t safi;
2183 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002184 struct listnode *node, *nnode;
2185 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002186 struct bgp *bgp;
2187 struct peer *peer;
2188 struct peer_group *group;
2189 struct bgp_filter *filter;
2190 struct bgp_node *bn;
2191 struct bgp_static *bgp_static;
2192
2193 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002194 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002195 {
paul1eb8ef22005-04-07 07:30:20 +00002196 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002197 {
2198 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2199 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2200 {
2201 filter = &peer->filter[afi][safi];
2202
paulfee0f4c2004-09-13 05:12:46 +00002203 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002204 {
2205 if (filter->map[direct].name)
2206 filter->map[direct].map =
2207 route_map_lookup_by_name (filter->map[direct].name);
2208 else
2209 filter->map[direct].map = NULL;
2210 }
2211
2212 if (filter->usmap.name)
2213 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2214 else
2215 filter->usmap.map = NULL;
2216 }
2217 }
paul1eb8ef22005-04-07 07:30:20 +00002218 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002219 {
2220 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2221 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2222 {
2223 filter = &group->conf->filter[afi][safi];
2224
paulfee0f4c2004-09-13 05:12:46 +00002225 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002226 {
2227 if (filter->map[direct].name)
2228 filter->map[direct].map =
2229 route_map_lookup_by_name (filter->map[direct].name);
2230 else
2231 filter->map[direct].map = NULL;
2232 }
2233
2234 if (filter->usmap.name)
2235 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2236 else
2237 filter->usmap.map = NULL;
2238 }
2239 }
2240 }
2241
2242 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002243 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002244 {
paul1eb8ef22005-04-07 07:30:20 +00002245 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002246 {
2247 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2248 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2249 {
2250 if (peer->default_rmap[afi][safi].name)
2251 peer->default_rmap[afi][safi].map =
2252 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2253 else
2254 peer->default_rmap[afi][safi].map = NULL;
2255 }
2256 }
2257 }
2258
2259 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002260 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002261 {
2262 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2263 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2264 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2265 bn = bgp_route_next (bn))
2266 if ((bgp_static = bn->info) != NULL)
2267 {
2268 if (bgp_static->rmap.name)
2269 bgp_static->rmap.map =
2270 route_map_lookup_by_name (bgp_static->rmap.name);
2271 else
2272 bgp_static->rmap.map = NULL;
2273 }
2274 }
2275
2276 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002277 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002278 {
2279 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2280 {
2281 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2282 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2283 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2284#ifdef HAVE_IPV6
2285 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2286 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2287 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2288#endif /* HAVE_IPV6 */
2289 }
2290 }
2291}
2292
paulfee0f4c2004-09-13 05:12:46 +00002293DEFUN (match_peer,
2294 match_peer_cmd,
2295 "match peer (A.B.C.D|X:X::X:X)",
2296 MATCH_STR
2297 "Match peer address\n"
2298 "IPv6 address of peer\n"
2299 "IP address of peer\n")
2300{
2301 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2302}
2303
2304DEFUN (match_peer_local,
2305 match_peer_local_cmd,
2306 "match peer local",
2307 MATCH_STR
2308 "Match peer address\n"
2309 "Static or Redistributed routes\n")
2310{
2311 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2312}
2313
2314DEFUN (no_match_peer,
2315 no_match_peer_cmd,
2316 "no match peer",
2317 NO_STR
2318 MATCH_STR
2319 "Match peer address\n")
2320{
2321 if (argc == 0)
2322 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2323
2324 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2325}
2326
2327ALIAS (no_match_peer,
2328 no_match_peer_val_cmd,
2329 "no match peer (A.B.C.D|X:X::X:X)",
2330 NO_STR
2331 MATCH_STR
2332 "Match peer address\n"
2333 "IPv6 address of peer\n"
2334 "IP address of peer\n")
2335
2336ALIAS (no_match_peer,
2337 no_match_peer_local_cmd,
2338 "no match peer local",
2339 NO_STR
2340 MATCH_STR
2341 "Match peer address\n"
2342 "Static or Redistributed routes\n")
2343
paul718e3742002-12-13 20:15:29 +00002344DEFUN (match_ip_address,
2345 match_ip_address_cmd,
2346 "match ip address (<1-199>|<1300-2699>|WORD)",
2347 MATCH_STR
2348 IP_STR
2349 "Match address of route\n"
2350 "IP access-list number\n"
2351 "IP access-list number (expanded range)\n"
2352 "IP Access-list name\n")
2353{
2354 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2355}
2356
2357DEFUN (no_match_ip_address,
2358 no_match_ip_address_cmd,
2359 "no match ip address",
2360 NO_STR
2361 MATCH_STR
2362 IP_STR
2363 "Match address of route\n")
2364{
2365 if (argc == 0)
2366 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2367
2368 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2369}
2370
2371ALIAS (no_match_ip_address,
2372 no_match_ip_address_val_cmd,
2373 "no match ip address (<1-199>|<1300-2699>|WORD)",
2374 NO_STR
2375 MATCH_STR
2376 IP_STR
2377 "Match address of route\n"
2378 "IP access-list number\n"
2379 "IP access-list number (expanded range)\n"
2380 "IP Access-list name\n")
2381
2382DEFUN (match_ip_next_hop,
2383 match_ip_next_hop_cmd,
2384 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2385 MATCH_STR
2386 IP_STR
2387 "Match next-hop address of route\n"
2388 "IP access-list number\n"
2389 "IP access-list number (expanded range)\n"
2390 "IP Access-list name\n")
2391{
2392 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2393}
2394
2395DEFUN (no_match_ip_next_hop,
2396 no_match_ip_next_hop_cmd,
2397 "no match ip next-hop",
2398 NO_STR
2399 MATCH_STR
2400 IP_STR
2401 "Match next-hop address of route\n")
2402{
2403 if (argc == 0)
2404 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2405
2406 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2407}
2408
2409ALIAS (no_match_ip_next_hop,
2410 no_match_ip_next_hop_val_cmd,
2411 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2412 NO_STR
2413 MATCH_STR
2414 IP_STR
2415 "Match next-hop address of route\n"
2416 "IP access-list number\n"
2417 "IP access-list number (expanded range)\n"
2418 "IP Access-list name\n")
2419
hassoc1643bb2005-02-02 16:43:17 +00002420DEFUN (match_ip_route_source,
2421 match_ip_route_source_cmd,
2422 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2423 MATCH_STR
2424 IP_STR
2425 "Match advertising source address of route\n"
2426 "IP access-list number\n"
2427 "IP access-list number (expanded range)\n"
2428 "IP standard access-list name\n")
2429{
2430 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2431}
2432
2433DEFUN (no_match_ip_route_source,
2434 no_match_ip_route_source_cmd,
2435 "no match ip route-source",
2436 NO_STR
2437 MATCH_STR
2438 IP_STR
2439 "Match advertising source address of route\n")
2440{
2441 if (argc == 0)
2442 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2443
2444 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2445}
2446
2447ALIAS (no_match_ip_route_source,
2448 no_match_ip_route_source_val_cmd,
2449 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2450 NO_STR
2451 MATCH_STR
2452 IP_STR
2453 "Match advertising source address of route\n"
2454 "IP access-list number\n"
2455 "IP access-list number (expanded range)\n"
2456 "IP standard access-list name\n");
2457
paul718e3742002-12-13 20:15:29 +00002458DEFUN (match_ip_address_prefix_list,
2459 match_ip_address_prefix_list_cmd,
2460 "match ip address prefix-list WORD",
2461 MATCH_STR
2462 IP_STR
2463 "Match address of route\n"
2464 "Match entries of prefix-lists\n"
2465 "IP prefix-list name\n")
2466{
2467 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2468}
2469
2470DEFUN (no_match_ip_address_prefix_list,
2471 no_match_ip_address_prefix_list_cmd,
2472 "no match ip address prefix-list",
2473 NO_STR
2474 MATCH_STR
2475 IP_STR
2476 "Match address of route\n"
2477 "Match entries of prefix-lists\n")
2478{
2479 if (argc == 0)
2480 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2481
2482 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2483}
2484
2485ALIAS (no_match_ip_address_prefix_list,
2486 no_match_ip_address_prefix_list_val_cmd,
2487 "no match ip address prefix-list WORD",
2488 NO_STR
2489 MATCH_STR
2490 IP_STR
2491 "Match address of route\n"
2492 "Match entries of prefix-lists\n"
2493 "IP prefix-list name\n")
2494
2495DEFUN (match_ip_next_hop_prefix_list,
2496 match_ip_next_hop_prefix_list_cmd,
2497 "match ip next-hop prefix-list WORD",
2498 MATCH_STR
2499 IP_STR
2500 "Match next-hop address of route\n"
2501 "Match entries of prefix-lists\n"
2502 "IP prefix-list name\n")
2503{
2504 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2505}
2506
2507DEFUN (no_match_ip_next_hop_prefix_list,
2508 no_match_ip_next_hop_prefix_list_cmd,
2509 "no match ip next-hop prefix-list",
2510 NO_STR
2511 MATCH_STR
2512 IP_STR
2513 "Match next-hop address of route\n"
2514 "Match entries of prefix-lists\n")
2515{
2516 if (argc == 0)
2517 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2518
2519 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2520}
2521
2522ALIAS (no_match_ip_next_hop_prefix_list,
2523 no_match_ip_next_hop_prefix_list_val_cmd,
2524 "no match ip next-hop prefix-list WORD",
2525 NO_STR
2526 MATCH_STR
2527 IP_STR
2528 "Match next-hop address of route\n"
2529 "Match entries of prefix-lists\n"
2530 "IP prefix-list name\n")
2531
hassoc1643bb2005-02-02 16:43:17 +00002532DEFUN (match_ip_route_source_prefix_list,
2533 match_ip_route_source_prefix_list_cmd,
2534 "match ip route-source prefix-list WORD",
2535 MATCH_STR
2536 IP_STR
2537 "Match advertising source address of route\n"
2538 "Match entries of prefix-lists\n"
2539 "IP prefix-list name\n")
2540{
2541 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2542}
2543
2544DEFUN (no_match_ip_route_source_prefix_list,
2545 no_match_ip_route_source_prefix_list_cmd,
2546 "no match ip route-source prefix-list",
2547 NO_STR
2548 MATCH_STR
2549 IP_STR
2550 "Match advertising source address of route\n"
2551 "Match entries of prefix-lists\n")
2552{
2553 if (argc == 0)
2554 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2555
2556 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2557}
2558
2559ALIAS (no_match_ip_route_source_prefix_list,
2560 no_match_ip_route_source_prefix_list_val_cmd,
2561 "no match ip route-source prefix-list WORD",
2562 NO_STR
2563 MATCH_STR
2564 IP_STR
2565 "Match advertising source address of route\n"
2566 "Match entries of prefix-lists\n"
2567 "IP prefix-list name\n");
2568
paul718e3742002-12-13 20:15:29 +00002569DEFUN (match_metric,
2570 match_metric_cmd,
2571 "match metric <0-4294967295>",
2572 MATCH_STR
2573 "Match metric of route\n"
2574 "Metric value\n")
2575{
2576 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2577}
2578
2579DEFUN (no_match_metric,
2580 no_match_metric_cmd,
2581 "no match metric",
2582 NO_STR
2583 MATCH_STR
2584 "Match metric of route\n")
2585{
2586 if (argc == 0)
2587 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2588
2589 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2590}
2591
2592ALIAS (no_match_metric,
2593 no_match_metric_val_cmd,
2594 "no match metric <0-4294967295>",
2595 NO_STR
2596 MATCH_STR
2597 "Match metric of route\n"
2598 "Metric value\n")
2599
2600DEFUN (match_community,
2601 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002602 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002603 MATCH_STR
2604 "Match BGP community list\n"
2605 "Community-list number (standard)\n"
2606 "Community-list number (expanded)\n"
2607 "Community-list name\n")
2608{
2609 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2610}
2611
2612DEFUN (match_community_exact,
2613 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002614 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002615 MATCH_STR
2616 "Match BGP community list\n"
2617 "Community-list number (standard)\n"
2618 "Community-list number (expanded)\n"
2619 "Community-list name\n"
2620 "Do exact matching of communities\n")
2621{
2622 int ret;
2623 char *argstr;
2624
2625 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2626 strlen (argv[0]) + strlen ("exact-match") + 2);
2627
2628 sprintf (argstr, "%s exact-match", argv[0]);
2629
2630 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2631
2632 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2633
2634 return ret;
2635}
2636
2637DEFUN (no_match_community,
2638 no_match_community_cmd,
2639 "no match community",
2640 NO_STR
2641 MATCH_STR
2642 "Match BGP community list\n")
2643{
2644 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2645}
2646
2647ALIAS (no_match_community,
2648 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002649 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002650 NO_STR
2651 MATCH_STR
2652 "Match BGP community list\n"
2653 "Community-list number (standard)\n"
2654 "Community-list number (expanded)\n"
2655 "Community-list name\n")
2656
2657ALIAS (no_match_community,
2658 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002659 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002660 NO_STR
2661 MATCH_STR
2662 "Match BGP community list\n"
2663 "Community-list number (standard)\n"
2664 "Community-list number (expanded)\n"
2665 "Community-list name\n"
2666 "Do exact matching of communities\n")
2667
paul73ffb252003-04-19 15:49:49 +00002668DEFUN (match_ecommunity,
2669 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002670 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002671 MATCH_STR
2672 "Match BGP/VPN extended community list\n"
2673 "Extended community-list number (standard)\n"
2674 "Extended community-list number (expanded)\n"
2675 "Extended community-list name\n")
2676{
2677 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2678}
2679
2680DEFUN (no_match_ecommunity,
2681 no_match_ecommunity_cmd,
2682 "no match extcommunity",
2683 NO_STR
2684 MATCH_STR
2685 "Match BGP/VPN extended community list\n")
2686{
2687 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2688}
2689
2690ALIAS (no_match_ecommunity,
2691 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002692 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002693 NO_STR
2694 MATCH_STR
2695 "Match BGP/VPN extended community list\n"
2696 "Extended community-list number (standard)\n"
2697 "Extended community-list number (expanded)\n"
2698 "Extended community-list name\n")
2699
paul718e3742002-12-13 20:15:29 +00002700DEFUN (match_aspath,
2701 match_aspath_cmd,
2702 "match as-path WORD",
2703 MATCH_STR
2704 "Match BGP AS path list\n"
2705 "AS path access-list name\n")
2706{
2707 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2708}
2709
2710DEFUN (no_match_aspath,
2711 no_match_aspath_cmd,
2712 "no match as-path",
2713 NO_STR
2714 MATCH_STR
2715 "Match BGP AS path list\n")
2716{
2717 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2718}
2719
2720ALIAS (no_match_aspath,
2721 no_match_aspath_val_cmd,
2722 "no match as-path WORD",
2723 NO_STR
2724 MATCH_STR
2725 "Match BGP AS path list\n"
2726 "AS path access-list name\n")
2727
2728DEFUN (match_origin,
2729 match_origin_cmd,
2730 "match origin (egp|igp|incomplete)",
2731 MATCH_STR
2732 "BGP origin code\n"
2733 "remote EGP\n"
2734 "local IGP\n"
2735 "unknown heritage\n")
2736{
2737 if (strncmp (argv[0], "igp", 2) == 0)
2738 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2739 if (strncmp (argv[0], "egp", 1) == 0)
2740 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2741 if (strncmp (argv[0], "incomplete", 2) == 0)
2742 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2743
2744 return CMD_WARNING;
2745}
2746
2747DEFUN (no_match_origin,
2748 no_match_origin_cmd,
2749 "no match origin",
2750 NO_STR
2751 MATCH_STR
2752 "BGP origin code\n")
2753{
2754 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2755}
2756
2757ALIAS (no_match_origin,
2758 no_match_origin_val_cmd,
2759 "no match origin (egp|igp|incomplete)",
2760 NO_STR
2761 MATCH_STR
2762 "BGP origin code\n"
2763 "remote EGP\n"
2764 "local IGP\n"
2765 "unknown heritage\n")
2766
2767DEFUN (set_ip_nexthop,
2768 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002769 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002770 SET_STR
2771 IP_STR
2772 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002773 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002774{
2775 union sockunion su;
2776 int ret;
2777
2778 ret = str2sockunion (argv[0], &su);
2779 if (ret < 0)
2780 {
2781 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2782 return CMD_WARNING;
2783 }
2784
2785 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2786}
2787
paulaf5cd0a2003-11-02 07:24:40 +00002788DEFUN (set_ip_nexthop_peer,
2789 set_ip_nexthop_peer_cmd,
2790 "set ip next-hop peer-address",
2791 SET_STR
2792 IP_STR
2793 "Next hop address\n"
2794 "Use peer address (for BGP only)\n")
2795{
2796 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2797}
2798
2799DEFUN (no_set_ip_nexthop_peer,
2800 no_set_ip_nexthop_peer_cmd,
2801 "no set ip next-hop peer-address",
2802 NO_STR
2803 SET_STR
2804 IP_STR
2805 "Next hop address\n"
2806 "Use peer address (for BGP only)\n")
2807{
2808 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2809}
2810
2811
paul718e3742002-12-13 20:15:29 +00002812DEFUN (no_set_ip_nexthop,
2813 no_set_ip_nexthop_cmd,
2814 "no set ip next-hop",
2815 NO_STR
2816 SET_STR
paul718e3742002-12-13 20:15:29 +00002817 "Next hop address\n")
2818{
paulaf5cd0a2003-11-02 07:24:40 +00002819 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002820 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2821
2822 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2823}
2824
2825ALIAS (no_set_ip_nexthop,
2826 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002827 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002828 NO_STR
2829 SET_STR
2830 IP_STR
2831 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002832 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002833
2834DEFUN (set_metric,
2835 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002836 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002837 SET_STR
2838 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002839 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002840{
2841 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2842}
2843
paul73ffb252003-04-19 15:49:49 +00002844ALIAS (set_metric,
2845 set_metric_addsub_cmd,
2846 "set metric <+/-metric>",
2847 SET_STR
2848 "Metric value for destination routing protocol\n"
2849 "Add or subtract BGP metric\n")
2850
paul718e3742002-12-13 20:15:29 +00002851DEFUN (no_set_metric,
2852 no_set_metric_cmd,
2853 "no set metric",
2854 NO_STR
2855 SET_STR
2856 "Metric value for destination routing protocol\n")
2857{
2858 if (argc == 0)
2859 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2860
2861 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2862}
2863
2864ALIAS (no_set_metric,
2865 no_set_metric_val_cmd,
2866 "no set metric <0-4294967295>",
2867 NO_STR
2868 SET_STR
2869 "Metric value for destination routing protocol\n"
2870 "Metric value\n")
2871
2872DEFUN (set_local_pref,
2873 set_local_pref_cmd,
2874 "set local-preference <0-4294967295>",
2875 SET_STR
2876 "BGP local preference path attribute\n"
2877 "Preference value\n")
2878{
2879 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2880}
2881
2882DEFUN (no_set_local_pref,
2883 no_set_local_pref_cmd,
2884 "no set local-preference",
2885 NO_STR
2886 SET_STR
2887 "BGP local preference path attribute\n")
2888{
2889 if (argc == 0)
2890 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2891
2892 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2893}
2894
2895ALIAS (no_set_local_pref,
2896 no_set_local_pref_val_cmd,
2897 "no set local-preference <0-4294967295>",
2898 NO_STR
2899 SET_STR
2900 "BGP local preference path attribute\n"
2901 "Preference value\n")
2902
2903DEFUN (set_weight,
2904 set_weight_cmd,
2905 "set weight <0-4294967295>",
2906 SET_STR
2907 "BGP weight for routing table\n"
2908 "Weight value\n")
2909{
2910 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2911}
2912
2913DEFUN (no_set_weight,
2914 no_set_weight_cmd,
2915 "no set weight",
2916 NO_STR
2917 SET_STR
2918 "BGP weight for routing table\n")
2919{
2920 if (argc == 0)
2921 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2922
2923 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2924}
2925
2926ALIAS (no_set_weight,
2927 no_set_weight_val_cmd,
2928 "no set weight <0-4294967295>",
2929 NO_STR
2930 SET_STR
2931 "BGP weight for routing table\n"
2932 "Weight value\n")
2933
2934DEFUN (set_aspath_prepend,
2935 set_aspath_prepend_cmd,
2936 "set as-path prepend .<1-65535>",
2937 SET_STR
2938 "Prepend string for a BGP AS-path attribute\n"
2939 "Prepend to the as-path\n"
2940 "AS number\n")
2941{
2942 int ret;
2943 char *str;
2944
2945 str = argv_concat (argv, argc, 0);
2946 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2947 XFREE (MTYPE_TMP, str);
2948
2949 return ret;
2950}
2951
2952DEFUN (no_set_aspath_prepend,
2953 no_set_aspath_prepend_cmd,
2954 "no set as-path prepend",
2955 NO_STR
2956 SET_STR
2957 "Prepend string for a BGP AS-path attribute\n"
2958 "Prepend to the as-path\n")
2959{
2960 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2961}
2962
2963ALIAS (no_set_aspath_prepend,
2964 no_set_aspath_prepend_val_cmd,
2965 "no set as-path prepend .<1-65535>",
2966 NO_STR
2967 SET_STR
2968 "Prepend string for a BGP AS-path attribute\n"
2969 "Prepend to the as-path\n"
2970 "AS number\n")
2971
2972DEFUN (set_community,
2973 set_community_cmd,
2974 "set community .AA:NN",
2975 SET_STR
2976 "BGP community attribute\n"
2977 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2978{
2979 int i;
2980 int first = 0;
2981 int additive = 0;
2982 struct buffer *b;
2983 struct community *com = NULL;
2984 char *str;
2985 char *argstr;
2986 int ret;
2987
2988 b = buffer_new (1024);
2989
2990 for (i = 0; i < argc; i++)
2991 {
2992 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2993 {
2994 additive = 1;
2995 continue;
2996 }
2997
2998 if (first)
2999 buffer_putc (b, ' ');
3000 else
3001 first = 1;
3002
3003 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3004 {
3005 buffer_putstr (b, "internet");
3006 continue;
3007 }
3008 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3009 {
3010 buffer_putstr (b, "local-AS");
3011 continue;
3012 }
3013 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3014 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3015 {
3016 buffer_putstr (b, "no-advertise");
3017 continue;
3018 }
3019 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3020 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3021 {
3022 buffer_putstr (b, "no-export");
3023 continue;
3024 }
3025 buffer_putstr (b, argv[i]);
3026 }
3027 buffer_putc (b, '\0');
3028
3029 /* Fetch result string then compile it to communities attribute. */
3030 str = buffer_getstr (b);
3031 buffer_free (b);
3032
3033 if (str)
3034 {
3035 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003036 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003037 }
3038
3039 /* Can't compile user input into communities attribute. */
3040 if (! com)
3041 {
3042 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3043 return CMD_WARNING;
3044 }
3045
3046 /* Set communites attribute string. */
3047 str = community_str (com);
3048
3049 if (additive)
3050 {
3051 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3052 strcpy (argstr, str);
3053 strcpy (argstr + strlen (str), " additive");
3054 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3055 XFREE (MTYPE_TMP, argstr);
3056 }
3057 else
3058 ret = bgp_route_set_add (vty, vty->index, "community", str);
3059
3060 community_free (com);
3061
3062 return ret;
3063}
3064
3065DEFUN (set_community_none,
3066 set_community_none_cmd,
3067 "set community none",
3068 SET_STR
3069 "BGP community attribute\n"
3070 "No community attribute\n")
3071{
3072 return bgp_route_set_add (vty, vty->index, "community", "none");
3073}
3074
3075DEFUN (no_set_community,
3076 no_set_community_cmd,
3077 "no set community",
3078 NO_STR
3079 SET_STR
3080 "BGP community attribute\n")
3081{
3082 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3083}
3084
3085ALIAS (no_set_community,
3086 no_set_community_val_cmd,
3087 "no set community .AA:NN",
3088 NO_STR
3089 SET_STR
3090 "BGP community attribute\n"
3091 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3092
3093ALIAS (no_set_community,
3094 no_set_community_none_cmd,
3095 "no set community none",
3096 NO_STR
3097 SET_STR
3098 "BGP community attribute\n"
3099 "No community attribute\n")
3100
3101DEFUN (set_community_delete,
3102 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003103 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003104 SET_STR
3105 "set BGP community list (for deletion)\n"
3106 "Community-list number (standard)\n"
3107 "Communitly-list number (expanded)\n"
3108 "Community-list name\n"
3109 "Delete matching communities\n")
3110{
3111 char *str;
3112
3113 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3114 strcpy (str, argv[0]);
3115 strcpy (str + strlen (argv[0]), " delete");
3116
3117 bgp_route_set_add (vty, vty->index, "comm-list", str);
3118
3119 XFREE (MTYPE_TMP, str);
3120 return CMD_SUCCESS;
3121}
3122
3123DEFUN (no_set_community_delete,
3124 no_set_community_delete_cmd,
3125 "no set comm-list",
3126 NO_STR
3127 SET_STR
3128 "set BGP community list (for deletion)\n")
3129{
3130 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3131}
3132
3133ALIAS (no_set_community_delete,
3134 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003135 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003136 NO_STR
3137 SET_STR
3138 "set BGP community list (for deletion)\n"
3139 "Community-list number (standard)\n"
3140 "Communitly-list number (expanded)\n"
3141 "Community-list name\n"
3142 "Delete matching communities\n")
3143
3144DEFUN (set_ecommunity_rt,
3145 set_ecommunity_rt_cmd,
3146 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3147 SET_STR
3148 "BGP extended community attribute\n"
3149 "Route Target extened communityt\n"
3150 "VPN extended community\n")
3151{
3152 int ret;
3153 char *str;
3154
3155 str = argv_concat (argv, argc, 0);
3156 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3157 XFREE (MTYPE_TMP, str);
3158
3159 return ret;
3160}
3161
3162DEFUN (no_set_ecommunity_rt,
3163 no_set_ecommunity_rt_cmd,
3164 "no set extcommunity rt",
3165 NO_STR
3166 SET_STR
3167 "BGP extended community attribute\n"
3168 "Route Target extened communityt\n")
3169{
3170 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3171}
3172
3173ALIAS (no_set_ecommunity_rt,
3174 no_set_ecommunity_rt_val_cmd,
3175 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3176 NO_STR
3177 SET_STR
3178 "BGP extended community attribute\n"
3179 "Route Target extened communityt\n"
3180 "VPN extended community\n")
3181
3182DEFUN (set_ecommunity_soo,
3183 set_ecommunity_soo_cmd,
3184 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3185 SET_STR
3186 "BGP extended community attribute\n"
3187 "Site-of-Origin extended community\n"
3188 "VPN extended community\n")
3189{
3190 int ret;
3191 char *str;
3192
3193 str = argv_concat (argv, argc, 0);
3194 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3195 XFREE (MTYPE_TMP, str);
3196 return ret;
3197}
3198
3199DEFUN (no_set_ecommunity_soo,
3200 no_set_ecommunity_soo_cmd,
3201 "no set extcommunity soo",
3202 NO_STR
3203 SET_STR
3204 "BGP extended community attribute\n"
3205 "Site-of-Origin extended community\n")
3206{
3207 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3208}
3209
3210ALIAS (no_set_ecommunity_soo,
3211 no_set_ecommunity_soo_val_cmd,
3212 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3213 NO_STR
3214 SET_STR
3215 "BGP extended community attribute\n"
3216 "Site-of-Origin extended community\n"
3217 "VPN extended community\n")
3218
3219DEFUN (set_origin,
3220 set_origin_cmd,
3221 "set origin (egp|igp|incomplete)",
3222 SET_STR
3223 "BGP origin code\n"
3224 "remote EGP\n"
3225 "local IGP\n"
3226 "unknown heritage\n")
3227{
3228 if (strncmp (argv[0], "igp", 2) == 0)
3229 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3230 if (strncmp (argv[0], "egp", 1) == 0)
3231 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3232 if (strncmp (argv[0], "incomplete", 2) == 0)
3233 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3234
3235 return CMD_WARNING;
3236}
3237
3238DEFUN (no_set_origin,
3239 no_set_origin_cmd,
3240 "no set origin",
3241 NO_STR
3242 SET_STR
3243 "BGP origin code\n")
3244{
3245 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3246}
3247
3248ALIAS (no_set_origin,
3249 no_set_origin_val_cmd,
3250 "no set origin (egp|igp|incomplete)",
3251 NO_STR
3252 SET_STR
3253 "BGP origin code\n"
3254 "remote EGP\n"
3255 "local IGP\n"
3256 "unknown heritage\n")
3257
3258DEFUN (set_atomic_aggregate,
3259 set_atomic_aggregate_cmd,
3260 "set atomic-aggregate",
3261 SET_STR
3262 "BGP atomic aggregate attribute\n" )
3263{
3264 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3265}
3266
3267DEFUN (no_set_atomic_aggregate,
3268 no_set_atomic_aggregate_cmd,
3269 "no set atomic-aggregate",
3270 NO_STR
3271 SET_STR
3272 "BGP atomic aggregate attribute\n" )
3273{
3274 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3275}
3276
3277DEFUN (set_aggregator_as,
3278 set_aggregator_as_cmd,
3279 "set aggregator as <1-65535> A.B.C.D",
3280 SET_STR
3281 "BGP aggregator attribute\n"
3282 "AS number of aggregator\n"
3283 "AS number\n"
3284 "IP address of aggregator\n")
3285{
3286 int ret;
3287 as_t as;
3288 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003289 char *argstr;
3290
paulfd79ac92004-10-13 05:06:08 +00003291 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)
3292
paul718e3742002-12-13 20:15:29 +00003293 ret = inet_aton (argv[1], &address);
3294 if (ret == 0)
3295 {
3296 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3297 return CMD_WARNING;
3298 }
3299
3300 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3301 strlen (argv[0]) + strlen (argv[1]) + 2);
3302
3303 sprintf (argstr, "%s %s", argv[0], argv[1]);
3304
3305 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3306
3307 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3308
3309 return ret;
3310}
3311
3312DEFUN (no_set_aggregator_as,
3313 no_set_aggregator_as_cmd,
3314 "no set aggregator as",
3315 NO_STR
3316 SET_STR
3317 "BGP aggregator attribute\n"
3318 "AS number of aggregator\n")
3319{
3320 int ret;
3321 as_t as;
3322 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003323 char *argstr;
3324
3325 if (argv == 0)
3326 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3327
paulfd79ac92004-10-13 05:06:08 +00003328 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)
paul718e3742002-12-13 20:15:29 +00003329
3330 ret = inet_aton (argv[1], &address);
3331 if (ret == 0)
3332 {
3333 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3334 return CMD_WARNING;
3335 }
3336
3337 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3338 strlen (argv[0]) + strlen (argv[1]) + 2);
3339
3340 sprintf (argstr, "%s %s", argv[0], argv[1]);
3341
3342 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3343
3344 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3345
3346 return ret;
3347}
3348
3349ALIAS (no_set_aggregator_as,
3350 no_set_aggregator_as_val_cmd,
3351 "no set aggregator as <1-65535> A.B.C.D",
3352 NO_STR
3353 SET_STR
3354 "BGP aggregator attribute\n"
3355 "AS number of aggregator\n"
3356 "AS number\n"
3357 "IP address of aggregator\n")
3358
3359
3360#ifdef HAVE_IPV6
3361DEFUN (match_ipv6_address,
3362 match_ipv6_address_cmd,
3363 "match ipv6 address WORD",
3364 MATCH_STR
3365 IPV6_STR
3366 "Match IPv6 address of route\n"
3367 "IPv6 access-list name\n")
3368{
3369 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3370}
3371
3372DEFUN (no_match_ipv6_address,
3373 no_match_ipv6_address_cmd,
3374 "no match ipv6 address WORD",
3375 NO_STR
3376 MATCH_STR
3377 IPV6_STR
3378 "Match IPv6 address of route\n"
3379 "IPv6 access-list name\n")
3380{
3381 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3382}
3383
3384DEFUN (match_ipv6_next_hop,
3385 match_ipv6_next_hop_cmd,
3386 "match ipv6 next-hop X:X::X:X",
3387 MATCH_STR
3388 IPV6_STR
3389 "Match IPv6 next-hop address of route\n"
3390 "IPv6 address of next hop\n")
3391{
3392 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3393}
3394
3395DEFUN (no_match_ipv6_next_hop,
3396 no_match_ipv6_next_hop_cmd,
3397 "no match ipv6 next-hop X:X::X:X",
3398 NO_STR
3399 MATCH_STR
3400 IPV6_STR
3401 "Match IPv6 next-hop address of route\n"
3402 "IPv6 address of next hop\n")
3403{
3404 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3405}
3406
3407DEFUN (match_ipv6_address_prefix_list,
3408 match_ipv6_address_prefix_list_cmd,
3409 "match ipv6 address prefix-list WORD",
3410 MATCH_STR
3411 IPV6_STR
3412 "Match address of route\n"
3413 "Match entries of prefix-lists\n"
3414 "IP prefix-list name\n")
3415{
3416 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3417}
3418
3419DEFUN (no_match_ipv6_address_prefix_list,
3420 no_match_ipv6_address_prefix_list_cmd,
3421 "no match ipv6 address prefix-list WORD",
3422 NO_STR
3423 MATCH_STR
3424 IPV6_STR
3425 "Match address of route\n"
3426 "Match entries of prefix-lists\n"
3427 "IP prefix-list name\n")
3428{
3429 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3430}
3431
3432DEFUN (set_ipv6_nexthop_global,
3433 set_ipv6_nexthop_global_cmd,
3434 "set ipv6 next-hop global X:X::X:X",
3435 SET_STR
3436 IPV6_STR
3437 "IPv6 next-hop address\n"
3438 "IPv6 global address\n"
3439 "IPv6 address of next hop\n")
3440{
3441 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3442}
3443
3444DEFUN (no_set_ipv6_nexthop_global,
3445 no_set_ipv6_nexthop_global_cmd,
3446 "no set ipv6 next-hop global",
3447 NO_STR
3448 SET_STR
3449 IPV6_STR
3450 "IPv6 next-hop address\n"
3451 "IPv6 global address\n")
3452{
3453 if (argc == 0)
3454 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3455
3456 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3457}
3458
3459ALIAS (no_set_ipv6_nexthop_global,
3460 no_set_ipv6_nexthop_global_val_cmd,
3461 "no set ipv6 next-hop global X:X::X:X",
3462 NO_STR
3463 SET_STR
3464 IPV6_STR
3465 "IPv6 next-hop address\n"
3466 "IPv6 global address\n"
3467 "IPv6 address of next hop\n")
3468
3469DEFUN (set_ipv6_nexthop_local,
3470 set_ipv6_nexthop_local_cmd,
3471 "set ipv6 next-hop local X:X::X:X",
3472 SET_STR
3473 IPV6_STR
3474 "IPv6 next-hop address\n"
3475 "IPv6 local address\n"
3476 "IPv6 address of next hop\n")
3477{
3478 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3479}
3480
3481DEFUN (no_set_ipv6_nexthop_local,
3482 no_set_ipv6_nexthop_local_cmd,
3483 "no set ipv6 next-hop local",
3484 NO_STR
3485 SET_STR
3486 IPV6_STR
3487 "IPv6 next-hop address\n"
3488 "IPv6 local address\n")
3489{
3490 if (argc == 0)
3491 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3492
3493 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3494}
3495
3496ALIAS (no_set_ipv6_nexthop_local,
3497 no_set_ipv6_nexthop_local_val_cmd,
3498 "no set ipv6 next-hop local X:X::X:X",
3499 NO_STR
3500 SET_STR
3501 IPV6_STR
3502 "IPv6 next-hop address\n"
3503 "IPv6 local address\n"
3504 "IPv6 address of next hop\n")
3505#endif /* HAVE_IPV6 */
3506
3507DEFUN (set_vpnv4_nexthop,
3508 set_vpnv4_nexthop_cmd,
3509 "set vpnv4 next-hop A.B.C.D",
3510 SET_STR
3511 "VPNv4 information\n"
3512 "VPNv4 next-hop address\n"
3513 "IP address of next hop\n")
3514{
3515 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3516}
3517
3518DEFUN (no_set_vpnv4_nexthop,
3519 no_set_vpnv4_nexthop_cmd,
3520 "no set vpnv4 next-hop",
3521 NO_STR
3522 SET_STR
3523 "VPNv4 information\n"
3524 "VPNv4 next-hop address\n")
3525{
3526 if (argc == 0)
3527 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3528
3529 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3530}
3531
3532ALIAS (no_set_vpnv4_nexthop,
3533 no_set_vpnv4_nexthop_val_cmd,
3534 "no set vpnv4 next-hop A.B.C.D",
3535 NO_STR
3536 SET_STR
3537 "VPNv4 information\n"
3538 "VPNv4 next-hop address\n"
3539 "IP address of next hop\n")
3540
3541DEFUN (set_originator_id,
3542 set_originator_id_cmd,
3543 "set originator-id A.B.C.D",
3544 SET_STR
3545 "BGP originator ID attribute\n"
3546 "IP address of originator\n")
3547{
3548 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3549}
3550
3551DEFUN (no_set_originator_id,
3552 no_set_originator_id_cmd,
3553 "no set originator-id",
3554 NO_STR
3555 SET_STR
3556 "BGP originator ID attribute\n")
3557{
3558 if (argc == 0)
3559 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3560
3561 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3562}
3563
3564ALIAS (no_set_originator_id,
3565 no_set_originator_id_val_cmd,
3566 "no set originator-id A.B.C.D",
3567 NO_STR
3568 SET_STR
3569 "BGP originator ID attribute\n"
3570 "IP address of originator\n")
3571
3572
3573/* Initialization of route map. */
3574void
3575bgp_route_map_init ()
3576{
3577 route_map_init ();
3578 route_map_init_vty ();
3579 route_map_add_hook (bgp_route_map_update);
3580 route_map_delete_hook (bgp_route_map_update);
3581
paulfee0f4c2004-09-13 05:12:46 +00003582 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003583 route_map_install_match (&route_match_ip_address_cmd);
3584 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003585 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003586 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3587 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003588 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003589 route_map_install_match (&route_match_aspath_cmd);
3590 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003591 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003592 route_map_install_match (&route_match_metric_cmd);
3593 route_map_install_match (&route_match_origin_cmd);
3594
3595 route_map_install_set (&route_set_ip_nexthop_cmd);
3596 route_map_install_set (&route_set_local_pref_cmd);
3597 route_map_install_set (&route_set_weight_cmd);
3598 route_map_install_set (&route_set_metric_cmd);
3599 route_map_install_set (&route_set_aspath_prepend_cmd);
3600 route_map_install_set (&route_set_origin_cmd);
3601 route_map_install_set (&route_set_atomic_aggregate_cmd);
3602 route_map_install_set (&route_set_aggregator_as_cmd);
3603 route_map_install_set (&route_set_community_cmd);
3604 route_map_install_set (&route_set_community_delete_cmd);
3605 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3606 route_map_install_set (&route_set_originator_id_cmd);
3607 route_map_install_set (&route_set_ecommunity_rt_cmd);
3608 route_map_install_set (&route_set_ecommunity_soo_cmd);
3609
paulfee0f4c2004-09-13 05:12:46 +00003610 install_element (RMAP_NODE, &match_peer_cmd);
3611 install_element (RMAP_NODE, &match_peer_local_cmd);
3612 install_element (RMAP_NODE, &no_match_peer_cmd);
3613 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3614 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003615 install_element (RMAP_NODE, &match_ip_address_cmd);
3616 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3617 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3618 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3619 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3620 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003621 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3622 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3623 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003624
3625 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3626 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3627 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3628 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3629 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3630 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003631 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3632 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3633 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003634
3635 install_element (RMAP_NODE, &match_aspath_cmd);
3636 install_element (RMAP_NODE, &no_match_aspath_cmd);
3637 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3638 install_element (RMAP_NODE, &match_metric_cmd);
3639 install_element (RMAP_NODE, &no_match_metric_cmd);
3640 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3641 install_element (RMAP_NODE, &match_community_cmd);
3642 install_element (RMAP_NODE, &match_community_exact_cmd);
3643 install_element (RMAP_NODE, &no_match_community_cmd);
3644 install_element (RMAP_NODE, &no_match_community_val_cmd);
3645 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003646 install_element (RMAP_NODE, &match_ecommunity_cmd);
3647 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3648 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003649 install_element (RMAP_NODE, &match_origin_cmd);
3650 install_element (RMAP_NODE, &no_match_origin_cmd);
3651 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3652
3653 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003654 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003655 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3656 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3657 install_element (RMAP_NODE, &set_local_pref_cmd);
3658 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3659 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3660 install_element (RMAP_NODE, &set_weight_cmd);
3661 install_element (RMAP_NODE, &no_set_weight_cmd);
3662 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3663 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003664 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003665 install_element (RMAP_NODE, &no_set_metric_cmd);
3666 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3667 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3668 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3669 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3670 install_element (RMAP_NODE, &set_origin_cmd);
3671 install_element (RMAP_NODE, &no_set_origin_cmd);
3672 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3673 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3674 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3675 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3676 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3677 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3678 install_element (RMAP_NODE, &set_community_cmd);
3679 install_element (RMAP_NODE, &set_community_none_cmd);
3680 install_element (RMAP_NODE, &no_set_community_cmd);
3681 install_element (RMAP_NODE, &no_set_community_val_cmd);
3682 install_element (RMAP_NODE, &no_set_community_none_cmd);
3683 install_element (RMAP_NODE, &set_community_delete_cmd);
3684 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3685 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3686 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3687 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3688 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3689 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3690 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3691 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3692 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3693 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3694 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3695 install_element (RMAP_NODE, &set_originator_id_cmd);
3696 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3697 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3698
3699#ifdef HAVE_IPV6
3700 route_map_install_match (&route_match_ipv6_address_cmd);
3701 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3702 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3703 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3704 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3705
3706 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3707 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3708 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3709 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3710 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3711 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3712 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3713 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3714 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3715 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3716 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3717 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3718#endif /* HAVE_IPV6 */
3719}