/* Community attribute related functions.
- Copyright (C) 1998, 2001 Kunihiro Ishiguro
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 1998, 2001 Kunihiro Ishiguro
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include <zebra.h>
+#include "command.h"
#include "hash.h"
#include "memory.h"
+#include "bgpd/bgp_memory.h"
#include "bgpd/bgp_community.h"
/* Hash of community attribute. */
XFREE (MTYPE_COMMUNITY_VAL, com->val);
if (com->str)
XFREE (MTYPE_COMMUNITY_STR, com->str);
+
+ if (com->json)
+ {
+ json_object_free(com->json);
+ com->json = NULL;
+ }
+
XFREE (MTYPE_COMMUNITY, com);
}
c = com->size -i -1;
if (c > 0)
- memcpy (com->val + i, com->val + (i + 1), c * sizeof (*val));
+ memmove (com->val + i, com->val + (i + 1), c * sizeof (*val));
com->size--;
return 0;
}
-static u_int32_t
+u_int32_t
community_val_get (struct community *com, int i)
{
u_char *p;
return NULL;
new = community_new ();;
+ new->json = NULL;
for (i = 0; i < com->size; i++)
{
0xFFFFFF03 "local-AS"
For other values, "AS:VAL" format is used. */
-static char *
-community_com2str (struct community *com)
+static void
+set_community_string (struct community *com)
{
int i;
char *str;
u_int32_t comval;
u_int16_t as;
u_int16_t val;
+ json_object *json_community_list = NULL;
+ json_object *json_string = NULL;
if (!com)
- return NULL;
+ return;
+ com->json = json_object_new_object();
+ json_community_list = json_object_new_array();
+
/* When communities attribute is empty. */
if (com->size == 0)
{
str = XMALLOC (MTYPE_COMMUNITY_STR, 1);
str[0] = '\0';
- return str;
+
+ json_object_string_add(com->json, "string", "");
+ json_object_object_add(com->json, "list", json_community_list);
+ com->str = str;
+ return;
}
/* Memory allocation is time consuming work. So we calculate
case COMMUNITY_INTERNET:
strcpy (pnt, "internet");
pnt += strlen ("internet");
+ json_string = json_object_new_string("internet");
+ json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_NO_EXPORT:
strcpy (pnt, "no-export");
pnt += strlen ("no-export");
+ json_string = json_object_new_string("noExport");
+ json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_NO_ADVERTISE:
strcpy (pnt, "no-advertise");
pnt += strlen ("no-advertise");
+ json_string = json_object_new_string("noAdvertise");
+ json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_LOCAL_AS:
strcpy (pnt, "local-AS");
pnt += strlen ("local-AS");
+ json_string = json_object_new_string("localAs");
+ json_object_array_add(json_community_list, json_string);
break;
default:
as = (comval >> 16) & 0xFFFF;
val = comval & 0xFFFF;
sprintf (pnt, "%u:%d", as, val);
+ json_string = json_object_new_string(pnt);
+ json_object_array_add(json_community_list, json_string);
pnt += strlen (pnt);
break;
}
}
*pnt = '\0';
- return str;
+ json_object_string_add(com->json, "string", str);
+ json_object_object_add(com->json, "list", json_community_list);
+ com->str = str;
}
/* Intern communities attribute. */
/* Make string. */
if (! find->str)
- find->str = community_com2str (find);
+ set_community_string (find);
return find;
}
/* Free community attribute. */
void
-community_unintern (struct community *com)
+community_unintern (struct community **com)
{
struct community *ret;
- if (com->refcnt)
- com->refcnt--;
+ if ((*com)->refcnt)
+ (*com)->refcnt--;
/* Pull off from hash. */
- if (com->refcnt == 0)
+ if ((*com)->refcnt == 0)
{
/* Community value com must exist in hash. */
- ret = (struct community *) hash_release (comhash, com);
+ ret = (struct community *) hash_release (comhash, *com);
assert (ret != NULL);
- community_free (com);
+ community_free (*com);
+ *com = NULL;
}
}
{
if (!com)
return NULL;
-
+
if (! com->str)
- com->str = community_com2str (com);
+ set_community_string (com);
return com->str;
}
unsigned int
community_hash_make (struct community *com)
{
+ unsigned char *pnt = (unsigned char *)com->val;
+ int size = com->size * 4;
+ unsigned int key = 0;
int c;
- unsigned int key;
- unsigned char *pnt;
- key = 0;
- pnt = (unsigned char *)com->val;
-
- for(c = 0; c < com->size * 4; c++)
- key += pnt[c];
-
+ for (c = 0; c < size; c += 4)
+ {
+ key += pnt[c];
+ key += pnt[c + 1];
+ key += pnt[c + 2];
+ key += pnt[c + 3];
+ }
+
return key;
}
{
separator = 1;
digit = 0;
+
+ if (community_low > UINT16_MAX)
+ {
+ *token = community_token_unknown;
+ return NULL;
+ }
+
community_high = community_low << 16;
community_low = 0;
}
*token = community_token_unknown;
return NULL;
}
+
+ if (community_low > UINT16_MAX)
+ {
+ *token = community_token_unknown;
+ return NULL;
+ }
+
*val = community_high + community_low;
*token = community_token_val;
return p;
case community_token_no_advertise:
case community_token_local_as:
if (com == NULL)
- com = community_new();
+ {
+ com = community_new();
+ com->json = NULL;
+ }
community_add_val (com, val);
break;
case community_token_unknown:
community_init (void)
{
comhash = hash_create ((unsigned int (*) (void *))community_hash_make,
- (int (*) (const void *, const void *))community_cmp);
+ (int (*) (const void *, const void *))community_cmp, NULL);
+}
+
+void
+community_finish (void)
+{
+ hash_free (comhash);
+ comhash = NULL;
}