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