blob: 806a50727ebd0a8643f2a76fc9191df5f4764a49 [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;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001198
paul718e3742002-12-13 20:15:29 +00001199 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);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001218
1219 /* HACK: if the old community is not intern'd,
1220 * we should free it here, or all reference to it may be lost.
1221 * Really need to cleanup attribute caching sometime.
1222 */
1223 if (old->refcnt == 0)
1224 community_free (old);
paul718e3742002-12-13 20:15:29 +00001225 new = community_uniq_sort (merge);
1226 community_free (merge);
1227 }
1228 else
1229 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001230
1231 /* will be interned by caller if required */
paul718e3742002-12-13 20:15:29 +00001232 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001233
paul718e3742002-12-13 20:15:29 +00001234 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1235 }
1236
1237 return RMAP_OKAY;
1238}
1239
1240/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001241static void *
paulfd79ac92004-10-13 05:06:08 +00001242route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001243{
1244 struct rmap_com_set *rcs;
1245 struct community *com = NULL;
1246 char *sp;
1247 int additive = 0;
1248 int none = 0;
1249
1250 if (strcmp (arg, "none") == 0)
1251 none = 1;
1252 else
1253 {
1254 sp = strstr (arg, "additive");
1255
1256 if (sp && sp > arg)
1257 {
1258 /* "additive" keyworkd is included. */
1259 additive = 1;
1260 *(sp - 1) = '\0';
1261 }
1262
1263 com = community_str2com (arg);
1264
1265 if (additive)
1266 *(sp - 1) = ' ';
1267
1268 if (! com)
1269 return NULL;
1270 }
1271
1272 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1273 memset (rcs, 0, sizeof (struct rmap_com_set));
1274
1275 rcs->com = com;
1276 rcs->additive = additive;
1277 rcs->none = none;
1278
1279 return rcs;
1280}
1281
1282/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001283static void
paul718e3742002-12-13 20:15:29 +00001284route_set_community_free (void *rule)
1285{
1286 struct rmap_com_set *rcs = rule;
1287
1288 if (rcs->com)
1289 community_free (rcs->com);
1290 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1291}
1292
1293/* Set community rule structure. */
1294struct route_map_rule_cmd route_set_community_cmd =
1295{
1296 "community",
1297 route_set_community,
1298 route_set_community_compile,
1299 route_set_community_free,
1300};
1301
hassofee6e4e2005-02-02 16:29:31 +00001302/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001303
1304/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001305static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001306route_set_community_delete (void *rule, struct prefix *prefix,
1307 route_map_object_t type, void *object)
1308{
1309 struct community_list *list;
1310 struct community *merge;
1311 struct community *new;
1312 struct community *old;
1313 struct bgp_info *binfo;
1314
1315 if (type == RMAP_BGP)
1316 {
1317 if (! rule)
1318 return RMAP_OKAY;
1319
1320 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001321 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001322 old = binfo->attr->community;
1323
1324 if (list && old)
1325 {
1326 merge = community_list_match_delete (community_dup (old), list);
1327 new = community_uniq_sort (merge);
1328 community_free (merge);
1329
1330 if (new->size == 0)
1331 {
1332 binfo->attr->community = NULL;
1333 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1334 community_free (new);
1335 }
1336 else
1337 {
1338 binfo->attr->community = new;
1339 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1340 }
1341 }
1342 }
1343
1344 return RMAP_OKAY;
1345}
1346
1347/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001348static void *
paulfd79ac92004-10-13 05:06:08 +00001349route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001350{
1351 char *p;
1352 char *str;
1353 int len;
1354
1355 p = strchr (arg, ' ');
1356 if (p)
1357 {
1358 len = p - arg;
1359 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1360 memcpy (str, arg, len);
1361 }
1362 else
1363 str = NULL;
1364
1365 return str;
1366}
1367
1368/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001369static void
paul718e3742002-12-13 20:15:29 +00001370route_set_community_delete_free (void *rule)
1371{
1372 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1373}
1374
1375/* Set community rule structure. */
1376struct route_map_rule_cmd route_set_community_delete_cmd =
1377{
1378 "comm-list",
1379 route_set_community_delete,
1380 route_set_community_delete_compile,
1381 route_set_community_delete_free,
1382};
1383
1384/* `set extcommunity rt COMMUNITY' */
1385
1386/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001387static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001388route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1389 route_map_object_t type, void *object)
1390{
1391 struct ecommunity *ecom;
1392 struct ecommunity *new_ecom;
1393 struct ecommunity *old_ecom;
1394 struct bgp_info *bgp_info;
1395
1396 if (type == RMAP_BGP)
1397 {
1398 ecom = rule;
1399 bgp_info = object;
1400
1401 if (! ecom)
1402 return RMAP_OKAY;
1403
1404 /* We assume additive for Extended Community. */
1405 old_ecom = bgp_info->attr->ecommunity;
1406
1407 if (old_ecom)
1408 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1409 else
1410 new_ecom = ecommunity_dup (ecom);
1411
1412 bgp_info->attr->ecommunity = new_ecom;
1413
hasso70601e02005-05-27 03:26:57 +00001414 if (old_ecom)
1415 ecommunity_free (old_ecom);
1416
paul718e3742002-12-13 20:15:29 +00001417 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1418 }
1419 return RMAP_OKAY;
1420}
1421
1422/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001423static void *
paulfd79ac92004-10-13 05:06:08 +00001424route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001425{
1426 struct ecommunity *ecom;
1427
1428 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1429 if (! ecom)
1430 return NULL;
1431 return ecom;
1432}
1433
1434/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001435static void
paul718e3742002-12-13 20:15:29 +00001436route_set_ecommunity_rt_free (void *rule)
1437{
1438 struct ecommunity *ecom = rule;
1439 ecommunity_free (ecom);
1440}
1441
1442/* Set community rule structure. */
1443struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1444{
1445 "extcommunity rt",
1446 route_set_ecommunity_rt,
1447 route_set_ecommunity_rt_compile,
1448 route_set_ecommunity_rt_free,
1449};
1450
1451/* `set extcommunity soo COMMUNITY' */
1452
1453/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001454static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001455route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1456 route_map_object_t type, void *object)
1457{
1458 struct ecommunity *ecom;
1459 struct bgp_info *bgp_info;
1460
1461 if (type == RMAP_BGP)
1462 {
1463 ecom = rule;
1464 bgp_info = object;
1465
1466 if (! ecom)
1467 return RMAP_OKAY;
1468
1469 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1470 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1471 }
1472 return RMAP_OKAY;
1473}
1474
1475/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001476static void *
paulfd79ac92004-10-13 05:06:08 +00001477route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001478{
1479 struct ecommunity *ecom;
1480
1481 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1482 if (! ecom)
1483 return NULL;
1484
1485 return ecom;
1486}
1487
1488/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001489static void
paul718e3742002-12-13 20:15:29 +00001490route_set_ecommunity_soo_free (void *rule)
1491{
1492 struct ecommunity *ecom = rule;
1493 ecommunity_free (ecom);
1494}
1495
1496/* Set community rule structure. */
1497struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1498{
1499 "extcommunity soo",
1500 route_set_ecommunity_soo,
1501 route_set_ecommunity_soo_compile,
1502 route_set_ecommunity_soo_free,
1503};
1504
1505/* `set origin ORIGIN' */
1506
1507/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001508static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001509route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1510{
1511 u_char *origin;
1512 struct bgp_info *bgp_info;
1513
1514 if (type == RMAP_BGP)
1515 {
1516 origin = rule;
1517 bgp_info = object;
1518
1519 bgp_info->attr->origin = *origin;
1520 }
1521
1522 return RMAP_OKAY;
1523}
1524
1525/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001526static void *
paulfd79ac92004-10-13 05:06:08 +00001527route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001528{
1529 u_char *origin;
1530
1531 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1532
1533 if (strcmp (arg, "igp") == 0)
1534 *origin = 0;
1535 else if (strcmp (arg, "egp") == 0)
1536 *origin = 1;
1537 else
1538 *origin = 2;
1539
1540 return origin;
1541}
1542
1543/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001544static void
paul718e3742002-12-13 20:15:29 +00001545route_set_origin_free (void *rule)
1546{
1547 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1548}
1549
1550/* Set metric rule structure. */
1551struct route_map_rule_cmd route_set_origin_cmd =
1552{
1553 "origin",
1554 route_set_origin,
1555 route_set_origin_compile,
1556 route_set_origin_free,
1557};
1558
1559/* `set atomic-aggregate' */
1560
1561/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001562static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001563route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1564 route_map_object_t type, void *object)
1565{
1566 struct bgp_info *bgp_info;
1567
1568 if (type == RMAP_BGP)
1569 {
1570 bgp_info = object;
1571 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1572 }
1573
1574 return RMAP_OKAY;
1575}
1576
1577/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001578static void *
paulfd79ac92004-10-13 05:06:08 +00001579route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001580{
1581 return (void *)1;
1582}
1583
1584/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001585static void
paul718e3742002-12-13 20:15:29 +00001586route_set_atomic_aggregate_free (void *rule)
1587{
1588 return;
1589}
1590
1591/* Set atomic aggregate rule structure. */
1592struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1593{
1594 "atomic-aggregate",
1595 route_set_atomic_aggregate,
1596 route_set_atomic_aggregate_compile,
1597 route_set_atomic_aggregate_free,
1598};
1599
1600/* `set aggregator as AS A.B.C.D' */
1601struct aggregator
1602{
1603 as_t as;
1604 struct in_addr address;
1605};
1606
paul94f2b392005-06-28 12:44:16 +00001607static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001608route_set_aggregator_as (void *rule, struct prefix *prefix,
1609 route_map_object_t type, void *object)
1610{
1611 struct bgp_info *bgp_info;
1612 struct aggregator *aggregator;
1613
1614 if (type == RMAP_BGP)
1615 {
1616 bgp_info = object;
1617 aggregator = rule;
1618
1619 bgp_info->attr->aggregator_as = aggregator->as;
1620 bgp_info->attr->aggregator_addr = aggregator->address;
1621 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1622 }
1623
1624 return RMAP_OKAY;
1625}
1626
paul94f2b392005-06-28 12:44:16 +00001627static void *
paulfd79ac92004-10-13 05:06:08 +00001628route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001629{
1630 struct aggregator *aggregator;
1631 char as[10];
1632 char address[20];
1633
1634 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1635 memset (aggregator, 0, sizeof (struct aggregator));
1636
1637 sscanf (arg, "%s %s", as, address);
1638
1639 aggregator->as = strtoul (as, NULL, 10);
1640 inet_aton (address, &aggregator->address);
1641
1642 return aggregator;
1643}
1644
paul94f2b392005-06-28 12:44:16 +00001645static void
paul718e3742002-12-13 20:15:29 +00001646route_set_aggregator_as_free (void *rule)
1647{
1648 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1649}
1650
1651struct route_map_rule_cmd route_set_aggregator_as_cmd =
1652{
1653 "aggregator as",
1654 route_set_aggregator_as,
1655 route_set_aggregator_as_compile,
1656 route_set_aggregator_as_free,
1657};
1658
1659#ifdef HAVE_IPV6
1660/* `match ipv6 address IP_ACCESS_LIST' */
1661
paul94f2b392005-06-28 12:44:16 +00001662static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001663route_match_ipv6_address (void *rule, struct prefix *prefix,
1664 route_map_object_t type, void *object)
1665{
1666 struct access_list *alist;
1667
1668 if (type == RMAP_BGP)
1669 {
1670 alist = access_list_lookup (AFI_IP6, (char *) rule);
1671 if (alist == NULL)
1672 return RMAP_NOMATCH;
1673
1674 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1675 RMAP_NOMATCH : RMAP_MATCH);
1676 }
1677 return RMAP_NOMATCH;
1678}
1679
paul94f2b392005-06-28 12:44:16 +00001680static void *
paulfd79ac92004-10-13 05:06:08 +00001681route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001682{
1683 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1684}
1685
paul94f2b392005-06-28 12:44:16 +00001686static void
paul718e3742002-12-13 20:15:29 +00001687route_match_ipv6_address_free (void *rule)
1688{
1689 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1690}
1691
1692/* Route map commands for ip address matching. */
1693struct route_map_rule_cmd route_match_ipv6_address_cmd =
1694{
1695 "ipv6 address",
1696 route_match_ipv6_address,
1697 route_match_ipv6_address_compile,
1698 route_match_ipv6_address_free
1699};
1700
1701/* `match ipv6 next-hop IP_ADDRESS' */
1702
paul94f2b392005-06-28 12:44:16 +00001703static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001704route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1705 route_map_object_t type, void *object)
1706{
1707 struct in6_addr *addr;
1708 struct bgp_info *bgp_info;
1709
1710 if (type == RMAP_BGP)
1711 {
1712 addr = rule;
1713 bgp_info = object;
1714
1715 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1716 return RMAP_MATCH;
1717
1718 if (bgp_info->attr->mp_nexthop_len == 32 &&
1719 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1720 return RMAP_MATCH;
1721
1722 return RMAP_NOMATCH;
1723 }
1724
1725 return RMAP_NOMATCH;
1726}
1727
paul94f2b392005-06-28 12:44:16 +00001728static void *
paulfd79ac92004-10-13 05:06:08 +00001729route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001730{
1731 struct in6_addr *address;
1732 int ret;
1733
1734 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1735
1736 ret = inet_pton (AF_INET6, arg, address);
1737 if (!ret)
1738 {
1739 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1740 return NULL;
1741 }
1742
1743 return address;
1744}
1745
paul94f2b392005-06-28 12:44:16 +00001746static void
paul718e3742002-12-13 20:15:29 +00001747route_match_ipv6_next_hop_free (void *rule)
1748{
1749 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1750}
1751
1752struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1753{
1754 "ipv6 next-hop",
1755 route_match_ipv6_next_hop,
1756 route_match_ipv6_next_hop_compile,
1757 route_match_ipv6_next_hop_free
1758};
1759
1760/* `match ipv6 address prefix-list PREFIX_LIST' */
1761
paul94f2b392005-06-28 12:44:16 +00001762static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001763route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1764 route_map_object_t type, void *object)
1765{
1766 struct prefix_list *plist;
1767
1768 if (type == RMAP_BGP)
1769 {
1770 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1771 if (plist == NULL)
1772 return RMAP_NOMATCH;
1773
1774 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1775 RMAP_NOMATCH : RMAP_MATCH);
1776 }
1777 return RMAP_NOMATCH;
1778}
1779
paul94f2b392005-06-28 12:44:16 +00001780static void *
paulfd79ac92004-10-13 05:06:08 +00001781route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001782{
1783 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1784}
1785
paul94f2b392005-06-28 12:44:16 +00001786static void
paul718e3742002-12-13 20:15:29 +00001787route_match_ipv6_address_prefix_list_free (void *rule)
1788{
1789 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1790}
1791
1792struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1793{
1794 "ipv6 address prefix-list",
1795 route_match_ipv6_address_prefix_list,
1796 route_match_ipv6_address_prefix_list_compile,
1797 route_match_ipv6_address_prefix_list_free
1798};
1799
1800/* `set ipv6 nexthop global IP_ADDRESS' */
1801
1802/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001803static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001804route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1805 route_map_object_t type, void *object)
1806{
1807 struct in6_addr *address;
1808 struct bgp_info *bgp_info;
1809
1810 if (type == RMAP_BGP)
1811 {
1812 /* Fetch routemap's rule information. */
1813 address = rule;
1814 bgp_info = object;
1815
1816 /* Set next hop value. */
1817 bgp_info->attr->mp_nexthop_global = *address;
1818
1819 /* Set nexthop length. */
1820 if (bgp_info->attr->mp_nexthop_len == 0)
1821 bgp_info->attr->mp_nexthop_len = 16;
1822 }
1823
1824 return RMAP_OKAY;
1825}
1826
1827/* Route map `ip next-hop' compile function. Given string is converted
1828 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001829static void *
paulfd79ac92004-10-13 05:06:08 +00001830route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001831{
1832 int ret;
1833 struct in6_addr *address;
1834
1835 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1836
1837 ret = inet_pton (AF_INET6, arg, address);
1838
1839 if (ret == 0)
1840 {
1841 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1842 return NULL;
1843 }
1844
1845 return address;
1846}
1847
1848/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001849static void
paul718e3742002-12-13 20:15:29 +00001850route_set_ipv6_nexthop_global_free (void *rule)
1851{
1852 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1853}
1854
1855/* Route map commands for ip nexthop set. */
1856struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1857{
1858 "ipv6 next-hop global",
1859 route_set_ipv6_nexthop_global,
1860 route_set_ipv6_nexthop_global_compile,
1861 route_set_ipv6_nexthop_global_free
1862};
1863
1864/* `set ipv6 nexthop local IP_ADDRESS' */
1865
1866/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001867static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001868route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1869 route_map_object_t type, void *object)
1870{
1871 struct in6_addr *address;
1872 struct bgp_info *bgp_info;
1873
1874 if (type == RMAP_BGP)
1875 {
1876 /* Fetch routemap's rule information. */
1877 address = rule;
1878 bgp_info = object;
1879
1880 /* Set next hop value. */
1881 bgp_info->attr->mp_nexthop_local = *address;
1882
1883 /* Set nexthop length. */
1884 if (bgp_info->attr->mp_nexthop_len != 32)
1885 bgp_info->attr->mp_nexthop_len = 32;
1886 }
1887
1888 return RMAP_OKAY;
1889}
1890
1891/* Route map `ip nexthop' compile function. Given string is converted
1892 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001893static void *
paulfd79ac92004-10-13 05:06:08 +00001894route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001895{
1896 int ret;
1897 struct in6_addr *address;
1898
1899 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1900
1901 ret = inet_pton (AF_INET6, arg, address);
1902
1903 if (ret == 0)
1904 {
1905 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1906 return NULL;
1907 }
1908
1909 return address;
1910}
1911
1912/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001913static void
paul718e3742002-12-13 20:15:29 +00001914route_set_ipv6_nexthop_local_free (void *rule)
1915{
1916 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1917}
1918
1919/* Route map commands for ip nexthop set. */
1920struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1921{
1922 "ipv6 next-hop local",
1923 route_set_ipv6_nexthop_local,
1924 route_set_ipv6_nexthop_local_compile,
1925 route_set_ipv6_nexthop_local_free
1926};
1927#endif /* HAVE_IPV6 */
1928
1929/* `set vpnv4 nexthop A.B.C.D' */
1930
paul94f2b392005-06-28 12:44:16 +00001931static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001932route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1933 route_map_object_t type, void *object)
1934{
1935 struct in_addr *address;
1936 struct bgp_info *bgp_info;
1937
1938 if (type == RMAP_BGP)
1939 {
1940 /* Fetch routemap's rule information. */
1941 address = rule;
1942 bgp_info = object;
1943
1944 /* Set next hop value. */
1945 bgp_info->attr->mp_nexthop_global_in = *address;
1946 }
1947
1948 return RMAP_OKAY;
1949}
1950
paul94f2b392005-06-28 12:44:16 +00001951static void *
paulfd79ac92004-10-13 05:06:08 +00001952route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001953{
1954 int ret;
1955 struct in_addr *address;
1956
1957 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1958
1959 ret = inet_aton (arg, address);
1960
1961 if (ret == 0)
1962 {
1963 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1964 return NULL;
1965 }
1966
1967 return address;
1968}
1969
paul94f2b392005-06-28 12:44:16 +00001970static void
paul718e3742002-12-13 20:15:29 +00001971route_set_vpnv4_nexthop_free (void *rule)
1972{
1973 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1974}
1975
1976/* Route map commands for ip nexthop set. */
1977struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1978{
1979 "vpnv4 next-hop",
1980 route_set_vpnv4_nexthop,
1981 route_set_vpnv4_nexthop_compile,
1982 route_set_vpnv4_nexthop_free
1983};
1984
1985/* `set originator-id' */
1986
1987/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001988static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001989route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1990{
1991 struct in_addr *address;
1992 struct bgp_info *bgp_info;
1993
1994 if (type == RMAP_BGP)
1995 {
1996 address = rule;
1997 bgp_info = object;
1998
1999 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
2000 bgp_info->attr->originator_id = *address;
2001 }
2002
2003 return RMAP_OKAY;
2004}
2005
2006/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002007static void *
paulfd79ac92004-10-13 05:06:08 +00002008route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002009{
2010 int ret;
2011 struct in_addr *address;
2012
2013 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2014
2015 ret = inet_aton (arg, address);
2016
2017 if (ret == 0)
2018 {
2019 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2020 return NULL;
2021 }
2022
2023 return address;
2024}
2025
2026/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002027static void
paul718e3742002-12-13 20:15:29 +00002028route_set_originator_id_free (void *rule)
2029{
2030 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2031}
2032
2033/* Set metric rule structure. */
2034struct route_map_rule_cmd route_set_originator_id_cmd =
2035{
2036 "originator-id",
2037 route_set_originator_id,
2038 route_set_originator_id_compile,
2039 route_set_originator_id_free,
2040};
2041
2042/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002043static int
paul718e3742002-12-13 20:15:29 +00002044bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002045 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002046{
2047 int ret;
2048
2049 ret = route_map_add_match (index, command, arg);
2050 if (ret)
2051 {
2052 switch (ret)
2053 {
2054 case RMAP_RULE_MISSING:
2055 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2056 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002057 case RMAP_COMPILE_ERROR:
2058 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2059 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002060 }
2061 }
2062 return CMD_SUCCESS;
2063}
2064
2065/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002066static int
paul718e3742002-12-13 20:15:29 +00002067bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002068 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002069{
2070 int ret;
2071
2072 ret = route_map_delete_match (index, command, arg);
2073 if (ret)
2074 {
2075 switch (ret)
2076 {
2077 case RMAP_RULE_MISSING:
2078 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2079 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002080 case RMAP_COMPILE_ERROR:
2081 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2082 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002083 }
2084 }
2085 return CMD_SUCCESS;
2086}
2087
2088/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002089static int
paul718e3742002-12-13 20:15:29 +00002090bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002091 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002092{
2093 int ret;
2094
2095 ret = route_map_add_set (index, command, arg);
2096 if (ret)
2097 {
2098 switch (ret)
2099 {
2100 case RMAP_RULE_MISSING:
2101 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2102 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002103 case RMAP_COMPILE_ERROR:
2104 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2105 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002106 }
2107 }
2108 return CMD_SUCCESS;
2109}
2110
2111/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002112static int
paul718e3742002-12-13 20:15:29 +00002113bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002114 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002115{
2116 int ret;
2117
2118 ret = route_map_delete_set (index, command, arg);
2119 if (ret)
2120 {
2121 switch (ret)
2122 {
2123 case RMAP_RULE_MISSING:
2124 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2125 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002126 case RMAP_COMPILE_ERROR:
2127 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2128 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002129 }
2130 }
2131 return CMD_SUCCESS;
2132}
2133
2134/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002135static void
paulfd79ac92004-10-13 05:06:08 +00002136bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002137{
2138 int i;
2139 afi_t afi;
2140 safi_t safi;
2141 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002142 struct listnode *node, *nnode;
2143 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002144 struct bgp *bgp;
2145 struct peer *peer;
2146 struct peer_group *group;
2147 struct bgp_filter *filter;
2148 struct bgp_node *bn;
2149 struct bgp_static *bgp_static;
2150
2151 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002152 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002153 {
paul1eb8ef22005-04-07 07:30:20 +00002154 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002155 {
2156 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2157 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2158 {
2159 filter = &peer->filter[afi][safi];
2160
paulfee0f4c2004-09-13 05:12:46 +00002161 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002162 {
2163 if (filter->map[direct].name)
2164 filter->map[direct].map =
2165 route_map_lookup_by_name (filter->map[direct].name);
2166 else
2167 filter->map[direct].map = NULL;
2168 }
2169
2170 if (filter->usmap.name)
2171 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2172 else
2173 filter->usmap.map = NULL;
2174 }
2175 }
paul1eb8ef22005-04-07 07:30:20 +00002176 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002177 {
2178 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2179 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2180 {
2181 filter = &group->conf->filter[afi][safi];
2182
paulfee0f4c2004-09-13 05:12:46 +00002183 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002184 {
2185 if (filter->map[direct].name)
2186 filter->map[direct].map =
2187 route_map_lookup_by_name (filter->map[direct].name);
2188 else
2189 filter->map[direct].map = NULL;
2190 }
2191
2192 if (filter->usmap.name)
2193 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2194 else
2195 filter->usmap.map = NULL;
2196 }
2197 }
2198 }
2199
2200 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002201 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002202 {
paul1eb8ef22005-04-07 07:30:20 +00002203 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002204 {
2205 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2206 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2207 {
2208 if (peer->default_rmap[afi][safi].name)
2209 peer->default_rmap[afi][safi].map =
2210 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2211 else
2212 peer->default_rmap[afi][safi].map = NULL;
2213 }
2214 }
2215 }
2216
2217 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002218 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002219 {
2220 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2221 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2222 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2223 bn = bgp_route_next (bn))
2224 if ((bgp_static = bn->info) != NULL)
2225 {
2226 if (bgp_static->rmap.name)
2227 bgp_static->rmap.map =
2228 route_map_lookup_by_name (bgp_static->rmap.name);
2229 else
2230 bgp_static->rmap.map = NULL;
2231 }
2232 }
2233
2234 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002235 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002236 {
2237 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2238 {
2239 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2240 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2241 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2242#ifdef HAVE_IPV6
2243 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2244 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2245 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2246#endif /* HAVE_IPV6 */
2247 }
2248 }
2249}
2250
paulfee0f4c2004-09-13 05:12:46 +00002251DEFUN (match_peer,
2252 match_peer_cmd,
2253 "match peer (A.B.C.D|X:X::X:X)",
2254 MATCH_STR
2255 "Match peer address\n"
2256 "IPv6 address of peer\n"
2257 "IP address of peer\n")
2258{
2259 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2260}
2261
2262DEFUN (match_peer_local,
2263 match_peer_local_cmd,
2264 "match peer local",
2265 MATCH_STR
2266 "Match peer address\n"
2267 "Static or Redistributed routes\n")
2268{
2269 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2270}
2271
2272DEFUN (no_match_peer,
2273 no_match_peer_cmd,
2274 "no match peer",
2275 NO_STR
2276 MATCH_STR
2277 "Match peer address\n")
2278{
2279 if (argc == 0)
2280 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2281
2282 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2283}
2284
2285ALIAS (no_match_peer,
2286 no_match_peer_val_cmd,
2287 "no match peer (A.B.C.D|X:X::X:X)",
2288 NO_STR
2289 MATCH_STR
2290 "Match peer address\n"
2291 "IPv6 address of peer\n"
2292 "IP address of peer\n")
2293
2294ALIAS (no_match_peer,
2295 no_match_peer_local_cmd,
2296 "no match peer local",
2297 NO_STR
2298 MATCH_STR
2299 "Match peer address\n"
2300 "Static or Redistributed routes\n")
2301
paul718e3742002-12-13 20:15:29 +00002302DEFUN (match_ip_address,
2303 match_ip_address_cmd,
2304 "match ip address (<1-199>|<1300-2699>|WORD)",
2305 MATCH_STR
2306 IP_STR
2307 "Match address of route\n"
2308 "IP access-list number\n"
2309 "IP access-list number (expanded range)\n"
2310 "IP Access-list name\n")
2311{
2312 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2313}
2314
2315DEFUN (no_match_ip_address,
2316 no_match_ip_address_cmd,
2317 "no match ip address",
2318 NO_STR
2319 MATCH_STR
2320 IP_STR
2321 "Match address of route\n")
2322{
2323 if (argc == 0)
2324 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2325
2326 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2327}
2328
2329ALIAS (no_match_ip_address,
2330 no_match_ip_address_val_cmd,
2331 "no match ip address (<1-199>|<1300-2699>|WORD)",
2332 NO_STR
2333 MATCH_STR
2334 IP_STR
2335 "Match address of route\n"
2336 "IP access-list number\n"
2337 "IP access-list number (expanded range)\n"
2338 "IP Access-list name\n")
2339
2340DEFUN (match_ip_next_hop,
2341 match_ip_next_hop_cmd,
2342 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2343 MATCH_STR
2344 IP_STR
2345 "Match next-hop address of route\n"
2346 "IP access-list number\n"
2347 "IP access-list number (expanded range)\n"
2348 "IP Access-list name\n")
2349{
2350 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2351}
2352
2353DEFUN (no_match_ip_next_hop,
2354 no_match_ip_next_hop_cmd,
2355 "no match ip next-hop",
2356 NO_STR
2357 MATCH_STR
2358 IP_STR
2359 "Match next-hop address of route\n")
2360{
2361 if (argc == 0)
2362 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2363
2364 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2365}
2366
2367ALIAS (no_match_ip_next_hop,
2368 no_match_ip_next_hop_val_cmd,
2369 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2370 NO_STR
2371 MATCH_STR
2372 IP_STR
2373 "Match next-hop address of route\n"
2374 "IP access-list number\n"
2375 "IP access-list number (expanded range)\n"
2376 "IP Access-list name\n")
2377
hassoc1643bb2005-02-02 16:43:17 +00002378DEFUN (match_ip_route_source,
2379 match_ip_route_source_cmd,
2380 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2381 MATCH_STR
2382 IP_STR
2383 "Match advertising source address of route\n"
2384 "IP access-list number\n"
2385 "IP access-list number (expanded range)\n"
2386 "IP standard access-list name\n")
2387{
2388 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2389}
2390
2391DEFUN (no_match_ip_route_source,
2392 no_match_ip_route_source_cmd,
2393 "no match ip route-source",
2394 NO_STR
2395 MATCH_STR
2396 IP_STR
2397 "Match advertising source address of route\n")
2398{
2399 if (argc == 0)
2400 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2401
2402 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2403}
2404
2405ALIAS (no_match_ip_route_source,
2406 no_match_ip_route_source_val_cmd,
2407 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2408 NO_STR
2409 MATCH_STR
2410 IP_STR
2411 "Match advertising source address of route\n"
2412 "IP access-list number\n"
2413 "IP access-list number (expanded range)\n"
2414 "IP standard access-list name\n");
2415
paul718e3742002-12-13 20:15:29 +00002416DEFUN (match_ip_address_prefix_list,
2417 match_ip_address_prefix_list_cmd,
2418 "match ip address prefix-list WORD",
2419 MATCH_STR
2420 IP_STR
2421 "Match address of route\n"
2422 "Match entries of prefix-lists\n"
2423 "IP prefix-list name\n")
2424{
2425 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2426}
2427
2428DEFUN (no_match_ip_address_prefix_list,
2429 no_match_ip_address_prefix_list_cmd,
2430 "no match ip address prefix-list",
2431 NO_STR
2432 MATCH_STR
2433 IP_STR
2434 "Match address of route\n"
2435 "Match entries of prefix-lists\n")
2436{
2437 if (argc == 0)
2438 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2439
2440 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2441}
2442
2443ALIAS (no_match_ip_address_prefix_list,
2444 no_match_ip_address_prefix_list_val_cmd,
2445 "no match ip address prefix-list WORD",
2446 NO_STR
2447 MATCH_STR
2448 IP_STR
2449 "Match address of route\n"
2450 "Match entries of prefix-lists\n"
2451 "IP prefix-list name\n")
2452
2453DEFUN (match_ip_next_hop_prefix_list,
2454 match_ip_next_hop_prefix_list_cmd,
2455 "match ip next-hop prefix-list WORD",
2456 MATCH_STR
2457 IP_STR
2458 "Match next-hop address of route\n"
2459 "Match entries of prefix-lists\n"
2460 "IP prefix-list name\n")
2461{
2462 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2463}
2464
2465DEFUN (no_match_ip_next_hop_prefix_list,
2466 no_match_ip_next_hop_prefix_list_cmd,
2467 "no match ip next-hop prefix-list",
2468 NO_STR
2469 MATCH_STR
2470 IP_STR
2471 "Match next-hop address of route\n"
2472 "Match entries of prefix-lists\n")
2473{
2474 if (argc == 0)
2475 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2476
2477 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2478}
2479
2480ALIAS (no_match_ip_next_hop_prefix_list,
2481 no_match_ip_next_hop_prefix_list_val_cmd,
2482 "no match ip next-hop prefix-list WORD",
2483 NO_STR
2484 MATCH_STR
2485 IP_STR
2486 "Match next-hop address of route\n"
2487 "Match entries of prefix-lists\n"
2488 "IP prefix-list name\n")
2489
hassoc1643bb2005-02-02 16:43:17 +00002490DEFUN (match_ip_route_source_prefix_list,
2491 match_ip_route_source_prefix_list_cmd,
2492 "match ip route-source prefix-list WORD",
2493 MATCH_STR
2494 IP_STR
2495 "Match advertising source address of route\n"
2496 "Match entries of prefix-lists\n"
2497 "IP prefix-list name\n")
2498{
2499 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2500}
2501
2502DEFUN (no_match_ip_route_source_prefix_list,
2503 no_match_ip_route_source_prefix_list_cmd,
2504 "no match ip route-source prefix-list",
2505 NO_STR
2506 MATCH_STR
2507 IP_STR
2508 "Match advertising source address of route\n"
2509 "Match entries of prefix-lists\n")
2510{
2511 if (argc == 0)
2512 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2513
2514 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2515}
2516
2517ALIAS (no_match_ip_route_source_prefix_list,
2518 no_match_ip_route_source_prefix_list_val_cmd,
2519 "no match ip route-source prefix-list WORD",
2520 NO_STR
2521 MATCH_STR
2522 IP_STR
2523 "Match advertising source address of route\n"
2524 "Match entries of prefix-lists\n"
2525 "IP prefix-list name\n");
2526
paul718e3742002-12-13 20:15:29 +00002527DEFUN (match_metric,
2528 match_metric_cmd,
2529 "match metric <0-4294967295>",
2530 MATCH_STR
2531 "Match metric of route\n"
2532 "Metric value\n")
2533{
2534 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2535}
2536
2537DEFUN (no_match_metric,
2538 no_match_metric_cmd,
2539 "no match metric",
2540 NO_STR
2541 MATCH_STR
2542 "Match metric of route\n")
2543{
2544 if (argc == 0)
2545 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2546
2547 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2548}
2549
2550ALIAS (no_match_metric,
2551 no_match_metric_val_cmd,
2552 "no match metric <0-4294967295>",
2553 NO_STR
2554 MATCH_STR
2555 "Match metric of route\n"
2556 "Metric value\n")
2557
2558DEFUN (match_community,
2559 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002560 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002561 MATCH_STR
2562 "Match BGP community list\n"
2563 "Community-list number (standard)\n"
2564 "Community-list number (expanded)\n"
2565 "Community-list name\n")
2566{
2567 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2568}
2569
2570DEFUN (match_community_exact,
2571 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002572 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002573 MATCH_STR
2574 "Match BGP community list\n"
2575 "Community-list number (standard)\n"
2576 "Community-list number (expanded)\n"
2577 "Community-list name\n"
2578 "Do exact matching of communities\n")
2579{
2580 int ret;
2581 char *argstr;
2582
2583 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2584 strlen (argv[0]) + strlen ("exact-match") + 2);
2585
2586 sprintf (argstr, "%s exact-match", argv[0]);
2587
2588 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2589
2590 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2591
2592 return ret;
2593}
2594
2595DEFUN (no_match_community,
2596 no_match_community_cmd,
2597 "no match community",
2598 NO_STR
2599 MATCH_STR
2600 "Match BGP community list\n")
2601{
2602 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2603}
2604
2605ALIAS (no_match_community,
2606 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002607 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002608 NO_STR
2609 MATCH_STR
2610 "Match BGP community list\n"
2611 "Community-list number (standard)\n"
2612 "Community-list number (expanded)\n"
2613 "Community-list name\n")
2614
2615ALIAS (no_match_community,
2616 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002617 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002618 NO_STR
2619 MATCH_STR
2620 "Match BGP community list\n"
2621 "Community-list number (standard)\n"
2622 "Community-list number (expanded)\n"
2623 "Community-list name\n"
2624 "Do exact matching of communities\n")
2625
paul73ffb252003-04-19 15:49:49 +00002626DEFUN (match_ecommunity,
2627 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002628 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002629 MATCH_STR
2630 "Match BGP/VPN extended community list\n"
2631 "Extended community-list number (standard)\n"
2632 "Extended community-list number (expanded)\n"
2633 "Extended community-list name\n")
2634{
2635 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2636}
2637
2638DEFUN (no_match_ecommunity,
2639 no_match_ecommunity_cmd,
2640 "no match extcommunity",
2641 NO_STR
2642 MATCH_STR
2643 "Match BGP/VPN extended community list\n")
2644{
2645 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2646}
2647
2648ALIAS (no_match_ecommunity,
2649 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002650 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002651 NO_STR
2652 MATCH_STR
2653 "Match BGP/VPN extended community list\n"
2654 "Extended community-list number (standard)\n"
2655 "Extended community-list number (expanded)\n"
2656 "Extended community-list name\n")
2657
paul718e3742002-12-13 20:15:29 +00002658DEFUN (match_aspath,
2659 match_aspath_cmd,
2660 "match as-path WORD",
2661 MATCH_STR
2662 "Match BGP AS path list\n"
2663 "AS path access-list name\n")
2664{
2665 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2666}
2667
2668DEFUN (no_match_aspath,
2669 no_match_aspath_cmd,
2670 "no match as-path",
2671 NO_STR
2672 MATCH_STR
2673 "Match BGP AS path list\n")
2674{
2675 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2676}
2677
2678ALIAS (no_match_aspath,
2679 no_match_aspath_val_cmd,
2680 "no match as-path WORD",
2681 NO_STR
2682 MATCH_STR
2683 "Match BGP AS path list\n"
2684 "AS path access-list name\n")
2685
2686DEFUN (match_origin,
2687 match_origin_cmd,
2688 "match origin (egp|igp|incomplete)",
2689 MATCH_STR
2690 "BGP origin code\n"
2691 "remote EGP\n"
2692 "local IGP\n"
2693 "unknown heritage\n")
2694{
2695 if (strncmp (argv[0], "igp", 2) == 0)
2696 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2697 if (strncmp (argv[0], "egp", 1) == 0)
2698 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2699 if (strncmp (argv[0], "incomplete", 2) == 0)
2700 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2701
2702 return CMD_WARNING;
2703}
2704
2705DEFUN (no_match_origin,
2706 no_match_origin_cmd,
2707 "no match origin",
2708 NO_STR
2709 MATCH_STR
2710 "BGP origin code\n")
2711{
2712 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2713}
2714
2715ALIAS (no_match_origin,
2716 no_match_origin_val_cmd,
2717 "no match origin (egp|igp|incomplete)",
2718 NO_STR
2719 MATCH_STR
2720 "BGP origin code\n"
2721 "remote EGP\n"
2722 "local IGP\n"
2723 "unknown heritage\n")
2724
2725DEFUN (set_ip_nexthop,
2726 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002727 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002728 SET_STR
2729 IP_STR
2730 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002731 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002732{
2733 union sockunion su;
2734 int ret;
2735
2736 ret = str2sockunion (argv[0], &su);
2737 if (ret < 0)
2738 {
2739 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2740 return CMD_WARNING;
2741 }
2742
2743 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2744}
2745
paulaf5cd0a2003-11-02 07:24:40 +00002746DEFUN (set_ip_nexthop_peer,
2747 set_ip_nexthop_peer_cmd,
2748 "set ip next-hop peer-address",
2749 SET_STR
2750 IP_STR
2751 "Next hop address\n"
2752 "Use peer address (for BGP only)\n")
2753{
2754 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2755}
2756
paul94f2b392005-06-28 12:44:16 +00002757DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002758 no_set_ip_nexthop_peer_cmd,
2759 "no set ip next-hop peer-address",
2760 NO_STR
2761 SET_STR
2762 IP_STR
2763 "Next hop address\n"
2764 "Use peer address (for BGP only)\n")
2765{
2766 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2767}
2768
2769
paul718e3742002-12-13 20:15:29 +00002770DEFUN (no_set_ip_nexthop,
2771 no_set_ip_nexthop_cmd,
2772 "no set ip next-hop",
2773 NO_STR
2774 SET_STR
paul718e3742002-12-13 20:15:29 +00002775 "Next hop address\n")
2776{
paulaf5cd0a2003-11-02 07:24:40 +00002777 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002778 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2779
2780 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2781}
2782
2783ALIAS (no_set_ip_nexthop,
2784 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002785 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002786 NO_STR
2787 SET_STR
2788 IP_STR
2789 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002790 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002791
2792DEFUN (set_metric,
2793 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002794 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002795 SET_STR
2796 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002797 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002798{
2799 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2800}
2801
paul73ffb252003-04-19 15:49:49 +00002802ALIAS (set_metric,
2803 set_metric_addsub_cmd,
2804 "set metric <+/-metric>",
2805 SET_STR
2806 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002807 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002808
paul718e3742002-12-13 20:15:29 +00002809DEFUN (no_set_metric,
2810 no_set_metric_cmd,
2811 "no set metric",
2812 NO_STR
2813 SET_STR
2814 "Metric value for destination routing protocol\n")
2815{
2816 if (argc == 0)
2817 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2818
2819 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2820}
2821
2822ALIAS (no_set_metric,
2823 no_set_metric_val_cmd,
2824 "no set metric <0-4294967295>",
2825 NO_STR
2826 SET_STR
2827 "Metric value for destination routing protocol\n"
2828 "Metric value\n")
2829
2830DEFUN (set_local_pref,
2831 set_local_pref_cmd,
2832 "set local-preference <0-4294967295>",
2833 SET_STR
2834 "BGP local preference path attribute\n"
2835 "Preference value\n")
2836{
2837 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2838}
2839
2840DEFUN (no_set_local_pref,
2841 no_set_local_pref_cmd,
2842 "no set local-preference",
2843 NO_STR
2844 SET_STR
2845 "BGP local preference path attribute\n")
2846{
2847 if (argc == 0)
2848 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2849
2850 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2851}
2852
2853ALIAS (no_set_local_pref,
2854 no_set_local_pref_val_cmd,
2855 "no set local-preference <0-4294967295>",
2856 NO_STR
2857 SET_STR
2858 "BGP local preference path attribute\n"
2859 "Preference value\n")
2860
2861DEFUN (set_weight,
2862 set_weight_cmd,
2863 "set weight <0-4294967295>",
2864 SET_STR
2865 "BGP weight for routing table\n"
2866 "Weight value\n")
2867{
2868 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2869}
2870
2871DEFUN (no_set_weight,
2872 no_set_weight_cmd,
2873 "no set weight",
2874 NO_STR
2875 SET_STR
2876 "BGP weight for routing table\n")
2877{
2878 if (argc == 0)
2879 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2880
2881 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2882}
2883
2884ALIAS (no_set_weight,
2885 no_set_weight_val_cmd,
2886 "no set weight <0-4294967295>",
2887 NO_STR
2888 SET_STR
2889 "BGP weight for routing table\n"
2890 "Weight value\n")
2891
2892DEFUN (set_aspath_prepend,
2893 set_aspath_prepend_cmd,
2894 "set as-path prepend .<1-65535>",
2895 SET_STR
2896 "Prepend string for a BGP AS-path attribute\n"
2897 "Prepend to the as-path\n"
2898 "AS number\n")
2899{
2900 int ret;
2901 char *str;
2902
2903 str = argv_concat (argv, argc, 0);
2904 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2905 XFREE (MTYPE_TMP, str);
2906
2907 return ret;
2908}
2909
2910DEFUN (no_set_aspath_prepend,
2911 no_set_aspath_prepend_cmd,
2912 "no set as-path prepend",
2913 NO_STR
2914 SET_STR
2915 "Prepend string for a BGP AS-path attribute\n"
2916 "Prepend to the as-path\n")
2917{
2918 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2919}
2920
2921ALIAS (no_set_aspath_prepend,
2922 no_set_aspath_prepend_val_cmd,
2923 "no set as-path prepend .<1-65535>",
2924 NO_STR
2925 SET_STR
2926 "Prepend string for a BGP AS-path attribute\n"
2927 "Prepend to the as-path\n"
2928 "AS number\n")
2929
2930DEFUN (set_community,
2931 set_community_cmd,
2932 "set community .AA:NN",
2933 SET_STR
2934 "BGP community attribute\n"
2935 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2936{
2937 int i;
2938 int first = 0;
2939 int additive = 0;
2940 struct buffer *b;
2941 struct community *com = NULL;
2942 char *str;
2943 char *argstr;
2944 int ret;
2945
2946 b = buffer_new (1024);
2947
2948 for (i = 0; i < argc; i++)
2949 {
2950 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2951 {
2952 additive = 1;
2953 continue;
2954 }
2955
2956 if (first)
2957 buffer_putc (b, ' ');
2958 else
2959 first = 1;
2960
2961 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2962 {
2963 buffer_putstr (b, "internet");
2964 continue;
2965 }
2966 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2967 {
2968 buffer_putstr (b, "local-AS");
2969 continue;
2970 }
2971 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2972 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2973 {
2974 buffer_putstr (b, "no-advertise");
2975 continue;
2976 }
2977 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2978 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2979 {
2980 buffer_putstr (b, "no-export");
2981 continue;
2982 }
2983 buffer_putstr (b, argv[i]);
2984 }
2985 buffer_putc (b, '\0');
2986
2987 /* Fetch result string then compile it to communities attribute. */
2988 str = buffer_getstr (b);
2989 buffer_free (b);
2990
2991 if (str)
2992 {
2993 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00002994 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00002995 }
2996
2997 /* Can't compile user input into communities attribute. */
2998 if (! com)
2999 {
3000 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3001 return CMD_WARNING;
3002 }
3003
3004 /* Set communites attribute string. */
3005 str = community_str (com);
3006
3007 if (additive)
3008 {
3009 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3010 strcpy (argstr, str);
3011 strcpy (argstr + strlen (str), " additive");
3012 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3013 XFREE (MTYPE_TMP, argstr);
3014 }
3015 else
3016 ret = bgp_route_set_add (vty, vty->index, "community", str);
3017
3018 community_free (com);
3019
3020 return ret;
3021}
3022
3023DEFUN (set_community_none,
3024 set_community_none_cmd,
3025 "set community none",
3026 SET_STR
3027 "BGP community attribute\n"
3028 "No community attribute\n")
3029{
3030 return bgp_route_set_add (vty, vty->index, "community", "none");
3031}
3032
3033DEFUN (no_set_community,
3034 no_set_community_cmd,
3035 "no set community",
3036 NO_STR
3037 SET_STR
3038 "BGP community attribute\n")
3039{
3040 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3041}
3042
3043ALIAS (no_set_community,
3044 no_set_community_val_cmd,
3045 "no set community .AA:NN",
3046 NO_STR
3047 SET_STR
3048 "BGP community attribute\n"
3049 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3050
3051ALIAS (no_set_community,
3052 no_set_community_none_cmd,
3053 "no set community none",
3054 NO_STR
3055 SET_STR
3056 "BGP community attribute\n"
3057 "No community attribute\n")
3058
3059DEFUN (set_community_delete,
3060 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003061 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003062 SET_STR
3063 "set BGP community list (for deletion)\n"
3064 "Community-list number (standard)\n"
3065 "Communitly-list number (expanded)\n"
3066 "Community-list name\n"
3067 "Delete matching communities\n")
3068{
3069 char *str;
3070
3071 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3072 strcpy (str, argv[0]);
3073 strcpy (str + strlen (argv[0]), " delete");
3074
3075 bgp_route_set_add (vty, vty->index, "comm-list", str);
3076
3077 XFREE (MTYPE_TMP, str);
3078 return CMD_SUCCESS;
3079}
3080
3081DEFUN (no_set_community_delete,
3082 no_set_community_delete_cmd,
3083 "no set comm-list",
3084 NO_STR
3085 SET_STR
3086 "set BGP community list (for deletion)\n")
3087{
3088 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3089}
3090
3091ALIAS (no_set_community_delete,
3092 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003093 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003094 NO_STR
3095 SET_STR
3096 "set BGP community list (for deletion)\n"
3097 "Community-list number (standard)\n"
3098 "Communitly-list number (expanded)\n"
3099 "Community-list name\n"
3100 "Delete matching communities\n")
3101
3102DEFUN (set_ecommunity_rt,
3103 set_ecommunity_rt_cmd,
3104 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3105 SET_STR
3106 "BGP extended community attribute\n"
3107 "Route Target extened communityt\n"
3108 "VPN extended community\n")
3109{
3110 int ret;
3111 char *str;
3112
3113 str = argv_concat (argv, argc, 0);
3114 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3115 XFREE (MTYPE_TMP, str);
3116
3117 return ret;
3118}
3119
3120DEFUN (no_set_ecommunity_rt,
3121 no_set_ecommunity_rt_cmd,
3122 "no set extcommunity rt",
3123 NO_STR
3124 SET_STR
3125 "BGP extended community attribute\n"
3126 "Route Target extened communityt\n")
3127{
3128 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3129}
3130
3131ALIAS (no_set_ecommunity_rt,
3132 no_set_ecommunity_rt_val_cmd,
3133 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3134 NO_STR
3135 SET_STR
3136 "BGP extended community attribute\n"
3137 "Route Target extened communityt\n"
3138 "VPN extended community\n")
3139
3140DEFUN (set_ecommunity_soo,
3141 set_ecommunity_soo_cmd,
3142 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3143 SET_STR
3144 "BGP extended community attribute\n"
3145 "Site-of-Origin extended community\n"
3146 "VPN extended community\n")
3147{
3148 int ret;
3149 char *str;
3150
3151 str = argv_concat (argv, argc, 0);
3152 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3153 XFREE (MTYPE_TMP, str);
3154 return ret;
3155}
3156
3157DEFUN (no_set_ecommunity_soo,
3158 no_set_ecommunity_soo_cmd,
3159 "no set extcommunity soo",
3160 NO_STR
3161 SET_STR
3162 "BGP extended community attribute\n"
3163 "Site-of-Origin extended community\n")
3164{
3165 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3166}
3167
3168ALIAS (no_set_ecommunity_soo,
3169 no_set_ecommunity_soo_val_cmd,
3170 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3171 NO_STR
3172 SET_STR
3173 "BGP extended community attribute\n"
3174 "Site-of-Origin extended community\n"
3175 "VPN extended community\n")
3176
3177DEFUN (set_origin,
3178 set_origin_cmd,
3179 "set origin (egp|igp|incomplete)",
3180 SET_STR
3181 "BGP origin code\n"
3182 "remote EGP\n"
3183 "local IGP\n"
3184 "unknown heritage\n")
3185{
3186 if (strncmp (argv[0], "igp", 2) == 0)
3187 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3188 if (strncmp (argv[0], "egp", 1) == 0)
3189 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3190 if (strncmp (argv[0], "incomplete", 2) == 0)
3191 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3192
3193 return CMD_WARNING;
3194}
3195
3196DEFUN (no_set_origin,
3197 no_set_origin_cmd,
3198 "no set origin",
3199 NO_STR
3200 SET_STR
3201 "BGP origin code\n")
3202{
3203 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3204}
3205
3206ALIAS (no_set_origin,
3207 no_set_origin_val_cmd,
3208 "no set origin (egp|igp|incomplete)",
3209 NO_STR
3210 SET_STR
3211 "BGP origin code\n"
3212 "remote EGP\n"
3213 "local IGP\n"
3214 "unknown heritage\n")
3215
3216DEFUN (set_atomic_aggregate,
3217 set_atomic_aggregate_cmd,
3218 "set atomic-aggregate",
3219 SET_STR
3220 "BGP atomic aggregate attribute\n" )
3221{
3222 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3223}
3224
3225DEFUN (no_set_atomic_aggregate,
3226 no_set_atomic_aggregate_cmd,
3227 "no set atomic-aggregate",
3228 NO_STR
3229 SET_STR
3230 "BGP atomic aggregate attribute\n" )
3231{
3232 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3233}
3234
3235DEFUN (set_aggregator_as,
3236 set_aggregator_as_cmd,
3237 "set aggregator as <1-65535> A.B.C.D",
3238 SET_STR
3239 "BGP aggregator attribute\n"
3240 "AS number of aggregator\n"
3241 "AS number\n"
3242 "IP address of aggregator\n")
3243{
3244 int ret;
3245 as_t as;
3246 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003247 char *argstr;
3248
paula94feb32005-05-23 13:17:29 +00003249 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paulfd79ac92004-10-13 05:06:08 +00003250
paul718e3742002-12-13 20:15:29 +00003251 ret = inet_aton (argv[1], &address);
3252 if (ret == 0)
3253 {
3254 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3255 return CMD_WARNING;
3256 }
3257
3258 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3259 strlen (argv[0]) + strlen (argv[1]) + 2);
3260
3261 sprintf (argstr, "%s %s", argv[0], argv[1]);
3262
3263 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3264
3265 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3266
3267 return ret;
3268}
3269
3270DEFUN (no_set_aggregator_as,
3271 no_set_aggregator_as_cmd,
3272 "no set aggregator as",
3273 NO_STR
3274 SET_STR
3275 "BGP aggregator attribute\n"
3276 "AS number of aggregator\n")
3277{
3278 int ret;
3279 as_t as;
3280 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003281 char *argstr;
3282
3283 if (argv == 0)
3284 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3285
paula94feb32005-05-23 13:17:29 +00003286 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paul718e3742002-12-13 20:15:29 +00003287
3288 ret = inet_aton (argv[1], &address);
3289 if (ret == 0)
3290 {
3291 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3292 return CMD_WARNING;
3293 }
3294
3295 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3296 strlen (argv[0]) + strlen (argv[1]) + 2);
3297
3298 sprintf (argstr, "%s %s", argv[0], argv[1]);
3299
3300 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3301
3302 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3303
3304 return ret;
3305}
3306
3307ALIAS (no_set_aggregator_as,
3308 no_set_aggregator_as_val_cmd,
3309 "no set aggregator as <1-65535> A.B.C.D",
3310 NO_STR
3311 SET_STR
3312 "BGP aggregator attribute\n"
3313 "AS number of aggregator\n"
3314 "AS number\n"
3315 "IP address of aggregator\n")
3316
3317
3318#ifdef HAVE_IPV6
3319DEFUN (match_ipv6_address,
3320 match_ipv6_address_cmd,
3321 "match ipv6 address WORD",
3322 MATCH_STR
3323 IPV6_STR
3324 "Match IPv6 address of route\n"
3325 "IPv6 access-list name\n")
3326{
3327 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3328}
3329
3330DEFUN (no_match_ipv6_address,
3331 no_match_ipv6_address_cmd,
3332 "no match ipv6 address WORD",
3333 NO_STR
3334 MATCH_STR
3335 IPV6_STR
3336 "Match IPv6 address of route\n"
3337 "IPv6 access-list name\n")
3338{
3339 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3340}
3341
3342DEFUN (match_ipv6_next_hop,
3343 match_ipv6_next_hop_cmd,
3344 "match ipv6 next-hop X:X::X:X",
3345 MATCH_STR
3346 IPV6_STR
3347 "Match IPv6 next-hop address of route\n"
3348 "IPv6 address of next hop\n")
3349{
3350 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3351}
3352
3353DEFUN (no_match_ipv6_next_hop,
3354 no_match_ipv6_next_hop_cmd,
3355 "no match ipv6 next-hop X:X::X:X",
3356 NO_STR
3357 MATCH_STR
3358 IPV6_STR
3359 "Match IPv6 next-hop address of route\n"
3360 "IPv6 address of next hop\n")
3361{
3362 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3363}
3364
3365DEFUN (match_ipv6_address_prefix_list,
3366 match_ipv6_address_prefix_list_cmd,
3367 "match ipv6 address prefix-list WORD",
3368 MATCH_STR
3369 IPV6_STR
3370 "Match address of route\n"
3371 "Match entries of prefix-lists\n"
3372 "IP prefix-list name\n")
3373{
3374 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3375}
3376
3377DEFUN (no_match_ipv6_address_prefix_list,
3378 no_match_ipv6_address_prefix_list_cmd,
3379 "no match ipv6 address prefix-list WORD",
3380 NO_STR
3381 MATCH_STR
3382 IPV6_STR
3383 "Match address of route\n"
3384 "Match entries of prefix-lists\n"
3385 "IP prefix-list name\n")
3386{
3387 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3388}
3389
3390DEFUN (set_ipv6_nexthop_global,
3391 set_ipv6_nexthop_global_cmd,
3392 "set ipv6 next-hop global X:X::X:X",
3393 SET_STR
3394 IPV6_STR
3395 "IPv6 next-hop address\n"
3396 "IPv6 global address\n"
3397 "IPv6 address of next hop\n")
3398{
3399 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3400}
3401
3402DEFUN (no_set_ipv6_nexthop_global,
3403 no_set_ipv6_nexthop_global_cmd,
3404 "no set ipv6 next-hop global",
3405 NO_STR
3406 SET_STR
3407 IPV6_STR
3408 "IPv6 next-hop address\n"
3409 "IPv6 global address\n")
3410{
3411 if (argc == 0)
3412 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3413
3414 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3415}
3416
3417ALIAS (no_set_ipv6_nexthop_global,
3418 no_set_ipv6_nexthop_global_val_cmd,
3419 "no set ipv6 next-hop global X:X::X:X",
3420 NO_STR
3421 SET_STR
3422 IPV6_STR
3423 "IPv6 next-hop address\n"
3424 "IPv6 global address\n"
3425 "IPv6 address of next hop\n")
3426
3427DEFUN (set_ipv6_nexthop_local,
3428 set_ipv6_nexthop_local_cmd,
3429 "set ipv6 next-hop local X:X::X:X",
3430 SET_STR
3431 IPV6_STR
3432 "IPv6 next-hop address\n"
3433 "IPv6 local address\n"
3434 "IPv6 address of next hop\n")
3435{
3436 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3437}
3438
3439DEFUN (no_set_ipv6_nexthop_local,
3440 no_set_ipv6_nexthop_local_cmd,
3441 "no set ipv6 next-hop local",
3442 NO_STR
3443 SET_STR
3444 IPV6_STR
3445 "IPv6 next-hop address\n"
3446 "IPv6 local address\n")
3447{
3448 if (argc == 0)
3449 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3450
3451 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3452}
3453
3454ALIAS (no_set_ipv6_nexthop_local,
3455 no_set_ipv6_nexthop_local_val_cmd,
3456 "no set ipv6 next-hop local X:X::X:X",
3457 NO_STR
3458 SET_STR
3459 IPV6_STR
3460 "IPv6 next-hop address\n"
3461 "IPv6 local address\n"
3462 "IPv6 address of next hop\n")
3463#endif /* HAVE_IPV6 */
3464
3465DEFUN (set_vpnv4_nexthop,
3466 set_vpnv4_nexthop_cmd,
3467 "set vpnv4 next-hop A.B.C.D",
3468 SET_STR
3469 "VPNv4 information\n"
3470 "VPNv4 next-hop address\n"
3471 "IP address of next hop\n")
3472{
3473 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3474}
3475
3476DEFUN (no_set_vpnv4_nexthop,
3477 no_set_vpnv4_nexthop_cmd,
3478 "no set vpnv4 next-hop",
3479 NO_STR
3480 SET_STR
3481 "VPNv4 information\n"
3482 "VPNv4 next-hop address\n")
3483{
3484 if (argc == 0)
3485 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3486
3487 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3488}
3489
3490ALIAS (no_set_vpnv4_nexthop,
3491 no_set_vpnv4_nexthop_val_cmd,
3492 "no set vpnv4 next-hop A.B.C.D",
3493 NO_STR
3494 SET_STR
3495 "VPNv4 information\n"
3496 "VPNv4 next-hop address\n"
3497 "IP address of next hop\n")
3498
3499DEFUN (set_originator_id,
3500 set_originator_id_cmd,
3501 "set originator-id A.B.C.D",
3502 SET_STR
3503 "BGP originator ID attribute\n"
3504 "IP address of originator\n")
3505{
3506 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3507}
3508
3509DEFUN (no_set_originator_id,
3510 no_set_originator_id_cmd,
3511 "no set originator-id",
3512 NO_STR
3513 SET_STR
3514 "BGP originator ID attribute\n")
3515{
3516 if (argc == 0)
3517 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3518
3519 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3520}
3521
3522ALIAS (no_set_originator_id,
3523 no_set_originator_id_val_cmd,
3524 "no set originator-id A.B.C.D",
3525 NO_STR
3526 SET_STR
3527 "BGP originator ID attribute\n"
3528 "IP address of originator\n")
3529
3530
3531/* Initialization of route map. */
3532void
paul94f2b392005-06-28 12:44:16 +00003533bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003534{
3535 route_map_init ();
3536 route_map_init_vty ();
3537 route_map_add_hook (bgp_route_map_update);
3538 route_map_delete_hook (bgp_route_map_update);
3539
paulfee0f4c2004-09-13 05:12:46 +00003540 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003541 route_map_install_match (&route_match_ip_address_cmd);
3542 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003543 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003544 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3545 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003546 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003547 route_map_install_match (&route_match_aspath_cmd);
3548 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003549 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003550 route_map_install_match (&route_match_metric_cmd);
3551 route_map_install_match (&route_match_origin_cmd);
3552
3553 route_map_install_set (&route_set_ip_nexthop_cmd);
3554 route_map_install_set (&route_set_local_pref_cmd);
3555 route_map_install_set (&route_set_weight_cmd);
3556 route_map_install_set (&route_set_metric_cmd);
3557 route_map_install_set (&route_set_aspath_prepend_cmd);
3558 route_map_install_set (&route_set_origin_cmd);
3559 route_map_install_set (&route_set_atomic_aggregate_cmd);
3560 route_map_install_set (&route_set_aggregator_as_cmd);
3561 route_map_install_set (&route_set_community_cmd);
3562 route_map_install_set (&route_set_community_delete_cmd);
3563 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3564 route_map_install_set (&route_set_originator_id_cmd);
3565 route_map_install_set (&route_set_ecommunity_rt_cmd);
3566 route_map_install_set (&route_set_ecommunity_soo_cmd);
3567
paulfee0f4c2004-09-13 05:12:46 +00003568 install_element (RMAP_NODE, &match_peer_cmd);
3569 install_element (RMAP_NODE, &match_peer_local_cmd);
3570 install_element (RMAP_NODE, &no_match_peer_cmd);
3571 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3572 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003573 install_element (RMAP_NODE, &match_ip_address_cmd);
3574 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3575 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3576 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3577 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3578 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003579 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3580 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3581 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003582
3583 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3584 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3585 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3586 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3587 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3588 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003589 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3590 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3591 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003592
3593 install_element (RMAP_NODE, &match_aspath_cmd);
3594 install_element (RMAP_NODE, &no_match_aspath_cmd);
3595 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3596 install_element (RMAP_NODE, &match_metric_cmd);
3597 install_element (RMAP_NODE, &no_match_metric_cmd);
3598 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3599 install_element (RMAP_NODE, &match_community_cmd);
3600 install_element (RMAP_NODE, &match_community_exact_cmd);
3601 install_element (RMAP_NODE, &no_match_community_cmd);
3602 install_element (RMAP_NODE, &no_match_community_val_cmd);
3603 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003604 install_element (RMAP_NODE, &match_ecommunity_cmd);
3605 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3606 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003607 install_element (RMAP_NODE, &match_origin_cmd);
3608 install_element (RMAP_NODE, &no_match_origin_cmd);
3609 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3610
3611 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003612 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003613 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3614 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3615 install_element (RMAP_NODE, &set_local_pref_cmd);
3616 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3617 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3618 install_element (RMAP_NODE, &set_weight_cmd);
3619 install_element (RMAP_NODE, &no_set_weight_cmd);
3620 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3621 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003622 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003623 install_element (RMAP_NODE, &no_set_metric_cmd);
3624 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3625 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3626 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3627 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3628 install_element (RMAP_NODE, &set_origin_cmd);
3629 install_element (RMAP_NODE, &no_set_origin_cmd);
3630 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3631 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3632 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3633 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3634 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3635 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3636 install_element (RMAP_NODE, &set_community_cmd);
3637 install_element (RMAP_NODE, &set_community_none_cmd);
3638 install_element (RMAP_NODE, &no_set_community_cmd);
3639 install_element (RMAP_NODE, &no_set_community_val_cmd);
3640 install_element (RMAP_NODE, &no_set_community_none_cmd);
3641 install_element (RMAP_NODE, &set_community_delete_cmd);
3642 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3643 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3644 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3645 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3646 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3647 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3648 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3649 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3650 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3651 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3652 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3653 install_element (RMAP_NODE, &set_originator_id_cmd);
3654 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3655 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3656
3657#ifdef HAVE_IPV6
3658 route_map_install_match (&route_match_ipv6_address_cmd);
3659 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3660 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3661 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3662 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3663
3664 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3665 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3666 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3667 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3668 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3669 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3670 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3671 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3672 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3673 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3674 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3675 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3676#endif /* HAVE_IPV6 */
3677}