blob: 6c10987bd19cf45c56c5a6c538100a15e84cc2f4 [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 {
paul22db9de2005-05-19 01:50:11 +0000127 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000128 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
129 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
130 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000131 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000132 else
paul22db9de2005-05-19 01:50:11 +0000133 ret = RMAP_NOMATCH;
134
135 sockunion_free (su2);
136 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000137 }
paul22db9de2005-05-19 01:50:11 +0000138 sockunion_free (su2);
139
paulfee0f4c2004-09-13 05:12:46 +0000140 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;
hasso70601e02005-05-27 03:26:57 +00001271
1272 if (old)
1273 community_free (old);
1274
paul718e3742002-12-13 20:15:29 +00001275 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1276 }
1277
1278 return RMAP_OKAY;
1279}
1280
1281/* Compile function for set community. */
1282void *
paulfd79ac92004-10-13 05:06:08 +00001283route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001284{
1285 struct rmap_com_set *rcs;
1286 struct community *com = NULL;
1287 char *sp;
1288 int additive = 0;
1289 int none = 0;
1290
1291 if (strcmp (arg, "none") == 0)
1292 none = 1;
1293 else
1294 {
1295 sp = strstr (arg, "additive");
1296
1297 if (sp && sp > arg)
1298 {
1299 /* "additive" keyworkd is included. */
1300 additive = 1;
1301 *(sp - 1) = '\0';
1302 }
1303
1304 com = community_str2com (arg);
1305
1306 if (additive)
1307 *(sp - 1) = ' ';
1308
1309 if (! com)
1310 return NULL;
1311 }
1312
1313 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1314 memset (rcs, 0, sizeof (struct rmap_com_set));
1315
1316 rcs->com = com;
1317 rcs->additive = additive;
1318 rcs->none = none;
1319
1320 return rcs;
1321}
1322
1323/* Free function for set community. */
1324void
1325route_set_community_free (void *rule)
1326{
1327 struct rmap_com_set *rcs = rule;
1328
1329 if (rcs->com)
1330 community_free (rcs->com);
1331 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1332}
1333
1334/* Set community rule structure. */
1335struct route_map_rule_cmd route_set_community_cmd =
1336{
1337 "community",
1338 route_set_community,
1339 route_set_community_compile,
1340 route_set_community_free,
1341};
1342
hassofee6e4e2005-02-02 16:29:31 +00001343/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001344
1345/* For community set mechanism. */
1346route_map_result_t
1347route_set_community_delete (void *rule, struct prefix *prefix,
1348 route_map_object_t type, void *object)
1349{
1350 struct community_list *list;
1351 struct community *merge;
1352 struct community *new;
1353 struct community *old;
1354 struct bgp_info *binfo;
1355
1356 if (type == RMAP_BGP)
1357 {
1358 if (! rule)
1359 return RMAP_OKAY;
1360
1361 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001362 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001363 old = binfo->attr->community;
1364
1365 if (list && old)
1366 {
1367 merge = community_list_match_delete (community_dup (old), list);
1368 new = community_uniq_sort (merge);
1369 community_free (merge);
1370
1371 if (new->size == 0)
1372 {
1373 binfo->attr->community = NULL;
1374 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1375 community_free (new);
1376 }
1377 else
1378 {
1379 binfo->attr->community = new;
1380 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1381 }
1382 }
1383 }
1384
1385 return RMAP_OKAY;
1386}
1387
1388/* Compile function for set community. */
1389void *
paulfd79ac92004-10-13 05:06:08 +00001390route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001391{
1392 char *p;
1393 char *str;
1394 int len;
1395
1396 p = strchr (arg, ' ');
1397 if (p)
1398 {
1399 len = p - arg;
1400 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1401 memcpy (str, arg, len);
1402 }
1403 else
1404 str = NULL;
1405
1406 return str;
1407}
1408
1409/* Free function for set community. */
1410void
1411route_set_community_delete_free (void *rule)
1412{
1413 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1414}
1415
1416/* Set community rule structure. */
1417struct route_map_rule_cmd route_set_community_delete_cmd =
1418{
1419 "comm-list",
1420 route_set_community_delete,
1421 route_set_community_delete_compile,
1422 route_set_community_delete_free,
1423};
1424
1425/* `set extcommunity rt COMMUNITY' */
1426
1427/* For community set mechanism. */
1428route_map_result_t
1429route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1430 route_map_object_t type, void *object)
1431{
1432 struct ecommunity *ecom;
1433 struct ecommunity *new_ecom;
1434 struct ecommunity *old_ecom;
1435 struct bgp_info *bgp_info;
1436
1437 if (type == RMAP_BGP)
1438 {
1439 ecom = rule;
1440 bgp_info = object;
1441
1442 if (! ecom)
1443 return RMAP_OKAY;
1444
1445 /* We assume additive for Extended Community. */
1446 old_ecom = bgp_info->attr->ecommunity;
1447
1448 if (old_ecom)
1449 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1450 else
1451 new_ecom = ecommunity_dup (ecom);
1452
1453 bgp_info->attr->ecommunity = new_ecom;
1454
hasso70601e02005-05-27 03:26:57 +00001455 if (old_ecom)
1456 ecommunity_free (old_ecom);
1457
paul718e3742002-12-13 20:15:29 +00001458 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1459 }
1460 return RMAP_OKAY;
1461}
1462
1463/* Compile function for set community. */
1464void *
paulfd79ac92004-10-13 05:06:08 +00001465route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001466{
1467 struct ecommunity *ecom;
1468
1469 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1470 if (! ecom)
1471 return NULL;
1472 return ecom;
1473}
1474
1475/* Free function for set community. */
1476void
1477route_set_ecommunity_rt_free (void *rule)
1478{
1479 struct ecommunity *ecom = rule;
1480 ecommunity_free (ecom);
1481}
1482
1483/* Set community rule structure. */
1484struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1485{
1486 "extcommunity rt",
1487 route_set_ecommunity_rt,
1488 route_set_ecommunity_rt_compile,
1489 route_set_ecommunity_rt_free,
1490};
1491
1492/* `set extcommunity soo COMMUNITY' */
1493
1494/* For community set mechanism. */
1495route_map_result_t
1496route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1497 route_map_object_t type, void *object)
1498{
1499 struct ecommunity *ecom;
1500 struct bgp_info *bgp_info;
1501
1502 if (type == RMAP_BGP)
1503 {
1504 ecom = rule;
1505 bgp_info = object;
1506
1507 if (! ecom)
1508 return RMAP_OKAY;
1509
1510 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1511 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1512 }
1513 return RMAP_OKAY;
1514}
1515
1516/* Compile function for set community. */
1517void *
paulfd79ac92004-10-13 05:06:08 +00001518route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001519{
1520 struct ecommunity *ecom;
1521
1522 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1523 if (! ecom)
1524 return NULL;
1525
1526 return ecom;
1527}
1528
1529/* Free function for set community. */
1530void
1531route_set_ecommunity_soo_free (void *rule)
1532{
1533 struct ecommunity *ecom = rule;
1534 ecommunity_free (ecom);
1535}
1536
1537/* Set community rule structure. */
1538struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1539{
1540 "extcommunity soo",
1541 route_set_ecommunity_soo,
1542 route_set_ecommunity_soo_compile,
1543 route_set_ecommunity_soo_free,
1544};
1545
1546/* `set origin ORIGIN' */
1547
1548/* For origin set. */
1549route_map_result_t
1550route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1551{
1552 u_char *origin;
1553 struct bgp_info *bgp_info;
1554
1555 if (type == RMAP_BGP)
1556 {
1557 origin = rule;
1558 bgp_info = object;
1559
1560 bgp_info->attr->origin = *origin;
1561 }
1562
1563 return RMAP_OKAY;
1564}
1565
1566/* Compile function for origin set. */
1567void *
paulfd79ac92004-10-13 05:06:08 +00001568route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001569{
1570 u_char *origin;
1571
1572 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1573
1574 if (strcmp (arg, "igp") == 0)
1575 *origin = 0;
1576 else if (strcmp (arg, "egp") == 0)
1577 *origin = 1;
1578 else
1579 *origin = 2;
1580
1581 return origin;
1582}
1583
1584/* Compile function for origin set. */
1585void
1586route_set_origin_free (void *rule)
1587{
1588 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1589}
1590
1591/* Set metric rule structure. */
1592struct route_map_rule_cmd route_set_origin_cmd =
1593{
1594 "origin",
1595 route_set_origin,
1596 route_set_origin_compile,
1597 route_set_origin_free,
1598};
1599
1600/* `set atomic-aggregate' */
1601
1602/* For atomic aggregate set. */
1603route_map_result_t
1604route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1605 route_map_object_t type, void *object)
1606{
1607 struct bgp_info *bgp_info;
1608
1609 if (type == RMAP_BGP)
1610 {
1611 bgp_info = object;
1612 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1613 }
1614
1615 return RMAP_OKAY;
1616}
1617
1618/* Compile function for atomic aggregate. */
1619void *
paulfd79ac92004-10-13 05:06:08 +00001620route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001621{
1622 return (void *)1;
1623}
1624
1625/* Compile function for atomic aggregate. */
1626void
1627route_set_atomic_aggregate_free (void *rule)
1628{
1629 return;
1630}
1631
1632/* Set atomic aggregate rule structure. */
1633struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1634{
1635 "atomic-aggregate",
1636 route_set_atomic_aggregate,
1637 route_set_atomic_aggregate_compile,
1638 route_set_atomic_aggregate_free,
1639};
1640
1641/* `set aggregator as AS A.B.C.D' */
1642struct aggregator
1643{
1644 as_t as;
1645 struct in_addr address;
1646};
1647
1648route_map_result_t
1649route_set_aggregator_as (void *rule, struct prefix *prefix,
1650 route_map_object_t type, void *object)
1651{
1652 struct bgp_info *bgp_info;
1653 struct aggregator *aggregator;
1654
1655 if (type == RMAP_BGP)
1656 {
1657 bgp_info = object;
1658 aggregator = rule;
1659
1660 bgp_info->attr->aggregator_as = aggregator->as;
1661 bgp_info->attr->aggregator_addr = aggregator->address;
1662 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1663 }
1664
1665 return RMAP_OKAY;
1666}
1667
1668void *
paulfd79ac92004-10-13 05:06:08 +00001669route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001670{
1671 struct aggregator *aggregator;
1672 char as[10];
1673 char address[20];
1674
1675 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1676 memset (aggregator, 0, sizeof (struct aggregator));
1677
1678 sscanf (arg, "%s %s", as, address);
1679
1680 aggregator->as = strtoul (as, NULL, 10);
1681 inet_aton (address, &aggregator->address);
1682
1683 return aggregator;
1684}
1685
1686void
1687route_set_aggregator_as_free (void *rule)
1688{
1689 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1690}
1691
1692struct route_map_rule_cmd route_set_aggregator_as_cmd =
1693{
1694 "aggregator as",
1695 route_set_aggregator_as,
1696 route_set_aggregator_as_compile,
1697 route_set_aggregator_as_free,
1698};
1699
1700#ifdef HAVE_IPV6
1701/* `match ipv6 address IP_ACCESS_LIST' */
1702
1703route_map_result_t
1704route_match_ipv6_address (void *rule, struct prefix *prefix,
1705 route_map_object_t type, void *object)
1706{
1707 struct access_list *alist;
1708
1709 if (type == RMAP_BGP)
1710 {
1711 alist = access_list_lookup (AFI_IP6, (char *) rule);
1712 if (alist == NULL)
1713 return RMAP_NOMATCH;
1714
1715 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1716 RMAP_NOMATCH : RMAP_MATCH);
1717 }
1718 return RMAP_NOMATCH;
1719}
1720
1721void *
paulfd79ac92004-10-13 05:06:08 +00001722route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001723{
1724 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1725}
1726
1727void
1728route_match_ipv6_address_free (void *rule)
1729{
1730 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1731}
1732
1733/* Route map commands for ip address matching. */
1734struct route_map_rule_cmd route_match_ipv6_address_cmd =
1735{
1736 "ipv6 address",
1737 route_match_ipv6_address,
1738 route_match_ipv6_address_compile,
1739 route_match_ipv6_address_free
1740};
1741
1742/* `match ipv6 next-hop IP_ADDRESS' */
1743
1744route_map_result_t
1745route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1746 route_map_object_t type, void *object)
1747{
1748 struct in6_addr *addr;
1749 struct bgp_info *bgp_info;
1750
1751 if (type == RMAP_BGP)
1752 {
1753 addr = rule;
1754 bgp_info = object;
1755
1756 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1757 return RMAP_MATCH;
1758
1759 if (bgp_info->attr->mp_nexthop_len == 32 &&
1760 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1761 return RMAP_MATCH;
1762
1763 return RMAP_NOMATCH;
1764 }
1765
1766 return RMAP_NOMATCH;
1767}
1768
1769void *
paulfd79ac92004-10-13 05:06:08 +00001770route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001771{
1772 struct in6_addr *address;
1773 int ret;
1774
1775 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1776
1777 ret = inet_pton (AF_INET6, arg, address);
1778 if (!ret)
1779 {
1780 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1781 return NULL;
1782 }
1783
1784 return address;
1785}
1786
1787void
1788route_match_ipv6_next_hop_free (void *rule)
1789{
1790 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1791}
1792
1793struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1794{
1795 "ipv6 next-hop",
1796 route_match_ipv6_next_hop,
1797 route_match_ipv6_next_hop_compile,
1798 route_match_ipv6_next_hop_free
1799};
1800
1801/* `match ipv6 address prefix-list PREFIX_LIST' */
1802
1803route_map_result_t
1804route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1805 route_map_object_t type, void *object)
1806{
1807 struct prefix_list *plist;
1808
1809 if (type == RMAP_BGP)
1810 {
1811 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1812 if (plist == NULL)
1813 return RMAP_NOMATCH;
1814
1815 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1816 RMAP_NOMATCH : RMAP_MATCH);
1817 }
1818 return RMAP_NOMATCH;
1819}
1820
1821void *
paulfd79ac92004-10-13 05:06:08 +00001822route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001823{
1824 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1825}
1826
1827void
1828route_match_ipv6_address_prefix_list_free (void *rule)
1829{
1830 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1831}
1832
1833struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1834{
1835 "ipv6 address prefix-list",
1836 route_match_ipv6_address_prefix_list,
1837 route_match_ipv6_address_prefix_list_compile,
1838 route_match_ipv6_address_prefix_list_free
1839};
1840
1841/* `set ipv6 nexthop global IP_ADDRESS' */
1842
1843/* Set nexthop to object. ojbect must be pointer to struct attr. */
1844route_map_result_t
1845route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1846 route_map_object_t type, void *object)
1847{
1848 struct in6_addr *address;
1849 struct bgp_info *bgp_info;
1850
1851 if (type == RMAP_BGP)
1852 {
1853 /* Fetch routemap's rule information. */
1854 address = rule;
1855 bgp_info = object;
1856
1857 /* Set next hop value. */
1858 bgp_info->attr->mp_nexthop_global = *address;
1859
1860 /* Set nexthop length. */
1861 if (bgp_info->attr->mp_nexthop_len == 0)
1862 bgp_info->attr->mp_nexthop_len = 16;
1863 }
1864
1865 return RMAP_OKAY;
1866}
1867
1868/* Route map `ip next-hop' compile function. Given string is converted
1869 to struct in_addr structure. */
1870void *
paulfd79ac92004-10-13 05:06:08 +00001871route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001872{
1873 int ret;
1874 struct in6_addr *address;
1875
1876 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1877
1878 ret = inet_pton (AF_INET6, arg, address);
1879
1880 if (ret == 0)
1881 {
1882 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1883 return NULL;
1884 }
1885
1886 return address;
1887}
1888
1889/* Free route map's compiled `ip next-hop' value. */
1890void
1891route_set_ipv6_nexthop_global_free (void *rule)
1892{
1893 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1894}
1895
1896/* Route map commands for ip nexthop set. */
1897struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1898{
1899 "ipv6 next-hop global",
1900 route_set_ipv6_nexthop_global,
1901 route_set_ipv6_nexthop_global_compile,
1902 route_set_ipv6_nexthop_global_free
1903};
1904
1905/* `set ipv6 nexthop local IP_ADDRESS' */
1906
1907/* Set nexthop to object. ojbect must be pointer to struct attr. */
1908route_map_result_t
1909route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1910 route_map_object_t type, void *object)
1911{
1912 struct in6_addr *address;
1913 struct bgp_info *bgp_info;
1914
1915 if (type == RMAP_BGP)
1916 {
1917 /* Fetch routemap's rule information. */
1918 address = rule;
1919 bgp_info = object;
1920
1921 /* Set next hop value. */
1922 bgp_info->attr->mp_nexthop_local = *address;
1923
1924 /* Set nexthop length. */
1925 if (bgp_info->attr->mp_nexthop_len != 32)
1926 bgp_info->attr->mp_nexthop_len = 32;
1927 }
1928
1929 return RMAP_OKAY;
1930}
1931
1932/* Route map `ip nexthop' compile function. Given string is converted
1933 to struct in_addr structure. */
1934void *
paulfd79ac92004-10-13 05:06:08 +00001935route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001936{
1937 int ret;
1938 struct in6_addr *address;
1939
1940 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1941
1942 ret = inet_pton (AF_INET6, arg, address);
1943
1944 if (ret == 0)
1945 {
1946 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1947 return NULL;
1948 }
1949
1950 return address;
1951}
1952
1953/* Free route map's compiled `ip nexthop' value. */
1954void
1955route_set_ipv6_nexthop_local_free (void *rule)
1956{
1957 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1958}
1959
1960/* Route map commands for ip nexthop set. */
1961struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1962{
1963 "ipv6 next-hop local",
1964 route_set_ipv6_nexthop_local,
1965 route_set_ipv6_nexthop_local_compile,
1966 route_set_ipv6_nexthop_local_free
1967};
1968#endif /* HAVE_IPV6 */
1969
1970/* `set vpnv4 nexthop A.B.C.D' */
1971
1972route_map_result_t
1973route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1974 route_map_object_t type, void *object)
1975{
1976 struct in_addr *address;
1977 struct bgp_info *bgp_info;
1978
1979 if (type == RMAP_BGP)
1980 {
1981 /* Fetch routemap's rule information. */
1982 address = rule;
1983 bgp_info = object;
1984
1985 /* Set next hop value. */
1986 bgp_info->attr->mp_nexthop_global_in = *address;
1987 }
1988
1989 return RMAP_OKAY;
1990}
1991
1992void *
paulfd79ac92004-10-13 05:06:08 +00001993route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001994{
1995 int ret;
1996 struct in_addr *address;
1997
1998 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1999
2000 ret = inet_aton (arg, address);
2001
2002 if (ret == 0)
2003 {
2004 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2005 return NULL;
2006 }
2007
2008 return address;
2009}
2010
2011void
2012route_set_vpnv4_nexthop_free (void *rule)
2013{
2014 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2015}
2016
2017/* Route map commands for ip nexthop set. */
2018struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2019{
2020 "vpnv4 next-hop",
2021 route_set_vpnv4_nexthop,
2022 route_set_vpnv4_nexthop_compile,
2023 route_set_vpnv4_nexthop_free
2024};
2025
2026/* `set originator-id' */
2027
2028/* For origin set. */
2029route_map_result_t
2030route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2031{
2032 struct in_addr *address;
2033 struct bgp_info *bgp_info;
2034
2035 if (type == RMAP_BGP)
2036 {
2037 address = rule;
2038 bgp_info = object;
2039
2040 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
2041 bgp_info->attr->originator_id = *address;
2042 }
2043
2044 return RMAP_OKAY;
2045}
2046
2047/* Compile function for originator-id set. */
2048void *
paulfd79ac92004-10-13 05:06:08 +00002049route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002050{
2051 int ret;
2052 struct in_addr *address;
2053
2054 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2055
2056 ret = inet_aton (arg, address);
2057
2058 if (ret == 0)
2059 {
2060 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2061 return NULL;
2062 }
2063
2064 return address;
2065}
2066
2067/* Compile function for originator_id set. */
2068void
2069route_set_originator_id_free (void *rule)
2070{
2071 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2072}
2073
2074/* Set metric rule structure. */
2075struct route_map_rule_cmd route_set_originator_id_cmd =
2076{
2077 "originator-id",
2078 route_set_originator_id,
2079 route_set_originator_id_compile,
2080 route_set_originator_id_free,
2081};
2082
2083/* Add bgp route map rule. */
2084int
2085bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002086 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002087{
2088 int ret;
2089
2090 ret = route_map_add_match (index, command, arg);
2091 if (ret)
2092 {
2093 switch (ret)
2094 {
2095 case RMAP_RULE_MISSING:
2096 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2097 return CMD_WARNING;
2098 break;
2099 case RMAP_COMPILE_ERROR:
2100 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2101 return CMD_WARNING;
2102 break;
2103 }
2104 }
2105 return CMD_SUCCESS;
2106}
2107
2108/* Delete bgp route map rule. */
2109int
2110bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002111 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002112{
2113 int ret;
2114
2115 ret = route_map_delete_match (index, command, arg);
2116 if (ret)
2117 {
2118 switch (ret)
2119 {
2120 case RMAP_RULE_MISSING:
2121 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2122 return CMD_WARNING;
2123 break;
2124 case RMAP_COMPILE_ERROR:
2125 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2126 return CMD_WARNING;
2127 break;
2128 }
2129 }
2130 return CMD_SUCCESS;
2131}
2132
2133/* Add bgp route map rule. */
2134int
2135bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002136 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002137{
2138 int ret;
2139
2140 ret = route_map_add_set (index, command, arg);
2141 if (ret)
2142 {
2143 switch (ret)
2144 {
2145 case RMAP_RULE_MISSING:
2146 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2147 return CMD_WARNING;
2148 break;
2149 case RMAP_COMPILE_ERROR:
2150 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2151 return CMD_WARNING;
2152 break;
2153 }
2154 }
2155 return CMD_SUCCESS;
2156}
2157
2158/* Delete bgp route map rule. */
2159int
2160bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002161 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002162{
2163 int ret;
2164
2165 ret = route_map_delete_set (index, command, arg);
2166 if (ret)
2167 {
2168 switch (ret)
2169 {
2170 case RMAP_RULE_MISSING:
2171 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2172 return CMD_WARNING;
2173 break;
2174 case RMAP_COMPILE_ERROR:
2175 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2176 return CMD_WARNING;
2177 break;
2178 }
2179 }
2180 return CMD_SUCCESS;
2181}
2182
2183/* Hook function for updating route_map assignment. */
2184void
paulfd79ac92004-10-13 05:06:08 +00002185bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002186{
2187 int i;
2188 afi_t afi;
2189 safi_t safi;
2190 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002191 struct listnode *node, *nnode;
2192 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002193 struct bgp *bgp;
2194 struct peer *peer;
2195 struct peer_group *group;
2196 struct bgp_filter *filter;
2197 struct bgp_node *bn;
2198 struct bgp_static *bgp_static;
2199
2200 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002201 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002202 {
paul1eb8ef22005-04-07 07:30:20 +00002203 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002204 {
2205 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2206 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2207 {
2208 filter = &peer->filter[afi][safi];
2209
paulfee0f4c2004-09-13 05:12:46 +00002210 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002211 {
2212 if (filter->map[direct].name)
2213 filter->map[direct].map =
2214 route_map_lookup_by_name (filter->map[direct].name);
2215 else
2216 filter->map[direct].map = NULL;
2217 }
2218
2219 if (filter->usmap.name)
2220 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2221 else
2222 filter->usmap.map = NULL;
2223 }
2224 }
paul1eb8ef22005-04-07 07:30:20 +00002225 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002226 {
2227 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2228 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2229 {
2230 filter = &group->conf->filter[afi][safi];
2231
paulfee0f4c2004-09-13 05:12:46 +00002232 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002233 {
2234 if (filter->map[direct].name)
2235 filter->map[direct].map =
2236 route_map_lookup_by_name (filter->map[direct].name);
2237 else
2238 filter->map[direct].map = NULL;
2239 }
2240
2241 if (filter->usmap.name)
2242 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2243 else
2244 filter->usmap.map = NULL;
2245 }
2246 }
2247 }
2248
2249 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002250 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002251 {
paul1eb8ef22005-04-07 07:30:20 +00002252 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002253 {
2254 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2255 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2256 {
2257 if (peer->default_rmap[afi][safi].name)
2258 peer->default_rmap[afi][safi].map =
2259 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2260 else
2261 peer->default_rmap[afi][safi].map = NULL;
2262 }
2263 }
2264 }
2265
2266 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002267 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002268 {
2269 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2270 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2271 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2272 bn = bgp_route_next (bn))
2273 if ((bgp_static = bn->info) != NULL)
2274 {
2275 if (bgp_static->rmap.name)
2276 bgp_static->rmap.map =
2277 route_map_lookup_by_name (bgp_static->rmap.name);
2278 else
2279 bgp_static->rmap.map = NULL;
2280 }
2281 }
2282
2283 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002284 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002285 {
2286 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2287 {
2288 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2289 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2290 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2291#ifdef HAVE_IPV6
2292 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2293 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2294 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2295#endif /* HAVE_IPV6 */
2296 }
2297 }
2298}
2299
paulfee0f4c2004-09-13 05:12:46 +00002300DEFUN (match_peer,
2301 match_peer_cmd,
2302 "match peer (A.B.C.D|X:X::X:X)",
2303 MATCH_STR
2304 "Match peer address\n"
2305 "IPv6 address of peer\n"
2306 "IP address of peer\n")
2307{
2308 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2309}
2310
2311DEFUN (match_peer_local,
2312 match_peer_local_cmd,
2313 "match peer local",
2314 MATCH_STR
2315 "Match peer address\n"
2316 "Static or Redistributed routes\n")
2317{
2318 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2319}
2320
2321DEFUN (no_match_peer,
2322 no_match_peer_cmd,
2323 "no match peer",
2324 NO_STR
2325 MATCH_STR
2326 "Match peer address\n")
2327{
2328 if (argc == 0)
2329 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2330
2331 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2332}
2333
2334ALIAS (no_match_peer,
2335 no_match_peer_val_cmd,
2336 "no match peer (A.B.C.D|X:X::X:X)",
2337 NO_STR
2338 MATCH_STR
2339 "Match peer address\n"
2340 "IPv6 address of peer\n"
2341 "IP address of peer\n")
2342
2343ALIAS (no_match_peer,
2344 no_match_peer_local_cmd,
2345 "no match peer local",
2346 NO_STR
2347 MATCH_STR
2348 "Match peer address\n"
2349 "Static or Redistributed routes\n")
2350
paul718e3742002-12-13 20:15:29 +00002351DEFUN (match_ip_address,
2352 match_ip_address_cmd,
2353 "match ip address (<1-199>|<1300-2699>|WORD)",
2354 MATCH_STR
2355 IP_STR
2356 "Match address of route\n"
2357 "IP access-list number\n"
2358 "IP access-list number (expanded range)\n"
2359 "IP Access-list name\n")
2360{
2361 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2362}
2363
2364DEFUN (no_match_ip_address,
2365 no_match_ip_address_cmd,
2366 "no match ip address",
2367 NO_STR
2368 MATCH_STR
2369 IP_STR
2370 "Match address of route\n")
2371{
2372 if (argc == 0)
2373 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2374
2375 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2376}
2377
2378ALIAS (no_match_ip_address,
2379 no_match_ip_address_val_cmd,
2380 "no match ip address (<1-199>|<1300-2699>|WORD)",
2381 NO_STR
2382 MATCH_STR
2383 IP_STR
2384 "Match address of route\n"
2385 "IP access-list number\n"
2386 "IP access-list number (expanded range)\n"
2387 "IP Access-list name\n")
2388
2389DEFUN (match_ip_next_hop,
2390 match_ip_next_hop_cmd,
2391 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2392 MATCH_STR
2393 IP_STR
2394 "Match next-hop address of route\n"
2395 "IP access-list number\n"
2396 "IP access-list number (expanded range)\n"
2397 "IP Access-list name\n")
2398{
2399 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2400}
2401
2402DEFUN (no_match_ip_next_hop,
2403 no_match_ip_next_hop_cmd,
2404 "no match ip next-hop",
2405 NO_STR
2406 MATCH_STR
2407 IP_STR
2408 "Match next-hop address of route\n")
2409{
2410 if (argc == 0)
2411 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2412
2413 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2414}
2415
2416ALIAS (no_match_ip_next_hop,
2417 no_match_ip_next_hop_val_cmd,
2418 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2419 NO_STR
2420 MATCH_STR
2421 IP_STR
2422 "Match next-hop address of route\n"
2423 "IP access-list number\n"
2424 "IP access-list number (expanded range)\n"
2425 "IP Access-list name\n")
2426
hassoc1643bb2005-02-02 16:43:17 +00002427DEFUN (match_ip_route_source,
2428 match_ip_route_source_cmd,
2429 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2430 MATCH_STR
2431 IP_STR
2432 "Match advertising source address of route\n"
2433 "IP access-list number\n"
2434 "IP access-list number (expanded range)\n"
2435 "IP standard access-list name\n")
2436{
2437 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2438}
2439
2440DEFUN (no_match_ip_route_source,
2441 no_match_ip_route_source_cmd,
2442 "no match ip route-source",
2443 NO_STR
2444 MATCH_STR
2445 IP_STR
2446 "Match advertising source address of route\n")
2447{
2448 if (argc == 0)
2449 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2450
2451 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2452}
2453
2454ALIAS (no_match_ip_route_source,
2455 no_match_ip_route_source_val_cmd,
2456 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2457 NO_STR
2458 MATCH_STR
2459 IP_STR
2460 "Match advertising source address of route\n"
2461 "IP access-list number\n"
2462 "IP access-list number (expanded range)\n"
2463 "IP standard access-list name\n");
2464
paul718e3742002-12-13 20:15:29 +00002465DEFUN (match_ip_address_prefix_list,
2466 match_ip_address_prefix_list_cmd,
2467 "match ip address prefix-list WORD",
2468 MATCH_STR
2469 IP_STR
2470 "Match address of route\n"
2471 "Match entries of prefix-lists\n"
2472 "IP prefix-list name\n")
2473{
2474 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2475}
2476
2477DEFUN (no_match_ip_address_prefix_list,
2478 no_match_ip_address_prefix_list_cmd,
2479 "no match ip address prefix-list",
2480 NO_STR
2481 MATCH_STR
2482 IP_STR
2483 "Match address of route\n"
2484 "Match entries of prefix-lists\n")
2485{
2486 if (argc == 0)
2487 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2488
2489 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2490}
2491
2492ALIAS (no_match_ip_address_prefix_list,
2493 no_match_ip_address_prefix_list_val_cmd,
2494 "no match ip address prefix-list WORD",
2495 NO_STR
2496 MATCH_STR
2497 IP_STR
2498 "Match address of route\n"
2499 "Match entries of prefix-lists\n"
2500 "IP prefix-list name\n")
2501
2502DEFUN (match_ip_next_hop_prefix_list,
2503 match_ip_next_hop_prefix_list_cmd,
2504 "match ip next-hop prefix-list WORD",
2505 MATCH_STR
2506 IP_STR
2507 "Match next-hop address of route\n"
2508 "Match entries of prefix-lists\n"
2509 "IP prefix-list name\n")
2510{
2511 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2512}
2513
2514DEFUN (no_match_ip_next_hop_prefix_list,
2515 no_match_ip_next_hop_prefix_list_cmd,
2516 "no match ip next-hop prefix-list",
2517 NO_STR
2518 MATCH_STR
2519 IP_STR
2520 "Match next-hop address of route\n"
2521 "Match entries of prefix-lists\n")
2522{
2523 if (argc == 0)
2524 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2525
2526 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2527}
2528
2529ALIAS (no_match_ip_next_hop_prefix_list,
2530 no_match_ip_next_hop_prefix_list_val_cmd,
2531 "no match ip next-hop prefix-list WORD",
2532 NO_STR
2533 MATCH_STR
2534 IP_STR
2535 "Match next-hop address of route\n"
2536 "Match entries of prefix-lists\n"
2537 "IP prefix-list name\n")
2538
hassoc1643bb2005-02-02 16:43:17 +00002539DEFUN (match_ip_route_source_prefix_list,
2540 match_ip_route_source_prefix_list_cmd,
2541 "match ip route-source prefix-list WORD",
2542 MATCH_STR
2543 IP_STR
2544 "Match advertising source address of route\n"
2545 "Match entries of prefix-lists\n"
2546 "IP prefix-list name\n")
2547{
2548 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2549}
2550
2551DEFUN (no_match_ip_route_source_prefix_list,
2552 no_match_ip_route_source_prefix_list_cmd,
2553 "no match ip route-source prefix-list",
2554 NO_STR
2555 MATCH_STR
2556 IP_STR
2557 "Match advertising source address of route\n"
2558 "Match entries of prefix-lists\n")
2559{
2560 if (argc == 0)
2561 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2562
2563 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2564}
2565
2566ALIAS (no_match_ip_route_source_prefix_list,
2567 no_match_ip_route_source_prefix_list_val_cmd,
2568 "no match ip route-source prefix-list WORD",
2569 NO_STR
2570 MATCH_STR
2571 IP_STR
2572 "Match advertising source address of route\n"
2573 "Match entries of prefix-lists\n"
2574 "IP prefix-list name\n");
2575
paul718e3742002-12-13 20:15:29 +00002576DEFUN (match_metric,
2577 match_metric_cmd,
2578 "match metric <0-4294967295>",
2579 MATCH_STR
2580 "Match metric of route\n"
2581 "Metric value\n")
2582{
2583 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2584}
2585
2586DEFUN (no_match_metric,
2587 no_match_metric_cmd,
2588 "no match metric",
2589 NO_STR
2590 MATCH_STR
2591 "Match metric of route\n")
2592{
2593 if (argc == 0)
2594 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2595
2596 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2597}
2598
2599ALIAS (no_match_metric,
2600 no_match_metric_val_cmd,
2601 "no match metric <0-4294967295>",
2602 NO_STR
2603 MATCH_STR
2604 "Match metric of route\n"
2605 "Metric value\n")
2606
2607DEFUN (match_community,
2608 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002609 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002610 MATCH_STR
2611 "Match BGP community list\n"
2612 "Community-list number (standard)\n"
2613 "Community-list number (expanded)\n"
2614 "Community-list name\n")
2615{
2616 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2617}
2618
2619DEFUN (match_community_exact,
2620 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002621 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002622 MATCH_STR
2623 "Match BGP community list\n"
2624 "Community-list number (standard)\n"
2625 "Community-list number (expanded)\n"
2626 "Community-list name\n"
2627 "Do exact matching of communities\n")
2628{
2629 int ret;
2630 char *argstr;
2631
2632 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2633 strlen (argv[0]) + strlen ("exact-match") + 2);
2634
2635 sprintf (argstr, "%s exact-match", argv[0]);
2636
2637 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2638
2639 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2640
2641 return ret;
2642}
2643
2644DEFUN (no_match_community,
2645 no_match_community_cmd,
2646 "no match community",
2647 NO_STR
2648 MATCH_STR
2649 "Match BGP community list\n")
2650{
2651 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2652}
2653
2654ALIAS (no_match_community,
2655 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002656 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002657 NO_STR
2658 MATCH_STR
2659 "Match BGP community list\n"
2660 "Community-list number (standard)\n"
2661 "Community-list number (expanded)\n"
2662 "Community-list name\n")
2663
2664ALIAS (no_match_community,
2665 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002666 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002667 NO_STR
2668 MATCH_STR
2669 "Match BGP community list\n"
2670 "Community-list number (standard)\n"
2671 "Community-list number (expanded)\n"
2672 "Community-list name\n"
2673 "Do exact matching of communities\n")
2674
paul73ffb252003-04-19 15:49:49 +00002675DEFUN (match_ecommunity,
2676 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002677 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002678 MATCH_STR
2679 "Match BGP/VPN extended community list\n"
2680 "Extended community-list number (standard)\n"
2681 "Extended community-list number (expanded)\n"
2682 "Extended community-list name\n")
2683{
2684 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2685}
2686
2687DEFUN (no_match_ecommunity,
2688 no_match_ecommunity_cmd,
2689 "no match extcommunity",
2690 NO_STR
2691 MATCH_STR
2692 "Match BGP/VPN extended community list\n")
2693{
2694 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2695}
2696
2697ALIAS (no_match_ecommunity,
2698 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002699 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002700 NO_STR
2701 MATCH_STR
2702 "Match BGP/VPN extended community list\n"
2703 "Extended community-list number (standard)\n"
2704 "Extended community-list number (expanded)\n"
2705 "Extended community-list name\n")
2706
paul718e3742002-12-13 20:15:29 +00002707DEFUN (match_aspath,
2708 match_aspath_cmd,
2709 "match as-path WORD",
2710 MATCH_STR
2711 "Match BGP AS path list\n"
2712 "AS path access-list name\n")
2713{
2714 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2715}
2716
2717DEFUN (no_match_aspath,
2718 no_match_aspath_cmd,
2719 "no match as-path",
2720 NO_STR
2721 MATCH_STR
2722 "Match BGP AS path list\n")
2723{
2724 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2725}
2726
2727ALIAS (no_match_aspath,
2728 no_match_aspath_val_cmd,
2729 "no match as-path WORD",
2730 NO_STR
2731 MATCH_STR
2732 "Match BGP AS path list\n"
2733 "AS path access-list name\n")
2734
2735DEFUN (match_origin,
2736 match_origin_cmd,
2737 "match origin (egp|igp|incomplete)",
2738 MATCH_STR
2739 "BGP origin code\n"
2740 "remote EGP\n"
2741 "local IGP\n"
2742 "unknown heritage\n")
2743{
2744 if (strncmp (argv[0], "igp", 2) == 0)
2745 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2746 if (strncmp (argv[0], "egp", 1) == 0)
2747 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2748 if (strncmp (argv[0], "incomplete", 2) == 0)
2749 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2750
2751 return CMD_WARNING;
2752}
2753
2754DEFUN (no_match_origin,
2755 no_match_origin_cmd,
2756 "no match origin",
2757 NO_STR
2758 MATCH_STR
2759 "BGP origin code\n")
2760{
2761 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2762}
2763
2764ALIAS (no_match_origin,
2765 no_match_origin_val_cmd,
2766 "no match origin (egp|igp|incomplete)",
2767 NO_STR
2768 MATCH_STR
2769 "BGP origin code\n"
2770 "remote EGP\n"
2771 "local IGP\n"
2772 "unknown heritage\n")
2773
2774DEFUN (set_ip_nexthop,
2775 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002776 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002777 SET_STR
2778 IP_STR
2779 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002780 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002781{
2782 union sockunion su;
2783 int ret;
2784
2785 ret = str2sockunion (argv[0], &su);
2786 if (ret < 0)
2787 {
2788 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2789 return CMD_WARNING;
2790 }
2791
2792 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2793}
2794
paulaf5cd0a2003-11-02 07:24:40 +00002795DEFUN (set_ip_nexthop_peer,
2796 set_ip_nexthop_peer_cmd,
2797 "set ip next-hop peer-address",
2798 SET_STR
2799 IP_STR
2800 "Next hop address\n"
2801 "Use peer address (for BGP only)\n")
2802{
2803 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2804}
2805
2806DEFUN (no_set_ip_nexthop_peer,
2807 no_set_ip_nexthop_peer_cmd,
2808 "no set ip next-hop peer-address",
2809 NO_STR
2810 SET_STR
2811 IP_STR
2812 "Next hop address\n"
2813 "Use peer address (for BGP only)\n")
2814{
2815 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2816}
2817
2818
paul718e3742002-12-13 20:15:29 +00002819DEFUN (no_set_ip_nexthop,
2820 no_set_ip_nexthop_cmd,
2821 "no set ip next-hop",
2822 NO_STR
2823 SET_STR
paul718e3742002-12-13 20:15:29 +00002824 "Next hop address\n")
2825{
paulaf5cd0a2003-11-02 07:24:40 +00002826 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002827 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2828
2829 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2830}
2831
2832ALIAS (no_set_ip_nexthop,
2833 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002834 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002835 NO_STR
2836 SET_STR
2837 IP_STR
2838 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002839 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002840
2841DEFUN (set_metric,
2842 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002843 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002844 SET_STR
2845 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002846 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002847{
2848 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2849}
2850
paul73ffb252003-04-19 15:49:49 +00002851ALIAS (set_metric,
2852 set_metric_addsub_cmd,
2853 "set metric <+/-metric>",
2854 SET_STR
2855 "Metric value for destination routing protocol\n"
2856 "Add or subtract BGP metric\n")
2857
paul718e3742002-12-13 20:15:29 +00002858DEFUN (no_set_metric,
2859 no_set_metric_cmd,
2860 "no set metric",
2861 NO_STR
2862 SET_STR
2863 "Metric value for destination routing protocol\n")
2864{
2865 if (argc == 0)
2866 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2867
2868 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2869}
2870
2871ALIAS (no_set_metric,
2872 no_set_metric_val_cmd,
2873 "no set metric <0-4294967295>",
2874 NO_STR
2875 SET_STR
2876 "Metric value for destination routing protocol\n"
2877 "Metric value\n")
2878
2879DEFUN (set_local_pref,
2880 set_local_pref_cmd,
2881 "set local-preference <0-4294967295>",
2882 SET_STR
2883 "BGP local preference path attribute\n"
2884 "Preference value\n")
2885{
2886 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2887}
2888
2889DEFUN (no_set_local_pref,
2890 no_set_local_pref_cmd,
2891 "no set local-preference",
2892 NO_STR
2893 SET_STR
2894 "BGP local preference path attribute\n")
2895{
2896 if (argc == 0)
2897 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2898
2899 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2900}
2901
2902ALIAS (no_set_local_pref,
2903 no_set_local_pref_val_cmd,
2904 "no set local-preference <0-4294967295>",
2905 NO_STR
2906 SET_STR
2907 "BGP local preference path attribute\n"
2908 "Preference value\n")
2909
2910DEFUN (set_weight,
2911 set_weight_cmd,
2912 "set weight <0-4294967295>",
2913 SET_STR
2914 "BGP weight for routing table\n"
2915 "Weight value\n")
2916{
2917 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2918}
2919
2920DEFUN (no_set_weight,
2921 no_set_weight_cmd,
2922 "no set weight",
2923 NO_STR
2924 SET_STR
2925 "BGP weight for routing table\n")
2926{
2927 if (argc == 0)
2928 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2929
2930 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2931}
2932
2933ALIAS (no_set_weight,
2934 no_set_weight_val_cmd,
2935 "no set weight <0-4294967295>",
2936 NO_STR
2937 SET_STR
2938 "BGP weight for routing table\n"
2939 "Weight value\n")
2940
2941DEFUN (set_aspath_prepend,
2942 set_aspath_prepend_cmd,
2943 "set as-path prepend .<1-65535>",
2944 SET_STR
2945 "Prepend string for a BGP AS-path attribute\n"
2946 "Prepend to the as-path\n"
2947 "AS number\n")
2948{
2949 int ret;
2950 char *str;
2951
2952 str = argv_concat (argv, argc, 0);
2953 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2954 XFREE (MTYPE_TMP, str);
2955
2956 return ret;
2957}
2958
2959DEFUN (no_set_aspath_prepend,
2960 no_set_aspath_prepend_cmd,
2961 "no set as-path prepend",
2962 NO_STR
2963 SET_STR
2964 "Prepend string for a BGP AS-path attribute\n"
2965 "Prepend to the as-path\n")
2966{
2967 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2968}
2969
2970ALIAS (no_set_aspath_prepend,
2971 no_set_aspath_prepend_val_cmd,
2972 "no set as-path prepend .<1-65535>",
2973 NO_STR
2974 SET_STR
2975 "Prepend string for a BGP AS-path attribute\n"
2976 "Prepend to the as-path\n"
2977 "AS number\n")
2978
2979DEFUN (set_community,
2980 set_community_cmd,
2981 "set community .AA:NN",
2982 SET_STR
2983 "BGP community attribute\n"
2984 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2985{
2986 int i;
2987 int first = 0;
2988 int additive = 0;
2989 struct buffer *b;
2990 struct community *com = NULL;
2991 char *str;
2992 char *argstr;
2993 int ret;
2994
2995 b = buffer_new (1024);
2996
2997 for (i = 0; i < argc; i++)
2998 {
2999 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3000 {
3001 additive = 1;
3002 continue;
3003 }
3004
3005 if (first)
3006 buffer_putc (b, ' ');
3007 else
3008 first = 1;
3009
3010 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3011 {
3012 buffer_putstr (b, "internet");
3013 continue;
3014 }
3015 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3016 {
3017 buffer_putstr (b, "local-AS");
3018 continue;
3019 }
3020 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3021 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3022 {
3023 buffer_putstr (b, "no-advertise");
3024 continue;
3025 }
3026 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3027 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3028 {
3029 buffer_putstr (b, "no-export");
3030 continue;
3031 }
3032 buffer_putstr (b, argv[i]);
3033 }
3034 buffer_putc (b, '\0');
3035
3036 /* Fetch result string then compile it to communities attribute. */
3037 str = buffer_getstr (b);
3038 buffer_free (b);
3039
3040 if (str)
3041 {
3042 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003043 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003044 }
3045
3046 /* Can't compile user input into communities attribute. */
3047 if (! com)
3048 {
3049 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3050 return CMD_WARNING;
3051 }
3052
3053 /* Set communites attribute string. */
3054 str = community_str (com);
3055
3056 if (additive)
3057 {
3058 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3059 strcpy (argstr, str);
3060 strcpy (argstr + strlen (str), " additive");
3061 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3062 XFREE (MTYPE_TMP, argstr);
3063 }
3064 else
3065 ret = bgp_route_set_add (vty, vty->index, "community", str);
3066
3067 community_free (com);
3068
3069 return ret;
3070}
3071
3072DEFUN (set_community_none,
3073 set_community_none_cmd,
3074 "set community none",
3075 SET_STR
3076 "BGP community attribute\n"
3077 "No community attribute\n")
3078{
3079 return bgp_route_set_add (vty, vty->index, "community", "none");
3080}
3081
3082DEFUN (no_set_community,
3083 no_set_community_cmd,
3084 "no set community",
3085 NO_STR
3086 SET_STR
3087 "BGP community attribute\n")
3088{
3089 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3090}
3091
3092ALIAS (no_set_community,
3093 no_set_community_val_cmd,
3094 "no set community .AA:NN",
3095 NO_STR
3096 SET_STR
3097 "BGP community attribute\n"
3098 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3099
3100ALIAS (no_set_community,
3101 no_set_community_none_cmd,
3102 "no set community none",
3103 NO_STR
3104 SET_STR
3105 "BGP community attribute\n"
3106 "No community attribute\n")
3107
3108DEFUN (set_community_delete,
3109 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003110 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003111 SET_STR
3112 "set BGP community list (for deletion)\n"
3113 "Community-list number (standard)\n"
3114 "Communitly-list number (expanded)\n"
3115 "Community-list name\n"
3116 "Delete matching communities\n")
3117{
3118 char *str;
3119
3120 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3121 strcpy (str, argv[0]);
3122 strcpy (str + strlen (argv[0]), " delete");
3123
3124 bgp_route_set_add (vty, vty->index, "comm-list", str);
3125
3126 XFREE (MTYPE_TMP, str);
3127 return CMD_SUCCESS;
3128}
3129
3130DEFUN (no_set_community_delete,
3131 no_set_community_delete_cmd,
3132 "no set comm-list",
3133 NO_STR
3134 SET_STR
3135 "set BGP community list (for deletion)\n")
3136{
3137 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3138}
3139
3140ALIAS (no_set_community_delete,
3141 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003142 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003143 NO_STR
3144 SET_STR
3145 "set BGP community list (for deletion)\n"
3146 "Community-list number (standard)\n"
3147 "Communitly-list number (expanded)\n"
3148 "Community-list name\n"
3149 "Delete matching communities\n")
3150
3151DEFUN (set_ecommunity_rt,
3152 set_ecommunity_rt_cmd,
3153 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3154 SET_STR
3155 "BGP extended community attribute\n"
3156 "Route Target extened communityt\n"
3157 "VPN extended community\n")
3158{
3159 int ret;
3160 char *str;
3161
3162 str = argv_concat (argv, argc, 0);
3163 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3164 XFREE (MTYPE_TMP, str);
3165
3166 return ret;
3167}
3168
3169DEFUN (no_set_ecommunity_rt,
3170 no_set_ecommunity_rt_cmd,
3171 "no set extcommunity rt",
3172 NO_STR
3173 SET_STR
3174 "BGP extended community attribute\n"
3175 "Route Target extened communityt\n")
3176{
3177 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3178}
3179
3180ALIAS (no_set_ecommunity_rt,
3181 no_set_ecommunity_rt_val_cmd,
3182 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3183 NO_STR
3184 SET_STR
3185 "BGP extended community attribute\n"
3186 "Route Target extened communityt\n"
3187 "VPN extended community\n")
3188
3189DEFUN (set_ecommunity_soo,
3190 set_ecommunity_soo_cmd,
3191 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3192 SET_STR
3193 "BGP extended community attribute\n"
3194 "Site-of-Origin extended community\n"
3195 "VPN extended community\n")
3196{
3197 int ret;
3198 char *str;
3199
3200 str = argv_concat (argv, argc, 0);
3201 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3202 XFREE (MTYPE_TMP, str);
3203 return ret;
3204}
3205
3206DEFUN (no_set_ecommunity_soo,
3207 no_set_ecommunity_soo_cmd,
3208 "no set extcommunity soo",
3209 NO_STR
3210 SET_STR
3211 "BGP extended community attribute\n"
3212 "Site-of-Origin extended community\n")
3213{
3214 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3215}
3216
3217ALIAS (no_set_ecommunity_soo,
3218 no_set_ecommunity_soo_val_cmd,
3219 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3220 NO_STR
3221 SET_STR
3222 "BGP extended community attribute\n"
3223 "Site-of-Origin extended community\n"
3224 "VPN extended community\n")
3225
3226DEFUN (set_origin,
3227 set_origin_cmd,
3228 "set origin (egp|igp|incomplete)",
3229 SET_STR
3230 "BGP origin code\n"
3231 "remote EGP\n"
3232 "local IGP\n"
3233 "unknown heritage\n")
3234{
3235 if (strncmp (argv[0], "igp", 2) == 0)
3236 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3237 if (strncmp (argv[0], "egp", 1) == 0)
3238 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3239 if (strncmp (argv[0], "incomplete", 2) == 0)
3240 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3241
3242 return CMD_WARNING;
3243}
3244
3245DEFUN (no_set_origin,
3246 no_set_origin_cmd,
3247 "no set origin",
3248 NO_STR
3249 SET_STR
3250 "BGP origin code\n")
3251{
3252 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3253}
3254
3255ALIAS (no_set_origin,
3256 no_set_origin_val_cmd,
3257 "no set origin (egp|igp|incomplete)",
3258 NO_STR
3259 SET_STR
3260 "BGP origin code\n"
3261 "remote EGP\n"
3262 "local IGP\n"
3263 "unknown heritage\n")
3264
3265DEFUN (set_atomic_aggregate,
3266 set_atomic_aggregate_cmd,
3267 "set atomic-aggregate",
3268 SET_STR
3269 "BGP atomic aggregate attribute\n" )
3270{
3271 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3272}
3273
3274DEFUN (no_set_atomic_aggregate,
3275 no_set_atomic_aggregate_cmd,
3276 "no set atomic-aggregate",
3277 NO_STR
3278 SET_STR
3279 "BGP atomic aggregate attribute\n" )
3280{
3281 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3282}
3283
3284DEFUN (set_aggregator_as,
3285 set_aggregator_as_cmd,
3286 "set aggregator as <1-65535> A.B.C.D",
3287 SET_STR
3288 "BGP aggregator attribute\n"
3289 "AS number of aggregator\n"
3290 "AS number\n"
3291 "IP address of aggregator\n")
3292{
3293 int ret;
3294 as_t as;
3295 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003296 char *argstr;
3297
paula94feb32005-05-23 13:17:29 +00003298 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paulfd79ac92004-10-13 05:06:08 +00003299
paul718e3742002-12-13 20:15:29 +00003300 ret = inet_aton (argv[1], &address);
3301 if (ret == 0)
3302 {
3303 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3304 return CMD_WARNING;
3305 }
3306
3307 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3308 strlen (argv[0]) + strlen (argv[1]) + 2);
3309
3310 sprintf (argstr, "%s %s", argv[0], argv[1]);
3311
3312 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3313
3314 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3315
3316 return ret;
3317}
3318
3319DEFUN (no_set_aggregator_as,
3320 no_set_aggregator_as_cmd,
3321 "no set aggregator as",
3322 NO_STR
3323 SET_STR
3324 "BGP aggregator attribute\n"
3325 "AS number of aggregator\n")
3326{
3327 int ret;
3328 as_t as;
3329 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003330 char *argstr;
3331
3332 if (argv == 0)
3333 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3334
paula94feb32005-05-23 13:17:29 +00003335 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paul718e3742002-12-13 20:15:29 +00003336
3337 ret = inet_aton (argv[1], &address);
3338 if (ret == 0)
3339 {
3340 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3341 return CMD_WARNING;
3342 }
3343
3344 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3345 strlen (argv[0]) + strlen (argv[1]) + 2);
3346
3347 sprintf (argstr, "%s %s", argv[0], argv[1]);
3348
3349 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3350
3351 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3352
3353 return ret;
3354}
3355
3356ALIAS (no_set_aggregator_as,
3357 no_set_aggregator_as_val_cmd,
3358 "no set aggregator as <1-65535> A.B.C.D",
3359 NO_STR
3360 SET_STR
3361 "BGP aggregator attribute\n"
3362 "AS number of aggregator\n"
3363 "AS number\n"
3364 "IP address of aggregator\n")
3365
3366
3367#ifdef HAVE_IPV6
3368DEFUN (match_ipv6_address,
3369 match_ipv6_address_cmd,
3370 "match ipv6 address WORD",
3371 MATCH_STR
3372 IPV6_STR
3373 "Match IPv6 address of route\n"
3374 "IPv6 access-list name\n")
3375{
3376 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3377}
3378
3379DEFUN (no_match_ipv6_address,
3380 no_match_ipv6_address_cmd,
3381 "no match ipv6 address WORD",
3382 NO_STR
3383 MATCH_STR
3384 IPV6_STR
3385 "Match IPv6 address of route\n"
3386 "IPv6 access-list name\n")
3387{
3388 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3389}
3390
3391DEFUN (match_ipv6_next_hop,
3392 match_ipv6_next_hop_cmd,
3393 "match ipv6 next-hop X:X::X:X",
3394 MATCH_STR
3395 IPV6_STR
3396 "Match IPv6 next-hop address of route\n"
3397 "IPv6 address of next hop\n")
3398{
3399 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3400}
3401
3402DEFUN (no_match_ipv6_next_hop,
3403 no_match_ipv6_next_hop_cmd,
3404 "no match ipv6 next-hop X:X::X:X",
3405 NO_STR
3406 MATCH_STR
3407 IPV6_STR
3408 "Match IPv6 next-hop address of route\n"
3409 "IPv6 address of next hop\n")
3410{
3411 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3412}
3413
3414DEFUN (match_ipv6_address_prefix_list,
3415 match_ipv6_address_prefix_list_cmd,
3416 "match ipv6 address prefix-list WORD",
3417 MATCH_STR
3418 IPV6_STR
3419 "Match address of route\n"
3420 "Match entries of prefix-lists\n"
3421 "IP prefix-list name\n")
3422{
3423 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3424}
3425
3426DEFUN (no_match_ipv6_address_prefix_list,
3427 no_match_ipv6_address_prefix_list_cmd,
3428 "no match ipv6 address prefix-list WORD",
3429 NO_STR
3430 MATCH_STR
3431 IPV6_STR
3432 "Match address of route\n"
3433 "Match entries of prefix-lists\n"
3434 "IP prefix-list name\n")
3435{
3436 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3437}
3438
3439DEFUN (set_ipv6_nexthop_global,
3440 set_ipv6_nexthop_global_cmd,
3441 "set ipv6 next-hop global X:X::X:X",
3442 SET_STR
3443 IPV6_STR
3444 "IPv6 next-hop address\n"
3445 "IPv6 global address\n"
3446 "IPv6 address of next hop\n")
3447{
3448 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3449}
3450
3451DEFUN (no_set_ipv6_nexthop_global,
3452 no_set_ipv6_nexthop_global_cmd,
3453 "no set ipv6 next-hop global",
3454 NO_STR
3455 SET_STR
3456 IPV6_STR
3457 "IPv6 next-hop address\n"
3458 "IPv6 global address\n")
3459{
3460 if (argc == 0)
3461 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3462
3463 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3464}
3465
3466ALIAS (no_set_ipv6_nexthop_global,
3467 no_set_ipv6_nexthop_global_val_cmd,
3468 "no set ipv6 next-hop global X:X::X:X",
3469 NO_STR
3470 SET_STR
3471 IPV6_STR
3472 "IPv6 next-hop address\n"
3473 "IPv6 global address\n"
3474 "IPv6 address of next hop\n")
3475
3476DEFUN (set_ipv6_nexthop_local,
3477 set_ipv6_nexthop_local_cmd,
3478 "set ipv6 next-hop local X:X::X:X",
3479 SET_STR
3480 IPV6_STR
3481 "IPv6 next-hop address\n"
3482 "IPv6 local address\n"
3483 "IPv6 address of next hop\n")
3484{
3485 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3486}
3487
3488DEFUN (no_set_ipv6_nexthop_local,
3489 no_set_ipv6_nexthop_local_cmd,
3490 "no set ipv6 next-hop local",
3491 NO_STR
3492 SET_STR
3493 IPV6_STR
3494 "IPv6 next-hop address\n"
3495 "IPv6 local address\n")
3496{
3497 if (argc == 0)
3498 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3499
3500 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3501}
3502
3503ALIAS (no_set_ipv6_nexthop_local,
3504 no_set_ipv6_nexthop_local_val_cmd,
3505 "no set ipv6 next-hop local X:X::X:X",
3506 NO_STR
3507 SET_STR
3508 IPV6_STR
3509 "IPv6 next-hop address\n"
3510 "IPv6 local address\n"
3511 "IPv6 address of next hop\n")
3512#endif /* HAVE_IPV6 */
3513
3514DEFUN (set_vpnv4_nexthop,
3515 set_vpnv4_nexthop_cmd,
3516 "set vpnv4 next-hop A.B.C.D",
3517 SET_STR
3518 "VPNv4 information\n"
3519 "VPNv4 next-hop address\n"
3520 "IP address of next hop\n")
3521{
3522 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3523}
3524
3525DEFUN (no_set_vpnv4_nexthop,
3526 no_set_vpnv4_nexthop_cmd,
3527 "no set vpnv4 next-hop",
3528 NO_STR
3529 SET_STR
3530 "VPNv4 information\n"
3531 "VPNv4 next-hop address\n")
3532{
3533 if (argc == 0)
3534 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3535
3536 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3537}
3538
3539ALIAS (no_set_vpnv4_nexthop,
3540 no_set_vpnv4_nexthop_val_cmd,
3541 "no set vpnv4 next-hop A.B.C.D",
3542 NO_STR
3543 SET_STR
3544 "VPNv4 information\n"
3545 "VPNv4 next-hop address\n"
3546 "IP address of next hop\n")
3547
3548DEFUN (set_originator_id,
3549 set_originator_id_cmd,
3550 "set originator-id A.B.C.D",
3551 SET_STR
3552 "BGP originator ID attribute\n"
3553 "IP address of originator\n")
3554{
3555 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3556}
3557
3558DEFUN (no_set_originator_id,
3559 no_set_originator_id_cmd,
3560 "no set originator-id",
3561 NO_STR
3562 SET_STR
3563 "BGP originator ID attribute\n")
3564{
3565 if (argc == 0)
3566 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3567
3568 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3569}
3570
3571ALIAS (no_set_originator_id,
3572 no_set_originator_id_val_cmd,
3573 "no set originator-id A.B.C.D",
3574 NO_STR
3575 SET_STR
3576 "BGP originator ID attribute\n"
3577 "IP address of originator\n")
3578
3579
3580/* Initialization of route map. */
3581void
3582bgp_route_map_init ()
3583{
3584 route_map_init ();
3585 route_map_init_vty ();
3586 route_map_add_hook (bgp_route_map_update);
3587 route_map_delete_hook (bgp_route_map_update);
3588
paulfee0f4c2004-09-13 05:12:46 +00003589 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003590 route_map_install_match (&route_match_ip_address_cmd);
3591 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003592 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003593 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3594 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003595 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003596 route_map_install_match (&route_match_aspath_cmd);
3597 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003598 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003599 route_map_install_match (&route_match_metric_cmd);
3600 route_map_install_match (&route_match_origin_cmd);
3601
3602 route_map_install_set (&route_set_ip_nexthop_cmd);
3603 route_map_install_set (&route_set_local_pref_cmd);
3604 route_map_install_set (&route_set_weight_cmd);
3605 route_map_install_set (&route_set_metric_cmd);
3606 route_map_install_set (&route_set_aspath_prepend_cmd);
3607 route_map_install_set (&route_set_origin_cmd);
3608 route_map_install_set (&route_set_atomic_aggregate_cmd);
3609 route_map_install_set (&route_set_aggregator_as_cmd);
3610 route_map_install_set (&route_set_community_cmd);
3611 route_map_install_set (&route_set_community_delete_cmd);
3612 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3613 route_map_install_set (&route_set_originator_id_cmd);
3614 route_map_install_set (&route_set_ecommunity_rt_cmd);
3615 route_map_install_set (&route_set_ecommunity_soo_cmd);
3616
paulfee0f4c2004-09-13 05:12:46 +00003617 install_element (RMAP_NODE, &match_peer_cmd);
3618 install_element (RMAP_NODE, &match_peer_local_cmd);
3619 install_element (RMAP_NODE, &no_match_peer_cmd);
3620 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3621 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003622 install_element (RMAP_NODE, &match_ip_address_cmd);
3623 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3624 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3625 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3626 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3627 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003628 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3629 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3630 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003631
3632 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3633 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3634 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3635 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3636 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3637 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003638 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3639 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3640 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003641
3642 install_element (RMAP_NODE, &match_aspath_cmd);
3643 install_element (RMAP_NODE, &no_match_aspath_cmd);
3644 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3645 install_element (RMAP_NODE, &match_metric_cmd);
3646 install_element (RMAP_NODE, &no_match_metric_cmd);
3647 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3648 install_element (RMAP_NODE, &match_community_cmd);
3649 install_element (RMAP_NODE, &match_community_exact_cmd);
3650 install_element (RMAP_NODE, &no_match_community_cmd);
3651 install_element (RMAP_NODE, &no_match_community_val_cmd);
3652 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003653 install_element (RMAP_NODE, &match_ecommunity_cmd);
3654 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3655 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003656 install_element (RMAP_NODE, &match_origin_cmd);
3657 install_element (RMAP_NODE, &no_match_origin_cmd);
3658 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3659
3660 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003661 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003662 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3663 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3664 install_element (RMAP_NODE, &set_local_pref_cmd);
3665 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3666 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3667 install_element (RMAP_NODE, &set_weight_cmd);
3668 install_element (RMAP_NODE, &no_set_weight_cmd);
3669 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3670 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003671 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003672 install_element (RMAP_NODE, &no_set_metric_cmd);
3673 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3674 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3675 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3676 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3677 install_element (RMAP_NODE, &set_origin_cmd);
3678 install_element (RMAP_NODE, &no_set_origin_cmd);
3679 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3680 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3681 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3682 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3683 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3684 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3685 install_element (RMAP_NODE, &set_community_cmd);
3686 install_element (RMAP_NODE, &set_community_none_cmd);
3687 install_element (RMAP_NODE, &no_set_community_cmd);
3688 install_element (RMAP_NODE, &no_set_community_val_cmd);
3689 install_element (RMAP_NODE, &no_set_community_none_cmd);
3690 install_element (RMAP_NODE, &set_community_delete_cmd);
3691 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3692 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3693 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3694 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3695 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3696 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3697 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3698 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3699 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3700 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3701 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3702 install_element (RMAP_NODE, &set_originator_id_cmd);
3703 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3704 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3705
3706#ifdef HAVE_IPV6
3707 route_map_install_match (&route_match_ipv6_address_cmd);
3708 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3709 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3710 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3711 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3712
3713 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3714 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3715 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3716 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3717 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3718 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3719 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3720 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3721 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3722 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3723 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3724 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3725#endif /* HAVE_IPV6 */
3726}