📄 bgp_filter.c
字号:
/* AS path filter list. Copyright (C) 1999 Kunihiro IshiguroThis file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING. If not, write to the FreeSoftware Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. */#include <zebra.h>#include "command.h"#include "log.h"#include "memory.h"#include "buffer.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_aspath.h"#include "bgpd/bgp_regex.h"#include "bgpd/bgp_filter.h"/* List of AS filter list. */struct as_list_list{ struct as_list *head; struct as_list *tail;};/* AS path filter master. */struct as_list_master{ /* List of access_list which name is number. */ struct as_list_list num; /* List of access_list which name is string. */ struct as_list_list str; /* Hook function which is executed when new access_list is added. */ void (*add_hook) (); /* Hook function which is executed when access_list is deleted. */ void (*delete_hook) ();};/* Element of AS path filter. */struct as_filter{ struct as_filter *next; struct as_filter *prev; enum as_filter_type type; regex_t *reg; char *reg_str;};enum as_list_type{ ACCESS_TYPE_STRING, ACCESS_TYPE_NUMBER};/* AS path filter list. */struct as_list{ char *name; enum as_list_type type; struct as_list *next; struct as_list *prev; struct as_filter *head; struct as_filter *tail;};/* ip as-path access-list 10 permit AS1. */static struct as_list_master as_list_master ={ {NULL, NULL}, {NULL, NULL}, NULL, NULL};/* Allocate new AS filter. */struct as_filter *as_filter_new (){ struct as_filter *new; new = XMALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter)); memset (new, 0, sizeof (struct as_filter)); return new;}/* Free allocated AS filter. */voidas_filter_free (struct as_filter *asfilter){ if (asfilter->reg) bgp_regex_free (asfilter->reg); if (asfilter->reg_str) XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str); XFREE (MTYPE_AS_FILTER, asfilter);}/* Make new AS filter. */struct as_filter *as_filter_make (regex_t *reg, char *reg_str, enum as_filter_type type){ struct as_filter *asfilter; asfilter = as_filter_new (); asfilter->reg = reg; asfilter->type = type; asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str); return asfilter;}struct as_filter *as_filter_lookup (struct as_list *aslist, char *reg_str, enum as_filter_type type){ struct as_filter *asfilter; for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) if (strcmp (reg_str, asfilter->reg_str) == 0) return asfilter; return NULL;}voidas_list_filter_add (struct as_list *aslist, struct as_filter *asfilter){ asfilter->next = NULL; asfilter->prev = aslist->tail; if (aslist->tail) aslist->tail->next = asfilter; else aslist->head = asfilter; aslist->tail = asfilter;}/* Lookup as_list from list of as_list by name. */struct as_list *as_list_lookup (char *name){ struct as_list *aslist; if (name == NULL) return NULL; for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) if (strcmp (aslist->name, name) == 0) return aslist; for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) if (strcmp (aslist->name, name) == 0) return aslist; return NULL;}struct as_list *as_list_new (){ struct as_list *new; new = XMALLOC (MTYPE_AS_LIST, sizeof (struct as_list)); memset (new, 0, sizeof (struct as_list)); return new;}voidas_list_free (struct as_list *aslist){ XFREE (MTYPE_AS_LIST, aslist);}/* Insert new AS list to list of as_list. Each as_list is sorted by the name. */struct as_list *as_list_insert (char *name){ int i; long number; struct as_list *aslist; struct as_list *point; struct as_list_list *list; /* Allocate new access_list and copy given name. */ aslist = as_list_new (); aslist->name = strdup (name); /* If name is made by all digit character. We treat it as number. */ for (number = 0, i = 0; i < strlen (name); i++) { if (isdigit ((int) name[i])) number = (number * 10) + (name[i] - '0'); else break; } /* In case of name is all digit character */ if (i == strlen (name)) { aslist->type = ACCESS_TYPE_NUMBER; /* Set access_list to number list. */ list = &as_list_master.num; for (point = list->head; point; point = point->next) if (atol (point->name) >= number) break; } else { aslist->type = ACCESS_TYPE_STRING; /* Set access_list to string list. */ list = &as_list_master.str; /* Set point to insertion point. */ for (point = list->head; point; point = point->next) if (strcmp (point->name, name) >= 0) break; } /* In case of this is the first element of master. */ if (list->head == NULL) { list->head = list->tail = aslist; return aslist; } /* In case of insertion is made at the tail of access_list. */ if (point == NULL) { aslist->prev = list->tail; list->tail->next = aslist; list->tail = aslist; return aslist; } /* In case of insertion is made at the head of access_list. */ if (point == list->head) { aslist->next = list->head; list->head->prev = aslist; list->head = aslist; return aslist; } /* Insertion is made at middle of the access_list. */ aslist->next = point; aslist->prev = point->prev; if (point->prev) point->prev->next = aslist; point->prev = aslist; return aslist;}struct as_list *as_list_get (char *name){ struct as_list *aslist; aslist = as_list_lookup (name); if (aslist == NULL) { aslist = as_list_insert (name); /* Run hook function. */ if (as_list_master.add_hook) (*as_list_master.add_hook) (); } return aslist;}static char *filter_type_str (enum as_filter_type type){ switch (type) { case AS_FILTER_PERMIT: return "permit"; break; case AS_FILTER_DENY: return "deny"; break; default: return ""; break; }}voidas_list_delete (struct as_list *aslist){ struct as_list_list *list; struct as_filter *filter, *next; for (filter = aslist->head; filter; filter = next) { next = filter->next; as_filter_free (filter); } if (aslist->type == ACCESS_TYPE_NUMBER) list = &as_list_master.num; else list = &as_list_master.str; if (aslist->next) aslist->next->prev = aslist->prev; else list->tail = aslist->prev; if (aslist->prev) aslist->prev->next = aslist->next; else list->head = aslist->next; as_list_free (aslist);}static intas_list_empty (struct as_list *aslist){ if (aslist->head == NULL && aslist->tail == NULL) return 1; else return 0;}voidas_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter){ if (asfilter->next) asfilter->next->prev = asfilter->prev; else aslist->tail = asfilter->prev; if (asfilter->prev) asfilter->prev->next = asfilter->next; else aslist->head = asfilter->next; as_filter_free (asfilter); /* If access_list becomes empty delete it from access_master. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -