]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_routemap.c
bgpd: conditional advertisement - other match rules support
[mirror_frr.git] / bgpd / bgp_routemap.c
index aafeb147625c90a31c06e97f77dff4025f775fdd..e4a9c29000675b40e5c6ec8c9f7c50f1728cf72e 100644 (file)
@@ -594,10 +594,14 @@ route_match_prefix_list_flowspec(afi_t afi, struct prefix_list *plist,
 
        memset(&api, 0, sizeof(api));
 
+       if (family2afi(p->u.prefix_flowspec.family) != afi)
+               return RMAP_NOMATCH;
+
        /* extract match from flowspec entries */
        ret = bgp_flowspec_match_rules_fill(
                                            (uint8_t *)p->u.prefix_flowspec.ptr,
-                                           p->u.prefix_flowspec.prefixlen, &api);
+                                           p->u.prefix_flowspec.prefixlen, &api,
+                                           afi);
        if (ret < 0)
                return RMAP_NOMATCH;
        if (api.match_bitmask & PREFIX_DST_PRESENT ||
@@ -1664,6 +1668,45 @@ static const struct route_map_rule_cmd route_match_tag_cmd = {
        route_map_rule_tag_free,
 };
 
+static enum route_map_cmd_result_t
+route_set_srte_color(void *rule, const struct prefix *prefix,
+                    route_map_object_t type, void *object)
+{
+       uint32_t *srte_color = rule;
+       struct bgp_path_info *path;
+
+       if (type != RMAP_BGP)
+               return RMAP_OKAY;
+
+       path = object;
+
+       path->attr->srte_color = *srte_color;
+       path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR);
+
+       return RMAP_OKAY;
+}
+
+/* Route map `sr-te color' compile function */
+static void *route_set_srte_color_compile(const char *arg)
+{
+       uint32_t *color;
+
+       color = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
+       *color = atoi(arg);
+
+       return color;
+}
+
+/* Free route map's compiled `sr-te color' value. */
+static void route_set_srte_color_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for sr-te color set. */
+struct route_map_rule_cmd route_set_srte_color_cmd = {
+       "sr-te color", route_set_srte_color, route_set_srte_color_compile,
+       route_set_srte_color_free};
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 struct rmap_ip_nexthop_set {
@@ -2602,6 +2645,7 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix,
                        ecommunity_free(&old_ecom);
        } else {
                ecom_lb.size = 1;
+               ecom_lb.unit_size = ECOMMUNITY_SIZE;
                ecom_lb.val = (uint8_t *)lb_eval.val;
                new_ecom = ecommunity_dup(&ecom_lb);
        }
@@ -3651,9 +3695,22 @@ static void bgp_route_map_process_peer(const char *rmap_name,
        if (filter->usmap.name && (strcmp(rmap_name, filter->usmap.name) == 0))
                filter->usmap.map = map;
 
+       if (filter->advmap.aname
+           && (strcmp(rmap_name, filter->advmap.aname) == 0)) {
+               filter->advmap.amap = map;
+       }
+
+       if (filter->advmap.cname
+           && (strcmp(rmap_name, filter->advmap.cname) == 0)) {
+               filter->advmap.cmap = map;
+       }
+
        if (peer->default_rmap[afi][safi].name
            && (strcmp(rmap_name, peer->default_rmap[afi][safi].name) == 0))
                peer->default_rmap[afi][safi].map = map;
+
+       /* Notify BGP conditional advertisement scanner percess */
+       peer->advmap_config_change[afi][safi] = true;
 }
 
 static void bgp_route_map_update_peer_group(const char *rmap_name,
@@ -3702,6 +3759,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                                         int route_update)
 {
        int i;
+       bool matched;
        afi_t afi;
        safi_t safi;
        struct peer *peer;
@@ -3756,8 +3814,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
 
                        if (BGP_DEBUG(zebra, ZEBRA))
                                zlog_debug(
-                                       "Processing route_map %s update on "
-                                       "table map",
+                                       "Processing route_map %s update on table map",
                                        rmap_name);
                        if (route_update)
                                bgp_zebra_announce_table(bgp, afi, safi);
@@ -3802,16 +3859,35 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                        if (!aggregate)
                                continue;
 
-                       if (!aggregate->rmap.name
-                           || (strcmp(rmap_name, aggregate->rmap.name) != 0))
-                               continue;
+                       matched = false;
 
-                       if (!aggregate->rmap.map)
-                               route_map_counter_increment(map);
+                       /* Update suppress map pointer. */
+                       if (aggregate->suppress_map_name
+                           && strmatch(aggregate->suppress_map_name,
+                                       rmap_name)) {
+                               if (aggregate->rmap.map == NULL)
+                                       route_map_counter_increment(map);
+
+                               aggregate->suppress_map = map;
+
+                               bgp_aggregate_toggle_suppressed(
+                                       aggregate, bgp, bgp_dest_get_prefix(bn),
+                                       afi, safi, false);
+
+                               matched = true;
+                       }
+
+                       if (aggregate->rmap.name
+                           && strmatch(rmap_name, aggregate->rmap.name)) {
+                               if (aggregate->rmap.map == NULL)
+                                       route_map_counter_increment(map);
 
-                       aggregate->rmap.map = map;
+                               aggregate->rmap.map = map;
 
-                       if (route_update) {
+                               matched = true;
+                       }
+
+                       if (matched && route_update) {
                                const struct prefix *bn_p =
                                        bgp_dest_get_prefix(bn);
 
@@ -3917,8 +3993,7 @@ static void bgp_route_map_mark_update(const char *rmap_name)
        /* If new update is received before the current timer timed out,
         * turn it off and start a new timer.
         */
-       if (bm->t_rmap_update != NULL)
-               THREAD_OFF(bm->t_rmap_update);
+       THREAD_OFF(bm->t_rmap_update);
 
        /* rmap_update_timer of 0 means don't do route updates */
        if (bm->rmap_update_timer) {
@@ -3991,32 +4066,64 @@ DEFUN (no_match_mac_address,
                                      RMAP_EVENT_FILTER_DELETED);
 }
 
+/*
+ * Helper to handle the case of the user passing in a number or type string
+ */
+static const char *parse_evpn_rt_type(const char *num_rt_type)
+{
+       switch (num_rt_type[0]) {
+       case '1':
+               return "ead";
+       case '2':
+               return "macip";
+       case '3':
+               return "multicast";
+       case '4':
+               return "es";
+       case '5':
+               return "prefix";
+       default:
+               break;
+       }
+
+       /* Was already full type string */
+       return num_rt_type;
+}
+
 DEFUN (match_evpn_route_type,
        match_evpn_route_type_cmd,
-       "match evpn route-type <macip | multicast | prefix>",
+       "match evpn route-type <macip|2|multicast|3|prefix|5>",
        MATCH_STR
        EVPN_HELP_STR
-       "Match route-type\n"
-       "mac-ip route\n"
-       "IMET route\n"
-       "prefix route\n")
-{
-       return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg,
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR)
+{
+       return bgp_route_match_add(vty, "evpn route-type",
+                                  parse_evpn_rt_type(argv[3]->arg),
                                   RMAP_EVENT_MATCH_ADDED);
 }
 
 DEFUN (no_match_evpn_route_type,
        no_match_evpn_route_type_cmd,
-       "no match evpn route-type <macip | multicast | prefix>",
+       "no match evpn route-type <macip|2|multicast|3|prefix|5>",
        NO_STR
        MATCH_STR
        EVPN_HELP_STR
-       "Match route-type\n"
-       "mac-ip route\n"
-       "IMET route\n"
-       "prefix route\n")
-{
-       return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg,
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR)
+{
+       return bgp_route_match_delete(vty, "evpn route-type",
+                                     parse_evpn_rt_type(argv[4]->arg),
                                      RMAP_EVENT_MATCH_DELETED);
 }
 
@@ -5682,6 +5789,9 @@ void bgp_route_map_init(void)
        route_map_match_tag_hook(generic_match_add);
        route_map_no_match_tag_hook(generic_match_delete);
 
+       route_map_set_srte_color_hook(generic_set_add);
+       route_map_no_set_srte_color_hook(generic_set_delete);
+
        route_map_set_ip_nexthop_hook(generic_set_add);
        route_map_no_set_ip_nexthop_hook(generic_set_delete);
 
@@ -5724,6 +5834,7 @@ void bgp_route_map_init(void)
        route_map_install_match(&route_match_vrl_source_vrf_cmd);
 
        route_map_install_set(&route_set_table_id_cmd);
+       route_map_install_set(&route_set_srte_color_cmd);
        route_map_install_set(&route_set_ip_nexthop_cmd);
        route_map_install_set(&route_set_local_pref_cmd);
        route_map_install_set(&route_set_weight_cmd);