blob: a2923fb1b6900950850fecb11f94250cc20e1d58 [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
60 ip route-source : (This will not be implemented by bgpd)
61 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
98/* `match ip address IP_ACCESS_LIST' */
99
100/* Match function should return 1 if match is success else return
101 zero. */
102route_map_result_t
103route_match_ip_address (void *rule, struct prefix *prefix,
104 route_map_object_t type, void *object)
105{
106 struct access_list *alist;
107 /* struct prefix_ipv4 match; */
108
109 if (type == RMAP_BGP)
110 {
111 alist = access_list_lookup (AFI_IP, (char *) rule);
112 if (alist == NULL)
113 return RMAP_NOMATCH;
114
115 return (access_list_apply (alist, prefix) == FILTER_DENY ?
116 RMAP_NOMATCH : RMAP_MATCH);
117 }
118 return RMAP_NOMATCH;
119}
120
121/* Route map `ip address' match statement. `arg' should be
122 access-list name. */
123void *
124route_match_ip_address_compile (char *arg)
125{
126 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
127}
128
129/* Free route map's compiled `ip address' value. */
130void
131route_match_ip_address_free (void *rule)
132{
133 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
134}
135
136/* Route map commands for ip address matching. */
137struct route_map_rule_cmd route_match_ip_address_cmd =
138{
139 "ip address",
140 route_match_ip_address,
141 route_match_ip_address_compile,
142 route_match_ip_address_free
143};
144
145/* `match ip next-hop IP_ADDRESS' */
146
147/* Match function return 1 if match is success else return zero. */
148route_map_result_t
149route_match_ip_next_hop (void *rule, struct prefix *prefix,
150 route_map_object_t type, void *object)
151{
152 struct access_list *alist;
153 struct bgp_info *bgp_info;
154 struct prefix_ipv4 p;
155
156 if (type == RMAP_BGP)
157 {
158 bgp_info = object;
159 p.family = AF_INET;
160 p.prefix = bgp_info->attr->nexthop;
161 p.prefixlen = IPV4_MAX_BITLEN;
162
163 alist = access_list_lookup (AFI_IP, (char *) rule);
164 if (alist == NULL)
165 return RMAP_NOMATCH;
166
167 return (access_list_apply (alist, &p) == FILTER_DENY ?
168 RMAP_NOMATCH : RMAP_MATCH);
169 }
170 return RMAP_NOMATCH;
171}
172
173/* Route map `ip next-hop' match statement. `arg' is
174 access-list name. */
175void *
176route_match_ip_next_hop_compile (char *arg)
177{
178 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
179}
180
181/* Free route map's compiled `ip address' value. */
182void
183route_match_ip_next_hop_free (void *rule)
184{
185 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
186}
187
188/* Route map commands for ip next-hop matching. */
189struct route_map_rule_cmd route_match_ip_next_hop_cmd =
190{
191 "ip next-hop",
192 route_match_ip_next_hop,
193 route_match_ip_next_hop_compile,
194 route_match_ip_next_hop_free
195};
196
197/* `match ip address prefix-list PREFIX_LIST' */
198
199route_map_result_t
200route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
201 route_map_object_t type, void *object)
202{
203 struct prefix_list *plist;
204
205 if (type == RMAP_BGP)
206 {
207 plist = prefix_list_lookup (AFI_IP, (char *) rule);
208 if (plist == NULL)
209 return RMAP_NOMATCH;
210
211 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
212 RMAP_NOMATCH : RMAP_MATCH);
213 }
214 return RMAP_NOMATCH;
215}
216
217void *
218route_match_ip_address_prefix_list_compile (char *arg)
219{
220 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
221}
222
223void
224route_match_ip_address_prefix_list_free (void *rule)
225{
226 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
227}
228
229struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
230{
231 "ip address prefix-list",
232 route_match_ip_address_prefix_list,
233 route_match_ip_address_prefix_list_compile,
234 route_match_ip_address_prefix_list_free
235};
236
237/* `match ip next-hop prefix-list PREFIX_LIST' */
238
239route_map_result_t
240route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
241 route_map_object_t type, void *object)
242{
243 struct prefix_list *plist;
244 struct bgp_info *bgp_info;
245 struct prefix_ipv4 p;
246
247 if (type == RMAP_BGP)
248 {
249 bgp_info = object;
250 p.family = AF_INET;
251 p.prefix = bgp_info->attr->nexthop;
252 p.prefixlen = IPV4_MAX_BITLEN;
253
254 plist = prefix_list_lookup (AFI_IP, (char *) rule);
255 if (plist == NULL)
256 return RMAP_NOMATCH;
257
258 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
259 RMAP_NOMATCH : RMAP_MATCH);
260 }
261 return RMAP_NOMATCH;
262}
263
264void *
265route_match_ip_next_hop_prefix_list_compile (char *arg)
266{
267 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
268}
269
270void
271route_match_ip_next_hop_prefix_list_free (void *rule)
272{
273 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
274}
275
276struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
277{
278 "ip next-hop prefix-list",
279 route_match_ip_next_hop_prefix_list,
280 route_match_ip_next_hop_prefix_list_compile,
281 route_match_ip_next_hop_prefix_list_free
282};
283
284/* `match metric METRIC' */
285
286/* Match function return 1 if match is success else return zero. */
287route_map_result_t
288route_match_metric (void *rule, struct prefix *prefix,
289 route_map_object_t type, void *object)
290{
291 u_int32_t *med;
292 struct bgp_info *bgp_info;
293
294 if (type == RMAP_BGP)
295 {
296 med = rule;
297 bgp_info = object;
298
299 if (bgp_info->attr->med == *med)
300 return RMAP_MATCH;
301 else
302 return RMAP_NOMATCH;
303 }
304 return RMAP_NOMATCH;
305}
306
307/* Route map `match metric' match statement. `arg' is MED value */
308void *
309route_match_metric_compile (char *arg)
310{
311 u_int32_t *med;
312 char *endptr = NULL;
313
314 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
315 *med = strtoul (arg, &endptr, 10);
316 if (*endptr != '\0' || *med == ULONG_MAX)
317 {
318 XFREE (MTYPE_ROUTE_MAP_COMPILED, med);
319 return NULL;
320 }
321 return med;
322}
323
324/* Free route map's compiled `match metric' value. */
325void
326route_match_metric_free (void *rule)
327{
328 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
329}
330
331/* Route map commands for metric matching. */
332struct route_map_rule_cmd route_match_metric_cmd =
333{
334 "metric",
335 route_match_metric,
336 route_match_metric_compile,
337 route_match_metric_free
338};
339
340/* `match as-path ASPATH' */
341
342/* Match function for as-path match. I assume given object is */
343route_map_result_t
344route_match_aspath (void *rule, struct prefix *prefix,
345 route_map_object_t type, void *object)
346{
347
348 struct as_list *as_list;
349 struct bgp_info *bgp_info;
350
351 if (type == RMAP_BGP)
352 {
353 as_list = as_list_lookup ((char *) rule);
354 if (as_list == NULL)
355 return RMAP_NOMATCH;
356
357 bgp_info = object;
358
359 /* Perform match. */
360 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
361 }
362 return RMAP_NOMATCH;
363}
364
365/* Compile function for as-path match. */
366void *
367route_match_aspath_compile (char *arg)
368{
369 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
370}
371
372/* Compile function for as-path match. */
373void
374route_match_aspath_free (void *rule)
375{
376 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
377}
378
379/* Route map commands for aspath matching. */
380struct route_map_rule_cmd route_match_aspath_cmd =
381{
382 "as-path",
383 route_match_aspath,
384 route_match_aspath_compile,
385 route_match_aspath_free
386};
387
388#if ROUTE_MATCH_ASPATH_OLD
389/* `match as-path ASPATH' */
390
391/* Match function for as-path match. I assume given object is */
392int
393route_match_aspath (void *rule, struct prefix *prefix, void *object)
394{
395 regex_t *regex;
396 struct bgp_info *bgp_info;
397
398 regex = rule;
399 bgp_info = object;
400
401 /* Perform match. */
402 return bgp_regexec (regex, bgp_info->attr->aspath);
403}
404
405/* Compile function for as-path match. */
406void *
407route_match_aspath_compile (char *arg)
408{
409 regex_t *regex;
410
411 regex = bgp_regcomp (arg);
412 if (! regex)
413 return NULL;
414
415 return regex;
416}
417
418/* Compile function for as-path match. */
419void
420route_match_aspath_free (void *rule)
421{
422 regex_t *regex = rule;
423
424 bgp_regex_free (regex);
425}
426
427/* Route map commands for aspath matching. */
428struct route_map_rule_cmd route_match_aspath_cmd =
429{
430 "as-path",
431 route_match_aspath,
432 route_match_aspath_compile,
433 route_match_aspath_free
434};
435#endif /* ROUTE_MATCH_ASPATH_OLD */
436
437/* `match community COMMUNIY' */
438struct rmap_community
439{
440 char *name;
441 int exact;
442};
443
444/* Match function for community match. */
445route_map_result_t
446route_match_community (void *rule, struct prefix *prefix,
447 route_map_object_t type, void *object)
448{
449 struct community_list *list;
450 struct bgp_info *bgp_info;
451 struct rmap_community *rcom;
452
453 if (type == RMAP_BGP)
454 {
455 bgp_info = object;
456 rcom = rule;
457
458 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_AUTO);
459 if (! list)
460 return RMAP_NOMATCH;
461
462 if (rcom->exact)
463 {
464 if (community_list_exact_match (bgp_info->attr->community, list))
465 return RMAP_MATCH;
466 }
467 else
468 {
469 if (community_list_match (bgp_info->attr->community, list))
470 return RMAP_MATCH;
471 }
472 }
473 return RMAP_NOMATCH;
474}
475
476/* Compile function for community match. */
477void *
478route_match_community_compile (char *arg)
479{
480 struct rmap_community *rcom;
481 int len;
482 char *p;
483
484 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
485
486 p = strchr (arg, ' ');
487 if (p)
488 {
489 len = p - arg;
490 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
491 memcpy (rcom->name, arg, len);
492 rcom->exact = 1;
493 }
494 else
495 {
496 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
497 rcom->exact = 0;
498 }
499 return rcom;
500}
501
502/* Compile function for community match. */
503void
504route_match_community_free (void *rule)
505{
506 struct rmap_community *rcom = rule;
507
508 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
509 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
510}
511
512/* Route map commands for community matching. */
513struct route_map_rule_cmd route_match_community_cmd =
514{
515 "community",
516 route_match_community,
517 route_match_community_compile,
518 route_match_community_free
519};
520
paul73ffb252003-04-19 15:49:49 +0000521/* Match function for extcommunity match. */
522route_map_result_t
523route_match_ecommunity (void *rule, struct prefix *prefix,
524 route_map_object_t type, void *object)
525{
526 struct community_list *list;
527 struct bgp_info *bgp_info;
528
529 if (type == RMAP_BGP)
530 {
531 bgp_info = object;
532
533 list = community_list_lookup (bgp_clist, (char *) rule,
534 EXTCOMMUNITY_LIST_AUTO);
535 if (! list)
536 return RMAP_NOMATCH;
537
538 if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
539 return RMAP_MATCH;
540 }
541 return RMAP_NOMATCH;
542}
543
544/* Compile function for extcommunity match. */
545void *
546route_match_ecommunity_compile (char *arg)
547{
548 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
549}
550
551/* Compile function for extcommunity match. */
552void
553route_match_ecommunity_free (void *rule)
554{
555 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
556}
557
558/* Route map commands for community matching. */
559struct route_map_rule_cmd route_match_ecommunity_cmd =
560{
561 "extcommunity",
562 route_match_ecommunity,
563 route_match_ecommunity_compile,
564 route_match_ecommunity_free
565};
566
paul718e3742002-12-13 20:15:29 +0000567/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
568 and `address-family vpnv4'. */
569
570/* `match origin' */
571route_map_result_t
572route_match_origin (void *rule, struct prefix *prefix,
573 route_map_object_t type, void *object)
574{
575 u_char *origin;
576 struct bgp_info *bgp_info;
577
578 if (type == RMAP_BGP)
579 {
580 origin = rule;
581 bgp_info = object;
582
583 if (bgp_info->attr->origin == *origin)
584 return RMAP_MATCH;
585 }
586
587 return RMAP_NOMATCH;
588}
589
590void *
591route_match_origin_compile (char *arg)
592{
593 u_char *origin;
594
595 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
596
597 if (strcmp (arg, "igp") == 0)
598 *origin = 0;
599 else if (strcmp (arg, "egp") == 0)
600 *origin = 1;
601 else
602 *origin = 2;
603
604 return origin;
605}
606
607/* Free route map's compiled `ip address' value. */
608void
609route_match_origin_free (void *rule)
610{
611 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
612}
613
614/* Route map commands for origin matching. */
615struct route_map_rule_cmd route_match_origin_cmd =
616{
617 "origin",
618 route_match_origin,
619 route_match_origin_compile,
620 route_match_origin_free
621};
622/* `set ip next-hop IP_ADDRESS' */
623
624/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000625struct rmap_ip_nexthop_set
626{
627 struct in_addr *address;
628 int peer_address;
629};
630
paul718e3742002-12-13 20:15:29 +0000631route_map_result_t
632route_set_ip_nexthop (void *rule, struct prefix *prefix,
633 route_map_object_t type, void *object)
634{
paulac41b2a2003-08-12 05:32:27 +0000635 struct rmap_ip_nexthop_set *rins = rule;
636 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000637 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000638 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000639
640 if (type == RMAP_BGP)
641 {
paul718e3742002-12-13 20:15:29 +0000642 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000643 peer = bgp_info->peer;
644
645 if (rins->peer_address)
646 {
647 if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN)
648 && peer->su_remote
649 && sockunion_family (peer->su_remote) == AF_INET)
650 {
651 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
652 bgp_info->attr->nexthop = peer_address;
653 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
654 }
655 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
656 && peer->su_local
657 && sockunion_family (peer->su_local) == AF_INET)
658 {
659 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
660 bgp_info->attr->nexthop = peer_address;
661 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
662 }
663 }
664 else
665 {
666 /* Set next hop value. */
667 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
668 bgp_info->attr->nexthop = *rins->address;
669 }
paul718e3742002-12-13 20:15:29 +0000670 }
671
672 return RMAP_OKAY;
673}
674
675/* Route map `ip nexthop' compile function. Given string is converted
676 to struct in_addr structure. */
677void *
678route_set_ip_nexthop_compile (char *arg)
679{
paulac41b2a2003-08-12 05:32:27 +0000680 struct rmap_ip_nexthop_set *rins;
681 struct in_addr *address = NULL;
682 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000683 int ret;
paul718e3742002-12-13 20:15:29 +0000684
paulac41b2a2003-08-12 05:32:27 +0000685 if (strcmp (arg, "peer-address") == 0)
686 peer_address = 1;
687 else
paul718e3742002-12-13 20:15:29 +0000688 {
paulac41b2a2003-08-12 05:32:27 +0000689 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
690 ret = inet_aton (arg, address);
691
692 if (ret == 0)
693 {
694 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
695 return NULL;
696 }
paul718e3742002-12-13 20:15:29 +0000697 }
698
paulac41b2a2003-08-12 05:32:27 +0000699 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
700 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
701
702 rins->address = address;
703 rins->peer_address = peer_address;
704
705 return rins;
paul718e3742002-12-13 20:15:29 +0000706}
707
708/* Free route map's compiled `ip nexthop' value. */
709void
710route_set_ip_nexthop_free (void *rule)
711{
paulac41b2a2003-08-12 05:32:27 +0000712 struct rmap_ip_nexthop_set *rins = rule;
713
714 if (rins->address)
715 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
716
717 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000718}
719
720/* Route map commands for ip nexthop set. */
721struct route_map_rule_cmd route_set_ip_nexthop_cmd =
722{
723 "ip next-hop",
724 route_set_ip_nexthop,
725 route_set_ip_nexthop_compile,
726 route_set_ip_nexthop_free
727};
728
729/* `set local-preference LOCAL_PREF' */
730
731/* Set local preference. */
732route_map_result_t
733route_set_local_pref (void *rule, struct prefix *prefix,
734 route_map_object_t type, void *object)
735{
736 u_int32_t *local_pref;
737 struct bgp_info *bgp_info;
738
739 if (type == RMAP_BGP)
740 {
741 /* Fetch routemap's rule information. */
742 local_pref = rule;
743 bgp_info = object;
744
745 /* Set local preference value. */
746 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
747 bgp_info->attr->local_pref = *local_pref;
748 }
749
750 return RMAP_OKAY;
751}
752
753/* set local preference compilation. */
754void *
755route_set_local_pref_compile (char *arg)
756{
757 u_int32_t *local_pref;
758 char *endptr = NULL;
759
760 /* Local preference value shoud be integer. */
761 if (! all_digit (arg))
762 return NULL;
763
764 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
765 *local_pref = strtoul (arg, &endptr, 10);
766 if (*endptr != '\0' || *local_pref == ULONG_MAX)
767 {
768 XFREE (MTYPE_ROUTE_MAP_COMPILED, local_pref);
769 return NULL;
770 }
771 return local_pref;
772}
773
774/* Free route map's local preference value. */
775void
776route_set_local_pref_free (void *rule)
777{
778 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
779}
780
781/* Set local preference rule structure. */
782struct route_map_rule_cmd route_set_local_pref_cmd =
783{
784 "local-preference",
785 route_set_local_pref,
786 route_set_local_pref_compile,
787 route_set_local_pref_free,
788};
789
790/* `set weight WEIGHT' */
791
792/* Set weight. */
793route_map_result_t
794route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
795 void *object)
796{
797 u_int32_t *weight;
798 struct bgp_info *bgp_info;
799
800 if (type == RMAP_BGP)
801 {
802 /* Fetch routemap's rule information. */
803 weight = rule;
804 bgp_info = object;
805
806 /* Set weight value. */
807 bgp_info->attr->weight = *weight;
808 }
809
810 return RMAP_OKAY;
811}
812
813/* set local preference compilation. */
814void *
815route_set_weight_compile (char *arg)
816{
817 u_int32_t *weight;
818 char *endptr = NULL;
819
820 /* Local preference value shoud be integer. */
821 if (! all_digit (arg))
822 return NULL;
823
824 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
825 *weight = strtoul (arg, &endptr, 10);
826 if (*endptr != '\0' || *weight == ULONG_MAX)
827 {
828 XFREE (MTYPE_ROUTE_MAP_COMPILED, weight);
829 return NULL;
830 }
831 return weight;
832}
833
834/* Free route map's local preference value. */
835void
836route_set_weight_free (void *rule)
837{
838 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
839}
840
841/* Set local preference rule structure. */
842struct route_map_rule_cmd route_set_weight_cmd =
843{
844 "weight",
845 route_set_weight,
846 route_set_weight_compile,
847 route_set_weight_free,
848};
849
850/* `set metric METRIC' */
851
852/* Set metric to attribute. */
853route_map_result_t
854route_set_metric (void *rule, struct prefix *prefix,
855 route_map_object_t type, void *object)
856{
857 char *metric;
858 u_int32_t metric_val;
859 struct bgp_info *bgp_info;
860
861 if (type == RMAP_BGP)
862 {
863 /* Fetch routemap's rule information. */
864 metric = rule;
865 bgp_info = object;
866
867 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
868 bgp_info->attr->med = 0;
869 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
870
871 if (all_digit (metric))
872 {
873 metric_val = strtoul (metric, (char **)NULL, 10);
874 bgp_info->attr->med = metric_val;
875 }
876 else
877 {
878 metric_val = strtoul (metric+1, (char **)NULL, 10);
879
880 if (strncmp (metric, "+", 1) == 0)
881 {
paul537d8ea2003-08-27 06:45:32 +0000882 if (bgp_info->attr->med/2 + metric_val/2 > UINT32_MAX/2)
883 bgp_info->attr->med = UINT32_MAX-1;
paul718e3742002-12-13 20:15:29 +0000884 else
paul537d8ea2003-08-27 06:45:32 +0000885 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +0000886 }
887 else if (strncmp (metric, "-", 1) == 0)
888 {
paul537d8ea2003-08-27 06:45:32 +0000889 if (bgp_info->attr->med <= metric_val)
890 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +0000891 else
paul537d8ea2003-08-27 06:45:32 +0000892 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +0000893 }
894 }
895 }
896 return RMAP_OKAY;
897}
898
899/* set metric compilation. */
900void *
901route_set_metric_compile (char *arg)
902{
903 u_int32_t metric;
904 char *endptr = NULL;
905
906 if (all_digit (arg))
907 {
908 /* set metric value check*/
909 metric = strtoul (arg, &endptr, 10);
910 if (*endptr != '\0' || metric == ULONG_MAX)
911 return NULL;
912 }
913 else
914 {
915 /* set metric +/-value check */
916 if ((strncmp (arg, "+", 1) != 0
917 && strncmp (arg, "-", 1) != 0)
918 || (! all_digit (arg+1)))
919 return NULL;
920
921 metric = strtoul (arg+1, &endptr, 10);
922 if (*endptr != '\0' || metric == ULONG_MAX)
923 return NULL;
924 }
925
926 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
927}
928
929/* Free route map's compiled `set metric' value. */
930void
931route_set_metric_free (void *rule)
932{
933 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
934}
935
936/* Set metric rule structure. */
937struct route_map_rule_cmd route_set_metric_cmd =
938{
939 "metric",
940 route_set_metric,
941 route_set_metric_compile,
942 route_set_metric_free,
943};
944
945/* `set as-path prepend ASPATH' */
946
947/* For AS path prepend mechanism. */
948route_map_result_t
949route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
950{
951 struct aspath *aspath;
952 struct aspath *new;
953 struct bgp_info *binfo;
954
955 if (type == RMAP_BGP)
956 {
957 aspath = rule;
958 binfo = object;
959
960 if (binfo->attr->aspath->refcnt)
961 new = aspath_dup (binfo->attr->aspath);
962 else
963 new = binfo->attr->aspath;
964
965 aspath_prepend (aspath, new);
966 binfo->attr->aspath = new;
967 }
968
969 return RMAP_OKAY;
970}
971
972/* Compile function for as-path prepend. */
973void *
974route_set_aspath_prepend_compile (char *arg)
975{
976 struct aspath *aspath;
977
978 aspath = aspath_str2aspath (arg);
979 if (! aspath)
980 return NULL;
981 return aspath;
982}
983
984/* Compile function for as-path prepend. */
985void
986route_set_aspath_prepend_free (void *rule)
987{
988 struct aspath *aspath = rule;
989 aspath_free (aspath);
990}
991
992/* Set metric rule structure. */
993struct route_map_rule_cmd route_set_aspath_prepend_cmd =
994{
995 "as-path prepend",
996 route_set_aspath_prepend,
997 route_set_aspath_prepend_compile,
998 route_set_aspath_prepend_free,
999};
1000
1001/* `set community COMMUNITY' */
1002struct rmap_com_set
1003{
1004 struct community *com;
1005 int additive;
1006 int none;
1007};
1008
1009/* For community set mechanism. */
1010route_map_result_t
1011route_set_community (void *rule, struct prefix *prefix,
1012 route_map_object_t type, void *object)
1013{
1014 struct rmap_com_set *rcs;
1015 struct bgp_info *binfo;
1016 struct attr *attr;
1017 struct community *new = NULL;
1018 struct community *old;
1019 struct community *merge;
1020
1021 if (type == RMAP_BGP)
1022 {
1023 rcs = rule;
1024 binfo = object;
1025 attr = binfo->attr;
1026 old = attr->community;
1027
1028 /* "none" case. */
1029 if (rcs->none)
1030 {
1031 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1032 attr->community = NULL;
1033 return RMAP_OKAY;
1034 }
1035
1036 /* "additive" case. */
1037 if (rcs->additive && old)
1038 {
1039 merge = community_merge (community_dup (old), rcs->com);
1040 new = community_uniq_sort (merge);
1041 community_free (merge);
1042 }
1043 else
1044 new = community_dup (rcs->com);
1045
1046 attr->community = new;
1047 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1048 }
1049
1050 return RMAP_OKAY;
1051}
1052
1053/* Compile function for set community. */
1054void *
1055route_set_community_compile (char *arg)
1056{
1057 struct rmap_com_set *rcs;
1058 struct community *com = NULL;
1059 char *sp;
1060 int additive = 0;
1061 int none = 0;
1062
1063 if (strcmp (arg, "none") == 0)
1064 none = 1;
1065 else
1066 {
1067 sp = strstr (arg, "additive");
1068
1069 if (sp && sp > arg)
1070 {
1071 /* "additive" keyworkd is included. */
1072 additive = 1;
1073 *(sp - 1) = '\0';
1074 }
1075
1076 com = community_str2com (arg);
1077
1078 if (additive)
1079 *(sp - 1) = ' ';
1080
1081 if (! com)
1082 return NULL;
1083 }
1084
1085 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1086 memset (rcs, 0, sizeof (struct rmap_com_set));
1087
1088 rcs->com = com;
1089 rcs->additive = additive;
1090 rcs->none = none;
1091
1092 return rcs;
1093}
1094
1095/* Free function for set community. */
1096void
1097route_set_community_free (void *rule)
1098{
1099 struct rmap_com_set *rcs = rule;
1100
1101 if (rcs->com)
1102 community_free (rcs->com);
1103 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1104}
1105
1106/* Set community rule structure. */
1107struct route_map_rule_cmd route_set_community_cmd =
1108{
1109 "community",
1110 route_set_community,
1111 route_set_community_compile,
1112 route_set_community_free,
1113};
1114
1115/* `set comm-list (<1-99>|<100-199>|WORD) delete' */
1116
1117/* For community set mechanism. */
1118route_map_result_t
1119route_set_community_delete (void *rule, struct prefix *prefix,
1120 route_map_object_t type, void *object)
1121{
1122 struct community_list *list;
1123 struct community *merge;
1124 struct community *new;
1125 struct community *old;
1126 struct bgp_info *binfo;
1127
1128 if (type == RMAP_BGP)
1129 {
1130 if (! rule)
1131 return RMAP_OKAY;
1132
1133 binfo = object;
1134 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_AUTO);
1135 old = binfo->attr->community;
1136
1137 if (list && old)
1138 {
1139 merge = community_list_match_delete (community_dup (old), list);
1140 new = community_uniq_sort (merge);
1141 community_free (merge);
1142
1143 if (new->size == 0)
1144 {
1145 binfo->attr->community = NULL;
1146 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1147 community_free (new);
1148 }
1149 else
1150 {
1151 binfo->attr->community = new;
1152 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1153 }
1154 }
1155 }
1156
1157 return RMAP_OKAY;
1158}
1159
1160/* Compile function for set community. */
1161void *
1162route_set_community_delete_compile (char *arg)
1163{
1164 char *p;
1165 char *str;
1166 int len;
1167
1168 p = strchr (arg, ' ');
1169 if (p)
1170 {
1171 len = p - arg;
1172 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1173 memcpy (str, arg, len);
1174 }
1175 else
1176 str = NULL;
1177
1178 return str;
1179}
1180
1181/* Free function for set community. */
1182void
1183route_set_community_delete_free (void *rule)
1184{
1185 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1186}
1187
1188/* Set community rule structure. */
1189struct route_map_rule_cmd route_set_community_delete_cmd =
1190{
1191 "comm-list",
1192 route_set_community_delete,
1193 route_set_community_delete_compile,
1194 route_set_community_delete_free,
1195};
1196
1197/* `set extcommunity rt COMMUNITY' */
1198
1199/* For community set mechanism. */
1200route_map_result_t
1201route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1202 route_map_object_t type, void *object)
1203{
1204 struct ecommunity *ecom;
1205 struct ecommunity *new_ecom;
1206 struct ecommunity *old_ecom;
1207 struct bgp_info *bgp_info;
1208
1209 if (type == RMAP_BGP)
1210 {
1211 ecom = rule;
1212 bgp_info = object;
1213
1214 if (! ecom)
1215 return RMAP_OKAY;
1216
1217 /* We assume additive for Extended Community. */
1218 old_ecom = bgp_info->attr->ecommunity;
1219
1220 if (old_ecom)
1221 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1222 else
1223 new_ecom = ecommunity_dup (ecom);
1224
1225 bgp_info->attr->ecommunity = new_ecom;
1226
1227 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1228 }
1229 return RMAP_OKAY;
1230}
1231
1232/* Compile function for set community. */
1233void *
1234route_set_ecommunity_rt_compile (char *arg)
1235{
1236 struct ecommunity *ecom;
1237
1238 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1239 if (! ecom)
1240 return NULL;
1241 return ecom;
1242}
1243
1244/* Free function for set community. */
1245void
1246route_set_ecommunity_rt_free (void *rule)
1247{
1248 struct ecommunity *ecom = rule;
1249 ecommunity_free (ecom);
1250}
1251
1252/* Set community rule structure. */
1253struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1254{
1255 "extcommunity rt",
1256 route_set_ecommunity_rt,
1257 route_set_ecommunity_rt_compile,
1258 route_set_ecommunity_rt_free,
1259};
1260
1261/* `set extcommunity soo COMMUNITY' */
1262
1263/* For community set mechanism. */
1264route_map_result_t
1265route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1266 route_map_object_t type, void *object)
1267{
1268 struct ecommunity *ecom;
1269 struct bgp_info *bgp_info;
1270
1271 if (type == RMAP_BGP)
1272 {
1273 ecom = rule;
1274 bgp_info = object;
1275
1276 if (! ecom)
1277 return RMAP_OKAY;
1278
1279 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1280 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1281 }
1282 return RMAP_OKAY;
1283}
1284
1285/* Compile function for set community. */
1286void *
1287route_set_ecommunity_soo_compile (char *arg)
1288{
1289 struct ecommunity *ecom;
1290
1291 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1292 if (! ecom)
1293 return NULL;
1294
1295 return ecom;
1296}
1297
1298/* Free function for set community. */
1299void
1300route_set_ecommunity_soo_free (void *rule)
1301{
1302 struct ecommunity *ecom = rule;
1303 ecommunity_free (ecom);
1304}
1305
1306/* Set community rule structure. */
1307struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1308{
1309 "extcommunity soo",
1310 route_set_ecommunity_soo,
1311 route_set_ecommunity_soo_compile,
1312 route_set_ecommunity_soo_free,
1313};
1314
1315/* `set origin ORIGIN' */
1316
1317/* For origin set. */
1318route_map_result_t
1319route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1320{
1321 u_char *origin;
1322 struct bgp_info *bgp_info;
1323
1324 if (type == RMAP_BGP)
1325 {
1326 origin = rule;
1327 bgp_info = object;
1328
1329 bgp_info->attr->origin = *origin;
1330 }
1331
1332 return RMAP_OKAY;
1333}
1334
1335/* Compile function for origin set. */
1336void *
1337route_set_origin_compile (char *arg)
1338{
1339 u_char *origin;
1340
1341 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1342
1343 if (strcmp (arg, "igp") == 0)
1344 *origin = 0;
1345 else if (strcmp (arg, "egp") == 0)
1346 *origin = 1;
1347 else
1348 *origin = 2;
1349
1350 return origin;
1351}
1352
1353/* Compile function for origin set. */
1354void
1355route_set_origin_free (void *rule)
1356{
1357 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1358}
1359
1360/* Set metric rule structure. */
1361struct route_map_rule_cmd route_set_origin_cmd =
1362{
1363 "origin",
1364 route_set_origin,
1365 route_set_origin_compile,
1366 route_set_origin_free,
1367};
1368
1369/* `set atomic-aggregate' */
1370
1371/* For atomic aggregate set. */
1372route_map_result_t
1373route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1374 route_map_object_t type, void *object)
1375{
1376 struct bgp_info *bgp_info;
1377
1378 if (type == RMAP_BGP)
1379 {
1380 bgp_info = object;
1381 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1382 }
1383
1384 return RMAP_OKAY;
1385}
1386
1387/* Compile function for atomic aggregate. */
1388void *
1389route_set_atomic_aggregate_compile (char *arg)
1390{
1391 return (void *)1;
1392}
1393
1394/* Compile function for atomic aggregate. */
1395void
1396route_set_atomic_aggregate_free (void *rule)
1397{
1398 return;
1399}
1400
1401/* Set atomic aggregate rule structure. */
1402struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1403{
1404 "atomic-aggregate",
1405 route_set_atomic_aggregate,
1406 route_set_atomic_aggregate_compile,
1407 route_set_atomic_aggregate_free,
1408};
1409
1410/* `set aggregator as AS A.B.C.D' */
1411struct aggregator
1412{
1413 as_t as;
1414 struct in_addr address;
1415};
1416
1417route_map_result_t
1418route_set_aggregator_as (void *rule, struct prefix *prefix,
1419 route_map_object_t type, void *object)
1420{
1421 struct bgp_info *bgp_info;
1422 struct aggregator *aggregator;
1423
1424 if (type == RMAP_BGP)
1425 {
1426 bgp_info = object;
1427 aggregator = rule;
1428
1429 bgp_info->attr->aggregator_as = aggregator->as;
1430 bgp_info->attr->aggregator_addr = aggregator->address;
1431 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1432 }
1433
1434 return RMAP_OKAY;
1435}
1436
1437void *
1438route_set_aggregator_as_compile (char *arg)
1439{
1440 struct aggregator *aggregator;
1441 char as[10];
1442 char address[20];
1443
1444 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1445 memset (aggregator, 0, sizeof (struct aggregator));
1446
1447 sscanf (arg, "%s %s", as, address);
1448
1449 aggregator->as = strtoul (as, NULL, 10);
1450 inet_aton (address, &aggregator->address);
1451
1452 return aggregator;
1453}
1454
1455void
1456route_set_aggregator_as_free (void *rule)
1457{
1458 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1459}
1460
1461struct route_map_rule_cmd route_set_aggregator_as_cmd =
1462{
1463 "aggregator as",
1464 route_set_aggregator_as,
1465 route_set_aggregator_as_compile,
1466 route_set_aggregator_as_free,
1467};
1468
1469#ifdef HAVE_IPV6
1470/* `match ipv6 address IP_ACCESS_LIST' */
1471
1472route_map_result_t
1473route_match_ipv6_address (void *rule, struct prefix *prefix,
1474 route_map_object_t type, void *object)
1475{
1476 struct access_list *alist;
1477
1478 if (type == RMAP_BGP)
1479 {
1480 alist = access_list_lookup (AFI_IP6, (char *) rule);
1481 if (alist == NULL)
1482 return RMAP_NOMATCH;
1483
1484 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1485 RMAP_NOMATCH : RMAP_MATCH);
1486 }
1487 return RMAP_NOMATCH;
1488}
1489
1490void *
1491route_match_ipv6_address_compile (char *arg)
1492{
1493 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1494}
1495
1496void
1497route_match_ipv6_address_free (void *rule)
1498{
1499 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1500}
1501
1502/* Route map commands for ip address matching. */
1503struct route_map_rule_cmd route_match_ipv6_address_cmd =
1504{
1505 "ipv6 address",
1506 route_match_ipv6_address,
1507 route_match_ipv6_address_compile,
1508 route_match_ipv6_address_free
1509};
1510
1511/* `match ipv6 next-hop IP_ADDRESS' */
1512
1513route_map_result_t
1514route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1515 route_map_object_t type, void *object)
1516{
1517 struct in6_addr *addr;
1518 struct bgp_info *bgp_info;
1519
1520 if (type == RMAP_BGP)
1521 {
1522 addr = rule;
1523 bgp_info = object;
1524
1525 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1526 return RMAP_MATCH;
1527
1528 if (bgp_info->attr->mp_nexthop_len == 32 &&
1529 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1530 return RMAP_MATCH;
1531
1532 return RMAP_NOMATCH;
1533 }
1534
1535 return RMAP_NOMATCH;
1536}
1537
1538void *
1539route_match_ipv6_next_hop_compile (char *arg)
1540{
1541 struct in6_addr *address;
1542 int ret;
1543
1544 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1545
1546 ret = inet_pton (AF_INET6, arg, address);
1547 if (!ret)
1548 {
1549 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1550 return NULL;
1551 }
1552
1553 return address;
1554}
1555
1556void
1557route_match_ipv6_next_hop_free (void *rule)
1558{
1559 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1560}
1561
1562struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1563{
1564 "ipv6 next-hop",
1565 route_match_ipv6_next_hop,
1566 route_match_ipv6_next_hop_compile,
1567 route_match_ipv6_next_hop_free
1568};
1569
1570/* `match ipv6 address prefix-list PREFIX_LIST' */
1571
1572route_map_result_t
1573route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1574 route_map_object_t type, void *object)
1575{
1576 struct prefix_list *plist;
1577
1578 if (type == RMAP_BGP)
1579 {
1580 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1581 if (plist == NULL)
1582 return RMAP_NOMATCH;
1583
1584 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1585 RMAP_NOMATCH : RMAP_MATCH);
1586 }
1587 return RMAP_NOMATCH;
1588}
1589
1590void *
1591route_match_ipv6_address_prefix_list_compile (char *arg)
1592{
1593 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1594}
1595
1596void
1597route_match_ipv6_address_prefix_list_free (void *rule)
1598{
1599 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1600}
1601
1602struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1603{
1604 "ipv6 address prefix-list",
1605 route_match_ipv6_address_prefix_list,
1606 route_match_ipv6_address_prefix_list_compile,
1607 route_match_ipv6_address_prefix_list_free
1608};
1609
1610/* `set ipv6 nexthop global IP_ADDRESS' */
1611
1612/* Set nexthop to object. ojbect must be pointer to struct attr. */
1613route_map_result_t
1614route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1615 route_map_object_t type, void *object)
1616{
1617 struct in6_addr *address;
1618 struct bgp_info *bgp_info;
1619
1620 if (type == RMAP_BGP)
1621 {
1622 /* Fetch routemap's rule information. */
1623 address = rule;
1624 bgp_info = object;
1625
1626 /* Set next hop value. */
1627 bgp_info->attr->mp_nexthop_global = *address;
1628
1629 /* Set nexthop length. */
1630 if (bgp_info->attr->mp_nexthop_len == 0)
1631 bgp_info->attr->mp_nexthop_len = 16;
1632 }
1633
1634 return RMAP_OKAY;
1635}
1636
1637/* Route map `ip next-hop' compile function. Given string is converted
1638 to struct in_addr structure. */
1639void *
1640route_set_ipv6_nexthop_global_compile (char *arg)
1641{
1642 int ret;
1643 struct in6_addr *address;
1644
1645 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1646
1647 ret = inet_pton (AF_INET6, arg, address);
1648
1649 if (ret == 0)
1650 {
1651 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1652 return NULL;
1653 }
1654
1655 return address;
1656}
1657
1658/* Free route map's compiled `ip next-hop' value. */
1659void
1660route_set_ipv6_nexthop_global_free (void *rule)
1661{
1662 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1663}
1664
1665/* Route map commands for ip nexthop set. */
1666struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1667{
1668 "ipv6 next-hop global",
1669 route_set_ipv6_nexthop_global,
1670 route_set_ipv6_nexthop_global_compile,
1671 route_set_ipv6_nexthop_global_free
1672};
1673
1674/* `set ipv6 nexthop local IP_ADDRESS' */
1675
1676/* Set nexthop to object. ojbect must be pointer to struct attr. */
1677route_map_result_t
1678route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1679 route_map_object_t type, void *object)
1680{
1681 struct in6_addr *address;
1682 struct bgp_info *bgp_info;
1683
1684 if (type == RMAP_BGP)
1685 {
1686 /* Fetch routemap's rule information. */
1687 address = rule;
1688 bgp_info = object;
1689
1690 /* Set next hop value. */
1691 bgp_info->attr->mp_nexthop_local = *address;
1692
1693 /* Set nexthop length. */
1694 if (bgp_info->attr->mp_nexthop_len != 32)
1695 bgp_info->attr->mp_nexthop_len = 32;
1696 }
1697
1698 return RMAP_OKAY;
1699}
1700
1701/* Route map `ip nexthop' compile function. Given string is converted
1702 to struct in_addr structure. */
1703void *
1704route_set_ipv6_nexthop_local_compile (char *arg)
1705{
1706 int ret;
1707 struct in6_addr *address;
1708
1709 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1710
1711 ret = inet_pton (AF_INET6, arg, address);
1712
1713 if (ret == 0)
1714 {
1715 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1716 return NULL;
1717 }
1718
1719 return address;
1720}
1721
1722/* Free route map's compiled `ip nexthop' value. */
1723void
1724route_set_ipv6_nexthop_local_free (void *rule)
1725{
1726 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1727}
1728
1729/* Route map commands for ip nexthop set. */
1730struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1731{
1732 "ipv6 next-hop local",
1733 route_set_ipv6_nexthop_local,
1734 route_set_ipv6_nexthop_local_compile,
1735 route_set_ipv6_nexthop_local_free
1736};
1737#endif /* HAVE_IPV6 */
1738
1739/* `set vpnv4 nexthop A.B.C.D' */
1740
1741route_map_result_t
1742route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1743 route_map_object_t type, void *object)
1744{
1745 struct in_addr *address;
1746 struct bgp_info *bgp_info;
1747
1748 if (type == RMAP_BGP)
1749 {
1750 /* Fetch routemap's rule information. */
1751 address = rule;
1752 bgp_info = object;
1753
1754 /* Set next hop value. */
1755 bgp_info->attr->mp_nexthop_global_in = *address;
1756 }
1757
1758 return RMAP_OKAY;
1759}
1760
1761void *
1762route_set_vpnv4_nexthop_compile (char *arg)
1763{
1764 int ret;
1765 struct in_addr *address;
1766
1767 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1768
1769 ret = inet_aton (arg, address);
1770
1771 if (ret == 0)
1772 {
1773 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1774 return NULL;
1775 }
1776
1777 return address;
1778}
1779
1780void
1781route_set_vpnv4_nexthop_free (void *rule)
1782{
1783 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1784}
1785
1786/* Route map commands for ip nexthop set. */
1787struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1788{
1789 "vpnv4 next-hop",
1790 route_set_vpnv4_nexthop,
1791 route_set_vpnv4_nexthop_compile,
1792 route_set_vpnv4_nexthop_free
1793};
1794
1795/* `set originator-id' */
1796
1797/* For origin set. */
1798route_map_result_t
1799route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1800{
1801 struct in_addr *address;
1802 struct bgp_info *bgp_info;
1803
1804 if (type == RMAP_BGP)
1805 {
1806 address = rule;
1807 bgp_info = object;
1808
1809 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1810 bgp_info->attr->originator_id = *address;
1811 }
1812
1813 return RMAP_OKAY;
1814}
1815
1816/* Compile function for originator-id set. */
1817void *
1818route_set_originator_id_compile (char *arg)
1819{
1820 int ret;
1821 struct in_addr *address;
1822
1823 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1824
1825 ret = inet_aton (arg, address);
1826
1827 if (ret == 0)
1828 {
1829 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1830 return NULL;
1831 }
1832
1833 return address;
1834}
1835
1836/* Compile function for originator_id set. */
1837void
1838route_set_originator_id_free (void *rule)
1839{
1840 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1841}
1842
1843/* Set metric rule structure. */
1844struct route_map_rule_cmd route_set_originator_id_cmd =
1845{
1846 "originator-id",
1847 route_set_originator_id,
1848 route_set_originator_id_compile,
1849 route_set_originator_id_free,
1850};
1851
1852/* Add bgp route map rule. */
1853int
1854bgp_route_match_add (struct vty *vty, struct route_map_index *index,
1855 char *command, char *arg)
1856{
1857 int ret;
1858
1859 ret = route_map_add_match (index, command, arg);
1860 if (ret)
1861 {
1862 switch (ret)
1863 {
1864 case RMAP_RULE_MISSING:
1865 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1866 return CMD_WARNING;
1867 break;
1868 case RMAP_COMPILE_ERROR:
1869 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1870 return CMD_WARNING;
1871 break;
1872 }
1873 }
1874 return CMD_SUCCESS;
1875}
1876
1877/* Delete bgp route map rule. */
1878int
1879bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
1880 char *command, char *arg)
1881{
1882 int ret;
1883
1884 ret = route_map_delete_match (index, command, arg);
1885 if (ret)
1886 {
1887 switch (ret)
1888 {
1889 case RMAP_RULE_MISSING:
1890 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1891 return CMD_WARNING;
1892 break;
1893 case RMAP_COMPILE_ERROR:
1894 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1895 return CMD_WARNING;
1896 break;
1897 }
1898 }
1899 return CMD_SUCCESS;
1900}
1901
1902/* Add bgp route map rule. */
1903int
1904bgp_route_set_add (struct vty *vty, struct route_map_index *index,
1905 char *command, char *arg)
1906{
1907 int ret;
1908
1909 ret = route_map_add_set (index, command, arg);
1910 if (ret)
1911 {
1912 switch (ret)
1913 {
1914 case RMAP_RULE_MISSING:
1915 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1916 return CMD_WARNING;
1917 break;
1918 case RMAP_COMPILE_ERROR:
1919 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1920 return CMD_WARNING;
1921 break;
1922 }
1923 }
1924 return CMD_SUCCESS;
1925}
1926
1927/* Delete bgp route map rule. */
1928int
1929bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
1930 char *command, char *arg)
1931{
1932 int ret;
1933
1934 ret = route_map_delete_set (index, command, arg);
1935 if (ret)
1936 {
1937 switch (ret)
1938 {
1939 case RMAP_RULE_MISSING:
1940 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1941 return CMD_WARNING;
1942 break;
1943 case RMAP_COMPILE_ERROR:
1944 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1945 return CMD_WARNING;
1946 break;
1947 }
1948 }
1949 return CMD_SUCCESS;
1950}
1951
1952/* Hook function for updating route_map assignment. */
1953void
1954bgp_route_map_update ()
1955{
1956 int i;
1957 afi_t afi;
1958 safi_t safi;
1959 int direct;
1960 struct listnode *nn, *nm;
1961 struct bgp *bgp;
1962 struct peer *peer;
1963 struct peer_group *group;
1964 struct bgp_filter *filter;
1965 struct bgp_node *bn;
1966 struct bgp_static *bgp_static;
1967
1968 /* For neighbor route-map updates. */
1969 LIST_LOOP (bm->bgp, bgp, nn)
1970 {
1971 LIST_LOOP (bgp->peer, peer, nm)
1972 {
1973 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1974 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1975 {
1976 filter = &peer->filter[afi][safi];
1977
1978 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
1979 {
1980 if (filter->map[direct].name)
1981 filter->map[direct].map =
1982 route_map_lookup_by_name (filter->map[direct].name);
1983 else
1984 filter->map[direct].map = NULL;
1985 }
1986
1987 if (filter->usmap.name)
1988 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
1989 else
1990 filter->usmap.map = NULL;
1991 }
1992 }
1993 LIST_LOOP (bgp->group, group, nm)
1994 {
1995 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1996 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1997 {
1998 filter = &group->conf->filter[afi][safi];
1999
2000 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
2001 {
2002 if (filter->map[direct].name)
2003 filter->map[direct].map =
2004 route_map_lookup_by_name (filter->map[direct].name);
2005 else
2006 filter->map[direct].map = NULL;
2007 }
2008
2009 if (filter->usmap.name)
2010 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2011 else
2012 filter->usmap.map = NULL;
2013 }
2014 }
2015 }
2016
2017 /* For default-originate route-map updates. */
2018 LIST_LOOP (bm->bgp, bgp, nn)
2019 {
2020 LIST_LOOP (bgp->peer, peer, nm)
2021 {
2022 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2023 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2024 {
2025 if (peer->default_rmap[afi][safi].name)
2026 peer->default_rmap[afi][safi].map =
2027 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2028 else
2029 peer->default_rmap[afi][safi].map = NULL;
2030 }
2031 }
2032 }
2033
2034 /* For network route-map updates. */
2035 LIST_LOOP (bm->bgp, bgp, nn)
2036 {
2037 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2038 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2039 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2040 bn = bgp_route_next (bn))
2041 if ((bgp_static = bn->info) != NULL)
2042 {
2043 if (bgp_static->rmap.name)
2044 bgp_static->rmap.map =
2045 route_map_lookup_by_name (bgp_static->rmap.name);
2046 else
2047 bgp_static->rmap.map = NULL;
2048 }
2049 }
2050
2051 /* For redistribute route-map updates. */
2052 LIST_LOOP (bm->bgp, bgp, nn)
2053 {
2054 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2055 {
2056 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2057 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2058 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2059#ifdef HAVE_IPV6
2060 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2061 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2062 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2063#endif /* HAVE_IPV6 */
2064 }
2065 }
2066}
2067
2068DEFUN (match_ip_address,
2069 match_ip_address_cmd,
2070 "match ip address (<1-199>|<1300-2699>|WORD)",
2071 MATCH_STR
2072 IP_STR
2073 "Match address of route\n"
2074 "IP access-list number\n"
2075 "IP access-list number (expanded range)\n"
2076 "IP Access-list name\n")
2077{
2078 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2079}
2080
2081DEFUN (no_match_ip_address,
2082 no_match_ip_address_cmd,
2083 "no match ip address",
2084 NO_STR
2085 MATCH_STR
2086 IP_STR
2087 "Match address of route\n")
2088{
2089 if (argc == 0)
2090 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2091
2092 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2093}
2094
2095ALIAS (no_match_ip_address,
2096 no_match_ip_address_val_cmd,
2097 "no match ip address (<1-199>|<1300-2699>|WORD)",
2098 NO_STR
2099 MATCH_STR
2100 IP_STR
2101 "Match address of route\n"
2102 "IP access-list number\n"
2103 "IP access-list number (expanded range)\n"
2104 "IP Access-list name\n")
2105
2106DEFUN (match_ip_next_hop,
2107 match_ip_next_hop_cmd,
2108 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2109 MATCH_STR
2110 IP_STR
2111 "Match next-hop address of route\n"
2112 "IP access-list number\n"
2113 "IP access-list number (expanded range)\n"
2114 "IP Access-list name\n")
2115{
2116 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2117}
2118
2119DEFUN (no_match_ip_next_hop,
2120 no_match_ip_next_hop_cmd,
2121 "no match ip next-hop",
2122 NO_STR
2123 MATCH_STR
2124 IP_STR
2125 "Match next-hop address of route\n")
2126{
2127 if (argc == 0)
2128 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2129
2130 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2131}
2132
2133ALIAS (no_match_ip_next_hop,
2134 no_match_ip_next_hop_val_cmd,
2135 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2136 NO_STR
2137 MATCH_STR
2138 IP_STR
2139 "Match next-hop address of route\n"
2140 "IP access-list number\n"
2141 "IP access-list number (expanded range)\n"
2142 "IP Access-list name\n")
2143
2144DEFUN (match_ip_address_prefix_list,
2145 match_ip_address_prefix_list_cmd,
2146 "match ip address prefix-list WORD",
2147 MATCH_STR
2148 IP_STR
2149 "Match address of route\n"
2150 "Match entries of prefix-lists\n"
2151 "IP prefix-list name\n")
2152{
2153 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2154}
2155
2156DEFUN (no_match_ip_address_prefix_list,
2157 no_match_ip_address_prefix_list_cmd,
2158 "no match ip address prefix-list",
2159 NO_STR
2160 MATCH_STR
2161 IP_STR
2162 "Match address of route\n"
2163 "Match entries of prefix-lists\n")
2164{
2165 if (argc == 0)
2166 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2167
2168 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2169}
2170
2171ALIAS (no_match_ip_address_prefix_list,
2172 no_match_ip_address_prefix_list_val_cmd,
2173 "no match ip address prefix-list WORD",
2174 NO_STR
2175 MATCH_STR
2176 IP_STR
2177 "Match address of route\n"
2178 "Match entries of prefix-lists\n"
2179 "IP prefix-list name\n")
2180
2181DEFUN (match_ip_next_hop_prefix_list,
2182 match_ip_next_hop_prefix_list_cmd,
2183 "match ip next-hop prefix-list WORD",
2184 MATCH_STR
2185 IP_STR
2186 "Match next-hop address of route\n"
2187 "Match entries of prefix-lists\n"
2188 "IP prefix-list name\n")
2189{
2190 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2191}
2192
2193DEFUN (no_match_ip_next_hop_prefix_list,
2194 no_match_ip_next_hop_prefix_list_cmd,
2195 "no match ip next-hop prefix-list",
2196 NO_STR
2197 MATCH_STR
2198 IP_STR
2199 "Match next-hop address of route\n"
2200 "Match entries of prefix-lists\n")
2201{
2202 if (argc == 0)
2203 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2204
2205 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2206}
2207
2208ALIAS (no_match_ip_next_hop_prefix_list,
2209 no_match_ip_next_hop_prefix_list_val_cmd,
2210 "no match ip next-hop prefix-list WORD",
2211 NO_STR
2212 MATCH_STR
2213 IP_STR
2214 "Match next-hop address of route\n"
2215 "Match entries of prefix-lists\n"
2216 "IP prefix-list name\n")
2217
2218DEFUN (match_metric,
2219 match_metric_cmd,
2220 "match metric <0-4294967295>",
2221 MATCH_STR
2222 "Match metric of route\n"
2223 "Metric value\n")
2224{
2225 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2226}
2227
2228DEFUN (no_match_metric,
2229 no_match_metric_cmd,
2230 "no match metric",
2231 NO_STR
2232 MATCH_STR
2233 "Match metric of route\n")
2234{
2235 if (argc == 0)
2236 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2237
2238 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2239}
2240
2241ALIAS (no_match_metric,
2242 no_match_metric_val_cmd,
2243 "no match metric <0-4294967295>",
2244 NO_STR
2245 MATCH_STR
2246 "Match metric of route\n"
2247 "Metric value\n")
2248
2249DEFUN (match_community,
2250 match_community_cmd,
2251 "match community (<1-99>|<100-199>|WORD)",
2252 MATCH_STR
2253 "Match BGP community list\n"
2254 "Community-list number (standard)\n"
2255 "Community-list number (expanded)\n"
2256 "Community-list name\n")
2257{
2258 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2259}
2260
2261DEFUN (match_community_exact,
2262 match_community_exact_cmd,
2263 "match community (<1-99>|<100-199>|WORD) exact-match",
2264 MATCH_STR
2265 "Match BGP community list\n"
2266 "Community-list number (standard)\n"
2267 "Community-list number (expanded)\n"
2268 "Community-list name\n"
2269 "Do exact matching of communities\n")
2270{
2271 int ret;
2272 char *argstr;
2273
2274 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2275 strlen (argv[0]) + strlen ("exact-match") + 2);
2276
2277 sprintf (argstr, "%s exact-match", argv[0]);
2278
2279 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2280
2281 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2282
2283 return ret;
2284}
2285
2286DEFUN (no_match_community,
2287 no_match_community_cmd,
2288 "no match community",
2289 NO_STR
2290 MATCH_STR
2291 "Match BGP community list\n")
2292{
2293 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2294}
2295
2296ALIAS (no_match_community,
2297 no_match_community_val_cmd,
2298 "no match community (<1-99>|<100-199>|WORD)",
2299 NO_STR
2300 MATCH_STR
2301 "Match BGP community list\n"
2302 "Community-list number (standard)\n"
2303 "Community-list number (expanded)\n"
2304 "Community-list name\n")
2305
2306ALIAS (no_match_community,
2307 no_match_community_exact_cmd,
2308 "no match community (<1-99>|<100-199>|WORD) exact-match",
2309 NO_STR
2310 MATCH_STR
2311 "Match BGP community list\n"
2312 "Community-list number (standard)\n"
2313 "Community-list number (expanded)\n"
2314 "Community-list name\n"
2315 "Do exact matching of communities\n")
2316
paul73ffb252003-04-19 15:49:49 +00002317DEFUN (match_ecommunity,
2318 match_ecommunity_cmd,
2319 "match extcommunity (<1-99>|<100-199>|WORD)",
2320 MATCH_STR
2321 "Match BGP/VPN extended community list\n"
2322 "Extended community-list number (standard)\n"
2323 "Extended community-list number (expanded)\n"
2324 "Extended community-list name\n")
2325{
2326 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2327}
2328
2329DEFUN (no_match_ecommunity,
2330 no_match_ecommunity_cmd,
2331 "no match extcommunity",
2332 NO_STR
2333 MATCH_STR
2334 "Match BGP/VPN extended community list\n")
2335{
2336 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2337}
2338
2339ALIAS (no_match_ecommunity,
2340 no_match_ecommunity_val_cmd,
2341 "no match extcommunity (<1-99>|<100-199>|WORD)",
2342 NO_STR
2343 MATCH_STR
2344 "Match BGP/VPN extended community list\n"
2345 "Extended community-list number (standard)\n"
2346 "Extended community-list number (expanded)\n"
2347 "Extended community-list name\n")
2348
paul718e3742002-12-13 20:15:29 +00002349DEFUN (match_aspath,
2350 match_aspath_cmd,
2351 "match as-path WORD",
2352 MATCH_STR
2353 "Match BGP AS path list\n"
2354 "AS path access-list name\n")
2355{
2356 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2357}
2358
2359DEFUN (no_match_aspath,
2360 no_match_aspath_cmd,
2361 "no match as-path",
2362 NO_STR
2363 MATCH_STR
2364 "Match BGP AS path list\n")
2365{
2366 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2367}
2368
2369ALIAS (no_match_aspath,
2370 no_match_aspath_val_cmd,
2371 "no match as-path WORD",
2372 NO_STR
2373 MATCH_STR
2374 "Match BGP AS path list\n"
2375 "AS path access-list name\n")
2376
2377DEFUN (match_origin,
2378 match_origin_cmd,
2379 "match origin (egp|igp|incomplete)",
2380 MATCH_STR
2381 "BGP origin code\n"
2382 "remote EGP\n"
2383 "local IGP\n"
2384 "unknown heritage\n")
2385{
2386 if (strncmp (argv[0], "igp", 2) == 0)
2387 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2388 if (strncmp (argv[0], "egp", 1) == 0)
2389 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2390 if (strncmp (argv[0], "incomplete", 2) == 0)
2391 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2392
2393 return CMD_WARNING;
2394}
2395
2396DEFUN (no_match_origin,
2397 no_match_origin_cmd,
2398 "no match origin",
2399 NO_STR
2400 MATCH_STR
2401 "BGP origin code\n")
2402{
2403 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2404}
2405
2406ALIAS (no_match_origin,
2407 no_match_origin_val_cmd,
2408 "no match origin (egp|igp|incomplete)",
2409 NO_STR
2410 MATCH_STR
2411 "BGP origin code\n"
2412 "remote EGP\n"
2413 "local IGP\n"
2414 "unknown heritage\n")
2415
2416DEFUN (set_ip_nexthop,
2417 set_ip_nexthop_cmd,
paulac41b2a2003-08-12 05:32:27 +00002418 "set ip next-hop (A.B.C.D|peer-address)",
paul718e3742002-12-13 20:15:29 +00002419 SET_STR
2420 IP_STR
2421 "Next hop address\n"
paulac41b2a2003-08-12 05:32:27 +00002422 "IP address of next hop\n"
2423 "Use peer address (for BGP only)\n")
paul718e3742002-12-13 20:15:29 +00002424{
2425 union sockunion su;
2426 int ret;
2427
paulac41b2a2003-08-12 05:32:27 +00002428 if (strncmp (argv[0], "peer-address", 1) == 0)
2429 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2430
paul718e3742002-12-13 20:15:29 +00002431 ret = str2sockunion (argv[0], &su);
2432 if (ret < 0)
2433 {
2434 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2435 return CMD_WARNING;
2436 }
2437
2438 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2439}
2440
2441DEFUN (no_set_ip_nexthop,
2442 no_set_ip_nexthop_cmd,
2443 "no set ip next-hop",
2444 NO_STR
2445 SET_STR
2446 IP_STR
2447 "Next hop address\n")
2448{
paulac41b2a2003-08-12 05:32:27 +00002449 if (argc == 0 || strncmp (argv[0], "peer-address", 1) == 0)
paul718e3742002-12-13 20:15:29 +00002450 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2451
2452 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2453}
2454
2455ALIAS (no_set_ip_nexthop,
2456 no_set_ip_nexthop_val_cmd,
paulac41b2a2003-08-12 05:32:27 +00002457 "no set ip next-hop (A.B.C.D|peer-address)",
paul718e3742002-12-13 20:15:29 +00002458 NO_STR
2459 SET_STR
2460 IP_STR
2461 "Next hop address\n"
paulac41b2a2003-08-12 05:32:27 +00002462 "IP address of next hop\n"
2463 "Use peer address (for BGP only)\n")
paul718e3742002-12-13 20:15:29 +00002464
2465DEFUN (set_metric,
2466 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002467 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002468 SET_STR
2469 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002470 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002471{
2472 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2473}
2474
paul73ffb252003-04-19 15:49:49 +00002475ALIAS (set_metric,
2476 set_metric_addsub_cmd,
2477 "set metric <+/-metric>",
2478 SET_STR
2479 "Metric value for destination routing protocol\n"
2480 "Add or subtract BGP metric\n")
2481
paul718e3742002-12-13 20:15:29 +00002482DEFUN (no_set_metric,
2483 no_set_metric_cmd,
2484 "no set metric",
2485 NO_STR
2486 SET_STR
2487 "Metric value for destination routing protocol\n")
2488{
2489 if (argc == 0)
2490 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2491
2492 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2493}
2494
2495ALIAS (no_set_metric,
2496 no_set_metric_val_cmd,
2497 "no set metric <0-4294967295>",
2498 NO_STR
2499 SET_STR
2500 "Metric value for destination routing protocol\n"
2501 "Metric value\n")
2502
2503DEFUN (set_local_pref,
2504 set_local_pref_cmd,
2505 "set local-preference <0-4294967295>",
2506 SET_STR
2507 "BGP local preference path attribute\n"
2508 "Preference value\n")
2509{
2510 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2511}
2512
2513DEFUN (no_set_local_pref,
2514 no_set_local_pref_cmd,
2515 "no set local-preference",
2516 NO_STR
2517 SET_STR
2518 "BGP local preference path attribute\n")
2519{
2520 if (argc == 0)
2521 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2522
2523 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2524}
2525
2526ALIAS (no_set_local_pref,
2527 no_set_local_pref_val_cmd,
2528 "no set local-preference <0-4294967295>",
2529 NO_STR
2530 SET_STR
2531 "BGP local preference path attribute\n"
2532 "Preference value\n")
2533
2534DEFUN (set_weight,
2535 set_weight_cmd,
2536 "set weight <0-4294967295>",
2537 SET_STR
2538 "BGP weight for routing table\n"
2539 "Weight value\n")
2540{
2541 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2542}
2543
2544DEFUN (no_set_weight,
2545 no_set_weight_cmd,
2546 "no set weight",
2547 NO_STR
2548 SET_STR
2549 "BGP weight for routing table\n")
2550{
2551 if (argc == 0)
2552 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2553
2554 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2555}
2556
2557ALIAS (no_set_weight,
2558 no_set_weight_val_cmd,
2559 "no set weight <0-4294967295>",
2560 NO_STR
2561 SET_STR
2562 "BGP weight for routing table\n"
2563 "Weight value\n")
2564
2565DEFUN (set_aspath_prepend,
2566 set_aspath_prepend_cmd,
2567 "set as-path prepend .<1-65535>",
2568 SET_STR
2569 "Prepend string for a BGP AS-path attribute\n"
2570 "Prepend to the as-path\n"
2571 "AS number\n")
2572{
2573 int ret;
2574 char *str;
2575
2576 str = argv_concat (argv, argc, 0);
2577 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2578 XFREE (MTYPE_TMP, str);
2579
2580 return ret;
2581}
2582
2583DEFUN (no_set_aspath_prepend,
2584 no_set_aspath_prepend_cmd,
2585 "no set as-path prepend",
2586 NO_STR
2587 SET_STR
2588 "Prepend string for a BGP AS-path attribute\n"
2589 "Prepend to the as-path\n")
2590{
2591 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2592}
2593
2594ALIAS (no_set_aspath_prepend,
2595 no_set_aspath_prepend_val_cmd,
2596 "no set as-path prepend .<1-65535>",
2597 NO_STR
2598 SET_STR
2599 "Prepend string for a BGP AS-path attribute\n"
2600 "Prepend to the as-path\n"
2601 "AS number\n")
2602
2603DEFUN (set_community,
2604 set_community_cmd,
2605 "set community .AA:NN",
2606 SET_STR
2607 "BGP community attribute\n"
2608 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2609{
2610 int i;
2611 int first = 0;
2612 int additive = 0;
2613 struct buffer *b;
2614 struct community *com = NULL;
2615 char *str;
2616 char *argstr;
2617 int ret;
2618
2619 b = buffer_new (1024);
2620
2621 for (i = 0; i < argc; i++)
2622 {
2623 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2624 {
2625 additive = 1;
2626 continue;
2627 }
2628
2629 if (first)
2630 buffer_putc (b, ' ');
2631 else
2632 first = 1;
2633
2634 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2635 {
2636 buffer_putstr (b, "internet");
2637 continue;
2638 }
2639 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2640 {
2641 buffer_putstr (b, "local-AS");
2642 continue;
2643 }
2644 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2645 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2646 {
2647 buffer_putstr (b, "no-advertise");
2648 continue;
2649 }
2650 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2651 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2652 {
2653 buffer_putstr (b, "no-export");
2654 continue;
2655 }
2656 buffer_putstr (b, argv[i]);
2657 }
2658 buffer_putc (b, '\0');
2659
2660 /* Fetch result string then compile it to communities attribute. */
2661 str = buffer_getstr (b);
2662 buffer_free (b);
2663
2664 if (str)
2665 {
2666 com = community_str2com (str);
2667 free (str);
2668 }
2669
2670 /* Can't compile user input into communities attribute. */
2671 if (! com)
2672 {
2673 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
2674 return CMD_WARNING;
2675 }
2676
2677 /* Set communites attribute string. */
2678 str = community_str (com);
2679
2680 if (additive)
2681 {
2682 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
2683 strcpy (argstr, str);
2684 strcpy (argstr + strlen (str), " additive");
2685 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
2686 XFREE (MTYPE_TMP, argstr);
2687 }
2688 else
2689 ret = bgp_route_set_add (vty, vty->index, "community", str);
2690
2691 community_free (com);
2692
2693 return ret;
2694}
2695
2696DEFUN (set_community_none,
2697 set_community_none_cmd,
2698 "set community none",
2699 SET_STR
2700 "BGP community attribute\n"
2701 "No community attribute\n")
2702{
2703 return bgp_route_set_add (vty, vty->index, "community", "none");
2704}
2705
2706DEFUN (no_set_community,
2707 no_set_community_cmd,
2708 "no set community",
2709 NO_STR
2710 SET_STR
2711 "BGP community attribute\n")
2712{
2713 return bgp_route_set_delete (vty, vty->index, "community", NULL);
2714}
2715
2716ALIAS (no_set_community,
2717 no_set_community_val_cmd,
2718 "no set community .AA:NN",
2719 NO_STR
2720 SET_STR
2721 "BGP community attribute\n"
2722 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2723
2724ALIAS (no_set_community,
2725 no_set_community_none_cmd,
2726 "no set community none",
2727 NO_STR
2728 SET_STR
2729 "BGP community attribute\n"
2730 "No community attribute\n")
2731
2732DEFUN (set_community_delete,
2733 set_community_delete_cmd,
2734 "set comm-list (<1-99>|<100-199>|WORD) delete",
2735 SET_STR
2736 "set BGP community list (for deletion)\n"
2737 "Community-list number (standard)\n"
2738 "Communitly-list number (expanded)\n"
2739 "Community-list name\n"
2740 "Delete matching communities\n")
2741{
2742 char *str;
2743
2744 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
2745 strcpy (str, argv[0]);
2746 strcpy (str + strlen (argv[0]), " delete");
2747
2748 bgp_route_set_add (vty, vty->index, "comm-list", str);
2749
2750 XFREE (MTYPE_TMP, str);
2751 return CMD_SUCCESS;
2752}
2753
2754DEFUN (no_set_community_delete,
2755 no_set_community_delete_cmd,
2756 "no set comm-list",
2757 NO_STR
2758 SET_STR
2759 "set BGP community list (for deletion)\n")
2760{
2761 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
2762}
2763
2764ALIAS (no_set_community_delete,
2765 no_set_community_delete_val_cmd,
2766 "no set comm-list (<1-99>|<100-199>|WORD) delete",
2767 NO_STR
2768 SET_STR
2769 "set BGP community list (for deletion)\n"
2770 "Community-list number (standard)\n"
2771 "Communitly-list number (expanded)\n"
2772 "Community-list name\n"
2773 "Delete matching communities\n")
2774
2775DEFUN (set_ecommunity_rt,
2776 set_ecommunity_rt_cmd,
2777 "set extcommunity rt .ASN:nn_or_IP-address:nn",
2778 SET_STR
2779 "BGP extended community attribute\n"
2780 "Route Target extened communityt\n"
2781 "VPN extended community\n")
2782{
2783 int ret;
2784 char *str;
2785
2786 str = argv_concat (argv, argc, 0);
2787 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
2788 XFREE (MTYPE_TMP, str);
2789
2790 return ret;
2791}
2792
2793DEFUN (no_set_ecommunity_rt,
2794 no_set_ecommunity_rt_cmd,
2795 "no set extcommunity rt",
2796 NO_STR
2797 SET_STR
2798 "BGP extended community attribute\n"
2799 "Route Target extened communityt\n")
2800{
2801 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
2802}
2803
2804ALIAS (no_set_ecommunity_rt,
2805 no_set_ecommunity_rt_val_cmd,
2806 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
2807 NO_STR
2808 SET_STR
2809 "BGP extended community attribute\n"
2810 "Route Target extened communityt\n"
2811 "VPN extended community\n")
2812
2813DEFUN (set_ecommunity_soo,
2814 set_ecommunity_soo_cmd,
2815 "set extcommunity soo .ASN:nn_or_IP-address:nn",
2816 SET_STR
2817 "BGP extended community attribute\n"
2818 "Site-of-Origin extended community\n"
2819 "VPN extended community\n")
2820{
2821 int ret;
2822 char *str;
2823
2824 str = argv_concat (argv, argc, 0);
2825 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
2826 XFREE (MTYPE_TMP, str);
2827 return ret;
2828}
2829
2830DEFUN (no_set_ecommunity_soo,
2831 no_set_ecommunity_soo_cmd,
2832 "no set extcommunity soo",
2833 NO_STR
2834 SET_STR
2835 "BGP extended community attribute\n"
2836 "Site-of-Origin extended community\n")
2837{
2838 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
2839}
2840
2841ALIAS (no_set_ecommunity_soo,
2842 no_set_ecommunity_soo_val_cmd,
2843 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
2844 NO_STR
2845 SET_STR
2846 "BGP extended community attribute\n"
2847 "Site-of-Origin extended community\n"
2848 "VPN extended community\n")
2849
2850DEFUN (set_origin,
2851 set_origin_cmd,
2852 "set origin (egp|igp|incomplete)",
2853 SET_STR
2854 "BGP origin code\n"
2855 "remote EGP\n"
2856 "local IGP\n"
2857 "unknown heritage\n")
2858{
2859 if (strncmp (argv[0], "igp", 2) == 0)
2860 return bgp_route_set_add (vty, vty->index, "origin", "igp");
2861 if (strncmp (argv[0], "egp", 1) == 0)
2862 return bgp_route_set_add (vty, vty->index, "origin", "egp");
2863 if (strncmp (argv[0], "incomplete", 2) == 0)
2864 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
2865
2866 return CMD_WARNING;
2867}
2868
2869DEFUN (no_set_origin,
2870 no_set_origin_cmd,
2871 "no set origin",
2872 NO_STR
2873 SET_STR
2874 "BGP origin code\n")
2875{
2876 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
2877}
2878
2879ALIAS (no_set_origin,
2880 no_set_origin_val_cmd,
2881 "no set origin (egp|igp|incomplete)",
2882 NO_STR
2883 SET_STR
2884 "BGP origin code\n"
2885 "remote EGP\n"
2886 "local IGP\n"
2887 "unknown heritage\n")
2888
2889DEFUN (set_atomic_aggregate,
2890 set_atomic_aggregate_cmd,
2891 "set atomic-aggregate",
2892 SET_STR
2893 "BGP atomic aggregate attribute\n" )
2894{
2895 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
2896}
2897
2898DEFUN (no_set_atomic_aggregate,
2899 no_set_atomic_aggregate_cmd,
2900 "no set atomic-aggregate",
2901 NO_STR
2902 SET_STR
2903 "BGP atomic aggregate attribute\n" )
2904{
2905 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
2906}
2907
2908DEFUN (set_aggregator_as,
2909 set_aggregator_as_cmd,
2910 "set aggregator as <1-65535> A.B.C.D",
2911 SET_STR
2912 "BGP aggregator attribute\n"
2913 "AS number of aggregator\n"
2914 "AS number\n"
2915 "IP address of aggregator\n")
2916{
2917 int ret;
2918 as_t as;
2919 struct in_addr address;
2920 char *endptr = NULL;
2921 char *argstr;
2922
2923 as = strtoul (argv[0], &endptr, 10);
2924 if (as == 0 || as == ULONG_MAX || *endptr != '\0')
2925 {
2926 vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
2927 return CMD_WARNING;
2928 }
2929
2930 ret = inet_aton (argv[1], &address);
2931 if (ret == 0)
2932 {
2933 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
2934 return CMD_WARNING;
2935 }
2936
2937 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2938 strlen (argv[0]) + strlen (argv[1]) + 2);
2939
2940 sprintf (argstr, "%s %s", argv[0], argv[1]);
2941
2942 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
2943
2944 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2945
2946 return ret;
2947}
2948
2949DEFUN (no_set_aggregator_as,
2950 no_set_aggregator_as_cmd,
2951 "no set aggregator as",
2952 NO_STR
2953 SET_STR
2954 "BGP aggregator attribute\n"
2955 "AS number of aggregator\n")
2956{
2957 int ret;
2958 as_t as;
2959 struct in_addr address;
2960 char *endptr = NULL;
2961 char *argstr;
2962
2963 if (argv == 0)
2964 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
2965
2966 as = strtoul (argv[0], &endptr, 10);
2967 if (as == 0 || as == ULONG_MAX || *endptr != '\0')
2968 {
2969 vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
2970 return CMD_WARNING;
2971 }
2972
2973 ret = inet_aton (argv[1], &address);
2974 if (ret == 0)
2975 {
2976 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
2977 return CMD_WARNING;
2978 }
2979
2980 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2981 strlen (argv[0]) + strlen (argv[1]) + 2);
2982
2983 sprintf (argstr, "%s %s", argv[0], argv[1]);
2984
2985 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
2986
2987 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2988
2989 return ret;
2990}
2991
2992ALIAS (no_set_aggregator_as,
2993 no_set_aggregator_as_val_cmd,
2994 "no set aggregator as <1-65535> A.B.C.D",
2995 NO_STR
2996 SET_STR
2997 "BGP aggregator attribute\n"
2998 "AS number of aggregator\n"
2999 "AS number\n"
3000 "IP address of aggregator\n")
3001
3002
3003#ifdef HAVE_IPV6
3004DEFUN (match_ipv6_address,
3005 match_ipv6_address_cmd,
3006 "match ipv6 address WORD",
3007 MATCH_STR
3008 IPV6_STR
3009 "Match IPv6 address of route\n"
3010 "IPv6 access-list name\n")
3011{
3012 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3013}
3014
3015DEFUN (no_match_ipv6_address,
3016 no_match_ipv6_address_cmd,
3017 "no match ipv6 address WORD",
3018 NO_STR
3019 MATCH_STR
3020 IPV6_STR
3021 "Match IPv6 address of route\n"
3022 "IPv6 access-list name\n")
3023{
3024 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3025}
3026
3027DEFUN (match_ipv6_next_hop,
3028 match_ipv6_next_hop_cmd,
3029 "match ipv6 next-hop X:X::X:X",
3030 MATCH_STR
3031 IPV6_STR
3032 "Match IPv6 next-hop address of route\n"
3033 "IPv6 address of next hop\n")
3034{
3035 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3036}
3037
3038DEFUN (no_match_ipv6_next_hop,
3039 no_match_ipv6_next_hop_cmd,
3040 "no match ipv6 next-hop X:X::X:X",
3041 NO_STR
3042 MATCH_STR
3043 IPV6_STR
3044 "Match IPv6 next-hop address of route\n"
3045 "IPv6 address of next hop\n")
3046{
3047 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3048}
3049
3050DEFUN (match_ipv6_address_prefix_list,
3051 match_ipv6_address_prefix_list_cmd,
3052 "match ipv6 address prefix-list WORD",
3053 MATCH_STR
3054 IPV6_STR
3055 "Match address of route\n"
3056 "Match entries of prefix-lists\n"
3057 "IP prefix-list name\n")
3058{
3059 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3060}
3061
3062DEFUN (no_match_ipv6_address_prefix_list,
3063 no_match_ipv6_address_prefix_list_cmd,
3064 "no match ipv6 address prefix-list WORD",
3065 NO_STR
3066 MATCH_STR
3067 IPV6_STR
3068 "Match address of route\n"
3069 "Match entries of prefix-lists\n"
3070 "IP prefix-list name\n")
3071{
3072 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3073}
3074
3075DEFUN (set_ipv6_nexthop_global,
3076 set_ipv6_nexthop_global_cmd,
3077 "set ipv6 next-hop global X:X::X:X",
3078 SET_STR
3079 IPV6_STR
3080 "IPv6 next-hop address\n"
3081 "IPv6 global address\n"
3082 "IPv6 address of next hop\n")
3083{
3084 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3085}
3086
3087DEFUN (no_set_ipv6_nexthop_global,
3088 no_set_ipv6_nexthop_global_cmd,
3089 "no set ipv6 next-hop global",
3090 NO_STR
3091 SET_STR
3092 IPV6_STR
3093 "IPv6 next-hop address\n"
3094 "IPv6 global address\n")
3095{
3096 if (argc == 0)
3097 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3098
3099 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3100}
3101
3102ALIAS (no_set_ipv6_nexthop_global,
3103 no_set_ipv6_nexthop_global_val_cmd,
3104 "no set ipv6 next-hop global X:X::X:X",
3105 NO_STR
3106 SET_STR
3107 IPV6_STR
3108 "IPv6 next-hop address\n"
3109 "IPv6 global address\n"
3110 "IPv6 address of next hop\n")
3111
3112DEFUN (set_ipv6_nexthop_local,
3113 set_ipv6_nexthop_local_cmd,
3114 "set ipv6 next-hop local X:X::X:X",
3115 SET_STR
3116 IPV6_STR
3117 "IPv6 next-hop address\n"
3118 "IPv6 local address\n"
3119 "IPv6 address of next hop\n")
3120{
3121 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3122}
3123
3124DEFUN (no_set_ipv6_nexthop_local,
3125 no_set_ipv6_nexthop_local_cmd,
3126 "no set ipv6 next-hop local",
3127 NO_STR
3128 SET_STR
3129 IPV6_STR
3130 "IPv6 next-hop address\n"
3131 "IPv6 local address\n")
3132{
3133 if (argc == 0)
3134 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3135
3136 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3137}
3138
3139ALIAS (no_set_ipv6_nexthop_local,
3140 no_set_ipv6_nexthop_local_val_cmd,
3141 "no set ipv6 next-hop local X:X::X:X",
3142 NO_STR
3143 SET_STR
3144 IPV6_STR
3145 "IPv6 next-hop address\n"
3146 "IPv6 local address\n"
3147 "IPv6 address of next hop\n")
3148#endif /* HAVE_IPV6 */
3149
3150DEFUN (set_vpnv4_nexthop,
3151 set_vpnv4_nexthop_cmd,
3152 "set vpnv4 next-hop A.B.C.D",
3153 SET_STR
3154 "VPNv4 information\n"
3155 "VPNv4 next-hop address\n"
3156 "IP address of next hop\n")
3157{
3158 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3159}
3160
3161DEFUN (no_set_vpnv4_nexthop,
3162 no_set_vpnv4_nexthop_cmd,
3163 "no set vpnv4 next-hop",
3164 NO_STR
3165 SET_STR
3166 "VPNv4 information\n"
3167 "VPNv4 next-hop address\n")
3168{
3169 if (argc == 0)
3170 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3171
3172 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3173}
3174
3175ALIAS (no_set_vpnv4_nexthop,
3176 no_set_vpnv4_nexthop_val_cmd,
3177 "no set vpnv4 next-hop A.B.C.D",
3178 NO_STR
3179 SET_STR
3180 "VPNv4 information\n"
3181 "VPNv4 next-hop address\n"
3182 "IP address of next hop\n")
3183
3184DEFUN (set_originator_id,
3185 set_originator_id_cmd,
3186 "set originator-id A.B.C.D",
3187 SET_STR
3188 "BGP originator ID attribute\n"
3189 "IP address of originator\n")
3190{
3191 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3192}
3193
3194DEFUN (no_set_originator_id,
3195 no_set_originator_id_cmd,
3196 "no set originator-id",
3197 NO_STR
3198 SET_STR
3199 "BGP originator ID attribute\n")
3200{
3201 if (argc == 0)
3202 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3203
3204 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3205}
3206
3207ALIAS (no_set_originator_id,
3208 no_set_originator_id_val_cmd,
3209 "no set originator-id A.B.C.D",
3210 NO_STR
3211 SET_STR
3212 "BGP originator ID attribute\n"
3213 "IP address of originator\n")
3214
3215
3216/* Initialization of route map. */
3217void
3218bgp_route_map_init ()
3219{
3220 route_map_init ();
3221 route_map_init_vty ();
3222 route_map_add_hook (bgp_route_map_update);
3223 route_map_delete_hook (bgp_route_map_update);
3224
3225 route_map_install_match (&route_match_ip_address_cmd);
3226 route_map_install_match (&route_match_ip_next_hop_cmd);
3227 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3228 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
3229 route_map_install_match (&route_match_aspath_cmd);
3230 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003231 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003232 route_map_install_match (&route_match_metric_cmd);
3233 route_map_install_match (&route_match_origin_cmd);
3234
3235 route_map_install_set (&route_set_ip_nexthop_cmd);
3236 route_map_install_set (&route_set_local_pref_cmd);
3237 route_map_install_set (&route_set_weight_cmd);
3238 route_map_install_set (&route_set_metric_cmd);
3239 route_map_install_set (&route_set_aspath_prepend_cmd);
3240 route_map_install_set (&route_set_origin_cmd);
3241 route_map_install_set (&route_set_atomic_aggregate_cmd);
3242 route_map_install_set (&route_set_aggregator_as_cmd);
3243 route_map_install_set (&route_set_community_cmd);
3244 route_map_install_set (&route_set_community_delete_cmd);
3245 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3246 route_map_install_set (&route_set_originator_id_cmd);
3247 route_map_install_set (&route_set_ecommunity_rt_cmd);
3248 route_map_install_set (&route_set_ecommunity_soo_cmd);
3249
3250 install_element (RMAP_NODE, &match_ip_address_cmd);
3251 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3252 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3253 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3254 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3255 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
3256
3257 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3258 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3259 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3260 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3261 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3262 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
3263
3264 install_element (RMAP_NODE, &match_aspath_cmd);
3265 install_element (RMAP_NODE, &no_match_aspath_cmd);
3266 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3267 install_element (RMAP_NODE, &match_metric_cmd);
3268 install_element (RMAP_NODE, &no_match_metric_cmd);
3269 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3270 install_element (RMAP_NODE, &match_community_cmd);
3271 install_element (RMAP_NODE, &match_community_exact_cmd);
3272 install_element (RMAP_NODE, &no_match_community_cmd);
3273 install_element (RMAP_NODE, &no_match_community_val_cmd);
3274 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003275 install_element (RMAP_NODE, &match_ecommunity_cmd);
3276 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3277 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003278 install_element (RMAP_NODE, &match_origin_cmd);
3279 install_element (RMAP_NODE, &no_match_origin_cmd);
3280 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3281
3282 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
3283 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3284 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3285 install_element (RMAP_NODE, &set_local_pref_cmd);
3286 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3287 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3288 install_element (RMAP_NODE, &set_weight_cmd);
3289 install_element (RMAP_NODE, &no_set_weight_cmd);
3290 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3291 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003292 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003293 install_element (RMAP_NODE, &no_set_metric_cmd);
3294 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3295 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3296 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3297 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3298 install_element (RMAP_NODE, &set_origin_cmd);
3299 install_element (RMAP_NODE, &no_set_origin_cmd);
3300 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3301 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3302 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3303 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3304 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3305 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3306 install_element (RMAP_NODE, &set_community_cmd);
3307 install_element (RMAP_NODE, &set_community_none_cmd);
3308 install_element (RMAP_NODE, &no_set_community_cmd);
3309 install_element (RMAP_NODE, &no_set_community_val_cmd);
3310 install_element (RMAP_NODE, &no_set_community_none_cmd);
3311 install_element (RMAP_NODE, &set_community_delete_cmd);
3312 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3313 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3314 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3315 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3316 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3317 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3318 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3319 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3320 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3321 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3322 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3323 install_element (RMAP_NODE, &set_originator_id_cmd);
3324 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3325 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3326
3327#ifdef HAVE_IPV6
3328 route_map_install_match (&route_match_ipv6_address_cmd);
3329 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3330 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3331 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3332 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3333
3334 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3335 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3336 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3337 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3338 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3339 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3340 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3341 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3342 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3343 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3344 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3345 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3346#endif /* HAVE_IPV6 */
3347}