diff options
Diffstat (limited to 'bgpd/bgp_routemap.c')
-rw-r--r-- | bgpd/bgp_routemap.c | 196 |
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); |