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

📄 routemap.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* Add route-map set statement to the route map. */introute_map_add_set (struct route_map_index *index, char *set_name,		   char *set_arg){  struct route_map_rule *rule;  struct route_map_rule *next;  struct route_map_rule_cmd *cmd;  void *compile;  int replaced = 0;  cmd = route_map_lookup_set (set_name);  if (cmd == NULL)    return RMAP_RULE_MISSING;  /* Next call compile function for this match statement. */  if (cmd->func_compile)    {      compile= (*cmd->func_compile)(set_arg);      if (compile == NULL)	return RMAP_COMPILE_ERROR;    }  else    compile = NULL; /* Add by WJL. if old set command of same kind exist, delete it first    to ensure only one set command of same kind exist under a    route_map_index. */  for (rule = index->set_list.head; rule; rule = next)    {      next = rule->next;      if (rule->cmd == cmd)	{	  route_map_rule_delete (&index->set_list, rule);	  replaced = 1;	}    }  /* Add new route map match rule. */  rule = route_map_rule_new ();  rule->cmd = cmd;  rule->value = compile;  if (set_arg)    rule->rule_str = XSTRDUP (MTYPE_ROUTE_MAP_RULE_STR, set_arg);  else    rule->rule_str = NULL;  /* Add new route match rule to linked list. */  route_map_rule_add (&index->set_list, rule);  /* Execute event hook. */  if (route_map_master.event_hook)    (*route_map_master.event_hook) (replaced ?				    RMAP_EVENT_SET_REPLACED:				    RMAP_EVENT_SET_ADDED,				    index->map->name);  return 0;}/* Delete route map set rule. */introute_map_delete_set (struct route_map_index *index, char *set_name,			char *set_arg){  struct route_map_rule *rule;  struct route_map_rule_cmd *cmd;  cmd = route_map_lookup_set (set_name);  if (cmd == NULL)    return 1;    for (rule = index->set_list.head; rule; rule = rule->next)    if ((rule->cmd == cmd) &&         (rulecmp (rule->rule_str, set_arg) == 0 || set_arg == NULL))      {        route_map_rule_delete (&index->set_list, rule);	/* Execute event hook. */	if (route_map_master.event_hook)	  (*route_map_master.event_hook) (RMAP_EVENT_SET_DELETED,					  index->map->name);        return 0;      }  /* Can't find matched rule. */  return 1;}/* Apply route map's each index to the object.   The matrix for a route-map looks like this:   (note, this includes the description for the "NEXT"   and "GOTO" frobs now                Match   |   No Match                      |    permit      a     |      c                      |    ------------------+---------------                      |    deny        b     |      d                      |     a) Apply Set statements, accept route      If NEXT is specified, goto NEXT statement      If GOTO is specified, goto the first clause where pref > nextpref      If nothing is specified, do as Cisco and finish   b) If NEXT is specified, goto NEXT statement      If nothing is specified, finally will be denied by route-map.   c) & d)   Goto Next index     If we get no matches after we've processed all updates, then the route   is dropped too.     Some notes on the new "NEXT" and "GOTO"     on-match next    - If this clause is matched, then the set statements                        are executed and then we drop through to the next clause     on-match goto n  - If this clause is matched, then the set statments                        are executed and then we goto the nth clause, or the                        first clause greater than this. In order to ensure                        route-maps *always* exit, you cannot jump backwards.                        Sorry ;)     We need to make sure our route-map processing matches the above*/route_map_result_troute_map_apply_index (struct route_map_index *index, struct prefix *prefix,                       route_map_object_t type, void *object){  int ret = 0;  struct route_map_rule *match;  struct route_map_rule *set;  /* Check all match rule and if there is no match rule, go to the     set statement. */  if (! index->match_list.head)    ret = RMAP_MATCH;  else    {      for (match = index->match_list.head; match; match = match->next)        {          /* Try each match statement in turn, If any return             RMAP_MATCH, go direct to set statement, otherwise, walk             to next match statement. */           ret = (*match->cmd->func_apply)(match->value, prefix, type, object);          if (ret == RMAP_MATCH)            break;	}    }  /* If end of match statement, still can't get any RMAP_MATCH return,     just return to next rout-map statement. */  if (ret != RMAP_MATCH)    return ret;  /* We get here if all match statements matched From the matrix     above, if this is PERMIT we go on and apply the SET functions.     If we're deny, we return indicating we matched a deny */  /* Apply set statement to the object. */  if (index->type == RMAP_PERMIT)    {      for (set = index->set_list.head; set; set = set->next)	ret = (*set->cmd->func_apply)(set->value, prefix, type, object);      return RMAP_MATCH;    }  else     {      return RMAP_DENYMATCH;    }  /* Should not get here! */  return RMAP_MATCH;}/* Apply route map to the object. */route_map_result_troute_map_apply (struct route_map *map, struct prefix *prefix, 		 route_map_object_t type, void *object){  int ret = 0;  struct route_map_index *index;  if (map == NULL)    return RMAP_DENYMATCH;  for (index = map->head; index; index = index->next)    {      /* Apply this index. End here if we get a RM_NOMATCH */      ret = route_map_apply_index (index, prefix, type, object);      if (ret == RMAP_MATCH || ret == RMAP_DENYMATCH)        return ret;      if (ret != RMAP_NOMATCH)	{	  /* We now have to handle the NEXT and GOTO clauses */	  if(index->exitpolicy == RMAP_EXIT)	    return ret;	  if(index->exitpolicy == RMAP_GOTO)	    {	      /* Find the next clause to jump to */	      struct route_map_index *next;	      next = index->next;	      while (next && next->pref < index->nextpref)		{		  index = next;		  next = next->next;		}	      if (next == NULL)		{		  /* No clauses match! */		  return ret;		}	    }	  /* Otherwise, we fall through as it was a NEXT */	}    }  /* Finally route-map does not match at all. */  return RMAP_DENYMATCH;}voidroute_map_add_hook (void (*func) (char *)){  route_map_master.add_hook = func;}voidroute_map_delete_hook (void (*func) (char *)){  route_map_master.delete_hook = func;}voidroute_map_event_hook (void (*func) (route_map_event_t, char *)){  route_map_master.event_hook = func;}voidroute_map_init (){  /* Make vector for match and set. */  route_match_vec = vector_init (1);  route_set_vec = vector_init (1);}/* VTY related functions. */DEFUN (route_map,       route_map_cmd,       "route-map WORD (deny|permit) <1-65535>",       "Create route-map or enter route-map command mode\n"       "Route map tag\n"       "Route map denies set operations\n"       "Route map permits set operations\n"       "Sequence to insert to/delete from existing route-map entry\n"){  int permit;  unsigned long pref;  struct route_map *map;  struct route_map_index *index;  char *endptr = NULL;  /* Permit check. */  if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)    permit = RMAP_PERMIT;  else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)    permit = RMAP_DENY;  else    {      vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);      return CMD_WARNING;    }  /* Preference check. */  pref = strtoul (argv[2], &endptr, 10);  if (pref == ULONG_MAX || *endptr != '\0')    {      vty_out (vty, "the fourth field must be positive integer%s",	       VTY_NEWLINE);      return CMD_WARNING;    }  if (pref == 0 || pref > 65535)    {      vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);      return CMD_WARNING;    }  /* Get route map. */  map = route_map_get (argv[0]);  index = route_map_index_get (map, permit, pref);  vty->index = index;  vty->node = RMAP_NODE;  return CMD_SUCCESS;}DEFUN (no_route_map_all,       no_route_map_all_cmd,       "no route-map WORD",       NO_STR       "Create route-map or enter route-map command mode\n"       "Route map tag\n"){  struct route_map *map;  map = route_map_lookup_by_name (argv[0]);  if (map == NULL)    {      vty_out (vty, "%% Could not find route-map %s%s",	       argv[0], VTY_NEWLINE);      return CMD_WARNING;    }  route_map_delete (map);  return CMD_SUCCESS;}DEFUN (no_route_map,       no_route_map_cmd,       "no route-map WORD (deny|permit) <1-65535>",       NO_STR       "Create route-map or enter route-map command mode\n"       "Route map tag\n"       "Route map denies set operations\n"       "Route map permits set operations\n"       "Sequence to insert to/delete from existing route-map entry\n"){  int permit;  unsigned long pref;  struct route_map *map;  struct route_map_index *index;  char *endptr = NULL;  /* Permit check. */  if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)    permit = RMAP_PERMIT;  else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)    permit = RMAP_DENY;  else    {      vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);      return CMD_WARNING;    }  /* Preference. */  pref = strtoul (argv[2], &endptr, 10);  if (pref == ULONG_MAX || *endptr != '\0')    {      vty_out (vty, "the fourth field must be positive integer%s",	       VTY_NEWLINE);      return CMD_WARNING;    }  if (pref == 0 || pref > 65535)    {      vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);      return CMD_WARNING;    }  /* Existence check. */  map = route_map_lookup_by_name (argv[0]);  if (map == NULL)    {      vty_out (vty, "%% Could not find route-map %s%s",	       argv[0], VTY_NEWLINE);      return CMD_WARNING;    }  /* Lookup route map index. */  index = route_map_index_lookup (map, permit, pref);  if (index == NULL)    {      vty_out (vty, "%% Could not find route-map entry %s %s%s", 	       argv[0], argv[2], VTY_NEWLINE);      return CMD_WARNING;    }  /* Delete index from route map. */  route_map_index_delete (index, 1);  /* If this route rule is the last one, delete route map itself. */  if (route_map_empty (map))    route_map_delete (map);  return CMD_SUCCESS;}DEFUN (rmap_onmatch_next,       rmap_onmatch_next_cmd,       "on-match next",       "Exit policy on matches\n"       "Next clause\n"){  struct route_map_index *index;  index = vty->index;  if (index)    index->exitpolicy = RMAP_NEXT;  return CMD_SUCCESS;}DEFUN (no_rmap_onmatch_next,       no_rmap_onmatch_next_cmd,       "no on-match next",       NO_STR       "Exit policy on matches\n"       "Next clause\n"){  struct route_map_index *index;  index = vty->index;    if (index)    index->exitpolicy = RMAP_EXIT;  return CMD_SUCCESS;}DEFUN (rmap_onmatch_goto,       rmap_onmatch_goto_cmd,       "on-match goto <1-65535>",       "Exit policy on matches\n"       "Goto Clause number\n"       "Number\n"){  struct route_map_index *index;  int d = 0;  if (argv[0])    d = atoi(argv[0]);  index = vty->index;  if (index)    {      if (d <= index->pref)	{	  /* Can't allow you to do that, Dave */	  vty_out (vty, "can't jump backwards in route-maps%s", 		   VTY_NEWLINE);	  return CMD_WARNING;	}      else	{	  index->exitpolicy = RMAP_GOTO;	  index->nextpref = d;	}    }  return CMD_SUCCESS;}DEFUN (no_rmap_onmatch_goto,       no_rmap_onmatch_goto_cmd,       "no on-match goto",       NO_STR       "Exit policy on matches\n"       "Next clause\n"){  struct route_map_index *index;  index = vty->index;  if (index)    index->exitpolicy = RMAP_EXIT;    return CMD_SUCCESS;}/* Configuration write function. */introute_map_config_write (struct vty *vty){  struct route_map *map;  struct route_map_index *index;  struct route_map_rule *rule;  int first = 1;  int write = 0;  for (map = route_map_master.head; map; map = map->next)    for (index = map->head; index; index = index->next)      {	if (!first)	  vty_out (vty, "!%s", VTY_NEWLINE);	else	  first = 0;	vty_out (vty, "route-map %s %s %d%s", 		 map->name,		 route_map_type_str (index->type),		 index->pref, VTY_NEWLINE);	for (rule = index->match_list.head; rule; rule = rule->next)	  vty_out (vty, " match %s %s%s", rule->cmd->str, 		   rule->rule_str ? rule->rule_str : "",		   VTY_NEWLINE);	for (rule = index->set_list.head; rule; rule = rule->next)	  vty_out (vty, " set %s %s%s", rule->cmd->str,		   rule->rule_str ? rule->rule_str : "",		   VTY_NEWLINE);	if (index->exitpolicy == RMAP_GOTO)	  vty_out (vty, " on-match goto %d%s", index->nextpref,		   VTY_NEWLINE);	if (index->exitpolicy == RMAP_NEXT)	  vty_out (vty," on-match next%s", VTY_NEWLINE);		write++;      }  return write;}/* Route map node structure. */struct cmd_node rmap_node ={  RMAP_NODE,  "%s(config-route-map)# ",  1};/* Initialization of route map vector. */voidroute_map_init_vty (){  /* Install route map top node. */  install_node (&rmap_node, route_map_config_write);  /* Install route map commands. */  install_default (RMAP_NODE);  install_element (CONFIG_NODE, &route_map_cmd);  install_element (CONFIG_NODE, &no_route_map_cmd);  install_element (CONFIG_NODE, &no_route_map_all_cmd);  /* Install the on-match stuff */  install_element (RMAP_NODE, &route_map_cmd);  install_element (RMAP_NODE, &rmap_onmatch_next_cmd);  install_element (RMAP_NODE, &no_rmap_onmatch_next_cmd);  install_element (RMAP_NODE, &rmap_onmatch_goto_cmd);  install_element (RMAP_NODE, &no_rmap_onmatch_goto_cmd);}

⌨️ 快捷键说明

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