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