diff options
author | Chris Hall <GMCH@hestia.halldom.com> | 2010-08-23 00:11:54 +0100 |
---|---|---|
committer | Chris Hall <GMCH@hestia.halldom.com> | 2010-08-23 00:11:54 +0100 |
commit | a814c0b5b769195da9e3d00c77cd94d35936ec19 (patch) | |
tree | c4381bb90cba45c4e0f6fc49d2b7f60bbe23a521 | |
parent | 11fe7d1d77cfd7b29ea14cc05b7fb2ea6ba13b74 (diff) | |
download | quagga-a814c0b5b769195da9e3d00c77cd94d35936ec19.tar.bz2 quagga-a814c0b5b769195da9e3d00c77cd94d35936ec19.tar.xz |
Add "match as-origin ASN" route-map entry
Provides a faster way to match the last ASN in the AS Path to an
expected ASN.
-rw-r--r-- | bgpd/bgp_aspath.h | 27 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 97 |
2 files changed, 122 insertions, 2 deletions
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index b8a5dfab..4556c503 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -21,6 +21,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGP_ASPATH_H #define _QUAGGA_BGP_ASPATH_H +/* Macro in case there are particular compiler issues. */ +#ifndef Inline + #define Inline static inline +#endif + /* AS path segment type. */ #define AS_SET 1 #define AS_SEQUENCE 2 @@ -47,14 +52,14 @@ struct assegment }; /* AS path may be include some AsSegments. */ -struct aspath +struct aspath { /* Reference count to this aspath. */ unsigned long refcnt; /* segment data */ struct assegment *segments; - + /* String expression of AS path. This string is used by vty output and AS path regular expression match. */ char *str; @@ -103,4 +108,22 @@ extern unsigned int aspath_has_as4 (struct aspath *); /* For SNMP BGP4PATHATTRASPATHSEGMENT, might be useful for debug */ extern u_char *aspath_snmp_pathseg (struct aspath *, size_t *); +Inline as_t +aspath_origin(struct aspath* asp) +{ + struct assegment* seg ; + + if ((asp == NULL) || (asp->segments == NULL)) + return 0 ; + + seg = asp->segments ; + while (seg->next != NULL) + seg = seg->next ; + + if ((seg->length == 0) || (seg->type != AS_SEQUENCE)) + return 0 ; + + return seg->as[seg->length - 1] ; +} ; + #endif /* _QUAGGA_BGP_ASPATH_H */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 64f2a90c..f40d057d 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -694,6 +694,63 @@ struct route_map_rule_cmd route_match_aspath_cmd = route_match_aspath_free }; +/*------------------------------------------------------------------------------ + * match as-origin ASN + */ + +static route_map_result_t +route_match_as_origin (void* p_asn, struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct bgp_info *bgp_info; + + if (type == RMAP_BGP) + { + bgp_info = object ; + + return *((as_t*)p_asn) == aspath_origin(bgp_info->attr->aspath) + ? RMAP_MATCH : RMAP_NOMATCH ; + } + return RMAP_NOMATCH; +} + +static void * +route_match_as_origin_compile (const char *arg) +{ + as_t* p_asn ; + unsigned long tmp ; + char* ep ; + + errno = 0 ; + ep = NULL ; + + tmp = strtoul (arg, &ep, 10) ; + if ((errno != 0) || (*ep != '\0')) + return NULL ; + + p_asn = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(as_t)) ; + + *p_asn = tmp ; + + return p_asn ; +} ; + +static void +route_match_as_origin_free (void* p_asn) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, p_asn); +} + +/* Route map commands for as-origin matching. */ +struct route_map_rule_cmd route_match_as_origin_cmd = +{ + "as-origin", + route_match_as_origin, + route_match_as_origin_compile, + route_match_as_origin_free +} ; + +/*----------------------------------------------------------------------------*/ /* `match community COMMUNIY' */ struct rmap_community { @@ -2854,6 +2911,42 @@ ALIAS (no_match_aspath, "Match BGP AS path list\n" "AS path access-list name\n") +/*------------------------------------------------------------------------------ + * match as-origin 9999 + * no match as-origin + * no match as-origin 9999 + */ + +DEFUN (match_as_origin, + match_as_origin_cmd, + "match as-origin " CMD_AS_RANGE, + MATCH_STR + "Match BGP AS path origin ASN\n" + "AS path origin ASN\n") +{ + return bgp_route_match_add (vty, vty->index, "as-origin", argv[0]); +} + +DEFUN (no_match_as_origin, + no_match_as_origin_cmd, + "no match as-origin", + NO_STR + MATCH_STR + "Match BGP AS path origin ASN\n") +{ + return bgp_route_match_delete (vty, vty->index, "as-origin", NULL); +} + +ALIAS (no_match_as_origin, + no_match_as_origin_val_cmd, + "no match as-origin " CMD_AS_RANGE, + NO_STR + MATCH_STR + "Match BGP AS path origin ASN\n" + "AS path origin ASN\n") + +/*----------------------------------------------------------------------------*/ + DEFUN (match_origin, match_origin_cmd, "match origin (egp|igp|incomplete)", @@ -3835,6 +3928,7 @@ bgp_route_map_init (void) route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); route_map_install_match (&route_match_ip_route_source_prefix_list_cmd); route_map_install_match (&route_match_aspath_cmd); + route_map_install_match (&route_match_as_origin_cmd); route_map_install_match (&route_match_community_cmd); route_map_install_match (&route_match_ecommunity_cmd); route_map_install_match (&route_match_metric_cmd); @@ -3884,6 +3978,9 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &match_aspath_cmd); install_element (RMAP_NODE, &no_match_aspath_cmd); install_element (RMAP_NODE, &no_match_aspath_val_cmd); + install_element (RMAP_NODE, &match_as_origin_cmd); + install_element (RMAP_NODE, &no_match_as_origin_cmd); + install_element (RMAP_NODE, &no_match_as_origin_val_cmd); install_element (RMAP_NODE, &match_metric_cmd); install_element (RMAP_NODE, &no_match_metric_cmd); install_element (RMAP_NODE, &no_match_metric_val_cmd); |