blob: 98e5a98fa040aa6c5ad88de278dbaf1e13f4cba1 [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
1226 if (old)
1227 community_free (old);
1228
paul718e3742002-12-13 20:15:29 +00001229 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1230 }
1231
1232 return RMAP_OKAY;
1233}
1234
1235/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001236static void *
paulfd79ac92004-10-13 05:06:08 +00001237route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001238{
1239 struct rmap_com_set *rcs;
1240 struct community *com = NULL;
1241 char *sp;
1242 int additive = 0;
1243 int none = 0;
1244
1245 if (strcmp (arg, "none") == 0)
1246 none = 1;
1247 else
1248 {
1249 sp = strstr (arg, "additive");
1250
1251 if (sp && sp > arg)
1252 {
1253 /* "additive" keyworkd is included. */
1254 additive = 1;
1255 *(sp - 1) = '\0';
1256 }
1257
1258 com = community_str2com (arg);
1259
1260 if (additive)
1261 *(sp - 1) = ' ';
1262
1263 if (! com)
1264 return NULL;
1265 }
1266
1267 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1268 memset (rcs, 0, sizeof (struct rmap_com_set));
1269
1270 rcs->com = com;
1271 rcs->additive = additive;
1272 rcs->none = none;
1273
1274 return rcs;
1275}
1276
1277/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001278static void
paul718e3742002-12-13 20:15:29 +00001279route_set_community_free (void *rule)
1280{
1281 struct rmap_com_set *rcs = rule;
1282
1283 if (rcs->com)
1284 community_free (rcs->com);
1285 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1286}
1287
1288/* Set community rule structure. */
1289struct route_map_rule_cmd route_set_community_cmd =
1290{
1291 "community",
1292 route_set_community,
1293 route_set_community_compile,
1294 route_set_community_free,
1295};
1296
hassofee6e4e2005-02-02 16:29:31 +00001297/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001298
1299/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001300static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001301route_set_community_delete (void *rule, struct prefix *prefix,
1302 route_map_object_t type, void *object)
1303{
1304 struct community_list *list;
1305 struct community *merge;
1306 struct community *new;
1307 struct community *old;
1308 struct bgp_info *binfo;
1309
1310 if (type == RMAP_BGP)
1311 {
1312 if (! rule)
1313 return RMAP_OKAY;
1314
1315 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001316 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001317 old = binfo->attr->community;
1318
1319 if (list && old)
1320 {
1321 merge = community_list_match_delete (community_dup (old), list);
1322 new = community_uniq_sort (merge);
1323 community_free (merge);
1324
1325 if (new->size == 0)
1326 {
1327 binfo->attr->community = NULL;
1328 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1329 community_free (new);
1330 }
1331 else
1332 {
1333 binfo->attr->community = new;
1334 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1335 }
1336 }
1337 }
1338
1339 return RMAP_OKAY;
1340}
1341
1342/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001343static void *
paulfd79ac92004-10-13 05:06:08 +00001344route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001345{
1346 char *p;
1347 char *str;
1348 int len;
1349
1350 p = strchr (arg, ' ');
1351 if (p)
1352 {
1353 len = p - arg;
1354 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1355 memcpy (str, arg, len);
1356 }
1357 else
1358 str = NULL;
1359
1360 return str;
1361}
1362
1363/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001364static void
paul718e3742002-12-13 20:15:29 +00001365route_set_community_delete_free (void *rule)
1366{
1367 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1368}
1369
1370/* Set community rule structure. */
1371struct route_map_rule_cmd route_set_community_delete_cmd =
1372{
1373 "comm-list",
1374 route_set_community_delete,
1375 route_set_community_delete_compile,
1376 route_set_community_delete_free,
1377};
1378
1379/* `set extcommunity rt COMMUNITY' */
1380
1381/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001382static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001383route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1384 route_map_object_t type, void *object)
1385{
1386 struct ecommunity *ecom;
1387 struct ecommunity *new_ecom;
1388 struct ecommunity *old_ecom;
1389 struct bgp_info *bgp_info;
1390
1391 if (type == RMAP_BGP)
1392 {
1393 ecom = rule;
1394 bgp_info = object;
1395
1396 if (! ecom)
1397 return RMAP_OKAY;
1398
1399 /* We assume additive for Extended Community. */
1400 old_ecom = bgp_info->attr->ecommunity;
1401
1402 if (old_ecom)
1403 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1404 else
1405 new_ecom = ecommunity_dup (ecom);
1406
1407 bgp_info->attr->ecommunity = new_ecom;
1408
hasso70601e02005-05-27 03:26:57 +00001409 if (old_ecom)
1410 ecommunity_free (old_ecom);
1411
paul718e3742002-12-13 20:15:29 +00001412 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1413 }
1414 return RMAP_OKAY;
1415}
1416
1417/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001418static void *
paulfd79ac92004-10-13 05:06:08 +00001419route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001420{
1421 struct ecommunity *ecom;
1422
1423 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1424 if (! ecom)
1425 return NULL;
1426 return ecom;
1427}
1428
1429/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001430static void
paul718e3742002-12-13 20:15:29 +00001431route_set_ecommunity_rt_free (void *rule)
1432{
1433 struct ecommunity *ecom = rule;
1434 ecommunity_free (ecom);
1435}
1436
1437/* Set community rule structure. */
1438struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1439{
1440 "extcommunity rt",
1441 route_set_ecommunity_rt,
1442 route_set_ecommunity_rt_compile,
1443 route_set_ecommunity_rt_free,
1444};
1445
1446/* `set extcommunity soo COMMUNITY' */
1447
1448/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001449static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001450route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1451 route_map_object_t type, void *object)
1452{
1453 struct ecommunity *ecom;
1454 struct bgp_info *bgp_info;
1455
1456 if (type == RMAP_BGP)
1457 {
1458 ecom = rule;
1459 bgp_info = object;
1460
1461 if (! ecom)
1462 return RMAP_OKAY;
1463
1464 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1465 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1466 }
1467 return RMAP_OKAY;
1468}
1469
1470/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001471static void *
paulfd79ac92004-10-13 05:06:08 +00001472route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001473{
1474 struct ecommunity *ecom;
1475
1476 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1477 if (! ecom)
1478 return NULL;
1479
1480 return ecom;
1481}
1482
1483/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001484static void
paul718e3742002-12-13 20:15:29 +00001485route_set_ecommunity_soo_free (void *rule)
1486{
1487 struct ecommunity *ecom = rule;
1488 ecommunity_free (ecom);
1489}
1490
1491/* Set community rule structure. */
1492struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1493{
1494 "extcommunity soo",
1495 route_set_ecommunity_soo,
1496 route_set_ecommunity_soo_compile,
1497 route_set_ecommunity_soo_free,
1498};
1499
1500/* `set origin ORIGIN' */
1501
1502/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001503static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001504route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1505{
1506 u_char *origin;
1507 struct bgp_info *bgp_info;
1508
1509 if (type == RMAP_BGP)
1510 {
1511 origin = rule;
1512 bgp_info = object;
1513
1514 bgp_info->attr->origin = *origin;
1515 }
1516
1517 return RMAP_OKAY;
1518}
1519
1520/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001521static void *
paulfd79ac92004-10-13 05:06:08 +00001522route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001523{
1524 u_char *origin;
1525
1526 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1527
1528 if (strcmp (arg, "igp") == 0)
1529 *origin = 0;
1530 else if (strcmp (arg, "egp") == 0)
1531 *origin = 1;
1532 else
1533 *origin = 2;
1534
1535 return origin;
1536}
1537
1538/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001539static void
paul718e3742002-12-13 20:15:29 +00001540route_set_origin_free (void *rule)
1541{
1542 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1543}
1544
1545/* Set metric rule structure. */
1546struct route_map_rule_cmd route_set_origin_cmd =
1547{
1548 "origin",
1549 route_set_origin,
1550 route_set_origin_compile,
1551 route_set_origin_free,
1552};
1553
1554/* `set atomic-aggregate' */
1555
1556/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001557static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001558route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1559 route_map_object_t type, void *object)
1560{
1561 struct bgp_info *bgp_info;
1562
1563 if (type == RMAP_BGP)
1564 {
1565 bgp_info = object;
1566 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1567 }
1568
1569 return RMAP_OKAY;
1570}
1571
1572/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001573static void *
paulfd79ac92004-10-13 05:06:08 +00001574route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001575{
1576 return (void *)1;
1577}
1578
1579/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001580static void
paul718e3742002-12-13 20:15:29 +00001581route_set_atomic_aggregate_free (void *rule)
1582{
1583 return;
1584}
1585
1586/* Set atomic aggregate rule structure. */
1587struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1588{
1589 "atomic-aggregate",
1590 route_set_atomic_aggregate,
1591 route_set_atomic_aggregate_compile,
1592 route_set_atomic_aggregate_free,
1593};
1594
1595/* `set aggregator as AS A.B.C.D' */
1596struct aggregator
1597{
1598 as_t as;
1599 struct in_addr address;
1600};
1601
paul94f2b392005-06-28 12:44:16 +00001602static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001603route_set_aggregator_as (void *rule, struct prefix *prefix,
1604 route_map_object_t type, void *object)
1605{
1606 struct bgp_info *bgp_info;
1607 struct aggregator *aggregator;
1608
1609 if (type == RMAP_BGP)
1610 {
1611 bgp_info = object;
1612 aggregator = rule;
1613
1614 bgp_info->attr->aggregator_as = aggregator->as;
1615 bgp_info->attr->aggregator_addr = aggregator->address;
1616 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1617 }
1618
1619 return RMAP_OKAY;
1620}
1621
paul94f2b392005-06-28 12:44:16 +00001622static void *
paulfd79ac92004-10-13 05:06:08 +00001623route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001624{
1625 struct aggregator *aggregator;
1626 char as[10];
1627 char address[20];
1628
1629 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1630 memset (aggregator, 0, sizeof (struct aggregator));
1631
1632 sscanf (arg, "%s %s", as, address);
1633
1634 aggregator->as = strtoul (as, NULL, 10);
1635 inet_aton (address, &aggregator->address);
1636
1637 return aggregator;
1638}
1639
paul94f2b392005-06-28 12:44:16 +00001640static void
paul718e3742002-12-13 20:15:29 +00001641route_set_aggregator_as_free (void *rule)
1642{
1643 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1644}
1645
1646struct route_map_rule_cmd route_set_aggregator_as_cmd =
1647{
1648 "aggregator as",
1649 route_set_aggregator_as,
1650 route_set_aggregator_as_compile,
1651 route_set_aggregator_as_free,
1652};
1653
1654#ifdef HAVE_IPV6
1655/* `match ipv6 address IP_ACCESS_LIST' */
1656
paul94f2b392005-06-28 12:44:16 +00001657static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001658route_match_ipv6_address (void *rule, struct prefix *prefix,
1659 route_map_object_t type, void *object)
1660{
1661 struct access_list *alist;
1662
1663 if (type == RMAP_BGP)
1664 {
1665 alist = access_list_lookup (AFI_IP6, (char *) rule);
1666 if (alist == NULL)
1667 return RMAP_NOMATCH;
1668
1669 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1670 RMAP_NOMATCH : RMAP_MATCH);
1671 }
1672 return RMAP_NOMATCH;
1673}
1674
paul94f2b392005-06-28 12:44:16 +00001675static void *
paulfd79ac92004-10-13 05:06:08 +00001676route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001677{
1678 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1679}
1680
paul94f2b392005-06-28 12:44:16 +00001681static void
paul718e3742002-12-13 20:15:29 +00001682route_match_ipv6_address_free (void *rule)
1683{
1684 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1685}
1686
1687/* Route map commands for ip address matching. */
1688struct route_map_rule_cmd route_match_ipv6_address_cmd =
1689{
1690 "ipv6 address",
1691 route_match_ipv6_address,
1692 route_match_ipv6_address_compile,
1693 route_match_ipv6_address_free
1694};
1695
1696/* `match ipv6 next-hop IP_ADDRESS' */
1697
paul94f2b392005-06-28 12:44:16 +00001698static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001699route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1700 route_map_object_t type, void *object)
1701{
1702 struct in6_addr *addr;
1703 struct bgp_info *bgp_info;
1704
1705 if (type == RMAP_BGP)
1706 {
1707 addr = rule;
1708 bgp_info = object;
1709
1710 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1711 return RMAP_MATCH;
1712
1713 if (bgp_info->attr->mp_nexthop_len == 32 &&
1714 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1715 return RMAP_MATCH;
1716
1717 return RMAP_NOMATCH;
1718 }
1719
1720 return RMAP_NOMATCH;
1721}
1722
paul94f2b392005-06-28 12:44:16 +00001723static void *
paulfd79ac92004-10-13 05:06:08 +00001724route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001725{
1726 struct in6_addr *address;
1727 int ret;
1728
1729 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1730
1731 ret = inet_pton (AF_INET6, arg, address);
1732 if (!ret)
1733 {
1734 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1735 return NULL;
1736 }
1737
1738 return address;
1739}
1740
paul94f2b392005-06-28 12:44:16 +00001741static void
paul718e3742002-12-13 20:15:29 +00001742route_match_ipv6_next_hop_free (void *rule)
1743{
1744 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1745}
1746
1747struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1748{
1749 "ipv6 next-hop",
1750 route_match_ipv6_next_hop,
1751 route_match_ipv6_next_hop_compile,
1752 route_match_ipv6_next_hop_free
1753};
1754
1755/* `match ipv6 address prefix-list PREFIX_LIST' */
1756
paul94f2b392005-06-28 12:44:16 +00001757static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001758route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1759 route_map_object_t type, void *object)
1760{
1761 struct prefix_list *plist;
1762
1763 if (type == RMAP_BGP)
1764 {
1765 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1766 if (plist == NULL)
1767 return RMAP_NOMATCH;
1768
1769 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1770 RMAP_NOMATCH : RMAP_MATCH);
1771 }
1772 return RMAP_NOMATCH;
1773}
1774
paul94f2b392005-06-28 12:44:16 +00001775static void *
paulfd79ac92004-10-13 05:06:08 +00001776route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001777{
1778 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1779}
1780
paul94f2b392005-06-28 12:44:16 +00001781static void
paul718e3742002-12-13 20:15:29 +00001782route_match_ipv6_address_prefix_list_free (void *rule)
1783{
1784 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1785}
1786
1787struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1788{
1789 "ipv6 address prefix-list",
1790 route_match_ipv6_address_prefix_list,
1791 route_match_ipv6_address_prefix_list_compile,
1792 route_match_ipv6_address_prefix_list_free
1793};
1794
1795/* `set ipv6 nexthop global IP_ADDRESS' */
1796
1797/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001798static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001799route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1800 route_map_object_t type, void *object)
1801{
1802 struct in6_addr *address;
1803 struct bgp_info *bgp_info;
1804
1805 if (type == RMAP_BGP)
1806 {
1807 /* Fetch routemap's rule information. */
1808 address = rule;
1809 bgp_info = object;
1810
1811 /* Set next hop value. */
1812 bgp_info->attr->mp_nexthop_global = *address;
1813
1814 /* Set nexthop length. */
1815 if (bgp_info->attr->mp_nexthop_len == 0)
1816 bgp_info->attr->mp_nexthop_len = 16;
1817 }
1818
1819 return RMAP_OKAY;
1820}
1821
1822/* Route map `ip next-hop' compile function. Given string is converted
1823 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001824static void *
paulfd79ac92004-10-13 05:06:08 +00001825route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001826{
1827 int ret;
1828 struct in6_addr *address;
1829
1830 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1831
1832 ret = inet_pton (AF_INET6, arg, address);
1833
1834 if (ret == 0)
1835 {
1836 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1837 return NULL;
1838 }
1839
1840 return address;
1841}
1842
1843/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001844static void
paul718e3742002-12-13 20:15:29 +00001845route_set_ipv6_nexthop_global_free (void *rule)
1846{
1847 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1848}
1849
1850/* Route map commands for ip nexthop set. */
1851struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1852{
1853 "ipv6 next-hop global",
1854 route_set_ipv6_nexthop_global,
1855 route_set_ipv6_nexthop_global_compile,
1856 route_set_ipv6_nexthop_global_free
1857};
1858
1859/* `set ipv6 nexthop local IP_ADDRESS' */
1860
1861/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001862static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001863route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1864 route_map_object_t type, void *object)
1865{
1866 struct in6_addr *address;
1867 struct bgp_info *bgp_info;
1868
1869 if (type == RMAP_BGP)
1870 {
1871 /* Fetch routemap's rule information. */
1872 address = rule;
1873 bgp_info = object;
1874
1875 /* Set next hop value. */
1876 bgp_info->attr->mp_nexthop_local = *address;
1877
1878 /* Set nexthop length. */
1879 if (bgp_info->attr->mp_nexthop_len != 32)
1880 bgp_info->attr->mp_nexthop_len = 32;
1881 }
1882
1883 return RMAP_OKAY;
1884}
1885
1886/* Route map `ip nexthop' compile function. Given string is converted
1887 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001888static void *
paulfd79ac92004-10-13 05:06:08 +00001889route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001890{
1891 int ret;
1892 struct in6_addr *address;
1893
1894 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1895
1896 ret = inet_pton (AF_INET6, arg, address);
1897
1898 if (ret == 0)
1899 {
1900 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1901 return NULL;
1902 }
1903
1904 return address;
1905}
1906
1907/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001908static void
paul718e3742002-12-13 20:15:29 +00001909route_set_ipv6_nexthop_local_free (void *rule)
1910{
1911 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1912}
1913
1914/* Route map commands for ip nexthop set. */
1915struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1916{
1917 "ipv6 next-hop local",
1918 route_set_ipv6_nexthop_local,
1919 route_set_ipv6_nexthop_local_compile,
1920 route_set_ipv6_nexthop_local_free
1921};
1922#endif /* HAVE_IPV6 */
1923
1924/* `set vpnv4 nexthop A.B.C.D' */
1925
paul94f2b392005-06-28 12:44:16 +00001926static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001927route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1928 route_map_object_t type, void *object)
1929{
1930 struct in_addr *address;
1931 struct bgp_info *bgp_info;
1932
1933 if (type == RMAP_BGP)
1934 {
1935 /* Fetch routemap's rule information. */
1936 address = rule;
1937 bgp_info = object;
1938
1939 /* Set next hop value. */
1940 bgp_info->attr->mp_nexthop_global_in = *address;
1941 }
1942
1943 return RMAP_OKAY;
1944}
1945
paul94f2b392005-06-28 12:44:16 +00001946static void *
paulfd79ac92004-10-13 05:06:08 +00001947route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001948{
1949 int ret;
1950 struct in_addr *address;
1951
1952 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1953
1954 ret = inet_aton (arg, address);
1955
1956 if (ret == 0)
1957 {
1958 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1959 return NULL;
1960 }
1961
1962 return address;
1963}
1964
paul94f2b392005-06-28 12:44:16 +00001965static void
paul718e3742002-12-13 20:15:29 +00001966route_set_vpnv4_nexthop_free (void *rule)
1967{
1968 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1969}
1970
1971/* Route map commands for ip nexthop set. */
1972struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1973{
1974 "vpnv4 next-hop",
1975 route_set_vpnv4_nexthop,
1976 route_set_vpnv4_nexthop_compile,
1977 route_set_vpnv4_nexthop_free
1978};
1979
1980/* `set originator-id' */
1981
1982/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001983static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001984route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1985{
1986 struct in_addr *address;
1987 struct bgp_info *bgp_info;
1988
1989 if (type == RMAP_BGP)
1990 {
1991 address = rule;
1992 bgp_info = object;
1993
1994 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1995 bgp_info->attr->originator_id = *address;
1996 }
1997
1998 return RMAP_OKAY;
1999}
2000
2001/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002002static void *
paulfd79ac92004-10-13 05:06:08 +00002003route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002004{
2005 int ret;
2006 struct in_addr *address;
2007
2008 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2009
2010 ret = inet_aton (arg, address);
2011
2012 if (ret == 0)
2013 {
2014 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2015 return NULL;
2016 }
2017
2018 return address;
2019}
2020
2021/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002022static void
paul718e3742002-12-13 20:15:29 +00002023route_set_originator_id_free (void *rule)
2024{
2025 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2026}
2027
2028/* Set metric rule structure. */
2029struct route_map_rule_cmd route_set_originator_id_cmd =
2030{
2031 "originator-id",
2032 route_set_originator_id,
2033 route_set_originator_id_compile,
2034 route_set_originator_id_free,
2035};
2036
2037/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002038static int
paul718e3742002-12-13 20:15:29 +00002039bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002040 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002041{
2042 int ret;
2043
2044 ret = route_map_add_match (index, command, arg);
2045 if (ret)
2046 {
2047 switch (ret)
2048 {
2049 case RMAP_RULE_MISSING:
2050 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2051 return CMD_WARNING;
2052 break;
2053 case RMAP_COMPILE_ERROR:
2054 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2055 return CMD_WARNING;
2056 break;
2057 }
2058 }
2059 return CMD_SUCCESS;
2060}
2061
2062/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002063static int
paul718e3742002-12-13 20:15:29 +00002064bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002065 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002066{
2067 int ret;
2068
2069 ret = route_map_delete_match (index, command, arg);
2070 if (ret)
2071 {
2072 switch (ret)
2073 {
2074 case RMAP_RULE_MISSING:
2075 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2076 return CMD_WARNING;
2077 break;
2078 case RMAP_COMPILE_ERROR:
2079 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2080 return CMD_WARNING;
2081 break;
2082 }
2083 }
2084 return CMD_SUCCESS;
2085}
2086
2087/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002088static int
paul718e3742002-12-13 20:15:29 +00002089bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002090 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002091{
2092 int ret;
2093
2094 ret = route_map_add_set (index, command, arg);
2095 if (ret)
2096 {
2097 switch (ret)
2098 {
2099 case RMAP_RULE_MISSING:
2100 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2101 return CMD_WARNING;
2102 break;
2103 case RMAP_COMPILE_ERROR:
2104 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2105 return CMD_WARNING;
2106 break;
2107 }
2108 }
2109 return CMD_SUCCESS;
2110}
2111
2112/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002113static int
paul718e3742002-12-13 20:15:29 +00002114bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002115 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002116{
2117 int ret;
2118
2119 ret = route_map_delete_set (index, command, arg);
2120 if (ret)
2121 {
2122 switch (ret)
2123 {
2124 case RMAP_RULE_MISSING:
2125 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2126 return CMD_WARNING;
2127 break;
2128 case RMAP_COMPILE_ERROR:
2129 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2130 return CMD_WARNING;
2131 break;
2132 }
2133 }
2134 return CMD_SUCCESS;
2135}
2136
2137/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002138static void
paulfd79ac92004-10-13 05:06:08 +00002139bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002140{
2141 int i;
2142 afi_t afi;
2143 safi_t safi;
2144 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002145 struct listnode *node, *nnode;
2146 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002147 struct bgp *bgp;
2148 struct peer *peer;
2149 struct peer_group *group;
2150 struct bgp_filter *filter;
2151 struct bgp_node *bn;
2152 struct bgp_static *bgp_static;
2153
2154 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002155 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002156 {
paul1eb8ef22005-04-07 07:30:20 +00002157 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002158 {
2159 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2160 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2161 {
2162 filter = &peer->filter[afi][safi];
2163
paulfee0f4c2004-09-13 05:12:46 +00002164 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002165 {
2166 if (filter->map[direct].name)
2167 filter->map[direct].map =
2168 route_map_lookup_by_name (filter->map[direct].name);
2169 else
2170 filter->map[direct].map = NULL;
2171 }
2172
2173 if (filter->usmap.name)
2174 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2175 else
2176 filter->usmap.map = NULL;
2177 }
2178 }
paul1eb8ef22005-04-07 07:30:20 +00002179 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002180 {
2181 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2182 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2183 {
2184 filter = &group->conf->filter[afi][safi];
2185
paulfee0f4c2004-09-13 05:12:46 +00002186 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002187 {
2188 if (filter->map[direct].name)
2189 filter->map[direct].map =
2190 route_map_lookup_by_name (filter->map[direct].name);
2191 else
2192 filter->map[direct].map = NULL;
2193 }
2194
2195 if (filter->usmap.name)
2196 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2197 else
2198 filter->usmap.map = NULL;
2199 }
2200 }
2201 }
2202
2203 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002204 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002205 {
paul1eb8ef22005-04-07 07:30:20 +00002206 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002207 {
2208 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2209 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2210 {
2211 if (peer->default_rmap[afi][safi].name)
2212 peer->default_rmap[afi][safi].map =
2213 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2214 else
2215 peer->default_rmap[afi][safi].map = NULL;
2216 }
2217 }
2218 }
2219
2220 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002221 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002222 {
2223 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2224 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2225 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2226 bn = bgp_route_next (bn))
2227 if ((bgp_static = bn->info) != NULL)
2228 {
2229 if (bgp_static->rmap.name)
2230 bgp_static->rmap.map =
2231 route_map_lookup_by_name (bgp_static->rmap.name);
2232 else
2233 bgp_static->rmap.map = NULL;
2234 }
2235 }
2236
2237 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002238 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002239 {
2240 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2241 {
2242 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2243 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2244 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2245#ifdef HAVE_IPV6
2246 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2247 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2248 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2249#endif /* HAVE_IPV6 */
2250 }
2251 }
2252}
2253
paulfee0f4c2004-09-13 05:12:46 +00002254DEFUN (match_peer,
2255 match_peer_cmd,
2256 "match peer (A.B.C.D|X:X::X:X)",
2257 MATCH_STR
2258 "Match peer address\n"
2259 "IPv6 address of peer\n"
2260 "IP address of peer\n")
2261{
2262 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2263}
2264
2265DEFUN (match_peer_local,
2266 match_peer_local_cmd,
2267 "match peer local",
2268 MATCH_STR
2269 "Match peer address\n"
2270 "Static or Redistributed routes\n")
2271{
2272 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2273}
2274
2275DEFUN (no_match_peer,
2276 no_match_peer_cmd,
2277 "no match peer",
2278 NO_STR
2279 MATCH_STR
2280 "Match peer address\n")
2281{
2282 if (argc == 0)
2283 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2284
2285 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2286}
2287
2288ALIAS (no_match_peer,
2289 no_match_peer_val_cmd,
2290 "no match peer (A.B.C.D|X:X::X:X)",
2291 NO_STR
2292 MATCH_STR
2293 "Match peer address\n"
2294 "IPv6 address of peer\n"
2295 "IP address of peer\n")
2296
2297ALIAS (no_match_peer,
2298 no_match_peer_local_cmd,
2299 "no match peer local",
2300 NO_STR
2301 MATCH_STR
2302 "Match peer address\n"
2303 "Static or Redistributed routes\n")
2304
paul718e3742002-12-13 20:15:29 +00002305DEFUN (match_ip_address,
2306 match_ip_address_cmd,
2307 "match ip address (<1-199>|<1300-2699>|WORD)",
2308 MATCH_STR
2309 IP_STR
2310 "Match address of route\n"
2311 "IP access-list number\n"
2312 "IP access-list number (expanded range)\n"
2313 "IP Access-list name\n")
2314{
2315 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2316}
2317
2318DEFUN (no_match_ip_address,
2319 no_match_ip_address_cmd,
2320 "no match ip address",
2321 NO_STR
2322 MATCH_STR
2323 IP_STR
2324 "Match address of route\n")
2325{
2326 if (argc == 0)
2327 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2328
2329 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2330}
2331
2332ALIAS (no_match_ip_address,
2333 no_match_ip_address_val_cmd,
2334 "no match ip address (<1-199>|<1300-2699>|WORD)",
2335 NO_STR
2336 MATCH_STR
2337 IP_STR
2338 "Match address of route\n"
2339 "IP access-list number\n"
2340 "IP access-list number (expanded range)\n"
2341 "IP Access-list name\n")
2342
2343DEFUN (match_ip_next_hop,
2344 match_ip_next_hop_cmd,
2345 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2346 MATCH_STR
2347 IP_STR
2348 "Match next-hop address of route\n"
2349 "IP access-list number\n"
2350 "IP access-list number (expanded range)\n"
2351 "IP Access-list name\n")
2352{
2353 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2354}
2355
2356DEFUN (no_match_ip_next_hop,
2357 no_match_ip_next_hop_cmd,
2358 "no match ip next-hop",
2359 NO_STR
2360 MATCH_STR
2361 IP_STR
2362 "Match next-hop address of route\n")
2363{
2364 if (argc == 0)
2365 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2366
2367 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2368}
2369
2370ALIAS (no_match_ip_next_hop,
2371 no_match_ip_next_hop_val_cmd,
2372 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2373 NO_STR
2374 MATCH_STR
2375 IP_STR
2376 "Match next-hop address of route\n"
2377 "IP access-list number\n"
2378 "IP access-list number (expanded range)\n"
2379 "IP Access-list name\n")
2380
hassoc1643bb2005-02-02 16:43:17 +00002381DEFUN (match_ip_route_source,
2382 match_ip_route_source_cmd,
2383 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2384 MATCH_STR
2385 IP_STR
2386 "Match advertising source address of route\n"
2387 "IP access-list number\n"
2388 "IP access-list number (expanded range)\n"
2389 "IP standard access-list name\n")
2390{
2391 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2392}
2393
2394DEFUN (no_match_ip_route_source,
2395 no_match_ip_route_source_cmd,
2396 "no match ip route-source",
2397 NO_STR
2398 MATCH_STR
2399 IP_STR
2400 "Match advertising source address of route\n")
2401{
2402 if (argc == 0)
2403 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2404
2405 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2406}
2407
2408ALIAS (no_match_ip_route_source,
2409 no_match_ip_route_source_val_cmd,
2410 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2411 NO_STR
2412 MATCH_STR
2413 IP_STR
2414 "Match advertising source address of route\n"
2415 "IP access-list number\n"
2416 "IP access-list number (expanded range)\n"
2417 "IP standard access-list name\n");
2418
paul718e3742002-12-13 20:15:29 +00002419DEFUN (match_ip_address_prefix_list,
2420 match_ip_address_prefix_list_cmd,
2421 "match ip address prefix-list WORD",
2422 MATCH_STR
2423 IP_STR
2424 "Match address of route\n"
2425 "Match entries of prefix-lists\n"
2426 "IP prefix-list name\n")
2427{
2428 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2429}
2430
2431DEFUN (no_match_ip_address_prefix_list,
2432 no_match_ip_address_prefix_list_cmd,
2433 "no match ip address prefix-list",
2434 NO_STR
2435 MATCH_STR
2436 IP_STR
2437 "Match address of route\n"
2438 "Match entries of prefix-lists\n")
2439{
2440 if (argc == 0)
2441 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2442
2443 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2444}
2445
2446ALIAS (no_match_ip_address_prefix_list,
2447 no_match_ip_address_prefix_list_val_cmd,
2448 "no match ip address prefix-list WORD",
2449 NO_STR
2450 MATCH_STR
2451 IP_STR
2452 "Match address of route\n"
2453 "Match entries of prefix-lists\n"
2454 "IP prefix-list name\n")
2455
2456DEFUN (match_ip_next_hop_prefix_list,
2457 match_ip_next_hop_prefix_list_cmd,
2458 "match ip next-hop prefix-list WORD",
2459 MATCH_STR
2460 IP_STR
2461 "Match next-hop address of route\n"
2462 "Match entries of prefix-lists\n"
2463 "IP prefix-list name\n")
2464{
2465 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2466}
2467
2468DEFUN (no_match_ip_next_hop_prefix_list,
2469 no_match_ip_next_hop_prefix_list_cmd,
2470 "no match ip next-hop prefix-list",
2471 NO_STR
2472 MATCH_STR
2473 IP_STR
2474 "Match next-hop address of route\n"
2475 "Match entries of prefix-lists\n")
2476{
2477 if (argc == 0)
2478 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2479
2480 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2481}
2482
2483ALIAS (no_match_ip_next_hop_prefix_list,
2484 no_match_ip_next_hop_prefix_list_val_cmd,
2485 "no match ip next-hop prefix-list WORD",
2486 NO_STR
2487 MATCH_STR
2488 IP_STR
2489 "Match next-hop address of route\n"
2490 "Match entries of prefix-lists\n"
2491 "IP prefix-list name\n")
2492
hassoc1643bb2005-02-02 16:43:17 +00002493DEFUN (match_ip_route_source_prefix_list,
2494 match_ip_route_source_prefix_list_cmd,
2495 "match ip route-source prefix-list WORD",
2496 MATCH_STR
2497 IP_STR
2498 "Match advertising source address of route\n"
2499 "Match entries of prefix-lists\n"
2500 "IP prefix-list name\n")
2501{
2502 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2503}
2504
2505DEFUN (no_match_ip_route_source_prefix_list,
2506 no_match_ip_route_source_prefix_list_cmd,
2507 "no match ip route-source prefix-list",
2508 NO_STR
2509 MATCH_STR
2510 IP_STR
2511 "Match advertising source address of route\n"
2512 "Match entries of prefix-lists\n")
2513{
2514 if (argc == 0)
2515 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2516
2517 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2518}
2519
2520ALIAS (no_match_ip_route_source_prefix_list,
2521 no_match_ip_route_source_prefix_list_val_cmd,
2522 "no match ip route-source prefix-list WORD",
2523 NO_STR
2524 MATCH_STR
2525 IP_STR
2526 "Match advertising source address of route\n"
2527 "Match entries of prefix-lists\n"
2528 "IP prefix-list name\n");
2529
paul718e3742002-12-13 20:15:29 +00002530DEFUN (match_metric,
2531 match_metric_cmd,
2532 "match metric <0-4294967295>",
2533 MATCH_STR
2534 "Match metric of route\n"
2535 "Metric value\n")
2536{
2537 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2538}
2539
2540DEFUN (no_match_metric,
2541 no_match_metric_cmd,
2542 "no match metric",
2543 NO_STR
2544 MATCH_STR
2545 "Match metric of route\n")
2546{
2547 if (argc == 0)
2548 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2549
2550 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2551}
2552
2553ALIAS (no_match_metric,
2554 no_match_metric_val_cmd,
2555 "no match metric <0-4294967295>",
2556 NO_STR
2557 MATCH_STR
2558 "Match metric of route\n"
2559 "Metric value\n")
2560
2561DEFUN (match_community,
2562 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002563 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002564 MATCH_STR
2565 "Match BGP community list\n"
2566 "Community-list number (standard)\n"
2567 "Community-list number (expanded)\n"
2568 "Community-list name\n")
2569{
2570 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2571}
2572
2573DEFUN (match_community_exact,
2574 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002575 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002576 MATCH_STR
2577 "Match BGP community list\n"
2578 "Community-list number (standard)\n"
2579 "Community-list number (expanded)\n"
2580 "Community-list name\n"
2581 "Do exact matching of communities\n")
2582{
2583 int ret;
2584 char *argstr;
2585
2586 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2587 strlen (argv[0]) + strlen ("exact-match") + 2);
2588
2589 sprintf (argstr, "%s exact-match", argv[0]);
2590
2591 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2592
2593 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2594
2595 return ret;
2596}
2597
2598DEFUN (no_match_community,
2599 no_match_community_cmd,
2600 "no match community",
2601 NO_STR
2602 MATCH_STR
2603 "Match BGP community list\n")
2604{
2605 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2606}
2607
2608ALIAS (no_match_community,
2609 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002610 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002611 NO_STR
2612 MATCH_STR
2613 "Match BGP community list\n"
2614 "Community-list number (standard)\n"
2615 "Community-list number (expanded)\n"
2616 "Community-list name\n")
2617
2618ALIAS (no_match_community,
2619 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002620 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002621 NO_STR
2622 MATCH_STR
2623 "Match BGP community list\n"
2624 "Community-list number (standard)\n"
2625 "Community-list number (expanded)\n"
2626 "Community-list name\n"
2627 "Do exact matching of communities\n")
2628
paul73ffb252003-04-19 15:49:49 +00002629DEFUN (match_ecommunity,
2630 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002631 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002632 MATCH_STR
2633 "Match BGP/VPN extended community list\n"
2634 "Extended community-list number (standard)\n"
2635 "Extended community-list number (expanded)\n"
2636 "Extended community-list name\n")
2637{
2638 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2639}
2640
2641DEFUN (no_match_ecommunity,
2642 no_match_ecommunity_cmd,
2643 "no match extcommunity",
2644 NO_STR
2645 MATCH_STR
2646 "Match BGP/VPN extended community list\n")
2647{
2648 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2649}
2650
2651ALIAS (no_match_ecommunity,
2652 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002653 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002654 NO_STR
2655 MATCH_STR
2656 "Match BGP/VPN extended community list\n"
2657 "Extended community-list number (standard)\n"
2658 "Extended community-list number (expanded)\n"
2659 "Extended community-list name\n")
2660
paul718e3742002-12-13 20:15:29 +00002661DEFUN (match_aspath,
2662 match_aspath_cmd,
2663 "match as-path WORD",
2664 MATCH_STR
2665 "Match BGP AS path list\n"
2666 "AS path access-list name\n")
2667{
2668 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2669}
2670
2671DEFUN (no_match_aspath,
2672 no_match_aspath_cmd,
2673 "no match as-path",
2674 NO_STR
2675 MATCH_STR
2676 "Match BGP AS path list\n")
2677{
2678 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2679}
2680
2681ALIAS (no_match_aspath,
2682 no_match_aspath_val_cmd,
2683 "no match as-path WORD",
2684 NO_STR
2685 MATCH_STR
2686 "Match BGP AS path list\n"
2687 "AS path access-list name\n")
2688
2689DEFUN (match_origin,
2690 match_origin_cmd,
2691 "match origin (egp|igp|incomplete)",
2692 MATCH_STR
2693 "BGP origin code\n"
2694 "remote EGP\n"
2695 "local IGP\n"
2696 "unknown heritage\n")
2697{
2698 if (strncmp (argv[0], "igp", 2) == 0)
2699 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2700 if (strncmp (argv[0], "egp", 1) == 0)
2701 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2702 if (strncmp (argv[0], "incomplete", 2) == 0)
2703 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2704
2705 return CMD_WARNING;
2706}
2707
2708DEFUN (no_match_origin,
2709 no_match_origin_cmd,
2710 "no match origin",
2711 NO_STR
2712 MATCH_STR
2713 "BGP origin code\n")
2714{
2715 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2716}
2717
2718ALIAS (no_match_origin,
2719 no_match_origin_val_cmd,
2720 "no match origin (egp|igp|incomplete)",
2721 NO_STR
2722 MATCH_STR
2723 "BGP origin code\n"
2724 "remote EGP\n"
2725 "local IGP\n"
2726 "unknown heritage\n")
2727
2728DEFUN (set_ip_nexthop,
2729 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002730 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002731 SET_STR
2732 IP_STR
2733 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002734 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002735{
2736 union sockunion su;
2737 int ret;
2738
2739 ret = str2sockunion (argv[0], &su);
2740 if (ret < 0)
2741 {
2742 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2743 return CMD_WARNING;
2744 }
2745
2746 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2747}
2748
paulaf5cd0a2003-11-02 07:24:40 +00002749DEFUN (set_ip_nexthop_peer,
2750 set_ip_nexthop_peer_cmd,
2751 "set ip next-hop peer-address",
2752 SET_STR
2753 IP_STR
2754 "Next hop address\n"
2755 "Use peer address (for BGP only)\n")
2756{
2757 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2758}
2759
paul94f2b392005-06-28 12:44:16 +00002760DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002761 no_set_ip_nexthop_peer_cmd,
2762 "no set ip next-hop peer-address",
2763 NO_STR
2764 SET_STR
2765 IP_STR
2766 "Next hop address\n"
2767 "Use peer address (for BGP only)\n")
2768{
2769 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2770}
2771
2772
paul718e3742002-12-13 20:15:29 +00002773DEFUN (no_set_ip_nexthop,
2774 no_set_ip_nexthop_cmd,
2775 "no set ip next-hop",
2776 NO_STR
2777 SET_STR
paul718e3742002-12-13 20:15:29 +00002778 "Next hop address\n")
2779{
paulaf5cd0a2003-11-02 07:24:40 +00002780 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002781 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2782
2783 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2784}
2785
2786ALIAS (no_set_ip_nexthop,
2787 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002788 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002789 NO_STR
2790 SET_STR
2791 IP_STR
2792 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002793 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002794
2795DEFUN (set_metric,
2796 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002797 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002798 SET_STR
2799 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002800 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002801{
2802 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2803}
2804
paul73ffb252003-04-19 15:49:49 +00002805ALIAS (set_metric,
2806 set_metric_addsub_cmd,
2807 "set metric <+/-metric>",
2808 SET_STR
2809 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002810 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002811
paul718e3742002-12-13 20:15:29 +00002812DEFUN (no_set_metric,
2813 no_set_metric_cmd,
2814 "no set metric",
2815 NO_STR
2816 SET_STR
2817 "Metric value for destination routing protocol\n")
2818{
2819 if (argc == 0)
2820 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2821
2822 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2823}
2824
2825ALIAS (no_set_metric,
2826 no_set_metric_val_cmd,
2827 "no set metric <0-4294967295>",
2828 NO_STR
2829 SET_STR
2830 "Metric value for destination routing protocol\n"
2831 "Metric value\n")
2832
2833DEFUN (set_local_pref,
2834 set_local_pref_cmd,
2835 "set local-preference <0-4294967295>",
2836 SET_STR
2837 "BGP local preference path attribute\n"
2838 "Preference value\n")
2839{
2840 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2841}
2842
2843DEFUN (no_set_local_pref,
2844 no_set_local_pref_cmd,
2845 "no set local-preference",
2846 NO_STR
2847 SET_STR
2848 "BGP local preference path attribute\n")
2849{
2850 if (argc == 0)
2851 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2852
2853 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2854}
2855
2856ALIAS (no_set_local_pref,
2857 no_set_local_pref_val_cmd,
2858 "no set local-preference <0-4294967295>",
2859 NO_STR
2860 SET_STR
2861 "BGP local preference path attribute\n"
2862 "Preference value\n")
2863
2864DEFUN (set_weight,
2865 set_weight_cmd,
2866 "set weight <0-4294967295>",
2867 SET_STR
2868 "BGP weight for routing table\n"
2869 "Weight value\n")
2870{
2871 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2872}
2873
2874DEFUN (no_set_weight,
2875 no_set_weight_cmd,
2876 "no set weight",
2877 NO_STR
2878 SET_STR
2879 "BGP weight for routing table\n")
2880{
2881 if (argc == 0)
2882 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2883
2884 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2885}
2886
2887ALIAS (no_set_weight,
2888 no_set_weight_val_cmd,
2889 "no set weight <0-4294967295>",
2890 NO_STR
2891 SET_STR
2892 "BGP weight for routing table\n"
2893 "Weight value\n")
2894
2895DEFUN (set_aspath_prepend,
2896 set_aspath_prepend_cmd,
2897 "set as-path prepend .<1-65535>",
2898 SET_STR
2899 "Prepend string for a BGP AS-path attribute\n"
2900 "Prepend to the as-path\n"
2901 "AS number\n")
2902{
2903 int ret;
2904 char *str;
2905
2906 str = argv_concat (argv, argc, 0);
2907 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2908 XFREE (MTYPE_TMP, str);
2909
2910 return ret;
2911}
2912
2913DEFUN (no_set_aspath_prepend,
2914 no_set_aspath_prepend_cmd,
2915 "no set as-path prepend",
2916 NO_STR
2917 SET_STR
2918 "Prepend string for a BGP AS-path attribute\n"
2919 "Prepend to the as-path\n")
2920{
2921 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2922}
2923
2924ALIAS (no_set_aspath_prepend,
2925 no_set_aspath_prepend_val_cmd,
2926 "no set as-path prepend .<1-65535>",
2927 NO_STR
2928 SET_STR
2929 "Prepend string for a BGP AS-path attribute\n"
2930 "Prepend to the as-path\n"
2931 "AS number\n")
2932
2933DEFUN (set_community,
2934 set_community_cmd,
2935 "set community .AA:NN",
2936 SET_STR
2937 "BGP community attribute\n"
2938 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2939{
2940 int i;
2941 int first = 0;
2942 int additive = 0;
2943 struct buffer *b;
2944 struct community *com = NULL;
2945 char *str;
2946 char *argstr;
2947 int ret;
2948
2949 b = buffer_new (1024);
2950
2951 for (i = 0; i < argc; i++)
2952 {
2953 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2954 {
2955 additive = 1;
2956 continue;
2957 }
2958
2959 if (first)
2960 buffer_putc (b, ' ');
2961 else
2962 first = 1;
2963
2964 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2965 {
2966 buffer_putstr (b, "internet");
2967 continue;
2968 }
2969 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2970 {
2971 buffer_putstr (b, "local-AS");
2972 continue;
2973 }
2974 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2975 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2976 {
2977 buffer_putstr (b, "no-advertise");
2978 continue;
2979 }
2980 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2981 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2982 {
2983 buffer_putstr (b, "no-export");
2984 continue;
2985 }
2986 buffer_putstr (b, argv[i]);
2987 }
2988 buffer_putc (b, '\0');
2989
2990 /* Fetch result string then compile it to communities attribute. */
2991 str = buffer_getstr (b);
2992 buffer_free (b);
2993
2994 if (str)
2995 {
2996 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00002997 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00002998 }
2999
3000 /* Can't compile user input into communities attribute. */
3001 if (! com)
3002 {
3003 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3004 return CMD_WARNING;
3005 }
3006
3007 /* Set communites attribute string. */
3008 str = community_str (com);
3009
3010 if (additive)
3011 {
3012 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3013 strcpy (argstr, str);
3014 strcpy (argstr + strlen (str), " additive");
3015 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3016 XFREE (MTYPE_TMP, argstr);
3017 }
3018 else
3019 ret = bgp_route_set_add (vty, vty->index, "community", str);
3020
3021 community_free (com);
3022
3023 return ret;
3024}
3025
3026DEFUN (set_community_none,
3027 set_community_none_cmd,
3028 "set community none",
3029 SET_STR
3030 "BGP community attribute\n"
3031 "No community attribute\n")
3032{
3033 return bgp_route_set_add (vty, vty->index, "community", "none");
3034}
3035
3036DEFUN (no_set_community,
3037 no_set_community_cmd,
3038 "no set community",
3039 NO_STR
3040 SET_STR
3041 "BGP community attribute\n")
3042{
3043 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3044}
3045
3046ALIAS (no_set_community,
3047 no_set_community_val_cmd,
3048 "no set community .AA:NN",
3049 NO_STR
3050 SET_STR
3051 "BGP community attribute\n"
3052 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3053
3054ALIAS (no_set_community,
3055 no_set_community_none_cmd,
3056 "no set community none",
3057 NO_STR
3058 SET_STR
3059 "BGP community attribute\n"
3060 "No community attribute\n")
3061
3062DEFUN (set_community_delete,
3063 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003064 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003065 SET_STR
3066 "set BGP community list (for deletion)\n"
3067 "Community-list number (standard)\n"
3068 "Communitly-list number (expanded)\n"
3069 "Community-list name\n"
3070 "Delete matching communities\n")
3071{
3072 char *str;
3073
3074 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3075 strcpy (str, argv[0]);
3076 strcpy (str + strlen (argv[0]), " delete");
3077
3078 bgp_route_set_add (vty, vty->index, "comm-list", str);
3079
3080 XFREE (MTYPE_TMP, str);
3081 return CMD_SUCCESS;
3082}
3083
3084DEFUN (no_set_community_delete,
3085 no_set_community_delete_cmd,
3086 "no set comm-list",
3087 NO_STR
3088 SET_STR
3089 "set BGP community list (for deletion)\n")
3090{
3091 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3092}
3093
3094ALIAS (no_set_community_delete,
3095 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003096 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003097 NO_STR
3098 SET_STR
3099 "set BGP community list (for deletion)\n"
3100 "Community-list number (standard)\n"
3101 "Communitly-list number (expanded)\n"
3102 "Community-list name\n"
3103 "Delete matching communities\n")
3104
3105DEFUN (set_ecommunity_rt,
3106 set_ecommunity_rt_cmd,
3107 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3108 SET_STR
3109 "BGP extended community attribute\n"
3110 "Route Target extened communityt\n"
3111 "VPN extended community\n")
3112{
3113 int ret;
3114 char *str;
3115
3116 str = argv_concat (argv, argc, 0);
3117 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3118 XFREE (MTYPE_TMP, str);
3119
3120 return ret;
3121}
3122
3123DEFUN (no_set_ecommunity_rt,
3124 no_set_ecommunity_rt_cmd,
3125 "no set extcommunity rt",
3126 NO_STR
3127 SET_STR
3128 "BGP extended community attribute\n"
3129 "Route Target extened communityt\n")
3130{
3131 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3132}
3133
3134ALIAS (no_set_ecommunity_rt,
3135 no_set_ecommunity_rt_val_cmd,
3136 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3137 NO_STR
3138 SET_STR
3139 "BGP extended community attribute\n"
3140 "Route Target extened communityt\n"
3141 "VPN extended community\n")
3142
3143DEFUN (set_ecommunity_soo,
3144 set_ecommunity_soo_cmd,
3145 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3146 SET_STR
3147 "BGP extended community attribute\n"
3148 "Site-of-Origin extended community\n"
3149 "VPN extended community\n")
3150{
3151 int ret;
3152 char *str;
3153
3154 str = argv_concat (argv, argc, 0);
3155 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3156 XFREE (MTYPE_TMP, str);
3157 return ret;
3158}
3159
3160DEFUN (no_set_ecommunity_soo,
3161 no_set_ecommunity_soo_cmd,
3162 "no set extcommunity soo",
3163 NO_STR
3164 SET_STR
3165 "BGP extended community attribute\n"
3166 "Site-of-Origin extended community\n")
3167{
3168 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3169}
3170
3171ALIAS (no_set_ecommunity_soo,
3172 no_set_ecommunity_soo_val_cmd,
3173 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3174 NO_STR
3175 SET_STR
3176 "BGP extended community attribute\n"
3177 "Site-of-Origin extended community\n"
3178 "VPN extended community\n")
3179
3180DEFUN (set_origin,
3181 set_origin_cmd,
3182 "set origin (egp|igp|incomplete)",
3183 SET_STR
3184 "BGP origin code\n"
3185 "remote EGP\n"
3186 "local IGP\n"
3187 "unknown heritage\n")
3188{
3189 if (strncmp (argv[0], "igp", 2) == 0)
3190 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3191 if (strncmp (argv[0], "egp", 1) == 0)
3192 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3193 if (strncmp (argv[0], "incomplete", 2) == 0)
3194 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3195
3196 return CMD_WARNING;
3197}
3198
3199DEFUN (no_set_origin,
3200 no_set_origin_cmd,
3201 "no set origin",
3202 NO_STR
3203 SET_STR
3204 "BGP origin code\n")
3205{
3206 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3207}
3208
3209ALIAS (no_set_origin,
3210 no_set_origin_val_cmd,
3211 "no set origin (egp|igp|incomplete)",
3212 NO_STR
3213 SET_STR
3214 "BGP origin code\n"
3215 "remote EGP\n"
3216 "local IGP\n"
3217 "unknown heritage\n")
3218
3219DEFUN (set_atomic_aggregate,
3220 set_atomic_aggregate_cmd,
3221 "set atomic-aggregate",
3222 SET_STR
3223 "BGP atomic aggregate attribute\n" )
3224{
3225 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3226}
3227
3228DEFUN (no_set_atomic_aggregate,
3229 no_set_atomic_aggregate_cmd,
3230 "no set atomic-aggregate",
3231 NO_STR
3232 SET_STR
3233 "BGP atomic aggregate attribute\n" )
3234{
3235 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3236}
3237
3238DEFUN (set_aggregator_as,
3239 set_aggregator_as_cmd,
3240 "set aggregator as <1-65535> A.B.C.D",
3241 SET_STR
3242 "BGP aggregator attribute\n"
3243 "AS number of aggregator\n"
3244 "AS number\n"
3245 "IP address of aggregator\n")
3246{
3247 int ret;
3248 as_t as;
3249 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003250 char *argstr;
3251
paula94feb32005-05-23 13:17:29 +00003252 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paulfd79ac92004-10-13 05:06:08 +00003253
paul718e3742002-12-13 20:15:29 +00003254 ret = inet_aton (argv[1], &address);
3255 if (ret == 0)
3256 {
3257 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3258 return CMD_WARNING;
3259 }
3260
3261 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3262 strlen (argv[0]) + strlen (argv[1]) + 2);
3263
3264 sprintf (argstr, "%s %s", argv[0], argv[1]);
3265
3266 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3267
3268 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3269
3270 return ret;
3271}
3272
3273DEFUN (no_set_aggregator_as,
3274 no_set_aggregator_as_cmd,
3275 "no set aggregator as",
3276 NO_STR
3277 SET_STR
3278 "BGP aggregator attribute\n"
3279 "AS number of aggregator\n")
3280{
3281 int ret;
3282 as_t as;
3283 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003284 char *argstr;
3285
3286 if (argv == 0)
3287 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3288
paula94feb32005-05-23 13:17:29 +00003289 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paul718e3742002-12-13 20:15:29 +00003290
3291 ret = inet_aton (argv[1], &address);
3292 if (ret == 0)
3293 {
3294 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3295 return CMD_WARNING;
3296 }
3297
3298 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3299 strlen (argv[0]) + strlen (argv[1]) + 2);
3300
3301 sprintf (argstr, "%s %s", argv[0], argv[1]);
3302
3303 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3304
3305 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3306
3307 return ret;
3308}
3309
3310ALIAS (no_set_aggregator_as,
3311 no_set_aggregator_as_val_cmd,
3312 "no set aggregator as <1-65535> A.B.C.D",
3313 NO_STR
3314 SET_STR
3315 "BGP aggregator attribute\n"
3316 "AS number of aggregator\n"
3317 "AS number\n"
3318 "IP address of aggregator\n")
3319
3320
3321#ifdef HAVE_IPV6
3322DEFUN (match_ipv6_address,
3323 match_ipv6_address_cmd,
3324 "match ipv6 address WORD",
3325 MATCH_STR
3326 IPV6_STR
3327 "Match IPv6 address of route\n"
3328 "IPv6 access-list name\n")
3329{
3330 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3331}
3332
3333DEFUN (no_match_ipv6_address,
3334 no_match_ipv6_address_cmd,
3335 "no match ipv6 address WORD",
3336 NO_STR
3337 MATCH_STR
3338 IPV6_STR
3339 "Match IPv6 address of route\n"
3340 "IPv6 access-list name\n")
3341{
3342 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3343}
3344
3345DEFUN (match_ipv6_next_hop,
3346 match_ipv6_next_hop_cmd,
3347 "match ipv6 next-hop X:X::X:X",
3348 MATCH_STR
3349 IPV6_STR
3350 "Match IPv6 next-hop address of route\n"
3351 "IPv6 address of next hop\n")
3352{
3353 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3354}
3355
3356DEFUN (no_match_ipv6_next_hop,
3357 no_match_ipv6_next_hop_cmd,
3358 "no match ipv6 next-hop X:X::X:X",
3359 NO_STR
3360 MATCH_STR
3361 IPV6_STR
3362 "Match IPv6 next-hop address of route\n"
3363 "IPv6 address of next hop\n")
3364{
3365 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3366}
3367
3368DEFUN (match_ipv6_address_prefix_list,
3369 match_ipv6_address_prefix_list_cmd,
3370 "match ipv6 address prefix-list WORD",
3371 MATCH_STR
3372 IPV6_STR
3373 "Match address of route\n"
3374 "Match entries of prefix-lists\n"
3375 "IP prefix-list name\n")
3376{
3377 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3378}
3379
3380DEFUN (no_match_ipv6_address_prefix_list,
3381 no_match_ipv6_address_prefix_list_cmd,
3382 "no match ipv6 address prefix-list WORD",
3383 NO_STR
3384 MATCH_STR
3385 IPV6_STR
3386 "Match address of route\n"
3387 "Match entries of prefix-lists\n"
3388 "IP prefix-list name\n")
3389{
3390 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3391}
3392
3393DEFUN (set_ipv6_nexthop_global,
3394 set_ipv6_nexthop_global_cmd,
3395 "set ipv6 next-hop global X:X::X:X",
3396 SET_STR
3397 IPV6_STR
3398 "IPv6 next-hop address\n"
3399 "IPv6 global address\n"
3400 "IPv6 address of next hop\n")
3401{
3402 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3403}
3404
3405DEFUN (no_set_ipv6_nexthop_global,
3406 no_set_ipv6_nexthop_global_cmd,
3407 "no set ipv6 next-hop global",
3408 NO_STR
3409 SET_STR
3410 IPV6_STR
3411 "IPv6 next-hop address\n"
3412 "IPv6 global address\n")
3413{
3414 if (argc == 0)
3415 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3416
3417 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3418}
3419
3420ALIAS (no_set_ipv6_nexthop_global,
3421 no_set_ipv6_nexthop_global_val_cmd,
3422 "no set ipv6 next-hop global X:X::X:X",
3423 NO_STR
3424 SET_STR
3425 IPV6_STR
3426 "IPv6 next-hop address\n"
3427 "IPv6 global address\n"
3428 "IPv6 address of next hop\n")
3429
3430DEFUN (set_ipv6_nexthop_local,
3431 set_ipv6_nexthop_local_cmd,
3432 "set ipv6 next-hop local X:X::X:X",
3433 SET_STR
3434 IPV6_STR
3435 "IPv6 next-hop address\n"
3436 "IPv6 local address\n"
3437 "IPv6 address of next hop\n")
3438{
3439 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3440}
3441
3442DEFUN (no_set_ipv6_nexthop_local,
3443 no_set_ipv6_nexthop_local_cmd,
3444 "no set ipv6 next-hop local",
3445 NO_STR
3446 SET_STR
3447 IPV6_STR
3448 "IPv6 next-hop address\n"
3449 "IPv6 local address\n")
3450{
3451 if (argc == 0)
3452 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3453
3454 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3455}
3456
3457ALIAS (no_set_ipv6_nexthop_local,
3458 no_set_ipv6_nexthop_local_val_cmd,
3459 "no set ipv6 next-hop local X:X::X:X",
3460 NO_STR
3461 SET_STR
3462 IPV6_STR
3463 "IPv6 next-hop address\n"
3464 "IPv6 local address\n"
3465 "IPv6 address of next hop\n")
3466#endif /* HAVE_IPV6 */
3467
3468DEFUN (set_vpnv4_nexthop,
3469 set_vpnv4_nexthop_cmd,
3470 "set vpnv4 next-hop A.B.C.D",
3471 SET_STR
3472 "VPNv4 information\n"
3473 "VPNv4 next-hop address\n"
3474 "IP address of next hop\n")
3475{
3476 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3477}
3478
3479DEFUN (no_set_vpnv4_nexthop,
3480 no_set_vpnv4_nexthop_cmd,
3481 "no set vpnv4 next-hop",
3482 NO_STR
3483 SET_STR
3484 "VPNv4 information\n"
3485 "VPNv4 next-hop address\n")
3486{
3487 if (argc == 0)
3488 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3489
3490 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3491}
3492
3493ALIAS (no_set_vpnv4_nexthop,
3494 no_set_vpnv4_nexthop_val_cmd,
3495 "no set vpnv4 next-hop A.B.C.D",
3496 NO_STR
3497 SET_STR
3498 "VPNv4 information\n"
3499 "VPNv4 next-hop address\n"
3500 "IP address of next hop\n")
3501
3502DEFUN (set_originator_id,
3503 set_originator_id_cmd,
3504 "set originator-id A.B.C.D",
3505 SET_STR
3506 "BGP originator ID attribute\n"
3507 "IP address of originator\n")
3508{
3509 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3510}
3511
3512DEFUN (no_set_originator_id,
3513 no_set_originator_id_cmd,
3514 "no set originator-id",
3515 NO_STR
3516 SET_STR
3517 "BGP originator ID attribute\n")
3518{
3519 if (argc == 0)
3520 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3521
3522 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3523}
3524
3525ALIAS (no_set_originator_id,
3526 no_set_originator_id_val_cmd,
3527 "no set originator-id A.B.C.D",
3528 NO_STR
3529 SET_STR
3530 "BGP originator ID attribute\n"
3531 "IP address of originator\n")
3532
3533
3534/* Initialization of route map. */
3535void
paul94f2b392005-06-28 12:44:16 +00003536bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003537{
3538 route_map_init ();
3539 route_map_init_vty ();
3540 route_map_add_hook (bgp_route_map_update);
3541 route_map_delete_hook (bgp_route_map_update);
3542
paulfee0f4c2004-09-13 05:12:46 +00003543 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003544 route_map_install_match (&route_match_ip_address_cmd);
3545 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003546 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003547 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3548 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003549 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003550 route_map_install_match (&route_match_aspath_cmd);
3551 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003552 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003553 route_map_install_match (&route_match_metric_cmd);
3554 route_map_install_match (&route_match_origin_cmd);
3555
3556 route_map_install_set (&route_set_ip_nexthop_cmd);
3557 route_map_install_set (&route_set_local_pref_cmd);
3558 route_map_install_set (&route_set_weight_cmd);
3559 route_map_install_set (&route_set_metric_cmd);
3560 route_map_install_set (&route_set_aspath_prepend_cmd);
3561 route_map_install_set (&route_set_origin_cmd);
3562 route_map_install_set (&route_set_atomic_aggregate_cmd);
3563 route_map_install_set (&route_set_aggregator_as_cmd);
3564 route_map_install_set (&route_set_community_cmd);
3565 route_map_install_set (&route_set_community_delete_cmd);
3566 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3567 route_map_install_set (&route_set_originator_id_cmd);
3568 route_map_install_set (&route_set_ecommunity_rt_cmd);
3569 route_map_install_set (&route_set_ecommunity_soo_cmd);
3570
paulfee0f4c2004-09-13 05:12:46 +00003571 install_element (RMAP_NODE, &match_peer_cmd);
3572 install_element (RMAP_NODE, &match_peer_local_cmd);
3573 install_element (RMAP_NODE, &no_match_peer_cmd);
3574 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3575 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003576 install_element (RMAP_NODE, &match_ip_address_cmd);
3577 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3578 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3579 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3580 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3581 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003582 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3583 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3584 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003585
3586 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3587 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3588 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3589 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3590 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3591 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003592 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3593 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3594 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003595
3596 install_element (RMAP_NODE, &match_aspath_cmd);
3597 install_element (RMAP_NODE, &no_match_aspath_cmd);
3598 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3599 install_element (RMAP_NODE, &match_metric_cmd);
3600 install_element (RMAP_NODE, &no_match_metric_cmd);
3601 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3602 install_element (RMAP_NODE, &match_community_cmd);
3603 install_element (RMAP_NODE, &match_community_exact_cmd);
3604 install_element (RMAP_NODE, &no_match_community_cmd);
3605 install_element (RMAP_NODE, &no_match_community_val_cmd);
3606 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003607 install_element (RMAP_NODE, &match_ecommunity_cmd);
3608 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3609 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003610 install_element (RMAP_NODE, &match_origin_cmd);
3611 install_element (RMAP_NODE, &no_match_origin_cmd);
3612 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3613
3614 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003615 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003616 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3617 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3618 install_element (RMAP_NODE, &set_local_pref_cmd);
3619 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3620 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3621 install_element (RMAP_NODE, &set_weight_cmd);
3622 install_element (RMAP_NODE, &no_set_weight_cmd);
3623 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3624 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003625 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003626 install_element (RMAP_NODE, &no_set_metric_cmd);
3627 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3628 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3629 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3630 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3631 install_element (RMAP_NODE, &set_origin_cmd);
3632 install_element (RMAP_NODE, &no_set_origin_cmd);
3633 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3634 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3635 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3636 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3637 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3638 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3639 install_element (RMAP_NODE, &set_community_cmd);
3640 install_element (RMAP_NODE, &set_community_none_cmd);
3641 install_element (RMAP_NODE, &no_set_community_cmd);
3642 install_element (RMAP_NODE, &no_set_community_val_cmd);
3643 install_element (RMAP_NODE, &no_set_community_none_cmd);
3644 install_element (RMAP_NODE, &set_community_delete_cmd);
3645 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3646 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3647 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3648 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3649 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3650 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3651 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3652 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3653 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3654 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3655 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3656 install_element (RMAP_NODE, &set_originator_id_cmd);
3657 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3658 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3659
3660#ifdef HAVE_IPV6
3661 route_map_install_match (&route_match_ipv6_address_cmd);
3662 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3663 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3664 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3665 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3666
3667 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3668 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3669 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3670 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3671 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3672 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3673 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3674 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3675 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3676 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3677 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3678 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3679#endif /* HAVE_IPV6 */
3680}