version 1.1.1.3, 2013/07/21 23:54:37
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 29 Software Foundation, Inc., 59 Temple Place - Suite 330
|
Line 29 Software Foundation, Inc., 59 Temple Place - Suite 330
|
#include "log.h" |
#include "log.h" |
#include "stream.h" |
#include "stream.h" |
#include "jhash.h" |
#include "jhash.h" |
|
#include "filter.h" |
|
|
#include "bgpd/bgpd.h" |
#include "bgpd/bgpd.h" |
#include "bgpd/bgp_aspath.h" |
#include "bgpd/bgp_aspath.h" |
#include "bgpd/bgp_debug.h" |
#include "bgpd/bgp_debug.h" |
#include "bgpd/bgp_attr.h" |
#include "bgpd/bgp_attr.h" |
| |
/* Attr. Flags and Attr. Type Code. */ |
/* Attr. Flags and Attr. Type Code. */ |
#define AS_HEADER_SIZE 2 |
#define AS_HEADER_SIZE 2 |
|
|
Line 90 static struct hash *ashash;
|
Line 91 static struct hash *ashash;
|
|
|
/* Stream for SNMP. See aspath_snmp_pathseg */ |
/* Stream for SNMP. See aspath_snmp_pathseg */ |
static struct stream *snmp_stream; |
static struct stream *snmp_stream; |
| |
/* Callers are required to initialize the memory */ |
/* Callers are required to initialize the memory */ |
static as_t * |
static as_t * |
assegment_data_new (int num) |
assegment_data_new (int num) |
Line 98 assegment_data_new (int num)
|
Line 99 assegment_data_new (int num)
|
return (XMALLOC (MTYPE_AS_SEG_DATA, ASSEGMENT_DATA_SIZE (num, 1))); |
return (XMALLOC (MTYPE_AS_SEG_DATA, ASSEGMENT_DATA_SIZE (num, 1))); |
} |
} |
|
|
|
static void |
|
assegment_data_free (as_t *asdata) |
|
{ |
|
XFREE (MTYPE_AS_SEG_DATA, asdata); |
|
} |
|
|
/* Get a new segment. Note that 0 is an allowed length, |
/* Get a new segment. Note that 0 is an allowed length, |
* and will result in a segment with no allocated data segment. |
* and will result in a segment with no allocated data segment. |
* the caller should immediately assign data to the segment, as the segment |
* the caller should immediately assign data to the segment, as the segment |
Line 126 assegment_free (struct assegment *seg)
|
Line 133 assegment_free (struct assegment *seg)
|
return; |
return; |
|
|
if (seg->as) |
if (seg->as) |
XFREE (MTYPE_AS_SEG_DATA, seg->as); | assegment_data_free (seg->as); |
memset (seg, 0xfe, sizeof(struct assegment)); |
memset (seg, 0xfe, sizeof(struct assegment)); |
XFREE (MTYPE_AS_SEG, seg); |
XFREE (MTYPE_AS_SEG, seg); |
|
|
Line 194 assegment_prepend_asns (struct assegment *seg, as_t as
|
Line 201 assegment_prepend_asns (struct assegment *seg, as_t as
|
if (num >= AS_SEGMENT_MAX) |
if (num >= AS_SEGMENT_MAX) |
return seg; /* we don't do huge prepends */ |
return seg; /* we don't do huge prepends */ |
|
|
newas = assegment_data_new (seg->length + num); | if ((newas = assegment_data_new (seg->length + num)) == NULL) |
| return seg; |
| |
for (i = 0; i < num; i++) |
for (i = 0; i < num; i++) |
newas[i] = asnum; |
newas[i] = asnum; |
|
|
memcpy (newas + num, seg->as, ASSEGMENT_DATA_SIZE (seg->length, 1)); |
memcpy (newas + num, seg->as, ASSEGMENT_DATA_SIZE (seg->length, 1)); |
XFREE (MTYPE_AS_SEG_DATA, seg->as); | assegment_data_free (seg->as); |
seg->as = newas; |
seg->as = newas; |
seg->length += num; |
seg->length += num; |
|
|
Line 308 assegment_normalise (struct assegment *head)
|
Line 316 assegment_normalise (struct assegment *head)
|
} |
} |
return head; |
return head; |
} |
} |
| |
static struct aspath * |
static struct aspath * |
aspath_new (void) |
aspath_new (void) |
{ |
{ |
Line 476 aspath_highest (struct aspath *aspath)
|
Line 484 aspath_highest (struct aspath *aspath)
|
return highest; |
return highest; |
} |
} |
|
|
|
/* Return the left-most ASN in path */ |
|
as_t |
|
aspath_leftmost (struct aspath *aspath) |
|
{ |
|
struct assegment *seg = aspath->segments; |
|
as_t leftmost = 0; |
|
|
|
if (seg && seg->length && seg->type == AS_SEQUENCE) |
|
leftmost = seg->as[0]; |
|
|
|
return leftmost; |
|
} |
|
|
/* Return 1 if there are any 4-byte ASes in the path */ |
/* Return 1 if there are any 4-byte ASes in the path */ |
unsigned int |
unsigned int |
aspath_has_as4 (struct aspath *aspath) |
aspath_has_as4 (struct aspath *aspath) |
Line 1362 aspath_filter_exclude (struct aspath * source, struct
|
Line 1383 aspath_filter_exclude (struct aspath * source, struct
|
|
|
/* Add specified AS to the leftmost of aspath. */ |
/* Add specified AS to the leftmost of aspath. */ |
static struct aspath * |
static struct aspath * |
aspath_add_one_as (struct aspath *aspath, as_t asno, u_char type) | aspath_add_asns (struct aspath *aspath, as_t asno, u_char type, unsigned num) |
{ |
{ |
struct assegment *assegment = aspath->segments; |
struct assegment *assegment = aspath->segments; |
|
unsigned i; |
|
|
/* In case of empty aspath. */ | if (assegment && assegment->type == type) |
if (assegment == NULL || assegment->length == 0) | |
{ |
{ |
aspath->segments = assegment_new (type, 1); | /* extend existing segment */ |
aspath->segments->as[0] = asno; | aspath->segments = assegment_prepend_asns (aspath->segments, asno, num); |
| |
if (assegment) | |
assegment_free (assegment); | |
| |
return aspath; | |
} |
} |
|
|
if (assegment->type == type) |
|
aspath->segments = assegment_prepend_asns (aspath->segments, asno, 1); |
|
else |
else |
{ |
{ |
/* create new segment | /* prepend with new segment */ |
* push it onto head of aspath's segment chain | struct assegment *newsegment = assegment_new (type, num); |
*/ | for (i = 0; i < num; i++) |
struct assegment *newsegment; | newsegment->as[i] = asno; |
| |
newsegment = assegment_new (type, 1); | /* insert potentially replacing empty segment */ |
newsegment->as[0] = asno; | if (assegment && assegment->length == 0) |
| { |
newsegment->next = assegment; | newsegment->next = assegment->next; |
| assegment_free (assegment); |
| } |
| else |
| newsegment->next = assegment; |
aspath->segments = newsegment; |
aspath->segments = newsegment; |
} |
} |
|
|
|
aspath_str_update (aspath); |
return aspath; |
return aspath; |
} |
} |
|
|
|
/* Add specified AS to the leftmost of aspath num times. */ |
|
struct aspath * |
|
aspath_add_seq_n (struct aspath *aspath, as_t asno, unsigned num) |
|
{ |
|
return aspath_add_asns (aspath, asno, AS_SEQUENCE, num); |
|
} |
|
|
/* Add specified AS to the leftmost of aspath. */ |
/* Add specified AS to the leftmost of aspath. */ |
struct aspath * |
struct aspath * |
aspath_add_seq (struct aspath *aspath, as_t asno) |
aspath_add_seq (struct aspath *aspath, as_t asno) |
{ |
{ |
return aspath_add_one_as (aspath, asno, AS_SEQUENCE); | return aspath_add_asns (aspath, asno, AS_SEQUENCE, 1); |
} |
} |
|
|
/* Compare leftmost AS value for MED check. If as1's leftmost AS and |
/* Compare leftmost AS value for MED check. If as1's leftmost AS and |
Line 1600 aspath_delete_confed_seq (struct aspath *aspath)
|
Line 1625 aspath_delete_confed_seq (struct aspath *aspath)
|
struct aspath* |
struct aspath* |
aspath_add_confed_seq (struct aspath *aspath, as_t asno) |
aspath_add_confed_seq (struct aspath *aspath, as_t asno) |
{ |
{ |
return aspath_add_one_as (aspath, asno, AS_CONFED_SEQUENCE); | return aspath_add_asns (aspath, asno, AS_CONFED_SEQUENCE, 1); |
} |
} |
|
|
/* Add new as value to as path structure. */ |
/* Add new as value to as path structure. */ |
Line 1657 aspath_count (void)
|
Line 1682 aspath_count (void)
|
{ |
{ |
return ashash->count; |
return ashash->count; |
} |
} |
| |
/* |
/* |
Theoretically, one as path can have: |
Theoretically, one as path can have: |
|
|
Line 1811 aspath_str2aspath (const char *str)
|
Line 1836 aspath_str2aspath (const char *str)
|
|
|
return aspath; |
return aspath; |
} |
} |
| |
/* Make hash value by raw aspath data. */ |
/* Make hash value by raw aspath data. */ |
unsigned int |
unsigned int |
aspath_key_make (void *p) |
aspath_key_make (void *p) |
Line 1856 aspath_cmp (const void *arg1, const void *arg2)
|
Line 1881 aspath_cmp (const void *arg1, const void *arg2)
|
void |
void |
aspath_init (void) |
aspath_init (void) |
{ |
{ |
ashash = hash_create_size (32767, aspath_key_make, aspath_cmp); | ashash = hash_create_size (32768, aspath_key_make, aspath_cmp); |
} |
} |
|
|
void |
void |
aspath_finish (void) |
aspath_finish (void) |
{ |
{ |
|
hash_clean (ashash, (void (*)(void *))aspath_free); |
hash_free (ashash); |
hash_free (ashash); |
ashash = NULL; |
ashash = NULL; |
|
|
if (snmp_stream) |
if (snmp_stream) |
stream_free (snmp_stream); |
stream_free (snmp_stream); |
} |
} |
| |
/* return and as path value */ |
/* return and as path value */ |
const char * |
const char * |
aspath_print (struct aspath *as) |
aspath_print (struct aspath *as) |
Line 1896 aspath_show_all_iterator (struct hash_backet *backet,
|
Line 1922 aspath_show_all_iterator (struct hash_backet *backet,
|
|
|
as = (struct aspath *) backet->data; |
as = (struct aspath *) backet->data; |
|
|
vty_out (vty, "[%p:%u] (%ld) ", backet, backet->key, as->refcnt); | vty_out (vty, "[%p:%u] (%ld) ", (void *)backet, backet->key, as->refcnt); |
vty_out (vty, "%s%s", as->str, VTY_NEWLINE); |
vty_out (vty, "%s%s", as->str, VTY_NEWLINE); |
} |
} |
|
|