~ubuntu-branches/ubuntu/breezy/quagga/breezy-security

« back to all changes in this revision

Viewing changes to bgpd/bgp_routemap.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-05-20 13:16:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050520131612-pr6paalox60o3x3n
Tags: upstream-0.99.1
ImportĀ upstreamĀ versionĀ 0.99.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Route map function of bgpd.
 
2
   Copyright (C) 1998, 1999 Kunihiro Ishiguro
 
3
 
 
4
This file is part of GNU Zebra.
 
5
 
 
6
GNU Zebra is free software; you can redistribute it and/or modify it
 
7
under the terms of the GNU General Public License as published by the
 
8
Free Software Foundation; either version 2, or (at your option) any
 
9
later version.
 
10
 
 
11
GNU Zebra is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with GNU Zebra; see the file COPYING.  If not, write to the Free
 
18
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
02111-1307, USA.  */
 
20
 
 
21
#include <zebra.h>
 
22
 
 
23
#include "prefix.h"
 
24
#include "filter.h"
 
25
#include "routemap.h"
 
26
#include "command.h"
 
27
#include "linklist.h"
 
28
#include "plist.h"
 
29
#include "memory.h"
 
30
#include "log.h"
 
31
#ifdef HAVE_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
 
 
53
o 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
 
60
       ip route-source  :  Done
 
61
       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
 
 
91
o Local extention
 
92
 
 
93
  set ipv6 next-hop global: Done
 
94
  set ipv6 next-hop local : Done
 
95
 
 
96
*/ 
 
97
 
 
98
 /* '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. */
 
103
route_map_result_t
 
104
route_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;
 
111
  struct listnode *node, *nnode;
 
112
 
 
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
        {
 
127
          if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
 
128
               CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
 
129
               CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
 
130
            {
 
131
              XFREE (MTYPE_SOCKUNION, su2);
 
132
 
 
133
              return RMAP_MATCH;
 
134
            }
 
135
          else
 
136
            return RMAP_NOMATCH;
 
137
        }
 
138
      XFREE (MTYPE_SOCKUNION, su2);
 
139
 
 
140
      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;
 
150
          for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 
151
            {
 
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
 
 
162
void *
 
163
route_match_peer_compile (const char *arg)
 
164
{
 
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. */
 
180
void
 
181
route_match_peer_free (void *rule)
 
182
{
 
183
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
184
}
 
185
 
 
186
/* Route map commands for ip address matching. */
 
187
struct 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
 
 
195
/* `match ip address IP_ACCESS_LIST' */
 
196
 
 
197
/* Match function should return 1 if match is success else return
 
198
   zero. */
 
199
route_map_result_t
 
200
route_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. */
 
220
void *
 
221
route_match_ip_address_compile (const char *arg)
 
222
{
 
223
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
224
}
 
225
 
 
226
/* Free route map's compiled `ip address' value. */
 
227
void
 
228
route_match_ip_address_free (void *rule)
 
229
{
 
230
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
231
}
 
232
 
 
233
/* Route map commands for ip address matching. */
 
234
struct 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. */
 
245
route_map_result_t
 
246
route_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. */
 
272
void *
 
273
route_match_ip_next_hop_compile (const char *arg)
 
274
{
 
275
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
276
}
 
277
 
 
278
/* Free route map's compiled `ip address' value. */
 
279
void
 
280
route_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. */
 
286
struct 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
 
 
294
/* `match ip route-source ACCESS-LIST' */
 
295
 
 
296
/* Match function return 1 if match is success else return zero. */
 
297
route_map_result_t
 
298
route_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. */
 
330
void *
 
331
route_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. */
 
337
void
 
338
route_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. */
 
344
struct 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
 
 
352
/* `match ip address prefix-list PREFIX_LIST' */
 
353
 
 
354
route_map_result_t
 
355
route_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
 
 
372
void *
 
373
route_match_ip_address_prefix_list_compile (const char *arg)
 
374
{
 
375
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
376
}
 
377
 
 
378
void
 
379
route_match_ip_address_prefix_list_free (void *rule)
 
380
{
 
381
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
382
}
 
383
 
 
384
struct 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
 
 
394
route_map_result_t
 
395
route_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
 
 
419
void *
 
420
route_match_ip_next_hop_prefix_list_compile (const char *arg)
 
421
{
 
422
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
423
}
 
424
 
 
425
void
 
426
route_match_ip_next_hop_prefix_list_free (void *rule)
 
427
{
 
428
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
429
}
 
430
 
 
431
struct 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
 
 
439
/* `match ip route-source prefix-list PREFIX_LIST' */
 
440
 
 
441
route_map_result_t
 
442
route_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
 
 
472
void *
 
473
route_match_ip_route_source_prefix_list_compile (const char *arg)
 
474
{
 
475
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
476
}
 
477
 
 
478
void
 
479
route_match_ip_route_source_prefix_list_free (void *rule)
 
480
{
 
481
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
482
}
 
483
 
 
484
struct 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
 
 
492
/* `match metric METRIC' */
 
493
 
 
494
/* Match function return 1 if match is success else return zero. */
 
495
route_map_result_t
 
496
route_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 */
 
516
void *
 
517
route_match_metric_compile (const char *arg)
 
518
{
 
519
  u_int32_t *med;
 
520
  char *endptr = NULL;
 
521
  unsigned long tmpval;
 
522
 
 
523
  tmpval = strtoul (arg, &endptr, 10);
 
524
  if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
 
525
    return NULL;
 
526
    
 
527
  med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
 
528
  
 
529
  if (!med)
 
530
    return med;
 
531
  
 
532
  *med = tmpval;
 
533
  return med;
 
534
}
 
535
 
 
536
/* Free route map's compiled `match metric' value. */
 
537
void
 
538
route_match_metric_free (void *rule)
 
539
{
 
540
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
541
}
 
542
 
 
543
/* Route map commands for metric matching. */
 
544
struct 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 */
 
555
route_map_result_t
 
556
route_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. */
 
578
void *
 
579
route_match_aspath_compile (const char *arg)
 
580
{
 
581
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
582
}
 
583
 
 
584
/* Compile function for as-path match. */
 
585
void
 
586
route_match_aspath_free (void *rule)
 
587
{
 
588
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
589
}
 
590
 
 
591
/* Route map commands for aspath matching. */
 
592
struct 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
};
 
599
 
 
600
#if ROUTE_MATCH_ASPATH_OLD
 
601
/* `match as-path ASPATH' */
 
602
 
 
603
/* Match function for as-path match.  I assume given object is */
 
604
int
 
605
route_match_aspath (void *rule, struct prefix *prefix, void *object)
 
606
{
 
607
  regex_t *regex;
 
608
  struct bgp_info *bgp_info;
 
609
 
 
610
  regex = rule;
 
611
  bgp_info = object;
 
612
  
 
613
  /* Perform match. */
 
614
  return bgp_regexec (regex, bgp_info->attr->aspath);
 
615
}
 
616
 
 
617
/* Compile function for as-path match. */
 
618
void *
 
619
route_match_aspath_compile (const char *arg)
 
620
{
 
621
  regex_t *regex;
 
622
 
 
623
  regex = bgp_regcomp (arg);
 
624
  if (! regex)
 
625
    return NULL;
 
626
 
 
627
  return regex;
 
628
}
 
629
 
 
630
/* Compile function for as-path match. */
 
631
void
 
632
route_match_aspath_free (void *rule)
 
633
{
 
634
  regex_t *regex = rule;
 
635
 
 
636
  bgp_regex_free (regex);
 
637
}
 
638
 
 
639
/* Route map commands for aspath matching. */
 
640
struct route_map_rule_cmd route_match_aspath_cmd = 
 
641
{
 
642
  "as-path",
 
643
  route_match_aspath,
 
644
  route_match_aspath_compile,
 
645
  route_match_aspath_free
 
646
};
 
647
#endif /* ROUTE_MATCH_ASPATH_OLD */
 
648
 
 
649
/* `match community COMMUNIY' */
 
650
struct rmap_community
 
651
{
 
652
  char *name;
 
653
  int exact;
 
654
};
 
655
 
 
656
/* Match function for community match. */
 
657
route_map_result_t
 
658
route_match_community (void *rule, struct prefix *prefix, 
 
659
                       route_map_object_t type, void *object)
 
660
{
 
661
  struct community_list *list;
 
662
  struct bgp_info *bgp_info;
 
663
  struct rmap_community *rcom;
 
664
 
 
665
  if (type == RMAP_BGP) 
 
666
    {
 
667
      bgp_info = object;
 
668
      rcom = rule;
 
669
 
 
670
      list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
 
671
      if (! list)
 
672
        return RMAP_NOMATCH;
 
673
 
 
674
      if (rcom->exact)
 
675
        {
 
676
          if (community_list_exact_match (bgp_info->attr->community, list))
 
677
            return RMAP_MATCH;
 
678
        }
 
679
      else
 
680
        {
 
681
          if (community_list_match (bgp_info->attr->community, list))
 
682
            return RMAP_MATCH;
 
683
        }
 
684
    }
 
685
  return RMAP_NOMATCH;
 
686
}
 
687
 
 
688
/* Compile function for community match. */
 
689
void *
 
690
route_match_community_compile (const char *arg)
 
691
{
 
692
  struct rmap_community *rcom;
 
693
  int len;
 
694
  char *p;
 
695
 
 
696
  rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
 
697
 
 
698
  p = strchr (arg, ' ');
 
699
  if (p)
 
700
    {
 
701
      len = p - arg;
 
702
      rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
 
703
      memcpy (rcom->name, arg, len);
 
704
      rcom->exact = 1;
 
705
    }
 
706
  else
 
707
    {
 
708
      rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
709
      rcom->exact = 0;
 
710
    }
 
711
  return rcom;
 
712
}
 
713
 
 
714
/* Compile function for community match. */
 
715
void
 
716
route_match_community_free (void *rule)
 
717
{
 
718
  struct rmap_community *rcom = rule;
 
719
 
 
720
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
 
721
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
 
722
}
 
723
 
 
724
/* Route map commands for community matching. */
 
725
struct route_map_rule_cmd route_match_community_cmd = 
 
726
{
 
727
  "community",
 
728
  route_match_community,
 
729
  route_match_community_compile,
 
730
  route_match_community_free
 
731
};
 
732
 
 
733
/* Match function for extcommunity match. */
 
734
route_map_result_t
 
735
route_match_ecommunity (void *rule, struct prefix *prefix, 
 
736
                        route_map_object_t type, void *object)
 
737
{
 
738
  struct community_list *list;
 
739
  struct bgp_info *bgp_info;
 
740
 
 
741
  if (type == RMAP_BGP) 
 
742
    {
 
743
      bgp_info = object;
 
744
 
 
745
      list = community_list_lookup (bgp_clist, (char *) rule,
 
746
                                    EXTCOMMUNITY_LIST_MASTER);
 
747
      if (! list)
 
748
        return RMAP_NOMATCH;
 
749
 
 
750
      if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
 
751
        return RMAP_MATCH;
 
752
    }
 
753
  return RMAP_NOMATCH;
 
754
}
 
755
 
 
756
/* Compile function for extcommunity match. */
 
757
void *
 
758
route_match_ecommunity_compile (const char *arg)
 
759
{
 
760
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
761
}
 
762
 
 
763
/* Compile function for extcommunity match. */
 
764
void
 
765
route_match_ecommunity_free (void *rule)
 
766
{
 
767
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
768
}
 
769
 
 
770
/* Route map commands for community matching. */
 
771
struct route_map_rule_cmd route_match_ecommunity_cmd = 
 
772
{
 
773
  "extcommunity",
 
774
  route_match_ecommunity,
 
775
  route_match_ecommunity_compile,
 
776
  route_match_ecommunity_free
 
777
};
 
778
 
 
779
/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
 
780
   and `address-family vpnv4'.  */
 
781
 
 
782
/* `match origin' */
 
783
route_map_result_t
 
784
route_match_origin (void *rule, struct prefix *prefix, 
 
785
                    route_map_object_t type, void *object)
 
786
{
 
787
  u_char *origin;
 
788
  struct bgp_info *bgp_info;
 
789
 
 
790
  if (type == RMAP_BGP)
 
791
    {
 
792
      origin = rule;
 
793
      bgp_info = object;
 
794
    
 
795
      if (bgp_info->attr->origin == *origin)
 
796
        return RMAP_MATCH;
 
797
    }
 
798
 
 
799
  return RMAP_NOMATCH;
 
800
}
 
801
 
 
802
void *
 
803
route_match_origin_compile (const char *arg)
 
804
{
 
805
  u_char *origin;
 
806
 
 
807
  origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
 
808
 
 
809
  if (strcmp (arg, "igp") == 0)
 
810
    *origin = 0;
 
811
  else if (strcmp (arg, "egp") == 0)
 
812
    *origin = 1;
 
813
  else
 
814
    *origin = 2;
 
815
 
 
816
  return origin;
 
817
}
 
818
 
 
819
/* Free route map's compiled `ip address' value. */
 
820
void
 
821
route_match_origin_free (void *rule)
 
822
{
 
823
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
824
}
 
825
 
 
826
/* Route map commands for origin matching. */
 
827
struct route_map_rule_cmd route_match_origin_cmd =
 
828
{
 
829
  "origin",
 
830
  route_match_origin,
 
831
  route_match_origin_compile,
 
832
  route_match_origin_free
 
833
};
 
834
/* `set ip next-hop IP_ADDRESS' */
 
835
 
 
836
/* Set nexthop to object.  ojbect must be pointer to struct attr. */
 
837
struct rmap_ip_nexthop_set
 
838
{
 
839
  struct in_addr *address;
 
840
  int peer_address;
 
841
};
 
842
 
 
843
route_map_result_t
 
844
route_set_ip_nexthop (void *rule, struct prefix *prefix,
 
845
                      route_map_object_t type, void *object)
 
846
{
 
847
  struct rmap_ip_nexthop_set *rins = rule;
 
848
  struct in_addr peer_address;
 
849
  struct bgp_info *bgp_info;
 
850
  struct peer *peer;
 
851
 
 
852
  if (type == RMAP_BGP)
 
853
    {
 
854
      bgp_info = object;
 
855
      peer = bgp_info->peer;
 
856
 
 
857
      if (rins->peer_address)
 
858
        {
 
859
         if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
 
860
           CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
 
861
              && peer->su_remote 
 
862
              && sockunion_family (peer->su_remote) == AF_INET)
 
863
            {
 
864
              inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
 
865
              bgp_info->attr->nexthop = peer_address;
 
866
              bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
867
            }
 
868
          else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
 
869
                   && peer->su_local
 
870
                   && sockunion_family (peer->su_local) == AF_INET)
 
871
            {
 
872
              inet_aton (sockunion_su2str (peer->su_local), &peer_address);
 
873
              bgp_info->attr->nexthop = peer_address;
 
874
              bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
875
            }
 
876
        }
 
877
      else
 
878
        {
 
879
          /* Set next hop value. */ 
 
880
          bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
881
          bgp_info->attr->nexthop = *rins->address;
 
882
        }
 
883
    }
 
884
 
 
885
  return RMAP_OKAY;
 
886
}
 
887
 
 
888
/* Route map `ip nexthop' compile function.  Given string is converted
 
889
   to struct in_addr structure. */
 
890
void *
 
891
route_set_ip_nexthop_compile (const char *arg)
 
892
{
 
893
  struct rmap_ip_nexthop_set *rins;
 
894
  struct in_addr *address = NULL;
 
895
  int peer_address = 0;
 
896
  int ret;
 
897
 
 
898
  if (strcmp (arg, "peer-address") == 0)
 
899
    peer_address = 1;
 
900
  else
 
901
    {
 
902
      address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
 
903
      ret = inet_aton (arg, address);
 
904
 
 
905
      if (ret == 0)
 
906
        {
 
907
          XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
908
          return NULL;
 
909
        }
 
910
    }
 
911
 
 
912
  rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
 
913
  memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
 
914
 
 
915
  rins->address = address;
 
916
  rins->peer_address = peer_address;
 
917
 
 
918
  return rins;
 
919
}
 
920
 
 
921
/* Free route map's compiled `ip nexthop' value. */
 
922
void
 
923
route_set_ip_nexthop_free (void *rule)
 
924
{
 
925
  struct rmap_ip_nexthop_set *rins = rule;
 
926
 
 
927
  if (rins->address)
 
928
    XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
 
929
    
 
930
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
 
931
}
 
932
 
 
933
/* Route map commands for ip nexthop set. */
 
934
struct route_map_rule_cmd route_set_ip_nexthop_cmd =
 
935
{
 
936
  "ip next-hop",
 
937
  route_set_ip_nexthop,
 
938
  route_set_ip_nexthop_compile,
 
939
  route_set_ip_nexthop_free
 
940
};
 
941
 
 
942
/* `set local-preference LOCAL_PREF' */
 
943
 
 
944
/* Set local preference. */
 
945
route_map_result_t
 
946
route_set_local_pref (void *rule, struct prefix *prefix,
 
947
                      route_map_object_t type, void *object)
 
948
{
 
949
  u_int32_t *local_pref;
 
950
  struct bgp_info *bgp_info;
 
951
 
 
952
  if (type == RMAP_BGP)
 
953
    {
 
954
      /* Fetch routemap's rule information. */
 
955
      local_pref = rule;
 
956
      bgp_info = object;
 
957
    
 
958
      /* Set local preference value. */ 
 
959
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
 
960
      bgp_info->attr->local_pref = *local_pref;
 
961
    }
 
962
 
 
963
  return RMAP_OKAY;
 
964
}
 
965
 
 
966
/* set local preference compilation. */
 
967
void *
 
968
route_set_local_pref_compile (const char *arg)
 
969
{
 
970
  unsigned long tmp;
 
971
  u_int32_t *local_pref;
 
972
  char *endptr = NULL;
 
973
 
 
974
  /* Local preference value shoud be integer. */
 
975
  if (! all_digit (arg))
 
976
    return NULL;
 
977
  
 
978
  tmp = strtoul (arg, &endptr, 10);
 
979
  if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
 
980
    return NULL;
 
981
   
 
982
  local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); 
 
983
  
 
984
  if (!local_pref)
 
985
    return local_pref;
 
986
  
 
987
  *local_pref = tmp;
 
988
  
 
989
  return local_pref;
 
990
}
 
991
 
 
992
/* Free route map's local preference value. */
 
993
void
 
994
route_set_local_pref_free (void *rule)
 
995
{
 
996
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
997
}
 
998
 
 
999
/* Set local preference rule structure. */
 
1000
struct route_map_rule_cmd route_set_local_pref_cmd = 
 
1001
{
 
1002
  "local-preference",
 
1003
  route_set_local_pref,
 
1004
  route_set_local_pref_compile,
 
1005
  route_set_local_pref_free,
 
1006
};
 
1007
 
 
1008
/* `set weight WEIGHT' */
 
1009
 
 
1010
/* Set weight. */
 
1011
route_map_result_t
 
1012
route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
 
1013
                  void *object)
 
1014
{
 
1015
  u_int32_t *weight;
 
1016
  struct bgp_info *bgp_info;
 
1017
 
 
1018
  if (type == RMAP_BGP)
 
1019
    {
 
1020
      /* Fetch routemap's rule information. */
 
1021
      weight = rule;
 
1022
      bgp_info = object;
 
1023
    
 
1024
      /* Set weight value. */ 
 
1025
      bgp_info->attr->weight = *weight;
 
1026
    }
 
1027
 
 
1028
  return RMAP_OKAY;
 
1029
}
 
1030
 
 
1031
/* set local preference compilation. */
 
1032
void *
 
1033
route_set_weight_compile (const char *arg)
 
1034
{
 
1035
  unsigned long tmp;
 
1036
  u_int32_t *weight;
 
1037
  char *endptr = NULL;
 
1038
 
 
1039
  /* Local preference value shoud be integer. */
 
1040
  if (! all_digit (arg))
 
1041
    return NULL;
 
1042
 
 
1043
 
 
1044
  tmp = strtoul (arg, &endptr, 10);
 
1045
  if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
 
1046
    return NULL;
 
1047
  
 
1048
  weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
 
1049
  
 
1050
  if (weight == NULL)
 
1051
    return weight;
 
1052
  
 
1053
  *weight = tmp;  
 
1054
  
 
1055
  return weight;
 
1056
}
 
1057
 
 
1058
/* Free route map's local preference value. */
 
1059
void
 
1060
route_set_weight_free (void *rule)
 
1061
{
 
1062
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1063
}
 
1064
 
 
1065
/* Set local preference rule structure. */
 
1066
struct route_map_rule_cmd route_set_weight_cmd = 
 
1067
{
 
1068
  "weight",
 
1069
  route_set_weight,
 
1070
  route_set_weight_compile,
 
1071
  route_set_weight_free,
 
1072
};
 
1073
 
 
1074
/* `set metric METRIC' */
 
1075
 
 
1076
/* Set metric to attribute. */
 
1077
route_map_result_t
 
1078
route_set_metric (void *rule, struct prefix *prefix, 
 
1079
                  route_map_object_t type, void *object)
 
1080
{
 
1081
  char *metric;
 
1082
  u_int32_t metric_val;
 
1083
  struct bgp_info *bgp_info;
 
1084
 
 
1085
  if (type == RMAP_BGP)
 
1086
    {
 
1087
      /* Fetch routemap's rule information. */
 
1088
      metric = rule;
 
1089
      bgp_info = object;
 
1090
 
 
1091
      if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
 
1092
        bgp_info->attr->med = 0;
 
1093
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
1094
 
 
1095
      if (all_digit (metric))
 
1096
        {
 
1097
          metric_val = strtoul (metric, (char **)NULL, 10);
 
1098
          bgp_info->attr->med = metric_val;
 
1099
        }
 
1100
      else
 
1101
        {
 
1102
          metric_val = strtoul (metric+1, (char **)NULL, 10);
 
1103
 
 
1104
          if (strncmp (metric, "+", 1) == 0)
 
1105
            {
 
1106
              if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
 
1107
                bgp_info->attr->med = BGP_MED_MAX - 1;
 
1108
              else
 
1109
                bgp_info->attr->med += metric_val;
 
1110
            }
 
1111
          else if (strncmp (metric, "-", 1) == 0)
 
1112
            {
 
1113
              if (bgp_info->attr->med <= metric_val)
 
1114
                bgp_info->attr->med = 0;
 
1115
              else
 
1116
                bgp_info->attr->med -= metric_val;
 
1117
            }
 
1118
        }
 
1119
    }
 
1120
  return RMAP_OKAY;
 
1121
}
 
1122
 
 
1123
/* set metric compilation. */
 
1124
void *
 
1125
route_set_metric_compile (const char *arg)
 
1126
{
 
1127
  u_int32_t metric;
 
1128
  char *endptr = NULL;
 
1129
 
 
1130
  if (all_digit (arg))
 
1131
    {
 
1132
      /* set metric value check*/
 
1133
      metric = strtoul (arg, &endptr, 10);
 
1134
      if (*endptr != '\0' || metric == ULONG_MAX)
 
1135
        return NULL;
 
1136
    }
 
1137
  else
 
1138
    {
 
1139
      /* set metric +/-value check */
 
1140
      if ((strncmp (arg, "+", 1) != 0
 
1141
           && strncmp (arg, "-", 1) != 0)
 
1142
           || (! all_digit (arg+1)))
 
1143
        return NULL;
 
1144
 
 
1145
      metric = strtoul (arg+1, &endptr, 10);
 
1146
      if (*endptr != '\0' || metric == ULONG_MAX)
 
1147
        return NULL;
 
1148
    }
 
1149
 
 
1150
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
1151
}
 
1152
 
 
1153
/* Free route map's compiled `set metric' value. */
 
1154
void
 
1155
route_set_metric_free (void *rule)
 
1156
{
 
1157
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1158
}
 
1159
 
 
1160
/* Set metric rule structure. */
 
1161
struct route_map_rule_cmd route_set_metric_cmd = 
 
1162
{
 
1163
  "metric",
 
1164
  route_set_metric,
 
1165
  route_set_metric_compile,
 
1166
  route_set_metric_free,
 
1167
};
 
1168
 
 
1169
/* `set as-path prepend ASPATH' */
 
1170
 
 
1171
/* For AS path prepend mechanism. */
 
1172
route_map_result_t
 
1173
route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
 
1174
{
 
1175
  struct aspath *aspath;
 
1176
  struct aspath *new;
 
1177
  struct bgp_info *binfo;
 
1178
 
 
1179
  if (type == RMAP_BGP)
 
1180
    {
 
1181
      aspath = rule;
 
1182
      binfo = object;
 
1183
    
 
1184
      if (binfo->attr->aspath->refcnt)
 
1185
        new = aspath_dup (binfo->attr->aspath);
 
1186
      else
 
1187
        new = binfo->attr->aspath;
 
1188
 
 
1189
      aspath_prepend (aspath, new);
 
1190
      binfo->attr->aspath = new;
 
1191
    }
 
1192
 
 
1193
  return RMAP_OKAY;
 
1194
}
 
1195
 
 
1196
/* Compile function for as-path prepend. */
 
1197
void *
 
1198
route_set_aspath_prepend_compile (const char *arg)
 
1199
{
 
1200
  struct aspath *aspath;
 
1201
 
 
1202
  aspath = aspath_str2aspath (arg);
 
1203
  if (! aspath)
 
1204
    return NULL;
 
1205
  return aspath;
 
1206
}
 
1207
 
 
1208
/* Compile function for as-path prepend. */
 
1209
void
 
1210
route_set_aspath_prepend_free (void *rule)
 
1211
{
 
1212
  struct aspath *aspath = rule;
 
1213
  aspath_free (aspath);
 
1214
}
 
1215
 
 
1216
/* Set metric rule structure. */
 
1217
struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
 
1218
{
 
1219
  "as-path prepend",
 
1220
  route_set_aspath_prepend,
 
1221
  route_set_aspath_prepend_compile,
 
1222
  route_set_aspath_prepend_free,
 
1223
};
 
1224
 
 
1225
/* `set community COMMUNITY' */
 
1226
struct rmap_com_set
 
1227
{
 
1228
  struct community *com;
 
1229
  int additive;
 
1230
  int none;
 
1231
};
 
1232
 
 
1233
/* For community set mechanism. */
 
1234
route_map_result_t
 
1235
route_set_community (void *rule, struct prefix *prefix,
 
1236
                     route_map_object_t type, void *object)
 
1237
{
 
1238
  struct rmap_com_set *rcs;
 
1239
  struct bgp_info *binfo;
 
1240
  struct attr *attr;
 
1241
  struct community *new = NULL;
 
1242
  struct community *old;
 
1243
  struct community *merge;
 
1244
 
 
1245
  if (type == RMAP_BGP)
 
1246
    {
 
1247
      rcs = rule;
 
1248
      binfo = object;
 
1249
      attr = binfo->attr;
 
1250
      old = attr->community;
 
1251
 
 
1252
      /* "none" case.  */
 
1253
      if (rcs->none)
 
1254
        {
 
1255
          attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
 
1256
          attr->community = NULL;
 
1257
          return RMAP_OKAY;
 
1258
        }
 
1259
 
 
1260
      /* "additive" case.  */
 
1261
      if (rcs->additive && old)
 
1262
        {
 
1263
          merge = community_merge (community_dup (old), rcs->com);
 
1264
          new = community_uniq_sort (merge);
 
1265
          community_free (merge);
 
1266
        }
 
1267
      else
 
1268
        new = community_dup (rcs->com);
 
1269
 
 
1270
      attr->community = new;
 
1271
      attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
1272
    }
 
1273
 
 
1274
  return RMAP_OKAY;
 
1275
}
 
1276
 
 
1277
/* Compile function for set community. */
 
1278
void *
 
1279
route_set_community_compile (const char *arg)
 
1280
{
 
1281
  struct rmap_com_set *rcs;
 
1282
  struct community *com = NULL;
 
1283
  char *sp;
 
1284
  int additive = 0;
 
1285
  int none = 0;
 
1286
  
 
1287
  if (strcmp (arg, "none") == 0)
 
1288
    none = 1;
 
1289
  else
 
1290
    {
 
1291
      sp = strstr (arg, "additive");
 
1292
 
 
1293
      if (sp && sp > arg)
 
1294
        {
 
1295
          /* "additive" keyworkd is included.  */
 
1296
          additive = 1;
 
1297
          *(sp - 1) = '\0';
 
1298
        }
 
1299
 
 
1300
      com = community_str2com (arg);
 
1301
 
 
1302
      if (additive)
 
1303
        *(sp - 1) = ' ';
 
1304
 
 
1305
      if (! com)
 
1306
        return NULL;
 
1307
    }
 
1308
  
 
1309
  rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
 
1310
  memset (rcs, 0, sizeof (struct rmap_com_set));
 
1311
  
 
1312
  rcs->com = com;
 
1313
  rcs->additive = additive;
 
1314
  rcs->none = none;
 
1315
  
 
1316
  return rcs;
 
1317
}
 
1318
 
 
1319
/* Free function for set community. */
 
1320
void
 
1321
route_set_community_free (void *rule)
 
1322
{
 
1323
  struct rmap_com_set *rcs = rule;
 
1324
 
 
1325
  if (rcs->com)
 
1326
    community_free (rcs->com);
 
1327
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
 
1328
}
 
1329
 
 
1330
/* Set community rule structure. */
 
1331
struct route_map_rule_cmd route_set_community_cmd = 
 
1332
{
 
1333
  "community",
 
1334
  route_set_community,
 
1335
  route_set_community_compile,
 
1336
  route_set_community_free,
 
1337
};
 
1338
 
 
1339
/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
 
1340
 
 
1341
/* For community set mechanism. */
 
1342
route_map_result_t
 
1343
route_set_community_delete (void *rule, struct prefix *prefix,
 
1344
                            route_map_object_t type, void *object)
 
1345
{
 
1346
  struct community_list *list;
 
1347
  struct community *merge;
 
1348
  struct community *new;
 
1349
  struct community *old;
 
1350
  struct bgp_info *binfo;
 
1351
 
 
1352
  if (type == RMAP_BGP)
 
1353
    {
 
1354
      if (! rule)
 
1355
        return RMAP_OKAY;
 
1356
 
 
1357
      binfo = object;
 
1358
      list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
 
1359
      old = binfo->attr->community;
 
1360
 
 
1361
      if (list && old)
 
1362
        {
 
1363
          merge = community_list_match_delete (community_dup (old), list);
 
1364
          new = community_uniq_sort (merge);
 
1365
          community_free (merge);
 
1366
 
 
1367
          if (new->size == 0)
 
1368
            {
 
1369
              binfo->attr->community = NULL;
 
1370
              binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
1371
              community_free (new);
 
1372
            }
 
1373
          else
 
1374
            {
 
1375
              binfo->attr->community = new;
 
1376
              binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
1377
            }
 
1378
        }
 
1379
    }
 
1380
 
 
1381
  return RMAP_OKAY;
 
1382
}
 
1383
 
 
1384
/* Compile function for set community. */
 
1385
void *
 
1386
route_set_community_delete_compile (const char *arg)
 
1387
{
 
1388
  char *p;
 
1389
  char *str;
 
1390
  int len;
 
1391
 
 
1392
  p = strchr (arg, ' ');
 
1393
  if (p)
 
1394
    {
 
1395
      len = p - arg;
 
1396
      str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
 
1397
      memcpy (str, arg, len);
 
1398
    }
 
1399
  else
 
1400
    str = NULL;
 
1401
 
 
1402
  return str;
 
1403
}
 
1404
 
 
1405
/* Free function for set community. */
 
1406
void
 
1407
route_set_community_delete_free (void *rule)
 
1408
{
 
1409
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1410
}
 
1411
 
 
1412
/* Set community rule structure. */
 
1413
struct route_map_rule_cmd route_set_community_delete_cmd =
 
1414
{
 
1415
  "comm-list",
 
1416
  route_set_community_delete,
 
1417
  route_set_community_delete_compile,
 
1418
  route_set_community_delete_free,
 
1419
};
 
1420
 
 
1421
/* `set extcommunity rt COMMUNITY' */
 
1422
 
 
1423
/* For community set mechanism. */
 
1424
route_map_result_t
 
1425
route_set_ecommunity_rt (void *rule, struct prefix *prefix, 
 
1426
                         route_map_object_t type, void *object)
 
1427
{
 
1428
  struct ecommunity *ecom;
 
1429
  struct ecommunity *new_ecom;
 
1430
  struct ecommunity *old_ecom;
 
1431
  struct bgp_info *bgp_info;
 
1432
 
 
1433
  if (type == RMAP_BGP)
 
1434
    {
 
1435
      ecom = rule;
 
1436
      bgp_info = object;
 
1437
    
 
1438
      if (! ecom)
 
1439
        return RMAP_OKAY;
 
1440
    
 
1441
      /* We assume additive for Extended Community. */
 
1442
      old_ecom = bgp_info->attr->ecommunity;
 
1443
 
 
1444
      if (old_ecom)
 
1445
        new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
 
1446
      else
 
1447
        new_ecom = ecommunity_dup (ecom);
 
1448
 
 
1449
      bgp_info->attr->ecommunity = new_ecom;
 
1450
 
 
1451
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
 
1452
    }
 
1453
  return RMAP_OKAY;
 
1454
}
 
1455
 
 
1456
/* Compile function for set community. */
 
1457
void *
 
1458
route_set_ecommunity_rt_compile (const char *arg)
 
1459
{
 
1460
  struct ecommunity *ecom;
 
1461
 
 
1462
  ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
 
1463
  if (! ecom)
 
1464
    return NULL;
 
1465
  return ecom;
 
1466
}
 
1467
 
 
1468
/* Free function for set community. */
 
1469
void
 
1470
route_set_ecommunity_rt_free (void *rule)
 
1471
{
 
1472
  struct ecommunity *ecom = rule;
 
1473
  ecommunity_free (ecom);
 
1474
}
 
1475
 
 
1476
/* Set community rule structure. */
 
1477
struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
 
1478
{
 
1479
  "extcommunity rt",
 
1480
  route_set_ecommunity_rt,
 
1481
  route_set_ecommunity_rt_compile,
 
1482
  route_set_ecommunity_rt_free,
 
1483
};
 
1484
 
 
1485
/* `set extcommunity soo COMMUNITY' */
 
1486
 
 
1487
/* For community set mechanism. */
 
1488
route_map_result_t
 
1489
route_set_ecommunity_soo (void *rule, struct prefix *prefix, 
 
1490
                         route_map_object_t type, void *object)
 
1491
{
 
1492
  struct ecommunity *ecom;
 
1493
  struct bgp_info *bgp_info;
 
1494
 
 
1495
  if (type == RMAP_BGP)
 
1496
    {
 
1497
      ecom = rule;
 
1498
      bgp_info = object;
 
1499
    
 
1500
      if (! ecom)
 
1501
        return RMAP_OKAY;
 
1502
    
 
1503
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
 
1504
      bgp_info->attr->ecommunity = ecommunity_dup (ecom);
 
1505
    }
 
1506
  return RMAP_OKAY;
 
1507
}
 
1508
 
 
1509
/* Compile function for set community. */
 
1510
void *
 
1511
route_set_ecommunity_soo_compile (const char *arg)
 
1512
{
 
1513
  struct ecommunity *ecom;
 
1514
 
 
1515
  ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
 
1516
  if (! ecom)
 
1517
    return NULL;
 
1518
  
 
1519
  return ecom;
 
1520
}
 
1521
 
 
1522
/* Free function for set community. */
 
1523
void
 
1524
route_set_ecommunity_soo_free (void *rule)
 
1525
{
 
1526
  struct ecommunity *ecom = rule;
 
1527
  ecommunity_free (ecom);
 
1528
}
 
1529
 
 
1530
/* Set community rule structure. */
 
1531
struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
 
1532
{
 
1533
  "extcommunity soo",
 
1534
  route_set_ecommunity_soo,
 
1535
  route_set_ecommunity_soo_compile,
 
1536
  route_set_ecommunity_soo_free,
 
1537
};
 
1538
 
 
1539
/* `set origin ORIGIN' */
 
1540
 
 
1541
/* For origin set. */
 
1542
route_map_result_t
 
1543
route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
 
1544
{
 
1545
  u_char *origin;
 
1546
  struct bgp_info *bgp_info;
 
1547
 
 
1548
  if (type == RMAP_BGP)
 
1549
    {
 
1550
      origin = rule;
 
1551
      bgp_info = object;
 
1552
    
 
1553
      bgp_info->attr->origin = *origin;
 
1554
    }
 
1555
 
 
1556
  return RMAP_OKAY;
 
1557
}
 
1558
 
 
1559
/* Compile function for origin set. */
 
1560
void *
 
1561
route_set_origin_compile (const char *arg)
 
1562
{
 
1563
  u_char *origin;
 
1564
 
 
1565
  origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
 
1566
 
 
1567
  if (strcmp (arg, "igp") == 0)
 
1568
    *origin = 0;
 
1569
  else if (strcmp (arg, "egp") == 0)
 
1570
    *origin = 1;
 
1571
  else
 
1572
    *origin = 2;
 
1573
 
 
1574
  return origin;
 
1575
}
 
1576
 
 
1577
/* Compile function for origin set. */
 
1578
void
 
1579
route_set_origin_free (void *rule)
 
1580
{
 
1581
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1582
}
 
1583
 
 
1584
/* Set metric rule structure. */
 
1585
struct route_map_rule_cmd route_set_origin_cmd = 
 
1586
{
 
1587
  "origin",
 
1588
  route_set_origin,
 
1589
  route_set_origin_compile,
 
1590
  route_set_origin_free,
 
1591
};
 
1592
 
 
1593
/* `set atomic-aggregate' */
 
1594
 
 
1595
/* For atomic aggregate set. */
 
1596
route_map_result_t
 
1597
route_set_atomic_aggregate (void *rule, struct prefix *prefix,
 
1598
                            route_map_object_t type, void *object)
 
1599
{
 
1600
  struct bgp_info *bgp_info;
 
1601
 
 
1602
  if (type == RMAP_BGP)
 
1603
    {
 
1604
      bgp_info = object;
 
1605
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
 
1606
    }
 
1607
 
 
1608
  return RMAP_OKAY;
 
1609
}
 
1610
 
 
1611
/* Compile function for atomic aggregate. */
 
1612
void *
 
1613
route_set_atomic_aggregate_compile (const char *arg)
 
1614
{
 
1615
  return (void *)1;
 
1616
}
 
1617
 
 
1618
/* Compile function for atomic aggregate. */
 
1619
void
 
1620
route_set_atomic_aggregate_free (void *rule)
 
1621
{
 
1622
  return;
 
1623
}
 
1624
 
 
1625
/* Set atomic aggregate rule structure. */
 
1626
struct route_map_rule_cmd route_set_atomic_aggregate_cmd = 
 
1627
{
 
1628
  "atomic-aggregate",
 
1629
  route_set_atomic_aggregate,
 
1630
  route_set_atomic_aggregate_compile,
 
1631
  route_set_atomic_aggregate_free,
 
1632
};
 
1633
 
 
1634
/* `set aggregator as AS A.B.C.D' */
 
1635
struct aggregator
 
1636
{
 
1637
  as_t as;
 
1638
  struct in_addr address;
 
1639
};
 
1640
 
 
1641
route_map_result_t
 
1642
route_set_aggregator_as (void *rule, struct prefix *prefix, 
 
1643
                         route_map_object_t type, void *object)
 
1644
{
 
1645
  struct bgp_info *bgp_info;
 
1646
  struct aggregator *aggregator;
 
1647
 
 
1648
  if (type == RMAP_BGP)
 
1649
    {
 
1650
      bgp_info = object;
 
1651
      aggregator = rule;
 
1652
    
 
1653
      bgp_info->attr->aggregator_as = aggregator->as;
 
1654
      bgp_info->attr->aggregator_addr = aggregator->address;
 
1655
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
 
1656
    }
 
1657
 
 
1658
  return RMAP_OKAY;
 
1659
}
 
1660
 
 
1661
void *
 
1662
route_set_aggregator_as_compile (const char *arg)
 
1663
{
 
1664
  struct aggregator *aggregator;
 
1665
  char as[10];
 
1666
  char address[20];
 
1667
 
 
1668
  aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
 
1669
  memset (aggregator, 0, sizeof (struct aggregator));
 
1670
 
 
1671
  sscanf (arg, "%s %s", as, address);
 
1672
 
 
1673
  aggregator->as = strtoul (as, NULL, 10);
 
1674
  inet_aton (address, &aggregator->address);
 
1675
 
 
1676
  return aggregator;
 
1677
}
 
1678
 
 
1679
void
 
1680
route_set_aggregator_as_free (void *rule)
 
1681
{
 
1682
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1683
}
 
1684
 
 
1685
struct route_map_rule_cmd route_set_aggregator_as_cmd = 
 
1686
{
 
1687
  "aggregator as",
 
1688
  route_set_aggregator_as,
 
1689
  route_set_aggregator_as_compile,
 
1690
  route_set_aggregator_as_free,
 
1691
};
 
1692
 
 
1693
#ifdef HAVE_IPV6
 
1694
/* `match ipv6 address IP_ACCESS_LIST' */
 
1695
 
 
1696
route_map_result_t
 
1697
route_match_ipv6_address (void *rule, struct prefix *prefix, 
 
1698
                          route_map_object_t type, void *object)
 
1699
{
 
1700
  struct access_list *alist;
 
1701
 
 
1702
  if (type == RMAP_BGP)
 
1703
    {
 
1704
      alist = access_list_lookup (AFI_IP6, (char *) rule);
 
1705
      if (alist == NULL)
 
1706
        return RMAP_NOMATCH;
 
1707
    
 
1708
      return (access_list_apply (alist, prefix) == FILTER_DENY ?
 
1709
              RMAP_NOMATCH : RMAP_MATCH);
 
1710
    }
 
1711
  return RMAP_NOMATCH;
 
1712
}
 
1713
 
 
1714
void *
 
1715
route_match_ipv6_address_compile (const char *arg)
 
1716
{
 
1717
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
1718
}
 
1719
 
 
1720
void
 
1721
route_match_ipv6_address_free (void *rule)
 
1722
{
 
1723
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1724
}
 
1725
 
 
1726
/* Route map commands for ip address matching. */
 
1727
struct route_map_rule_cmd route_match_ipv6_address_cmd =
 
1728
{
 
1729
  "ipv6 address",
 
1730
  route_match_ipv6_address,
 
1731
  route_match_ipv6_address_compile,
 
1732
  route_match_ipv6_address_free
 
1733
};
 
1734
 
 
1735
/* `match ipv6 next-hop IP_ADDRESS' */
 
1736
 
 
1737
route_map_result_t
 
1738
route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
 
1739
                           route_map_object_t type, void *object)
 
1740
{
 
1741
  struct in6_addr *addr;
 
1742
  struct bgp_info *bgp_info;
 
1743
 
 
1744
  if (type == RMAP_BGP)
 
1745
    {
 
1746
      addr = rule;
 
1747
      bgp_info = object;
 
1748
    
 
1749
      if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
 
1750
        return RMAP_MATCH;
 
1751
 
 
1752
      if (bgp_info->attr->mp_nexthop_len == 32 &&
 
1753
          IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
 
1754
        return RMAP_MATCH;
 
1755
 
 
1756
      return RMAP_NOMATCH;
 
1757
    }
 
1758
 
 
1759
  return RMAP_NOMATCH;
 
1760
}
 
1761
 
 
1762
void *
 
1763
route_match_ipv6_next_hop_compile (const char *arg)
 
1764
{
 
1765
  struct in6_addr *address;
 
1766
  int ret;
 
1767
 
 
1768
  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
 
1769
 
 
1770
  ret = inet_pton (AF_INET6, arg, address);
 
1771
  if (!ret)
 
1772
    {
 
1773
      XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
1774
      return NULL;
 
1775
    }
 
1776
 
 
1777
  return address;
 
1778
}
 
1779
 
 
1780
void
 
1781
route_match_ipv6_next_hop_free (void *rule)
 
1782
{
 
1783
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1784
}
 
1785
 
 
1786
struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
 
1787
{
 
1788
  "ipv6 next-hop",
 
1789
  route_match_ipv6_next_hop,
 
1790
  route_match_ipv6_next_hop_compile,
 
1791
  route_match_ipv6_next_hop_free
 
1792
};
 
1793
 
 
1794
/* `match ipv6 address prefix-list PREFIX_LIST' */
 
1795
 
 
1796
route_map_result_t
 
1797
route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, 
 
1798
                              route_map_object_t type, void *object)
 
1799
{
 
1800
  struct prefix_list *plist;
 
1801
 
 
1802
  if (type == RMAP_BGP)
 
1803
    {
 
1804
      plist = prefix_list_lookup (AFI_IP6, (char *) rule);
 
1805
      if (plist == NULL)
 
1806
        return RMAP_NOMATCH;
 
1807
    
 
1808
      return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
 
1809
              RMAP_NOMATCH : RMAP_MATCH);
 
1810
    }
 
1811
  return RMAP_NOMATCH;
 
1812
}
 
1813
 
 
1814
void *
 
1815
route_match_ipv6_address_prefix_list_compile (const char *arg)
 
1816
{
 
1817
  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
1818
}
 
1819
 
 
1820
void
 
1821
route_match_ipv6_address_prefix_list_free (void *rule)
 
1822
{
 
1823
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1824
}
 
1825
 
 
1826
struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
 
1827
{
 
1828
  "ipv6 address prefix-list",
 
1829
  route_match_ipv6_address_prefix_list,
 
1830
  route_match_ipv6_address_prefix_list_compile,
 
1831
  route_match_ipv6_address_prefix_list_free
 
1832
};
 
1833
 
 
1834
/* `set ipv6 nexthop global IP_ADDRESS' */
 
1835
 
 
1836
/* Set nexthop to object.  ojbect must be pointer to struct attr. */
 
1837
route_map_result_t
 
1838
route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, 
 
1839
                               route_map_object_t type, void *object)
 
1840
{
 
1841
  struct in6_addr *address;
 
1842
  struct bgp_info *bgp_info;
 
1843
 
 
1844
  if (type == RMAP_BGP)
 
1845
    {
 
1846
      /* Fetch routemap's rule information. */
 
1847
      address = rule;
 
1848
      bgp_info = object;
 
1849
    
 
1850
      /* Set next hop value. */ 
 
1851
      bgp_info->attr->mp_nexthop_global = *address;
 
1852
    
 
1853
      /* Set nexthop length. */
 
1854
      if (bgp_info->attr->mp_nexthop_len == 0)
 
1855
        bgp_info->attr->mp_nexthop_len = 16;
 
1856
    }
 
1857
 
 
1858
  return RMAP_OKAY;
 
1859
}
 
1860
 
 
1861
/* Route map `ip next-hop' compile function.  Given string is converted
 
1862
   to struct in_addr structure. */
 
1863
void *
 
1864
route_set_ipv6_nexthop_global_compile (const char *arg)
 
1865
{
 
1866
  int ret;
 
1867
  struct in6_addr *address;
 
1868
 
 
1869
  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
 
1870
 
 
1871
  ret = inet_pton (AF_INET6, arg, address);
 
1872
 
 
1873
  if (ret == 0)
 
1874
    {
 
1875
      XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
1876
      return NULL;
 
1877
    }
 
1878
 
 
1879
  return address;
 
1880
}
 
1881
 
 
1882
/* Free route map's compiled `ip next-hop' value. */
 
1883
void
 
1884
route_set_ipv6_nexthop_global_free (void *rule)
 
1885
{
 
1886
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1887
}
 
1888
 
 
1889
/* Route map commands for ip nexthop set. */
 
1890
struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
 
1891
{
 
1892
  "ipv6 next-hop global",
 
1893
  route_set_ipv6_nexthop_global,
 
1894
  route_set_ipv6_nexthop_global_compile,
 
1895
  route_set_ipv6_nexthop_global_free
 
1896
};
 
1897
 
 
1898
/* `set ipv6 nexthop local IP_ADDRESS' */
 
1899
 
 
1900
/* Set nexthop to object.  ojbect must be pointer to struct attr. */
 
1901
route_map_result_t
 
1902
route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
 
1903
                              route_map_object_t type, void *object)
 
1904
{
 
1905
  struct in6_addr *address;
 
1906
  struct bgp_info *bgp_info;
 
1907
 
 
1908
  if (type == RMAP_BGP)
 
1909
    {
 
1910
      /* Fetch routemap's rule information. */
 
1911
      address = rule;
 
1912
      bgp_info = object;
 
1913
    
 
1914
      /* Set next hop value. */ 
 
1915
      bgp_info->attr->mp_nexthop_local = *address;
 
1916
    
 
1917
      /* Set nexthop length. */
 
1918
      if (bgp_info->attr->mp_nexthop_len != 32)
 
1919
        bgp_info->attr->mp_nexthop_len = 32;
 
1920
    }
 
1921
 
 
1922
  return RMAP_OKAY;
 
1923
}
 
1924
 
 
1925
/* Route map `ip nexthop' compile function.  Given string is converted
 
1926
   to struct in_addr structure. */
 
1927
void *
 
1928
route_set_ipv6_nexthop_local_compile (const char *arg)
 
1929
{
 
1930
  int ret;
 
1931
  struct in6_addr *address;
 
1932
 
 
1933
  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
 
1934
 
 
1935
  ret = inet_pton (AF_INET6, arg, address);
 
1936
 
 
1937
  if (ret == 0)
 
1938
    {
 
1939
      XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
1940
      return NULL;
 
1941
    }
 
1942
 
 
1943
  return address;
 
1944
}
 
1945
 
 
1946
/* Free route map's compiled `ip nexthop' value. */
 
1947
void
 
1948
route_set_ipv6_nexthop_local_free (void *rule)
 
1949
{
 
1950
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1951
}
 
1952
 
 
1953
/* Route map commands for ip nexthop set. */
 
1954
struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
 
1955
{
 
1956
  "ipv6 next-hop local",
 
1957
  route_set_ipv6_nexthop_local,
 
1958
  route_set_ipv6_nexthop_local_compile,
 
1959
  route_set_ipv6_nexthop_local_free
 
1960
};
 
1961
#endif /* HAVE_IPV6 */
 
1962
 
 
1963
/* `set vpnv4 nexthop A.B.C.D' */
 
1964
 
 
1965
route_map_result_t
 
1966
route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, 
 
1967
                         route_map_object_t type, void *object)
 
1968
{
 
1969
  struct in_addr *address;
 
1970
  struct bgp_info *bgp_info;
 
1971
 
 
1972
  if (type == RMAP_BGP)
 
1973
    {
 
1974
      /* Fetch routemap's rule information. */
 
1975
      address = rule;
 
1976
      bgp_info = object;
 
1977
    
 
1978
      /* Set next hop value. */ 
 
1979
      bgp_info->attr->mp_nexthop_global_in = *address;
 
1980
    }
 
1981
 
 
1982
  return RMAP_OKAY;
 
1983
}
 
1984
 
 
1985
void *
 
1986
route_set_vpnv4_nexthop_compile (const char *arg)
 
1987
{
 
1988
  int ret;
 
1989
  struct in_addr *address;
 
1990
 
 
1991
  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
 
1992
 
 
1993
  ret = inet_aton (arg, address);
 
1994
 
 
1995
  if (ret == 0)
 
1996
    {
 
1997
      XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
1998
      return NULL;
 
1999
    }
 
2000
 
 
2001
  return address;
 
2002
}
 
2003
 
 
2004
void
 
2005
route_set_vpnv4_nexthop_free (void *rule)
 
2006
{
 
2007
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
2008
}
 
2009
 
 
2010
/* Route map commands for ip nexthop set. */
 
2011
struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
 
2012
{
 
2013
  "vpnv4 next-hop",
 
2014
  route_set_vpnv4_nexthop,
 
2015
  route_set_vpnv4_nexthop_compile,
 
2016
  route_set_vpnv4_nexthop_free
 
2017
};
 
2018
 
 
2019
/* `set originator-id' */
 
2020
 
 
2021
/* For origin set. */
 
2022
route_map_result_t
 
2023
route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
 
2024
{
 
2025
  struct in_addr *address;
 
2026
  struct bgp_info *bgp_info;
 
2027
 
 
2028
  if (type == RMAP_BGP) 
 
2029
    {
 
2030
      address = rule;
 
2031
      bgp_info = object;
 
2032
    
 
2033
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
 
2034
      bgp_info->attr->originator_id = *address;
 
2035
    }
 
2036
 
 
2037
  return RMAP_OKAY;
 
2038
}
 
2039
 
 
2040
/* Compile function for originator-id set. */
 
2041
void *
 
2042
route_set_originator_id_compile (const char *arg)
 
2043
{
 
2044
  int ret;
 
2045
  struct in_addr *address;
 
2046
 
 
2047
  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
 
2048
 
 
2049
  ret = inet_aton (arg, address);
 
2050
 
 
2051
  if (ret == 0)
 
2052
    {
 
2053
      XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
2054
      return NULL;
 
2055
    }
 
2056
 
 
2057
  return address;
 
2058
}
 
2059
 
 
2060
/* Compile function for originator_id set. */
 
2061
void
 
2062
route_set_originator_id_free (void *rule)
 
2063
{
 
2064
  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
2065
}
 
2066
 
 
2067
/* Set metric rule structure. */
 
2068
struct route_map_rule_cmd route_set_originator_id_cmd = 
 
2069
{
 
2070
  "originator-id",
 
2071
  route_set_originator_id,
 
2072
  route_set_originator_id_compile,
 
2073
  route_set_originator_id_free,
 
2074
};
 
2075
 
 
2076
/* Add bgp route map rule. */
 
2077
int
 
2078
bgp_route_match_add (struct vty *vty, struct route_map_index *index,
 
2079
                     const char *command, const char *arg)
 
2080
{
 
2081
  int ret;
 
2082
 
 
2083
  ret = route_map_add_match (index, command, arg);
 
2084
  if (ret)
 
2085
    {
 
2086
      switch (ret)
 
2087
        {
 
2088
        case RMAP_RULE_MISSING:
 
2089
          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 
2090
          return CMD_WARNING;
 
2091
          break;
 
2092
        case RMAP_COMPILE_ERROR:
 
2093
          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 
2094
          return CMD_WARNING;
 
2095
          break;
 
2096
        }
 
2097
    }
 
2098
  return CMD_SUCCESS;
 
2099
}
 
2100
 
 
2101
/* Delete bgp route map rule. */
 
2102
int
 
2103
bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
 
2104
                        const char *command, const char *arg)
 
2105
{
 
2106
  int ret;
 
2107
 
 
2108
  ret = route_map_delete_match (index, command, arg);
 
2109
  if (ret)
 
2110
    {
 
2111
      switch (ret)
 
2112
        {
 
2113
        case RMAP_RULE_MISSING:
 
2114
          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 
2115
          return CMD_WARNING;
 
2116
          break;
 
2117
        case RMAP_COMPILE_ERROR:
 
2118
          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 
2119
          return CMD_WARNING;
 
2120
          break;
 
2121
        }
 
2122
    }
 
2123
  return CMD_SUCCESS;
 
2124
}
 
2125
 
 
2126
/* Add bgp route map rule. */
 
2127
int
 
2128
bgp_route_set_add (struct vty *vty, struct route_map_index *index,
 
2129
                   const char *command, const char *arg)
 
2130
{
 
2131
  int ret;
 
2132
 
 
2133
  ret = route_map_add_set (index, command, arg);
 
2134
  if (ret)
 
2135
    {
 
2136
      switch (ret)
 
2137
        {
 
2138
        case RMAP_RULE_MISSING:
 
2139
          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 
2140
          return CMD_WARNING;
 
2141
          break;
 
2142
        case RMAP_COMPILE_ERROR:
 
2143
          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 
2144
          return CMD_WARNING;
 
2145
          break;
 
2146
        }
 
2147
    }
 
2148
  return CMD_SUCCESS;
 
2149
}
 
2150
 
 
2151
/* Delete bgp route map rule. */
 
2152
int
 
2153
bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
 
2154
                      const char *command, const char *arg)
 
2155
{
 
2156
  int ret;
 
2157
 
 
2158
  ret = route_map_delete_set (index, command, arg);
 
2159
  if (ret)
 
2160
    {
 
2161
      switch (ret)
 
2162
        {
 
2163
        case RMAP_RULE_MISSING:
 
2164
          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 
2165
          return CMD_WARNING;
 
2166
          break;
 
2167
        case RMAP_COMPILE_ERROR:
 
2168
          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 
2169
          return CMD_WARNING;
 
2170
          break;
 
2171
        }
 
2172
    }
 
2173
  return CMD_SUCCESS;
 
2174
}
 
2175
 
 
2176
/* Hook function for updating route_map assignment. */
 
2177
void
 
2178
bgp_route_map_update (const char *unused)
 
2179
{
 
2180
  int i;
 
2181
  afi_t afi;
 
2182
  safi_t safi;
 
2183
  int direct;
 
2184
  struct listnode *node, *nnode;
 
2185
  struct listnode *mnode, *mnnode;
 
2186
  struct bgp *bgp;
 
2187
  struct peer *peer;
 
2188
  struct peer_group *group;
 
2189
  struct bgp_filter *filter;
 
2190
  struct bgp_node *bn;
 
2191
  struct bgp_static *bgp_static;
 
2192
 
 
2193
  /* For neighbor route-map updates. */
 
2194
  for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 
2195
    {
 
2196
      for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 
2197
        {
 
2198
          for (afi = AFI_IP; afi < AFI_MAX; afi++)
 
2199
            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 
2200
              {
 
2201
                filter = &peer->filter[afi][safi];
 
2202
          
 
2203
               for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
 
2204
                  {
 
2205
                    if (filter->map[direct].name)
 
2206
                      filter->map[direct].map = 
 
2207
                        route_map_lookup_by_name (filter->map[direct].name);
 
2208
                    else
 
2209
                      filter->map[direct].map = NULL;
 
2210
                  }
 
2211
 
 
2212
                if (filter->usmap.name)
 
2213
                  filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
 
2214
                else
 
2215
                  filter->usmap.map = NULL;
 
2216
              }
 
2217
        }
 
2218
      for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 
2219
        {
 
2220
          for (afi = AFI_IP; afi < AFI_MAX; afi++)
 
2221
            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 
2222
              {
 
2223
                filter = &group->conf->filter[afi][safi];
 
2224
          
 
2225
               for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
 
2226
                  {
 
2227
                    if (filter->map[direct].name)
 
2228
                      filter->map[direct].map = 
 
2229
                        route_map_lookup_by_name (filter->map[direct].name);
 
2230
                    else
 
2231
                      filter->map[direct].map = NULL;
 
2232
                  }
 
2233
 
 
2234
                if (filter->usmap.name)
 
2235
                  filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
 
2236
                else
 
2237
                  filter->usmap.map = NULL;
 
2238
              }
 
2239
        }
 
2240
    }
 
2241
 
 
2242
  /* For default-originate route-map updates. */
 
2243
  for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 
2244
    {
 
2245
      for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 
2246
        {
 
2247
          for (afi = AFI_IP; afi < AFI_MAX; afi++)
 
2248
            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 
2249
              {
 
2250
                if (peer->default_rmap[afi][safi].name)
 
2251
                  peer->default_rmap[afi][safi].map =
 
2252
                    route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
 
2253
                else
 
2254
                  peer->default_rmap[afi][safi].map = NULL;
 
2255
              }
 
2256
        }
 
2257
    }
 
2258
 
 
2259
  /* For network route-map updates. */
 
2260
  for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 
2261
    {
 
2262
      for (afi = AFI_IP; afi < AFI_MAX; afi++)
 
2263
        for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 
2264
          for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
 
2265
               bn = bgp_route_next (bn))
 
2266
            if ((bgp_static = bn->info) != NULL)
 
2267
              {
 
2268
                if (bgp_static->rmap.name)
 
2269
                  bgp_static->rmap.map =
 
2270
                         route_map_lookup_by_name (bgp_static->rmap.name);
 
2271
                else
 
2272
                  bgp_static->rmap.map = NULL;
 
2273
              }
 
2274
    }
 
2275
 
 
2276
  /* For redistribute route-map updates. */
 
2277
  for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 
2278
    {
 
2279
      for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
2280
        {
 
2281
          if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
 
2282
            bgp->rmap[ZEBRA_FAMILY_IPV4][i].map = 
 
2283
              route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
 
2284
#ifdef HAVE_IPV6
 
2285
          if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
 
2286
            bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
 
2287
              route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
 
2288
#endif /* HAVE_IPV6 */
 
2289
        }
 
2290
    }
 
2291
}
 
2292
 
 
2293
DEFUN (match_peer,
 
2294
       match_peer_cmd,
 
2295
       "match peer (A.B.C.D|X:X::X:X)",
 
2296
       MATCH_STR
 
2297
       "Match peer address\n"
 
2298
       "IPv6 address of peer\n"
 
2299
       "IP address of peer\n")
 
2300
{
 
2301
  return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
 
2302
}
 
2303
 
 
2304
DEFUN (match_peer_local,
 
2305
        match_peer_local_cmd,
 
2306
        "match peer local",
 
2307
        MATCH_STR
 
2308
        "Match peer address\n"
 
2309
        "Static or Redistributed routes\n")
 
2310
{
 
2311
  return bgp_route_match_add (vty, vty->index, "peer", NULL);
 
2312
}
 
2313
 
 
2314
DEFUN (no_match_peer,
 
2315
       no_match_peer_cmd,
 
2316
       "no match peer",
 
2317
       NO_STR
 
2318
       MATCH_STR
 
2319
       "Match peer address\n")
 
2320
{
 
2321
 if (argc == 0)
 
2322
   return bgp_route_match_delete (vty, vty->index, "peer", NULL);
 
2323
 
 
2324
  return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
 
2325
}
 
2326
 
 
2327
ALIAS (no_match_peer,
 
2328
       no_match_peer_val_cmd,
 
2329
       "no match peer (A.B.C.D|X:X::X:X)",
 
2330
       NO_STR
 
2331
       MATCH_STR
 
2332
       "Match peer address\n"
 
2333
       "IPv6 address of peer\n"
 
2334
       "IP address of peer\n")
 
2335
 
 
2336
ALIAS (no_match_peer,
 
2337
       no_match_peer_local_cmd,
 
2338
       "no match peer local",
 
2339
       NO_STR
 
2340
       MATCH_STR
 
2341
       "Match peer address\n"
 
2342
       "Static or Redistributed routes\n")
 
2343
 
 
2344
DEFUN (match_ip_address, 
 
2345
       match_ip_address_cmd,
 
2346
       "match ip address (<1-199>|<1300-2699>|WORD)",
 
2347
       MATCH_STR
 
2348
       IP_STR
 
2349
       "Match address of route\n"
 
2350
       "IP access-list number\n"
 
2351
       "IP access-list number (expanded range)\n"
 
2352
       "IP Access-list name\n")
 
2353
{
 
2354
  return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
 
2355
}
 
2356
 
 
2357
DEFUN (no_match_ip_address, 
 
2358
       no_match_ip_address_cmd,
 
2359
       "no match ip address",
 
2360
       NO_STR
 
2361
       MATCH_STR
 
2362
       IP_STR
 
2363
       "Match address of route\n")
 
2364
{
 
2365
  if (argc == 0)
 
2366
    return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
 
2367
 
 
2368
  return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
 
2369
}
 
2370
 
 
2371
ALIAS (no_match_ip_address, 
 
2372
       no_match_ip_address_val_cmd,
 
2373
       "no match ip address (<1-199>|<1300-2699>|WORD)",
 
2374
       NO_STR
 
2375
       MATCH_STR
 
2376
       IP_STR
 
2377
       "Match address of route\n"
 
2378
       "IP access-list number\n"
 
2379
       "IP access-list number (expanded range)\n"
 
2380
       "IP Access-list name\n")
 
2381
 
 
2382
DEFUN (match_ip_next_hop, 
 
2383
       match_ip_next_hop_cmd,
 
2384
       "match ip next-hop (<1-199>|<1300-2699>|WORD)",
 
2385
       MATCH_STR
 
2386
       IP_STR
 
2387
       "Match next-hop address of route\n"
 
2388
       "IP access-list number\n"
 
2389
       "IP access-list number (expanded range)\n"
 
2390
       "IP Access-list name\n")
 
2391
{
 
2392
  return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
 
2393
}
 
2394
 
 
2395
DEFUN (no_match_ip_next_hop,
 
2396
       no_match_ip_next_hop_cmd,
 
2397
       "no match ip next-hop",
 
2398
       NO_STR
 
2399
       MATCH_STR
 
2400
       IP_STR
 
2401
       "Match next-hop address of route\n")
 
2402
{
 
2403
  if (argc == 0)
 
2404
    return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
 
2405
 
 
2406
  return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
 
2407
}
 
2408
 
 
2409
ALIAS (no_match_ip_next_hop,
 
2410
       no_match_ip_next_hop_val_cmd,
 
2411
       "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
 
2412
       NO_STR
 
2413
       MATCH_STR
 
2414
       IP_STR
 
2415
       "Match next-hop address of route\n"
 
2416
       "IP access-list number\n"
 
2417
       "IP access-list number (expanded range)\n"
 
2418
       "IP Access-list name\n")
 
2419
 
 
2420
DEFUN (match_ip_route_source, 
 
2421
       match_ip_route_source_cmd,
 
2422
       "match ip route-source (<1-199>|<1300-2699>|WORD)",
 
2423
       MATCH_STR
 
2424
       IP_STR
 
2425
       "Match advertising source address of route\n"
 
2426
       "IP access-list number\n"
 
2427
       "IP access-list number (expanded range)\n"
 
2428
       "IP standard access-list name\n")
 
2429
{
 
2430
  return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
 
2431
}
 
2432
 
 
2433
DEFUN (no_match_ip_route_source,
 
2434
       no_match_ip_route_source_cmd,
 
2435
       "no match ip route-source",
 
2436
       NO_STR
 
2437
       MATCH_STR
 
2438
       IP_STR
 
2439
       "Match advertising source address of route\n")
 
2440
{
 
2441
  if (argc == 0)
 
2442
    return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
 
2443
 
 
2444
  return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
 
2445
}
 
2446
 
 
2447
ALIAS (no_match_ip_route_source,
 
2448
       no_match_ip_route_source_val_cmd,
 
2449
       "no match ip route-source (<1-199>|<1300-2699>|WORD)",
 
2450
       NO_STR
 
2451
       MATCH_STR
 
2452
       IP_STR
 
2453
       "Match advertising source address of route\n"
 
2454
       "IP access-list number\n"
 
2455
       "IP access-list number (expanded range)\n"
 
2456
       "IP standard access-list name\n");
 
2457
 
 
2458
DEFUN (match_ip_address_prefix_list, 
 
2459
       match_ip_address_prefix_list_cmd,
 
2460
       "match ip address prefix-list WORD",
 
2461
       MATCH_STR
 
2462
       IP_STR
 
2463
       "Match address of route\n"
 
2464
       "Match entries of prefix-lists\n"
 
2465
       "IP prefix-list name\n")
 
2466
{
 
2467
  return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
 
2468
}
 
2469
 
 
2470
DEFUN (no_match_ip_address_prefix_list,
 
2471
       no_match_ip_address_prefix_list_cmd,
 
2472
       "no match ip address prefix-list",
 
2473
       NO_STR
 
2474
       MATCH_STR
 
2475
       IP_STR
 
2476
       "Match address of route\n"
 
2477
       "Match entries of prefix-lists\n")
 
2478
{
 
2479
  if (argc == 0)
 
2480
    return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
 
2481
 
 
2482
  return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
 
2483
}
 
2484
 
 
2485
ALIAS (no_match_ip_address_prefix_list,
 
2486
       no_match_ip_address_prefix_list_val_cmd,
 
2487
       "no match ip address prefix-list WORD",
 
2488
       NO_STR
 
2489
       MATCH_STR
 
2490
       IP_STR
 
2491
       "Match address of route\n"
 
2492
       "Match entries of prefix-lists\n"
 
2493
       "IP prefix-list name\n")
 
2494
 
 
2495
DEFUN (match_ip_next_hop_prefix_list, 
 
2496
       match_ip_next_hop_prefix_list_cmd,
 
2497
       "match ip next-hop prefix-list WORD",
 
2498
       MATCH_STR
 
2499
       IP_STR
 
2500
       "Match next-hop address of route\n"
 
2501
       "Match entries of prefix-lists\n"
 
2502
       "IP prefix-list name\n")
 
2503
{
 
2504
  return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 
2505
}
 
2506
 
 
2507
DEFUN (no_match_ip_next_hop_prefix_list,
 
2508
       no_match_ip_next_hop_prefix_list_cmd,
 
2509
       "no match ip next-hop prefix-list",
 
2510
       NO_STR
 
2511
       MATCH_STR
 
2512
       IP_STR
 
2513
       "Match next-hop address of route\n"
 
2514
       "Match entries of prefix-lists\n")
 
2515
{
 
2516
  if (argc == 0)
 
2517
    return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
 
2518
 
 
2519
  return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 
2520
}
 
2521
 
 
2522
ALIAS (no_match_ip_next_hop_prefix_list,
 
2523
       no_match_ip_next_hop_prefix_list_val_cmd,
 
2524
       "no match ip next-hop prefix-list WORD",
 
2525
       NO_STR
 
2526
       MATCH_STR
 
2527
       IP_STR
 
2528
       "Match next-hop address of route\n"
 
2529
       "Match entries of prefix-lists\n"
 
2530
       "IP prefix-list name\n")
 
2531
 
 
2532
DEFUN (match_ip_route_source_prefix_list, 
 
2533
       match_ip_route_source_prefix_list_cmd,
 
2534
       "match ip route-source prefix-list WORD",
 
2535
       MATCH_STR
 
2536
       IP_STR
 
2537
       "Match advertising source address of route\n"
 
2538
       "Match entries of prefix-lists\n"
 
2539
       "IP prefix-list name\n")
 
2540
{
 
2541
  return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
 
2542
}
 
2543
 
 
2544
DEFUN (no_match_ip_route_source_prefix_list,
 
2545
       no_match_ip_route_source_prefix_list_cmd,
 
2546
       "no match ip route-source prefix-list",
 
2547
       NO_STR
 
2548
       MATCH_STR
 
2549
       IP_STR
 
2550
       "Match advertising source address of route\n"
 
2551
       "Match entries of prefix-lists\n")
 
2552
{
 
2553
  if (argc == 0)
 
2554
    return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
 
2555
 
 
2556
  return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
 
2557
}
 
2558
 
 
2559
ALIAS (no_match_ip_route_source_prefix_list,
 
2560
       no_match_ip_route_source_prefix_list_val_cmd,
 
2561
       "no match ip route-source prefix-list WORD",
 
2562
       NO_STR
 
2563
       MATCH_STR
 
2564
       IP_STR
 
2565
       "Match advertising source address of route\n"
 
2566
       "Match entries of prefix-lists\n"
 
2567
       "IP prefix-list name\n");
 
2568
 
 
2569
DEFUN (match_metric, 
 
2570
       match_metric_cmd,
 
2571
       "match metric <0-4294967295>",
 
2572
       MATCH_STR
 
2573
       "Match metric of route\n"
 
2574
       "Metric value\n")
 
2575
{
 
2576
  return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
 
2577
}
 
2578
 
 
2579
DEFUN (no_match_metric,
 
2580
       no_match_metric_cmd,
 
2581
       "no match metric",
 
2582
       NO_STR
 
2583
       MATCH_STR
 
2584
       "Match metric of route\n")
 
2585
{
 
2586
  if (argc == 0)
 
2587
    return bgp_route_match_delete (vty, vty->index, "metric", NULL);
 
2588
 
 
2589
  return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
 
2590
}
 
2591
 
 
2592
ALIAS (no_match_metric,
 
2593
       no_match_metric_val_cmd,
 
2594
       "no match metric <0-4294967295>",
 
2595
       NO_STR
 
2596
       MATCH_STR
 
2597
       "Match metric of route\n"
 
2598
       "Metric value\n")
 
2599
 
 
2600
DEFUN (match_community, 
 
2601
       match_community_cmd,
 
2602
       "match community (<1-99>|<100-500>|WORD)",
 
2603
       MATCH_STR
 
2604
       "Match BGP community list\n"
 
2605
       "Community-list number (standard)\n"
 
2606
       "Community-list number (expanded)\n"
 
2607
       "Community-list name\n")
 
2608
{
 
2609
  return bgp_route_match_add (vty, vty->index, "community", argv[0]);
 
2610
}
 
2611
 
 
2612
DEFUN (match_community_exact, 
 
2613
       match_community_exact_cmd,
 
2614
       "match community (<1-99>|<100-500>|WORD) exact-match",
 
2615
       MATCH_STR
 
2616
       "Match BGP community list\n"
 
2617
       "Community-list number (standard)\n"
 
2618
       "Community-list number (expanded)\n"
 
2619
       "Community-list name\n"
 
2620
       "Do exact matching of communities\n")
 
2621
{
 
2622
  int ret;
 
2623
  char *argstr;
 
2624
 
 
2625
  argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
 
2626
                    strlen (argv[0]) + strlen ("exact-match") + 2);
 
2627
 
 
2628
  sprintf (argstr, "%s exact-match", argv[0]);
 
2629
 
 
2630
  ret = bgp_route_match_add (vty, vty->index, "community", argstr);
 
2631
 
 
2632
  XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
 
2633
 
 
2634
  return ret;
 
2635
}
 
2636
 
 
2637
DEFUN (no_match_community,
 
2638
       no_match_community_cmd,
 
2639
       "no match community",
 
2640
       NO_STR
 
2641
       MATCH_STR
 
2642
       "Match BGP community list\n")
 
2643
{
 
2644
  return bgp_route_match_delete (vty, vty->index, "community", NULL);
 
2645
}
 
2646
 
 
2647
ALIAS (no_match_community,
 
2648
       no_match_community_val_cmd,
 
2649
       "no match community (<1-99>|<100-500>|WORD)",
 
2650
       NO_STR
 
2651
       MATCH_STR
 
2652
       "Match BGP community list\n"
 
2653
       "Community-list number (standard)\n"
 
2654
       "Community-list number (expanded)\n"
 
2655
       "Community-list name\n")
 
2656
 
 
2657
ALIAS (no_match_community,
 
2658
       no_match_community_exact_cmd,
 
2659
       "no match community (<1-99>|<100-500>|WORD) exact-match",
 
2660
       NO_STR
 
2661
       MATCH_STR
 
2662
       "Match BGP community list\n"
 
2663
       "Community-list number (standard)\n"
 
2664
       "Community-list number (expanded)\n"
 
2665
       "Community-list name\n"
 
2666
       "Do exact matching of communities\n")
 
2667
 
 
2668
DEFUN (match_ecommunity, 
 
2669
       match_ecommunity_cmd,
 
2670
       "match extcommunity (<1-99>|<100-500>|WORD)",
 
2671
       MATCH_STR
 
2672
       "Match BGP/VPN extended community list\n"
 
2673
       "Extended community-list number (standard)\n"
 
2674
       "Extended community-list number (expanded)\n"
 
2675
       "Extended community-list name\n")
 
2676
{
 
2677
  return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
 
2678
}
 
2679
 
 
2680
DEFUN (no_match_ecommunity,
 
2681
       no_match_ecommunity_cmd,
 
2682
       "no match extcommunity",
 
2683
       NO_STR
 
2684
       MATCH_STR
 
2685
       "Match BGP/VPN extended community list\n")
 
2686
{
 
2687
  return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
 
2688
}
 
2689
 
 
2690
ALIAS (no_match_ecommunity,
 
2691
       no_match_ecommunity_val_cmd,
 
2692
       "no match extcommunity (<1-99>|<100-500>|WORD)",
 
2693
       NO_STR
 
2694
       MATCH_STR
 
2695
       "Match BGP/VPN extended community list\n"
 
2696
       "Extended community-list number (standard)\n"
 
2697
       "Extended community-list number (expanded)\n"
 
2698
       "Extended community-list name\n")
 
2699
 
 
2700
DEFUN (match_aspath,
 
2701
       match_aspath_cmd,
 
2702
       "match as-path WORD",
 
2703
       MATCH_STR
 
2704
       "Match BGP AS path list\n"
 
2705
       "AS path access-list name\n")
 
2706
{
 
2707
  return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
 
2708
}
 
2709
 
 
2710
DEFUN (no_match_aspath,
 
2711
       no_match_aspath_cmd,
 
2712
       "no match as-path",
 
2713
       NO_STR
 
2714
       MATCH_STR
 
2715
       "Match BGP AS path list\n")
 
2716
{
 
2717
  return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
 
2718
}
 
2719
 
 
2720
ALIAS (no_match_aspath,
 
2721
       no_match_aspath_val_cmd,
 
2722
       "no match as-path WORD",
 
2723
       NO_STR
 
2724
       MATCH_STR
 
2725
       "Match BGP AS path list\n"
 
2726
       "AS path access-list name\n")
 
2727
 
 
2728
DEFUN (match_origin,
 
2729
       match_origin_cmd,
 
2730
       "match origin (egp|igp|incomplete)",
 
2731
       MATCH_STR
 
2732
       "BGP origin code\n"
 
2733
       "remote EGP\n"
 
2734
       "local IGP\n"
 
2735
       "unknown heritage\n")
 
2736
{
 
2737
  if (strncmp (argv[0], "igp", 2) == 0)
 
2738
    return bgp_route_match_add (vty, vty->index, "origin", "igp");
 
2739
  if (strncmp (argv[0], "egp", 1) == 0)
 
2740
    return bgp_route_match_add (vty, vty->index, "origin", "egp");
 
2741
  if (strncmp (argv[0], "incomplete", 2) == 0)
 
2742
    return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
 
2743
 
 
2744
  return CMD_WARNING;
 
2745
}
 
2746
 
 
2747
DEFUN (no_match_origin,
 
2748
       no_match_origin_cmd,
 
2749
       "no match origin",
 
2750
       NO_STR
 
2751
       MATCH_STR
 
2752
       "BGP origin code\n")
 
2753
{
 
2754
  return bgp_route_match_delete (vty, vty->index, "origin", NULL);
 
2755
}
 
2756
 
 
2757
ALIAS (no_match_origin,
 
2758
       no_match_origin_val_cmd,
 
2759
       "no match origin (egp|igp|incomplete)",
 
2760
       NO_STR
 
2761
       MATCH_STR
 
2762
       "BGP origin code\n"
 
2763
       "remote EGP\n"
 
2764
       "local IGP\n"
 
2765
       "unknown heritage\n")
 
2766
 
 
2767
DEFUN (set_ip_nexthop,
 
2768
       set_ip_nexthop_cmd,
 
2769
       "set ip next-hop A.B.C.D",
 
2770
       SET_STR
 
2771
       IP_STR
 
2772
       "Next hop address\n"
 
2773
       "IP address of next hop\n")
 
2774
{
 
2775
  union sockunion su;
 
2776
  int ret;
 
2777
 
 
2778
  ret = str2sockunion (argv[0], &su);
 
2779
  if (ret < 0)
 
2780
    {
 
2781
      vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
 
2782
      return CMD_WARNING;
 
2783
    }
 
2784
 
 
2785
  return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
 
2786
}
 
2787
 
 
2788
DEFUN (set_ip_nexthop_peer,
 
2789
       set_ip_nexthop_peer_cmd,
 
2790
       "set ip next-hop peer-address",
 
2791
       SET_STR
 
2792
       IP_STR
 
2793
       "Next hop address\n"
 
2794
       "Use peer address (for BGP only)\n")
 
2795
{
 
2796
  return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
 
2797
}
 
2798
 
 
2799
DEFUN (no_set_ip_nexthop_peer,
 
2800
       no_set_ip_nexthop_peer_cmd,
 
2801
       "no set ip next-hop peer-address",
 
2802
       NO_STR
 
2803
       SET_STR
 
2804
       IP_STR
 
2805
       "Next hop address\n"
 
2806
       "Use peer address (for BGP only)\n")
 
2807
{
 
2808
  return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
 
2809
}
 
2810
 
 
2811
 
 
2812
DEFUN (no_set_ip_nexthop,
 
2813
       no_set_ip_nexthop_cmd,
 
2814
       "no set ip next-hop",
 
2815
       NO_STR
 
2816
       SET_STR
 
2817
       "Next hop address\n")
 
2818
{
 
2819
  if (argc == 0)
 
2820
    return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
 
2821
 
 
2822
  return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
 
2823
}
 
2824
 
 
2825
ALIAS (no_set_ip_nexthop,
 
2826
       no_set_ip_nexthop_val_cmd,
 
2827
       "no set ip next-hop A.B.C.D",
 
2828
       NO_STR
 
2829
       SET_STR
 
2830
       IP_STR
 
2831
       "Next hop address\n"
 
2832
       "IP address of next hop\n")
 
2833
 
 
2834
DEFUN (set_metric,
 
2835
       set_metric_cmd,
 
2836
       "set metric <0-4294967295>",
 
2837
       SET_STR
 
2838
       "Metric value for destination routing protocol\n"
 
2839
       "Metric value\n")
 
2840
{
 
2841
  return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
 
2842
}
 
2843
 
 
2844
ALIAS (set_metric,
 
2845
       set_metric_addsub_cmd,
 
2846
       "set metric <+/-metric>",
 
2847
       SET_STR
 
2848
       "Metric value for destination routing protocol\n"
 
2849
       "Add or subtract BGP metric\n")
 
2850
 
 
2851
DEFUN (no_set_metric,
 
2852
       no_set_metric_cmd,
 
2853
       "no set metric",
 
2854
       NO_STR
 
2855
       SET_STR
 
2856
       "Metric value for destination routing protocol\n")
 
2857
{
 
2858
  if (argc == 0)
 
2859
    return bgp_route_set_delete (vty, vty->index, "metric", NULL);
 
2860
 
 
2861
  return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
 
2862
}
 
2863
 
 
2864
ALIAS (no_set_metric,
 
2865
       no_set_metric_val_cmd,
 
2866
       "no set metric <0-4294967295>",
 
2867
       NO_STR
 
2868
       SET_STR
 
2869
       "Metric value for destination routing protocol\n"
 
2870
       "Metric value\n")
 
2871
 
 
2872
DEFUN (set_local_pref,
 
2873
       set_local_pref_cmd,
 
2874
       "set local-preference <0-4294967295>",
 
2875
       SET_STR
 
2876
       "BGP local preference path attribute\n"
 
2877
       "Preference value\n")
 
2878
{
 
2879
  return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
 
2880
}
 
2881
 
 
2882
DEFUN (no_set_local_pref,
 
2883
       no_set_local_pref_cmd,
 
2884
       "no set local-preference",
 
2885
       NO_STR
 
2886
       SET_STR
 
2887
       "BGP local preference path attribute\n")
 
2888
{
 
2889
  if (argc == 0)
 
2890
    return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
 
2891
 
 
2892
  return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
 
2893
}
 
2894
 
 
2895
ALIAS (no_set_local_pref,
 
2896
       no_set_local_pref_val_cmd,
 
2897
       "no set local-preference <0-4294967295>",
 
2898
       NO_STR
 
2899
       SET_STR
 
2900
       "BGP local preference path attribute\n"
 
2901
       "Preference value\n")
 
2902
 
 
2903
DEFUN (set_weight,
 
2904
       set_weight_cmd,
 
2905
       "set weight <0-4294967295>",
 
2906
       SET_STR
 
2907
       "BGP weight for routing table\n"
 
2908
       "Weight value\n")
 
2909
{
 
2910
  return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
 
2911
}
 
2912
 
 
2913
DEFUN (no_set_weight,
 
2914
       no_set_weight_cmd,
 
2915
       "no set weight",
 
2916
       NO_STR
 
2917
       SET_STR
 
2918
       "BGP weight for routing table\n")
 
2919
{
 
2920
  if (argc == 0)
 
2921
    return bgp_route_set_delete (vty, vty->index, "weight", NULL);
 
2922
  
 
2923
  return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
 
2924
}
 
2925
 
 
2926
ALIAS (no_set_weight,
 
2927
       no_set_weight_val_cmd,
 
2928
       "no set weight <0-4294967295>",
 
2929
       NO_STR
 
2930
       SET_STR
 
2931
       "BGP weight for routing table\n"
 
2932
       "Weight value\n")
 
2933
 
 
2934
DEFUN (set_aspath_prepend,
 
2935
       set_aspath_prepend_cmd,
 
2936
       "set as-path prepend .<1-65535>",
 
2937
       SET_STR
 
2938
       "Prepend string for a BGP AS-path attribute\n"
 
2939
       "Prepend to the as-path\n"
 
2940
       "AS number\n")
 
2941
{
 
2942
  int ret;
 
2943
  char *str;
 
2944
 
 
2945
  str = argv_concat (argv, argc, 0);
 
2946
  ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
 
2947
  XFREE (MTYPE_TMP, str);
 
2948
 
 
2949
  return ret;
 
2950
}
 
2951
 
 
2952
DEFUN (no_set_aspath_prepend,
 
2953
       no_set_aspath_prepend_cmd,
 
2954
       "no set as-path prepend",
 
2955
       NO_STR
 
2956
       SET_STR
 
2957
       "Prepend string for a BGP AS-path attribute\n"
 
2958
       "Prepend to the as-path\n")
 
2959
{
 
2960
  return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
 
2961
}
 
2962
 
 
2963
ALIAS (no_set_aspath_prepend,
 
2964
       no_set_aspath_prepend_val_cmd,
 
2965
       "no set as-path prepend .<1-65535>",
 
2966
       NO_STR
 
2967
       SET_STR
 
2968
       "Prepend string for a BGP AS-path attribute\n"
 
2969
       "Prepend to the as-path\n"
 
2970
       "AS number\n")
 
2971
 
 
2972
DEFUN (set_community,
 
2973
       set_community_cmd,
 
2974
       "set community .AA:NN",
 
2975
       SET_STR
 
2976
       "BGP community attribute\n"
 
2977
       "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
 
2978
{
 
2979
  int i;
 
2980
  int first = 0;
 
2981
  int additive = 0;
 
2982
  struct buffer *b;
 
2983
  struct community *com = NULL;
 
2984
  char *str;
 
2985
  char *argstr;
 
2986
  int ret;
 
2987
 
 
2988
  b = buffer_new (1024);
 
2989
 
 
2990
  for (i = 0; i < argc; i++)
 
2991
    {
 
2992
      if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
 
2993
        {
 
2994
          additive = 1;
 
2995
          continue;
 
2996
        }
 
2997
 
 
2998
      if (first)
 
2999
        buffer_putc (b, ' ');
 
3000
      else
 
3001
        first = 1;
 
3002
 
 
3003
      if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
 
3004
        {
 
3005
          buffer_putstr (b, "internet");
 
3006
          continue;
 
3007
        }
 
3008
      if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
 
3009
        {
 
3010
          buffer_putstr (b, "local-AS");
 
3011
          continue;
 
3012
        }
 
3013
      if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
 
3014
          && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
 
3015
        {
 
3016
          buffer_putstr (b, "no-advertise");
 
3017
          continue;
 
3018
        }
 
3019
      if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
 
3020
          && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
 
3021
        {
 
3022
          buffer_putstr (b, "no-export");
 
3023
          continue;
 
3024
        }
 
3025
      buffer_putstr (b, argv[i]);
 
3026
    }
 
3027
  buffer_putc (b, '\0');
 
3028
 
 
3029
  /* Fetch result string then compile it to communities attribute.  */
 
3030
  str = buffer_getstr (b);
 
3031
  buffer_free (b);
 
3032
 
 
3033
  if (str)
 
3034
    {
 
3035
      com = community_str2com (str);
 
3036
      XFREE (MTYPE_TMP, str);
 
3037
    }
 
3038
 
 
3039
  /* Can't compile user input into communities attribute.  */
 
3040
  if (! com)
 
3041
    {
 
3042
      vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
 
3043
      return CMD_WARNING;
 
3044
    }
 
3045
 
 
3046
  /* Set communites attribute string.  */
 
3047
  str = community_str (com);
 
3048
 
 
3049
  if (additive)
 
3050
    {
 
3051
      argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
 
3052
      strcpy (argstr, str);
 
3053
      strcpy (argstr + strlen (str), " additive");
 
3054
      ret =  bgp_route_set_add (vty, vty->index, "community", argstr);
 
3055
      XFREE (MTYPE_TMP, argstr);
 
3056
    }
 
3057
  else
 
3058
    ret =  bgp_route_set_add (vty, vty->index, "community", str);
 
3059
 
 
3060
  community_free (com);
 
3061
 
 
3062
  return ret;
 
3063
}
 
3064
 
 
3065
DEFUN (set_community_none,
 
3066
       set_community_none_cmd,
 
3067
       "set community none",
 
3068
       SET_STR
 
3069
       "BGP community attribute\n"
 
3070
       "No community attribute\n")
 
3071
{
 
3072
  return bgp_route_set_add (vty, vty->index, "community", "none");
 
3073
}
 
3074
 
 
3075
DEFUN (no_set_community,
 
3076
       no_set_community_cmd,
 
3077
       "no set community",
 
3078
       NO_STR
 
3079
       SET_STR
 
3080
       "BGP community attribute\n")
 
3081
{
 
3082
  return bgp_route_set_delete (vty, vty->index, "community", NULL);
 
3083
}
 
3084
 
 
3085
ALIAS (no_set_community,
 
3086
       no_set_community_val_cmd,
 
3087
       "no set community .AA:NN",
 
3088
       NO_STR
 
3089
       SET_STR
 
3090
       "BGP community attribute\n"
 
3091
       "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
 
3092
 
 
3093
ALIAS (no_set_community,
 
3094
       no_set_community_none_cmd,
 
3095
       "no set community none",
 
3096
       NO_STR
 
3097
       SET_STR
 
3098
       "BGP community attribute\n"
 
3099
       "No community attribute\n")
 
3100
 
 
3101
DEFUN (set_community_delete,
 
3102
       set_community_delete_cmd,
 
3103
       "set comm-list (<1-99>|<100-500>|WORD) delete",
 
3104
       SET_STR
 
3105
       "set BGP community list (for deletion)\n"
 
3106
       "Community-list number (standard)\n"
 
3107
       "Communitly-list number (expanded)\n"
 
3108
       "Community-list name\n"
 
3109
       "Delete matching communities\n")
 
3110
{
 
3111
  char *str;
 
3112
 
 
3113
  str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
 
3114
  strcpy (str, argv[0]);
 
3115
  strcpy (str + strlen (argv[0]), " delete");
 
3116
 
 
3117
  bgp_route_set_add (vty, vty->index, "comm-list", str);
 
3118
 
 
3119
  XFREE (MTYPE_TMP, str);
 
3120
  return CMD_SUCCESS;
 
3121
}
 
3122
 
 
3123
DEFUN (no_set_community_delete,
 
3124
       no_set_community_delete_cmd,
 
3125
       "no set comm-list",
 
3126
       NO_STR
 
3127
       SET_STR
 
3128
       "set BGP community list (for deletion)\n")
 
3129
{
 
3130
  return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
 
3131
}
 
3132
 
 
3133
ALIAS (no_set_community_delete,
 
3134
       no_set_community_delete_val_cmd,
 
3135
       "no set comm-list (<1-99>|<100-500>|WORD) delete",
 
3136
       NO_STR
 
3137
       SET_STR
 
3138
       "set BGP community list (for deletion)\n"
 
3139
       "Community-list number (standard)\n"
 
3140
       "Communitly-list number (expanded)\n"
 
3141
       "Community-list name\n"
 
3142
       "Delete matching communities\n")
 
3143
 
 
3144
DEFUN (set_ecommunity_rt,
 
3145
       set_ecommunity_rt_cmd,
 
3146
       "set extcommunity rt .ASN:nn_or_IP-address:nn",
 
3147
       SET_STR
 
3148
       "BGP extended community attribute\n"
 
3149
       "Route Target extened communityt\n"
 
3150
       "VPN extended community\n")
 
3151
{
 
3152
  int ret;
 
3153
  char *str;
 
3154
 
 
3155
  str = argv_concat (argv, argc, 0);
 
3156
  ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
 
3157
  XFREE (MTYPE_TMP, str);
 
3158
 
 
3159
  return ret;
 
3160
}
 
3161
 
 
3162
DEFUN (no_set_ecommunity_rt,
 
3163
       no_set_ecommunity_rt_cmd,
 
3164
       "no set extcommunity rt",
 
3165
       NO_STR
 
3166
       SET_STR
 
3167
       "BGP extended community attribute\n"
 
3168
       "Route Target extened communityt\n")
 
3169
{
 
3170
  return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
 
3171
}
 
3172
 
 
3173
ALIAS (no_set_ecommunity_rt,
 
3174
       no_set_ecommunity_rt_val_cmd,
 
3175
       "no set extcommunity rt .ASN:nn_or_IP-address:nn",
 
3176
       NO_STR
 
3177
       SET_STR
 
3178
       "BGP extended community attribute\n"
 
3179
       "Route Target extened communityt\n"
 
3180
       "VPN extended community\n")
 
3181
 
 
3182
DEFUN (set_ecommunity_soo,
 
3183
       set_ecommunity_soo_cmd,
 
3184
       "set extcommunity soo .ASN:nn_or_IP-address:nn",
 
3185
       SET_STR
 
3186
       "BGP extended community attribute\n"
 
3187
       "Site-of-Origin extended community\n"
 
3188
       "VPN extended community\n")
 
3189
{
 
3190
  int ret;
 
3191
  char *str;
 
3192
 
 
3193
  str = argv_concat (argv, argc, 0);
 
3194
  ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
 
3195
  XFREE (MTYPE_TMP, str);
 
3196
  return ret;
 
3197
}
 
3198
 
 
3199
DEFUN (no_set_ecommunity_soo,
 
3200
       no_set_ecommunity_soo_cmd,
 
3201
       "no set extcommunity soo",
 
3202
       NO_STR
 
3203
       SET_STR
 
3204
       "BGP extended community attribute\n"
 
3205
       "Site-of-Origin extended community\n")
 
3206
{
 
3207
  return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
 
3208
}
 
3209
 
 
3210
ALIAS (no_set_ecommunity_soo,
 
3211
       no_set_ecommunity_soo_val_cmd,
 
3212
       "no set extcommunity soo .ASN:nn_or_IP-address:nn",
 
3213
       NO_STR
 
3214
       SET_STR
 
3215
       "BGP extended community attribute\n"
 
3216
       "Site-of-Origin extended community\n"
 
3217
       "VPN extended community\n")
 
3218
 
 
3219
DEFUN (set_origin,
 
3220
       set_origin_cmd,
 
3221
       "set origin (egp|igp|incomplete)",
 
3222
       SET_STR
 
3223
       "BGP origin code\n"
 
3224
       "remote EGP\n"
 
3225
       "local IGP\n"
 
3226
       "unknown heritage\n")
 
3227
{
 
3228
  if (strncmp (argv[0], "igp", 2) == 0)
 
3229
    return bgp_route_set_add (vty, vty->index, "origin", "igp");
 
3230
  if (strncmp (argv[0], "egp", 1) == 0)
 
3231
    return bgp_route_set_add (vty, vty->index, "origin", "egp");
 
3232
  if (strncmp (argv[0], "incomplete", 2) == 0)
 
3233
    return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
 
3234
 
 
3235
  return CMD_WARNING;
 
3236
}
 
3237
 
 
3238
DEFUN (no_set_origin,
 
3239
       no_set_origin_cmd,
 
3240
       "no set origin",
 
3241
       NO_STR
 
3242
       SET_STR
 
3243
       "BGP origin code\n")
 
3244
{
 
3245
  return bgp_route_set_delete (vty, vty->index, "origin", NULL);
 
3246
}
 
3247
 
 
3248
ALIAS (no_set_origin,
 
3249
       no_set_origin_val_cmd,
 
3250
       "no set origin (egp|igp|incomplete)",
 
3251
       NO_STR
 
3252
       SET_STR
 
3253
       "BGP origin code\n"
 
3254
       "remote EGP\n"
 
3255
       "local IGP\n"
 
3256
       "unknown heritage\n")
 
3257
 
 
3258
DEFUN (set_atomic_aggregate,
 
3259
       set_atomic_aggregate_cmd,
 
3260
       "set atomic-aggregate",
 
3261
       SET_STR
 
3262
       "BGP atomic aggregate attribute\n" )
 
3263
{
 
3264
  return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
 
3265
}
 
3266
 
 
3267
DEFUN (no_set_atomic_aggregate,
 
3268
       no_set_atomic_aggregate_cmd,
 
3269
       "no set atomic-aggregate",
 
3270
       NO_STR
 
3271
       SET_STR
 
3272
       "BGP atomic aggregate attribute\n" )
 
3273
{
 
3274
  return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
 
3275
}
 
3276
 
 
3277
DEFUN (set_aggregator_as,
 
3278
       set_aggregator_as_cmd,
 
3279
       "set aggregator as <1-65535> A.B.C.D",
 
3280
       SET_STR
 
3281
       "BGP aggregator attribute\n"
 
3282
       "AS number of aggregator\n"
 
3283
       "AS number\n"
 
3284
       "IP address of aggregator\n")
 
3285
{
 
3286
  int ret;
 
3287
  as_t as;
 
3288
  struct in_addr address;
 
3289
  char *argstr;
 
3290
 
 
3291
  VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)
 
3292
  
 
3293
  ret = inet_aton (argv[1], &address);
 
3294
  if (ret == 0)
 
3295
    {
 
3296
      vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
 
3297
      return CMD_WARNING;
 
3298
    }
 
3299
 
 
3300
  argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
 
3301
                    strlen (argv[0]) + strlen (argv[1]) + 2);
 
3302
 
 
3303
  sprintf (argstr, "%s %s", argv[0], argv[1]);
 
3304
 
 
3305
  ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
 
3306
 
 
3307
  XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
 
3308
 
 
3309
  return ret;
 
3310
}
 
3311
 
 
3312
DEFUN (no_set_aggregator_as,
 
3313
       no_set_aggregator_as_cmd,
 
3314
       "no set aggregator as",
 
3315
       NO_STR
 
3316
       SET_STR
 
3317
       "BGP aggregator attribute\n"
 
3318
       "AS number of aggregator\n")
 
3319
{
 
3320
  int ret;
 
3321
  as_t as;
 
3322
  struct in_addr address;
 
3323
  char *argstr;
 
3324
 
 
3325
  if (argv == 0)
 
3326
    return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
 
3327
  
 
3328
  VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)  
 
3329
 
 
3330
  ret = inet_aton (argv[1], &address);
 
3331
  if (ret == 0)
 
3332
    {
 
3333
      vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
 
3334
      return CMD_WARNING;
 
3335
    }
 
3336
 
 
3337
  argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
 
3338
                    strlen (argv[0]) + strlen (argv[1]) + 2);
 
3339
 
 
3340
  sprintf (argstr, "%s %s", argv[0], argv[1]);
 
3341
 
 
3342
  ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
 
3343
 
 
3344
  XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
 
3345
 
 
3346
  return ret;
 
3347
}
 
3348
 
 
3349
ALIAS (no_set_aggregator_as,
 
3350
       no_set_aggregator_as_val_cmd,
 
3351
       "no set aggregator as <1-65535> A.B.C.D",
 
3352
       NO_STR
 
3353
       SET_STR
 
3354
       "BGP aggregator attribute\n"
 
3355
       "AS number of aggregator\n"
 
3356
       "AS number\n"
 
3357
       "IP address of aggregator\n")
 
3358
 
 
3359
 
 
3360
#ifdef HAVE_IPV6
 
3361
DEFUN (match_ipv6_address, 
 
3362
       match_ipv6_address_cmd,
 
3363
       "match ipv6 address WORD",
 
3364
       MATCH_STR
 
3365
       IPV6_STR
 
3366
       "Match IPv6 address of route\n"
 
3367
       "IPv6 access-list name\n")
 
3368
{
 
3369
  return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
 
3370
}
 
3371
 
 
3372
DEFUN (no_match_ipv6_address, 
 
3373
       no_match_ipv6_address_cmd,
 
3374
       "no match ipv6 address WORD",
 
3375
       NO_STR
 
3376
       MATCH_STR
 
3377
       IPV6_STR
 
3378
       "Match IPv6 address of route\n"
 
3379
       "IPv6 access-list name\n")
 
3380
{
 
3381
  return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
 
3382
}
 
3383
 
 
3384
DEFUN (match_ipv6_next_hop, 
 
3385
       match_ipv6_next_hop_cmd,
 
3386
       "match ipv6 next-hop X:X::X:X",
 
3387
       MATCH_STR
 
3388
       IPV6_STR
 
3389
       "Match IPv6 next-hop address of route\n"
 
3390
       "IPv6 address of next hop\n")
 
3391
{
 
3392
  return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
 
3393
}
 
3394
 
 
3395
DEFUN (no_match_ipv6_next_hop,
 
3396
       no_match_ipv6_next_hop_cmd,
 
3397
       "no match ipv6 next-hop X:X::X:X",
 
3398
       NO_STR
 
3399
       MATCH_STR
 
3400
       IPV6_STR
 
3401
       "Match IPv6 next-hop address of route\n"
 
3402
       "IPv6 address of next hop\n")
 
3403
{
 
3404
  return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
 
3405
}
 
3406
 
 
3407
DEFUN (match_ipv6_address_prefix_list, 
 
3408
       match_ipv6_address_prefix_list_cmd,
 
3409
       "match ipv6 address prefix-list WORD",
 
3410
       MATCH_STR
 
3411
       IPV6_STR
 
3412
       "Match address of route\n"
 
3413
       "Match entries of prefix-lists\n"
 
3414
       "IP prefix-list name\n")
 
3415
{
 
3416
  return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
 
3417
}
 
3418
 
 
3419
DEFUN (no_match_ipv6_address_prefix_list,
 
3420
       no_match_ipv6_address_prefix_list_cmd,
 
3421
       "no match ipv6 address prefix-list WORD",
 
3422
       NO_STR
 
3423
       MATCH_STR
 
3424
       IPV6_STR
 
3425
       "Match address of route\n"
 
3426
       "Match entries of prefix-lists\n"
 
3427
       "IP prefix-list name\n")
 
3428
{
 
3429
  return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
 
3430
}
 
3431
 
 
3432
DEFUN (set_ipv6_nexthop_global,
 
3433
       set_ipv6_nexthop_global_cmd,
 
3434
       "set ipv6 next-hop global X:X::X:X",
 
3435
       SET_STR
 
3436
       IPV6_STR
 
3437
       "IPv6 next-hop address\n"
 
3438
       "IPv6 global address\n"
 
3439
       "IPv6 address of next hop\n")
 
3440
{
 
3441
  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
 
3442
}
 
3443
 
 
3444
DEFUN (no_set_ipv6_nexthop_global,
 
3445
       no_set_ipv6_nexthop_global_cmd,
 
3446
       "no set ipv6 next-hop global",
 
3447
       NO_STR
 
3448
       SET_STR
 
3449
       IPV6_STR
 
3450
       "IPv6 next-hop address\n"
 
3451
       "IPv6 global address\n")
 
3452
{
 
3453
  if (argc == 0)
 
3454
    return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
 
3455
 
 
3456
  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
 
3457
}
 
3458
 
 
3459
ALIAS (no_set_ipv6_nexthop_global,
 
3460
       no_set_ipv6_nexthop_global_val_cmd,
 
3461
       "no set ipv6 next-hop global X:X::X:X",
 
3462
       NO_STR
 
3463
       SET_STR
 
3464
       IPV6_STR
 
3465
       "IPv6 next-hop address\n"
 
3466
       "IPv6 global address\n"
 
3467
       "IPv6 address of next hop\n")
 
3468
 
 
3469
DEFUN (set_ipv6_nexthop_local,
 
3470
       set_ipv6_nexthop_local_cmd,
 
3471
       "set ipv6 next-hop local X:X::X:X",
 
3472
       SET_STR
 
3473
       IPV6_STR
 
3474
       "IPv6 next-hop address\n"
 
3475
       "IPv6 local address\n"
 
3476
       "IPv6 address of next hop\n")
 
3477
{
 
3478
  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
 
3479
}
 
3480
 
 
3481
DEFUN (no_set_ipv6_nexthop_local,
 
3482
       no_set_ipv6_nexthop_local_cmd,
 
3483
       "no set ipv6 next-hop local",
 
3484
       NO_STR
 
3485
       SET_STR
 
3486
       IPV6_STR
 
3487
       "IPv6 next-hop address\n"
 
3488
       "IPv6 local address\n")
 
3489
{
 
3490
  if (argc == 0)
 
3491
    return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
 
3492
  
 
3493
  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
 
3494
}
 
3495
 
 
3496
ALIAS (no_set_ipv6_nexthop_local,
 
3497
       no_set_ipv6_nexthop_local_val_cmd,
 
3498
       "no set ipv6 next-hop local X:X::X:X",
 
3499
       NO_STR
 
3500
       SET_STR
 
3501
       IPV6_STR
 
3502
       "IPv6 next-hop address\n"
 
3503
       "IPv6 local address\n"
 
3504
       "IPv6 address of next hop\n")
 
3505
#endif /* HAVE_IPV6 */
 
3506
 
 
3507
DEFUN (set_vpnv4_nexthop,
 
3508
       set_vpnv4_nexthop_cmd,
 
3509
       "set vpnv4 next-hop A.B.C.D",
 
3510
       SET_STR
 
3511
       "VPNv4 information\n"
 
3512
       "VPNv4 next-hop address\n"
 
3513
       "IP address of next hop\n")
 
3514
{
 
3515
  return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
 
3516
}
 
3517
 
 
3518
DEFUN (no_set_vpnv4_nexthop,
 
3519
       no_set_vpnv4_nexthop_cmd,
 
3520
       "no set vpnv4 next-hop",
 
3521
       NO_STR
 
3522
       SET_STR
 
3523
       "VPNv4 information\n"
 
3524
       "VPNv4 next-hop address\n")
 
3525
{
 
3526
  if (argc == 0)
 
3527
    return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
 
3528
 
 
3529
  return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
 
3530
}
 
3531
 
 
3532
ALIAS (no_set_vpnv4_nexthop,
 
3533
       no_set_vpnv4_nexthop_val_cmd,
 
3534
       "no set vpnv4 next-hop A.B.C.D",
 
3535
       NO_STR
 
3536
       SET_STR
 
3537
       "VPNv4 information\n"
 
3538
       "VPNv4 next-hop address\n"
 
3539
       "IP address of next hop\n")
 
3540
 
 
3541
DEFUN (set_originator_id,
 
3542
       set_originator_id_cmd,
 
3543
       "set originator-id A.B.C.D",
 
3544
       SET_STR
 
3545
       "BGP originator ID attribute\n"
 
3546
       "IP address of originator\n")
 
3547
{
 
3548
  return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
 
3549
}
 
3550
 
 
3551
DEFUN (no_set_originator_id,
 
3552
       no_set_originator_id_cmd,
 
3553
       "no set originator-id",
 
3554
       NO_STR
 
3555
       SET_STR
 
3556
       "BGP originator ID attribute\n")
 
3557
{
 
3558
  if (argc == 0)
 
3559
    return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
 
3560
  
 
3561
  return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
 
3562
}
 
3563
 
 
3564
ALIAS (no_set_originator_id,
 
3565
       no_set_originator_id_val_cmd,
 
3566
       "no set originator-id A.B.C.D",
 
3567
       NO_STR
 
3568
       SET_STR
 
3569
       "BGP originator ID attribute\n"
 
3570
       "IP address of originator\n")
 
3571
 
 
3572
 
 
3573
/* Initialization of route map. */
 
3574
void
 
3575
bgp_route_map_init ()
 
3576
{
 
3577
  route_map_init ();
 
3578
  route_map_init_vty ();
 
3579
  route_map_add_hook (bgp_route_map_update);
 
3580
  route_map_delete_hook (bgp_route_map_update);
 
3581
 
 
3582
  route_map_install_match (&route_match_peer_cmd);
 
3583
  route_map_install_match (&route_match_ip_address_cmd);
 
3584
  route_map_install_match (&route_match_ip_next_hop_cmd);
 
3585
  route_map_install_match (&route_match_ip_route_source_cmd);
 
3586
  route_map_install_match (&route_match_ip_address_prefix_list_cmd);
 
3587
  route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
 
3588
  route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
 
3589
  route_map_install_match (&route_match_aspath_cmd);
 
3590
  route_map_install_match (&route_match_community_cmd);
 
3591
  route_map_install_match (&route_match_ecommunity_cmd);
 
3592
  route_map_install_match (&route_match_metric_cmd);
 
3593
  route_map_install_match (&route_match_origin_cmd);
 
3594
 
 
3595
  route_map_install_set (&route_set_ip_nexthop_cmd);
 
3596
  route_map_install_set (&route_set_local_pref_cmd);
 
3597
  route_map_install_set (&route_set_weight_cmd);
 
3598
  route_map_install_set (&route_set_metric_cmd);
 
3599
  route_map_install_set (&route_set_aspath_prepend_cmd);
 
3600
  route_map_install_set (&route_set_origin_cmd);
 
3601
  route_map_install_set (&route_set_atomic_aggregate_cmd);
 
3602
  route_map_install_set (&route_set_aggregator_as_cmd);
 
3603
  route_map_install_set (&route_set_community_cmd);
 
3604
  route_map_install_set (&route_set_community_delete_cmd);
 
3605
  route_map_install_set (&route_set_vpnv4_nexthop_cmd);
 
3606
  route_map_install_set (&route_set_originator_id_cmd);
 
3607
  route_map_install_set (&route_set_ecommunity_rt_cmd);
 
3608
  route_map_install_set (&route_set_ecommunity_soo_cmd);
 
3609
 
 
3610
  install_element (RMAP_NODE, &match_peer_cmd);
 
3611
  install_element (RMAP_NODE, &match_peer_local_cmd);
 
3612
  install_element (RMAP_NODE, &no_match_peer_cmd);
 
3613
  install_element (RMAP_NODE, &no_match_peer_val_cmd);
 
3614
  install_element (RMAP_NODE, &no_match_peer_local_cmd);
 
3615
  install_element (RMAP_NODE, &match_ip_address_cmd);
 
3616
  install_element (RMAP_NODE, &no_match_ip_address_cmd);
 
3617
  install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
 
3618
  install_element (RMAP_NODE, &match_ip_next_hop_cmd);
 
3619
  install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
 
3620
  install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
 
3621
  install_element (RMAP_NODE, &match_ip_route_source_cmd);
 
3622
  install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
 
3623
  install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
 
3624
 
 
3625
  install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
 
3626
  install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
 
3627
  install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
 
3628
  install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
 
3629
  install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
 
3630
  install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
 
3631
  install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
 
3632
  install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
 
3633
  install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
 
3634
 
 
3635
  install_element (RMAP_NODE, &match_aspath_cmd);
 
3636
  install_element (RMAP_NODE, &no_match_aspath_cmd);
 
3637
  install_element (RMAP_NODE, &no_match_aspath_val_cmd);
 
3638
  install_element (RMAP_NODE, &match_metric_cmd);
 
3639
  install_element (RMAP_NODE, &no_match_metric_cmd);
 
3640
  install_element (RMAP_NODE, &no_match_metric_val_cmd);
 
3641
  install_element (RMAP_NODE, &match_community_cmd);
 
3642
  install_element (RMAP_NODE, &match_community_exact_cmd);
 
3643
  install_element (RMAP_NODE, &no_match_community_cmd);
 
3644
  install_element (RMAP_NODE, &no_match_community_val_cmd);
 
3645
  install_element (RMAP_NODE, &no_match_community_exact_cmd);
 
3646
  install_element (RMAP_NODE, &match_ecommunity_cmd);
 
3647
  install_element (RMAP_NODE, &no_match_ecommunity_cmd);
 
3648
  install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
 
3649
  install_element (RMAP_NODE, &match_origin_cmd);
 
3650
  install_element (RMAP_NODE, &no_match_origin_cmd);
 
3651
  install_element (RMAP_NODE, &no_match_origin_val_cmd);
 
3652
 
 
3653
  install_element (RMAP_NODE, &set_ip_nexthop_cmd);
 
3654
  install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
 
3655
  install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
 
3656
  install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
 
3657
  install_element (RMAP_NODE, &set_local_pref_cmd);
 
3658
  install_element (RMAP_NODE, &no_set_local_pref_cmd);
 
3659
  install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
 
3660
  install_element (RMAP_NODE, &set_weight_cmd);
 
3661
  install_element (RMAP_NODE, &no_set_weight_cmd);
 
3662
  install_element (RMAP_NODE, &no_set_weight_val_cmd);
 
3663
  install_element (RMAP_NODE, &set_metric_cmd);
 
3664
  install_element (RMAP_NODE, &set_metric_addsub_cmd);
 
3665
  install_element (RMAP_NODE, &no_set_metric_cmd);
 
3666
  install_element (RMAP_NODE, &no_set_metric_val_cmd);
 
3667
  install_element (RMAP_NODE, &set_aspath_prepend_cmd);
 
3668
  install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
 
3669
  install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
 
3670
  install_element (RMAP_NODE, &set_origin_cmd);
 
3671
  install_element (RMAP_NODE, &no_set_origin_cmd);
 
3672
  install_element (RMAP_NODE, &no_set_origin_val_cmd);
 
3673
  install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
 
3674
  install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
 
3675
  install_element (RMAP_NODE, &set_aggregator_as_cmd);
 
3676
  install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
 
3677
  install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
 
3678
  install_element (RMAP_NODE, &set_community_cmd);
 
3679
  install_element (RMAP_NODE, &set_community_none_cmd);
 
3680
  install_element (RMAP_NODE, &no_set_community_cmd);
 
3681
  install_element (RMAP_NODE, &no_set_community_val_cmd);
 
3682
  install_element (RMAP_NODE, &no_set_community_none_cmd);
 
3683
  install_element (RMAP_NODE, &set_community_delete_cmd);
 
3684
  install_element (RMAP_NODE, &no_set_community_delete_cmd);
 
3685
  install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
 
3686
  install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
 
3687
  install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
 
3688
  install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
 
3689
  install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
 
3690
  install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
 
3691
  install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
 
3692
  install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
 
3693
  install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
 
3694
  install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
 
3695
  install_element (RMAP_NODE, &set_originator_id_cmd);
 
3696
  install_element (RMAP_NODE, &no_set_originator_id_cmd);
 
3697
  install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
 
3698
 
 
3699
#ifdef HAVE_IPV6
 
3700
  route_map_install_match (&route_match_ipv6_address_cmd);
 
3701
  route_map_install_match (&route_match_ipv6_next_hop_cmd);
 
3702
  route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
 
3703
  route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
 
3704
  route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
 
3705
 
 
3706
  install_element (RMAP_NODE, &match_ipv6_address_cmd);
 
3707
  install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
 
3708
  install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
 
3709
  install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
 
3710
  install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
 
3711
  install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
 
3712
  install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
 
3713
  install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
 
3714
  install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
 
3715
  install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
 
3716
  install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
 
3717
  install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
 
3718
#endif /* HAVE_IPV6 */
 
3719
}