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