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