summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-08-23 00:11:54 +0100
committerChris Hall <GMCH@hestia.halldom.com>2010-08-23 00:11:54 +0100
commita814c0b5b769195da9e3d00c77cd94d35936ec19 (patch)
treec4381bb90cba45c4e0f6fc49d2b7f60bbe23a521
parent11fe7d1d77cfd7b29ea14cc05b7fb2ea6ba13b74 (diff)
downloadquagga-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.h27
-rw-r--r--bgpd/bgp_routemap.c97
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);