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