Annotation of embedaddon/quagga/bgpd/bgp_routemap.c, revision 1.1.1.3
1.1 misho 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: route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
111: void *object)
112: {
113: union sockunion *su;
1.1.1.3 ! misho 114: union sockunion su_def = { .sa.sa_family = AF_INET,
! 115: .sin.sin_addr.s_addr = INADDR_ANY };
1.1 misho 116: struct peer_group *group;
117: struct peer *peer;
118: struct listnode *node, *nnode;
119:
120: if (type == RMAP_BGP)
121: {
122: su = rule;
123: peer = ((struct bgp_info *) object)->peer;
124:
125: if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
126: ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
127: 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 */
1.1.1.3 ! misho 131: if (sockunion_same (su, &su_def))
1.1 misho 132: {
133: int ret;
134: if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
135: CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
136: CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
137: ret = RMAP_MATCH;
138: else
139: ret = RMAP_NOMATCH;
140: return ret;
141: }
1.1.1.3 ! misho 142:
1.1 misho 143: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
144: {
145: if (sockunion_same (su, &peer->su))
146: return RMAP_MATCH;
147:
148: return RMAP_NOMATCH;
149: }
150: else
151: {
152: group = peer->group;
153: for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
154: {
155: if (sockunion_same (su, &peer->su))
156: return RMAP_MATCH;
157: }
158: return RMAP_NOMATCH;
159: }
160: }
161: return RMAP_NOMATCH;
162: }
163:
164: static void *
165: route_match_peer_compile (const char *arg)
166: {
167: union sockunion *su;
168: int ret;
169:
170: su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
171:
1.1.1.3 ! misho 172: ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
1.1 misho 173: if (ret < 0) {
174: XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
175: return NULL;
176: }
177:
178: return su;
179: }
180:
181: /* Free route map's compiled `ip address' value. */
182: static void
183: route_match_peer_free (void *rule)
184: {
185: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
186: }
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: 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: if (type == RMAP_BGP)
209: {
210: alist = access_list_lookup (AFI_IP, (char *) rule);
211: if (alist == NULL)
212: return RMAP_NOMATCH;
213:
214: return (access_list_apply (alist, prefix) == FILTER_DENY ?
215: RMAP_NOMATCH : RMAP_MATCH);
216: }
217: return RMAP_NOMATCH;
218: }
219:
220: /* Route map `ip address' match statement. `arg' should be
221: access-list name. */
222: static void *
223: route_match_ip_address_compile (const char *arg)
224: {
225: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
226: }
227:
228: /* Free route map's compiled `ip address' value. */
229: static void
230: route_match_ip_address_free (void *rule)
231: {
232: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
233: }
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: 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: if (type == RMAP_BGP)
256: {
257: bgp_info = object;
258: p.family = AF_INET;
259: p.prefix = bgp_info->attr->nexthop;
260: p.prefixlen = IPV4_MAX_BITLEN;
261:
262: alist = access_list_lookup (AFI_IP, (char *) rule);
263: if (alist == NULL)
264: return RMAP_NOMATCH;
265:
266: return (access_list_apply (alist, &p) == FILTER_DENY ?
267: RMAP_NOMATCH : RMAP_MATCH);
268: }
269: return RMAP_NOMATCH;
270: }
271:
272: /* Route map `ip next-hop' match statement. `arg' is
273: access-list name. */
274: static void *
275: route_match_ip_next_hop_compile (const char *arg)
276: {
277: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
278: }
279:
280: /* Free route map's compiled `ip address' value. */
281: static void
282: route_match_ip_next_hop_free (void *rule)
283: {
284: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
285: }
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: 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: if (type == RMAP_BGP)
309: {
310: bgp_info = object;
311: peer = bgp_info->peer;
312:
313: if (! peer || sockunion_family (&peer->su) != AF_INET)
314: return RMAP_NOMATCH;
315:
316: p.family = AF_INET;
317: p.prefix = peer->su.sin.sin_addr;
318: p.prefixlen = IPV4_MAX_BITLEN;
319:
320: alist = access_list_lookup (AFI_IP, (char *) rule);
321: if (alist == NULL)
322: return RMAP_NOMATCH;
323:
324: return (access_list_apply (alist, &p) == FILTER_DENY ?
325: RMAP_NOMATCH : RMAP_MATCH);
326: }
327: return RMAP_NOMATCH;
328: }
329:
330: /* Route map `ip route-source' match statement. `arg' is
331: access-list name. */
332: static void *
333: route_match_ip_route_source_compile (const char *arg)
334: {
335: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
336: }
337:
338: /* Free route map's compiled `ip address' value. */
339: static void
340: route_match_ip_route_source_free (void *rule)
341: {
342: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
343: }
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: 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: if (type == RMAP_BGP)
363: {
364: plist = prefix_list_lookup (AFI_IP, (char *) rule);
365: if (plist == NULL)
366: return RMAP_NOMATCH;
367:
368: return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
369: RMAP_NOMATCH : RMAP_MATCH);
370: }
371: return RMAP_NOMATCH;
372: }
373:
374: static void *
375: route_match_ip_address_prefix_list_compile (const char *arg)
376: {
377: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
378: }
379:
380: static void
381: route_match_ip_address_prefix_list_free (void *rule)
382: {
383: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
384: }
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: 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: if (type == RMAP_BGP)
405: {
406: bgp_info = object;
407: p.family = AF_INET;
408: p.prefix = bgp_info->attr->nexthop;
409: p.prefixlen = IPV4_MAX_BITLEN;
410:
411: plist = prefix_list_lookup (AFI_IP, (char *) rule);
412: if (plist == NULL)
413: return RMAP_NOMATCH;
414:
415: return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
416: RMAP_NOMATCH : RMAP_MATCH);
417: }
418: return RMAP_NOMATCH;
419: }
420:
421: static void *
422: route_match_ip_next_hop_prefix_list_compile (const char *arg)
423: {
424: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
425: }
426:
427: static void
428: route_match_ip_next_hop_prefix_list_free (void *rule)
429: {
430: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
431: }
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: 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: if (type == RMAP_BGP)
453: {
454: bgp_info = object;
455: peer = bgp_info->peer;
456:
457: if (! peer || sockunion_family (&peer->su) != AF_INET)
458: return RMAP_NOMATCH;
459:
460: p.family = AF_INET;
461: p.prefix = peer->su.sin.sin_addr;
462: p.prefixlen = IPV4_MAX_BITLEN;
463:
464: plist = prefix_list_lookup (AFI_IP, (char *) rule);
465: if (plist == NULL)
466: return RMAP_NOMATCH;
467:
468: return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
469: RMAP_NOMATCH : RMAP_MATCH);
470: }
471: return RMAP_NOMATCH;
472: }
473:
474: static void *
475: route_match_ip_route_source_prefix_list_compile (const char *arg)
476: {
477: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
478: }
479:
480: static void
481: route_match_ip_route_source_prefix_list_free (void *rule)
482: {
483: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
484: }
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: 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: if (type == RMAP_BGP)
505: {
506: med = rule;
507: bgp_info = object;
508:
509: if (bgp_info->attr->med == *med)
510: return RMAP_MATCH;
511: else
512: return RMAP_NOMATCH;
513: }
514: return RMAP_NOMATCH;
515: }
516:
517: /* Route map `match metric' match statement. `arg' is MED value */
518: static void *
519: route_match_metric_compile (const char *arg)
520: {
521: u_int32_t *med;
522: char *endptr = NULL;
523: unsigned long tmpval;
524:
1.1.1.2 misho 525: /* Metric value shoud be integer. */
526: if (! all_digit (arg))
527: return NULL;
528:
529: errno = 0;
1.1 misho 530: tmpval = strtoul (arg, &endptr, 10);
1.1.1.2 misho 531: if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
1.1 misho 532: return NULL;
533:
534: med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
535:
536: if (!med)
537: return med;
538:
539: *med = tmpval;
540: return med;
541: }
542:
543: /* Free route map's compiled `match metric' value. */
544: static void
545: route_match_metric_free (void *rule)
546: {
547: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
548: }
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: 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: if (type == RMAP_BGP)
571: {
572: as_list = as_list_lookup ((char *) rule);
573: if (as_list == NULL)
574: return RMAP_NOMATCH;
575:
576: bgp_info = object;
577:
578: /* Perform match. */
579: return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
580: }
581: return RMAP_NOMATCH;
582: }
583:
584: /* Compile function for as-path match. */
585: static void *
586: route_match_aspath_compile (const char *arg)
587: {
588: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
589: }
590:
591: /* Compile function for as-path match. */
592: static void
593: route_match_aspath_free (void *rule)
594: {
595: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
596: }
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: 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: if (type == RMAP_BGP)
624: {
625: bgp_info = object;
626: rcom = rule;
627:
628: list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
629: if (! list)
630: return RMAP_NOMATCH;
631:
632: if (rcom->exact)
633: {
634: if (community_list_exact_match (bgp_info->attr->community, list))
635: return RMAP_MATCH;
636: }
637: else
638: {
639: if (community_list_match (bgp_info->attr->community, list))
640: return RMAP_MATCH;
641: }
642: }
643: return RMAP_NOMATCH;
644: }
645:
646: /* Compile function for community match. */
647: static void *
648: route_match_community_compile (const char *arg)
649: {
650: struct rmap_community *rcom;
651: int len;
652: char *p;
653:
654: rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
655:
656: p = strchr (arg, ' ');
657: if (p)
658: {
659: len = p - arg;
660: rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
661: memcpy (rcom->name, arg, len);
662: rcom->exact = 1;
663: }
664: else
665: {
666: rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
667: rcom->exact = 0;
668: }
669: return rcom;
670: }
671:
672: /* Compile function for community match. */
673: static void
674: route_match_community_free (void *rule)
675: {
676: struct rmap_community *rcom = rule;
677:
678: XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
679: XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
680: }
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: 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: if (type == RMAP_BGP)
700: {
701: bgp_info = object;
702:
703: if (!bgp_info->attr->extra)
704: return RMAP_NOMATCH;
705:
706: list = community_list_lookup (bgp_clist, (char *) rule,
707: EXTCOMMUNITY_LIST_MASTER);
708: if (! list)
709: return RMAP_NOMATCH;
710:
711: if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
712: return RMAP_MATCH;
713: }
714: return RMAP_NOMATCH;
715: }
716:
717: /* Compile function for extcommunity match. */
718: static void *
719: route_match_ecommunity_compile (const char *arg)
720: {
721: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
722: }
723:
724: /* Compile function for extcommunity match. */
725: static void
726: route_match_ecommunity_free (void *rule)
727: {
728: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
729: }
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: 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: if (type == RMAP_BGP)
752: {
753: origin = rule;
754: bgp_info = object;
755:
756: if (bgp_info->attr->origin == *origin)
757: return RMAP_MATCH;
758: }
759:
760: return RMAP_NOMATCH;
761: }
762:
763: static void *
764: route_match_origin_compile (const char *arg)
765: {
766: u_char *origin;
767:
768: origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
769:
770: if (strcmp (arg, "igp") == 0)
771: *origin = 0;
772: else if (strcmp (arg, "egp") == 0)
773: *origin = 1;
774: else
775: *origin = 2;
776:
777: return origin;
778: }
779:
780: /* Free route map's compiled `ip address' value. */
781: static void
782: route_match_origin_free (void *rule)
783: {
784: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
785: }
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: };
1.1.1.2 misho 795:
796: /* match probability { */
797:
798: static route_map_result_t
799: 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: r = random();
805: #else
806: r = (long) rand();
807: #endif
808:
809: switch (*(unsigned *) rule)
810: {
811: case 0: break;
812: case RAND_MAX: return RMAP_MATCH;
813: default:
814: if (r < *(unsigned *) rule)
815: {
816: return RMAP_MATCH;
817: }
818: }
819:
820: return RMAP_NOMATCH;
821: }
822:
823: static void *
824: 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: srandom (time (NULL));
831: #else
832: srand (time (NULL));
833: #endif
834:
835: perc = atoi (arg);
836: lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
837:
838: switch (perc)
839: {
840: case 0: *lobule = 0; break;
841: case 100: *lobule = RAND_MAX; break;
842: default: *lobule = RAND_MAX / 100 * perc;
843: }
844:
845: return lobule;
846: }
847:
848: static void
849: route_match_probability_free (void *rule)
850: {
851: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
852: }
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:
1.1 misho 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: route_set_ip_nexthop (void *rule, struct prefix *prefix,
875: route_map_object_t type, void *object)
876: {
877: struct rmap_ip_nexthop_set *rins = rule;
878: struct bgp_info *bgp_info;
879: struct peer *peer;
880:
881: if (type == RMAP_BGP)
882: {
883: bgp_info = object;
884: peer = bgp_info->peer;
885:
886: if (rins->peer_address)
887: {
888: if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
889: CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
890: && peer->su_remote
891: && sockunion_family (peer->su_remote) == AF_INET)
892: {
1.1.1.3 ! misho 893: bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
1.1 misho 894: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
895: }
896: else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
897: && peer->su_local
898: && sockunion_family (peer->su_local) == AF_INET)
899: {
1.1.1.3 ! misho 900: bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
1.1 misho 901: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
902: }
903: }
904: else
905: {
906: /* Set next hop value. */
907: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
908: bgp_info->attr->nexthop = *rins->address;
909: }
910: }
911:
912: 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: route_set_ip_nexthop_compile (const char *arg)
919: {
920: struct rmap_ip_nexthop_set *rins;
921: struct in_addr *address = NULL;
922: int peer_address = 0;
923: int ret;
924:
925: if (strcmp (arg, "peer-address") == 0)
926: peer_address = 1;
927: else
928: {
929: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
930: ret = inet_aton (arg, address);
931:
932: if (ret == 0)
933: {
934: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
935: return NULL;
936: }
937: }
938:
939: rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
940:
941: rins->address = address;
942: rins->peer_address = peer_address;
943:
944: return rins;
945: }
946:
947: /* Free route map's compiled `ip nexthop' value. */
948: static void
949: route_set_ip_nexthop_free (void *rule)
950: {
951: struct rmap_ip_nexthop_set *rins = rule;
952:
953: if (rins->address)
954: XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
955:
956: XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
957: }
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: 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: if (type == RMAP_BGP)
979: {
980: /* Fetch routemap's rule information. */
981: local_pref = rule;
982: bgp_info = object;
983:
984: /* Set local preference value. */
985: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
986: bgp_info->attr->local_pref = *local_pref;
987: }
988:
989: return RMAP_OKAY;
990: }
991:
992: /* set local preference compilation. */
993: static void *
994: route_set_local_pref_compile (const char *arg)
995: {
996: unsigned long tmp;
997: u_int32_t *local_pref;
998: char *endptr = NULL;
999:
1000: /* Local preference value shoud be integer. */
1001: if (! all_digit (arg))
1002: return NULL;
1003:
1.1.1.2 misho 1004: errno = 0;
1.1 misho 1005: tmp = strtoul (arg, &endptr, 10);
1.1.1.2 misho 1006: if (*endptr != '\0' || errno || tmp > UINT32_MAX)
1.1 misho 1007: return NULL;
1008:
1009: local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1010:
1011: if (!local_pref)
1012: return local_pref;
1013:
1014: *local_pref = tmp;
1015:
1016: return local_pref;
1017: }
1018:
1019: /* Free route map's local preference value. */
1020: static void
1021: route_set_local_pref_free (void *rule)
1022: {
1023: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1024: }
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: 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: if (type == RMAP_BGP)
1046: {
1047: /* Fetch routemap's rule information. */
1048: weight = rule;
1049: bgp_info = object;
1050:
1051: /* Set weight value. */
1052: if (*weight)
1053: (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1054: else if (bgp_info->attr->extra)
1055: bgp_info->attr->extra->weight = 0;
1056: }
1057:
1058: return RMAP_OKAY;
1059: }
1060:
1061: /* set local preference compilation. */
1062: static void *
1063: route_set_weight_compile (const char *arg)
1064: {
1065: unsigned long tmp;
1066: u_int32_t *weight;
1067: char *endptr = NULL;
1068:
1069: /* Local preference value shoud be integer. */
1070: if (! all_digit (arg))
1071: return NULL;
1072:
1.1.1.2 misho 1073: errno = 0;
1.1 misho 1074: tmp = strtoul (arg, &endptr, 10);
1.1.1.2 misho 1075: if (*endptr != '\0' || errno || tmp > UINT32_MAX)
1.1 misho 1076: return NULL;
1077:
1078: weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1079:
1080: if (weight == NULL)
1081: return weight;
1082:
1083: *weight = tmp;
1084:
1085: return weight;
1086: }
1087:
1088: /* Free route map's local preference value. */
1089: static void
1090: route_set_weight_free (void *rule)
1091: {
1092: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1093: }
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: 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: if (type == RMAP_BGP)
1116: {
1117: /* Fetch routemap's rule information. */
1118: metric = rule;
1119: bgp_info = object;
1120:
1121: if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1122: bgp_info->attr->med = 0;
1123: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1124:
1125: if (all_digit (metric))
1126: {
1127: metric_val = strtoul (metric, (char **)NULL, 10);
1128: bgp_info->attr->med = metric_val;
1129: }
1130: else
1131: {
1132: metric_val = strtoul (metric+1, (char **)NULL, 10);
1133:
1134: if (strncmp (metric, "+", 1) == 0)
1135: {
1136: if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1137: bgp_info->attr->med = BGP_MED_MAX - 1;
1138: else
1139: bgp_info->attr->med += metric_val;
1140: }
1141: else if (strncmp (metric, "-", 1) == 0)
1142: {
1143: if (bgp_info->attr->med <= metric_val)
1144: bgp_info->attr->med = 0;
1145: else
1146: bgp_info->attr->med -= metric_val;
1147: }
1148: }
1149: }
1150: return RMAP_OKAY;
1151: }
1152:
1153: /* set metric compilation. */
1154: static void *
1155: route_set_metric_compile (const char *arg)
1156: {
1157: u_int32_t metric;
1158: unsigned long larg;
1159: char *endptr = NULL;
1160:
1161: if (all_digit (arg))
1162: {
1163: /* set metric value check*/
1.1.1.2 misho 1164: errno = 0;
1.1 misho 1165: larg = strtoul (arg, &endptr, 10);
1.1.1.2 misho 1166: if (*endptr != '\0' || errno || larg > UINT32_MAX)
1.1 misho 1167: return NULL;
1168: metric = larg;
1169: }
1170: else
1171: {
1172: /* set metric +/-value check */
1173: if ((strncmp (arg, "+", 1) != 0
1174: && strncmp (arg, "-", 1) != 0)
1175: || (! all_digit (arg+1)))
1176: return NULL;
1177:
1.1.1.2 misho 1178: errno = 0;
1.1 misho 1179: larg = strtoul (arg+1, &endptr, 10);
1.1.1.2 misho 1180: if (*endptr != '\0' || errno || larg > UINT32_MAX)
1.1 misho 1181: return NULL;
1182: metric = larg;
1183: }
1184:
1185: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1186: }
1187:
1188: /* Free route map's compiled `set metric' value. */
1189: static void
1190: route_set_metric_free (void *rule)
1191: {
1192: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1193: }
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: 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: if (type == RMAP_BGP)
1215: {
1216: aspath = rule;
1217: binfo = object;
1218:
1219: if (binfo->attr->aspath->refcnt)
1220: new = aspath_dup (binfo->attr->aspath);
1221: else
1222: new = binfo->attr->aspath;
1223:
1224: aspath_prepend (aspath, new);
1225: binfo->attr->aspath = new;
1226: }
1227:
1228: return RMAP_OKAY;
1229: }
1230:
1231: /* Compile function for as-path prepend. */
1232: static void *
1233: route_set_aspath_prepend_compile (const char *arg)
1234: {
1235: struct aspath *aspath;
1236:
1237: aspath = aspath_str2aspath (arg);
1238: if (! aspath)
1239: return NULL;
1240: return aspath;
1241: }
1242:
1243: /* Compile function for as-path prepend. */
1244: static void
1245: route_set_aspath_prepend_free (void *rule)
1246: {
1247: struct aspath *aspath = rule;
1248: aspath_free (aspath);
1249: }
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: 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: if (type == RMAP_BGP)
1273: {
1274: exclude_path = rule;
1275: binfo = object;
1276: if (binfo->attr->aspath->refcnt)
1277: new_path = aspath_dup (binfo->attr->aspath);
1278: else
1279: new_path = binfo->attr->aspath;
1280: binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1281: }
1282: 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: route_set_aspath_exclude_compile (const char *arg)
1293: {
1294: struct aspath *aspath;
1295:
1296: aspath = aspath_str2aspath (arg);
1297: if (! aspath)
1298: return NULL;
1299: return aspath;
1300: }
1301:
1302: static void
1303: route_set_aspath_exclude_free (void *rule)
1304: {
1305: struct aspath *aspath = rule;
1306: aspath_free (aspath);
1307: }
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: 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: struct community *new = NULL;
1335: struct community *old;
1336: struct community *merge;
1337:
1338: if (type == RMAP_BGP)
1339: {
1340: rcs = rule;
1341: binfo = object;
1342: attr = binfo->attr;
1343: old = attr->community;
1344:
1345: /* "none" case. */
1346: if (rcs->none)
1347: {
1348: attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1349: attr->community = NULL;
1.1.1.3 ! misho 1350: /* See the longer comment down below. */
! 1351: if (old && old->refcnt == 0)
! 1352: community_free(old);
1.1 misho 1353: return RMAP_OKAY;
1354: }
1355:
1356: /* "additive" case. */
1357: if (rcs->additive && old)
1358: {
1359: 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: if (old->refcnt == 0)
1366: community_free (old);
1367: new = community_uniq_sort (merge);
1368: community_free (merge);
1369: }
1370: else
1371: new = community_dup (rcs->com);
1372:
1373: /* will be interned by caller if required */
1374: attr->community = new;
1375:
1376: attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1377: }
1378:
1379: return RMAP_OKAY;
1380: }
1381:
1382: /* Compile function for set community. */
1383: static void *
1384: route_set_community_compile (const char *arg)
1385: {
1386: struct rmap_com_set *rcs;
1387: struct community *com = NULL;
1388: char *sp;
1389: int additive = 0;
1390: int none = 0;
1391:
1392: if (strcmp (arg, "none") == 0)
1393: none = 1;
1394: else
1395: {
1396: sp = strstr (arg, "additive");
1397:
1398: if (sp && sp > arg)
1399: {
1400: /* "additive" keyworkd is included. */
1401: additive = 1;
1402: *(sp - 1) = '\0';
1403: }
1404:
1405: com = community_str2com (arg);
1406:
1407: if (additive)
1408: *(sp - 1) = ' ';
1409:
1410: if (! com)
1411: return NULL;
1412: }
1413:
1414: rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1415: rcs->com = com;
1416: rcs->additive = additive;
1417: rcs->none = none;
1418:
1419: return rcs;
1420: }
1421:
1422: /* Free function for set community. */
1423: static void
1424: route_set_community_free (void *rule)
1425: {
1426: struct rmap_com_set *rcs = rule;
1427:
1428: if (rcs->com)
1429: community_free (rcs->com);
1430: XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1431: }
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: 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: if (type == RMAP_BGP)
1456: {
1457: if (! rule)
1458: return RMAP_OKAY;
1459:
1460: binfo = object;
1461: list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
1462: old = binfo->attr->community;
1463:
1464: if (list && old)
1465: {
1466: merge = community_list_match_delete (community_dup (old), list);
1467: new = community_uniq_sort (merge);
1468: 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: if (old->refcnt == 0)
1475: community_free (old);
1476:
1477: if (new->size == 0)
1478: {
1479: binfo->attr->community = NULL;
1480: binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1481: community_free (new);
1482: }
1483: else
1484: {
1485: binfo->attr->community = new;
1486: binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1487: }
1488: }
1489: }
1490:
1491: return RMAP_OKAY;
1492: }
1493:
1494: /* Compile function for set community. */
1495: static void *
1496: route_set_community_delete_compile (const char *arg)
1497: {
1498: char *p;
1499: char *str;
1500: int len;
1501:
1502: p = strchr (arg, ' ');
1503: if (p)
1504: {
1505: len = p - arg;
1506: str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1507: memcpy (str, arg, len);
1508: }
1509: else
1510: str = NULL;
1511:
1512: return str;
1513: }
1514:
1515: /* Free function for set community. */
1516: static void
1517: route_set_community_delete_free (void *rule)
1518: {
1519: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1520: }
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: 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: if (type == RMAP_BGP)
1544: {
1545: ecom = rule;
1546: bgp_info = object;
1547:
1548: if (! ecom)
1549: return RMAP_OKAY;
1550:
1551: /* We assume additive for Extended Community. */
1552: old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1553:
1554: if (old_ecom)
1555: new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1556: else
1557: new_ecom = ecommunity_dup (ecom);
1558:
1559: bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1560:
1561: if (old_ecom)
1562: ecommunity_unintern (&old_ecom);
1563:
1564: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1565: }
1566: return RMAP_OKAY;
1567: }
1568:
1569: /* Compile function for set community. */
1570: static void *
1571: route_set_ecommunity_rt_compile (const char *arg)
1572: {
1573: struct ecommunity *ecom;
1574:
1575: ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1576: if (! ecom)
1577: return NULL;
1578: return ecommunity_intern (ecom);
1579: }
1580:
1581: /* Free function for set community. */
1582: static void
1583: route_set_ecommunity_rt_free (void *rule)
1584: {
1585: struct ecommunity *ecom = rule;
1586: ecommunity_unintern (&ecom);
1587: }
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: 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: if (type == RMAP_BGP)
1609: {
1610: ecom = rule;
1611: bgp_info = object;
1612:
1613: if (! ecom)
1614: return RMAP_OKAY;
1615:
1616: old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1617:
1618: if (old_ecom)
1619: new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1620: else
1621: new_ecom = ecommunity_dup (ecom);
1622:
1623: bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1624:
1625: if (old_ecom)
1626: ecommunity_unintern (&old_ecom);
1627:
1628: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1629: }
1630: return RMAP_OKAY;
1631: }
1632:
1633: /* Compile function for set community. */
1634: static void *
1635: route_set_ecommunity_soo_compile (const char *arg)
1636: {
1637: struct ecommunity *ecom;
1638:
1639: ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1640: if (! ecom)
1641: return NULL;
1642:
1643: return ecommunity_intern (ecom);
1644: }
1645:
1646: /* Free function for set community. */
1647: static void
1648: route_set_ecommunity_soo_free (void *rule)
1649: {
1650: struct ecommunity *ecom = rule;
1651: ecommunity_unintern (&ecom);
1652: }
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: 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: if (type == RMAP_BGP)
1673: {
1674: origin = rule;
1675: bgp_info = object;
1676:
1677: bgp_info->attr->origin = *origin;
1678: }
1679:
1680: return RMAP_OKAY;
1681: }
1682:
1683: /* Compile function for origin set. */
1684: static void *
1685: route_set_origin_compile (const char *arg)
1686: {
1687: u_char *origin;
1688:
1689: origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1690:
1691: if (strcmp (arg, "igp") == 0)
1692: *origin = 0;
1693: else if (strcmp (arg, "egp") == 0)
1694: *origin = 1;
1695: else
1696: *origin = 2;
1697:
1698: return origin;
1699: }
1700:
1701: /* Compile function for origin set. */
1702: static void
1703: route_set_origin_free (void *rule)
1704: {
1705: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1706: }
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: 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: if (type == RMAP_BGP)
1727: {
1728: bgp_info = object;
1729: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1730: }
1731:
1732: return RMAP_OKAY;
1733: }
1734:
1735: /* Compile function for atomic aggregate. */
1736: static void *
1737: route_set_atomic_aggregate_compile (const char *arg)
1738: {
1739: return (void *)1;
1740: }
1741:
1742: /* Compile function for atomic aggregate. */
1743: static void
1744: route_set_atomic_aggregate_free (void *rule)
1745: {
1746: 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: 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: if (type == RMAP_BGP)
1774: {
1775: bgp_info = object;
1776: aggregator = rule;
1777: ae = bgp_attr_extra_get (bgp_info->attr);
1778:
1779: ae->aggregator_as = aggregator->as;
1780: ae->aggregator_addr = aggregator->address;
1781: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1782: }
1783:
1784: return RMAP_OKAY;
1785: }
1786:
1787: static void *
1788: route_set_aggregator_as_compile (const char *arg)
1789: {
1790: struct aggregator *aggregator;
1791: char as[10];
1792: char address[20];
1793:
1794: aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1795: sscanf (arg, "%s %s", as, address);
1796:
1797: aggregator->as = strtoul (as, NULL, 10);
1798: inet_aton (address, &aggregator->address);
1799:
1800: return aggregator;
1801: }
1802:
1803: static void
1804: route_set_aggregator_as_free (void *rule)
1805: {
1806: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1807: }
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: 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: if (type == RMAP_BGP)
1827: {
1828: alist = access_list_lookup (AFI_IP6, (char *) rule);
1829: if (alist == NULL)
1830: return RMAP_NOMATCH;
1831:
1832: return (access_list_apply (alist, prefix) == FILTER_DENY ?
1833: RMAP_NOMATCH : RMAP_MATCH);
1834: }
1835: return RMAP_NOMATCH;
1836: }
1837:
1838: static void *
1839: route_match_ipv6_address_compile (const char *arg)
1840: {
1841: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1842: }
1843:
1844: static void
1845: route_match_ipv6_address_free (void *rule)
1846: {
1847: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1848: }
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: 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: if (type == RMAP_BGP)
1869: {
1870: addr = rule;
1871: bgp_info = object;
1872:
1873: if (!bgp_info->attr->extra)
1874: return RMAP_NOMATCH;
1875:
1876: if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
1877: return RMAP_MATCH;
1878:
1879: if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1880: IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
1881: return RMAP_MATCH;
1882:
1883: return RMAP_NOMATCH;
1884: }
1885:
1886: return RMAP_NOMATCH;
1887: }
1888:
1889: static void *
1890: route_match_ipv6_next_hop_compile (const char *arg)
1891: {
1892: struct in6_addr *address;
1893: int ret;
1894:
1895: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1896:
1897: ret = inet_pton (AF_INET6, arg, address);
1898: if (!ret)
1899: {
1900: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1901: return NULL;
1902: }
1903:
1904: return address;
1905: }
1906:
1907: static void
1908: route_match_ipv6_next_hop_free (void *rule)
1909: {
1910: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1911: }
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: 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: if (type == RMAP_BGP)
1930: {
1931: plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1932: if (plist == NULL)
1933: return RMAP_NOMATCH;
1934:
1935: return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1936: RMAP_NOMATCH : RMAP_MATCH);
1937: }
1938: return RMAP_NOMATCH;
1939: }
1940:
1941: static void *
1942: route_match_ipv6_address_prefix_list_compile (const char *arg)
1943: {
1944: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1945: }
1946:
1947: static void
1948: route_match_ipv6_address_prefix_list_free (void *rule)
1949: {
1950: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1951: }
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: 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: if (type == RMAP_BGP)
1972: {
1973: /* Fetch routemap's rule information. */
1974: address = rule;
1975: bgp_info = object;
1976:
1977: /* Set next hop value. */
1978: (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
1979:
1980: /* Set nexthop length. */
1981: if (bgp_info->attr->extra->mp_nexthop_len == 0)
1982: bgp_info->attr->extra->mp_nexthop_len = 16;
1983: }
1984:
1985: 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: route_set_ipv6_nexthop_global_compile (const char *arg)
1992: {
1993: int ret;
1994: struct in6_addr *address;
1995:
1996: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1997:
1998: ret = inet_pton (AF_INET6, arg, address);
1999:
2000: if (ret == 0)
2001: {
2002: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2003: return NULL;
2004: }
2005:
2006: return address;
2007: }
2008:
2009: /* Free route map's compiled `ip next-hop' value. */
2010: static void
2011: route_set_ipv6_nexthop_global_free (void *rule)
2012: {
2013: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2014: }
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: 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: if (type == RMAP_BGP)
2036: {
2037: /* Fetch routemap's rule information. */
2038: address = rule;
2039: bgp_info = object;
2040:
2041: /* Set next hop value. */
2042: (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
2043:
2044: /* Set nexthop length. */
2045: if (bgp_info->attr->extra->mp_nexthop_len != 32)
2046: bgp_info->attr->extra->mp_nexthop_len = 32;
2047: }
2048:
2049: 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: route_set_ipv6_nexthop_local_compile (const char *arg)
2056: {
2057: int ret;
2058: struct in6_addr *address;
2059:
2060: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2061:
2062: ret = inet_pton (AF_INET6, arg, address);
2063:
2064: if (ret == 0)
2065: {
2066: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2067: return NULL;
2068: }
2069:
2070: return address;
2071: }
2072:
2073: /* Free route map's compiled `ip nexthop' value. */
2074: static void
2075: route_set_ipv6_nexthop_local_free (void *rule)
2076: {
2077: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2078: }
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: 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: if (type == RMAP_BGP)
2100: {
2101: /* Fetch routemap's rule information. */
2102: address = rule;
2103: bgp_info = object;
2104:
2105: /* Set next hop value. */
2106: (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
2107: }
2108:
2109: return RMAP_OKAY;
2110: }
2111:
2112: static void *
2113: route_set_vpnv4_nexthop_compile (const char *arg)
2114: {
2115: int ret;
2116: struct in_addr *address;
2117:
2118: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2119:
2120: ret = inet_aton (arg, address);
2121:
2122: if (ret == 0)
2123: {
2124: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2125: return NULL;
2126: }
2127:
2128: return address;
2129: }
2130:
2131: static void
2132: route_set_vpnv4_nexthop_free (void *rule)
2133: {
2134: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2135: }
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: 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: if (type == RMAP_BGP)
2156: {
2157: address = rule;
2158: bgp_info = object;
2159:
2160: bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
2161: (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
2162: }
2163:
2164: return RMAP_OKAY;
2165: }
2166:
2167: /* Compile function for originator-id set. */
2168: static void *
2169: route_set_originator_id_compile (const char *arg)
2170: {
2171: int ret;
2172: struct in_addr *address;
2173:
2174: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2175:
2176: ret = inet_aton (arg, address);
2177:
2178: if (ret == 0)
2179: {
2180: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2181: return NULL;
2182: }
2183:
2184: return address;
2185: }
2186:
2187: /* Compile function for originator_id set. */
2188: static void
2189: route_set_originator_id_free (void *rule)
2190: {
2191: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2192: }
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: 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: ret = route_map_add_match (index, command, arg);
2211: if (ret)
2212: {
2213: switch (ret)
2214: {
2215: case RMAP_RULE_MISSING:
2216: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2217: return CMD_WARNING;
2218: case RMAP_COMPILE_ERROR:
2219: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2220: return CMD_WARNING;
2221: }
2222: }
2223: return CMD_SUCCESS;
2224: }
2225:
2226: /* Delete bgp route map rule. */
2227: static int
2228: 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: ret = route_map_delete_match (index, command, arg);
2234: if (ret)
2235: {
2236: switch (ret)
2237: {
2238: case RMAP_RULE_MISSING:
2239: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2240: return CMD_WARNING;
2241: case RMAP_COMPILE_ERROR:
2242: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2243: return CMD_WARNING;
2244: }
2245: }
2246: return CMD_SUCCESS;
2247: }
2248:
2249: /* Add bgp route map rule. */
2250: static int
2251: 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: ret = route_map_add_set (index, command, arg);
2257: if (ret)
2258: {
2259: switch (ret)
2260: {
2261: case RMAP_RULE_MISSING:
2262: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2263: return CMD_WARNING;
2264: case RMAP_COMPILE_ERROR:
2265: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2266: return CMD_WARNING;
2267: }
2268: }
2269: return CMD_SUCCESS;
2270: }
2271:
2272: /* Delete bgp route map rule. */
2273: static int
2274: 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: ret = route_map_delete_set (index, command, arg);
2280: if (ret)
2281: {
2282: switch (ret)
2283: {
2284: case RMAP_RULE_MISSING:
2285: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2286: return CMD_WARNING;
2287: case RMAP_COMPILE_ERROR:
2288: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2289: return CMD_WARNING;
2290: }
2291: }
2292: return CMD_SUCCESS;
2293: }
2294:
2295: /* Hook function for updating route_map assignment. */
2296: static void
2297: 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: for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2314: {
2315: for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2316: {
2317: for (afi = AFI_IP; afi < AFI_MAX; afi++)
2318: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2319: {
2320: filter = &peer->filter[afi][safi];
2321:
2322: for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
2323: {
2324: if (filter->map[direct].name)
2325: filter->map[direct].map =
2326: route_map_lookup_by_name (filter->map[direct].name);
2327: else
2328: filter->map[direct].map = NULL;
2329: }
2330:
2331: if (filter->usmap.name)
2332: filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2333: else
2334: filter->usmap.map = NULL;
2335: }
2336: }
2337: for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2338: {
2339: for (afi = AFI_IP; afi < AFI_MAX; afi++)
2340: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2341: {
2342: filter = &group->conf->filter[afi][safi];
2343:
2344: for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
2345: {
2346: if (filter->map[direct].name)
2347: filter->map[direct].map =
2348: route_map_lookup_by_name (filter->map[direct].name);
2349: else
2350: filter->map[direct].map = NULL;
2351: }
2352:
2353: if (filter->usmap.name)
2354: filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2355: else
2356: filter->usmap.map = NULL;
2357: }
2358: }
2359: }
2360:
2361: /* For default-originate route-map updates. */
2362: for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2363: {
2364: for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2365: {
2366: for (afi = AFI_IP; afi < AFI_MAX; afi++)
2367: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2368: {
2369: if (peer->default_rmap[afi][safi].name)
2370: peer->default_rmap[afi][safi].map =
2371: route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2372: else
2373: peer->default_rmap[afi][safi].map = NULL;
2374: }
2375: }
2376: }
2377:
2378: /* For network route-map updates. */
2379: for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2380: {
2381: for (afi = AFI_IP; afi < AFI_MAX; afi++)
2382: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2383: for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2384: bn = bgp_route_next (bn))
2385: if ((bgp_static = bn->info) != NULL)
2386: {
2387: if (bgp_static->rmap.name)
2388: bgp_static->rmap.map =
2389: route_map_lookup_by_name (bgp_static->rmap.name);
2390: else
2391: bgp_static->rmap.map = NULL;
2392: }
2393: }
2394:
2395: /* For redistribute route-map updates. */
2396: for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2397: {
2398: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2399: {
2400: if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2401: bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2402: route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2403: #ifdef HAVE_IPV6
2404: if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2405: bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2406: route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2407: #endif /* HAVE_IPV6 */
2408: }
2409: }
2410: }
2411:
2412: 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: return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2421: }
2422:
2423: 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: {
1.1.1.3 ! misho 2430: return bgp_route_match_add (vty, vty->index, "peer", "local");
1.1 misho 2431: }
2432:
2433: 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: if (argc == 0)
2441: return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2442:
2443: 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: 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: return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2474: }
2475:
2476: 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: if (argc == 0)
2485: return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2486:
2487: 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: 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: return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2512: }
2513:
2514: 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: if (argc == 0)
2523: return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2524:
2525: 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:
1.1.1.2 misho 2539: /* match probability { */
2540:
2541: 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: return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2549: }
2550:
2551: 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: 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:
1.1 misho 2571: 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: return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2582: }
2583:
2584: 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: if (argc == 0)
2593: return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2594:
2595: 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: 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: return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2619: }
2620:
2621: 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: if (argc == 0)
2631: return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2632:
2633: 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: 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: return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2656: }
2657:
2658: 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: if (argc == 0)
2668: return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2669:
2670: 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: 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: return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2693: }
2694:
2695: 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: if (argc == 0)
2705: return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2706:
2707: 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: 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: return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2728: }
2729:
2730: 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: if (argc == 0)
2738: return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2739:
2740: 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: 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: return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2761: }
2762:
2763: 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: argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2777: strlen (argv[0]) + strlen ("exact-match") + 2);
2778:
2779: sprintf (argstr, "%s exact-match", argv[0]);
2780:
2781: ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2782:
2783: XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2784:
2785: return ret;
2786: }
2787:
2788: 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: 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: 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: return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2829: }
2830:
2831: 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: 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: 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: return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2859: }
2860:
2861: 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: 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: 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: if (strncmp (argv[0], "igp", 2) == 0)
2889: return bgp_route_match_add (vty, vty->index, "origin", "igp");
2890: if (strncmp (argv[0], "egp", 1) == 0)
2891: return bgp_route_match_add (vty, vty->index, "origin", "egp");
2892: if (strncmp (argv[0], "incomplete", 2) == 0)
2893: return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2894:
2895: return CMD_WARNING;
2896: }
2897:
2898: 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: 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: 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: ret = str2sockunion (argv[0], &su);
2930: if (ret < 0)
2931: {
2932: vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2933: return CMD_WARNING;
2934: }
2935:
2936: return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2937: }
2938:
2939: 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: return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2948: }
2949:
2950: 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: return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2960: }
2961:
2962:
2963: 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: if (argc == 0)
2971: return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2972:
2973: 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: 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: 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: 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: if (argc == 0)
3010: return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3011:
3012: 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: 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: return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3031: }
3032:
3033: 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: if (argc == 0)
3041: return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3042:
3043: 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: 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: return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3062: }
3063:
3064: 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: if (argc == 0)
3072: return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3073:
3074: 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: 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: str = argv_concat (argv, argc, 0);
3097: ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3098: XFREE (MTYPE_TMP, str);
3099:
3100: return ret;
3101: }
3102:
3103: 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: if (argc == 0)
3115: return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3116:
3117: str = argv_concat (argv, argc, 0);
3118: ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3119: XFREE (MTYPE_TMP, str);
3120: 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: 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: str = argv_concat (argv, argc, 0);
3144: ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3145: XFREE (MTYPE_TMP, str);
3146: return ret;
3147: }
3148:
3149: 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: if (argc == 0)
3161: return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3162:
3163: str = argv_concat (argv, argc, 0);
3164: ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3165: XFREE (MTYPE_TMP, str);
3166: 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: 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: int first = 0;
3187: int additive = 0;
3188: struct buffer *b;
3189: struct community *com = NULL;
3190: char *str;
3191: char *argstr;
3192: int ret;
3193:
3194: b = buffer_new (1024);
3195:
3196: for (i = 0; i < argc; i++)
3197: {
3198: if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3199: {
3200: additive = 1;
3201: continue;
3202: }
3203:
3204: if (first)
3205: buffer_putc (b, ' ');
3206: else
3207: first = 1;
3208:
3209: if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3210: {
3211: buffer_putstr (b, "internet");
3212: continue;
3213: }
3214: if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3215: {
3216: buffer_putstr (b, "local-AS");
3217: continue;
3218: }
3219: if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3220: && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3221: {
3222: buffer_putstr (b, "no-advertise");
3223: continue;
3224: }
3225: if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3226: && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3227: {
3228: buffer_putstr (b, "no-export");
3229: continue;
3230: }
3231: buffer_putstr (b, argv[i]);
3232: }
3233: buffer_putc (b, '\0');
3234:
3235: /* Fetch result string then compile it to communities attribute. */
3236: str = buffer_getstr (b);
3237: buffer_free (b);
3238:
3239: if (str)
3240: {
3241: com = community_str2com (str);
3242: XFREE (MTYPE_TMP, str);
3243: }
3244:
3245: /* Can't compile user input into communities attribute. */
3246: if (! com)
3247: {
3248: vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3249: return CMD_WARNING;
3250: }
3251:
3252: /* Set communites attribute string. */
3253: str = community_str (com);
3254:
3255: if (additive)
3256: {
3257: argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3258: strcpy (argstr, str);
3259: strcpy (argstr + strlen (str), " additive");
3260: ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3261: XFREE (MTYPE_TMP, argstr);
3262: }
3263: else
3264: ret = bgp_route_set_add (vty, vty->index, "community", str);
3265:
3266: community_free (com);
3267:
3268: return ret;
3269: }
3270:
3271: 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: return bgp_route_set_add (vty, vty->index, "community", "none");
3279: }
3280:
3281: 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: 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: 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: str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3320: strcpy (str, argv[0]);
3321: strcpy (str + strlen (argv[0]), " delete");
3322:
3323: bgp_route_set_add (vty, vty->index, "comm-list", str);
3324:
3325: XFREE (MTYPE_TMP, str);
3326: return CMD_SUCCESS;
3327: }
3328:
3329: 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: 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: 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: str = argv_concat (argv, argc, 0);
3362: ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3363: XFREE (MTYPE_TMP, str);
3364:
3365: return ret;
3366: }
3367:
3368: 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: 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: 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: str = argv_concat (argv, argc, 0);
3400: ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3401: XFREE (MTYPE_TMP, str);
3402: return ret;
3403: }
3404:
3405: 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: 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: 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: if (strncmp (argv[0], "igp", 2) == 0)
3435: return bgp_route_set_add (vty, vty->index, "origin", "igp");
3436: if (strncmp (argv[0], "egp", 1) == 0)
3437: return bgp_route_set_add (vty, vty->index, "origin", "egp");
3438: if (strncmp (argv[0], "incomplete", 2) == 0)
3439: return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3440:
3441: return CMD_WARNING;
3442: }
3443:
3444: 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: 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: DEFUN (set_atomic_aggregate,
3465: set_atomic_aggregate_cmd,
3466: "set atomic-aggregate",
3467: SET_STR
3468: "BGP atomic aggregate attribute\n" )
3469: {
3470: return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3471: }
3472:
3473: 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: return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3481: }
3482:
3483: 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: VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
3498:
3499: ret = inet_aton (argv[1], &address);
3500: if (ret == 0)
3501: {
3502: vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3503: return CMD_WARNING;
3504: }
3505:
3506: argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3507: strlen (argv[0]) + strlen (argv[1]) + 2);
3508:
3509: sprintf (argstr, "%s %s", argv[0], argv[1]);
3510:
3511: ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3512:
3513: XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3514:
3515: return ret;
3516: }
3517:
3518: 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: if (argv == 0)
3532: return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3533:
3534: VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
3535:
3536: ret = inet_aton (argv[1], &address);
3537: if (ret == 0)
3538: {
3539: vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3540: return CMD_WARNING;
3541: }
3542:
3543: argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3544: strlen (argv[0]) + strlen (argv[1]) + 2);
3545:
3546: sprintf (argstr, "%s %s", argv[0], argv[1]);
3547:
3548: ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3549:
3550: XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3551:
3552: 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: 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: return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3576: }
3577:
3578: 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: return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3588: }
3589:
3590: 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: return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3599: }
3600:
3601: 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: return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3611: }
3612:
3613: 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: return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3623: }
3624:
3625: 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: return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3636: }
3637:
3638: 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: return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3648: }
3649:
3650: 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: if (argc == 0)
3660: return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3661:
3662: 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: 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: return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3685: }
3686:
3687: 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: if (argc == 0)
3697: return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3698:
3699: 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: 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: return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3722: }
3723:
3724: 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: if (argc == 0)
3733: return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3734:
3735: 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: 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: return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3755: }
3756:
3757: 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: if (argc == 0)
3765: return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3766:
3767: 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: 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: return CMD_SUCCESS;
3786: }
3787:
3788: 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: 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: 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: return CMD_SUCCESS;
3815: }
3816:
3817: 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: 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: bgp_route_map_init (void)
3840: {
3841: route_map_init ();
3842: route_map_init_vty ();
3843: route_map_add_hook (bgp_route_map_update);
3844: route_map_delete_hook (bgp_route_map_update);
3845:
3846: route_map_install_match (&route_match_peer_cmd);
3847: route_map_install_match (&route_match_ip_address_cmd);
3848: route_map_install_match (&route_match_ip_next_hop_cmd);
3849: route_map_install_match (&route_match_ip_route_source_cmd);
3850: route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3851: route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
3852: route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
3853: route_map_install_match (&route_match_aspath_cmd);
3854: route_map_install_match (&route_match_community_cmd);
3855: route_map_install_match (&route_match_ecommunity_cmd);
3856: route_map_install_match (&route_match_metric_cmd);
3857: route_map_install_match (&route_match_origin_cmd);
1.1.1.2 misho 3858: route_map_install_match (&route_match_probability_cmd);
1.1 misho 3859:
3860: route_map_install_set (&route_set_ip_nexthop_cmd);
3861: route_map_install_set (&route_set_local_pref_cmd);
3862: route_map_install_set (&route_set_weight_cmd);
3863: route_map_install_set (&route_set_metric_cmd);
3864: route_map_install_set (&route_set_aspath_prepend_cmd);
3865: route_map_install_set (&route_set_aspath_exclude_cmd);
3866: route_map_install_set (&route_set_origin_cmd);
3867: route_map_install_set (&route_set_atomic_aggregate_cmd);
3868: route_map_install_set (&route_set_aggregator_as_cmd);
3869: route_map_install_set (&route_set_community_cmd);
3870: route_map_install_set (&route_set_community_delete_cmd);
3871: route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3872: route_map_install_set (&route_set_originator_id_cmd);
3873: route_map_install_set (&route_set_ecommunity_rt_cmd);
3874: route_map_install_set (&route_set_ecommunity_soo_cmd);
3875:
3876: install_element (RMAP_NODE, &match_peer_cmd);
3877: install_element (RMAP_NODE, &match_peer_local_cmd);
3878: install_element (RMAP_NODE, &no_match_peer_cmd);
3879: install_element (RMAP_NODE, &no_match_peer_val_cmd);
3880: install_element (RMAP_NODE, &no_match_peer_local_cmd);
3881: install_element (RMAP_NODE, &match_ip_address_cmd);
3882: install_element (RMAP_NODE, &no_match_ip_address_cmd);
3883: install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3884: install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3885: install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3886: install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
3887: install_element (RMAP_NODE, &match_ip_route_source_cmd);
3888: install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3889: install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
3890: install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3891: install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3892: install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3893: install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3894: install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3895: install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
3896: install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3897: install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3898: install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
3899:
3900: install_element (RMAP_NODE, &match_aspath_cmd);
3901: install_element (RMAP_NODE, &no_match_aspath_cmd);
3902: install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3903: install_element (RMAP_NODE, &match_metric_cmd);
3904: install_element (RMAP_NODE, &no_match_metric_cmd);
3905: install_element (RMAP_NODE, &no_match_metric_val_cmd);
3906: install_element (RMAP_NODE, &match_community_cmd);
3907: install_element (RMAP_NODE, &match_community_exact_cmd);
3908: install_element (RMAP_NODE, &no_match_community_cmd);
3909: install_element (RMAP_NODE, &no_match_community_val_cmd);
3910: install_element (RMAP_NODE, &no_match_community_exact_cmd);
3911: install_element (RMAP_NODE, &match_ecommunity_cmd);
3912: install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3913: install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
3914: install_element (RMAP_NODE, &match_origin_cmd);
3915: install_element (RMAP_NODE, &no_match_origin_cmd);
3916: install_element (RMAP_NODE, &no_match_origin_val_cmd);
1.1.1.2 misho 3917: install_element (RMAP_NODE, &match_probability_cmd);
3918: install_element (RMAP_NODE, &no_match_probability_cmd);
3919: install_element (RMAP_NODE, &no_match_probability_val_cmd);
1.1 misho 3920:
3921: install_element (RMAP_NODE, &set_ip_nexthop_cmd);
3922: install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
3923: install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3924: install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3925: install_element (RMAP_NODE, &set_local_pref_cmd);
3926: install_element (RMAP_NODE, &no_set_local_pref_cmd);
3927: install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3928: install_element (RMAP_NODE, &set_weight_cmd);
3929: install_element (RMAP_NODE, &no_set_weight_cmd);
3930: install_element (RMAP_NODE, &no_set_weight_val_cmd);
3931: install_element (RMAP_NODE, &set_metric_cmd);
3932: install_element (RMAP_NODE, &set_metric_addsub_cmd);
3933: install_element (RMAP_NODE, &no_set_metric_cmd);
3934: install_element (RMAP_NODE, &no_set_metric_val_cmd);
3935: install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3936: install_element (RMAP_NODE, &set_aspath_exclude_cmd);
3937: install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3938: install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3939: install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3940: install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
3941: install_element (RMAP_NODE, &set_origin_cmd);
3942: install_element (RMAP_NODE, &no_set_origin_cmd);
3943: install_element (RMAP_NODE, &no_set_origin_val_cmd);
3944: install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3945: install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3946: install_element (RMAP_NODE, &set_aggregator_as_cmd);
3947: install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3948: install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3949: install_element (RMAP_NODE, &set_community_cmd);
3950: install_element (RMAP_NODE, &set_community_none_cmd);
3951: install_element (RMAP_NODE, &no_set_community_cmd);
3952: install_element (RMAP_NODE, &no_set_community_val_cmd);
3953: install_element (RMAP_NODE, &no_set_community_none_cmd);
3954: install_element (RMAP_NODE, &set_community_delete_cmd);
3955: install_element (RMAP_NODE, &no_set_community_delete_cmd);
3956: install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3957: install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3958: install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3959: install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3960: install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3961: install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3962: install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3963: install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3964: install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3965: install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3966: install_element (RMAP_NODE, &set_originator_id_cmd);
3967: install_element (RMAP_NODE, &no_set_originator_id_cmd);
3968: install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3969:
3970: #ifdef HAVE_IPV6
3971: route_map_install_match (&route_match_ipv6_address_cmd);
3972: route_map_install_match (&route_match_ipv6_next_hop_cmd);
3973: route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3974: route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3975: route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3976:
3977: install_element (RMAP_NODE, &match_ipv6_address_cmd);
3978: install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3979: install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3980: install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3981: install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3982: install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3983: install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3984: install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3985: install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3986: install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3987: install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3988: 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: install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3995: install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3996: install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3997: install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3998: install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3999: install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
4000: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>