route_match_ip_next_hop_prefix_list_free
};
+/* `match ipv6 next-hop prefix-list PREFIXLIST_NAME' */
+static enum route_map_cmd_result_t
+route_match_ipv6_next_hop_prefix_list(void *rule, const struct prefix *prefix,
+ void *object)
+{
+ struct prefix_list *plist;
+ struct bgp_path_info *path;
+ struct prefix_ipv6 p;
+
+ if (prefix->family == AF_INET6) {
+ path = object;
+ p.family = AF_INET6;
+ p.prefix = path->attr->mp_nexthop_global;
+ p.prefixlen = IPV6_MAX_BITLEN;
+
+ plist = prefix_list_lookup(AFI_IP6, (char *)rule);
+ if (!plist)
+ return RMAP_NOMATCH;
+
+ if (prefix_list_apply(plist, &p) == PREFIX_PERMIT)
+ return RMAP_MATCH;
+
+ if (path->attr->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ p.prefix = path->attr->mp_nexthop_local;
+ if (prefix_list_apply(plist, &p) == PREFIX_PERMIT)
+ return RMAP_MATCH;
+ }
+ }
+
+ return RMAP_NOMATCH;
+}
+
+static void *route_match_ipv6_next_hop_prefix_list_compile(const char *arg)
+{
+ return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+static void route_match_ipv6_next_hop_prefix_list_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static const struct route_map_rule_cmd
+ route_match_ipv6_next_hop_prefix_list_cmd = {
+ "ipv6 next-hop prefix-list",
+ route_match_ipv6_next_hop_prefix_list,
+ route_match_ipv6_next_hop_prefix_list_compile,
+ route_match_ipv6_next_hop_prefix_list_free
+};
+
/* `match ip next-hop type <blackhole>' */
static enum route_map_cmd_result_t
if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
return RMAP_NOMATCH;
- if (path->extra == NULL)
+ if (path->extra == NULL || path->extra->bgp_orig == NULL)
return RMAP_NOMATCH;
if (strncmp(vrf_name, vrf_id_to_name(path->extra->bgp_orig->vrf_id),
if (!list)
return RMAP_NOMATCH;
- if (ecommunity_list_match(path->attr->ecommunity, list))
+ if (ecommunity_list_match(bgp_attr_get_ecommunity(path->attr), list))
return RMAP_MATCH;
return RMAP_NOMATCH;
if (rcs->none) {
attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
- attr->ecommunity = NULL;
+ bgp_attr_set_ecommunity(attr, NULL);
return RMAP_OKAY;
}
return RMAP_OKAY;
/* We assume additive for Extended Community. */
- old_ecom = path->attr->ecommunity;
+ old_ecom = bgp_attr_get_ecommunity(path->attr);
if (old_ecom) {
new_ecom =
new_ecom = ecommunity_dup(rcs->ecom);
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
- path->attr->ecommunity = new_ecom;
+ bgp_attr_set_ecommunity(path->attr, new_ecom);
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
/* add to route or merge with existing */
- old_ecom = path->attr->ecommunity;
+ old_ecom = bgp_attr_get_ecommunity(path->attr);
if (old_ecom) {
new_ecom = ecommunity_dup(old_ecom);
ecommunity_add_val(new_ecom, &lb_eval, true, true);
}
/* new_ecom will be intern()'d or attr_flush()'d in call stack */
- path->attr->ecommunity = new_ecom;
+ bgp_attr_set_ecommunity(path->attr, new_ecom);
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
/* Mark that route-map has set link bandwidth; used in attribute
route_match_ipv6_address_free
};
+/* `match ipv6 next-hop ACCESSLIST6_NAME' */
+static enum route_map_cmd_result_t
+route_match_ipv6_next_hop(void *rule, const struct prefix *prefix, void *object)
+{
+ struct bgp_path_info *path;
+ struct access_list *alist;
+ struct prefix_ipv6 p;
+
+ if (prefix->family == AF_INET6) {
+ path = object;
+ p.family = AF_INET6;
+ p.prefix = path->attr->mp_nexthop_global;
+ p.prefixlen = IPV6_MAX_BITLEN;
+
+ alist = access_list_lookup(AFI_IP6, (char *)rule);
+ if (!alist)
+ return RMAP_NOMATCH;
+
+ if (access_list_apply(alist, &p) == FILTER_PERMIT)
+ return RMAP_MATCH;
+
+ if (path->attr->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ p.prefix = path->attr->mp_nexthop_local;
+ if (access_list_apply(alist, &p) == FILTER_PERMIT)
+ return RMAP_MATCH;
+ }
+ }
+
+ return RMAP_NOMATCH;
+}
+
+static void *route_match_ipv6_next_hop_compile(const char *arg)
+{
+ return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+static void route_match_ipv6_next_hop_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = {
+ "ipv6 next-hop",
+ route_match_ipv6_next_hop,
+ route_match_ipv6_next_hop_compile,
+ route_match_ipv6_next_hop_free
+};
+
/* `match ipv6 next-hop IP_ADDRESS' */
static enum route_map_cmd_result_t
-route_match_ipv6_next_hop(void *rule, const struct prefix *prefix, void *object)
+route_match_ipv6_next_hop_address(void *rule, const struct prefix *prefix,
+ void *object)
{
struct in6_addr *addr = rule;
struct bgp_path_info *path;
return RMAP_NOMATCH;
}
-static void *route_match_ipv6_next_hop_compile(const char *arg)
+static void *route_match_ipv6_next_hop_address_compile(const char *arg)
{
struct in6_addr *address;
int ret;
return address;
}
-static void route_match_ipv6_next_hop_free(void *rule)
+static void route_match_ipv6_next_hop_address_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
-static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = {
- "ipv6 next-hop",
- route_match_ipv6_next_hop,
- route_match_ipv6_next_hop_compile,
- route_match_ipv6_next_hop_free
+static const struct route_map_rule_cmd route_match_ipv6_next_hop_address_cmd = {
+ "ipv6 next-hop address",
+ route_match_ipv6_next_hop_address,
+ route_match_ipv6_next_hop_address_compile,
+ route_match_ipv6_next_hop_address_free
};
/* `match ip next-hop IP_ADDRESS' */
DEFUN_YANG (match_mac_address,
match_mac_address_cmd,
- "match mac address WORD",
+ "match mac address ACCESSLIST_MAC_NAME",
MATCH_STR
"mac address\n"
"Match address of route\n"
DEFUN_YANG (no_match_mac_address,
no_match_mac_address_cmd,
- "no match mac address WORD",
+ "no match mac address ACCESSLIST_MAC_NAME",
NO_STR
MATCH_STR
"mac\n"
DEFPY_YANG (match_ip_route_source,
match_ip_route_source_cmd,
- "match ip route-source WORD",
+ "match ip route-source ACCESSLIST4_NAME",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
DEFUN_YANG (no_match_ip_route_source,
no_match_ip_route_source_cmd,
- "no match ip route-source [WORD]",
+ "no match ip route-source [ACCESSLIST4_NAME]",
NO_STR
MATCH_STR
IP_STR
DEFUN_YANG (match_ip_route_source_prefix_list,
match_ip_route_source_prefix_list_cmd,
- "match ip route-source prefix-list WORD",
+ "match ip route-source prefix-list PREFIXLIST_NAME",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
DEFUN_YANG (no_match_ip_route_source_prefix_list,
no_match_ip_route_source_prefix_list_cmd,
- "no match ip route-source prefix-list [WORD]",
+ "no match ip route-source prefix-list [PREFIXLIST_NAME]",
NO_STR
MATCH_STR
IP_STR
DEFUN_YANG (match_ipv6_next_hop,
match_ipv6_next_hop_cmd,
- "match ipv6 next-hop X:X::X:X",
+ "match ipv6 next-hop ACCESSLIST6_NAME",
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "IPv6 access-list name\n")
+{
+ const char *xpath =
+ "./match-condition[condition='frr-route-map:ipv6-next-hop-list']";
+ char xpath_value[XPATH_MAXLEN];
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/rmap-match-condition/list-name", xpath);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+ argv[argc - 1]->arg);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_match_ipv6_next_hop,
+ no_match_ipv6_next_hop_cmd,
+ "no match ipv6 next-hop [ACCESSLIST6_NAME]",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "IPv6 access-list name\n")
+{
+ const char *xpath =
+ "./match-condition[condition='frr-route-map:ipv6-next-hop-list']";
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (match_ipv6_next_hop_address,
+ match_ipv6_next_hop_address_cmd,
+ "match ipv6 next-hop address X:X::X:X",
MATCH_STR
IPV6_STR
"Match IPv6 next-hop address of route\n"
+ "IPv6 address\n"
"IPv6 address of next hop\n")
{
const char *xpath =
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-match-condition/frr-bgp-route-map:ipv6-address",
xpath);
- nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+ argv[argc - 1]->arg);
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN_YANG (no_match_ipv6_next_hop,
- no_match_ipv6_next_hop_cmd,
- "no match ipv6 next-hop X:X::X:X",
+DEFUN_YANG (no_match_ipv6_next_hop_address,
+ no_match_ipv6_next_hop_address_cmd,
+ "no match ipv6 next-hop address X:X::X:X",
NO_STR
MATCH_STR
IPV6_STR
"Match IPv6 next-hop address of route\n"
+ "IPv6 address\n"
"IPv6 address of next hop\n")
{
const char *xpath =
return nb_cli_apply_changes(vty, NULL);
}
+ALIAS_HIDDEN (match_ipv6_next_hop_address,
+ match_ipv6_next_hop_old_cmd,
+ "match ipv6 next-hop X:X::X:X",
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "IPv6 address of next hop\n")
+
+ALIAS_HIDDEN (no_match_ipv6_next_hop_address,
+ no_match_ipv6_next_hop_old_cmd,
+ "no match ipv6 next-hop X:X::X:X",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "IPv6 address of next hop\n")
+
+DEFUN_YANG (match_ipv6_next_hop_prefix_list,
+ match_ipv6_next_hop_prefix_list_cmd,
+ "match ipv6 next-hop prefix-list PREFIXLIST_NAME",
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "Match entries by prefix-list\n"
+ "IPv6 prefix-list name\n")
+{
+ const char *xpath =
+ "./match-condition[condition='frr-route-map:ipv6-next-hop-prefix-list']";
+ char xpath_value[XPATH_MAXLEN];
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/rmap-match-condition/list-name", xpath);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+ argv[argc - 1]->arg);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_match_ipv6_next_hop_prefix_list,
+ no_match_ipv6_next_hop_prefix_list_cmd,
+ "no match ipv6 next-hop prefix-list [PREFIXLIST_NAME]",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 next-hop address of route\n"
+ "Match entries by prefix-list\n"
+ "IPv6 prefix-list name\n")
+{
+ const char *xpath =
+ "./match-condition[condition='frr-route-map:ipv6-next-hop-prefix-list']";
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
DEFPY_YANG (match_ipv4_next_hop,
match_ipv4_next_hop_cmd,
"match ip next-hop address A.B.C.D",
route_map_match_ip_next_hop_hook(generic_match_add);
route_map_no_match_ip_next_hop_hook(generic_match_delete);
+ route_map_match_ipv6_next_hop_hook(generic_match_add);
+ route_map_no_match_ipv6_next_hop_hook(generic_match_delete);
+
route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
route_map_match_ipv6_next_hop_type_hook(generic_match_add);
route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete);
+ route_map_match_ipv6_next_hop_prefix_list_hook(generic_match_add);
+ route_map_no_match_ipv6_next_hop_prefix_list_hook(generic_match_delete);
+
route_map_match_metric_hook(generic_match_add);
route_map_no_match_metric_hook(generic_match_delete);
route_map_install_match(&route_match_ipv6_address_cmd);
route_map_install_match(&route_match_ipv6_next_hop_cmd);
+ route_map_install_match(&route_match_ipv6_next_hop_address_cmd);
+ route_map_install_match(&route_match_ipv6_next_hop_prefix_list_cmd);
route_map_install_match(&route_match_ipv4_next_hop_cmd);
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
route_map_install_match(&route_match_ipv6_next_hop_type_cmd);
route_map_install_set(&route_set_ipv6_nexthop_peer_cmd);
install_element(RMAP_NODE, &match_ipv6_next_hop_cmd);
+ install_element(RMAP_NODE, &match_ipv6_next_hop_address_cmd);
+ install_element(RMAP_NODE, &match_ipv6_next_hop_prefix_list_cmd);
install_element(RMAP_NODE, &no_match_ipv6_next_hop_cmd);
+ install_element(RMAP_NODE, &no_match_ipv6_next_hop_address_cmd);
+ install_element(RMAP_NODE, &no_match_ipv6_next_hop_prefix_list_cmd);
+ install_element(RMAP_NODE, &match_ipv6_next_hop_old_cmd);
+ install_element(RMAP_NODE, &no_match_ipv6_next_hop_old_cmd);
install_element(RMAP_NODE, &match_ipv4_next_hop_cmd);
install_element(RMAP_NODE, &no_match_ipv4_next_hop_cmd);
install_element(RMAP_NODE, &set_ipv6_nexthop_global_cmd);