]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_routemap.c
c49c2e9974aba96c4dc125b0483cf499546694e7
[mirror_frr.git] / bgpd / bgp_routemap.c
1 /* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-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
53 o 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
91 o Local extention
92
93 set ipv6 next-hop global: Done
94 set ipv6 next-hop local : Done
95
96 */
97 \f
98 /* '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. */
103 route_map_result_t
104 route_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
162 void *
163 route_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. */
180 void
181 route_match_peer_free (void *rule)
182 {
183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
184 }
185
186 /* Route map commands for ip address matching. */
187 struct 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
195 /* `match ip address IP_ACCESS_LIST' */
196
197 /* Match function should return 1 if match is success else return
198 zero. */
199 route_map_result_t
200 route_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. */
220 void *
221 route_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. */
227 void
228 route_match_ip_address_free (void *rule)
229 {
230 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
231 }
232
233 /* Route map commands for ip address matching. */
234 struct 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 \f
242 /* `match ip next-hop IP_ADDRESS' */
243
244 /* Match function return 1 if match is success else return zero. */
245 route_map_result_t
246 route_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. */
272 void *
273 route_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. */
279 void
280 route_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. */
286 struct 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 \f
294 /* `match ip address prefix-list PREFIX_LIST' */
295
296 route_map_result_t
297 route_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
314 void *
315 route_match_ip_address_prefix_list_compile (char *arg)
316 {
317 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
318 }
319
320 void
321 route_match_ip_address_prefix_list_free (void *rule)
322 {
323 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
324 }
325
326 struct 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 \f
334 /* `match ip next-hop prefix-list PREFIX_LIST' */
335
336 route_map_result_t
337 route_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
361 void *
362 route_match_ip_next_hop_prefix_list_compile (char *arg)
363 {
364 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
365 }
366
367 void
368 route_match_ip_next_hop_prefix_list_free (void *rule)
369 {
370 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
371 }
372
373 struct 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 \f
381 /* `match metric METRIC' */
382
383 /* Match function return 1 if match is success else return zero. */
384 route_map_result_t
385 route_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 */
405 void *
406 route_match_metric_compile (char *arg)
407 {
408 u_int32_t *med;
409 char *endptr = NULL;
410 unsigned long tmpval;
411
412 tmpval = strtoul (arg, &endptr, 10);
413 if (*endptr != '\0' || tmpval == ULONG_MAX)
414 return NULL;
415 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
416 *med = tmpval;
417 return med;
418 }
419
420 /* Free route map's compiled `match metric' value. */
421 void
422 route_match_metric_free (void *rule)
423 {
424 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
425 }
426
427 /* Route map commands for metric matching. */
428 struct 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 \f
436 /* `match as-path ASPATH' */
437
438 /* Match function for as-path match. I assume given object is */
439 route_map_result_t
440 route_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. */
462 void *
463 route_match_aspath_compile (char *arg)
464 {
465 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
466 }
467
468 /* Compile function for as-path match. */
469 void
470 route_match_aspath_free (void *rule)
471 {
472 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
473 }
474
475 /* Route map commands for aspath matching. */
476 struct 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 */
488 int
489 route_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. */
502 void *
503 route_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. */
515 void
516 route_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. */
524 struct 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 \f
533 /* `match community COMMUNIY' */
534 struct rmap_community
535 {
536 char *name;
537 int exact;
538 };
539
540 /* Match function for community match. */
541 route_map_result_t
542 route_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. */
573 void *
574 route_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. */
599 void
600 route_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. */
609 struct 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 \f
617 /* Match function for extcommunity match. */
618 route_map_result_t
619 route_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. */
641 void *
642 route_match_ecommunity_compile (char *arg)
643 {
644 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
645 }
646
647 /* Compile function for extcommunity match. */
648 void
649 route_match_ecommunity_free (void *rule)
650 {
651 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
652 }
653
654 /* Route map commands for community matching. */
655 struct 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 \f
663 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
664 and `address-family vpnv4'. */
665 \f
666 /* `match origin' */
667 route_map_result_t
668 route_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
686 void *
687 route_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. */
704 void
705 route_match_origin_free (void *rule)
706 {
707 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
708 }
709
710 /* Route map commands for origin matching. */
711 struct 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. */
721 struct rmap_ip_nexthop_set
722 {
723 struct in_addr *address;
724 int peer_address;
725 };
726
727 route_map_result_t
728 route_set_ip_nexthop (void *rule, struct prefix *prefix,
729 route_map_object_t type, void *object)
730 {
731 struct rmap_ip_nexthop_set *rins = rule;
732 struct in_addr peer_address;
733 struct bgp_info *bgp_info;
734 struct peer *peer;
735
736 if (type == RMAP_BGP)
737 {
738 bgp_info = object;
739 peer = bgp_info->peer;
740
741 if (rins->peer_address)
742 {
743 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
744 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
745 && 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 }
767 }
768
769 return RMAP_OKAY;
770 }
771
772 /* Route map `ip nexthop' compile function. Given string is converted
773 to struct in_addr structure. */
774 void *
775 route_set_ip_nexthop_compile (char *arg)
776 {
777 struct rmap_ip_nexthop_set *rins;
778 struct in_addr *address = NULL;
779 int peer_address = 0;
780 int ret;
781
782 if (strcmp (arg, "peer-address") == 0)
783 peer_address = 1;
784 else
785 {
786 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 }
794 }
795
796 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;
803 }
804
805 /* Free route map's compiled `ip nexthop' value. */
806 void
807 route_set_ip_nexthop_free (void *rule)
808 {
809 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);
815 }
816
817 /* Route map commands for ip nexthop set. */
818 struct 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 \f
826 /* `set local-preference LOCAL_PREF' */
827
828 /* Set local preference. */
829 route_map_result_t
830 route_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. */
851 void *
852 route_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. */
872 void
873 route_set_local_pref_free (void *rule)
874 {
875 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
876 }
877
878 /* Set local preference rule structure. */
879 struct 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 \f
887 /* `set weight WEIGHT' */
888
889 /* Set weight. */
890 route_map_result_t
891 route_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. */
911 void *
912 route_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. */
932 void
933 route_set_weight_free (void *rule)
934 {
935 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
936 }
937
938 /* Set local preference rule structure. */
939 struct 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 \f
947 /* `set metric METRIC' */
948
949 /* Set metric to attribute. */
950 route_map_result_t
951 route_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 {
979 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
980 bgp_info->attr->med = BGP_MED_MAX - 1;
981 else
982 bgp_info->attr->med += metric_val;
983 }
984 else if (strncmp (metric, "-", 1) == 0)
985 {
986 if (bgp_info->attr->med <= metric_val)
987 bgp_info->attr->med = 0;
988 else
989 bgp_info->attr->med -= metric_val;
990 }
991 }
992 }
993 return RMAP_OKAY;
994 }
995
996 /* set metric compilation. */
997 void *
998 route_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. */
1027 void
1028 route_set_metric_free (void *rule)
1029 {
1030 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1031 }
1032
1033 /* Set metric rule structure. */
1034 struct 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 \f
1042 /* `set as-path prepend ASPATH' */
1043
1044 /* For AS path prepend mechanism. */
1045 route_map_result_t
1046 route_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. */
1070 void *
1071 route_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. */
1082 void
1083 route_set_aspath_prepend_free (void *rule)
1084 {
1085 struct aspath *aspath = rule;
1086 aspath_free (aspath);
1087 }
1088
1089 /* Set metric rule structure. */
1090 struct 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 \f
1098 /* `set community COMMUNITY' */
1099 struct rmap_com_set
1100 {
1101 struct community *com;
1102 int additive;
1103 int none;
1104 };
1105
1106 /* For community set mechanism. */
1107 route_map_result_t
1108 route_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. */
1151 void *
1152 route_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. */
1193 void
1194 route_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. */
1204 struct 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 \f
1212 /* `set comm-list (<1-99>|<100-199>|WORD) delete' */
1213
1214 /* For community set mechanism. */
1215 route_map_result_t
1216 route_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. */
1258 void *
1259 route_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. */
1279 void
1280 route_set_community_delete_free (void *rule)
1281 {
1282 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1283 }
1284
1285 /* Set community rule structure. */
1286 struct 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 \f
1294 /* `set extcommunity rt COMMUNITY' */
1295
1296 /* For community set mechanism. */
1297 route_map_result_t
1298 route_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. */
1330 void *
1331 route_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. */
1342 void
1343 route_set_ecommunity_rt_free (void *rule)
1344 {
1345 struct ecommunity *ecom = rule;
1346 ecommunity_free (ecom);
1347 }
1348
1349 /* Set community rule structure. */
1350 struct 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. */
1361 route_map_result_t
1362 route_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. */
1383 void *
1384 route_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. */
1396 void
1397 route_set_ecommunity_soo_free (void *rule)
1398 {
1399 struct ecommunity *ecom = rule;
1400 ecommunity_free (ecom);
1401 }
1402
1403 /* Set community rule structure. */
1404 struct 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 \f
1412 /* `set origin ORIGIN' */
1413
1414 /* For origin set. */
1415 route_map_result_t
1416 route_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. */
1433 void *
1434 route_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. */
1451 void
1452 route_set_origin_free (void *rule)
1453 {
1454 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1455 }
1456
1457 /* Set metric rule structure. */
1458 struct 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 \f
1466 /* `set atomic-aggregate' */
1467
1468 /* For atomic aggregate set. */
1469 route_map_result_t
1470 route_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. */
1485 void *
1486 route_set_atomic_aggregate_compile (char *arg)
1487 {
1488 return (void *)1;
1489 }
1490
1491 /* Compile function for atomic aggregate. */
1492 void
1493 route_set_atomic_aggregate_free (void *rule)
1494 {
1495 return;
1496 }
1497
1498 /* Set atomic aggregate rule structure. */
1499 struct 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 \f
1507 /* `set aggregator as AS A.B.C.D' */
1508 struct aggregator
1509 {
1510 as_t as;
1511 struct in_addr address;
1512 };
1513
1514 route_map_result_t
1515 route_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
1534 void *
1535 route_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
1552 void
1553 route_set_aggregator_as_free (void *rule)
1554 {
1555 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1556 }
1557
1558 struct 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 \f
1566 #ifdef HAVE_IPV6
1567 /* `match ipv6 address IP_ACCESS_LIST' */
1568
1569 route_map_result_t
1570 route_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
1587 void *
1588 route_match_ipv6_address_compile (char *arg)
1589 {
1590 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1591 }
1592
1593 void
1594 route_match_ipv6_address_free (void *rule)
1595 {
1596 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1597 }
1598
1599 /* Route map commands for ip address matching. */
1600 struct 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 \f
1608 /* `match ipv6 next-hop IP_ADDRESS' */
1609
1610 route_map_result_t
1611 route_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
1635 void *
1636 route_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
1653 void
1654 route_match_ipv6_next_hop_free (void *rule)
1655 {
1656 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1657 }
1658
1659 struct 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 \f
1667 /* `match ipv6 address prefix-list PREFIX_LIST' */
1668
1669 route_map_result_t
1670 route_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
1687 void *
1688 route_match_ipv6_address_prefix_list_compile (char *arg)
1689 {
1690 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1691 }
1692
1693 void
1694 route_match_ipv6_address_prefix_list_free (void *rule)
1695 {
1696 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1697 }
1698
1699 struct 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 \f
1707 /* `set ipv6 nexthop global IP_ADDRESS' */
1708
1709 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1710 route_map_result_t
1711 route_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. */
1736 void *
1737 route_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. */
1756 void
1757 route_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. */
1763 struct 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 \f
1771 /* `set ipv6 nexthop local IP_ADDRESS' */
1772
1773 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1774 route_map_result_t
1775 route_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. */
1800 void *
1801 route_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. */
1820 void
1821 route_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. */
1827 struct 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 \f
1836 /* `set vpnv4 nexthop A.B.C.D' */
1837
1838 route_map_result_t
1839 route_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
1858 void *
1859 route_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
1877 void
1878 route_set_vpnv4_nexthop_free (void *rule)
1879 {
1880 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1881 }
1882
1883 /* Route map commands for ip nexthop set. */
1884 struct 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 \f
1892 /* `set originator-id' */
1893
1894 /* For origin set. */
1895 route_map_result_t
1896 route_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. */
1914 void *
1915 route_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. */
1934 void
1935 route_set_originator_id_free (void *rule)
1936 {
1937 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1938 }
1939
1940 /* Set metric rule structure. */
1941 struct 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 \f
1949 /* Add bgp route map rule. */
1950 int
1951 bgp_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. */
1975 int
1976 bgp_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. */
2000 int
2001 bgp_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. */
2025 int
2026 bgp_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. */
2050 void
2051 bgp_route_map_update (char *unused)
2052 {
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
2075 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
2076 {
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
2097 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
2098 {
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 \f
2165 DEFUN (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
2176 DEFUN (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
2186 DEFUN (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
2199 ALIAS (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
2208 ALIAS (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
2216 DEFUN (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
2229 DEFUN (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
2243 ALIAS (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
2254 DEFUN (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
2267 DEFUN (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
2281 ALIAS (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
2292 DEFUN (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
2304 DEFUN (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
2319 ALIAS (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
2329 DEFUN (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
2341 DEFUN (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
2356 ALIAS (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
2366 DEFUN (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
2376 DEFUN (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
2389 ALIAS (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
2397 DEFUN (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
2409 DEFUN (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
2434 DEFUN (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
2444 ALIAS (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
2454 ALIAS (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
2465 DEFUN (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
2477 DEFUN (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
2487 ALIAS (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
2497 DEFUN (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
2507 DEFUN (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
2517 ALIAS (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
2525 DEFUN (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
2544 DEFUN (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
2554 ALIAS (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
2564 DEFUN (set_ip_nexthop,
2565 set_ip_nexthop_cmd,
2566 "set ip next-hop A.B.C.D",
2567 SET_STR
2568 IP_STR
2569 "Next hop address\n"
2570 "IP address of next hop\n")
2571 {
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
2585 DEFUN (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
2596 DEFUN (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
2609 DEFUN (no_set_ip_nexthop,
2610 no_set_ip_nexthop_cmd,
2611 "no set ip next-hop",
2612 NO_STR
2613 SET_STR
2614 "Next hop address\n")
2615 {
2616 if (argc == 0)
2617 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
2622 ALIAS (no_set_ip_nexthop,
2623 no_set_ip_nexthop_val_cmd,
2624 "no set ip next-hop A.B.C.D",
2625 NO_STR
2626 SET_STR
2627 IP_STR
2628 "Next hop address\n"
2629 "IP address of next hop\n")
2630
2631 DEFUN (set_metric,
2632 set_metric_cmd,
2633 "set metric <0-4294967295>",
2634 SET_STR
2635 "Metric value for destination routing protocol\n"
2636 "Metric value\n")
2637 {
2638 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2639 }
2640
2641 ALIAS (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
2648 DEFUN (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
2661 ALIAS (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
2669 DEFUN (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
2679 DEFUN (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
2692 ALIAS (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
2700 DEFUN (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
2710 DEFUN (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
2723 ALIAS (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
2731 DEFUN (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
2749 DEFUN (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
2760 ALIAS (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
2769 DEFUN (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
2862 DEFUN (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
2872 DEFUN (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
2882 ALIAS (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
2890 ALIAS (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
2898 DEFUN (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
2920 DEFUN (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
2930 ALIAS (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
2941 DEFUN (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
2959 DEFUN (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
2970 ALIAS (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
2979 DEFUN (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
2996 DEFUN (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
3007 ALIAS (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
3016 DEFUN (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
3035 DEFUN (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
3045 ALIAS (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
3055 DEFUN (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
3064 DEFUN (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
3074 DEFUN (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
3115 DEFUN (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
3158 ALIAS (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 \f
3169 #ifdef HAVE_IPV6
3170 DEFUN (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
3181 DEFUN (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
3193 DEFUN (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
3204 DEFUN (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
3216 DEFUN (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
3228 DEFUN (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
3241 DEFUN (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
3253 DEFUN (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
3268 ALIAS (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
3278 DEFUN (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
3290 DEFUN (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
3305 ALIAS (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
3316 DEFUN (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
3327 DEFUN (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
3341 ALIAS (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
3350 DEFUN (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
3360 DEFUN (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
3373 ALIAS (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 \f
3382 /* Initialization of route map. */
3383 void
3384 bgp_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
3391 route_map_install_match (&route_match_peer_cmd);
3392 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);
3398 route_map_install_match (&route_match_ecommunity_cmd);
3399 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
3417 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);
3422 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);
3447 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);
3450 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);
3455 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
3456 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);
3465 install_element (RMAP_NODE, &set_metric_addsub_cmd);
3466 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 }