blob: bc9b6f788d3949881959b0a5c8423ea603b02deb [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "prefix.h"
24#include "filter.h"
25#include "routemap.h"
26#include "command.h"
27#include "linklist.h"
28#include "plist.h"
29#include "memory.h"
30#include "log.h"
31#ifdef HAVE_GNU_REGEX
32#include <regex.h>
33#else
34#include "regex-gnu.h"
35#endif /* HAVE_GNU_REGEX */
36#include "buffer.h"
37#include "sockunion.h"
38
39#include "bgpd/bgpd.h"
40#include "bgpd/bgp_table.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_aspath.h"
43#include "bgpd/bgp_route.h"
44#include "bgpd/bgp_regex.h"
45#include "bgpd/bgp_community.h"
46#include "bgpd/bgp_clist.h"
47#include "bgpd/bgp_filter.h"
48#include "bgpd/bgp_mplsvpn.h"
49#include "bgpd/bgp_ecommunity.h"
50
51/* Memo of route-map commands.
52
53o Cisco route-map
54
55 match as-path : Done
56 community : Done
57 interface : Not yet
58 ip address : Done
59 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000060 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000061 ip prefix-list : Done
62 ipv6 address : Done
63 ipv6 next-hop : Done
64 ipv6 route-source: (This will not be implemented by bgpd)
65 ipv6 prefix-list : Done
66 length : (This will not be implemented by bgpd)
67 metric : Done
68 route-type : (This will not be implemented by bgpd)
69 tag : (This will not be implemented by bgpd)
70
71 set as-path prepend : Done
72 as-path tag : Not yet
73 automatic-tag : (This will not be implemented by bgpd)
74 community : Done
75 comm-list : Not yet
76 dampning : Not yet
77 default : (This will not be implemented by bgpd)
78 interface : (This will not be implemented by bgpd)
79 ip default : (This will not be implemented by bgpd)
80 ip next-hop : Done
81 ip precedence : (This will not be implemented by bgpd)
82 ip tos : (This will not be implemented by bgpd)
83 level : (This will not be implemented by bgpd)
84 local-preference : Done
85 metric : Done
86 metric-type : Not yet
87 origin : Done
88 tag : (This will not be implemented by bgpd)
89 weight : Done
90
91o Local extention
92
93 set ipv6 next-hop global: Done
94 set ipv6 next-hop local : Done
95
96*/
97
paulfee0f4c2004-09-13 05:12:46 +000098 /* 'match peer (A.B.C.D|X:X::X:X)' */
99
100/* Compares the peer specified in the 'match peer' clause with the peer
101 received in bgp_info->peer. If it is the same, or if the peer structure
102 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000103static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000104route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
105 void *object)
106{
107 union sockunion *su;
108 union sockunion *su2;
109 struct peer_group *group;
110 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000111 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000112
113 if (type == RMAP_BGP)
114 {
115 su = rule;
116 peer = ((struct bgp_info *) object)->peer;
117
118 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
119 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
120 return RMAP_NOMATCH;
121
122 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
123 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
124 su2 = sockunion_str2su ("0.0.0.0");
125 if ( sockunion_same (su, su2) )
126 {
paul22db9de2005-05-19 01:50:11 +0000127 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000128 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
129 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
130 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000131 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000132 else
paul22db9de2005-05-19 01:50:11 +0000133 ret = RMAP_NOMATCH;
134
135 sockunion_free (su2);
136 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000137 }
paul22db9de2005-05-19 01:50:11 +0000138 sockunion_free (su2);
139
paulfee0f4c2004-09-13 05:12:46 +0000140 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
141 {
142 if (sockunion_same (su, &peer->su))
143 return RMAP_MATCH;
144
145 return RMAP_NOMATCH;
146 }
147 else
148 {
149 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000150 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000151 {
152 if (sockunion_same (su, &peer->su))
153 return RMAP_MATCH;
154
155 return RMAP_NOMATCH;
156 }
157 }
158 }
159 return RMAP_NOMATCH;
160}
161
paul94f2b392005-06-28 12:44:16 +0000162static void *
paulfd79ac92004-10-13 05:06:08 +0000163route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000164{
165 union sockunion *su;
166 int ret;
167
168 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
169
170 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
171 if (ret < 0) {
172 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
173 return NULL;
174 }
175
176 return su;
177}
178
179/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000180static void
paulfee0f4c2004-09-13 05:12:46 +0000181route_match_peer_free (void *rule)
182{
183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
184}
185
186/* Route map commands for ip address matching. */
187struct route_map_rule_cmd route_match_peer_cmd =
188{
189 "peer",
190 route_match_peer,
191 route_match_peer_compile,
192 route_match_peer_free
193};
194
paul718e3742002-12-13 20:15:29 +0000195/* `match ip address IP_ACCESS_LIST' */
196
197/* Match function should return 1 if match is success else return
198 zero. */
paul94f2b392005-06-28 12:44:16 +0000199static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000200route_match_ip_address (void *rule, struct prefix *prefix,
201 route_map_object_t type, void *object)
202{
203 struct access_list *alist;
204 /* struct prefix_ipv4 match; */
205
206 if (type == RMAP_BGP)
207 {
208 alist = access_list_lookup (AFI_IP, (char *) rule);
209 if (alist == NULL)
210 return RMAP_NOMATCH;
211
212 return (access_list_apply (alist, prefix) == FILTER_DENY ?
213 RMAP_NOMATCH : RMAP_MATCH);
214 }
215 return RMAP_NOMATCH;
216}
217
218/* Route map `ip address' match statement. `arg' should be
219 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000220static void *
paulfd79ac92004-10-13 05:06:08 +0000221route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000222{
223 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
224}
225
226/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000227static void
paul718e3742002-12-13 20:15:29 +0000228route_match_ip_address_free (void *rule)
229{
230 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
231}
232
233/* Route map commands for ip address matching. */
234struct route_map_rule_cmd route_match_ip_address_cmd =
235{
236 "ip address",
237 route_match_ip_address,
238 route_match_ip_address_compile,
239 route_match_ip_address_free
240};
241
242/* `match ip next-hop IP_ADDRESS' */
243
244/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000245static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000246route_match_ip_next_hop (void *rule, struct prefix *prefix,
247 route_map_object_t type, void *object)
248{
249 struct access_list *alist;
250 struct bgp_info *bgp_info;
251 struct prefix_ipv4 p;
252
253 if (type == RMAP_BGP)
254 {
255 bgp_info = object;
256 p.family = AF_INET;
257 p.prefix = bgp_info->attr->nexthop;
258 p.prefixlen = IPV4_MAX_BITLEN;
259
260 alist = access_list_lookup (AFI_IP, (char *) rule);
261 if (alist == NULL)
262 return RMAP_NOMATCH;
263
264 return (access_list_apply (alist, &p) == FILTER_DENY ?
265 RMAP_NOMATCH : RMAP_MATCH);
266 }
267 return RMAP_NOMATCH;
268}
269
270/* Route map `ip next-hop' match statement. `arg' is
271 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000272static void *
paulfd79ac92004-10-13 05:06:08 +0000273route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000274{
275 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
276}
277
278/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000279static void
paul718e3742002-12-13 20:15:29 +0000280route_match_ip_next_hop_free (void *rule)
281{
282 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
283}
284
285/* Route map commands for ip next-hop matching. */
286struct route_map_rule_cmd route_match_ip_next_hop_cmd =
287{
288 "ip next-hop",
289 route_match_ip_next_hop,
290 route_match_ip_next_hop_compile,
291 route_match_ip_next_hop_free
292};
293
hassoc1643bb2005-02-02 16:43:17 +0000294/* `match ip route-source ACCESS-LIST' */
295
296/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000297static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000298route_match_ip_route_source (void *rule, struct prefix *prefix,
299 route_map_object_t type, void *object)
300{
301 struct access_list *alist;
302 struct bgp_info *bgp_info;
303 struct peer *peer;
304 struct prefix_ipv4 p;
305
306 if (type == RMAP_BGP)
307 {
308 bgp_info = object;
309 peer = bgp_info->peer;
310
311 if (! peer || sockunion_family (&peer->su) != AF_INET)
312 return RMAP_NOMATCH;
313
314 p.family = AF_INET;
315 p.prefix = peer->su.sin.sin_addr;
316 p.prefixlen = IPV4_MAX_BITLEN;
317
318 alist = access_list_lookup (AFI_IP, (char *) rule);
319 if (alist == NULL)
320 return RMAP_NOMATCH;
321
322 return (access_list_apply (alist, &p) == FILTER_DENY ?
323 RMAP_NOMATCH : RMAP_MATCH);
324 }
325 return RMAP_NOMATCH;
326}
327
328/* Route map `ip route-source' match statement. `arg' is
329 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000330static void *
hassoc1643bb2005-02-02 16:43:17 +0000331route_match_ip_route_source_compile (const char *arg)
332{
333 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
334}
335
336/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000337static void
hassoc1643bb2005-02-02 16:43:17 +0000338route_match_ip_route_source_free (void *rule)
339{
340 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
341}
342
343/* Route map commands for ip route-source matching. */
344struct route_map_rule_cmd route_match_ip_route_source_cmd =
345{
346 "ip route-source",
347 route_match_ip_route_source,
348 route_match_ip_route_source_compile,
349 route_match_ip_route_source_free
350};
351
paul718e3742002-12-13 20:15:29 +0000352/* `match ip address prefix-list PREFIX_LIST' */
353
paul94f2b392005-06-28 12:44:16 +0000354static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000355route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
356 route_map_object_t type, void *object)
357{
358 struct prefix_list *plist;
359
360 if (type == RMAP_BGP)
361 {
362 plist = prefix_list_lookup (AFI_IP, (char *) rule);
363 if (plist == NULL)
364 return RMAP_NOMATCH;
365
366 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
367 RMAP_NOMATCH : RMAP_MATCH);
368 }
369 return RMAP_NOMATCH;
370}
371
paul94f2b392005-06-28 12:44:16 +0000372static void *
paulfd79ac92004-10-13 05:06:08 +0000373route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000374{
375 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
376}
377
paul94f2b392005-06-28 12:44:16 +0000378static void
paul718e3742002-12-13 20:15:29 +0000379route_match_ip_address_prefix_list_free (void *rule)
380{
381 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
382}
383
384struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
385{
386 "ip address prefix-list",
387 route_match_ip_address_prefix_list,
388 route_match_ip_address_prefix_list_compile,
389 route_match_ip_address_prefix_list_free
390};
391
392/* `match ip next-hop prefix-list PREFIX_LIST' */
393
paul94f2b392005-06-28 12:44:16 +0000394static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000395route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
396 route_map_object_t type, void *object)
397{
398 struct prefix_list *plist;
399 struct bgp_info *bgp_info;
400 struct prefix_ipv4 p;
401
402 if (type == RMAP_BGP)
403 {
404 bgp_info = object;
405 p.family = AF_INET;
406 p.prefix = bgp_info->attr->nexthop;
407 p.prefixlen = IPV4_MAX_BITLEN;
408
409 plist = prefix_list_lookup (AFI_IP, (char *) rule);
410 if (plist == NULL)
411 return RMAP_NOMATCH;
412
413 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
414 RMAP_NOMATCH : RMAP_MATCH);
415 }
416 return RMAP_NOMATCH;
417}
418
paul94f2b392005-06-28 12:44:16 +0000419static void *
paulfd79ac92004-10-13 05:06:08 +0000420route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000421{
422 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
423}
424
paul94f2b392005-06-28 12:44:16 +0000425static void
paul718e3742002-12-13 20:15:29 +0000426route_match_ip_next_hop_prefix_list_free (void *rule)
427{
428 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
429}
430
431struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
432{
433 "ip next-hop prefix-list",
434 route_match_ip_next_hop_prefix_list,
435 route_match_ip_next_hop_prefix_list_compile,
436 route_match_ip_next_hop_prefix_list_free
437};
438
hassoc1643bb2005-02-02 16:43:17 +0000439/* `match ip route-source prefix-list PREFIX_LIST' */
440
paul94f2b392005-06-28 12:44:16 +0000441static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000442route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
443 route_map_object_t type, void *object)
444{
445 struct prefix_list *plist;
446 struct bgp_info *bgp_info;
447 struct peer *peer;
448 struct prefix_ipv4 p;
449
450 if (type == RMAP_BGP)
451 {
452 bgp_info = object;
453 peer = bgp_info->peer;
454
455 if (! peer || sockunion_family (&peer->su) != AF_INET)
456 return RMAP_NOMATCH;
457
458 p.family = AF_INET;
459 p.prefix = peer->su.sin.sin_addr;
460 p.prefixlen = IPV4_MAX_BITLEN;
461
462 plist = prefix_list_lookup (AFI_IP, (char *) rule);
463 if (plist == NULL)
464 return RMAP_NOMATCH;
465
466 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
467 RMAP_NOMATCH : RMAP_MATCH);
468 }
469 return RMAP_NOMATCH;
470}
471
paul94f2b392005-06-28 12:44:16 +0000472static void *
hassoc1643bb2005-02-02 16:43:17 +0000473route_match_ip_route_source_prefix_list_compile (const char *arg)
474{
475 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
476}
477
paul94f2b392005-06-28 12:44:16 +0000478static void
hassoc1643bb2005-02-02 16:43:17 +0000479route_match_ip_route_source_prefix_list_free (void *rule)
480{
481 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
482}
483
484struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
485{
486 "ip route-source prefix-list",
487 route_match_ip_route_source_prefix_list,
488 route_match_ip_route_source_prefix_list_compile,
489 route_match_ip_route_source_prefix_list_free
490};
491
paul718e3742002-12-13 20:15:29 +0000492/* `match metric METRIC' */
493
494/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000495static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000496route_match_metric (void *rule, struct prefix *prefix,
497 route_map_object_t type, void *object)
498{
499 u_int32_t *med;
500 struct bgp_info *bgp_info;
501
502 if (type == RMAP_BGP)
503 {
504 med = rule;
505 bgp_info = object;
506
507 if (bgp_info->attr->med == *med)
508 return RMAP_MATCH;
509 else
510 return RMAP_NOMATCH;
511 }
512 return RMAP_NOMATCH;
513}
514
515/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000516static void *
paulfd79ac92004-10-13 05:06:08 +0000517route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000518{
519 u_int32_t *med;
520 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000521 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000522
paul3b424972003-10-13 09:47:32 +0000523 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000524 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000525 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000526
paul718e3742002-12-13 20:15:29 +0000527 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000528
529 if (!med)
530 return med;
531
paul3b424972003-10-13 09:47:32 +0000532 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000533 return med;
534}
535
536/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000537static void
paul718e3742002-12-13 20:15:29 +0000538route_match_metric_free (void *rule)
539{
540 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
541}
542
543/* Route map commands for metric matching. */
544struct route_map_rule_cmd route_match_metric_cmd =
545{
546 "metric",
547 route_match_metric,
548 route_match_metric_compile,
549 route_match_metric_free
550};
551
552/* `match as-path ASPATH' */
553
554/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000555static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000556route_match_aspath (void *rule, struct prefix *prefix,
557 route_map_object_t type, void *object)
558{
559
560 struct as_list *as_list;
561 struct bgp_info *bgp_info;
562
563 if (type == RMAP_BGP)
564 {
565 as_list = as_list_lookup ((char *) rule);
566 if (as_list == NULL)
567 return RMAP_NOMATCH;
568
569 bgp_info = object;
570
571 /* Perform match. */
572 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
573 }
574 return RMAP_NOMATCH;
575}
576
577/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000578static void *
paulfd79ac92004-10-13 05:06:08 +0000579route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000580{
581 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
582}
583
584/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000585static void
paul718e3742002-12-13 20:15:29 +0000586route_match_aspath_free (void *rule)
587{
588 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
589}
590
591/* Route map commands for aspath matching. */
592struct route_map_rule_cmd route_match_aspath_cmd =
593{
594 "as-path",
595 route_match_aspath,
596 route_match_aspath_compile,
597 route_match_aspath_free
598};
paul718e3742002-12-13 20:15:29 +0000599
600/* `match community COMMUNIY' */
601struct rmap_community
602{
603 char *name;
604 int exact;
605};
606
607/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000608static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000609route_match_community (void *rule, struct prefix *prefix,
610 route_map_object_t type, void *object)
611{
612 struct community_list *list;
613 struct bgp_info *bgp_info;
614 struct rmap_community *rcom;
615
616 if (type == RMAP_BGP)
617 {
618 bgp_info = object;
619 rcom = rule;
620
hassofee6e4e2005-02-02 16:29:31 +0000621 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000622 if (! list)
623 return RMAP_NOMATCH;
624
625 if (rcom->exact)
626 {
627 if (community_list_exact_match (bgp_info->attr->community, list))
628 return RMAP_MATCH;
629 }
630 else
631 {
632 if (community_list_match (bgp_info->attr->community, list))
633 return RMAP_MATCH;
634 }
635 }
636 return RMAP_NOMATCH;
637}
638
639/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000640static void *
paulfd79ac92004-10-13 05:06:08 +0000641route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000642{
643 struct rmap_community *rcom;
644 int len;
645 char *p;
646
647 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
648
649 p = strchr (arg, ' ');
650 if (p)
651 {
652 len = p - arg;
653 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
654 memcpy (rcom->name, arg, len);
655 rcom->exact = 1;
656 }
657 else
658 {
659 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
660 rcom->exact = 0;
661 }
662 return rcom;
663}
664
665/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000666static void
paul718e3742002-12-13 20:15:29 +0000667route_match_community_free (void *rule)
668{
669 struct rmap_community *rcom = rule;
670
671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
672 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
673}
674
675/* Route map commands for community matching. */
676struct route_map_rule_cmd route_match_community_cmd =
677{
678 "community",
679 route_match_community,
680 route_match_community_compile,
681 route_match_community_free
682};
683
paul73ffb252003-04-19 15:49:49 +0000684/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000685static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000686route_match_ecommunity (void *rule, struct prefix *prefix,
687 route_map_object_t type, void *object)
688{
689 struct community_list *list;
690 struct bgp_info *bgp_info;
691
692 if (type == RMAP_BGP)
693 {
694 bgp_info = object;
695
696 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000697 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000698 if (! list)
699 return RMAP_NOMATCH;
700
701 if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
702 return RMAP_MATCH;
703 }
704 return RMAP_NOMATCH;
705}
706
707/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000708static void *
paulfd79ac92004-10-13 05:06:08 +0000709route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000710{
711 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
712}
713
714/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000715static void
paul73ffb252003-04-19 15:49:49 +0000716route_match_ecommunity_free (void *rule)
717{
718 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
719}
720
721/* Route map commands for community matching. */
722struct route_map_rule_cmd route_match_ecommunity_cmd =
723{
724 "extcommunity",
725 route_match_ecommunity,
726 route_match_ecommunity_compile,
727 route_match_ecommunity_free
728};
729
paul718e3742002-12-13 20:15:29 +0000730/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
731 and `address-family vpnv4'. */
732
733/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000734static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000735route_match_origin (void *rule, struct prefix *prefix,
736 route_map_object_t type, void *object)
737{
738 u_char *origin;
739 struct bgp_info *bgp_info;
740
741 if (type == RMAP_BGP)
742 {
743 origin = rule;
744 bgp_info = object;
745
746 if (bgp_info->attr->origin == *origin)
747 return RMAP_MATCH;
748 }
749
750 return RMAP_NOMATCH;
751}
752
paul94f2b392005-06-28 12:44:16 +0000753static void *
paulfd79ac92004-10-13 05:06:08 +0000754route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000755{
756 u_char *origin;
757
758 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
759
760 if (strcmp (arg, "igp") == 0)
761 *origin = 0;
762 else if (strcmp (arg, "egp") == 0)
763 *origin = 1;
764 else
765 *origin = 2;
766
767 return origin;
768}
769
770/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000771static void
paul718e3742002-12-13 20:15:29 +0000772route_match_origin_free (void *rule)
773{
774 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
775}
776
777/* Route map commands for origin matching. */
778struct route_map_rule_cmd route_match_origin_cmd =
779{
780 "origin",
781 route_match_origin,
782 route_match_origin_compile,
783 route_match_origin_free
784};
785/* `set ip next-hop IP_ADDRESS' */
786
787/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000788struct rmap_ip_nexthop_set
789{
790 struct in_addr *address;
791 int peer_address;
792};
793
paul94f2b392005-06-28 12:44:16 +0000794static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000795route_set_ip_nexthop (void *rule, struct prefix *prefix,
796 route_map_object_t type, void *object)
797{
paulac41b2a2003-08-12 05:32:27 +0000798 struct rmap_ip_nexthop_set *rins = rule;
799 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000800 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000801 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000802
803 if (type == RMAP_BGP)
804 {
paul718e3742002-12-13 20:15:29 +0000805 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000806 peer = bgp_info->peer;
807
808 if (rins->peer_address)
809 {
paulfee0f4c2004-09-13 05:12:46 +0000810 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
811 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000812 && peer->su_remote
813 && sockunion_family (peer->su_remote) == AF_INET)
814 {
815 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
816 bgp_info->attr->nexthop = peer_address;
817 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
818 }
819 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
820 && peer->su_local
821 && sockunion_family (peer->su_local) == AF_INET)
822 {
823 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
824 bgp_info->attr->nexthop = peer_address;
825 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
826 }
827 }
828 else
829 {
830 /* Set next hop value. */
831 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
832 bgp_info->attr->nexthop = *rins->address;
833 }
paul718e3742002-12-13 20:15:29 +0000834 }
835
836 return RMAP_OKAY;
837}
838
839/* Route map `ip nexthop' compile function. Given string is converted
840 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000841static void *
paulfd79ac92004-10-13 05:06:08 +0000842route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000843{
paulac41b2a2003-08-12 05:32:27 +0000844 struct rmap_ip_nexthop_set *rins;
845 struct in_addr *address = NULL;
846 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000847 int ret;
paul718e3742002-12-13 20:15:29 +0000848
paulac41b2a2003-08-12 05:32:27 +0000849 if (strcmp (arg, "peer-address") == 0)
850 peer_address = 1;
851 else
paul718e3742002-12-13 20:15:29 +0000852 {
paulac41b2a2003-08-12 05:32:27 +0000853 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
854 ret = inet_aton (arg, address);
855
856 if (ret == 0)
857 {
858 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
859 return NULL;
860 }
paul718e3742002-12-13 20:15:29 +0000861 }
862
paulac41b2a2003-08-12 05:32:27 +0000863 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
864 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
865
866 rins->address = address;
867 rins->peer_address = peer_address;
868
869 return rins;
paul718e3742002-12-13 20:15:29 +0000870}
871
872/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000873static void
paul718e3742002-12-13 20:15:29 +0000874route_set_ip_nexthop_free (void *rule)
875{
paulac41b2a2003-08-12 05:32:27 +0000876 struct rmap_ip_nexthop_set *rins = rule;
877
878 if (rins->address)
879 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
880
881 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000882}
883
884/* Route map commands for ip nexthop set. */
885struct route_map_rule_cmd route_set_ip_nexthop_cmd =
886{
887 "ip next-hop",
888 route_set_ip_nexthop,
889 route_set_ip_nexthop_compile,
890 route_set_ip_nexthop_free
891};
892
893/* `set local-preference LOCAL_PREF' */
894
895/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000896static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000897route_set_local_pref (void *rule, struct prefix *prefix,
898 route_map_object_t type, void *object)
899{
900 u_int32_t *local_pref;
901 struct bgp_info *bgp_info;
902
903 if (type == RMAP_BGP)
904 {
905 /* Fetch routemap's rule information. */
906 local_pref = rule;
907 bgp_info = object;
908
909 /* Set local preference value. */
910 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
911 bgp_info->attr->local_pref = *local_pref;
912 }
913
914 return RMAP_OKAY;
915}
916
917/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000918static void *
paulfd79ac92004-10-13 05:06:08 +0000919route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000920{
paulfd79ac92004-10-13 05:06:08 +0000921 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000922 u_int32_t *local_pref;
923 char *endptr = NULL;
924
925 /* Local preference value shoud be integer. */
926 if (! all_digit (arg))
927 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000928
929 tmp = strtoul (arg, &endptr, 10);
930 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
931 return NULL;
932
933 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
934
935 if (!local_pref)
936 return local_pref;
937
938 *local_pref = tmp;
939
paul718e3742002-12-13 20:15:29 +0000940 return local_pref;
941}
942
943/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +0000944static void
paul718e3742002-12-13 20:15:29 +0000945route_set_local_pref_free (void *rule)
946{
947 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
948}
949
950/* Set local preference rule structure. */
951struct route_map_rule_cmd route_set_local_pref_cmd =
952{
953 "local-preference",
954 route_set_local_pref,
955 route_set_local_pref_compile,
956 route_set_local_pref_free,
957};
958
959/* `set weight WEIGHT' */
960
961/* Set weight. */
paul94f2b392005-06-28 12:44:16 +0000962static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000963route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
964 void *object)
965{
966 u_int32_t *weight;
967 struct bgp_info *bgp_info;
968
969 if (type == RMAP_BGP)
970 {
971 /* Fetch routemap's rule information. */
972 weight = rule;
973 bgp_info = object;
974
975 /* Set weight value. */
976 bgp_info->attr->weight = *weight;
977 }
978
979 return RMAP_OKAY;
980}
981
982/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000983static void *
paulfd79ac92004-10-13 05:06:08 +0000984route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000985{
paulfd79ac92004-10-13 05:06:08 +0000986 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000987 u_int32_t *weight;
988 char *endptr = NULL;
989
990 /* Local preference value shoud be integer. */
991 if (! all_digit (arg))
992 return NULL;
993
paulfd79ac92004-10-13 05:06:08 +0000994
995 tmp = strtoul (arg, &endptr, 10);
996 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
997 return NULL;
998
paul718e3742002-12-13 20:15:29 +0000999 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001000
1001 if (weight == NULL)
1002 return weight;
1003
1004 *weight = tmp;
1005
paul718e3742002-12-13 20:15:29 +00001006 return weight;
1007}
1008
1009/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001010static void
paul718e3742002-12-13 20:15:29 +00001011route_set_weight_free (void *rule)
1012{
1013 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1014}
1015
1016/* Set local preference rule structure. */
1017struct route_map_rule_cmd route_set_weight_cmd =
1018{
1019 "weight",
1020 route_set_weight,
1021 route_set_weight_compile,
1022 route_set_weight_free,
1023};
1024
1025/* `set metric METRIC' */
1026
1027/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001028static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001029route_set_metric (void *rule, struct prefix *prefix,
1030 route_map_object_t type, void *object)
1031{
1032 char *metric;
1033 u_int32_t metric_val;
1034 struct bgp_info *bgp_info;
1035
1036 if (type == RMAP_BGP)
1037 {
1038 /* Fetch routemap's rule information. */
1039 metric = rule;
1040 bgp_info = object;
1041
1042 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1043 bgp_info->attr->med = 0;
1044 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1045
1046 if (all_digit (metric))
1047 {
1048 metric_val = strtoul (metric, (char **)NULL, 10);
1049 bgp_info->attr->med = metric_val;
1050 }
1051 else
1052 {
1053 metric_val = strtoul (metric+1, (char **)NULL, 10);
1054
1055 if (strncmp (metric, "+", 1) == 0)
1056 {
paul3b424972003-10-13 09:47:32 +00001057 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1058 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001059 else
paul537d8ea2003-08-27 06:45:32 +00001060 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001061 }
1062 else if (strncmp (metric, "-", 1) == 0)
1063 {
paul537d8ea2003-08-27 06:45:32 +00001064 if (bgp_info->attr->med <= metric_val)
1065 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001066 else
paul537d8ea2003-08-27 06:45:32 +00001067 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001068 }
1069 }
1070 }
1071 return RMAP_OKAY;
1072}
1073
1074/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001075static void *
paulfd79ac92004-10-13 05:06:08 +00001076route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001077{
1078 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001079 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001080 char *endptr = NULL;
1081
1082 if (all_digit (arg))
1083 {
1084 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001085 larg = strtoul (arg, &endptr, 10);
1086 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001087 return NULL;
paul94f2b392005-06-28 12:44:16 +00001088 metric = larg;
paul718e3742002-12-13 20:15:29 +00001089 }
1090 else
1091 {
1092 /* set metric +/-value check */
1093 if ((strncmp (arg, "+", 1) != 0
1094 && strncmp (arg, "-", 1) != 0)
1095 || (! all_digit (arg+1)))
1096 return NULL;
1097
paul94f2b392005-06-28 12:44:16 +00001098 larg = strtoul (arg+1, &endptr, 10);
1099 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001100 return NULL;
paul94f2b392005-06-28 12:44:16 +00001101 metric = larg;
paul718e3742002-12-13 20:15:29 +00001102 }
1103
1104 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1105}
1106
1107/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001108static void
paul718e3742002-12-13 20:15:29 +00001109route_set_metric_free (void *rule)
1110{
1111 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1112}
1113
1114/* Set metric rule structure. */
1115struct route_map_rule_cmd route_set_metric_cmd =
1116{
1117 "metric",
1118 route_set_metric,
1119 route_set_metric_compile,
1120 route_set_metric_free,
1121};
1122
1123/* `set as-path prepend ASPATH' */
1124
1125/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001126static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001127route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1128{
1129 struct aspath *aspath;
1130 struct aspath *new;
1131 struct bgp_info *binfo;
1132
1133 if (type == RMAP_BGP)
1134 {
1135 aspath = rule;
1136 binfo = object;
1137
1138 if (binfo->attr->aspath->refcnt)
1139 new = aspath_dup (binfo->attr->aspath);
1140 else
1141 new = binfo->attr->aspath;
1142
1143 aspath_prepend (aspath, new);
1144 binfo->attr->aspath = new;
1145 }
1146
1147 return RMAP_OKAY;
1148}
1149
1150/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001151static void *
paulfd79ac92004-10-13 05:06:08 +00001152route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001153{
1154 struct aspath *aspath;
1155
1156 aspath = aspath_str2aspath (arg);
1157 if (! aspath)
1158 return NULL;
1159 return aspath;
1160}
1161
1162/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001163static void
paul718e3742002-12-13 20:15:29 +00001164route_set_aspath_prepend_free (void *rule)
1165{
1166 struct aspath *aspath = rule;
1167 aspath_free (aspath);
1168}
1169
1170/* Set metric rule structure. */
1171struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1172{
1173 "as-path prepend",
1174 route_set_aspath_prepend,
1175 route_set_aspath_prepend_compile,
1176 route_set_aspath_prepend_free,
1177};
1178
1179/* `set community COMMUNITY' */
1180struct rmap_com_set
1181{
1182 struct community *com;
1183 int additive;
1184 int none;
1185};
1186
1187/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001188static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001189route_set_community (void *rule, struct prefix *prefix,
1190 route_map_object_t type, void *object)
1191{
1192 struct rmap_com_set *rcs;
1193 struct bgp_info *binfo;
1194 struct attr *attr;
1195 struct community *new = NULL;
1196 struct community *old;
1197 struct community *merge;
1198
1199 if (type == RMAP_BGP)
1200 {
1201 rcs = rule;
1202 binfo = object;
1203 attr = binfo->attr;
1204 old = attr->community;
1205
1206 /* "none" case. */
1207 if (rcs->none)
1208 {
1209 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1210 attr->community = NULL;
1211 return RMAP_OKAY;
1212 }
1213
1214 /* "additive" case. */
1215 if (rcs->additive && old)
1216 {
1217 merge = community_merge (community_dup (old), rcs->com);
1218 new = community_uniq_sort (merge);
1219 community_free (merge);
1220 }
1221 else
1222 new = community_dup (rcs->com);
1223
1224 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001225
paul718e3742002-12-13 20:15:29 +00001226 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1227 }
1228
1229 return RMAP_OKAY;
1230}
1231
1232/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001233static void *
paulfd79ac92004-10-13 05:06:08 +00001234route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001235{
1236 struct rmap_com_set *rcs;
1237 struct community *com = NULL;
1238 char *sp;
1239 int additive = 0;
1240 int none = 0;
1241
1242 if (strcmp (arg, "none") == 0)
1243 none = 1;
1244 else
1245 {
1246 sp = strstr (arg, "additive");
1247
1248 if (sp && sp > arg)
1249 {
1250 /* "additive" keyworkd is included. */
1251 additive = 1;
1252 *(sp - 1) = '\0';
1253 }
1254
1255 com = community_str2com (arg);
1256
1257 if (additive)
1258 *(sp - 1) = ' ';
1259
1260 if (! com)
1261 return NULL;
1262 }
1263
1264 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1265 memset (rcs, 0, sizeof (struct rmap_com_set));
1266
1267 rcs->com = com;
1268 rcs->additive = additive;
1269 rcs->none = none;
1270
1271 return rcs;
1272}
1273
1274/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001275static void
paul718e3742002-12-13 20:15:29 +00001276route_set_community_free (void *rule)
1277{
1278 struct rmap_com_set *rcs = rule;
1279
1280 if (rcs->com)
1281 community_free (rcs->com);
1282 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1283}
1284
1285/* Set community rule structure. */
1286struct route_map_rule_cmd route_set_community_cmd =
1287{
1288 "community",
1289 route_set_community,
1290 route_set_community_compile,
1291 route_set_community_free,
1292};
1293
hassofee6e4e2005-02-02 16:29:31 +00001294/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001295
1296/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001297static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001298route_set_community_delete (void *rule, struct prefix *prefix,
1299 route_map_object_t type, void *object)
1300{
1301 struct community_list *list;
1302 struct community *merge;
1303 struct community *new;
1304 struct community *old;
1305 struct bgp_info *binfo;
1306
1307 if (type == RMAP_BGP)
1308 {
1309 if (! rule)
1310 return RMAP_OKAY;
1311
1312 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001313 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001314 old = binfo->attr->community;
1315
1316 if (list && old)
1317 {
1318 merge = community_list_match_delete (community_dup (old), list);
1319 new = community_uniq_sort (merge);
1320 community_free (merge);
1321
1322 if (new->size == 0)
1323 {
1324 binfo->attr->community = NULL;
1325 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1326 community_free (new);
1327 }
1328 else
1329 {
1330 binfo->attr->community = new;
1331 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1332 }
1333 }
1334 }
1335
1336 return RMAP_OKAY;
1337}
1338
1339/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001340static void *
paulfd79ac92004-10-13 05:06:08 +00001341route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001342{
1343 char *p;
1344 char *str;
1345 int len;
1346
1347 p = strchr (arg, ' ');
1348 if (p)
1349 {
1350 len = p - arg;
1351 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1352 memcpy (str, arg, len);
1353 }
1354 else
1355 str = NULL;
1356
1357 return str;
1358}
1359
1360/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001361static void
paul718e3742002-12-13 20:15:29 +00001362route_set_community_delete_free (void *rule)
1363{
1364 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1365}
1366
1367/* Set community rule structure. */
1368struct route_map_rule_cmd route_set_community_delete_cmd =
1369{
1370 "comm-list",
1371 route_set_community_delete,
1372 route_set_community_delete_compile,
1373 route_set_community_delete_free,
1374};
1375
1376/* `set extcommunity rt COMMUNITY' */
1377
1378/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001379static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001380route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1381 route_map_object_t type, void *object)
1382{
1383 struct ecommunity *ecom;
1384 struct ecommunity *new_ecom;
1385 struct ecommunity *old_ecom;
1386 struct bgp_info *bgp_info;
1387
1388 if (type == RMAP_BGP)
1389 {
1390 ecom = rule;
1391 bgp_info = object;
1392
1393 if (! ecom)
1394 return RMAP_OKAY;
1395
1396 /* We assume additive for Extended Community. */
1397 old_ecom = bgp_info->attr->ecommunity;
1398
1399 if (old_ecom)
1400 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1401 else
1402 new_ecom = ecommunity_dup (ecom);
1403
1404 bgp_info->attr->ecommunity = new_ecom;
1405
hasso70601e02005-05-27 03:26:57 +00001406 if (old_ecom)
1407 ecommunity_free (old_ecom);
1408
paul718e3742002-12-13 20:15:29 +00001409 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1410 }
1411 return RMAP_OKAY;
1412}
1413
1414/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001415static void *
paulfd79ac92004-10-13 05:06:08 +00001416route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001417{
1418 struct ecommunity *ecom;
1419
1420 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1421 if (! ecom)
1422 return NULL;
1423 return ecom;
1424}
1425
1426/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001427static void
paul718e3742002-12-13 20:15:29 +00001428route_set_ecommunity_rt_free (void *rule)
1429{
1430 struct ecommunity *ecom = rule;
1431 ecommunity_free (ecom);
1432}
1433
1434/* Set community rule structure. */
1435struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1436{
1437 "extcommunity rt",
1438 route_set_ecommunity_rt,
1439 route_set_ecommunity_rt_compile,
1440 route_set_ecommunity_rt_free,
1441};
1442
1443/* `set extcommunity soo COMMUNITY' */
1444
1445/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001446static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001447route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1448 route_map_object_t type, void *object)
1449{
1450 struct ecommunity *ecom;
1451 struct bgp_info *bgp_info;
1452
1453 if (type == RMAP_BGP)
1454 {
1455 ecom = rule;
1456 bgp_info = object;
1457
1458 if (! ecom)
1459 return RMAP_OKAY;
1460
1461 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1462 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1463 }
1464 return RMAP_OKAY;
1465}
1466
1467/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001468static void *
paulfd79ac92004-10-13 05:06:08 +00001469route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001470{
1471 struct ecommunity *ecom;
1472
1473 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1474 if (! ecom)
1475 return NULL;
1476
1477 return ecom;
1478}
1479
1480/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001481static void
paul718e3742002-12-13 20:15:29 +00001482route_set_ecommunity_soo_free (void *rule)
1483{
1484 struct ecommunity *ecom = rule;
1485 ecommunity_free (ecom);
1486}
1487
1488/* Set community rule structure. */
1489struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1490{
1491 "extcommunity soo",
1492 route_set_ecommunity_soo,
1493 route_set_ecommunity_soo_compile,
1494 route_set_ecommunity_soo_free,
1495};
1496
1497/* `set origin ORIGIN' */
1498
1499/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001500static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001501route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1502{
1503 u_char *origin;
1504 struct bgp_info *bgp_info;
1505
1506 if (type == RMAP_BGP)
1507 {
1508 origin = rule;
1509 bgp_info = object;
1510
1511 bgp_info->attr->origin = *origin;
1512 }
1513
1514 return RMAP_OKAY;
1515}
1516
1517/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001518static void *
paulfd79ac92004-10-13 05:06:08 +00001519route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001520{
1521 u_char *origin;
1522
1523 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1524
1525 if (strcmp (arg, "igp") == 0)
1526 *origin = 0;
1527 else if (strcmp (arg, "egp") == 0)
1528 *origin = 1;
1529 else
1530 *origin = 2;
1531
1532 return origin;
1533}
1534
1535/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001536static void
paul718e3742002-12-13 20:15:29 +00001537route_set_origin_free (void *rule)
1538{
1539 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1540}
1541
1542/* Set metric rule structure. */
1543struct route_map_rule_cmd route_set_origin_cmd =
1544{
1545 "origin",
1546 route_set_origin,
1547 route_set_origin_compile,
1548 route_set_origin_free,
1549};
1550
1551/* `set atomic-aggregate' */
1552
1553/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001554static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001555route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1556 route_map_object_t type, void *object)
1557{
1558 struct bgp_info *bgp_info;
1559
1560 if (type == RMAP_BGP)
1561 {
1562 bgp_info = object;
1563 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1564 }
1565
1566 return RMAP_OKAY;
1567}
1568
1569/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001570static void *
paulfd79ac92004-10-13 05:06:08 +00001571route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001572{
1573 return (void *)1;
1574}
1575
1576/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001577static void
paul718e3742002-12-13 20:15:29 +00001578route_set_atomic_aggregate_free (void *rule)
1579{
1580 return;
1581}
1582
1583/* Set atomic aggregate rule structure. */
1584struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1585{
1586 "atomic-aggregate",
1587 route_set_atomic_aggregate,
1588 route_set_atomic_aggregate_compile,
1589 route_set_atomic_aggregate_free,
1590};
1591
1592/* `set aggregator as AS A.B.C.D' */
1593struct aggregator
1594{
1595 as_t as;
1596 struct in_addr address;
1597};
1598
paul94f2b392005-06-28 12:44:16 +00001599static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001600route_set_aggregator_as (void *rule, struct prefix *prefix,
1601 route_map_object_t type, void *object)
1602{
1603 struct bgp_info *bgp_info;
1604 struct aggregator *aggregator;
1605
1606 if (type == RMAP_BGP)
1607 {
1608 bgp_info = object;
1609 aggregator = rule;
1610
1611 bgp_info->attr->aggregator_as = aggregator->as;
1612 bgp_info->attr->aggregator_addr = aggregator->address;
1613 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1614 }
1615
1616 return RMAP_OKAY;
1617}
1618
paul94f2b392005-06-28 12:44:16 +00001619static void *
paulfd79ac92004-10-13 05:06:08 +00001620route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001621{
1622 struct aggregator *aggregator;
1623 char as[10];
1624 char address[20];
1625
1626 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1627 memset (aggregator, 0, sizeof (struct aggregator));
1628
1629 sscanf (arg, "%s %s", as, address);
1630
1631 aggregator->as = strtoul (as, NULL, 10);
1632 inet_aton (address, &aggregator->address);
1633
1634 return aggregator;
1635}
1636
paul94f2b392005-06-28 12:44:16 +00001637static void
paul718e3742002-12-13 20:15:29 +00001638route_set_aggregator_as_free (void *rule)
1639{
1640 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1641}
1642
1643struct route_map_rule_cmd route_set_aggregator_as_cmd =
1644{
1645 "aggregator as",
1646 route_set_aggregator_as,
1647 route_set_aggregator_as_compile,
1648 route_set_aggregator_as_free,
1649};
1650
1651#ifdef HAVE_IPV6
1652/* `match ipv6 address IP_ACCESS_LIST' */
1653
paul94f2b392005-06-28 12:44:16 +00001654static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001655route_match_ipv6_address (void *rule, struct prefix *prefix,
1656 route_map_object_t type, void *object)
1657{
1658 struct access_list *alist;
1659
1660 if (type == RMAP_BGP)
1661 {
1662 alist = access_list_lookup (AFI_IP6, (char *) rule);
1663 if (alist == NULL)
1664 return RMAP_NOMATCH;
1665
1666 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1667 RMAP_NOMATCH : RMAP_MATCH);
1668 }
1669 return RMAP_NOMATCH;
1670}
1671
paul94f2b392005-06-28 12:44:16 +00001672static void *
paulfd79ac92004-10-13 05:06:08 +00001673route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001674{
1675 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1676}
1677
paul94f2b392005-06-28 12:44:16 +00001678static void
paul718e3742002-12-13 20:15:29 +00001679route_match_ipv6_address_free (void *rule)
1680{
1681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1682}
1683
1684/* Route map commands for ip address matching. */
1685struct route_map_rule_cmd route_match_ipv6_address_cmd =
1686{
1687 "ipv6 address",
1688 route_match_ipv6_address,
1689 route_match_ipv6_address_compile,
1690 route_match_ipv6_address_free
1691};
1692
1693/* `match ipv6 next-hop IP_ADDRESS' */
1694
paul94f2b392005-06-28 12:44:16 +00001695static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001696route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1697 route_map_object_t type, void *object)
1698{
1699 struct in6_addr *addr;
1700 struct bgp_info *bgp_info;
1701
1702 if (type == RMAP_BGP)
1703 {
1704 addr = rule;
1705 bgp_info = object;
1706
1707 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1708 return RMAP_MATCH;
1709
1710 if (bgp_info->attr->mp_nexthop_len == 32 &&
1711 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1712 return RMAP_MATCH;
1713
1714 return RMAP_NOMATCH;
1715 }
1716
1717 return RMAP_NOMATCH;
1718}
1719
paul94f2b392005-06-28 12:44:16 +00001720static void *
paulfd79ac92004-10-13 05:06:08 +00001721route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001722{
1723 struct in6_addr *address;
1724 int ret;
1725
1726 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1727
1728 ret = inet_pton (AF_INET6, arg, address);
1729 if (!ret)
1730 {
1731 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1732 return NULL;
1733 }
1734
1735 return address;
1736}
1737
paul94f2b392005-06-28 12:44:16 +00001738static void
paul718e3742002-12-13 20:15:29 +00001739route_match_ipv6_next_hop_free (void *rule)
1740{
1741 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1742}
1743
1744struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1745{
1746 "ipv6 next-hop",
1747 route_match_ipv6_next_hop,
1748 route_match_ipv6_next_hop_compile,
1749 route_match_ipv6_next_hop_free
1750};
1751
1752/* `match ipv6 address prefix-list PREFIX_LIST' */
1753
paul94f2b392005-06-28 12:44:16 +00001754static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001755route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1756 route_map_object_t type, void *object)
1757{
1758 struct prefix_list *plist;
1759
1760 if (type == RMAP_BGP)
1761 {
1762 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1763 if (plist == NULL)
1764 return RMAP_NOMATCH;
1765
1766 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1767 RMAP_NOMATCH : RMAP_MATCH);
1768 }
1769 return RMAP_NOMATCH;
1770}
1771
paul94f2b392005-06-28 12:44:16 +00001772static void *
paulfd79ac92004-10-13 05:06:08 +00001773route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001774{
1775 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1776}
1777
paul94f2b392005-06-28 12:44:16 +00001778static void
paul718e3742002-12-13 20:15:29 +00001779route_match_ipv6_address_prefix_list_free (void *rule)
1780{
1781 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1782}
1783
1784struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1785{
1786 "ipv6 address prefix-list",
1787 route_match_ipv6_address_prefix_list,
1788 route_match_ipv6_address_prefix_list_compile,
1789 route_match_ipv6_address_prefix_list_free
1790};
1791
1792/* `set ipv6 nexthop global IP_ADDRESS' */
1793
1794/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001795static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001796route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1797 route_map_object_t type, void *object)
1798{
1799 struct in6_addr *address;
1800 struct bgp_info *bgp_info;
1801
1802 if (type == RMAP_BGP)
1803 {
1804 /* Fetch routemap's rule information. */
1805 address = rule;
1806 bgp_info = object;
1807
1808 /* Set next hop value. */
1809 bgp_info->attr->mp_nexthop_global = *address;
1810
1811 /* Set nexthop length. */
1812 if (bgp_info->attr->mp_nexthop_len == 0)
1813 bgp_info->attr->mp_nexthop_len = 16;
1814 }
1815
1816 return RMAP_OKAY;
1817}
1818
1819/* Route map `ip next-hop' compile function. Given string is converted
1820 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001821static void *
paulfd79ac92004-10-13 05:06:08 +00001822route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001823{
1824 int ret;
1825 struct in6_addr *address;
1826
1827 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1828
1829 ret = inet_pton (AF_INET6, arg, address);
1830
1831 if (ret == 0)
1832 {
1833 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1834 return NULL;
1835 }
1836
1837 return address;
1838}
1839
1840/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001841static void
paul718e3742002-12-13 20:15:29 +00001842route_set_ipv6_nexthop_global_free (void *rule)
1843{
1844 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1845}
1846
1847/* Route map commands for ip nexthop set. */
1848struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1849{
1850 "ipv6 next-hop global",
1851 route_set_ipv6_nexthop_global,
1852 route_set_ipv6_nexthop_global_compile,
1853 route_set_ipv6_nexthop_global_free
1854};
1855
1856/* `set ipv6 nexthop local IP_ADDRESS' */
1857
1858/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001859static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001860route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1861 route_map_object_t type, void *object)
1862{
1863 struct in6_addr *address;
1864 struct bgp_info *bgp_info;
1865
1866 if (type == RMAP_BGP)
1867 {
1868 /* Fetch routemap's rule information. */
1869 address = rule;
1870 bgp_info = object;
1871
1872 /* Set next hop value. */
1873 bgp_info->attr->mp_nexthop_local = *address;
1874
1875 /* Set nexthop length. */
1876 if (bgp_info->attr->mp_nexthop_len != 32)
1877 bgp_info->attr->mp_nexthop_len = 32;
1878 }
1879
1880 return RMAP_OKAY;
1881}
1882
1883/* Route map `ip nexthop' compile function. Given string is converted
1884 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001885static void *
paulfd79ac92004-10-13 05:06:08 +00001886route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001887{
1888 int ret;
1889 struct in6_addr *address;
1890
1891 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1892
1893 ret = inet_pton (AF_INET6, arg, address);
1894
1895 if (ret == 0)
1896 {
1897 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1898 return NULL;
1899 }
1900
1901 return address;
1902}
1903
1904/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001905static void
paul718e3742002-12-13 20:15:29 +00001906route_set_ipv6_nexthop_local_free (void *rule)
1907{
1908 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1909}
1910
1911/* Route map commands for ip nexthop set. */
1912struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1913{
1914 "ipv6 next-hop local",
1915 route_set_ipv6_nexthop_local,
1916 route_set_ipv6_nexthop_local_compile,
1917 route_set_ipv6_nexthop_local_free
1918};
1919#endif /* HAVE_IPV6 */
1920
1921/* `set vpnv4 nexthop A.B.C.D' */
1922
paul94f2b392005-06-28 12:44:16 +00001923static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001924route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1925 route_map_object_t type, void *object)
1926{
1927 struct in_addr *address;
1928 struct bgp_info *bgp_info;
1929
1930 if (type == RMAP_BGP)
1931 {
1932 /* Fetch routemap's rule information. */
1933 address = rule;
1934 bgp_info = object;
1935
1936 /* Set next hop value. */
1937 bgp_info->attr->mp_nexthop_global_in = *address;
1938 }
1939
1940 return RMAP_OKAY;
1941}
1942
paul94f2b392005-06-28 12:44:16 +00001943static void *
paulfd79ac92004-10-13 05:06:08 +00001944route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001945{
1946 int ret;
1947 struct in_addr *address;
1948
1949 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1950
1951 ret = inet_aton (arg, address);
1952
1953 if (ret == 0)
1954 {
1955 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1956 return NULL;
1957 }
1958
1959 return address;
1960}
1961
paul94f2b392005-06-28 12:44:16 +00001962static void
paul718e3742002-12-13 20:15:29 +00001963route_set_vpnv4_nexthop_free (void *rule)
1964{
1965 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1966}
1967
1968/* Route map commands for ip nexthop set. */
1969struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1970{
1971 "vpnv4 next-hop",
1972 route_set_vpnv4_nexthop,
1973 route_set_vpnv4_nexthop_compile,
1974 route_set_vpnv4_nexthop_free
1975};
1976
1977/* `set originator-id' */
1978
1979/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001980static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001981route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1982{
1983 struct in_addr *address;
1984 struct bgp_info *bgp_info;
1985
1986 if (type == RMAP_BGP)
1987 {
1988 address = rule;
1989 bgp_info = object;
1990
1991 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1992 bgp_info->attr->originator_id = *address;
1993 }
1994
1995 return RMAP_OKAY;
1996}
1997
1998/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00001999static void *
paulfd79ac92004-10-13 05:06:08 +00002000route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002001{
2002 int ret;
2003 struct in_addr *address;
2004
2005 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2006
2007 ret = inet_aton (arg, address);
2008
2009 if (ret == 0)
2010 {
2011 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2012 return NULL;
2013 }
2014
2015 return address;
2016}
2017
2018/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002019static void
paul718e3742002-12-13 20:15:29 +00002020route_set_originator_id_free (void *rule)
2021{
2022 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2023}
2024
2025/* Set metric rule structure. */
2026struct route_map_rule_cmd route_set_originator_id_cmd =
2027{
2028 "originator-id",
2029 route_set_originator_id,
2030 route_set_originator_id_compile,
2031 route_set_originator_id_free,
2032};
2033
2034/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002035static int
paul718e3742002-12-13 20:15:29 +00002036bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002037 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002038{
2039 int ret;
2040
2041 ret = route_map_add_match (index, command, arg);
2042 if (ret)
2043 {
2044 switch (ret)
2045 {
2046 case RMAP_RULE_MISSING:
2047 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2048 return CMD_WARNING;
2049 break;
2050 case RMAP_COMPILE_ERROR:
2051 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2052 return CMD_WARNING;
2053 break;
2054 }
2055 }
2056 return CMD_SUCCESS;
2057}
2058
2059/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002060static int
paul718e3742002-12-13 20:15:29 +00002061bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002062 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002063{
2064 int ret;
2065
2066 ret = route_map_delete_match (index, command, arg);
2067 if (ret)
2068 {
2069 switch (ret)
2070 {
2071 case RMAP_RULE_MISSING:
2072 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2073 return CMD_WARNING;
2074 break;
2075 case RMAP_COMPILE_ERROR:
2076 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2077 return CMD_WARNING;
2078 break;
2079 }
2080 }
2081 return CMD_SUCCESS;
2082}
2083
2084/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002085static int
paul718e3742002-12-13 20:15:29 +00002086bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002087 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002088{
2089 int ret;
2090
2091 ret = route_map_add_set (index, command, arg);
2092 if (ret)
2093 {
2094 switch (ret)
2095 {
2096 case RMAP_RULE_MISSING:
2097 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2098 return CMD_WARNING;
2099 break;
2100 case RMAP_COMPILE_ERROR:
2101 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2102 return CMD_WARNING;
2103 break;
2104 }
2105 }
2106 return CMD_SUCCESS;
2107}
2108
2109/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002110static int
paul718e3742002-12-13 20:15:29 +00002111bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002112 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002113{
2114 int ret;
2115
2116 ret = route_map_delete_set (index, command, arg);
2117 if (ret)
2118 {
2119 switch (ret)
2120 {
2121 case RMAP_RULE_MISSING:
2122 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2123 return CMD_WARNING;
2124 break;
2125 case RMAP_COMPILE_ERROR:
2126 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2127 return CMD_WARNING;
2128 break;
2129 }
2130 }
2131 return CMD_SUCCESS;
2132}
2133
2134/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002135static void
paulfd79ac92004-10-13 05:06:08 +00002136bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002137{
2138 int i;
2139 afi_t afi;
2140 safi_t safi;
2141 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002142 struct listnode *node, *nnode;
2143 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002144 struct bgp *bgp;
2145 struct peer *peer;
2146 struct peer_group *group;
2147 struct bgp_filter *filter;
2148 struct bgp_node *bn;
2149 struct bgp_static *bgp_static;
2150
2151 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002152 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002153 {
paul1eb8ef22005-04-07 07:30:20 +00002154 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002155 {
2156 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2157 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2158 {
2159 filter = &peer->filter[afi][safi];
2160
paulfee0f4c2004-09-13 05:12:46 +00002161 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002162 {
2163 if (filter->map[direct].name)
2164 filter->map[direct].map =
2165 route_map_lookup_by_name (filter->map[direct].name);
2166 else
2167 filter->map[direct].map = NULL;
2168 }
2169
2170 if (filter->usmap.name)
2171 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2172 else
2173 filter->usmap.map = NULL;
2174 }
2175 }
paul1eb8ef22005-04-07 07:30:20 +00002176 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002177 {
2178 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2179 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2180 {
2181 filter = &group->conf->filter[afi][safi];
2182
paulfee0f4c2004-09-13 05:12:46 +00002183 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002184 {
2185 if (filter->map[direct].name)
2186 filter->map[direct].map =
2187 route_map_lookup_by_name (filter->map[direct].name);
2188 else
2189 filter->map[direct].map = NULL;
2190 }
2191
2192 if (filter->usmap.name)
2193 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2194 else
2195 filter->usmap.map = NULL;
2196 }
2197 }
2198 }
2199
2200 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002201 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002202 {
paul1eb8ef22005-04-07 07:30:20 +00002203 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002204 {
2205 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2206 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2207 {
2208 if (peer->default_rmap[afi][safi].name)
2209 peer->default_rmap[afi][safi].map =
2210 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2211 else
2212 peer->default_rmap[afi][safi].map = NULL;
2213 }
2214 }
2215 }
2216
2217 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002218 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002219 {
2220 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2221 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2222 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2223 bn = bgp_route_next (bn))
2224 if ((bgp_static = bn->info) != NULL)
2225 {
2226 if (bgp_static->rmap.name)
2227 bgp_static->rmap.map =
2228 route_map_lookup_by_name (bgp_static->rmap.name);
2229 else
2230 bgp_static->rmap.map = NULL;
2231 }
2232 }
2233
2234 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002235 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002236 {
2237 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2238 {
2239 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2240 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2241 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2242#ifdef HAVE_IPV6
2243 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2244 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2245 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2246#endif /* HAVE_IPV6 */
2247 }
2248 }
2249}
2250
paulfee0f4c2004-09-13 05:12:46 +00002251DEFUN (match_peer,
2252 match_peer_cmd,
2253 "match peer (A.B.C.D|X:X::X:X)",
2254 MATCH_STR
2255 "Match peer address\n"
2256 "IPv6 address of peer\n"
2257 "IP address of peer\n")
2258{
2259 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2260}
2261
2262DEFUN (match_peer_local,
2263 match_peer_local_cmd,
2264 "match peer local",
2265 MATCH_STR
2266 "Match peer address\n"
2267 "Static or Redistributed routes\n")
2268{
2269 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2270}
2271
2272DEFUN (no_match_peer,
2273 no_match_peer_cmd,
2274 "no match peer",
2275 NO_STR
2276 MATCH_STR
2277 "Match peer address\n")
2278{
2279 if (argc == 0)
2280 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2281
2282 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2283}
2284
2285ALIAS (no_match_peer,
2286 no_match_peer_val_cmd,
2287 "no match peer (A.B.C.D|X:X::X:X)",
2288 NO_STR
2289 MATCH_STR
2290 "Match peer address\n"
2291 "IPv6 address of peer\n"
2292 "IP address of peer\n")
2293
2294ALIAS (no_match_peer,
2295 no_match_peer_local_cmd,
2296 "no match peer local",
2297 NO_STR
2298 MATCH_STR
2299 "Match peer address\n"
2300 "Static or Redistributed routes\n")
2301
paul718e3742002-12-13 20:15:29 +00002302DEFUN (match_ip_address,
2303 match_ip_address_cmd,
2304 "match ip address (<1-199>|<1300-2699>|WORD)",
2305 MATCH_STR
2306 IP_STR
2307 "Match address of route\n"
2308 "IP access-list number\n"
2309 "IP access-list number (expanded range)\n"
2310 "IP Access-list name\n")
2311{
2312 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2313}
2314
2315DEFUN (no_match_ip_address,
2316 no_match_ip_address_cmd,
2317 "no match ip address",
2318 NO_STR
2319 MATCH_STR
2320 IP_STR
2321 "Match address of route\n")
2322{
2323 if (argc == 0)
2324 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2325
2326 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2327}
2328
2329ALIAS (no_match_ip_address,
2330 no_match_ip_address_val_cmd,
2331 "no match ip address (<1-199>|<1300-2699>|WORD)",
2332 NO_STR
2333 MATCH_STR
2334 IP_STR
2335 "Match address of route\n"
2336 "IP access-list number\n"
2337 "IP access-list number (expanded range)\n"
2338 "IP Access-list name\n")
2339
2340DEFUN (match_ip_next_hop,
2341 match_ip_next_hop_cmd,
2342 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2343 MATCH_STR
2344 IP_STR
2345 "Match next-hop address of route\n"
2346 "IP access-list number\n"
2347 "IP access-list number (expanded range)\n"
2348 "IP Access-list name\n")
2349{
2350 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2351}
2352
2353DEFUN (no_match_ip_next_hop,
2354 no_match_ip_next_hop_cmd,
2355 "no match ip next-hop",
2356 NO_STR
2357 MATCH_STR
2358 IP_STR
2359 "Match next-hop address of route\n")
2360{
2361 if (argc == 0)
2362 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2363
2364 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2365}
2366
2367ALIAS (no_match_ip_next_hop,
2368 no_match_ip_next_hop_val_cmd,
2369 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2370 NO_STR
2371 MATCH_STR
2372 IP_STR
2373 "Match next-hop address of route\n"
2374 "IP access-list number\n"
2375 "IP access-list number (expanded range)\n"
2376 "IP Access-list name\n")
2377
hassoc1643bb2005-02-02 16:43:17 +00002378DEFUN (match_ip_route_source,
2379 match_ip_route_source_cmd,
2380 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2381 MATCH_STR
2382 IP_STR
2383 "Match advertising source address of route\n"
2384 "IP access-list number\n"
2385 "IP access-list number (expanded range)\n"
2386 "IP standard access-list name\n")
2387{
2388 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2389}
2390
2391DEFUN (no_match_ip_route_source,
2392 no_match_ip_route_source_cmd,
2393 "no match ip route-source",
2394 NO_STR
2395 MATCH_STR
2396 IP_STR
2397 "Match advertising source address of route\n")
2398{
2399 if (argc == 0)
2400 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2401
2402 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2403}
2404
2405ALIAS (no_match_ip_route_source,
2406 no_match_ip_route_source_val_cmd,
2407 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2408 NO_STR
2409 MATCH_STR
2410 IP_STR
2411 "Match advertising source address of route\n"
2412 "IP access-list number\n"
2413 "IP access-list number (expanded range)\n"
2414 "IP standard access-list name\n");
2415
paul718e3742002-12-13 20:15:29 +00002416DEFUN (match_ip_address_prefix_list,
2417 match_ip_address_prefix_list_cmd,
2418 "match ip address prefix-list WORD",
2419 MATCH_STR
2420 IP_STR
2421 "Match address of route\n"
2422 "Match entries of prefix-lists\n"
2423 "IP prefix-list name\n")
2424{
2425 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2426}
2427
2428DEFUN (no_match_ip_address_prefix_list,
2429 no_match_ip_address_prefix_list_cmd,
2430 "no match ip address prefix-list",
2431 NO_STR
2432 MATCH_STR
2433 IP_STR
2434 "Match address of route\n"
2435 "Match entries of prefix-lists\n")
2436{
2437 if (argc == 0)
2438 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2439
2440 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2441}
2442
2443ALIAS (no_match_ip_address_prefix_list,
2444 no_match_ip_address_prefix_list_val_cmd,
2445 "no match ip address prefix-list WORD",
2446 NO_STR
2447 MATCH_STR
2448 IP_STR
2449 "Match address of route\n"
2450 "Match entries of prefix-lists\n"
2451 "IP prefix-list name\n")
2452
2453DEFUN (match_ip_next_hop_prefix_list,
2454 match_ip_next_hop_prefix_list_cmd,
2455 "match ip next-hop prefix-list WORD",
2456 MATCH_STR
2457 IP_STR
2458 "Match next-hop address of route\n"
2459 "Match entries of prefix-lists\n"
2460 "IP prefix-list name\n")
2461{
2462 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2463}
2464
2465DEFUN (no_match_ip_next_hop_prefix_list,
2466 no_match_ip_next_hop_prefix_list_cmd,
2467 "no match ip next-hop prefix-list",
2468 NO_STR
2469 MATCH_STR
2470 IP_STR
2471 "Match next-hop address of route\n"
2472 "Match entries of prefix-lists\n")
2473{
2474 if (argc == 0)
2475 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2476
2477 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2478}
2479
2480ALIAS (no_match_ip_next_hop_prefix_list,
2481 no_match_ip_next_hop_prefix_list_val_cmd,
2482 "no match ip next-hop prefix-list WORD",
2483 NO_STR
2484 MATCH_STR
2485 IP_STR
2486 "Match next-hop address of route\n"
2487 "Match entries of prefix-lists\n"
2488 "IP prefix-list name\n")
2489
hassoc1643bb2005-02-02 16:43:17 +00002490DEFUN (match_ip_route_source_prefix_list,
2491 match_ip_route_source_prefix_list_cmd,
2492 "match ip route-source prefix-list WORD",
2493 MATCH_STR
2494 IP_STR
2495 "Match advertising source address of route\n"
2496 "Match entries of prefix-lists\n"
2497 "IP prefix-list name\n")
2498{
2499 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2500}
2501
2502DEFUN (no_match_ip_route_source_prefix_list,
2503 no_match_ip_route_source_prefix_list_cmd,
2504 "no match ip route-source prefix-list",
2505 NO_STR
2506 MATCH_STR
2507 IP_STR
2508 "Match advertising source address of route\n"
2509 "Match entries of prefix-lists\n")
2510{
2511 if (argc == 0)
2512 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2513
2514 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2515}
2516
2517ALIAS (no_match_ip_route_source_prefix_list,
2518 no_match_ip_route_source_prefix_list_val_cmd,
2519 "no match ip route-source prefix-list WORD",
2520 NO_STR
2521 MATCH_STR
2522 IP_STR
2523 "Match advertising source address of route\n"
2524 "Match entries of prefix-lists\n"
2525 "IP prefix-list name\n");
2526
paul718e3742002-12-13 20:15:29 +00002527DEFUN (match_metric,
2528 match_metric_cmd,
2529 "match metric <0-4294967295>",
2530 MATCH_STR
2531 "Match metric of route\n"
2532 "Metric value\n")
2533{
2534 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2535}
2536
2537DEFUN (no_match_metric,
2538 no_match_metric_cmd,
2539 "no match metric",
2540 NO_STR
2541 MATCH_STR
2542 "Match metric of route\n")
2543{
2544 if (argc == 0)
2545 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2546
2547 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2548}
2549
2550ALIAS (no_match_metric,
2551 no_match_metric_val_cmd,
2552 "no match metric <0-4294967295>",
2553 NO_STR
2554 MATCH_STR
2555 "Match metric of route\n"
2556 "Metric value\n")
2557
2558DEFUN (match_community,
2559 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002560 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002561 MATCH_STR
2562 "Match BGP community list\n"
2563 "Community-list number (standard)\n"
2564 "Community-list number (expanded)\n"
2565 "Community-list name\n")
2566{
2567 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2568}
2569
2570DEFUN (match_community_exact,
2571 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002572 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002573 MATCH_STR
2574 "Match BGP community list\n"
2575 "Community-list number (standard)\n"
2576 "Community-list number (expanded)\n"
2577 "Community-list name\n"
2578 "Do exact matching of communities\n")
2579{
2580 int ret;
2581 char *argstr;
2582
2583 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2584 strlen (argv[0]) + strlen ("exact-match") + 2);
2585
2586 sprintf (argstr, "%s exact-match", argv[0]);
2587
2588 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2589
2590 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2591
2592 return ret;
2593}
2594
2595DEFUN (no_match_community,
2596 no_match_community_cmd,
2597 "no match community",
2598 NO_STR
2599 MATCH_STR
2600 "Match BGP community list\n")
2601{
2602 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2603}
2604
2605ALIAS (no_match_community,
2606 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002607 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002608 NO_STR
2609 MATCH_STR
2610 "Match BGP community list\n"
2611 "Community-list number (standard)\n"
2612 "Community-list number (expanded)\n"
2613 "Community-list name\n")
2614
2615ALIAS (no_match_community,
2616 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002617 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002618 NO_STR
2619 MATCH_STR
2620 "Match BGP community list\n"
2621 "Community-list number (standard)\n"
2622 "Community-list number (expanded)\n"
2623 "Community-list name\n"
2624 "Do exact matching of communities\n")
2625
paul73ffb252003-04-19 15:49:49 +00002626DEFUN (match_ecommunity,
2627 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002628 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002629 MATCH_STR
2630 "Match BGP/VPN extended community list\n"
2631 "Extended community-list number (standard)\n"
2632 "Extended community-list number (expanded)\n"
2633 "Extended community-list name\n")
2634{
2635 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2636}
2637
2638DEFUN (no_match_ecommunity,
2639 no_match_ecommunity_cmd,
2640 "no match extcommunity",
2641 NO_STR
2642 MATCH_STR
2643 "Match BGP/VPN extended community list\n")
2644{
2645 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2646}
2647
2648ALIAS (no_match_ecommunity,
2649 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002650 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002651 NO_STR
2652 MATCH_STR
2653 "Match BGP/VPN extended community list\n"
2654 "Extended community-list number (standard)\n"
2655 "Extended community-list number (expanded)\n"
2656 "Extended community-list name\n")
2657
paul718e3742002-12-13 20:15:29 +00002658DEFUN (match_aspath,
2659 match_aspath_cmd,
2660 "match as-path WORD",
2661 MATCH_STR
2662 "Match BGP AS path list\n"
2663 "AS path access-list name\n")
2664{
2665 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2666}
2667
2668DEFUN (no_match_aspath,
2669 no_match_aspath_cmd,
2670 "no match as-path",
2671 NO_STR
2672 MATCH_STR
2673 "Match BGP AS path list\n")
2674{
2675 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2676}
2677
2678ALIAS (no_match_aspath,
2679 no_match_aspath_val_cmd,
2680 "no match as-path WORD",
2681 NO_STR
2682 MATCH_STR
2683 "Match BGP AS path list\n"
2684 "AS path access-list name\n")
2685
2686DEFUN (match_origin,
2687 match_origin_cmd,
2688 "match origin (egp|igp|incomplete)",
2689 MATCH_STR
2690 "BGP origin code\n"
2691 "remote EGP\n"
2692 "local IGP\n"
2693 "unknown heritage\n")
2694{
2695 if (strncmp (argv[0], "igp", 2) == 0)
2696 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2697 if (strncmp (argv[0], "egp", 1) == 0)
2698 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2699 if (strncmp (argv[0], "incomplete", 2) == 0)
2700 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2701
2702 return CMD_WARNING;
2703}
2704
2705DEFUN (no_match_origin,
2706 no_match_origin_cmd,
2707 "no match origin",
2708 NO_STR
2709 MATCH_STR
2710 "BGP origin code\n")
2711{
2712 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2713}
2714
2715ALIAS (no_match_origin,
2716 no_match_origin_val_cmd,
2717 "no match origin (egp|igp|incomplete)",
2718 NO_STR
2719 MATCH_STR
2720 "BGP origin code\n"
2721 "remote EGP\n"
2722 "local IGP\n"
2723 "unknown heritage\n")
2724
2725DEFUN (set_ip_nexthop,
2726 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002727 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002728 SET_STR
2729 IP_STR
2730 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002731 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002732{
2733 union sockunion su;
2734 int ret;
2735
2736 ret = str2sockunion (argv[0], &su);
2737 if (ret < 0)
2738 {
2739 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2740 return CMD_WARNING;
2741 }
2742
2743 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2744}
2745
paulaf5cd0a2003-11-02 07:24:40 +00002746DEFUN (set_ip_nexthop_peer,
2747 set_ip_nexthop_peer_cmd,
2748 "set ip next-hop peer-address",
2749 SET_STR
2750 IP_STR
2751 "Next hop address\n"
2752 "Use peer address (for BGP only)\n")
2753{
2754 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2755}
2756
paul94f2b392005-06-28 12:44:16 +00002757DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002758 no_set_ip_nexthop_peer_cmd,
2759 "no set ip next-hop peer-address",
2760 NO_STR
2761 SET_STR
2762 IP_STR
2763 "Next hop address\n"
2764 "Use peer address (for BGP only)\n")
2765{
2766 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2767}
2768
2769
paul718e3742002-12-13 20:15:29 +00002770DEFUN (no_set_ip_nexthop,
2771 no_set_ip_nexthop_cmd,
2772 "no set ip next-hop",
2773 NO_STR
2774 SET_STR
paul718e3742002-12-13 20:15:29 +00002775 "Next hop address\n")
2776{
paulaf5cd0a2003-11-02 07:24:40 +00002777 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002778 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2779
2780 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2781}
2782
2783ALIAS (no_set_ip_nexthop,
2784 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002785 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002786 NO_STR
2787 SET_STR
2788 IP_STR
2789 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002790 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002791
2792DEFUN (set_metric,
2793 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002794 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002795 SET_STR
2796 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002797 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002798{
2799 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2800}
2801
paul73ffb252003-04-19 15:49:49 +00002802ALIAS (set_metric,
2803 set_metric_addsub_cmd,
2804 "set metric <+/-metric>",
2805 SET_STR
2806 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002807 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002808
paul718e3742002-12-13 20:15:29 +00002809DEFUN (no_set_metric,
2810 no_set_metric_cmd,
2811 "no set metric",
2812 NO_STR
2813 SET_STR
2814 "Metric value for destination routing protocol\n")
2815{
2816 if (argc == 0)
2817 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2818
2819 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2820}
2821
2822ALIAS (no_set_metric,
2823 no_set_metric_val_cmd,
2824 "no set metric <0-4294967295>",
2825 NO_STR
2826 SET_STR
2827 "Metric value for destination routing protocol\n"
2828 "Metric value\n")
2829
2830DEFUN (set_local_pref,
2831 set_local_pref_cmd,
2832 "set local-preference <0-4294967295>",
2833 SET_STR
2834 "BGP local preference path attribute\n"
2835 "Preference value\n")
2836{
2837 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2838}
2839
2840DEFUN (no_set_local_pref,
2841 no_set_local_pref_cmd,
2842 "no set local-preference",
2843 NO_STR
2844 SET_STR
2845 "BGP local preference path attribute\n")
2846{
2847 if (argc == 0)
2848 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2849
2850 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2851}
2852
2853ALIAS (no_set_local_pref,
2854 no_set_local_pref_val_cmd,
2855 "no set local-preference <0-4294967295>",
2856 NO_STR
2857 SET_STR
2858 "BGP local preference path attribute\n"
2859 "Preference value\n")
2860
2861DEFUN (set_weight,
2862 set_weight_cmd,
2863 "set weight <0-4294967295>",
2864 SET_STR
2865 "BGP weight for routing table\n"
2866 "Weight value\n")
2867{
2868 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2869}
2870
2871DEFUN (no_set_weight,
2872 no_set_weight_cmd,
2873 "no set weight",
2874 NO_STR
2875 SET_STR
2876 "BGP weight for routing table\n")
2877{
2878 if (argc == 0)
2879 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2880
2881 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2882}
2883
2884ALIAS (no_set_weight,
2885 no_set_weight_val_cmd,
2886 "no set weight <0-4294967295>",
2887 NO_STR
2888 SET_STR
2889 "BGP weight for routing table\n"
2890 "Weight value\n")
2891
2892DEFUN (set_aspath_prepend,
2893 set_aspath_prepend_cmd,
2894 "set as-path prepend .<1-65535>",
2895 SET_STR
2896 "Prepend string for a BGP AS-path attribute\n"
2897 "Prepend to the as-path\n"
2898 "AS number\n")
2899{
2900 int ret;
2901 char *str;
2902
2903 str = argv_concat (argv, argc, 0);
2904 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2905 XFREE (MTYPE_TMP, str);
2906
2907 return ret;
2908}
2909
2910DEFUN (no_set_aspath_prepend,
2911 no_set_aspath_prepend_cmd,
2912 "no set as-path prepend",
2913 NO_STR
2914 SET_STR
2915 "Prepend string for a BGP AS-path attribute\n"
2916 "Prepend to the as-path\n")
2917{
2918 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2919}
2920
2921ALIAS (no_set_aspath_prepend,
2922 no_set_aspath_prepend_val_cmd,
2923 "no set as-path prepend .<1-65535>",
2924 NO_STR
2925 SET_STR
2926 "Prepend string for a BGP AS-path attribute\n"
2927 "Prepend to the as-path\n"
2928 "AS number\n")
2929
2930DEFUN (set_community,
2931 set_community_cmd,
2932 "set community .AA:NN",
2933 SET_STR
2934 "BGP community attribute\n"
2935 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2936{
2937 int i;
2938 int first = 0;
2939 int additive = 0;
2940 struct buffer *b;
2941 struct community *com = NULL;
2942 char *str;
2943 char *argstr;
2944 int ret;
2945
2946 b = buffer_new (1024);
2947
2948 for (i = 0; i < argc; i++)
2949 {
2950 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2951 {
2952 additive = 1;
2953 continue;
2954 }
2955
2956 if (first)
2957 buffer_putc (b, ' ');
2958 else
2959 first = 1;
2960
2961 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2962 {
2963 buffer_putstr (b, "internet");
2964 continue;
2965 }
2966 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2967 {
2968 buffer_putstr (b, "local-AS");
2969 continue;
2970 }
2971 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2972 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2973 {
2974 buffer_putstr (b, "no-advertise");
2975 continue;
2976 }
2977 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2978 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2979 {
2980 buffer_putstr (b, "no-export");
2981 continue;
2982 }
2983 buffer_putstr (b, argv[i]);
2984 }
2985 buffer_putc (b, '\0');
2986
2987 /* Fetch result string then compile it to communities attribute. */
2988 str = buffer_getstr (b);
2989 buffer_free (b);
2990
2991 if (str)
2992 {
2993 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00002994 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00002995 }
2996
2997 /* Can't compile user input into communities attribute. */
2998 if (! com)
2999 {
3000 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3001 return CMD_WARNING;
3002 }
3003
3004 /* Set communites attribute string. */
3005 str = community_str (com);
3006
3007 if (additive)
3008 {
3009 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3010 strcpy (argstr, str);
3011 strcpy (argstr + strlen (str), " additive");
3012 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3013 XFREE (MTYPE_TMP, argstr);
3014 }
3015 else
3016 ret = bgp_route_set_add (vty, vty->index, "community", str);
3017
3018 community_free (com);
3019
3020 return ret;
3021}
3022
3023DEFUN (set_community_none,
3024 set_community_none_cmd,
3025 "set community none",
3026 SET_STR
3027 "BGP community attribute\n"
3028 "No community attribute\n")
3029{
3030 return bgp_route_set_add (vty, vty->index, "community", "none");
3031}
3032
3033DEFUN (no_set_community,
3034 no_set_community_cmd,
3035 "no set community",
3036 NO_STR
3037 SET_STR
3038 "BGP community attribute\n")
3039{
3040 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3041}
3042
3043ALIAS (no_set_community,
3044 no_set_community_val_cmd,
3045 "no set community .AA:NN",
3046 NO_STR
3047 SET_STR
3048 "BGP community attribute\n"
3049 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3050
3051ALIAS (no_set_community,
3052 no_set_community_none_cmd,
3053 "no set community none",
3054 NO_STR
3055 SET_STR
3056 "BGP community attribute\n"
3057 "No community attribute\n")
3058
3059DEFUN (set_community_delete,
3060 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003061 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003062 SET_STR
3063 "set BGP community list (for deletion)\n"
3064 "Community-list number (standard)\n"
3065 "Communitly-list number (expanded)\n"
3066 "Community-list name\n"
3067 "Delete matching communities\n")
3068{
3069 char *str;
3070
3071 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3072 strcpy (str, argv[0]);
3073 strcpy (str + strlen (argv[0]), " delete");
3074
3075 bgp_route_set_add (vty, vty->index, "comm-list", str);
3076
3077 XFREE (MTYPE_TMP, str);
3078 return CMD_SUCCESS;
3079}
3080
3081DEFUN (no_set_community_delete,
3082 no_set_community_delete_cmd,
3083 "no set comm-list",
3084 NO_STR
3085 SET_STR
3086 "set BGP community list (for deletion)\n")
3087{
3088 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3089}
3090
3091ALIAS (no_set_community_delete,
3092 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003093 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003094 NO_STR
3095 SET_STR
3096 "set BGP community list (for deletion)\n"
3097 "Community-list number (standard)\n"
3098 "Communitly-list number (expanded)\n"
3099 "Community-list name\n"
3100 "Delete matching communities\n")
3101
3102DEFUN (set_ecommunity_rt,
3103 set_ecommunity_rt_cmd,
3104 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3105 SET_STR
3106 "BGP extended community attribute\n"
3107 "Route Target extened communityt\n"
3108 "VPN extended community\n")
3109{
3110 int ret;
3111 char *str;
3112
3113 str = argv_concat (argv, argc, 0);
3114 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3115 XFREE (MTYPE_TMP, str);
3116
3117 return ret;
3118}
3119
3120DEFUN (no_set_ecommunity_rt,
3121 no_set_ecommunity_rt_cmd,
3122 "no set extcommunity rt",
3123 NO_STR
3124 SET_STR
3125 "BGP extended community attribute\n"
3126 "Route Target extened communityt\n")
3127{
3128 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3129}
3130
3131ALIAS (no_set_ecommunity_rt,
3132 no_set_ecommunity_rt_val_cmd,
3133 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3134 NO_STR
3135 SET_STR
3136 "BGP extended community attribute\n"
3137 "Route Target extened communityt\n"
3138 "VPN extended community\n")
3139
3140DEFUN (set_ecommunity_soo,
3141 set_ecommunity_soo_cmd,
3142 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3143 SET_STR
3144 "BGP extended community attribute\n"
3145 "Site-of-Origin extended community\n"
3146 "VPN extended community\n")
3147{
3148 int ret;
3149 char *str;
3150
3151 str = argv_concat (argv, argc, 0);
3152 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3153 XFREE (MTYPE_TMP, str);
3154 return ret;
3155}
3156
3157DEFUN (no_set_ecommunity_soo,
3158 no_set_ecommunity_soo_cmd,
3159 "no set extcommunity soo",
3160 NO_STR
3161 SET_STR
3162 "BGP extended community attribute\n"
3163 "Site-of-Origin extended community\n")
3164{
3165 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3166}
3167
3168ALIAS (no_set_ecommunity_soo,
3169 no_set_ecommunity_soo_val_cmd,
3170 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3171 NO_STR
3172 SET_STR
3173 "BGP extended community attribute\n"
3174 "Site-of-Origin extended community\n"
3175 "VPN extended community\n")
3176
3177DEFUN (set_origin,
3178 set_origin_cmd,
3179 "set origin (egp|igp|incomplete)",
3180 SET_STR
3181 "BGP origin code\n"
3182 "remote EGP\n"
3183 "local IGP\n"
3184 "unknown heritage\n")
3185{
3186 if (strncmp (argv[0], "igp", 2) == 0)
3187 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3188 if (strncmp (argv[0], "egp", 1) == 0)
3189 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3190 if (strncmp (argv[0], "incomplete", 2) == 0)
3191 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3192
3193 return CMD_WARNING;
3194}
3195
3196DEFUN (no_set_origin,
3197 no_set_origin_cmd,
3198 "no set origin",
3199 NO_STR
3200 SET_STR
3201 "BGP origin code\n")
3202{
3203 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3204}
3205
3206ALIAS (no_set_origin,
3207 no_set_origin_val_cmd,
3208 "no set origin (egp|igp|incomplete)",
3209 NO_STR
3210 SET_STR
3211 "BGP origin code\n"
3212 "remote EGP\n"
3213 "local IGP\n"
3214 "unknown heritage\n")
3215
3216DEFUN (set_atomic_aggregate,
3217 set_atomic_aggregate_cmd,
3218 "set atomic-aggregate",
3219 SET_STR
3220 "BGP atomic aggregate attribute\n" )
3221{
3222 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3223}
3224
3225DEFUN (no_set_atomic_aggregate,
3226 no_set_atomic_aggregate_cmd,
3227 "no set atomic-aggregate",
3228 NO_STR
3229 SET_STR
3230 "BGP atomic aggregate attribute\n" )
3231{
3232 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3233}
3234
3235DEFUN (set_aggregator_as,
3236 set_aggregator_as_cmd,
3237 "set aggregator as <1-65535> A.B.C.D",
3238 SET_STR
3239 "BGP aggregator attribute\n"
3240 "AS number of aggregator\n"
3241 "AS number\n"
3242 "IP address of aggregator\n")
3243{
3244 int ret;
3245 as_t as;
3246 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003247 char *argstr;
3248
paula94feb32005-05-23 13:17:29 +00003249 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paulfd79ac92004-10-13 05:06:08 +00003250
paul718e3742002-12-13 20:15:29 +00003251 ret = inet_aton (argv[1], &address);
3252 if (ret == 0)
3253 {
3254 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3255 return CMD_WARNING;
3256 }
3257
3258 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3259 strlen (argv[0]) + strlen (argv[1]) + 2);
3260
3261 sprintf (argstr, "%s %s", argv[0], argv[1]);
3262
3263 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3264
3265 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3266
3267 return ret;
3268}
3269
3270DEFUN (no_set_aggregator_as,
3271 no_set_aggregator_as_cmd,
3272 "no set aggregator as",
3273 NO_STR
3274 SET_STR
3275 "BGP aggregator attribute\n"
3276 "AS number of aggregator\n")
3277{
3278 int ret;
3279 as_t as;
3280 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003281 char *argstr;
3282
3283 if (argv == 0)
3284 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3285
paula94feb32005-05-23 13:17:29 +00003286 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paul718e3742002-12-13 20:15:29 +00003287
3288 ret = inet_aton (argv[1], &address);
3289 if (ret == 0)
3290 {
3291 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3292 return CMD_WARNING;
3293 }
3294
3295 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3296 strlen (argv[0]) + strlen (argv[1]) + 2);
3297
3298 sprintf (argstr, "%s %s", argv[0], argv[1]);
3299
3300 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3301
3302 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3303
3304 return ret;
3305}
3306
3307ALIAS (no_set_aggregator_as,
3308 no_set_aggregator_as_val_cmd,
3309 "no set aggregator as <1-65535> A.B.C.D",
3310 NO_STR
3311 SET_STR
3312 "BGP aggregator attribute\n"
3313 "AS number of aggregator\n"
3314 "AS number\n"
3315 "IP address of aggregator\n")
3316
3317
3318#ifdef HAVE_IPV6
3319DEFUN (match_ipv6_address,
3320 match_ipv6_address_cmd,
3321 "match ipv6 address WORD",
3322 MATCH_STR
3323 IPV6_STR
3324 "Match IPv6 address of route\n"
3325 "IPv6 access-list name\n")
3326{
3327 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3328}
3329
3330DEFUN (no_match_ipv6_address,
3331 no_match_ipv6_address_cmd,
3332 "no match ipv6 address WORD",
3333 NO_STR
3334 MATCH_STR
3335 IPV6_STR
3336 "Match IPv6 address of route\n"
3337 "IPv6 access-list name\n")
3338{
3339 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3340}
3341
3342DEFUN (match_ipv6_next_hop,
3343 match_ipv6_next_hop_cmd,
3344 "match ipv6 next-hop X:X::X:X",
3345 MATCH_STR
3346 IPV6_STR
3347 "Match IPv6 next-hop address of route\n"
3348 "IPv6 address of next hop\n")
3349{
3350 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3351}
3352
3353DEFUN (no_match_ipv6_next_hop,
3354 no_match_ipv6_next_hop_cmd,
3355 "no match ipv6 next-hop X:X::X:X",
3356 NO_STR
3357 MATCH_STR
3358 IPV6_STR
3359 "Match IPv6 next-hop address of route\n"
3360 "IPv6 address of next hop\n")
3361{
3362 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3363}
3364
3365DEFUN (match_ipv6_address_prefix_list,
3366 match_ipv6_address_prefix_list_cmd,
3367 "match ipv6 address prefix-list WORD",
3368 MATCH_STR
3369 IPV6_STR
3370 "Match address of route\n"
3371 "Match entries of prefix-lists\n"
3372 "IP prefix-list name\n")
3373{
3374 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3375}
3376
3377DEFUN (no_match_ipv6_address_prefix_list,
3378 no_match_ipv6_address_prefix_list_cmd,
3379 "no match ipv6 address prefix-list WORD",
3380 NO_STR
3381 MATCH_STR
3382 IPV6_STR
3383 "Match address of route\n"
3384 "Match entries of prefix-lists\n"
3385 "IP prefix-list name\n")
3386{
3387 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3388}
3389
3390DEFUN (set_ipv6_nexthop_global,
3391 set_ipv6_nexthop_global_cmd,
3392 "set ipv6 next-hop global X:X::X:X",
3393 SET_STR
3394 IPV6_STR
3395 "IPv6 next-hop address\n"
3396 "IPv6 global address\n"
3397 "IPv6 address of next hop\n")
3398{
3399 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3400}
3401
3402DEFUN (no_set_ipv6_nexthop_global,
3403 no_set_ipv6_nexthop_global_cmd,
3404 "no set ipv6 next-hop global",
3405 NO_STR
3406 SET_STR
3407 IPV6_STR
3408 "IPv6 next-hop address\n"
3409 "IPv6 global address\n")
3410{
3411 if (argc == 0)
3412 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3413
3414 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3415}
3416
3417ALIAS (no_set_ipv6_nexthop_global,
3418 no_set_ipv6_nexthop_global_val_cmd,
3419 "no set ipv6 next-hop global X:X::X:X",
3420 NO_STR
3421 SET_STR
3422 IPV6_STR
3423 "IPv6 next-hop address\n"
3424 "IPv6 global address\n"
3425 "IPv6 address of next hop\n")
3426
3427DEFUN (set_ipv6_nexthop_local,
3428 set_ipv6_nexthop_local_cmd,
3429 "set ipv6 next-hop local X:X::X:X",
3430 SET_STR
3431 IPV6_STR
3432 "IPv6 next-hop address\n"
3433 "IPv6 local address\n"
3434 "IPv6 address of next hop\n")
3435{
3436 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3437}
3438
3439DEFUN (no_set_ipv6_nexthop_local,
3440 no_set_ipv6_nexthop_local_cmd,
3441 "no set ipv6 next-hop local",
3442 NO_STR
3443 SET_STR
3444 IPV6_STR
3445 "IPv6 next-hop address\n"
3446 "IPv6 local address\n")
3447{
3448 if (argc == 0)
3449 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3450
3451 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3452}
3453
3454ALIAS (no_set_ipv6_nexthop_local,
3455 no_set_ipv6_nexthop_local_val_cmd,
3456 "no set ipv6 next-hop local X:X::X:X",
3457 NO_STR
3458 SET_STR
3459 IPV6_STR
3460 "IPv6 next-hop address\n"
3461 "IPv6 local address\n"
3462 "IPv6 address of next hop\n")
3463#endif /* HAVE_IPV6 */
3464
3465DEFUN (set_vpnv4_nexthop,
3466 set_vpnv4_nexthop_cmd,
3467 "set vpnv4 next-hop A.B.C.D",
3468 SET_STR
3469 "VPNv4 information\n"
3470 "VPNv4 next-hop address\n"
3471 "IP address of next hop\n")
3472{
3473 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3474}
3475
3476DEFUN (no_set_vpnv4_nexthop,
3477 no_set_vpnv4_nexthop_cmd,
3478 "no set vpnv4 next-hop",
3479 NO_STR
3480 SET_STR
3481 "VPNv4 information\n"
3482 "VPNv4 next-hop address\n")
3483{
3484 if (argc == 0)
3485 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3486
3487 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3488}
3489
3490ALIAS (no_set_vpnv4_nexthop,
3491 no_set_vpnv4_nexthop_val_cmd,
3492 "no set vpnv4 next-hop A.B.C.D",
3493 NO_STR
3494 SET_STR
3495 "VPNv4 information\n"
3496 "VPNv4 next-hop address\n"
3497 "IP address of next hop\n")
3498
3499DEFUN (set_originator_id,
3500 set_originator_id_cmd,
3501 "set originator-id A.B.C.D",
3502 SET_STR
3503 "BGP originator ID attribute\n"
3504 "IP address of originator\n")
3505{
3506 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3507}
3508
3509DEFUN (no_set_originator_id,
3510 no_set_originator_id_cmd,
3511 "no set originator-id",
3512 NO_STR
3513 SET_STR
3514 "BGP originator ID attribute\n")
3515{
3516 if (argc == 0)
3517 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3518
3519 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3520}
3521
3522ALIAS (no_set_originator_id,
3523 no_set_originator_id_val_cmd,
3524 "no set originator-id A.B.C.D",
3525 NO_STR
3526 SET_STR
3527 "BGP originator ID attribute\n"
3528 "IP address of originator\n")
3529
3530
3531/* Initialization of route map. */
3532void
paul94f2b392005-06-28 12:44:16 +00003533bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003534{
3535 route_map_init ();
3536 route_map_init_vty ();
3537 route_map_add_hook (bgp_route_map_update);
3538 route_map_delete_hook (bgp_route_map_update);
3539
paulfee0f4c2004-09-13 05:12:46 +00003540 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003541 route_map_install_match (&route_match_ip_address_cmd);
3542 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003543 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003544 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3545 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003546 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003547 route_map_install_match (&route_match_aspath_cmd);
3548 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003549 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003550 route_map_install_match (&route_match_metric_cmd);
3551 route_map_install_match (&route_match_origin_cmd);
3552
3553 route_map_install_set (&route_set_ip_nexthop_cmd);
3554 route_map_install_set (&route_set_local_pref_cmd);
3555 route_map_install_set (&route_set_weight_cmd);
3556 route_map_install_set (&route_set_metric_cmd);
3557 route_map_install_set (&route_set_aspath_prepend_cmd);
3558 route_map_install_set (&route_set_origin_cmd);
3559 route_map_install_set (&route_set_atomic_aggregate_cmd);
3560 route_map_install_set (&route_set_aggregator_as_cmd);
3561 route_map_install_set (&route_set_community_cmd);
3562 route_map_install_set (&route_set_community_delete_cmd);
3563 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3564 route_map_install_set (&route_set_originator_id_cmd);
3565 route_map_install_set (&route_set_ecommunity_rt_cmd);
3566 route_map_install_set (&route_set_ecommunity_soo_cmd);
3567
paulfee0f4c2004-09-13 05:12:46 +00003568 install_element (RMAP_NODE, &match_peer_cmd);
3569 install_element (RMAP_NODE, &match_peer_local_cmd);
3570 install_element (RMAP_NODE, &no_match_peer_cmd);
3571 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3572 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003573 install_element (RMAP_NODE, &match_ip_address_cmd);
3574 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3575 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3576 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3577 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3578 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003579 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3580 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3581 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003582
3583 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3584 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3585 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3586 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3587 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3588 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003589 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3590 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3591 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003592
3593 install_element (RMAP_NODE, &match_aspath_cmd);
3594 install_element (RMAP_NODE, &no_match_aspath_cmd);
3595 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3596 install_element (RMAP_NODE, &match_metric_cmd);
3597 install_element (RMAP_NODE, &no_match_metric_cmd);
3598 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3599 install_element (RMAP_NODE, &match_community_cmd);
3600 install_element (RMAP_NODE, &match_community_exact_cmd);
3601 install_element (RMAP_NODE, &no_match_community_cmd);
3602 install_element (RMAP_NODE, &no_match_community_val_cmd);
3603 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003604 install_element (RMAP_NODE, &match_ecommunity_cmd);
3605 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3606 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003607 install_element (RMAP_NODE, &match_origin_cmd);
3608 install_element (RMAP_NODE, &no_match_origin_cmd);
3609 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3610
3611 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003612 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003613 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3614 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3615 install_element (RMAP_NODE, &set_local_pref_cmd);
3616 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3617 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3618 install_element (RMAP_NODE, &set_weight_cmd);
3619 install_element (RMAP_NODE, &no_set_weight_cmd);
3620 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3621 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003622 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003623 install_element (RMAP_NODE, &no_set_metric_cmd);
3624 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3625 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3626 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3627 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3628 install_element (RMAP_NODE, &set_origin_cmd);
3629 install_element (RMAP_NODE, &no_set_origin_cmd);
3630 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3631 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3632 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3633 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3634 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3635 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3636 install_element (RMAP_NODE, &set_community_cmd);
3637 install_element (RMAP_NODE, &set_community_none_cmd);
3638 install_element (RMAP_NODE, &no_set_community_cmd);
3639 install_element (RMAP_NODE, &no_set_community_val_cmd);
3640 install_element (RMAP_NODE, &no_set_community_none_cmd);
3641 install_element (RMAP_NODE, &set_community_delete_cmd);
3642 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3643 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3644 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3645 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3646 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3647 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3648 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3649 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3650 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3651 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3652 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3653 install_element (RMAP_NODE, &set_originator_id_cmd);
3654 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3655 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3656
3657#ifdef HAVE_IPV6
3658 route_map_install_match (&route_match_ipv6_address_cmd);
3659 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3660 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3661 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3662 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3663
3664 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3665 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3666 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3667 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3668 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3669 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3670 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3671 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3672 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3673 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3674 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3675 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3676#endif /* HAVE_IPV6 */
3677}