Diff for /embedaddon/quagga/bgpd/bgp_clist.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 17:26:12 version 1.1.1.2, 2016/11/02 10:09:10
Line 23  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 23  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "command.h"  #include "command.h"
 #include "prefix.h"  #include "prefix.h"
 #include "memory.h"  #include "memory.h"
   #include "filter.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_community.h"  #include "bgpd/bgp_community.h"
Line 30  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 31  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "bgpd/bgp_aspath.h"  #include "bgpd/bgp_aspath.h"
 #include "bgpd/bgp_regex.h"  #include "bgpd/bgp_regex.h"
 #include "bgpd/bgp_clist.h"  #include "bgpd/bgp_clist.h"
 /* Lookup master structure for community-list or  /* Lookup master structure for community-list or
    extcommunity-list.  */     extcommunity-list.  */
 struct community_list_master *  struct community_list_master *
Line 262  community_list_empty_p (struct community_list *list) Line 263  community_list_empty_p (struct community_list *list)
 {  {
   return (list->head == NULL && list->tail == NULL) ? 1 : 0;    return (list->head == NULL && list->tail == NULL) ? 1 : 0;
 }  }
 /* Add community-list entry to the list.  */  /* Add community-list entry to the list.  */
 static void  static void
 community_list_entry_add (struct community_list *list,  community_list_entry_add (struct community_list *list,
Line 329  community_list_entry_lookup (struct community_list *li Line 330  community_list_entry_lookup (struct community_list *li
     }      }
   return NULL;    return NULL;
 }  }
 static char *
 community_str_get (struct community *com, int i)
 {
   int len;
   u_int32_t comval;
   u_int16_t as;
   u_int16_t val;
   char *str;
   char *pnt;
 
   memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
   comval = ntohl (comval);
 
   switch (comval)
     {
       case COMMUNITY_INTERNET:
         len = strlen (" internet");
         break;
       case COMMUNITY_NO_EXPORT:
         len = strlen (" no-export");
         break;
       case COMMUNITY_NO_ADVERTISE:
         len = strlen (" no-advertise");
         break;
       case COMMUNITY_LOCAL_AS:
         len = strlen (" local-AS");
         break;
       default:
         len = strlen (" 65536:65535");
         break;
     }
 
   /* Allocate memory.  */
   str = pnt = XMALLOC (MTYPE_COMMUNITY_STR, len);
 
   switch (comval)
     {
       case COMMUNITY_INTERNET:
         strcpy (pnt, "internet");
         pnt += strlen ("internet");
         break;
       case COMMUNITY_NO_EXPORT:
         strcpy (pnt, "no-export");
         pnt += strlen ("no-export");
         break;
       case COMMUNITY_NO_ADVERTISE:
         strcpy (pnt, "no-advertise");
         pnt += strlen ("no-advertise");
         break;
       case COMMUNITY_LOCAL_AS:
         strcpy (pnt, "local-AS");
         pnt += strlen ("local-AS");
         break;
       default:
         as = (comval >> 16) & 0xFFFF;
         val = comval & 0xFFFF;
         sprintf (pnt, "%u:%d", as, val);
         pnt += strlen (pnt);
         break;
     }
 
   *pnt = '\0';
 
   return str;
 }
 
 /* Internal function to perform regular expression match for
  *  * a single community. */
 static int
 community_regexp_include (regex_t * reg, struct community *com, int i)
 {
   const char *str;
 
   /* When there is no communities attribute it is treated as empty
  *      string.  */
   if (com == NULL || com->size == 0)
     str = "";
   else
     str = community_str_get (com, i);
 
   /* Regular expression match.  */
   if (regexec (reg, str, 0, NULL, 0) == 0)
     return 1;
 
   /* No match.  */
   return 0;
 }
 
 /* Internal function to perform regular expression match for community  /* Internal function to perform regular expression match for community
    attribute.  */     attribute.  */
 static int  static int
Line 372  ecommunity_regexp_match (struct ecommunity *ecom, rege Line 461  ecommunity_regexp_match (struct ecommunity *ecom, rege
   return 0;    return 0;
 }  }
   
 /* Delete community attribute using regular expression match.  Return  
    modified communites attribute.  */  
 static struct community *  
 community_regexp_delete (struct community *com, regex_t * reg)  
 {  
   int i;  
   u_int32_t comval;  
   /* Maximum is "65535:65535" + '\0'. */  
   char c[12];  
   const char *str;  
   
   if (!com)  
     return NULL;  
   
   i = 0;  
   while (i < com->size)  
     {  
       memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));  
       comval = ntohl (comval);  
   
       switch (comval)  
         {  
         case COMMUNITY_INTERNET:  
           str = "internet";  
           break;  
         case COMMUNITY_NO_EXPORT:  
           str = "no-export";  
           break;  
         case COMMUNITY_NO_ADVERTISE:  
           str = "no-advertise";  
           break;  
         case COMMUNITY_LOCAL_AS:  
           str = "local-AS";  
           break;  
         default:  
           sprintf (c, "%d:%d", (comval >> 16) & 0xFFFF, comval & 0xFFFF);  
           str = c;  
           break;  
         }  
   
       if (regexec (reg, str, 0, NULL, 0) == 0)  
         community_del_val (com, com_nthval (com, i));  
       else  
         i++;  
     }  
   return com;  
 }  
   
 /* When given community attribute matches to the community-list return  /* When given community attribute matches to the community-list return
    1 else return 0.  */     1 else return 0.  */
 int  int
Line 509  community_list_match_delete (struct community *com, Line 550  community_list_match_delete (struct community *com,
                              struct community_list *list)                               struct community_list *list)
 {  {
   struct community_entry *entry;    struct community_entry *entry;
     u_int32_t val;
     u_int32_t com_index_to_delete[com->size];
     int delete_index = 0;
     int i;
   
  for (entry = list->head; entry; entry = entry->next)  /* Loop over each community value and evaluate each against the
    * community-list.  If we need to delete a community value add its index to
    * com_index_to_delete.
    */
   for (i = 0; i < com->size; i++)
     {      {
      if (entry->any)      val = community_val_get (com, i);
 
       for (entry = list->head; entry; entry = entry->next)
         {          {
          if (entry->direct == COMMUNITY_PERMIT)           if (entry->any)
             {              {
              /* This is a tricky part.  Currently only              if (entry->direct == COMMUNITY_PERMIT)
               * route_set_community_delete() uses this function.  In the                {
               * function com->size is zero, it free the community                  com_index_to_delete[delete_index] = i;
               * structure.                    delete_index++;
               */                }
              com->size = 0;              break;
             }              }
           return com;  
         }  
   
      if ((entry->style == COMMUNITY_LIST_STANDARD)           else if ((entry->style == COMMUNITY_LIST_STANDARD)
          && (community_include (entry->u.com, COMMUNITY_INTERNET)                   && (community_include (entry->u.com, COMMUNITY_INTERNET)
              || community_match (com, entry->u.com) ))                       || community_include (entry->u.com, val) ))
        {            {
               if (entry->direct == COMMUNITY_PERMIT)                if (entry->direct == COMMUNITY_PERMIT)
                community_delete (com, entry->u.com);                {
              else                  com_index_to_delete[delete_index] = i;
                break;                  delete_index++;
        }                }
      else if ((entry->style == COMMUNITY_LIST_EXPANDED)              break;
               && community_regexp_match (com, entry->reg))            }
        {
          if (entry->direct == COMMUNITY_PERMIT)          else if ((entry->style == COMMUNITY_LIST_EXPANDED)
            community_regexp_delete (com, entry->reg);                   && community_regexp_include (entry->reg, com, i))
          else            {
            break;              if (entry->direct == COMMUNITY_PERMIT)
        }                {
                   com_index_to_delete[delete_index] = i;
                   delete_index++;
                 }
               break;
             }
          }
      }
 
   /* Delete all of the communities we flagged for deletion */
   for (i = delete_index-1; i >= 0; i--)
     {
       val = community_val_get (com, com_index_to_delete[i]);
       community_del_val (com, &val);
     }      }
   
   return com;    return com;
 }  }
   
Line 590  community_list_dup_check (struct community_list *list, Line 653  community_list_dup_check (struct community_list *list,
     }      }
   return 0;    return 0;
 }  }
 /* Set community-list.  */  /* Set community-list.  */
 int  int
 community_list_set (struct community_list_handler *ch,  community_list_set (struct community_list_handler *ch,

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>