summaryrefslogtreecommitdiff
path: root/bgpd/bgp_routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_routemap.c')
-rw-r--r--bgpd/bgp_routemap.c196
1 files changed, 195 insertions, 1 deletions
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 73165d35..b11aaf23 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -57,7 +57,7 @@ o Cisco route-map
interface : Not yet
ip address : Done
ip next-hop : Done
- ip route-source : (This will not be implemented by bgpd)
+ ip route-source : Done
ip prefix-list : Done
ipv6 address : Done
ipv6 next-hop : Done
@@ -291,6 +291,64 @@ struct route_map_rule_cmd route_match_ip_next_hop_cmd =
route_match_ip_next_hop_free
};
+/* `match ip route-source ACCESS-LIST' */
+
+/* Match function return 1 if match is success else return zero. */
+route_map_result_t
+route_match_ip_route_source (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct access_list *alist;
+ struct bgp_info *bgp_info;
+ struct peer *peer;
+ struct prefix_ipv4 p;
+
+ if (type == RMAP_BGP)
+ {
+ bgp_info = object;
+ peer = bgp_info->peer;
+
+ if (! peer || sockunion_family (&peer->su) != AF_INET)
+ return RMAP_NOMATCH;
+
+ p.family = AF_INET;
+ p.prefix = peer->su.sin.sin_addr;
+ p.prefixlen = IPV4_MAX_BITLEN;
+
+ alist = access_list_lookup (AFI_IP, (char *) rule);
+ if (alist == NULL)
+ return RMAP_NOMATCH;
+
+ return (access_list_apply (alist, &p) == FILTER_DENY ?
+ RMAP_NOMATCH : RMAP_MATCH);
+ }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `ip route-source' match statement. `arg' is
+ access-list name. */
+void *
+route_match_ip_route_source_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `ip address' value. */
+void
+route_match_ip_route_source_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip route-source matching. */
+struct route_map_rule_cmd route_match_ip_route_source_cmd =
+{
+ "ip route-source",
+ route_match_ip_route_source,
+ route_match_ip_route_source_compile,
+ route_match_ip_route_source_free
+};
+
/* `match ip address prefix-list PREFIX_LIST' */
route_map_result_t
@@ -378,6 +436,59 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
route_match_ip_next_hop_prefix_list_free
};
+/* `match ip route-source prefix-list PREFIX_LIST' */
+
+route_map_result_t
+route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct prefix_list *plist;
+ struct bgp_info *bgp_info;
+ struct peer *peer;
+ struct prefix_ipv4 p;
+
+ if (type == RMAP_BGP)
+ {
+ bgp_info = object;
+ peer = bgp_info->peer;
+
+ if (! peer || sockunion_family (&peer->su) != AF_INET)
+ return RMAP_NOMATCH;
+
+ p.family = AF_INET;
+ p.prefix = peer->su.sin.sin_addr;
+ p.prefixlen = IPV4_MAX_BITLEN;
+
+ plist = prefix_list_lookup (AFI_IP, (char *) rule);
+ if (plist == NULL)
+ return RMAP_NOMATCH;
+
+ return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
+ RMAP_NOMATCH : RMAP_MATCH);
+ }
+ return RMAP_NOMATCH;
+}
+
+void *
+route_match_ip_route_source_prefix_list_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+void
+route_match_ip_route_source_prefix_list_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
+{
+ "ip route-source prefix-list",
+ route_match_ip_route_source_prefix_list,
+ route_match_ip_route_source_prefix_list_compile,
+ route_match_ip_route_source_prefix_list_free
+};
+
/* `match metric METRIC' */
/* Match function return 1 if match is success else return zero. */
@@ -2305,6 +2416,44 @@ ALIAS (no_match_ip_next_hop,
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
+DEFUN (match_ip_route_source,
+ match_ip_route_source_cmd,
+ "match ip route-source (<1-199>|<1300-2699>|WORD)",
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP standard access-list name\n")
+{
+ return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
+}
+
+DEFUN (no_match_ip_route_source,
+ no_match_ip_route_source_cmd,
+ "no match ip route-source",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n")
+{
+ if (argc == 0)
+ return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
+
+ return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
+}
+
+ALIAS (no_match_ip_route_source,
+ no_match_ip_route_source_val_cmd,
+ "no match ip route-source (<1-199>|<1300-2699>|WORD)",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP standard access-list name\n");
+
DEFUN (match_ip_address_prefix_list,
match_ip_address_prefix_list_cmd,
"match ip address prefix-list WORD",
@@ -2379,6 +2528,43 @@ ALIAS (no_match_ip_next_hop_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
+DEFUN (match_ip_route_source_prefix_list,
+ match_ip_route_source_prefix_list_cmd,
+ "match ip route-source prefix-list WORD",
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
+}
+
+DEFUN (no_match_ip_route_source_prefix_list,
+ no_match_ip_route_source_prefix_list_cmd,
+ "no match ip route-source prefix-list",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n"
+ "Match entries of prefix-lists\n")
+{
+ if (argc == 0)
+ return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
+
+ return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
+}
+
+ALIAS (no_match_ip_route_source_prefix_list,
+ no_match_ip_route_source_prefix_list_val_cmd,
+ "no match ip route-source prefix-list WORD",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match advertising source address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n");
+
DEFUN (match_metric,
match_metric_cmd,
"match metric <0-4294967295>",
@@ -3395,8 +3581,10 @@ bgp_route_map_init ()
route_map_install_match (&route_match_peer_cmd);
route_map_install_match (&route_match_ip_address_cmd);
route_map_install_match (&route_match_ip_next_hop_cmd);
+ route_map_install_match (&route_match_ip_route_source_cmd);
route_map_install_match (&route_match_ip_address_prefix_list_cmd);
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_community_cmd);
route_map_install_match (&route_match_ecommunity_cmd);
@@ -3429,6 +3617,9 @@ bgp_route_map_init ()
install_element (RMAP_NODE, &match_ip_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
+ install_element (RMAP_NODE, &match_ip_route_source_cmd);
+ install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
+ install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
@@ -3436,6 +3627,9 @@ bgp_route_map_init ()
install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
+ install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_aspath_cmd);
install_element (RMAP_NODE, &no_match_aspath_cmd);