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

« back to all changes in this revision

Viewing changes to bgpd/bgp_filter.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
/* AS path filter list.
 
2
   Copyright (C) 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 "command.h"
 
24
#include "log.h"
 
25
#include "memory.h"
 
26
#include "buffer.h"
 
27
 
 
28
#include "bgpd/bgpd.h"
 
29
#include "bgpd/bgp_aspath.h"
 
30
#include "bgpd/bgp_regex.h"
 
31
#include "bgpd/bgp_filter.h"
 
32
 
 
33
/* List of AS filter list. */
 
34
struct as_list_list
 
35
{
 
36
  struct as_list *head;
 
37
  struct as_list *tail;
 
38
};
 
39
 
 
40
/* AS path filter master. */
 
41
struct as_list_master
 
42
{
 
43
  /* List of access_list which name is number. */
 
44
  struct as_list_list num;
 
45
 
 
46
  /* List of access_list which name is string. */
 
47
  struct as_list_list str;
 
48
 
 
49
  /* Hook function which is executed when new access_list is added. */
 
50
  void (*add_hook) ();
 
51
 
 
52
  /* Hook function which is executed when access_list is deleted. */
 
53
  void (*delete_hook) ();
 
54
};
 
55
 
 
56
/* Element of AS path filter. */
 
57
struct as_filter
 
58
{
 
59
  struct as_filter *next;
 
60
  struct as_filter *prev;
 
61
 
 
62
  enum as_filter_type type;
 
63
 
 
64
  regex_t *reg;
 
65
  char *reg_str;
 
66
};
 
67
 
 
68
enum as_list_type
 
69
{
 
70
  ACCESS_TYPE_STRING,
 
71
  ACCESS_TYPE_NUMBER
 
72
};
 
73
 
 
74
/* AS path filter list. */
 
75
struct as_list
 
76
{
 
77
  char *name;
 
78
 
 
79
  enum as_list_type type;
 
80
 
 
81
  struct as_list *next;
 
82
  struct as_list *prev;
 
83
 
 
84
  struct as_filter *head;
 
85
  struct as_filter *tail;
 
86
};
 
87
 
 
88
/* ip as-path access-list 10 permit AS1. */
 
89
 
 
90
static struct as_list_master as_list_master =
 
91
{
 
92
  {NULL, NULL},
 
93
  {NULL, NULL},
 
94
  NULL,
 
95
  NULL
 
96
};
 
97
 
 
98
/* Allocate new AS filter. */
 
99
struct as_filter *
 
100
as_filter_new ()
 
101
{
 
102
  struct as_filter *new;
 
103
 
 
104
  new = XMALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter));
 
105
  memset (new, 0, sizeof (struct as_filter));
 
106
  return new;
 
107
}
 
108
 
 
109
/* Free allocated AS filter. */
 
110
void
 
111
as_filter_free (struct as_filter *asfilter)
 
112
{
 
113
  if (asfilter->reg)
 
114
    bgp_regex_free (asfilter->reg);
 
115
  if (asfilter->reg_str)
 
116
    XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str);
 
117
  XFREE (MTYPE_AS_FILTER, asfilter);
 
118
}
 
119
 
 
120
/* Make new AS filter. */
 
121
struct as_filter *
 
122
as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
 
123
{
 
124
  struct as_filter *asfilter;
 
125
 
 
126
  asfilter = as_filter_new ();
 
127
  asfilter->reg = reg;
 
128
  asfilter->type = type;
 
129
  asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str);
 
130
 
 
131
  return asfilter;
 
132
}
 
133
 
 
134
struct as_filter *
 
135
as_filter_lookup (struct as_list *aslist, const char *reg_str,
 
136
                  enum as_filter_type type)
 
137
{
 
138
  struct as_filter *asfilter;
 
139
 
 
140
  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
141
    if (strcmp (reg_str, asfilter->reg_str) == 0)
 
142
      return asfilter;
 
143
  return NULL;
 
144
}
 
145
 
 
146
void
 
147
as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
 
148
{
 
149
  asfilter->next = NULL;
 
150
  asfilter->prev = aslist->tail;
 
151
 
 
152
  if (aslist->tail)
 
153
    aslist->tail->next = asfilter;
 
154
  else
 
155
    aslist->head = asfilter;
 
156
  aslist->tail = asfilter;
 
157
}
 
158
 
 
159
/* Lookup as_list from list of as_list by name. */
 
160
struct as_list *
 
161
as_list_lookup (const char *name)
 
162
{
 
163
  struct as_list *aslist;
 
164
 
 
165
  if (name == NULL)
 
166
    return NULL;
 
167
 
 
168
  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
 
169
    if (strcmp (aslist->name, name) == 0)
 
170
      return aslist;
 
171
 
 
172
  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
 
173
    if (strcmp (aslist->name, name) == 0)
 
174
      return aslist;
 
175
 
 
176
  return NULL;
 
177
}
 
178
 
 
179
struct as_list *
 
180
as_list_new ()
 
181
{
 
182
  struct as_list *new;
 
183
 
 
184
  new = XMALLOC (MTYPE_AS_LIST, sizeof (struct as_list));
 
185
  memset (new, 0, sizeof (struct as_list));
 
186
  return new;
 
187
}
 
188
 
 
189
void
 
190
as_list_free (struct as_list *aslist)
 
191
{
 
192
  XFREE (MTYPE_AS_LIST, aslist);
 
193
}
 
194
 
 
195
/* Insert new AS list to list of as_list.  Each as_list is sorted by
 
196
   the name. */
 
197
struct as_list *
 
198
as_list_insert (const char *name)
 
199
{
 
200
  size_t i;
 
201
  long number;
 
202
  struct as_list *aslist;
 
203
  struct as_list *point;
 
204
  struct as_list_list *list;
 
205
 
 
206
  /* Allocate new access_list and copy given name. */
 
207
  aslist = as_list_new ();
 
208
  aslist->name = strdup (name);
 
209
 
 
210
  /* If name is made by all digit character.  We treat it as
 
211
     number. */
 
212
  for (number = 0, i = 0; i < strlen (name); i++)
 
213
    {
 
214
      if (isdigit ((int) name[i]))
 
215
        number = (number * 10) + (name[i] - '0');
 
216
      else
 
217
        break;
 
218
    }
 
219
 
 
220
  /* In case of name is all digit character */
 
221
  if (i == strlen (name))
 
222
    {
 
223
      aslist->type = ACCESS_TYPE_NUMBER;
 
224
 
 
225
      /* Set access_list to number list. */
 
226
      list = &as_list_master.num;
 
227
 
 
228
      for (point = list->head; point; point = point->next)
 
229
        if (atol (point->name) >= number)
 
230
          break;
 
231
    }
 
232
  else
 
233
    {
 
234
      aslist->type = ACCESS_TYPE_STRING;
 
235
 
 
236
      /* Set access_list to string list. */
 
237
      list = &as_list_master.str;
 
238
  
 
239
      /* Set point to insertion point. */
 
240
      for (point = list->head; point; point = point->next)
 
241
        if (strcmp (point->name, name) >= 0)
 
242
          break;
 
243
    }
 
244
 
 
245
  /* In case of this is the first element of master. */
 
246
  if (list->head == NULL)
 
247
    {
 
248
      list->head = list->tail = aslist;
 
249
      return aslist;
 
250
    }
 
251
 
 
252
  /* In case of insertion is made at the tail of access_list. */
 
253
  if (point == NULL)
 
254
    {
 
255
      aslist->prev = list->tail;
 
256
      list->tail->next = aslist;
 
257
      list->tail = aslist;
 
258
      return aslist;
 
259
    }
 
260
 
 
261
  /* In case of insertion is made at the head of access_list. */
 
262
  if (point == list->head)
 
263
    {
 
264
      aslist->next = list->head;
 
265
      list->head->prev = aslist;
 
266
      list->head = aslist;
 
267
      return aslist;
 
268
    }
 
269
 
 
270
  /* Insertion is made at middle of the access_list. */
 
271
  aslist->next = point;
 
272
  aslist->prev = point->prev;
 
273
 
 
274
  if (point->prev)
 
275
    point->prev->next = aslist;
 
276
  point->prev = aslist;
 
277
 
 
278
  return aslist;
 
279
}
 
280
 
 
281
struct as_list *
 
282
as_list_get (const char *name)
 
283
{
 
284
  struct as_list *aslist;
 
285
 
 
286
  aslist = as_list_lookup (name);
 
287
  if (aslist == NULL)
 
288
    {
 
289
      aslist = as_list_insert (name);
 
290
 
 
291
      /* Run hook function. */
 
292
      if (as_list_master.add_hook)
 
293
        (*as_list_master.add_hook) ();
 
294
    }
 
295
 
 
296
  return aslist;
 
297
}
 
298
 
 
299
static const char *
 
300
filter_type_str (enum as_filter_type type)
 
301
{
 
302
  switch (type)
 
303
    {
 
304
    case AS_FILTER_PERMIT:
 
305
      return "permit";
 
306
      break;
 
307
    case AS_FILTER_DENY:
 
308
      return "deny";
 
309
      break;
 
310
    default:
 
311
      return "";
 
312
      break;
 
313
    }
 
314
}
 
315
 
 
316
void
 
317
as_list_delete (struct as_list *aslist)
 
318
{
 
319
  struct as_list_list *list;
 
320
  struct as_filter *filter, *next;
 
321
 
 
322
  for (filter = aslist->head; filter; filter = next)
 
323
    {
 
324
      next = filter->next;
 
325
      as_filter_free (filter);
 
326
    }
 
327
 
 
328
  if (aslist->type == ACCESS_TYPE_NUMBER)
 
329
    list = &as_list_master.num;
 
330
  else
 
331
    list = &as_list_master.str;
 
332
 
 
333
  if (aslist->next)
 
334
    aslist->next->prev = aslist->prev;
 
335
  else
 
336
    list->tail = aslist->prev;
 
337
 
 
338
  if (aslist->prev)
 
339
    aslist->prev->next = aslist->next;
 
340
  else
 
341
    list->head = aslist->next;
 
342
 
 
343
  as_list_free (aslist);
 
344
}
 
345
 
 
346
static int
 
347
as_list_empty (struct as_list *aslist)
 
348
{
 
349
  if (aslist->head == NULL && aslist->tail == NULL)
 
350
    return 1;
 
351
  else
 
352
    return 0;
 
353
}
 
354
 
 
355
void
 
356
as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
 
357
{
 
358
  if (asfilter->next)
 
359
    asfilter->next->prev = asfilter->prev;
 
360
  else
 
361
    aslist->tail = asfilter->prev;
 
362
 
 
363
  if (asfilter->prev)
 
364
    asfilter->prev->next = asfilter->next;
 
365
  else
 
366
    aslist->head = asfilter->next;
 
367
 
 
368
  as_filter_free (asfilter);
 
369
 
 
370
  /* If access_list becomes empty delete it from access_master. */
 
371
  if (as_list_empty (aslist))
 
372
    as_list_delete (aslist);
 
373
 
 
374
  /* Run hook function. */
 
375
  if (as_list_master.delete_hook)
 
376
    (*as_list_master.delete_hook) ();
 
377
}
 
378
 
 
379
static int
 
380
as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
 
381
{
 
382
  if (bgp_regexec (asfilter->reg, aspath) != REG_NOMATCH)
 
383
    return 1;
 
384
  return 0;
 
385
}
 
386
 
 
387
/* Apply AS path filter to AS. */
 
388
enum as_filter_type
 
389
as_list_apply (struct as_list *aslist, void *object)
 
390
{
 
391
  struct as_filter *asfilter;
 
392
  struct aspath *aspath;
 
393
 
 
394
  aspath = (struct aspath *) object;
 
395
 
 
396
  if (aslist == NULL)
 
397
    return AS_FILTER_DENY;
 
398
 
 
399
  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
400
    {
 
401
      if (as_filter_match (asfilter, aspath))
 
402
        return asfilter->type;
 
403
    }
 
404
  return AS_FILTER_DENY;
 
405
}
 
406
 
 
407
/* Add hook function. */
 
408
void
 
409
as_list_add_hook (void (*func) ())
 
410
{
 
411
  as_list_master.add_hook = func;
 
412
}
 
413
 
 
414
/* Delete hook function. */
 
415
void
 
416
as_list_delete_hook (void (*func) ())
 
417
{
 
418
  as_list_master.delete_hook = func;
 
419
}
 
420
 
 
421
int
 
422
as_list_dup_check (struct as_list *aslist, struct as_filter *new)
 
423
{
 
424
  struct as_filter *asfilter;
 
425
 
 
426
  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
427
    {
 
428
      if (asfilter->type == new->type
 
429
          && strcmp (asfilter->reg_str, new->reg_str) == 0)
 
430
        return 1;
 
431
    }
 
432
  return 0;
 
433
}
 
434
 
 
435
DEFUN (ip_as_path, ip_as_path_cmd,
 
436
       "ip as-path access-list WORD (deny|permit) .LINE",
 
437
       IP_STR
 
438
       "BGP autonomous system path filter\n"
 
439
       "Specify an access list name\n"
 
440
       "Regular expression access list name\n"
 
441
       "Specify packets to reject\n"
 
442
       "Specify packets to forward\n"
 
443
       "A regular-expression to match the BGP AS paths\n")
 
444
{
 
445
  enum as_filter_type type;
 
446
  struct as_filter *asfilter;
 
447
  struct as_list *aslist;
 
448
  regex_t *regex;
 
449
  char *regstr;
 
450
 
 
451
  /* Check the filter type. */
 
452
  if (strncmp (argv[1], "p", 1) == 0)
 
453
    type = AS_FILTER_PERMIT;
 
454
  else if (strncmp (argv[1], "d", 1) == 0)
 
455
    type = AS_FILTER_DENY;
 
456
  else
 
457
    {
 
458
      vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
 
459
      return CMD_WARNING;
 
460
    }
 
461
 
 
462
  /* Check AS path regex. */
 
463
  regstr = argv_concat(argv, argc, 2);
 
464
 
 
465
  regex = bgp_regcomp (regstr);
 
466
  if (!regex)
 
467
    {
 
468
      XFREE (MTYPE_TMP, regstr);
 
469
      vty_out (vty, "can't compile regexp %s%s", argv[0],
 
470
               VTY_NEWLINE);
 
471
      return CMD_WARNING;
 
472
    }
 
473
 
 
474
  asfilter = as_filter_make (regex, regstr, type);
 
475
  
 
476
  XFREE (MTYPE_TMP, regstr);
 
477
 
 
478
  /* Install new filter to the access_list. */
 
479
  aslist = as_list_get (argv[0]);
 
480
 
 
481
  /* Duplicate insertion check. */;
 
482
  if (as_list_dup_check (aslist, asfilter))
 
483
    as_filter_free (asfilter);
 
484
  else
 
485
    as_list_filter_add (aslist, asfilter);
 
486
 
 
487
  return CMD_SUCCESS;
 
488
}
 
489
 
 
490
DEFUN (no_ip_as_path,
 
491
       no_ip_as_path_cmd,
 
492
       "no ip as-path access-list WORD (deny|permit) .LINE",
 
493
       NO_STR
 
494
       IP_STR
 
495
       "BGP autonomous system path filter\n"
 
496
       "Specify an access list name\n"
 
497
       "Regular expression access list name\n"
 
498
       "Specify packets to reject\n"
 
499
       "Specify packets to forward\n"
 
500
       "A regular-expression to match the BGP AS paths\n")
 
501
{
 
502
  enum as_filter_type type;
 
503
  struct as_filter *asfilter;
 
504
  struct as_list *aslist;
 
505
  char *regstr;
 
506
  regex_t *regex;
 
507
 
 
508
  /* Lookup AS list from AS path list. */
 
509
  aslist = as_list_lookup (argv[0]);
 
510
  if (aslist == NULL)
 
511
    {
 
512
      vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
 
513
               VTY_NEWLINE);
 
514
      return CMD_WARNING;
 
515
    }
 
516
 
 
517
  /* Check the filter type. */
 
518
  if (strncmp (argv[1], "p", 1) == 0)
 
519
    type = AS_FILTER_PERMIT;
 
520
  else if (strncmp (argv[1], "d", 1) == 0)
 
521
    type = AS_FILTER_DENY;
 
522
  else
 
523
    {
 
524
      vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
 
525
      return CMD_WARNING;
 
526
    }
 
527
  
 
528
  /* Compile AS path. */
 
529
  regstr = argv_concat(argv, argc, 2);
 
530
 
 
531
  regex = bgp_regcomp (regstr);
 
532
  if (!regex)
 
533
    {
 
534
      XFREE (MTYPE_TMP, regstr);
 
535
      vty_out (vty, "can't compile regexp %s%s", argv[0],
 
536
               VTY_NEWLINE);
 
537
      return CMD_WARNING;
 
538
    }
 
539
 
 
540
  /* Lookup asfilter. */
 
541
  asfilter = as_filter_lookup (aslist, regstr, type);
 
542
 
 
543
  XFREE (MTYPE_TMP, regstr);
 
544
  bgp_regex_free (regex);
 
545
 
 
546
  if (asfilter == NULL)
 
547
    {
 
548
      vty_out (vty, "%s", VTY_NEWLINE);
 
549
      return CMD_WARNING;
 
550
    }
 
551
 
 
552
  as_list_filter_delete (aslist, asfilter);
 
553
 
 
554
  return CMD_SUCCESS;
 
555
}
 
556
 
 
557
DEFUN (no_ip_as_path_all,
 
558
       no_ip_as_path_all_cmd,
 
559
       "no ip as-path access-list WORD",
 
560
       NO_STR
 
561
       IP_STR
 
562
       "BGP autonomous system path filter\n"
 
563
       "Specify an access list name\n"
 
564
       "Regular expression access list name\n")
 
565
{
 
566
  struct as_list *aslist;
 
567
 
 
568
  aslist = as_list_lookup (argv[0]);
 
569
  if (aslist == NULL)
 
570
    {
 
571
      vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
 
572
               VTY_NEWLINE);
 
573
      return CMD_WARNING;
 
574
    }
 
575
 
 
576
  as_list_delete (aslist);
 
577
 
 
578
  /* Run hook function. */
 
579
  if (as_list_master.delete_hook)
 
580
    (*as_list_master.delete_hook) ();
 
581
 
 
582
  return CMD_SUCCESS;
 
583
}
 
584
 
 
585
void
 
586
as_list_show (struct vty *vty, struct as_list *aslist)
 
587
{
 
588
  struct as_filter *asfilter;
 
589
 
 
590
  vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
 
591
 
 
592
  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
593
    {
 
594
      vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
 
595
               asfilter->reg_str, VTY_NEWLINE);
 
596
    }
 
597
}
 
598
 
 
599
void
 
600
as_list_show_all (struct vty *vty)
 
601
{
 
602
  struct as_list *aslist;
 
603
  struct as_filter *asfilter;
 
604
 
 
605
  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
 
606
    {
 
607
      vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
 
608
 
 
609
      for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
610
        {
 
611
          vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
 
612
                   asfilter->reg_str, VTY_NEWLINE);
 
613
        }
 
614
    }
 
615
 
 
616
  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
 
617
    {
 
618
      vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
 
619
 
 
620
      for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
621
        {
 
622
          vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
 
623
                   asfilter->reg_str, VTY_NEWLINE);
 
624
        }
 
625
    }
 
626
}
 
627
 
 
628
DEFUN (show_ip_as_path_access_list,
 
629
       show_ip_as_path_access_list_cmd,
 
630
       "show ip as-path-access-list WORD",
 
631
       SHOW_STR
 
632
       IP_STR
 
633
       "List AS path access lists\n"
 
634
       "AS path access list name\n")
 
635
{
 
636
  struct as_list *aslist;
 
637
 
 
638
  aslist = as_list_lookup (argv[0]);
 
639
  if (aslist)
 
640
    as_list_show (vty, aslist);
 
641
 
 
642
  return CMD_SUCCESS;
 
643
}
 
644
 
 
645
DEFUN (show_ip_as_path_access_list_all,
 
646
       show_ip_as_path_access_list_all_cmd,
 
647
       "show ip as-path-access-list",
 
648
       SHOW_STR
 
649
       IP_STR
 
650
       "List AS path access lists\n")
 
651
{
 
652
  as_list_show_all (vty);
 
653
  return CMD_SUCCESS;
 
654
}
 
655
 
 
656
int
 
657
config_write_as_list (struct vty *vty)
 
658
{
 
659
  struct as_list *aslist;
 
660
  struct as_filter *asfilter;
 
661
  int write = 0;
 
662
 
 
663
  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
 
664
    for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
665
      {
 
666
        vty_out (vty, "ip as-path access-list %s %s %s%s",
 
667
                 aslist->name, filter_type_str (asfilter->type), 
 
668
                 asfilter->reg_str,
 
669
                 VTY_NEWLINE);
 
670
        write++;
 
671
      }
 
672
 
 
673
  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
 
674
    for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
 
675
      {
 
676
        vty_out (vty, "ip as-path access-list %s %s %s%s",
 
677
                 aslist->name, filter_type_str (asfilter->type), 
 
678
                 asfilter->reg_str,
 
679
                 VTY_NEWLINE);
 
680
        write++;
 
681
      }
 
682
  return write;
 
683
}
 
684
 
 
685
struct cmd_node as_list_node =
 
686
{
 
687
  AS_LIST_NODE,
 
688
  "",
 
689
  1
 
690
};
 
691
 
 
692
/* Register functions. */
 
693
void
 
694
bgp_filter_init ()
 
695
{
 
696
  install_node (&as_list_node, config_write_as_list);
 
697
 
 
698
  install_element (CONFIG_NODE, &ip_as_path_cmd);
 
699
  install_element (CONFIG_NODE, &no_ip_as_path_cmd);
 
700
  install_element (CONFIG_NODE, &no_ip_as_path_all_cmd);
 
701
 
 
702
  install_element (VIEW_NODE, &show_ip_as_path_access_list_cmd);
 
703
  install_element (VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
 
704
  install_element (ENABLE_NODE, &show_ip_as_path_access_list_cmd);
 
705
  install_element (ENABLE_NODE, &show_ip_as_path_access_list_all_cmd);
 
706
}