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