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