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