⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 routemap.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Route map function.   Copyright (C) 1998, 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 "linklist.h"#include "memory.h"#include "vector.h"#include "prefix.h"#include "routemap.h"#include "command.h"/* Vector for route match rules. */static vector route_match_vec;/* Vector for route set rules. */static vector route_set_vec;/* Route map rule. This rule has both `match' rule and `set' rule. */struct route_map_rule{  /* Rule type. */  struct route_map_rule_cmd *cmd;  /* For pretty printing. */  char *rule_str;  /* Pre-compiled match rule. */  void *value;  /* Linked list. */  struct route_map_rule *next;  struct route_map_rule *prev;};/* Making route map list. */struct route_map_list{  struct route_map *head;  struct route_map *tail;  void (*add_hook) (char *);  void (*delete_hook) (char *);  void (*event_hook) (route_map_event_t, char *); };/* Master list of route map. */static struct route_map_list route_map_master = { NULL, NULL, NULL, NULL };static voidroute_map_rule_delete (struct route_map_rule_list *,		       struct route_map_rule *);static voidroute_map_index_delete (struct route_map_index *, int);/* New route map allocation. Please note route map's name must be   specified. */static struct route_map *route_map_new (char *name){  struct route_map *new;  new =  XCALLOC (MTYPE_ROUTE_MAP, sizeof (struct route_map));  new->name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, name);  return new;}/* Add new name to route_map. */static struct route_map *route_map_add (char *name){  struct route_map *map;  struct route_map_list *list;  map = route_map_new (name);  list = &route_map_master;      map->next = NULL;  map->prev = list->tail;  if (list->tail)    list->tail->next = map;  else    list->head = map;  list->tail = map;  /* Execute hook. */  if (route_map_master.add_hook)    (*route_map_master.add_hook) (name);  return map;}/* Route map delete from list. */static voidroute_map_delete (struct route_map *map){  struct route_map_list *list;  struct route_map_index *index;  char *name;    while ((index = map->head) != NULL)    route_map_index_delete (index, 0);  name = map->name;  list = &route_map_master;  if (map->next)    map->next->prev = map->prev;  else    list->tail = map->prev;  if (map->prev)    map->prev->next = map->next;  else    list->head = map->next;  XFREE (MTYPE_ROUTE_MAP, map);  /* Execute deletion hook. */  if (route_map_master.delete_hook)    (*route_map_master.delete_hook) (name);  if (name)    XFREE (MTYPE_ROUTE_MAP_NAME, name);}/* Lookup route map by route map name string. */struct route_map *route_map_lookup_by_name (char *name){  struct route_map *map;  for (map = route_map_master.head; map; map = map->next)    if (strcmp (map->name, name) == 0)      return map;  return NULL;}/* Lookup route map.  If there isn't route map create one and return   it. */struct route_map *route_map_get (char *name){  struct route_map *map;  map = route_map_lookup_by_name (name);  if (map == NULL)    map = route_map_add (name);  return map;}/* Return route map's type string. */static char *route_map_type_str (enum route_map_type type){  switch (type)    {    case RMAP_PERMIT:      return "permit";      break;    case RMAP_DENY:      return "deny";      break;    default:      return "";      break;    }}introute_map_empty (struct route_map *map){  if (map->head == NULL && map->tail == NULL)    return 1;  else    return 0;}/* For debug. */voidroute_map_print (){  struct route_map *map;  struct route_map_index *index;  struct route_map_rule *rule;  for (map = route_map_master.head; map; map = map->next)    for (index = map->head; index; index = index->next)      {	printf ("route-map %s %s %d\n", 		map->name,		route_map_type_str (index->type),		index->pref);	for (rule = index->match_list.head; rule; rule = rule->next)	  printf (" match %s %s\n", rule->cmd->str, rule->rule_str);	for (rule = index->set_list.head; rule; rule = rule->next)	  printf (" set %s %s\n", rule->cmd->str, rule->rule_str);	if (index->exitpolicy == RMAP_GOTO)	  printf (" on-match goto %d\n", index->nextpref);	if (index->exitpolicy == RMAP_NEXT)	  printf (" on-match next\n");      }}/* New route map allocation. Please note route map's name must be   specified. */struct route_map_index *route_map_index_new (){  struct route_map_index *new;  new =  XCALLOC (MTYPE_ROUTE_MAP_INDEX, sizeof (struct route_map_index));  new->exitpolicy = RMAP_EXIT; /* Default to Cisco-style */  return new;}/* Free route map index. */static voidroute_map_index_delete (struct route_map_index *index, int notify){  struct route_map_rule *rule;  /* Free route match. */  while ((rule = index->match_list.head) != NULL)    route_map_rule_delete (&index->match_list, rule);  /* Free route set. */  while ((rule = index->set_list.head) != NULL)    route_map_rule_delete (&index->set_list, rule);  /* Remove index from route map list. */  if (index->next)    index->next->prev = index->prev;  else    index->map->tail = index->prev;  if (index->prev)    index->prev->next = index->next;  else    index->map->head = index->next;    /* Execute event hook. */  if (route_map_master.event_hook && notify)    (*route_map_master.event_hook) (RMAP_EVENT_INDEX_DELETED,				    index->map->name);  XFREE (MTYPE_ROUTE_MAP_INDEX, index);}/* Lookup index from route map. */struct route_map_index *route_map_index_lookup (struct route_map *map, enum route_map_type type,			int pref){  struct route_map_index *index;  for (index = map->head; index; index = index->next)    if ((index->type == type || type == RMAP_ANY)	&& index->pref == pref)      return index;  return NULL;}/* Add new index to route map. */struct route_map_index *route_map_index_add (struct route_map *map, enum route_map_type type,		     int pref){  struct route_map_index *index;  struct route_map_index *point;  /* Allocate new route map inex. */  index = route_map_index_new ();  index->map = map;  index->type = type;  index->pref = pref;    /* Compare preference. */  for (point = map->head; point; point = point->next)    if (point->pref >= pref)      break;  if (map->head == NULL)    {      map->head = map->tail = index;    }  else if (point == NULL)    {      index->prev = map->tail;      map->tail->next = index;      map->tail = index;    }  else if (point == map->head)    {      index->next = map->head;      map->head->prev = index;      map->head = index;    }  else    {      index->next = point;      index->prev = point->prev;      if (point->prev)	point->prev->next = index;      point->prev = index;    }  /* Execute event hook. */  if (route_map_master.event_hook)    (*route_map_master.event_hook) (RMAP_EVENT_INDEX_ADDED,				    map->name);  return index;}/* Get route map index. */struct route_map_index *route_map_index_get (struct route_map *map, enum route_map_type type, 		     int pref){  struct route_map_index *index;  index = route_map_index_lookup (map, RMAP_ANY, pref);  if (index && index->type != type)    {      /* Delete index from route map. */      route_map_index_delete (index, 1);      index = NULL;    }  if (index == NULL)    index = route_map_index_add (map, type, pref);  return index;}/* New route map rule */struct route_map_rule *route_map_rule_new (){  struct route_map_rule *new;  new = XCALLOC (MTYPE_ROUTE_MAP_RULE, sizeof (struct route_map_rule));  return new;}/* Install rule command to the match list. */voidroute_map_install_match (struct route_map_rule_cmd *cmd){  vector_set (route_match_vec, cmd);}/* Install rule command to the set list. */voidroute_map_install_set (struct route_map_rule_cmd *cmd){  vector_set (route_set_vec, cmd);}/* Lookup rule command from match list. */struct route_map_rule_cmd *route_map_lookup_match (char *name){  int i;  struct route_map_rule_cmd *rule;  for (i = 0; i < vector_max (route_match_vec); i++)    if ((rule = vector_slot (route_match_vec, i)) != NULL)      if (strcmp (rule->str, name) == 0)	return rule;  return NULL;}/* Lookup rule command from set list. */struct route_map_rule_cmd *route_map_lookup_set (char *name){  int i;  struct route_map_rule_cmd *rule;  for (i = 0; i < vector_max (route_set_vec); i++)    if ((rule = vector_slot (route_set_vec, i)) != NULL)      if (strcmp (rule->str, name) == 0)	return rule;  return NULL;}/* Add match and set rule to rule list. */static voidroute_map_rule_add (struct route_map_rule_list *list,		    struct route_map_rule *rule){  rule->next = NULL;  rule->prev = list->tail;  if (list->tail)    list->tail->next = rule;  else    list->head = rule;  list->tail = rule;}/* Delete rule from rule list. */static voidroute_map_rule_delete (struct route_map_rule_list *list,		       struct route_map_rule *rule){  if (rule->cmd->func_free)    (*rule->cmd->func_free) (rule->value);  if (rule->rule_str)    XFREE (MTYPE_ROUTE_MAP_RULE_STR, rule->rule_str);  if (rule->next)    rule->next->prev = rule->prev;  else    list->tail = rule->prev;  if (rule->prev)    rule->prev->next = rule->next;  else    list->head = rule->next;  XFREE (MTYPE_ROUTE_MAP_RULE, rule);}/* strcmp wrapper function which don't crush even argument is NULL. */intrulecmp (char *dst, char *src){  if (dst == NULL)    {      if (src ==  NULL)	return 0;      else	return 1;    }  else    {      if (src == NULL)	return 1;      else	return strcmp (dst, src);    }  return 1;}/* Add match statement to route map. */introute_map_add_match (struct route_map_index *index, char *match_name,		     char *match_arg){  struct route_map_rule *rule;  struct route_map_rule *next;  struct route_map_rule_cmd *cmd;  void *compile;  int replaced = 0;  /* First lookup rule for add match statement. */  cmd = route_map_lookup_match (match_name);  if (cmd == NULL)    return RMAP_RULE_MISSING;  /* Next call compile function for this match statement. */  if (cmd->func_compile)    {      compile= (*cmd->func_compile)(match_arg);      if (compile == NULL)	return RMAP_COMPILE_ERROR;    }  else    compile = NULL;  /* If argument is completely same ignore it. */  for (rule = index->match_list.head; rule; rule = next)    {      next = rule->next;      if (rule->cmd == cmd)	{		  route_map_rule_delete (&index->match_list, rule);	  replaced = 1;	}    }  /* Add new route map match rule. */  rule = route_map_rule_new ();  rule->cmd = cmd;  rule->value = compile;  if (match_arg)    rule->rule_str = XSTRDUP (MTYPE_ROUTE_MAP_RULE_STR, match_arg);  else    rule->rule_str = NULL;  /* Add new route match rule to linked list. */  route_map_rule_add (&index->match_list, rule);  /* Execute event hook. */  if (route_map_master.event_hook)    (*route_map_master.event_hook) (replaced ?				    RMAP_EVENT_MATCH_REPLACED:				    RMAP_EVENT_MATCH_ADDED,				    index->map->name);  return 0;}/* Delete specified route match rule. */introute_map_delete_match (struct route_map_index *index, char *match_name,			char *match_arg){  struct route_map_rule *rule;  struct route_map_rule_cmd *cmd;  cmd = route_map_lookup_match (match_name);  if (cmd == NULL)    return 1;    for (rule = index->match_list.head; rule; rule = rule->next)    if (rule->cmd == cmd && 	(rulecmp (rule->rule_str, match_arg) == 0 || match_arg == NULL))      {	route_map_rule_delete (&index->match_list, rule);	/* Execute event hook. */	if (route_map_master.event_hook)	  (*route_map_master.event_hook) (RMAP_EVENT_MATCH_DELETED,					  index->map->name);	return 0;      }  /* Can't find matched rule. */  return 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -